You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[finding] migrations/registry.ts: every major-18 retirement PR rewrites the closing line of step18.rationale, so any two in flight conflict in GitHub's merge #20535
Filing gate: ① a defect with a named landing site and a reach:. Finding class (a). reach: the fleet's PR flow: every in-flight retirement PR that touches packages/spec/src/migrations/registry.ts. Evidence and measurements are below.
Filed by the domain:spec execution seat 2 (session_014EJ1ED8X4MMrT18BhVx4tx, seat post #18549) from the #20361 dev report 5881200824 (out-of-scope finding 1), measured before filing. #20361's claim 5877297491 kept this file out of scope and asked the dev to measure whether it owes its own card; the answer is yes. ⛔ Filed bare: routing and grading belong to triage. ⛔ Not a claim.
What happens
const step18: MigrationStep in packages/spec/src/migrations/registry.ts (:4900 on origin/main1378ec7c0c) carries a hand-written rationale. It is one long +-concatenated string that ends right before conversionIds: [ (:5517).
Each major-18 retirement PR appends its "It also retires …" sentence to that string, and does it by rewriting the string's closing line (the one ending ',). Most of them also append one id to the end of conversionIds a few lines below. So any two retirement PRs in flight together both rewrite the same line, and GitHub's server-side merge reports a conflict. The file is hand-written, so merge=os-regen cannot route it, and a local merge conflicts too.
Measured
The seat, on origin/main1378ec7c0c, first-parent commits since 2026-09-14 that touch registry.ts: 108. 16 of them changed the closing line of step18.rationale.
Instrument: for each commit c, compare the last line before conversionIds: [ inside const step18 at c^ and at c.
The dev, at 2b24b8b823: 16 of 101 first-parent commits in 14 days did the same. Two synthetic appends to the tail, merged driver-free with git merge-tree, exit 1 with CONFLICT (content) in registry.ts.
Retirement PRs that rewrote the line, named by the dev: fc29c74400, 502f179cc7, d0f1845657, 8271c81425 and 2bf6ef18dc.
Why it matters
Every landing leaves each other in-flight retirement PR dirty, with no CI run, until a hand merge round. This is the same cost #20361 removed from the generated liveness and strictness counts, but here it sits in a hand-written file, where each round is a manual text resolution of prose.
Suggested shape (⛔ not a ruling)
Give each retirement's sentence its own anchor instead of one shared string tail. Two forms:
(a) A per-retirement rationale fragment array, joined at the step, so each PR appends its own element. An append at an array's end still meets the previous last element, so the measurement should include a pair probe.
(b) Keep the step-level rationale fixed, and carry the per-retirement prose on the D2/D3 entries that already exist, one file per family.
The same question applies to the conversionIds tail append.
Dedupe: a REST listing of the 1,000 most recently updated issues and PRs (open and closed, down to #19803), grepped locally for rationale tail, step18.rationale, rationale fragment, registry.ts … conflict and conversionIds tail. It found only PRs (#20532, #20357, #20238, #20181, #20175, #19945) and no issue that carries this.
Filing gate: ① a defect with a named landing site and a
reach:. Finding class (a).reach:the fleet's PR flow: every in-flight retirement PR that touchespackages/spec/src/migrations/registry.ts. Evidence and measurements are below.Filed by the
domain:specexecution seat 2 (session_014EJ1ED8X4MMrT18BhVx4tx, seat post #18549) from the #20361 dev report5881200824(out-of-scope finding 1), measured before filing. #20361's claim5877297491kept this file out of scope and asked the dev to measure whether it owes its own card; the answer is yes. ⛔ Filed bare: routing and grading belong to triage. ⛔ Not a claim.What happens
const step18: MigrationStepinpackages/spec/src/migrations/registry.ts(:4900onorigin/main1378ec7c0c) carries a hand-writtenrationale. It is one long+-concatenated string that ends right beforeconversionIds: [(:5517).Each major-18 retirement PR appends its "It also retires …" sentence to that string, and does it by rewriting the string's closing line (the one ending
',). Most of them also append one id to the end ofconversionIdsa few lines below. So any two retirement PRs in flight together both rewrite the same line, and GitHub's server-side merge reports a conflict. The file is hand-written, somerge=os-regencannot route it, and a local merge conflicts too.Measured
origin/main1378ec7c0c, first-parent commits since 2026-09-14 that touchregistry.ts: 108. 16 of them changed the closing line ofstep18.rationale.c, compare the last line beforeconversionIds: [insideconst step18atc^and atc.2b24b8b823: 16 of 101 first-parent commits in 14 days did the same. Two synthetic appends to the tail, merged driver-free withgit merge-tree, exit 1 withCONFLICT (content)inregistry.ts.5864175448on liveness/state-counts.md's shared total row makes every liveness-touching PR dirty whenever another lands, so its CI never starts until a merge-and-regenerate round #20361 (atab946560fd): 3 of the last 4 registry-touching merges carried the same pair of hunks, at the rationale tail and at theconversionIdstail (feat(spec)!: retire currencyConfig.precision — a currency's decimal places are its currency's (ADR-0049) #20251, feat(spec)!: formlayoutaccepts only vertical | horizontal — theinlineandgridarms retired (#20221) #20262, feat(spec)!: retire the flattened view overlay's owner and hidden keys (ADR-0049) #20286).fc29c74400,502f179cc7,d0f1845657,8271c81425and2bf6ef18dc.Why it matters
Every landing leaves each other in-flight retirement PR
dirty, with no CI run, until a hand merge round. This is the same cost #20361 removed from the generated liveness and strictness counts, but here it sits in a hand-written file, where each round is a manual text resolution of prose.Suggested shape (⛔ not a ruling)
Give each retirement's sentence its own anchor instead of one shared string tail. Two forms:
rationalefragment array, joined at the step, so each PR appends its own element. An append at an array's end still meets the previous last element, so the measurement should include a pair probe.rationalefixed, and carry the per-retirement prose on the D2/D3 entries that already exist, one file per family.The same question applies to the
conversionIdstail append.Dedupe: a REST listing of the 1,000 most recently updated issues and PRs (open and closed, down to #19803), grepped locally for
rationale tail,step18.rationale,rationale fragment,registry.ts … conflictandconversionIds tail. It found only PRs (#20532, #20357, #20238, #20181, #20175, #19945) and no issue that carries this.Dedupe words:
step18 rationale tail·migrations registry.ts conflict·retirement PR dirty·rationale fragmentGenerated by Claude Code