Skip to content

docs/emitters: naming's stable-name promise needs the prior manifest #583

Closed

Description

@OmarAlJarrah

Problem

docs/emitters/refine/naming.md promises: "Collisions are resolved deterministically in Ctx.Syms, which is keyed by IR ID: adding one endpoint never renames an existing method." The mechanism it names does not deliver that promise. Keying by ID and being deterministic are both necessary but neither is sufficient: a function of the current document alone cannot tell which of two colliding operations shipped first.

Cloudflare's Forge is a working counterexample: packages/forge/shared/sdk-method-names.ts at cloudflare/forge@00b8ede. Its renamer is deterministic, order-independent (it renames every member of a collision from that member's own identity) and keyed by operationId, so it has every property docs/emitters/refine/naming.md names. Run it on two revisions of one group:

Revision Operations in group zones with method name get Resulting names
v1 zones-get-zone get
v2 zones-get-zone, zones-get-zone-settings zonesGetZone, zonesGetZoneSettings

Adding one endpoint renamed the method v1 shipped, which is a breaking SDK change. Reversing the input order gives the same v2 names, so the renamer is order-independent and still breaks the shipped name. Any rule that looks only at the current document can resolve such a collision against the incumbent, whether it renames every member, orders by ID or orders by name. The only question is how often it happens.

What would deliver the promise

The incumbent has to be known, and only the prior generation knows it. docs/emitters/write-integrate.md already designs a prior manifest (EmitterInput.Prior, keyed by IR ID) for write/integrate. Collision resolution could consume it: a symbol the prior manifest assigns keeps its name, and only symbols new in this generation are disambiguated. Output stays a pure function of the inputs, because the prior manifest is an explicit input.

Two limits should be stated beside the fix:

Acceptance

  • docs/emitters/refine/naming.md names the mechanism that backs the promise (the prior manifest), or narrows the promise to what ID-keying alone guarantees.
  • The mandatory tests (docs/emitters/testing/mandatory-tests.md) gain a case: generate v1, add a colliding endpoint, regenerate against v1's manifest, and assert the v1 symbol is unchanged.

Activity

  1. OmarAlJarrah commented on Sep 30, 2026

    @OmarAlJarrah
    MemberAuthor

    A constraint on the fix: pin a prior symbol only when the IR ID and a key that survives reordering agree (#679). Where an ID contains an array index, the same ID can name a different entity in the next revision (#678); pinning by ID alone would give the new entity the old one's name. Pin only the disambiguation choice: a changed natural name, such as a renamed operationId, should still rename.

  2. added
    priority:P2Rarer spec shapes, or an IR decision to settle before the emitter
    on Oct 19, 2026
  3. changed the title [-]docs/emitter-design: §4.12's stable-name promise needs the prior manifest[/-] [+]docs/emitters: naming's stable-name promise needs the prior manifest[/+] on Nov 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    priority:P2Rarer spec shapes, or an IR decision to settle before the emittertype:docsDocumentation only

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions