+ "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."
0 commit comments