Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changelog.d/11082-string-payload-scanner-dotdir.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
### Fixed

- `scripts/string_payload_access_inventory.py` scanned **zero files** when run from a checkout under any dot-prefixed directory — which is where every agent worktree lives (`.claude/worktrees/agent-<id>/`). The skip filter tested `path.parts`, the ABSOLUTE path, so `.claude` matched `part.startswith(".")` and every source file was skipped. The gate then reported each baseline row as `found 0` and printed `Run: … --write-baseline`; following that instruction would have written an all-zero baseline and left the ratchet permanently satisfied. The filter now tests the path relative to the repo root, a scan of zero files fails loudly instead of returning a verdict, and `--self-test` covers a checkout under a dot-named parent (a tempdir alone could not catch this, since `/var/folders/…` has no dot component). CI was never affected: runners check out to `/home/runner/work/perry/perry`. (#11082)
46 changes: 44 additions & 2 deletions scripts/string_payload_access_inventory.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,15 @@ def collect_inventory(root: Path = REPO_ROOT) -> tuple[list[Finding], int]:
for crate_dir in crate_dirs(root):
crate = crate_dir.name
for path in sorted(crate_dir.rglob("*.rs")):
rel_path = path.relative_to(root).as_posix()
if any(part.startswith(".") or part == "target" for part in path.parts):
rel = path.relative_to(root)
rel_path = rel.as_posix()
# Filter on the path RELATIVE to the repo root. `path.parts` is
# absolute, so a checkout living under any dot-prefixed directory
# -- `.claude/worktrees/agent-<id>/` is where agents run -- matched
# `part.startswith(".")` on every file and skipped the entire
# workspace. The scan then found nothing and the gate reported each
# baseline row as "found 0", i.e. "everything was converted".
if any(part.startswith(".") or part == "target" for part in rel.parts):
continue
files_scanned += 1
text = path.read_text(encoding="utf-8")
Expand Down Expand Up @@ -359,6 +366,30 @@ def expect(condition: bool, message: str) -> None:
source.write_text(planted, encoding="utf-8")
discovered, files_scanned = collect_inventory(temp_root)
expect(files_scanned == 1, "synthetic crate source was not scanned exactly once")

# The same tree, one level under a DOT-PREFIXED directory. Agents run
# from `.claude/worktrees/agent-<id>/`, and the filter used to test the
# ABSOLUTE path, so every file was skipped and the scan silently
# returned nothing. A tempdir alone cannot catch this: `/var/folders/...`
# has no dot component.
dot_root = temp_root / ".agentdir" / "checkout"
dot_crate = dot_root / "crates" / "synthetic-crate"
(dot_crate / "src").mkdir(parents=True)
(dot_crate / "Cargo.toml").write_text(
'[package]\nname = "synthetic-crate"\nversion = "0.0.0"\n',
encoding="utf-8",
)
(dot_crate / "src" / "lib.rs").write_text(planted, encoding="utf-8")
dot_found, dot_scanned = collect_inventory(dot_root)
expect(
dot_scanned == 1,
"a checkout under a dot-prefixed directory scanned no files "
"(the filter is testing the absolute path again)",
)
expect(
counts_for(dot_found) == counts_for(findings),
"a checkout under a dot-prefixed directory lost findings",
)
expect(
counts_for(discovered) == counts_for(findings),
"filesystem inventory disagreed with direct source scanning",
Expand Down Expand Up @@ -403,6 +434,17 @@ def main(argv: list[str] | None = None) -> int:
return run_self_tests()

findings, files_scanned = collect_inventory()
# A scan of zero files is not a clean tree, it is a broken scan. Without
# this, every baseline row reads "found 0" and the failure text invites
# `--write-baseline`, which would zero the ratchet and satisfy it forever.
if files_scanned == 0:
print(
"string-payload access inventory: SCANNED NO FILES -- this is a broken "
"scan, not a converted tree. Do NOT run --write-baseline. Check that "
"crates/ exists under the repo root being scanned.",
file=sys.stderr,
)
return 1
actual = counts_for(findings)
if args.write_baseline:
write_baseline(args.baseline, actual)
Expand Down
Loading