Skip to content

chore: gate03-sweep.sh --compare keys on absolute paths and silently treats a directory with no *.json as an empty baseline #182

Open

Description

@hermanngeorge15

Two hazards in one comparison mechanism, each of which has already cost this project a spurious result.

  1. A directory with no *.json loads as a silent empty baseline. --compare globs *.json in each argument. This repository deliberately commits no raw reports (only manifest.tsv, summary.tsv, checksums.sha256), so pointing --compare at a committed sweep directory loads zero findings and reports every real finding in the candidate as a new addition (a spurious 500-line diff in Phase 4 plan 04-07). It should refuse to compare an empty side with a clear error.
  2. Findings are keyed on the absolute path recorded in the JSON. A sweep captured while the repository was a disposable agent worktree embeds that worktree's path for the repo-local input rows, so a later run from another checkout sees those rows as wholesale additions and removals. Phase 5 plan 05-01 hit this, and the orchestrator had to re-capture three rows from the main checkout. The key should be relative to a declared root (or the script should refuse repo-local rows that are not under the current root).

Both are mitigated today by procedure (always point --compare at .planning/local/; sweep repo-local inputs by the main checkout's literal paths), which is exactly the kind of mitigation that is forgotten.


Filed at the close-out of Phase 5 (CAT-03, #35), plan 05-07 Task 2, from .planning/phases/05-persistence-lifecycle-hijack-cat-03-35/deferred-items.md. Nothing here is fixed in v0.2.0.

Activity

  1. added this to the v0.3.0 milestone on Oct 9, 2026
  2. added
    bugSomething isn't working
    P2Normal priority
    ciBuild and release pipeline
    on Oct 9, 2026
  3. hermanngeorge15 commented on Oct 22, 2026

    @hermanngeorge15
    ContributorAuthor

    Both hazards still present on main @ edec71c. Flagging explicitly because PR #192 recently touched this same script (fix: keep sweep helper variables local) and that was a different bug — variable isolation, not comparison semantics. This issue was not affected by it.

    Hazard 1 reproduced empirically. A baseline directory containing no *.json — which is exactly what a committed sweep directory looks like here, since the repo commits only manifest.tsv, summary.tsv and checksums.sha256:

    $ ls base/   -> manifest.tsv
    $ ls cand/   -> r.json   (2 findings)
    
    $ ./scripts/gate03-sweep.sh --compare base cand
    /abs/path/doc.md:7	PI001
    /abs/path/doc.md:9	PI031
    exit 1
    

    Every candidate finding is reported as a new addition, exit 1, and no error or warning is raised. load_findings() returns an empty set() for a directory with no matching glob, and nothing downstream distinguishes "no findings" from "no input".

    Hazard 2 confirmed by inspection. findings.add((report['file'], match['line'], match['pattern_id'])) keys on report['file'], which is the absolute path as scanned. Two sweeps of the same content from different checkout paths therefore share no keys, and the whole candidate reads as new.

    Smallest fix that closes hazard 1 without touching the comparison logic: have load_findings count the files it globbed and fail with a clear message when the glob matched nothing, so an empty side is refused rather than silently treated as a clean baseline.

    Not scheduling — maintenance-only after v0.2.0 — but worth noting that of the two, hazard 1 is the one that has already produced a spurious result twice (the 500-line Phase 4 plan 04-07 diff cited above, and the GATE-03 --compare exit code investigated in quick-260902-jhy).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal prioritybugSomething isn't workingciBuild and release pipeline

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions