Skip to content

Commit e890bed

Browse files
fix(scripts): ADR-0087 gate reads an any index signature (D8 p4) and a src/index.tsx entry (D9) (#26496)
<!-- claude-projects-attribution: {"github_login":"os-steve"} --> _Requested by **Steve** · [project thread](https://claude.ai/code/project/chan_01FdL1XeUyvVNxLreh3F4Qi9?thread=cmsg_01FdL1XeUyvVNxLreh3F4Qi9Ex6pB8edHJLnCCc1tgdXz5)_ Part of #26220 (PR 2 of 2 for parts 3 and 4: the gate code for the ADR-0087 amendment that landed in #26455). Clause-②: no Metadata-protocol: none ## What changes `scripts/check-adr-0087-registration.mjs` only (+288 / −11). - **Part 3: predicate 4 reads an `any` index signature (D8, amended).** When the base surface is concrete, a bare `<path>#<Symbol>` naming an exported `interface`, or a `type` alias whose right-hand side is one object type literal, now goes through `indexSignatureLimb`. The limb holds when all three hold: (1) at the merge base an index signature's value type is `any`; (2) at HEAD at least one of those carries another value type, with `unknown` counted as narrowed here only; (3) the kind, the heritage (type parameters, `extends`) and every member are identical position by position on the comment-masked, normalised surface. Only the value types of base-`any` index signatures are set aside, so a re-typed non-`any` index signature is a moved member, which reads no wider than the ADR text. A dotted member path does not reach the limb. When the limb fails, the existing #6048 refusal now also prints why the limb did not hold, e.g. "the member count moved (2 -> 1)". - **Part 4: the D9 entry may be `src/index.tsx`.** `sourceEntryAt` maps `dist/index.d.ts` (or its twin) to the package's one source entry, `src/index.ts` or `src/index.tsx` (`SOURCE_ENTRY_NAMES`). Both present is refused as AMBIGUOUS by name. Neither present is refused as unmappable, as before. The build tool is never read. - New helpers, exported for the unit pins: `structuralDeclarationParts`, `readIndexSignature`, `indexSignatureLimb`. The member splitter does not treat the `>` of `=>` as a closer, so a nested literal's index signature is never read as a top-level one. ## Battery rows New battery `IX (#26220): predicate 4 reads an any index signature; the entry may be src/index.tsx`, 52 cases, roster floor 56 → 57: - Predicate 4, green: IX-G1 #26293's shape (`[key: string]: any` → `unknown` on a generic interface; the verdict names both sides) and IX-G2 an object-literal alias with a `readonly` index signature narrowed to `string`. - Predicate 4, red, each with predicate 4's FALSE refusal and the limb's reason: - R1 a member removed beside the narrowed signature (the #6048 class); - R2 a member re-typed; - R3 a member made optional; - R4 a type-parameter default changed; - R5 an `extends` added; - R6 a non-`any` base signature re-typed; - R7 a base signature typed `unknown`; - R8 still `any` at HEAD; - R9 the signature's key changed; - R10 an intersection alias; - R11 a nested `any` signature behind an `=>`; - R12 a dotted path. - Units: IX-U1–U4 (the index-signature reader, mapped and computed names refused, the compared parts, and the #6048 shape failing the limb). - D9: IX-T1 a `src/index.tsx`-only package retires an export (green; the verdict names `Gone.tsx`). IX-T2 both entries present is red as ambiguous; its `.ts` twin exports the same names, so only the refusal holds it red. IX-T3 neither entry is red as unmappable. ## Ablations One-time, on the committed fix, each restored with `git checkout HEAD --` (blob hash re-checked): | ablation | failures | turns red | | --- | --- | --- | | limb call off | 3 | IX-G1, G1b, G2 | | `=>` guard off in the splitter | 3 | IX-R11 goes green | | set aside every index signature, not only base-`any` | 6 | IX-R6, R7 go green | | heritage comparison off | 6 | IX-R4, R5 go green | | `src/index.tsx` dropped from the entry names | 4 | IX-T1, T1b, T2 | | ambiguity refusal off | 3 | IX-T2 goes green | | dotted exclusion off | 1 | IX-R12's message; it stays red because the limb reads no member path, so the exclusion is a stated guard rather than the only one | ## Proof on the held PRs With this branch's gate, `--base origin/main --head <their head>`: - **#26293 at `e349c832`: exit 0.** The verdict is `ui/packages/types/src/base.ts#ComponentRendererProps ([key: string]: any -> [key: string]: unknown)`. Main's gate refuses it at predicate 4. - **#26365 at `20d75f11`: exit 1, on a refusal the amendment does not cover.** Main's gate refused all three operands at the MERGE BASE as unmappable (`src/index.tsx`). With this branch the base side maps and reads. The new refusal is at HEAD: "no workspace manifest at … is named `@object-ui/plugin-ai`". #26365 deletes the whole package, and D9 predicate 1 reads "absent at HEAD" through a Program over the package's entry at each rev, which a deleted package does not have. Admitting a whole-package removal needs its own D9 wording (Tier H). Seat 1 has put that choice to the maintainer, and it is not in this PR. ## Tests and gates - `node scripts/check-adr-0087-registration.mjs --self-test`: exit 0, "627 assertions over real temp git repos" (575 before this branch). - `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack`: 34 commands derived at this head (base `d0a7e748`). All 34 exit 0, including `--base origin/main` and `--self-test` of this gate, `check-scripts-symbol-anchors`, `check-declaration-mirrors`, `check-self-test-wired`, `pnpm check:changeset-gate-self-tests` and `pnpm check:pm-dispatch-gates`. `--ran`: 34 derived, 34 run, 0 NOT-MEASURED, 0 UNRUN. - No package is touched, so there is no build closure and no changeset (`skip-changeset`). ## Acceptance notes - Part 3 and part 4 follow the amendment text of #26455 line by line. The one place this code reads narrower than the text is condition 3: only base-`any` index signatures have their value types set aside, so a non-`any` one that changes is a re-typed member. This is stated in the function's comment and pinned by IX-R6 and its ablation. - #26324 (predicate 2 cannot certify an operand named `default`) is a separate card and is not addressed here. --- 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01Am8eYNReiNP66D2JihPS1q Co-authored-by: Claude <noreply@anthropic.com>
1 parent 73683ee commit e890bed

1 file changed

Lines changed: 288 additions & 11 deletions

File tree

0 commit comments

Comments
 (0)