-
Notifications
You must be signed in to change notification settings - Fork 0
Design agent runtime state vs immutable config split #106
Description
Problem
All domain models are frozen Pydantic BaseModels. This is correct for configuration/identity, but becomes expensive during agent execution.
Task.with_transition() does model_dump() → dict mutation → model_validate() on every state change, re-running all validators (whitespace checks, dependency dedup, assignment consistency) each time. An agent executing a task through CREATED→ASSIGNED→IN_PROGRESS→IN_REVIEW→COMPLETED triggers 4 full serialize/validate cycles.
When the M3 engine loop runs, an agent will need:
- Conversation history accumulating message by message
- Working memory evolving during execution
- Cost accumulating per-call
- Task status transitioning through states
None of this is modeled. The frozen AgentIdentity can't evolve during a task.
Proposed Solution
Introduce a config vs runtime separation:
| Concept | Type | Mutability | Purpose |
|---|---|---|---|
AgentIdentity |
Frozen BaseModel | Immutable | "Who am I" — config, personality, role |
AgentContext |
Mutable class | Mutable | Runtime state — conversation, memory, cost |
Task |
Frozen BaseModel | Immutable | Snapshot for persistence/reporting |
TaskExecution |
Mutable class | Mutable | Active state machine during execution |
The mutable runtime types hold references to their frozen config counterparts. State transitions happen cheaply on the mutable type; snapshots can be taken when persistence/reporting is needed.
Why Now
This is an M3 blocker. The engine loop (#11) and task lifecycle (#21) both need a state management story. Retrofitting this after M3 code builds on model_copy/with_transition patterns will be significantly more expensive.
Acceptance Criteria
- Design document or ADR for config-vs-runtime split
-
AgentContextclass with conversation, cost accumulation, and task reference -
TaskExecutionclass with cheap state transitions (no full re-validation) - Existing frozen models remain unchanged (they become the "config" / "snapshot" layer)
- Update DESIGN_SPEC.md Section 3 and Section 6 with the new model