Repository navigation
docs(emitters): define what a generation keeps for the next one - #1336
Open
OmarAlJarrah wants to merge 7 commits into
Open
OmarAlJarrah wants to merge 7 commits into
OmarAlJarrah wants to merge 7 commits into
Conversation
The manifest recorded hashes, a file list and the entity-to-symbol map, too little for a regeneration to honor what the last one did: an edited generated file was overwritten, a no-op rewrote every file, a reformatted spec looked new, and keep regions were found by path. The manifest now records the document's digest instead of the spec's, a normalized digest per written file, the options version, the steps that ran, files written once, each entity's correlation key, base name and symbol, and each keep region by its entity, under a schema version migrated forward. Regions follow their entity to its new file. Every ID-keyed input that matches nothing is reported with its likely new home. A README is merged as blocks the user writes around. Collisions now read the prior manifest: a shipped symbol keeps its name while its ID and correlation key agree, and only newcomers take a suffix, so adding an endpoint renames nothing. The prior manifest joins the inputs the purity rule names. A spike at Go 1.27.3 chose dst for the Go merge adapter: go/ast nodes moved between files lost their doc comments, one into a function body, while dst and a text splice were both correct, and only dst reaches inside a declaration. Claims that IDs survive any rename are narrowed to renames that keep the pointer.
2 of 3 tasks
…ts' into docs/emitters-generations
Collision resolution now keeps the names the prior generation shipped, read from its manifest, but the refiner context carried no prior state, so the naming step had nothing to read it from. Ctx.Prior carries the PriorState the emitter is given.
…ts' into docs/emitters-generations
This was referenced Nov 2, 2026
…ts' into docs/emitters-generations
…ts' into docs/emitters-generations
…ts' into docs/emitters-generations
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
What one generation has to leave for the next, so that a regeneration honors what was shipped and edited. These issues are one contract, the generation manifest, and the rename claims they all rest on, so they land together.
What the manifest records (#713) (
docs/emitters/write-integrate.md#what-the-manifest-records):sourcesleft out, the digestPlan.Versionalready takes, so reformatting or moving a spec is no new generation.\nline endings, trailing newlines dropped). A file with the header whose bytes no longer match was edited outside its regions, and is reported, never overwritten.Regions follow their entity (#714). A keep region belongs to the entity it sits in or follows, and is recorded by ID, correlation key and name. When a rename moves the entity to another file, the region moves with it. A region whose entity is gone is reported and its file kept. A merge mode beyond additive would take standard three-way merge semantics, never one of its own.
A key that matches nothing (#716). A hint, a runtime-policy override, a naming overlay or an overlay whose key no entity has draws
emitters/unmatched-key. The warning names the entity whose correlation key matches, as the likely new home. It never aborts a run. The runtime-policy and hint documents from #1332 now point at this one rule.Shipped names (#583) (
docs/emitters/refine/naming.md#collisions-and-the-names-a-generation-shipped).operationIdstill renames. An ID alone pins nothing (ir: an ID derived from an array index names a different entity after the array changes #678), as the issue's comment required.Prior, which it omitted although names now read it.README blocks (#705). The docs emitter returns sections as blocks with stable IDs between markers. Integration replaces only those blocks: text outside them is kept byte for byte, frozen blocks are kept, removals are reported, and the table of contents is rebuilt last from the merged file's headings.
The Go merge adapter uses
dst(#794). A spike at Go 1.27.3 anddstv0.28.0 added a type and a method from a new generation to a file holding a keep region, three ways:go/astnodes moved and printed: every moved doc comment was misplaced, and one landed insideGetZone's body.go/astto locate declarations, source text spliced in,astutil.AddImport: correct, but it cannot reach inside a declaration, as a field-level merge (open question 5) would need.dst: correct, imports managed, and a file with generics, a range-over-func iterator andminround-trips byte for byte.dstis MIT-licensed, v0 and maintained in bursts, last released in 2026. The documents pin it exactly, allow it inemitters/golangalone (packages.mdstates the archtest entry the package will need), and make the spike's cases the adapter's tests.IDs and renames (#677). The statements across
docs/that #677 lists promised that IDs survive any rename, though an operation's ID is built from its path and a component's from its name. Each now says what holds: a rename of what the ID is not built from (anoperationId, atitle) is "same ID, new symbol", and a path or component rename is carried by the correlation key. That coversarchitecture.md,ir/identity.md,prior-art.md(both sites),reference-learnings.md, and inemitters/:plan/overview.md,shaping-hints.md,write-integrate.md,surface-verification.md, T-8 and the README's INV3 row. #419 (stating the answer indocs/ir/open-questions.md) and #679 (the correlation-key pass) stay open.T-37 pins shipped names, and T-38 the manifest and integration rules.
Closes #713
Closes #714
Closes #716
Closes #583
Closes #705
Closes #794
Closes #677
Test plan
identical: true.dstlicence (MIT, from its LICENSE), tags (v0.28.0 latest) and commit history checked through the GitHub API.go vet.Stacked on #1335 (#1329 ← #1331 ← #1332 ← #1334 ← #1335). Merge in order. After each base lands, "Update branch" is a merge of
mainthat conflicts nowhere.