All courses · Course overview · Lesson sequence
Skip to lesson textAnswers and explanations · State that survives ambiguity
The baseline table is: revision 0 ACTIVE, zero reservations, no fact or draft; revision 1 RESERVED, one reservation and no fact; revision 2 IN_FLIGHT with that same reservation; revision 3 ACTIVE with a valid EX-001 fact but no draft; revision 4 REVIEW with the fact and exact draft. The transitions reserve, begin invocation, record a fact and prepare a draft. They do not represent four tool calls.
RESERVED says an attempt has budget and identity. IN_FLIGHT says its result may be uncertain. Treating both as “busy” loses the evidence needed to decide whether invoking again is a new call or a dangerous replay. Module 5 uses that distinction.
Run this inside project, or add project to Python's import path:
from engine import Checkpoints, Engine, StaleRevision
from workflow import Request
store = Checkpoints()
try:
engine = Engine(store)
engine.start(Request("STATE-1", "EX-001", 1927))
first, stale = store.get("STATE-1"), store.get("STATE-1")
engine._save(first, "ACTIVE", "reviewed_by_first_caller")
try:
engine._save(stale, "ACTIVE", "overwrite_by_old_caller")
except StaleRevision:
pass
else:
raise AssertionError("stale write accepted")
assert store.get("STATE-1")["reason"] == "reviewed_by_first_caller"
finally:
store.close()
_save is used here to expose the mechanism for learning; application code should use the public controller operations. After the conflict, reconsider whether the intended action is still appropriate for the new evidence, not just which revision number to supply.
A defensible future route is ACTIVE → NEEDS_OBSERVATION when the input explicitly represents ambiguity; a human-supplied revised observation could start a new request identity or a designed revision protocol. Returning to ACTIVE needs a validated observation and preserved provenance. It does not grant correction authority. The current schema has no uncertainty representation, so this design requires more than adding a string to PHASES.
ACTIVE → APPROVED_FOR_SIMULATION is structurally forbidden. ACTIVE → REVIEW is structurally allowed but cannot be used without a fact and generated draft. Request ID identifies the work; revision identifies one saved version of that work. A schema change from observed_year: int to an interval needs a deliberate conversion and changed comparison logic. Renaming the JSON schema tag alone would silently change meaning.
Self-check: your artifact should name five baseline revisions, distinguish attempt count from work count, preserve the winning update and identify a semantic precondition. If it says “SQLite makes all external actions atomic,” revise it: our transaction covers the snapshot row, not a remote action.