Skip to content

forge: model runs as an explicit state machine with a drawn transition diagram #9

Open

Description

@ric03uec

Problem

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.
  • Adding new outcomes.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions