Goal State Machine

Goal State Machine

In One Sentence

The core of an Agent’s “planning capability” is a state machine: a Goal has a lifecycle and transitions from one phase to the next; the Agent drives it with round continuation until it is reached or blocked.

The Four States (Aligned with the Official)

StateMeaningAuto round continuation
activeIn progress✅ Yes (RoundDriver continues)
pausedPaused❌ No (waiting to resume)
blockedBlocked (blocker unresolved)❌ No
completeCompleted❌ No

Legal Transitions

goal.CanTransition constrains direction, not just target validity:

active   → active / paused / blocked / complete
paused   → active / complete
blocked  → active / complete
complete → (terminal, no outgoing edge)

paused/blocked are entered only from active; complete is terminal. Illegal moves return GOAL_INVALID_TRANSITION.

Stable Error Codes

Nine stable GOAL_* error codes aligned with the official error.ts (e.g. GOAL_INVALID_MAX_ROUNDS, GOAL_STALE_REVISION, GOAL_NOT_FOUND). Errors are routed by stable string, never by parsing message text.

In Dsh-Go

1ts := goal.NewGoalToolset(sl) // bound to the session log
2// 6 tools: goal_list / goal_set_phase / goal_set_description
3//         / goal_set_max_rounds / goal_add_blocker / goal_report_blocker

The example shows how a stable error code is expressed cleanly:

1if _, err := call(ts, "goal_set_max_rounds", map[string]any{"maxRounds": float64(-1)}); err != nil {
2    if ge, ok := err.(*goal.GoalError); ok {
3        fmt.Println(ge.Code) // GOAL_INVALID_MAX_ROUNDS
4    }
5}

Ralph: Goal-Driven Auto-Iteration

workflow.RunRalph runs a fresh structured-output child per round, carrying only the objective and the prior bounded handoff. A child reports continue / complete / blocked; the loop ends on complete or blocked, and reports budget-limited at the round ceiling.

Todo: Whole-List Three-State Checklist

Goal and Todo complement each other. A todo list is replaced wholesale (last-write-wins); each item is pending / in_progress / completed. Sequential mode allows at most one in_progress (AllowParallel relaxes it). Normalize enforces non-empty, unique content and the active count.

Source Reference

  • pkg/goal/goal.go — the Goal state machine and its 6 tools
  • pkg/goal/errors.go — 9 stable error codes + GoalError
  • pkg/goal/transition.go — CanTransition
  • pkg/workflow/ralph.go — RunRalph
  • Runnable example: examples/tutorial step 3

Next Steps