Skip to content

Commit a77e460

Browse files
authored
fix(scripts): ADR-0087 runtime-interface-only reads CODE, not docblock prose (#12881) (#12997)
* fix(scripts): ADR-0087 runtime-interface-only reads CODE, not docblock prose (#12881) Step 4 of the `runtime-interface-only` predicate scanned whole metadata-surface files for the claimed symbol, so a JSDoc sentence naming a runtime type counted as an unresolvable reference and refused the disposition. Measured: the only `.zod.ts` in the tree naming `ObjectStackClient` is contract.zod.ts, which explains what `unwrapResponse` keys on in one docblock line. Mask comment spans with the shared scripts/js-comment-mask.mjs before every read step 4 performs. Strings stay unmasked on purpose. Self-test gains both directions: RIO-G2/G3/G4 (prose, line comment, commented-out import) and RIO-R10/R11/R12 (prose beside a code reference, beside a real import, and a string literal), plus RIO-R3 converted to a code-level mention. * docs(scripts): record the step-4 code-not-prose rule on the ADR-0087 anchor (#12881) * fix(scripts): stage js-comment-mask.mjs into the fw-gate sandbox (#12881) The digest self-test stages an executable COPY of check-adr-0087-registration.mjs into a throwaway repo and runs it. That gate gained a ./js-comment-mask.mjs import, which the sandbox manifest did not copy, so both #6494 ROUND TRIP cases died on ERR_MODULE_NOT_FOUND and read as a broken round trip. Fix the manifest, not the import: the single hard-coded invoked-as.mjs line becomes a list, matching how the gate's own I1/I2 fixture spells it.
1 parent 4d25d22 commit a77e460

3 files changed

Lines changed: 215 additions & 21 deletions

File tree

‎scripts/adr-anchors/scripts__check-adr-0087-registration.mjs.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
"adrs": [
44
"ADR-0087"
55
],
6-
"invariant": "This gate enforces ADR-0087's changeset disposition: every changeset a PR newly declares breaking must carry exactly one `<!-- adr-0087: ... -->` marker, and every `not-required` category is RE-VERIFIED on every run — an allow-list nobody re-checks is the failure mode the whole mechanism exists to avoid. `CATEGORIES` is closed and is pinned to ADR-0087's addendum of 2026-08-13 in BOTH directions by `assertInputs`: a category the gate accepts and the ADR never describes is an exemption an author cannot look up; a category the ADR describes and the gate rejects is one nobody can claim (#8299). `runtime-interface-only` is a NARROWING of `no-migration-prescription`, never a fifth way around it — it inherits that refusal, and it names symbols as `<path>#<Symbol>` because a bare name is not a symbol identity here (`PackagePublishResult` is two unrelated symbols: the service interface PR #8277 changed, and a Zod projection in `packages/spec`). Never widen the exemptions here without the ADR half in the same PR, and never let this gate infer WHICH symbols a PR touched — that is the cross-package retirement detector the maintainer ruling of 2026-08-07 deliberately routes around."
6+
"invariant": "This gate enforces ADR-0087's changeset disposition: every changeset a PR newly declares breaking must carry exactly one `<!-- adr-0087: ... -->` marker, and every `not-required` category is RE-VERIFIED on every run — an allow-list nobody re-checks is the failure mode the whole mechanism exists to avoid. `CATEGORIES` is closed and is pinned to ADR-0087's addendum of 2026-08-13 in BOTH directions by `assertInputs`: a category the gate accepts and the ADR never describes is an exemption an author cannot look up; a category the ADR describes and the gate rejects is one nobody can claim (#8299). `runtime-interface-only` is a NARROWING of `no-migration-prescription`, never a fifth way around it — it inherits that refusal, and it names symbols as `<path>#<Symbol>` because a bare name is not a symbol identity here (`PackagePublishResult` is two unrelated symbols: the service interface PR #8277 changed, and a Zod projection in `packages/spec`). Its step-4 reference scan reads CODE, not prose: comment spans are masked through the shared `scripts/js-comment-mask.mjs` before every read that step performs, because a docblock naming a runtime type puts nothing in a schema and gives `objectstack migrate meta` nothing to reach — counting one refused an honest, steps-1-to-3-clean claim and pushed the author toward a dishonest `no-migration-prescription`, which is the #8299 anti-pattern arriving through the door #8299 built (#12881). String literals are deliberately NOT masked; widening this to `comment || literal` is a change of the refusal posture (#4690) and needs arguing, not slipping in. Never widen the exemptions here without the ADR half in the same PR, and never let this gate infer WHICH symbols a PR touched — that is the cross-package retirement detector the maintainer ruling of 2026-08-07 deliberately routes around."
77
}

0 commit comments

Comments
 (0)