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
{{ message }}
Repository navigation
forge: model runs as an explicit state machine with a drawn transition diagram #9
A Forge run today has no first-class notion of what stage it is in. The pieces exist — a tmux session, a worktree, an exec.log, a judge.log, an eventual ledger row with an --outcome — but nothing enumerates the states a run can occupy or the transitions between them.
Consequences:
lmstack-forge status reports the tmux pane's idleness, not the run's phase. A pane can be idle because the model is thinking, because the judge is reviewing, because everything crashed, or because the PR is already open.
lmstack-forge with no key lists tmux sessions and nothing else. The sweep has to reconstruct "is this still running?" from wall time and log tails.
Outcomes (pr-opened, pr-opened-stuck, abandoned, no-change, failed — see bin/lmstack-ledger line 50) are the only formal states, and they are all terminal. There is no vocabulary for in-progress phases.
What would close this
Define the finite set of states a Forge can be in (rough shape, to be pinned down in the ticket): queued → exec-running → exec-done → judge-running → judge-done → pr-opened plus terminal exits abandoned / no-change / failed.
Define the legal transitions. Illegal transitions should be impossible to record, not just discouraged.
Persist the current state per run (e.g. ~/.lmstack/runs/<key>/state) and update it at each transition point in bin/lmstack-forge / the exec skill / the judge.
Render the diagram in the docs — a state-transition graph committed as a Mermaid block so it renders on GitHub and stays close to the code.
Show the state in the forges list (lmstack-forge with no key), replacing the raw tmux-session dump with <key> <state> <age>.
Sweep uses the state, not log-tail guessing.
Why deterministic matters
Right now "is this Forge stuck?" is a judgment call made by reading logs. With an explicit machine, stuck becomes state == exec-running AND age > threshold — testable, alertable, and cheap to reason about across many concurrent runs.
Out of scope
Changing what the exec or judge phases actually do.
Activity