Files
boocode/openspec/changes/archived/2026-06-07-eval-sandbox-agent-runtime/specs/state-graph/spec.md
indifferentketchup c935687725 chore(openspec): drop 9 superseded proposals + 11 stub archive files
Drop 9 batch proposals that are superseded by the boocode-lift-analysis
(boocontext-audit, conductor upgrades, self-healing/verify-gate skills):
add-3tier-memory, import-llm-evaluator, import-pregel-engine, plugin-platform,
conductor-evolution, code-intelligence-upgrade, dev-workflow, ui-overhaul,
agent-reliability.

Delete 11 stub archive files (49-66B each, 'Status: Shipped. Archived.' only)
that provide zero documentation value over the existing CHANGELOG.md + git tags.
2026-06-07 22:15:38 +00:00

1.8 KiB

ADDED Requirements

Requirement: State definition via annotations

The system SHALL provide an Annotation API for defining graph state schemas:

  • Annotation<T>(reducer?) — creates a state key with optional reducer
  • Annotation.Root({ key: Annotation<T> }) — combines keys into a state schema
  • Reducers: LastValue (default — overwrite), BinaryOperator (custom merge function)

Scenario: Annotation.Root defines typed state

  • WHEN const State = Annotation.Root({ messages: Annotation<string[]>(addMessages), step: Annotation<number>() }) is defined
  • THEN State SHALL have State, Update, and Node type members

Scenario: LastValue reducer replaces on each write

  • WHEN a node writes { step: 2 } and then { step: 3 } in the same step
  • THEN the LastValue channel SHALL throw an InvalidUpdateError

Scenario: BinaryOperator reducer accumulates

  • WHEN a node returns { messages: ["hello"] } and another returns { messages: ["world"] } with an addMessages reducer
  • THEN the final state SHALL contain messages: ["hello", "world"]

Requirement: StateGraph builder

The system SHALL provide a StateGraph class for constructing stateful agent graphs.

Scenario: StateGraph is constructed with state schema

  • WHEN new StateGraph({ stateSchema: State }) is called
  • THEN the graph SHALL accept nodes that receive and can update the defined state

Scenario: Nodes can read and write state

  • WHEN a node function receives state with { messages, step } and returns { step: step + 1 }
  • THEN the graph SHALL update step and preserve messages

Scenario: Conditional edges route based on state

  • WHEN addConditionalEdges("node_a", (state) => state.step > 5 ? "end" : "node_b") is added
  • THEN execution SHALL route based on the state value at runtime