Agentic systems / Pattern 02 / Build the working path

Implement and resume a deterministic incident workflow

Use immutable checkpoints to make each transition inspectable, then design a persistence boundary without pretending memory is durable storage.

By Sandeep Belgavi · 23 October 2026 · Architecture and design patterns

Execute the fixture and its transition tests

Save pattern_02.py with test_pattern_02.py. Use python3 -B pattern_02.py on a macOS environment with Python 3, or py -3 -B pattern_02.py on Windows with the Python launcher. The expected output is stage=ready category=latency evidence=fixture:L1. Run -B -m unittest -v test_pattern_02.py with that interpreter to exercise the transition boundaries.

The program was tested on Windows with Python 3.13. It requires Python 3.11 or later and no third-party package. The macOS invocation is platform guidance. The classifier in the demonstration always returns latency; no language model is contacted. That deliberately simple adapter lets the tests isolate workflow behavior from classification uncertainty. It does not establish that an arbitrary report will be classified correctly.

Architecture and request sequence

Component diagram for Implement and resume a deterministic incident workflow
Original reference architecture by Sandeep Belgavi. Arrows show the responsibilities and transitions described below.
Read the architecture as text
  • Checkpoint input: Incident, stage and accepted fields
  • advance function: Exactly one validated transition
  • Adapter or inventory: Only the current stage dependency
  • Successor object: Immutable in-memory checkpoint
  • Proposed durable commit: Not implemented in the fixture
  • Checkpoint input → advance function: load current stage
  • advance function → Adapter or inventory: invoke stage dependency
  • Adapter or inventory → Successor object: construct successor
  • Successor object → Proposed durable commit: commit in proposed extension
Request sequence for Implement and resume a deterministic incident workflow
Illustrative sequence for this design; failure and recovery variants are explained in the article.
Read the sequence as text
  1. Caller → Workflow: Advance new checkpoint
  2. Workflow → Classifier: Invoke callable once
  3. Caller → Workflow: Advance classified checkpoint
  4. Workflow → Evidence: Read category inventory
  5. Caller → Workflow: Advance collected to ready

Follow advance through one stage at a time

Checkpoint holds incident, stage, category and evidence. Its frozen dataclass prevents field assignment after construction. advance requires a nonempty incident and dispatches by stage. At new it calls the classifier, validates the proposed category and returns classified. At classified it retrieves the corresponding inventory value and rejects anything other than a nonempty string. At collected it validates the stored fields and returns ready. A ready checkpoint returns an equivalent ready checkpoint.

Notice that the function advances only one transition per call. The three-iteration demonstration is a caller policy, not a loop hidden inside the transition function. A job runner can therefore store each accepted successor before scheduling the next stage. The code makes no external changes while constructing the successor. That property simplifies retry reasoning for the current fixture, although a future collector that writes elsewhere would introduce a separate side-effect contract.

Resume without repeating model judgment

The resume test constructs a classified checkpoint and passes no classifier. Collection still succeeds because that stage does not invoke the classifier. This proves a narrow, useful behavior: a persisted accepted category can be reused without asking the model to choose again. It does not prove that the checkpoint was actually persisted, authenticated or protected from tampering. Those are storage and service responsibilities outside the in-memory demonstration.

Tests also reject an unknown stage, a missing evidence locator and a corrupt ready checkpoint. Validation on resume matters because stored data can outlive the code that produced it. In a production adaptation, validate the schema version before applying stage-specific checks. Never let an unrecognized stage default to ready. Keep the original checkpoint available when validation fails so a repair tool can inspect the inconsistency without guessing what happened.

Add persistence with an explicit commit boundary

A proposed durable implementation stores each accepted transition with incident identity, previous version, successor stage and evidence locator. Update the current row only if its version still matches the worker's expected version; append the transition record in the same database transaction. A duplicate job can then discover that its predecessor already committed. A conflicting successor must be rejected rather than overwrite a later stage. This is a proposed extension, not code shipped in the fixture.

Python's SQLite interface supports parameter binding and explicit transaction control; use those facilities instead of building SQL from incident text. Source: Python 3.11 sqlite3. A local database can support a single-node prototype, but selecting a production datastore requires its own concurrency and recovery design. Test interruption before and after commit. A checkpoint transaction does not atomically cover a remote collector or notification service.

Package stage execution as a bounded worker

A container reference design uses an unprivileged Python runtime and a command that accepts one checkpoint identifier, loads it, advances one stage and attempts the conditional commit. It exits with a distinguishable retryable, invalid or completed result. Mount durable storage outside the container's ephemeral filesystem, or use an authenticated database client. The tiny downloadable program needs none of that infrastructure and simply prints its in-memory result.

Separate deployment configuration for the classifier from workflow configuration. A classifier credential should not grant arbitrary database writes, and a collector should receive only its approved data scope. Set resource limits and a maximum stage duration in the worker supervisor. These are container and service recommendations, not an executed deployment. Before building the image, lock the Python dependency environment and base-image digest; before promotion, run the transition tests against the packaged artifact and exercise a checkpoint created by the previous release.

Implementation evidence and remaining work

The linked source and tests establish eight deterministic transition behaviors. They do not provide a persistent store, migration implementation, distributed queue or live model classifier. The SQLite documentation supports only the stated database-interface facts. All schema and worker layouts are original proposals. Use Evals to evaluate a future classifier separately from the state machine that surrounds it.