Repository navigation
[finding] The parse-error blind spot is wider than scripts/ts-parse.mjs closed — ts.createProgram, ts.transpileModule, and 10 sites in packages/ #10575
Description
Activity
claude commented
on Aug 21, 2026 claudeboton Aug 21, 2026 – with ClaudeContributorAuthorMore actionsFolded into #10574 for implementation this round — #10574 wires the guard that exists, this card is the same axis widened, and
check-parse-guard.mjs's own header already names these as deliberately-not-covered so the two must move together or the header's scope claim goes stale. Sessionsession_01DdCnBGcHeufjrq7drTD3wt, branchclaude/issue-10574-wire-parse-guard. The PR will close both.
Generated by Claude Code
Triage (half-state heal + grading ratified): removed
finding— the card is dispatched in flight, and a card cannot be both awaiting-first-grade and dispatched. Promotion ratified (measured blind-spot census over a gate family). No other labels touched.
Generated by Claude Code
- added a commit that references this issue
on Aug 21, 2026 Implemented as part of the folded round — draft PR #10612 closes this card together with #10574. Full structured report is on #10574 (comment marked
os-dev-report).What landed here, and what did not:
Axis 1 — taken fully.
ts-parse.mjsgainscreateProgramChecked(checksgetSyntacticDiagnostics()over every file the Program pulled in, not just the roots — a Program's answers are transitive, pinned by a case whose root parses and whose import does not) andtranspileChecked(reportDiagnostics: trueforced, deliberately not a parameter).check-published-readme-exports.mjs:836andcheck-where-matcher-conformance.mjs:493are converted, andcheck-parse-guard.mjsnow fails on all three raw spellings, so the header's scope caveat is a bound the file computes rather than a sentence.Axis 2 — counted, not built. No cross-tree helper. The out-of-tree population is walked, counted and named on every run: 28 parses in 20 files, 13 in shipped/gate code and 15 in tests. Deliberately not a ratchet. The shape decision is #10606, which carries the measurement, the two
try/catchwrappers this card named (both verified still present, verbatim), and four options with a recommendation.Two corrections to this card's table, both measured on
mainatd5e7b9f5a1:check-skill-examples.tshas 1createSourceFilesite (:308), not 2 — the second was:692, a comment namingts.createProgram, which the gate masks. This is precisely why the gate masks prose.- the four
ts.createProgramsites inpackages/spec/scripts/**were missed entirely:build-api-surface.ts:110,build-export-origins.ts:232,check-dual-source-exports.ts:154,check-exported-any.ts:186. Two of them are gates, and none of the four callsgetSyntacticDiagnostics(). So Axis 2 is 13 shipped/gate sites, not 10.
Line numbers in this card had also drifted:
check-published-readme-exports.mjs:775 → :830(moved by #10596) andcheck-where-matcher-conformance.mjs:481 → :482.Generated by Claude Code
Generated by Claude Code
- added a commit that references this issue
on Aug 23, 2026
Filed while implementing #10133. Nothing is red today — same framing as the parent card, and for the same reason.
#10133 closed one parser (
ts.createSourceFile) in one tree (scripts/**). The class is wider on both axes, measured onmainat 68ca346:Axis 1 — two other TypeScript parse entry points, both inside
scripts/**Neither is covered by
scripts/ts-parse.mjs, and both are named incheck-parse-guard.mjs's header as deliberately not covered so its green line does not over-claim:scripts/check-published-readme-exports.mjs:775—ts.createProgram([...absEntries], TS_OPTIONS). A Program reports syntax throughgetSyntacticDiagnostics(), a different API. Nothing reads it.scripts/check-where-matcher-conformance.mjs:481—ts.transpileModule(code, { ... }). It reports nothing at all unlessreportDiagnostics: trueis passed, so it is the quietest of the three.Axis 2 — every parse outside
scripts/**These cannot import the root
scripts/ts-parse.mjsfor the reasoninvoked-as.mjsgives about its ownpackages/clisibling:scripts/runs as plain.mjsagainst a possibly unbuilt tree, and making a published package depend on repo tooling to answer "did this parse?" trades one bug for a worse one. So this needs a decision about shape, not a copy of the helper.packages/lint/src/validate-react-page-props.tstry { ... } catch { continue; }packages/lint/src/lint-startup-registry-verdict.tstry { ... } catch { return []; }packages/lint/src/validate-hook-body-writes.tssetParentNodes: falsepackages/lint/scripts/check-doc-formula-expressions.mjspackages/spec/scripts/check-skill-examples.tspackages/spec/scripts/lib/strictness-ledger.tspackages/cli/src/utils/detect-free-identifiers.tsThe two
try/catchwrappers are worth naming separately. They are dead code today —createSourceFilecannot throw — but they are written ascontinue/return [], so the moment a parse did throw they would become a silent skip rather than a loud failure. That is the same defect this class is about, pre-installed.validate-react-page-props.ts's own comment says "the syntax gate reports unparseable sources", which is a claim worth verifying rather than inheriting.What this is not
Not a request to copy
ts-parse.mjsintopackages/. The decision a card here has to make is whether the package-side lint validators want the same refusal semantics at all:scripts/**gates audit a tree the author controls, while a publish-time lint validator is handed metadata by an author and may legitimately want to report an unparseable source rather than abort the process. Those are different contracts and the answer may differ per row above.Refs: #10133 (the parent class,
scripts/**half) · #10573 (the implementation and its measurements)Generated by Claude Code