Skip to content

fix(devx): the two corpus walkers skip .cache/, so a console pin bump no longer reds on objectui's files - #15596

Merged
baozhoutao merged 2 commits into
mainfrom
claude/issue-15557-corpus-walkers-skip-cache
Sep 4, 2026
Merged

fix(devx): the two corpus walkers skip .cache/, so a console pin bump no longer reds on objectui's files#15596
baozhoutao merged 2 commits into
mainfrom
claude/issue-15557-corpus-walkers-skip-cache

Conversation

@claude

@claude claude Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Fixes #15557

scripts/build-console.sh materialises objectui at the pinned SHA into .cache/objectui-SHA/ — a whole foreign checkout, gitignored (.gitignore), that every console pin bump MUST create because the console cannot be built without it. Both repo-wide corpus walkers descended into it, so a pin bump read two reds against objectui's files, and one of them told the operator to go and pin a shape in this repo's masker.

Direction 1 of the card, per the dispatch ruling: both walkers add .cache to the directory-name skip set they already keep — the node_modules class, "not our source". .gitignore-honouring (direction 2) is a wider contract change and is not attempted here.

Premise re-measured on a fresh origin/main tree

.cache/ was absent on this container, so the behaviour was reproduced by planting one: .cache/objectui-probe/{AGENTS.md, apps/console/src/pages/Probe.tsx, package.json}, the three shapes a real build worktree carries. Same tree, same commit, nothing else changed between the columns; the probe was deleted before the commit and git status is clean.

walk no .cache planted .cache, before the fix planted .cache, after the fix
collectSources() (comment-mask corpus) 5961 files 5962 (1 under .cache) 5961 (0 under .cache)
scannedFiles() (agent-test-spelling) 450 files 451, incl. .cache/objectui-probe/AGENTS.md 450 (0 under .cache)
deriveVitestScripts() (same gate, second walk) 81 manifests, 5 names 82 manifests, 6 names — the foreign test:probe-only entered the derived set 81 manifests, 5 names
pnpm check:agent-test-spelling exit 0 exit 1.cache/objectui-probe/AGENTS.md:3 exit 0

The premise holds, and the measurement found one consequence the card did not name: deriveVitestScripts walks the same tree, so a foreign package's script names silently widened the set of names this gate judges in our own corpus — a false-red channel in the opposite direction from the one that was reported.

The controls — both directions, in each gate's own fixture

Each --self-test now plants the SAME BYTES inside and outside .cache/ on a real temp tree, so the only variable is location and the exclusion cannot become a mute button:

  • check-comment-mask-corpussrc/probe.tsx and .cache/objectui-pin/src/probe.tsx, identical, against a masker that disagrees with the parser on them. The copy outside is collected and reds; the copy inside never enters the corpus; and the same bytes, compared directly with compareFile, still disagree — so the exclusion is by location, not because those bytes happen to agree. 5 cases; the single battery's floor moves 12 → 17.
  • check-agent-test-spelling — objectui's own instruction (pnpm --filter PKG test -- --run) in an AGENTS.md under .cache/objectui-pin/, plus a foreign manifest. Sweep is CLEAN, the walk never reaches the file, the manifest does not widen the derivation; the identical text one directory higher (vendor/objectui-pin/AGENTS.md) still reds and the finding names it. 5 cases in a new battery; SELF_TEST_BATTERY_FLOOR 12 → 13.

Ablation, trap-guarded, one set at a time, mutation confirmed on disk by anchor grep counts and restore proved by blob hash:

ablation mutation on disk result restore
drop '.cache' from SKIPPED_DIRECTORIES entry-present 1 → 0, ablated form 1 --self-test exit 1, 3/17 self-test case(s) failed — the three new walk cases git diff HEAD empty; blob a2e698b9 = HEAD blob
drop '.cache' from SKIP_DIRS entry-present 1 → 0, ablated form 1 --self-test exit 1, ✗ check-agent-test-spelling --self-test -- 3 failure(s) — the three new .cache cases git diff HEAD empty; blob b028549f = HEAD blob

Neither gate is built: node runs scripts/*.mjs from source, so there is no dist/ leg to prove for either ablation.

Importer census — who else reads these sets

SKIPPED_DIRECTORIES is exported, so every importer was enumerated: git grep over scripts/, packages/, apps/ for SKIPPED_DIRECTORIES / CORPUS_FLOOR / collectSources returns no importer of this module's set — the other collectSources hits are unrelated local definitions (check-react-page-adapter-contract, tenant-audit-census, isystem-census, one plugin test). SKIP_DIRS is module-local and not exported. 43 scripts keep a private skip set of their own; no gate asserts agreement between them, and check-skill-identifier-liveness pins only its OWN set's contents. Independent evidence that no cross-walker parity gate exists: .git is already in SKIPPED_DIRECTORIES and already absent from the list js-comment-mask.mjs's header quotes, and main is green.

js-comment-mask.mjs's header quotes six directories as part of the 2026-08-21 measurement it records. That file is untouched (its PR is live); the corpus gate's own doc comment now says which of the two is the instrument and which is the history, so the claim it makes is true as written.

scripts/pm/dispatch-gates.mjs is untouched. Both new fixture path literals sit inside runSelfTestCases, which COMPOUND_ANCHOR_LEDGER already classifies (['scripts/check-comment-mask-corpus.mjs', 'runSelfTestCases', false]), so they are masked from hint extraction; check:pm-dispatch-gates is green.

Verification — all at 4eaa5de8f (merge of origin/main into this branch), exit codes captured before any pipe

command exit verdict line
node scripts/check-comment-mask-corpus.mjs --self-test 0 All 17 self-test cases passed.
node scripts/check-comment-mask-corpus.mjs 0 ✓ comment-mask corpus sweep [scripts/js-comment-mask.mjs]: 5961 files, 0 disagree, 0 unparseable, 66.7s (comparator self-test: 17 cases pass).
pnpm check:agent-test-spelling 0 ✓ check-agent-test-spelling: 0 violations — 450 file(s) · 6331 bare -- token(s) · 1454 launcher-rooted run(s) · 9 separator(s) JUDGED · 5 vitest-backed script name(s) derived from 81 manifest(s)
pnpm check:pm-dispatch-gates 0 ✓ dispatch-gates self-test: 1445 cases pass. (no case edited; the dispatch expected 1415 — the merge of origin/main raised it)
pnpm check:nul-bytes 0 check-nul-bytes: OK (scanned 7557 text file(s) … no raw ASCII control bytes)
pnpm check:watch-hint-literal 0 56 declaration(s) across 4 rostered name(s) … no unrostered spelling of the idiom in the tree
the other 18 commands of the derived family 0 each

The family is node scripts/pm/dispatch-gates.mjs --changed --commands --repo objectstack-ai/objectstack (exit 0, 24 commands, --repo … checked against this checkout's 'origin' remote — it holds), re-derived after merging origin/main: the first derivation warned ⚠️ STALE TREE and named scripts/pm/dispatch-gates.mjs itself as changed in that range. The post-merge list is byte-identical, and every one of the 24 commands was run. Nothing NOT MEASURED: no exit 3, no PREREQUISITE NOT MET, no ERR_MODULE_NOT_FOUND.

Neither edited script has a vitest suite — their tests ARE their --self-test, both of which were run and both of which served as the ablation instrument. The one file in the tree naming check-comment-mask-corpus.mjs in a test (packages/client/src/envelope-caller-census.test.ts) references it in prose only.

Lint: a declared narrowing, not a whole-repo run. eslint --no-inline-config over the two edited files: exit 0, and --format json reports 2 files, 0 errors, 0 warnings. The population is eslint's own flat config (both files matched it and were linted rather than ignored), and the config cannot move a verdict on any untouched file because this repo runs one eslint.config.mjs which "never enables type-aware linting (no parserOptions.project, no typed @typescript-eslint rules) for ANY file" — its own words, at eslint.config.mjs:326. CI runs the farm regardless.

No changeset: scripts/** only, nothing published from any package — skip-changeset applied and read back.

🤖 Generated with Claude Code

https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk


Generated by Claude Code

… no longer reds on objectui's files (#15557)

`scripts/build-console.sh` materialises objectui at the pinned SHA into
`.cache/objectui-<sha>/` -- a whole foreign checkout, gitignored, that every
console pin bump must create. Both repo-wide corpus walkers descended into it:
`check-comment-mask-corpus` judged objectui's sources against this repo's
masker and told the operator to pin a shape in `js-comment-mask.mjs`, and
`check-agent-test-spelling` red on objectui's own AGENTS.md while its
`deriveVitestScripts` walk let a foreign manifest widen the script names it
judges here. CI never saw either, because the lint job does not build the
console.

Both walkers now carry `.cache` in the directory skip set they already keep,
next to `node_modules` -- the same "not our source" class. Each self-test gains
a control that plants the SAME BYTES inside and outside `.cache/` on a real
temp tree: the copy inside never enters the corpus, the copy outside still
reds, so the exclusion cannot become a mute button.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
@claude claude Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 4, 2026
@github-actions github-actions Bot added the size/m label Sep 4, 2026
@claude

claude Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

ACCEPT — PM seat domain:devx @ objectstack (#6023), session session_012zGPuVVX3deAx9LdjK8jCk.

Reviewed against the three-dot diff origin/main...claude/issue-15557-corpus-walkers-skip-cache (head 4eaa5de8f, a merge of origin/main over 39227a876; two files, +113/−9), not the self-report. Direction 1 as ruled.

  • check-comment-mask-corpus.mjs: SKIPPED_DIRECTORIES gains '.cache'; self-test 12 → 17 with a temp fixture tree carrying the SAME planted source outside and under .cache/: the walk collects the outside copy only, the sweep judges exactly one file and reds on it, and compareFile shows the .cache copy would have disagreed had it been walked — both directions, no roster.
  • check-agent-test-spelling.mjs: SKIP_DIRS gains '.cache'; a new 5-case battery (floor 12 → 13): a planted .cache/objectui-pin/{AGENTS.md,package.json} leaves the sweep CLEAN, the walk never reaches it, and its manifest does not widen the derived vitest-script set; the same bytes under vendor/ still RED and are named. The manifest-derivation leak (a foreign package's script names entering the judged set, 81 → 82 manifests) is a consequence the card did not name — found by the premise measurement and covered by the same line.
  • No other file touched; no gate pins these sets or asserts agreement across walkers (importer census in the PR body).

Dev's verification quoted (on 4eaa5de8f): premise re-measured by planting the three shapes (.cache absent on this container) — 5961 → 5962 → 5961 files, 450 → 451 → 450, 81/5 → 82/6 → 81/5 manifests/names, the spelling gate exit 0 → 1 → 0 with the plant still present; --self-test All 17 self-test cases passed. / corpus sweep 5961 files, 0 disagree, 0 unparseable; check:agent-test-spelling 0 violations … 450 file(s); one-set-at-a-time ablations each red their three new cases, restores by blob (a2e698b9, b028549f) with empty git diff HEAD; derived family 24 commands re-derived after merging main, all exit 0 (dispatch-gates self-test: 1445 cases pass. — main's count after #15570); NOT MEASURED none.

Flipping ready + enabling auto-merge (MCP rate-limited since ~22:45Z — retried each tick with #15590, #15593, #15595). Fixes #15557.


Generated by Claude Code

@baozhoutao
baozhoutao marked this pull request as ready for review September 4, 2026 23:17
@baozhoutao
baozhoutao enabled auto-merge September 4, 2026 23:17
@baozhoutao
baozhoutao added this pull request to the merge queue Sep 4, 2026
Merged via the queue into main with commit 4e4d79d Sep 4, 2026
36 checks passed
@baozhoutao
baozhoutao deleted the claude/issue-15557-corpus-walkers-skip-cache branch September 4, 2026 23:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants