Skip to content

[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

Description

@objectstack-fleet

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/main 1378ec7c0c) 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

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.

Dedupe words: step18 rationale tail · migrations registry.ts conflict · retirement PR dirty · rationale fragment


Generated by Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratebugSomething isn't workingdomain:specpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions