A conflict-parked branch has no way back into the lane — #214 has been finished and unlanded for three days #271

Closed
opened 2026-09-02 06:55:36 +00:00 by viberfox-agent · 0 comments
Collaborator

What happens

shipReady catches MergeConflict and parks the ticket
(tools/autopilot.ts:394-406):

await api(`/issues/${n}/labels/${await labelId(SHIP)}`, { method: "DELETE" });
await comment(n,
  `\u{1f916} **Not shipping this one — the branch conflicts with \`main\`** (another ticket landed first).\n\n` +
  `Rebase \`${branch}\` onto \`main\`, resolve, push, and put the \`ship\` label back to land it.`);

The instruction is addressed to a person. docs/direction.md's premise for this
whole lane is that there is no person: "work continues while the maintainer is
unavailable, so every gate has to be a machine one."
So a conflict is not a park,
it is a stop.

The instance

#214 — "gap: you cannot find out what a navigation mark is" — was promoted
into the build lane by the 3-day retrospective (#218) on 2026-08-30. It was
refined, built, and reported complete the same morning: the register's benaming,
vaarwater and naut_funct reach the client, the cache moved v1 → v2, and a
player can walk up to a buoy and read Look at 884.120R (Kribbaken · BOVEN-RIJN EN
WAAL)
. At 10:15 it hit this branch and stopped.

Three days later feat/214-nav-marks-readout is still unlanded, and — because the
ticket carries no autopilot label (#270) — it has not appeared on the daily note
once. A working feature, built by the lane, invisible and stationary.

Why "retrying cannot resolve this" is only half true

The comment above the park says:

Retrying cannot resolve this — every autopilot ticket edits docs/direction.md,
so two in flight collide with whichever lands first.

That is right about a re-merge, which is what landOnMain attempts: a
fast-forward cannot be retried into existence. It is not right about a rebase.
The stated collision is two tickets editing different rows of the same markdown
table, which is the case git rebase resolves without help nearly every time.
Nothing currently attempts it.

Note also that #214 is not an autopilot ticket and does not edit docs/direction.md
at all — the reason given for parking rather than retrying does not even apply to
the ticket it stopped.

What to change

  1. Attempt one rebase before parking. In the MergeConflict handler, rebase
    the branch onto main in the same throwaway checkout landOnMain already
    makes. If it applies cleanly: force-push the branch, re-dispatch CI against it
    (dispatchCi, the path a fresh branch already takes), leave ship on, and
    leave the ticket for a later tick to land — the verdict is read on a later tick
    anyway, so this needs no new waiting.
  2. One attempt, not a loop. Record that a rebase was tried so a branch cannot
    be rebased on every tick. If the rebase conflicts, park as today.
  3. Park with a label the digest reads. Whichever way it ends, a parked ticket
    must be visible on the daily note — that is #270, and this ticket is the reason
    it matters.
  4. Nothing weakens. The rebase changes which commit is offered; it does not
    change what is required of it. The re-dispatched run must be green, the fence
    check runs again on the new diff, and landOnMain still fast-forwards to the
    exact commit CI passed on.

Scope

tools/autopilot.ts only. The unattended lane may build this and may not merge
it; it lands for review.

Worth doing in the same pass, or worth saying explicitly if not: #214's branch
is still sitting there
and is the obvious first thing to run the new path
against.

Filed by the 7-day retrospective on #269.

## What happens `shipReady` catches `MergeConflict` and parks the ticket (`tools/autopilot.ts:394-406`): ```ts await api(`/issues/${n}/labels/${await labelId(SHIP)}`, { method: "DELETE" }); await comment(n, `\u{1f916} **Not shipping this one — the branch conflicts with \`main\`** (another ticket landed first).\n\n` + `Rebase \`${branch}\` onto \`main\`, resolve, push, and put the \`ship\` label back to land it.`); ``` The instruction is addressed to a person. `docs/direction.md`'s premise for this whole lane is that there is no person: *"work continues while the maintainer is unavailable, so every gate has to be a machine one."* So a conflict is not a park, it is a stop. ## The instance **#214** — *"gap: you cannot find out what a navigation mark is"* — was promoted into the build lane by the 3-day retrospective (#218) on 2026-08-30. It was refined, built, and reported complete the same morning: the register's `benaming`, `vaarwater` and `naut_funct` reach the client, the cache moved `v1` → `v2`, and a player can walk up to a buoy and read *Look at 884.120R (Kribbaken · BOVEN-RIJN EN WAAL)*. At 10:15 it hit this branch and stopped. Three days later `feat/214-nav-marks-readout` is still unlanded, and — because the ticket carries no `autopilot` label (#270) — it has not appeared on the daily note once. A working feature, built by the lane, invisible and stationary. ## Why "retrying cannot resolve this" is only half true The comment above the park says: > Retrying cannot resolve this — every autopilot ticket edits `docs/direction.md`, > so two in flight collide with whichever lands first. That is right about a *re-merge*, which is what `landOnMain` attempts: a fast-forward cannot be retried into existence. It is not right about a **rebase**. The stated collision is two tickets editing different rows of the same markdown table, which is the case `git rebase` resolves without help nearly every time. Nothing currently attempts it. Note also that #214 is not an autopilot ticket and does not edit `docs/direction.md` at all — the reason given for parking rather than retrying does not even apply to the ticket it stopped. ## What to change 1. **Attempt one rebase before parking.** In the `MergeConflict` handler, rebase the branch onto `main` in the same throwaway checkout `landOnMain` already makes. If it applies cleanly: force-push the branch, re-dispatch CI against it (`dispatchCi`, the path a fresh branch already takes), leave `ship` on, and leave the ticket for a later tick to land — the verdict is read on a later tick anyway, so this needs no new waiting. 2. **One attempt, not a loop.** Record that a rebase was tried so a branch cannot be rebased on every tick. If the rebase conflicts, park as today. 3. **Park with a label the digest reads.** Whichever way it ends, a parked ticket must be visible on the daily note — that is #270, and this ticket is the reason it matters. 4. **Nothing weakens.** The rebase changes which commit is offered; it does not change what is required of it. The re-dispatched run must be green, the fence check runs again on the new diff, and `landOnMain` still fast-forwards to the exact commit CI passed on. ## Scope `tools/autopilot.ts` only. The unattended lane may build this and may not merge it; it lands for review. Worth doing in the same pass, or worth saying explicitly if not: **#214's branch is still sitting there** and is the obvious first thing to run the new path against. <sub>Filed by the 7-day retrospective on #269.</sub>
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
jeroen/cartopolis#271
No description provided.