fix(devx): the docs-frontmatter self-test refuses an unreadable extractor with exit 3 PREREQUISITE NOT MET - #15940
Merged
os-project-manager merged 4 commits intoSep 5, 2026
Conversation
…EQUISITE NOT MET frame Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016vtdMao3dQS9EfQfpyWixd
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016vtdMao3dQS9EfQfpyWixd
…c-frontmatter-prerequisite-refusal
…ctor with exit 3 PREREQUISITE NOT MET Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016vtdMao3dQS9EfQfpyWixd
os-project-manager
marked this pull request as ready for review
September 5, 2026 15:52
os-project-manager
enabled auto-merge
September 5, 2026 15:53
os-project-manager
deleted the
claude/issue-15835-doc-frontmatter-prerequisite-refusal
branch
September 5, 2026 16:22
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #15835
scripts/check-doc-frontmatter.mjs --self-testanswered an uninstalledapps/docswith exit 1 and, in its own words,the battery is the bug— a finding's exit code and a remedy that sends the reader hunting for a deleted case that was never deleted. Battery (7) resolves the docs build's own extractor fromapps/docs; with the dependency absent its one resolvability assertion failed, its other nine cases never registered, and the floor then fired on top of that. This brings the gate onto the convention its siblings already hold: exit 3PREREQUISITE NOT MET, raised through the shared frame inscripts/import-prerequisite.mjs.Before / after, same tree, same command
Root installed,
apps/docsnot — the card's own repro:The misleading half is gone from what it prints:
the battery is the bug,below its pinned floorandcases that used to run no longer doare all absent, and that absence is asserted, not just observed.This is a diagnosis change, not a verdict change — measured, not assumed
Every state, both legs, base vs head, on one worktree:
--self-testapps/docsabsentapps/docsabsent--self-test--self-testyaml)yaml)⇒ No case passes that previously failed, in either direction. And the row that moves is not reachable in CI at all: the
lintjob runspnpm install --frozen-lockfileover the whole workspace before it invokes this gate, so the guard is never entered there and CI's exit codes are byte-identical.Where the refusal sits, and why
At the top of
selfTest(), before the first case registers — the shapescripts/pm/check-governed-merges.mjslanded. The shared frame's clause "this gate exited before running a single check" is inherited verbatim by every importer, so a refusal raised beside battery (7), after six batteries had already judged, would make that sentence false in all of them at once. The price is named in the code: on an uninstalled local tree the other batteries no longer report their own findings. The run still fails either way.What is a prerequisite, and what deliberately is not
Only the two on-disk facts, read with the frame's OWN probes (
findPackageDir,entryPointOnDisk) rather than re-spelled here:fumadocs-coreis nowhere on the resolution path fromapps/docs→pnpm installpnpm installEverything else stays a finding at exit 1, judged by battery (7) as before: the package is whole and the subpath does not resolve (the build's extractor moved — exactly the drift battery (7) exists to catch), or it resolves and the import throws (a real defect in an installed dependency, which this gate has no standing to prescribe an install for). A manifest declaring no default entry is deferred, never guessed at.
What pins it
New battery
(11), floor 14 — and what is pinned is the printed refusal, never the exit code alone. A run that exited 3 while still printingthe battery is the bugwould satisfy a code-only assertion and leave the reader exactly where the card found them.nullfor this checkout, so batteries (1)–(10) are observed unaffected;nullfor a constructed tree that HAS the extractor — the control that an always-refusing probe would fail;node_modulespresent without the package / package present without its entry / manifest with no declared entry — four constructed roots, four distinct verdicts;apps/docs, spawned as a real process, asserted on the exit code and on the text (names the class, the prerequisite, the remedy, states that nothing was measured) and on the absence of the old diagnosis. The child is marked--fixture-childso it can never spawn one of its own.scripts/import-prerequisite.mjsis untouched — this card calls that frame, it does not edit it. Mergedorigin/mainafter #15911 landed (14:49:24Z), so the refusal is raised through the fixed frame; withyamlmet, no closure section is added, which is the designed behaviour.Verification
Run on the final head
425f2929, exit codes captured before any pipe.dispatch-gates --changed --commands: 32 families derived, 32 run, all exit 0;--ranreconciliation0 NOT-MEASURED, 0 UNRUN.pnpm lint(repo-wideeslint . --no-inline-config, no narrowing): exit 0.check-governed-merges.mjs --test scripts/check-doc-frontmatter.mjs: NOT governed — ordinary queue landing.git diff HEADempty). The uninstalled row returns to exit 1 withthe battery is the bug— the guard is load-bearing.Changeset: none,
skip-changesetapplied. The diff is one CI-internal gate script and publishes nothing from any package —lint.yml's own note calls "this PR edits a CI-internal script" the textbook case, and the two most recent sibling PRs on this family (#15862, #15911) landed the same way.Generated by Claude Code