Smeldr's orchestration layer registers five governed StateFlows: Signal, Task, Decision, Amendment, Goal, each with its own states and transitions, each state optionally marked IsTerminal. The doc comment on that field reads simply: "marks this state as a sink." Two of the five flows proved that wasn't a complete definition.
The gap, found twice in one day
Task's flow runs backlog → active → waiting-plan → plan-reviewing → implementing → commit-reviewing → done. It has exactly one honest success path. What it didn't have: a way to close a Task whose own plan concludes "I looked, and this is already done, there's nothing to build."
That's not hypothetical. A real Task (T238) sat stuck at plan-reviewing for two days after its own investigation found the work it was dispatched to do had already shipped under a different commit. The flow had one legal exit from that state, implementing, and nothing to build meant nothing to do there. The Task just... sat.
The same day, a second and structurally sharper version of the same gap turned up in Goal's flow. Goal.parked was declared IsTerminal: true. It also has a live transition back to open. Those two facts contradict each other: a state you can leave isn't a sink, whatever its own struct literal claims. Nothing had ever checked this: IsTerminal is written once at flow registration and never read again anywhere in the codebase.
Same shape, different severity
Both bugs are instances of one missing concept: a governed item can close because the underlying need was met by *something other than its own tracked work*. That's a real, distinct outcome from done (which specifically means this item's own work produced the result), and neither flow had a state for it.
The fix, in both flows: a new resolved terminal state, reachable from every point that precedes real work actually starting: active/waiting-plan/plan-reviewing for Task, open/in-progress/parked for Goal, and nowhere else. implementing/commit-reviewing are excluded on purpose: once a build is genuinely in flight, "nothing to build" is no longer a live possibility by definition.
Every transition into resolved requires a reason. The entire point of the state is an explanation of what actually resolved the need elsewhere, and a transition that skipped that explanation would just relocate the same problem T238 exposed, one level down.
The stricter reading of IsTerminal wasn't true either
While auditing the other three flows for the same shape, not assuming they were fine, checking each one's own registered transitions, a third, milder version of the bug turned up: Decision.superseded is marked terminal and has an outbound edge to archived. Same shape as Goal.parked's bug, but far more benign: archived is *also* terminal, so the edge never leads back to live work, only between two closed states.
IsTerminal's own doc comment, read literally, forbade even that: "no outbound transitions are permitted from a terminal state," full stop. Decision's flow had quietly relied on a looser reading since it was written, and nothing had ever enforced the stricter one. Rather than invent a fix for an edge nothing was actually hitting, we corrected the comment to say what the codebase has always actually relied on: a terminal state may not transition to a *non-terminal* one. Terminal-to-terminal bookkeeping stays legal.
What this doesn't change
No exported Go symbol changed: orchTaskFlow/orchGoalFlow are both unexported functions, and the State/Transition/StateFlow types themselves are untouched. The behaviour change is real, though: transition_item and get_valid_transitions now report a resolved option for Task and Goal that wasn't there before. Patch bump, same class as any other behaviour-only fix with no new API surface.