Uh oh!
There was an error while loading. Please reload this page.
docs(spec): measure what the driver-less merge queue does to the two unsharded ADR-0087 projections - #8359
Conversation
…unsharded ADR-0087 projections (#8344) #8344 asked an open question it could not answer from a PR branch: `.gitattributes` routes `packages/spec/spec-changes.json` and `docs/protocol-upgrade-guide.md` through `merge=os-regen`, a LOCAL git driver, while the merge queue rebuilds each PR server-side where no custom driver runs. Stale-but-clean, conflict, or correct? Measured, not reasoned: the real in-flight case (#8325's branch against a `main` already carrying #8324 and #8327) plus four synthetic two-registrations-in-flight pairs, each merged in a clone with no `merge.os-regen.driver` configured. Answer: never stale-but-clean. Both files are sorted unions and a registration is insertion-only, so the queue's text merge either takes both sides — byte-identical to the regeneration, all three `check:` gates green on the un-regenerated result — or conflicts. It conflicts only on ADJACENT registry ids; one existing entry between them already merges clean and current. So the card's default direction is measured NOT to work: sharding these two files buys back zero ejections, because every conflicting case also conflicts in `packages/spec/src/migrations/registry.ts` — generated, committed, unsharded and NOT_DRIVER_MANAGED — which every registration touches by construction. No sharding, no CI regenerate-and-diff; the finding and its reproduction are the deliverable. This also corrects `build-spec-changes.ts`'s stated reason for staying a single file ("two PRs append under different majors"): in-flight registrations land in the same current major, so distance in id sort order is what separates them. The conclusion held; the reason did not. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WocN37om5bw81JDoEEMA2e
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
📓 Docs Drift CheckThis PR changes 1 package(s): 106 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
⛔ 7 release-owned page(s) also reference the affected code. These are read-only:
|
Uh oh!
There was an error while loading. Please reload this page.
Fixes#8344
The card's step 1 was to measure what the merge queue's driver-less, server-side rebuild actually produces for
packages/spec/spec-changes.jsonanddocs/protocol-upgrade-guide.mdwhen two ADR-0087 registrations are in flight — the filer explicitly could not observe this from a PR branch. That measurement exists now, and it changes the direction. No sharding, no CI regenerate-and-diff: the finding and its reproduction are the deliverable.How the queue's environment was reproduced
.gitattributesroutes both files throughmerge=os-regen, which is registered per clone byscripts/setup-git-hooks.mjs. A fresh clone has nomerge.os-regen.driverin its config, and git then falls back to the built-in text merge — which is exactly the queue's situation. So the server-side equivalent is a driver-less clone plus git's own merge:merge-tree --write-treeis merge-ort, the same algorithmgit mergeruns; the adjacent-id row below was re-confirmed with a real working-treegit mergein that clone, with identical results.Inputs: the real in-flight case that raised the issue — PR #8325's branch at its pre-merge tip
02694c4, againstmainat1b2eb1b, which already carried #8324 and #8327 — plus four synthetic pairs, each a throwaway branch offorigin/mainregistering one semantic entry and runninggen:migration-registry+gen:spec-changes+gen:upgrade-guide. The synthetic branches were never pushed and nothing in this PR registers an ADR-0087 entry.The measurement
mainvs #8325c985c4a), all three filesaaa-probe-first/zzz-probe-last)check:spec-changes0,check:upgrade-guide0,check:migration-registry0check:spec-changes0,check:upgrade-guide0,check:migration-registry0Reverse side of the same test — the same adjacent-id merge, run in a clone with the driver registered:
What it answers
The open question resolves to "never stale-but-clean." Both files are sorted unions, and an ADR-0087 registration is insertion-only. A text merge of two insertion-only diffs therefore either takes both sides — which is the regeneration, byte for byte — or refuses. There is no third outcome. The clean rows are not merely conflict-free: the
--checkgates were run against the un-regenerated merge result and pass, which is what proves them current.The residual hazard is real but is a conflict, not silence — and it is narrow: it needs the two in-flight entries to be adjacent in id sort order. One existing entry between them is already enough (a semantic entry renders as 7 lines in
spec-changes.jsonand 3 in the guide, comfortably past git's 3-line context window).The card's default direction is measured not to work. Sharding these two files buys back zero ejections, because every conflicting case above also conflicts in
packages/spec/src/migrations/registry.ts— generated, committed, unsharded, and deliberately outside the driver (NOT_DRIVER_MANAGED) — which every registration touches by construction. #7297 removed the collision at the source; it does not reach the generated file the sources are concatenated into. Sharding the projections whileregistry.tsstill conflicts would be work that changes no outcome.The fallback direction (a CI regenerate-and-diff) is also not warranted: it would guard against staleness, and staleness is the one outcome measured not to occur.
What landed
Documentation only — three comment/prose surfaces, no behaviour change:
packages/spec/src/migrations/entries/README.md— the table, the reproduction, and why sharding does not reachregistry.ts, appended to the existing "What this does not fix" section that already names these two files..gitattributes— the header block states the durability bound this card is about; it now also records what was measured for the two entries that are still single files, and why they stay that way.packages/spec/scripts/build-spec-changes.ts— corrects the stated reason for staying a single file. It said "two PRs append under different majors"; in-flight registrations land in the same current major, so what separates them is distance in id sort order. The conclusion held, the reason did not.Verification
Gate families re-derived against the actual changed paths with
node scripts/pm/dispatch-gates.mjs; that surfaced three the dispatch list did not name (check:cross-package-test-inputs,check:type-source-resolution,scripts/check-dev-prereqs.mjs) and dropped two that no longer match (check:doc-authoring,check:objectui-changeset). All the surfaced ones were run.scripts/check-dev-prereqs.mjsexits 1 in this container with "the workspace is not built — 12 of 67 packages declare an entry point under dist/ that is not on disk", naming packages this diff does not touch (client-react,studio,embedder-openai, …). It is a container-state precondition, not a code gate; CI builds the workspace.check:i18nandcheck:doc-formula-expressionsfailed the same way until the closures were built, then passed.No changeset:
packages/specis published, but itsfilesarray ships onlysrc/**/*.zod.tsfromsrc/, so neither the migrations README nor.gitattributesnor ascripts/comment reaches a consumer, and nothing about the package's behaviour changes.skip-changesetapplied.Out of scope, left open: #7297 remains open as the sharding this measurement builds on; #8324, #8327 and #8325 are referenced only as the measurement's real inputs.
Generated by Claude Code