You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
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
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 on main at 68ca346:
Axis 1 — two other TypeScript parse entry points, both inside scripts/**
Neither is covered by scripts/ts-parse.mjs, and both are named in check-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 through getSyntacticDiagnostics(), a different API. Nothing reads it.
scripts/check-where-matcher-conformance.mjs:481 — ts.transpileModule(code, { ... }). It reports nothing at all unless reportDiagnostics: true is passed, so it is the quietest of the three.
Axis 2 — every parse outside scripts/**
These cannot import the root scripts/ts-parse.mjs for the reason invoked-as.mjs gives about its own packages/cli sibling: scripts/ runs as plain .mjs against 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.
The two try/catch wrappers are worth naming separately. They are dead code today — createSourceFile cannot throw — but they are written as continue / 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.mjs into packages/. 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)
Folded 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. Session session_01DdCnBGcHeufjrq7drTD3wt, branch claude/issue-10574-wire-parse-guard. The PR will close both.
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.
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.mjs gains createProgramChecked (checks getSyntacticDiagnostics() 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) and transpileChecked (reportDiagnostics: true forced, deliberately not a parameter). check-published-readme-exports.mjs:836 and check-where-matcher-conformance.mjs:493 are converted, and check-parse-guard.mjs now 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/catch wrappers this card named (both verified still present, verbatim), and four options with a recommendation.
Two corrections to this card's table, both measured on main at d5e7b9f5a1:
check-skill-examples.ts has 1createSourceFile site (:308), not 2 — the second was :692, a comment naming ts.createProgram, which the gate masks. This is precisely why the gate masks prose.
the four ts.createProgram sites in packages/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 calls getSyntacticDiagnostics(). 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) and check-where-matcher-conformance.mjs:481 → :482.
Activity
claude commentedon Aug 21, 2026
Folded 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
os-zhuang commentedon Aug 21, 2026
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
fix(devx): wire check:parse-guard into CI, and widen it to all three …
os-zhuang commentedon 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.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
fix(devx): wire check:parse-guard into CI, and widen it to all three …