Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions docs/adr/0087-metadata-protocol-upgrade-contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,7 @@ gate's log and its `--list` output.
<!-- adr-0087: not-required (no-migration-prescription) <why> -->
<!-- adr-0087: not-required (runtime-interface-only <path>#<Symbol>[, ...]) <why> -->
<!-- adr-0087: not-required (type-surface-only <path>#<Symbol>[, ...]) <why> -->
<!-- adr-0087: not-required (type-surface-only <path>#<a>.<b>.<member>[, ...]) <why> -->
```

**The vocabulary is closed, and every exemption is re-verified on every run** — an
Expand Down Expand Up @@ -676,6 +677,7 @@ The vocabulary above gained a sixth answer:

```text
<!-- adr-0087: not-required (type-surface-only <path>#<Symbol>[, ...]) <why> -->
<!-- adr-0087: not-required (type-surface-only <path>#<a>.<b>.<member>[, ...]) <why> -->
```

### The dead end it closes
Expand Down Expand Up @@ -748,6 +750,23 @@ checks all four by name (`published`, `no-spec-diff`, `no-metadata-surface-diff`
*both* revs and requires `any` / `unknown` / no annotation at base, and a
concrete type at HEAD.

⭐ **The reference is a bare symbol OR a dotted member path.** `<path>#<Symbol>`
resolves a bare name to the **first same-named definition in the file**, and on a
real SDK module that is not a symbol identity: `packages/client/src/index.ts`
declares `get` 14 times and `delete` 10 times, so the members PR #15445 and PR
#15451 actually narrowed had **no addressable spelling at all** — the category
was closed to them by the grammar rather than by any judgement about the claim,
and the gate answered a true sentence about a member the diff never touched
(#15627). A reference may therefore also be written `<path>#<a>.<b>.<member>`:
the object-literal nesting the member sits in, walked **structurally** from the
top of the file over a comment- and literal-masked projection, with the member's
definition taken from inside the resolved body. Bare references keep their exact
previous meaning. ⛔ A line number is never the disambiguator — this file's line
numbers were measured to rot within one day. A dotted path that resolves to
**zero** candidates, or to **more than one**, is reported by name and refused,
never guessed at: a reference that silently landed on the wrong same-named member
would be writable but wrong, which is worse than the refusal it replaces.

### ⭐ Predicate 4 is what makes this a narrowing rather than a hole

This is the **only** category exempt from the `no-migration-prescription` refusal.
Expand Down
Loading
Loading