What is broken
An epic issue's fabrika lane can come up before the epic has a plan, and it boots on the
single-task coder template (packages/fabrika-cli/src/lane/templates/coder.workflow.json) instead of
an emitted epic machine. Nothing downstream says the lane is wrong:
- Triage note (verified at
origin/main, commit eb7c6fa): runEmit
(packages/fabrika-cli/src/lane/emit-verb.ts) correctly refuses TOPOLOGY_ABSENT when the epic
body carries no readable ## Dependencies topology — but that refusal happens inside emit; a
boot path that placed a coder-template workflow.json into .fabrika/lanes/<epic>/ before emit
ever runs leaves the wrong-machine lane behind, and nothing cleans it up.
placeMachine (packages/fabrika-cli/src/lane/store.ts) refuses with "remove it to regenerate"
once any workflow.json exists in the lane dir — so the wrong-template lane actively blocks
re-emission until someone deletes the directory by hand.
lane migrate --check (packages/fabrika-cli/src/lane/migrate-verb.ts) only grafts committed
templates and compares bytes/state replay; a coder-template lane grafts cleanly and reads
current. It never compares the lane's machine shape against the board's expectation for its
issue (epic with children ≠ one task named "issue").
Observed on epic #5979 (2026-08-21): stale lane carried a single-task workflow.json, ledger read
ISSUE.WIP → ISSUE.BLOCKED, a builder backed off because no children existed, recipe unpark
refused only on bare BLOCKED, and the only repair was deleting .fabrika/lanes/5979/ and re-running
lane emit.
Why standalone
Searched the open board for an owner of this surface (fabrika report dedup, plus an issue search
on lane emit). Closest neighbours each cover a different defect: #6474 (the absent-topology
refusal cannot distinguish a non-epic from an unplanned epic), #6237 (descoped child leaves the
topology unbootable), #6871 (claim marker on a closed issue). None owns wrong-template boot or the
migrate-check blindness, so this mints standalone.
Fix direction
Two changes, possibly both needed:
- Refuse a
lane emit-shaped boot for a type:epic issue until a readable plan topology exists,
so no lane directory is left behind on the coder template.
- Teach
lane migrate --check to flag a lane whose machine shape does not match the board's
current expectation for its issue (single-task machine on an epic with children), as a distinct
verdict rather than current.
Acceptance criteria
Original report (verbatim)
Summary
An epic issue's fabrika lane was booted before the epic had a plan, and it came up on the single-task CODER machine template instead of an epic topology. Every later diagnostic treats the lane as healthy: recipe unpark refuses only on bare BLOCKED, and lane migrate --check does not flag the template mismatch. Removing the lane directory and re-running lane emit was the only repair.
What I was doing
Driving epic #5979 through the operate loop. The lane under .fabrika/lanes/5979/ had been booted 2026-08-21 16:30 — before plan-epic ever ran on the epic. lane emit refused at that time ("no readable topology"), but a lane directory with a workflow.json was left behind.
What I observed
- The stale lane's workflow.json was the single-task template with one task named "issue"; its ledger carried ISSUE.WIP → ISSUE.BLOCKED.
lane emit on the existing lane exits 14: "remove it to regenerate" — so the wrong-template lane actively blocks re-emission.
lane migrate --check reported nothing wrong.
- A builder dispatched against it backed off because no children existed, and the fold read
blocked on task "issue".
Why it matters
Any driver that boots a lane pre-plan strands work on a machine that cannot represent the epic, and nothing in the tooling says the lane is wrong. The failure surfaces only as confusing downstream refusals.
Pointers
Suggested next step (non-binding)
Two options, possibly both: refuse lane emit-shaped boot for a type:epic issue until a plan exists, and teach lane migrate --check to compare a lane's machine shape against the board's current expectation for its issue.
Filed by an agent · session 01a02ab8-f5ac-7647-9d28-963dc3ecf62a · branch umut/adr-0334-bootstrap-merge-arms · 2026-08-22T21:38:22Z
What is broken
An epic issue's fabrika lane can come up before the epic has a plan, and it boots on the
single-task coder template (
packages/fabrika-cli/src/lane/templates/coder.workflow.json) instead ofan emitted epic machine. Nothing downstream says the lane is wrong:
origin/main, commit eb7c6fa):runEmit(
packages/fabrika-cli/src/lane/emit-verb.ts) correctly refusesTOPOLOGY_ABSENTwhen the epicbody carries no readable
## Dependenciestopology — but that refusal happens inside emit; aboot path that placed a coder-template
workflow.jsoninto.fabrika/lanes/<epic>/before emitever runs leaves the wrong-machine lane behind, and nothing cleans it up.
placeMachine(packages/fabrika-cli/src/lane/store.ts) refuses with "remove it to regenerate"once any
workflow.jsonexists in the lane dir — so the wrong-template lane actively blocksre-emission until someone deletes the directory by hand.
lane migrate --check(packages/fabrika-cli/src/lane/migrate-verb.ts) only grafts committedtemplates and compares bytes/state replay; a coder-template lane grafts cleanly and reads
current. It never compares the lane's machine shape against the board's expectation for itsissue (epic with children ≠ one task named "issue").
Observed on epic #5979 (2026-08-21): stale lane carried a single-task workflow.json, ledger read
ISSUE.WIP → ISSUE.BLOCKED, a builder backed off because no children existed,
recipe unparkrefused only on bare BLOCKED, and the only repair was deleting
.fabrika/lanes/5979/and re-runninglane emit.Why standalone
Searched the open board for an owner of this surface (
fabrika report dedup, plus an issue searchon
lane emit). Closest neighbours each cover a different defect: #6474 (the absent-topologyrefusal cannot distinguish a non-epic from an unplanned epic), #6237 (descoped child leaves the
topology unbootable), #6871 (claim marker on a closed issue). None owns wrong-template boot or the
migrate-check blindness, so this mints standalone.
Fix direction
Two changes, possibly both needed:
lane emit-shaped boot for atype:epicissue until a readable plan topology exists,so no lane directory is left behind on the coder template.
lane migrate --checkto flag a lane whose machine shape does not match the board'scurrent expectation for its issue (single-task machine on an epic with children), as a distinct
verdict rather than
current.Acceptance criteria
type:epicissue that carries no readable plan topology is refused with a named refusal ("plan the epic first"), and no lane directory with a single-taskworkflow.jsonis left behind.fabrika lane migrate --checkreports a non-currentrow for a lane whose machine shape does not match its issue's expectation (single-task machine on an epic with linked children), with a reason naming the mismatch.lane emitalone, without manually removing the lane directory (or the existing refusal names exactly that remedy).Original report (verbatim)
Summary
An epic issue's fabrika lane was booted before the epic had a plan, and it came up on the single-task CODER machine template instead of an epic topology. Every later diagnostic treats the lane as healthy:
recipe unparkrefuses only on bare BLOCKED, andlane migrate --checkdoes not flag the template mismatch. Removing the lane directory and re-runninglane emitwas the only repair.What I was doing
Driving epic #5979 through the operate loop. The lane under
.fabrika/lanes/5979/had been booted 2026-08-21 16:30 — before plan-epic ever ran on the epic.lane emitrefused at that time ("no readable topology"), but a lane directory with a workflow.json was left behind.What I observed
lane emiton the existing lane exits 14: "remove it to regenerate" — so the wrong-template lane actively blocks re-emission.lane migrate --checkreported nothing wrong.blockedon task "issue".Why it matters
Any driver that boots a lane pre-plan strands work on a machine that cannot represent the epic, and nothing in the tooling says the lane is wrong. The failure surfaces only as confusing downstream refusals.
Pointers
.fabrika/lanes/(lane dirs),fabrika lane emit,fabrika lane migrate --checkSuggested next step (non-binding)
Two options, possibly both: refuse
lane emit-shaped boot for a type:epic issue until a plan exists, and teachlane migrate --checkto compare a lane's machine shape against the board's current expectation for its issue.Filed by an agent · session
01a02ab8-f5ac-7647-9d28-963dc3ecf62a· branchumut/adr-0334-bootstrap-merge-arms· 2026-08-22T21:38:22Z