Skip to content

fix(tooling): string-payload ratchet scans nothing under a dot-directory (and invites zeroing its own baseline) - #11082

Closed
proggeramlug wants to merge 1 commit into
mainfrom
fix/string-payload-scanner-dotdir
Closed

proggeramlug wants to merge 1 commit into
mainfrom
fix/string-payload-scanner-dotdir

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

scripts/string_payload_access_inventory.py scans zero files from any checkout under a dot-prefixed directory — which is where every agent worktree lives (.claude/worktrees/agent-<id>/).

rel_path = path.relative_to(root).as_posix()
if any(part.startswith(".") or part == "target" for part in path.parts):   # <- ABSOLUTE path
    continue

.claude matches part.startswith("."), so every source file is skipped. Diagnosed by the turnloop lane, which hit it in an agent worktree; I reproduced it and confirmed the pieces in isolation all work — INLINE_OFFSET_RE matches, scan_text finds, crate_dirs() returns 67 crates — and the file filter throws all of it away.

Why this is worse than a broken scan

Finding nothing makes every baseline row read baseline 349, found 0 — "all of these were converted" — and the failure text then says:

Run: python3 scripts/string_payload_access_inventory.py --write-baseline

An agent or reviewer doing exactly what the error instructs would commit an all-zero baseline. The ratchet would be permanently satisfied, could never catch a regression again, and the diff would look like a legitimate "record the progress" commit.

Changes

  1. Filter on the path relative to the repo root, which is what the filter always meant to test.
  2. Refuse to report a verdict after scanning zero files, with an explicit "do NOT run --write-baseline". A scanner that looked at nothing must not be able to issue a clean bill of health — CLAUDE.md's fourth way a gate cannot fail.
  3. Self-test the dot-directory case. The existing fixture plants a synthetic crate in a tempdir and asserts files_scanned == 1, which is the right shape but cannot catch this, because /var/folders/… has no dot component. The new fixture plants the same tree under .agentdir/ and asserts both the file count and the findings.

Measured, same dot-named directory, before and after

BEFORE:  reader-helper | perry-runtime: baseline 13, found 0
         Run: python3 scripts/string_payload_access_inventory.py --write-baseline
AFTER:   string-payload access inventory: 4056 files; 393 inline offsets and 14 reader helpers

--self-test passes, and the new fixture was confirmed to fail against the old filter before being wired in.

CI was never affected: runners check out to /home/runner/work/perry/perry, which has no dot component, so the gate has been genuinely live there throughout. This is purely about local and agent runs — which is where most of its invocations now happen.

Summary by CodeRabbit

  • Bug Fixes
    • The inventory scan now works when the checkout is inside a dot-prefixed directory.
    • Scans that find no files now report an error instead of returning misleading results.
    • Added a self-test for checkouts under dot-prefixed directories.

…directory

`collect_inventory` filtered on `path.parts` — the ABSOLUTE path — so any
checkout living under a dot-prefixed directory skipped every file. Agent
worktrees live at `.claude/worktrees/agent-<id>/`, so for a growing share of
the people who run this gate it scanned 0 files and found 0 sites.

That is not a quiet failure. Finding nothing makes every baseline row read
"baseline 349, found 0", i.e. "all of these were converted", and the failure
text then says:

    Run: python3 scripts/string_payload_access_inventory.py --write-baseline

Doing what the error says would commit an all-zero baseline. The ratchet would
be satisfied forever and could never catch a regression again, and the diff
would look like a legitimate "record the progress" commit in review.

Three changes:
- filter on the path RELATIVE to the repo root (`rel.parts`), which is the
  thing the filter was always meant to test;
- refuse to report a verdict after scanning zero files, with an explicit "do
  NOT run --write-baseline" — a scanner that looked at nothing must not be able
  to produce a clean bill of health (CLAUDE.md's fourth way a gate cannot fail);
- self-test the dot-directory case. The existing fixture plants a synthetic
  crate in a tempdir and asserts files_scanned == 1, which is the right shape
  but cannot catch this, because `/var/folders/...` has no dot component. The
  new fixture plants the same tree under `.agentdir/` and asserts both the file
  count and the findings.

Measured before/after in a dot-named directory: before, "found 0" for every row
plus the --write-baseline instruction; after, 4056 files scanned, 393 inline
offsets and 14 reader helpers, exit 0.

CI was never affected — runners check out to /home/runner/work/perry/perry.
Diagnosis by the turnloop lane, which hit it in an agent worktree.
@coderabbitai

coderabbitai Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: f420aecf-e112-461c-95e1-c311e9a84143

📥 Commits

Reviewing files that changed from the base of the PR and between 2f85451 and 6c5b4f5.

📒 Files selected for processing (2)
  • changelog.d/11082-string-payload-scanner-dotdir.md
  • scripts/string_payload_access_inventory.py

Included review availability: Your plan provides up to 8 included reviews per hour; 1 remains after this review.


📝 Walkthrough

Walkthrough

The scanner now applies its path filter relative to the repository root. A self-test covers scanning under a dot-prefixed directory. The command exits with an error when it scans zero files.

Changes

Scanner behavior

Layer / File(s) Summary
Scan checkout-relative paths and reject empty inventories
scripts/string_payload_access_inventory.py, changelog.d/11082-string-payload-scanner-dotdir.md
The scanner filters repository-relative paths, and the self-test checks a checkout under a dot-prefixed directory. The command reports an error and exits with code 1 when it scans zero files. The changelog records these changes.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Low

Merge Risk: ⚪ Minimal · up to 6c5b4

The scanner fix is mergeable after normal checks; no outstanding risk is established.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 1 files. (1 skipped: 1 … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the string-payload scanner bug under dot-prefixed directories and its baseline risk. It is specific and related to the main change, though somewhat long.
Description check ✅ Passed The description explains the problem, its impact, the changes, and the reported self-test results. It is mostly complete, but it does not include a Related issue section or complete the template check…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 1 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@proggeramlug

Copy link
Copy Markdown
Contributor Author

Landed on main in merge train 260 (#11085), released as v0.5.1643 at d8f24f15ed.

Cherry-picked from this PR's head 6c5b4f5cdf and validated as one tree — CI 22/22 green, all 6 gap-suite shards. A train rebase gives the commits new SHAs, so GitHub cannot auto-close the source PR; closing by hand.

Nothing needed from you. Thanks.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant