You're reading the 0.10.0 archive.

Break, resume, and inspect a hank

A hank is a JSON program that arranges codons, a codon is a single agent task in that sequence, and a checkpoint is a recorded completion boundary that lets an execution resume where it stopped. Those three pieces are what make a long agent run operable: instead of treating a multi-hour pipeline as something that either finishes or is lost, we can interrupt it, restart it, step it back, and audit what it produced.

This chapter puts those operations to work on the seven-codon chapter-5 hank. We will run it once to completion, interrupt it after a checkpoint seals and resume the same execution, roll back one codon and regenerate the downstream artifacts, trace a cited price in the final award brief back to its digitized source, and compare a fresh lower-tier model run against the mixed-model baseline. Each section ends with a check-it block so we verify behavior rather than assume it.

Before starting, download the 0.10.0 fixture bundle. Extract it from its parent directory, then prepare the chapter's task data:

⌁ Terminal
tar -xzf hankweave-fixtures-0.10.0.tar.gz
cd hankweave-fixtures-0.10.0
cd chapters/ch5
python3 ../../verify.py prepare-data ../../quote-template-unification task-data

The environment needs a few things in place before any paid run. Use Node.js 22.19.0 or later for the package's Node-shebang entrypoint. The commands below use Bun's bunx launcher; the equivalent Node/npm spelling is npx hankweave@0.10.0. Install Bun and Git, run as a non-root user with writable execution and output directories, and export both ANTHROPIC_API_KEY and BASETEN_API_KEY. The prepared task-data directory under chapters/ch5 contains task inputs only; the held-out truth and generator remain in the bundle.

Complete the hank, then operate it#

We start from the complete chapter-5 hank rather than retyping a program, because the exercises that follow depend on its exact shape. It has seven fresh codons: three normalizers, survey-and-extracts, validate-and-repair, reconcile, and award-brief. The first, second, third, fourth, and seventh codons use haiku; the two judgment codons use pi/baseten/deepseek-ai/DeepSeek-V4-Pro. The configured per-codon caps add to $9.00; the accepted chapter capture records $0.71 in tracked codon cost for one complete execution, not a provider-billing promise.

The hank reconciles eight suppliers – AST, BCN, CDR, DVR, EMB, FJR, HBR, and IRS – across five BOM parts, producing 40 data rows, or 41 CSV lines including the header. The unknown GRN intake is quarantined rather than counted as a ninth quoting supplier. Read through the definition once before running it; the sections below operate its checkpoints, inspect its chain-of-custody fields, and measure the effect of changing the judgment tier.

JSON
{
  "$schema": "https://unpkg.com/hankweave@0.10.0/schemas/hank.schema.json",
  "meta": {
    "name": "quote-template-unification",
    "version": "1.0.0",
    "description": "Normalize eight suppliers across three digitizer dialects and five native extracts against RFQ NC-RFQ-0042, quarantine GRN, reconcile 40 supplier-part rows, and publish a cited award brief plus exception queue."
  },
  "hank": [
    {
      "id": "normalize-aster",
      "name": "Normalize Aster (Datalab dialect)",
      "model": "haiku",
      "continuationMode": "fresh",
      "description": "Mechanical extraction of both Aster submissions (original + rev2) into canonical envelope objects. No judgment: dedup, alias resolution, and validity checks happen downstream.",
      "rigSetup": [
        {
          "type": "command",
          "command": {
            "run": "mkdir -p pipeline"
          }
        },
        {
          "type": "copy",
          "copy": {
            "from": "rigs/preflight.ts",
            "to": "pipeline/preflight.ts"
          }
        },
        {
          "type": "command",
          "command": {
            "run": "bun pipeline/preflight.ts"
          }
        }
      ],
      "promptFile": "prompts/normalize-aster.md",
      "checkpointedFiles": [
        "envelope-aster.json"
      ],
      "outputFiles": [
        {
          "copy": [
            "envelope-aster.json"
          ]
        }
      ],
      "onFailure": "abort",
      "budget": {
        "maxTimeSeconds": 240,
        "maxDollars": 0.5,
        "onExceeded": "fail"
      }
    },
    {
      "id": "normalize-beacon",
      "name": "Normalize Beacon (Reducto dialect)",
      "model": "haiku",
      "continuationMode": "fresh",
      "description": "Mechanical extraction of Beacon's PDF-derived Reducto-shaped submission, including its pack pricing, part substitution, and one-time tooling charge, into a canonical envelope object.",
      "promptFile": "prompts/normalize-beacon.md",
      "checkpointedFiles": [
        "envelope-beacon.json"
      ],
      "outputFiles": [
        {
          "copy": [
            "envelope-beacon.json"
          ]
        }
      ],
      "onFailure": "abort",
      "budget": {
        "maxTimeSeconds": 240,
        "maxDollars": 0.5,
        "onExceeded": "fail"
      }
    },
    {
      "id": "normalize-cedar",
      "name": "Normalize Cedar (generic-OCR dialect)",
      "model": "haiku",
      "continuationMode": "fresh",
      "description": "Mechanical extraction of Cedar's skewed-scan OCR submission, including its OCR-confusable part id, NO_BID line, handwritten lead-time annotation, and near-term expiry date, into a canonical envelope object.",
      "promptFile": "prompts/normalize-cedar.md",
      "checkpointedFiles": [
        "envelope-cedar.json"
      ],
      "outputFiles": [
        {
          "copy": [
            "envelope-cedar.json"
          ]
        }
      ],
      "onFailure": "abort",
      "budget": {
        "maxTimeSeconds": 240,
        "maxDollars": 0.5,
        "onExceeded": "fail"
      }
    },
    {
      "id": "survey-and-extracts",
      "name": "Prepare native exports and review raw intake",
      "model": "haiku",
      "continuationMode": "fresh",
      "promptFile": "./prompts/survey-and-extracts.md",
      "rigSetup": [
        {
          "type": "copy",
          "copy": {
            "from": "rigs/native-inputs.ts",
            "to": "pipeline/native-inputs.ts"
          }
        },
        {
          "type": "command",
          "command": {
            "run": "bun pipeline/native-inputs.ts"
          }
        }
      ],
      "onFailure": "retry",
      "retryConfig": {
        "maxAttempts": 3,
        "delayMs": 20000,
        "maxDelayMs": 120000
      },
      "budget": {
        "maxDollars": 1.5,
        "maxTimeSeconds": 1800,
        "onExceeded": "complete"
      },
      "checkpointedFiles": [
        "envelope-dover.json",
        "envelope-embar.json",
        "envelope-fjord.json",
        "envelope-harbor.json",
        "envelope-iris.json",
        "survey-notes.json"
      ],
      "outputFiles": [
        {
          "copy": [
            "envelope-dover.json",
            "envelope-embar.json",
            "envelope-fjord.json",
            "envelope-harbor.json",
            "envelope-iris.json",
            "survey-notes.json"
          ]
        }
      ]
    },
    {
      "id": "validate-and-repair",
      "name": "Validate & Repair Envelopes",
      "model": "pi/baseten/deepseek-ai/DeepSeek-V4-Pro",
      "continuationMode": "fresh",
      "description": "Reads all eight supplier envelopes plus survey notes, the RFQ contract and lookups. Resolves aliases, substitutions, duplicate submissions and line extensions; quarantines GRN and routes unresolved hazards to the exception ledger.",
      "promptFile": "prompts/validate-and-repair.md",
      "rigSetup": [
        {
          "type": "copy",
          "copy": {
            "from": "rigs/native-inputs.ts",
            "to": "pipeline/native-inputs.ts"
          }
        },
        {
          "type": "command",
          "command": {
            "run": "bun pipeline/native-inputs.ts --check"
          }
        }
      ],
      "checkpointedFiles": [
        "validated-records.json",
        "exception-ledger.json"
      ],
      "outputFiles": [
        {
          "copy": [
            "validated-records.json",
            "exception-ledger.json"
          ]
        }
      ],
      "sentinels": [
        {
          "sentinelConfig": "sentinels/quality-observer.json"
        }
      ],
      "onFailure": "abort",
      "budget": {
        "maxDollars": 3.0,
        "maxTimeSeconds": 2400,
        "onExceeded": "complete"
      }
    },
    {
      "id": "reconcile",
      "name": "Reconcile to Unified Records",
      "model": "pi/baseten/deepseek-ai/DeepSeek-V4-Pro",
      "continuationMode": "fresh",
      "description": "Joins validated records against the RFQ's 5-part BOM across all 8 quoting suppliers, guarantees exactly 40 data rows, and keeps GRN only in the exception ledger.",
      "promptFile": "prompts/reconcile.md",
      "checkpointedFiles": [
        "unified-records.csv",
        "exception-ledger.json"
      ],
      "outputFiles": [
        {
          "copy": [
            "unified-records.csv",
            "exception-ledger.json"
          ]
        }
      ],
      "onFailure": "abort",
      "budget": {
        "maxDollars": 2.0,
        "maxTimeSeconds": 1800,
        "onExceeded": "fail"
      }
    },
    {
      "id": "award-brief",
      "name": "Award Brief & Exception Queue",
      "model": "haiku",
      "continuationMode": "fresh",
      "description": "Renders cited financial recommendations deterministically from reconciled rows; the agent completes only a qualitative assessment. Source-based pre-copy checks protect the financial block and the lossless exception CSV.",
      "promptFile": "prompts/award-brief.md",
      "rigSetup": [
        {
          "type": "copy",
          "copy": {
            "from": "rigs/render-exceptions.ts",
            "to": "pipeline/render-exceptions.ts"
          }
        },
        {
          "type": "copy",
          "copy": {
            "from": "rigs/render-award.ts",
            "to": "pipeline/render-award.ts"
          }
        },
        {
          "type": "command",
          "command": {
            "run": "bun pipeline/render-exceptions.ts && bun pipeline/render-award.ts"
          }
        }
      ],
      "checkpointedFiles": [
        "award-brief.md",
        "exceptions.csv"
      ],
      "outputFiles": [
        {
          "beforeCopy": [
            {
              "type": "command",
              "command": {
                "run": "bun pipeline/render-exceptions.ts --check && bun pipeline/render-award.ts --check"
              }
            }
          ],
          "copy": [
            "award-brief.md",
            "exceptions.csv",
            "unified-records.csv"
          ]
        }
      ],
      "onFailure": "abort",
      "budget": {
        "maxDollars": 1.0,
        "maxTimeSeconds": 1200,
        "onExceeded": "complete"
      }
    }
  ]
}

With the definition in place, run the anchor once with a fresh execution and an output copy:

⌁ Terminal
bunx hankweave@0.10.0 hank.json task-data --headless --start-new --execution exec --max-cost 9 --shim-idle-timeout 1800 --overwrite-output -o out

Check-it – anchor contract:

⌁ Terminal
python3 ../../verify.py chapter 5 out
bun rigs/render-exceptions.ts out --check && bun rigs/render-award.ts out --check

These checks assert the eight-supplier, 40-row contract, source references, the award brief, and the survey notes. They are stronger evidence than a zero process exit alone, and every later section builds on this baseline output.

How resume actually works in 0.10.0#

Before we interrupt anything, the resume model needs to be precise, because 0.10.0 has no --resume flag. When an execution directory already exists for the same data hash, running the hank without --start-new reuses that execution. Use --start-new (or -n/--new) when we need a new execution directory and a newly resolved plan.

A resumed execution keeps its .hankweave/state.json plan. Its resolved codon models and configuration are frozen, so editing the hank or passing --model does not re-resolve that plan. To change the model of a failed codon, start a fresh plan with --start-new; rollback resumes with the same frozen plan and does not re-resolve the hank or honor a --model change.

Two edge cases are worth knowing before they surprise us. A changed hank hash in headless mode prints Non-interactive mode, skipping confirmation prompt. and then fails with Operation cancelled by user. unless we pass -y. This confirmation case applies when we reuse an execution whose hank changed; it is not needed to resume an unchanged hank and data source. -y is the short-only flag. And if the newest execution for the data hash is already complete, the command starts the server, exits 0, and marks the run Resuming: <exec-id> – but nothing states that the execution was already complete and that no codon will run.

Check-it – reuse choice: keep the same data source and omit --start-new when we are deliberately resuming; use --start-new for an independent plan. A completed reused run is checked by its exit status and the Shutting down server: all codons completed line, not by claiming that a new codon ran.

Kill the run, then resume it#

With that model in mind, we can test it. We start a fresh headless run in one terminal, then watch its checkpoint repository from another. The checkpoint store is a non-bare shadow repository, not the project .git. Launch the run first; startup creates the repository and its initial checkpoint:

⌁ Terminal
bunx hankweave@0.10.0 hank.json task-data --headless --start-new --execution exec-kill --max-cost 9 --shim-idle-timeout 1800 --overwrite-output -o out-resume

After the run has started, wait for the completed:validate-and-repair checkpoint commit while the first terminal is still running:

⌁ Terminal
git --git-dir=exec-kill/.hankweave/checkpoints/.hankweavecheckpoints --work-tree=exec-kill/agentRoot log --oneline

Once that commit appears, press Ctrl-C in the first terminal and wait for the process to exit before resuming. The graceful shutdown keeps the sealed checkpoint. The interrupted timeline can be reported as crashed; that status records the interrupted run, while the sealed checkpoint remains available. Resume with the same execution and data, without --start-new:

⌁ Terminal
bunx hankweave@0.10.0 hank.json task-data --headless --execution exec-kill --max-cost 9 --shim-idle-timeout 1800 --overwrite-output -o out-resume

The startup information identifies isResuming: true, the matched execution ID, source path, and execution path. Only reconcile and award-brief should run after validate-and-repair has sealed; the resumed codons use their persisted models and budgets. A second Ctrl-C during shutdown escalates to force shutdown, skips checkpoints, telemetry, and state transitions, and exits 1 under the shutdown watchdog.

The captured two-codon scenario below demonstrates the same checkpoint rollback and resume mechanics on a smaller timeline, so the sequence is easier to read. Its assertion is deliberately about write-line and write-second, not about the chapter-5 codon names.

Output
[<ts>] [INFO] [DEBUG] Initializing checkpoints...
[<ts>] [INFO] Fresh run <id> - branch will be created on first checkpoint
[<ts>] [DEBUG] Built execution thread: 0 codons across 1 runs, next codon: write-line
[<ts>] [INFO] Added checkpoint patterns: out.txt
[<ts>] [INFO] [CHECKPOINT-DEBUG] Creating checkpoint for codon write-line with status completed
[<ts>] [INFO] [CHECKPOINT-DEBUG] Created checkpoint: <sha> (completed) on branch run-<id>
[<ts>] [DEBUG] Built execution thread: 1 codons across 1 runs, next codon: write-second
[<ts>] [DEBUG] Built execution thread: 1 codons across 1 runs, next codon: write-second
[<ts>] [INFO] Added checkpoint patterns: out.txt
[<ts>] [INFO] Added checkpoint patterns: second.txt
[<ts>] [INFO] Shutting down server: SIGTERM
[<ts>] [INFO] [DEBUG] Initializing checkpoints...
[<ts>] [DEBUG] Built execution thread: 2 codons across 1 runs, next codon: none
[<ts>] [DEBUG] Built execution thread: 2 codons across 1 runs, next codon: none
[<ts>] [INFO] Found last successfully completed thread codon to rollback to: {"codon":{"codonId":"write-line","startTime":"<ts>","status":"completed","claudePid":"<pid>","claudeLogPath":".hankweave/runs/<id>/write-line-claude.log","claudeSessionId":"<session>","currentCost":0.01025235,"currentTokens":{"inputTokens":"<n>","outputTokens":"<n>","cacheCreationTokens":"<n>","cacheReadTokens":"<n>"},"assistantMessageCount":4,"extensionCount":0,"endTime":"<ts>","exitCode":0,"finalCost":"<n>","finalTokens":{"inputTokens":"<n>","outputTokens":"<n>","cacheCreationTokens":"<n>","cacheReadTokens":"<n>"},"resultMessageReceived":true,"completionCheckpoint":"<sha>"},"runId":"<id>","runStatus":"crashed","runStartTime":"<ts>","runEndTime":"<ts>","gitBranch":"run-<id>","globalIndex":1,"runIndex":0,"codonIndexInRun":0,"validatedCheckpoints":[],"continuationSessionId":null}
[<ts>] [INFO] Starting codon-by-codon rollback to completed checkpoint <sha> in codon write-line (Write one line)
[<ts>] [ERROR] Target checkpoint <sha> not found in manifest, returning all entries
[<ts>] [INFO] Found 0 archive entries to restore during rollback
[<ts>] [INFO] Checked out checkpoint <sha7> (detached HEAD)
[<ts>] [DEBUG] Built execution thread: 1 codons across 2 runs, next codon: write-second
[<ts>] [DEBUG] Built execution thread: 1 codons across 2 runs, next codon: write-second
[<ts>] [DEBUG] [getNextCodonToExecute] Execution thread determined next codon: write-second
[<ts>] [INFO] Added checkpoint patterns: out.txt
[<ts>] [INFO] Added checkpoint patterns: second.txt
[<ts>] [DEBUG] Built execution thread: 2 codons across 2 runs, next codon: none
[<ts>] [INFO] [CHECKPOINT-DEBUG] Creating checkpoint for codon write-second with status completed
[<ts>] [INFO] [CHECKPOINT-DEBUG] Created checkpoint: <sha> (completed) on branch run-<id>
[<ts>] [DEBUG] Built execution thread: 2 codons across 2 runs, next codon: none
[<ts>] [DEBUG] Built execution thread: 2 codons across 2 runs, next codon: none
[<ts>] [INFO] Shutting down server: all codons completed
[<ts>] [INFO] Shutting down sentinel manager...
[<ts>] [INFO] Shutdown: all codons completed (exit code: 0)

Two lines in that log deserve attention. The Target checkpoint … not found in manifest line is the captured manifest-lookup warning; the later Checked out checkpoint <sha7> (detached HEAD) line is the actual shadow-git restore, after which write-second completes. The capture proves the warning and recovery sequence, not the warning's root cause. The companion assertion counts start events across both runs:

Output
codon.started events across both runs — write-line: 1 · write-second: 2 (codon 1 was sealed before the kill, so it must start exactly once)

Roll back one codon#

Resume moves an execution forward from its last sealed checkpoint; rollback moves it backward to an earlier one. Rollback is an interactive TUI (terminal user interface) or WebSocket-client operation, not a CLI flag. The earlier runs were headless, so start a separate interactive execution for this exercise; the TUI is the default when we omit --headless:

⌁ Terminal
bunx hankweave@0.10.0 hank.json task-data --start-new --execution exec-rollback --max-cost 9 --shim-idle-timeout 1800 --overwrite-output -o out-rollback

After the run completes, press r for the rollback menu, choose 2 to list checkpoints, select the validate-and-repair checkpoint whose type is completed, and confirm with y. The TUI sends rollback.toCheckpoint with the selected checkpoint SHA; the raw WebSocket rollback.toCodon command is for a client that sends the command directly, not a literal TUI menu selection. The protocol reference owns the complete command signatures. The runtime journals each stage of the operation, and the emitted events are:

Scroll to explore the table →
idcategoryjournaledsentinelRoutedpayloadFieldsreceipts
rollback.codonCheckpointserver-statetruetruecodonId, codonName, checkpoint, checkpointType, messageschemas/event-schemas.ts:647, schemas/event-schemas.ts:971, schemas/event-schemas.ts:1252, hankweave-runtime.ts:4684, hankweave-runtime.ts:5136, hankweave-runtime.ts:5191
rollback.completedserver-statetruetruefromRun, toRun, checkpoint, codonId, codonName, checkpointType, autoRestartschemas/event-schemas.ts:662, schemas/event-schemas.ts:972, schemas/event-schemas.ts:1255, hankweave-runtime.ts:4722, hankweave-runtime.ts:5254
rollback.progressserver-statetruetruecurrentStep, totalSteps, messageschemas/event-schemas.ts:657, schemas/event-schemas.ts:970, schemas/event-schemas.ts:1254, hankweave-runtime.ts:5117, hankweave-runtime.ts:5156
rollback.startedserver-statetruetruefromRun, fromCodon, toCodon, toCheckpoint, checkpointType, codonsToProcessschemas/event-schemas.ts:642, schemas/event-schemas.ts:969, schemas/event-schemas.ts:1251, hankweave-runtime.ts:4645, hankweave-runtime.ts:5095

Rollback restores the working directory to the selected checkpoint, then a resumed run regenerates unified-records.csv and award-brief.md through reconcile and award-brief. The checkpoint before validate-and-repair remains untouched, and the old timeline remains inspectable because the resumed run creates a new branch from the detached checkpoint state.

The checkpoint repository has an explicit layout: GIT_DIR=exec-rollback/.hankweave/checkpoints/.hankweavecheckpoints and GIT_WORK_TREE=exec-rollback/agentRoot. If rollback reports Target checkpoint … not found in manifest even though the commit is in the log, inspect the shadow repository and recover from the checkpoint commit whose subject begins error:<codonId> or completed:<codonId>–these are commit subjects, not git tags:

⌁ Terminal
git --git-dir=exec-rollback/.hankweave/checkpoints/.hankweavecheckpoints --work-tree=exec-rollback/agentRoot log --oneline --decorate
checkpoint_sha="$(git --git-dir=exec-rollback/.hankweave/checkpoints/.hankweavecheckpoints --work-tree=exec-rollback/agentRoot log --format='%H %s' | awk '$2 ~ /^(error:|completed:)/ { print $1; exit }')"
git --git-dir=exec-rollback/.hankweave/checkpoints/.hankweavecheckpoints --work-tree=exec-rollback/agentRoot checkout --detach "$checkpoint_sha"

Copy the needed files from exec-rollback/agentRoot into a separate recovery directory before continuing; do not inspect the project .git as a substitute for this shadow repository.

Check-it – rollback: after the TUI operation and resumed run, check the regenerated output copy and the two output hooks:

⌁ Terminal
python3 ../../verify.py chapter 5 out-rollback
bun rigs/render-exceptions.ts out-rollback --check && bun rigs/render-award.ts out-rollback --check
git --git-dir=exec-rollback/.hankweave/checkpoints/.hankweavecheckpoints --work-tree=exec-rollback/agentRoot log --oneline --decorate

Confirm that unified-records.csv and award-brief.md were regenerated in out-rollback and that the checkpoint before validate-and-repair is still present in the explicit shadow-repository log. The captured scenario log supplies the rollback diagnostic, but its write-line and write-second names are not chapter-5 results.

Trace one dollar figure to its source#

The operations so far prove the pipeline can stop and restart; this section checks whether its output can be believed. We follow one award amount instead of trusting a final paragraph. The award brief cites a source document and block; the unified-records row repeats the document, quote, line, and block identifiers; the validated record and envelope lead back to the digitized source. Here, source evidence means the input files under task-data/digitized/ and task-data/digitized-extracts/: normalize codons copy those fields without judgment, while validate-and-repair changes only derived records and exception decisions, not those input files. award-brief renders what upstream stages settled. The excerpt below shows the award table and the first rows of the unified records it projects from; note the [doc:block] citations attached to every figure.

MARKDOWN
Projection of unified-records.csv only. Rank QUOTED, ranking_eligible=true rows by line_extension_minor; break equal-price ties by supplier_code ascending. Unit prices are already normalized per each upstream. No eligible bid means no recommendation; unsupported data stops export rather than inventing a price or citation.

| Buyer part | Selected supplier | Unit price (USD per each) | Line extension (USD) | Tie / no-bid decision | Ineligible QUOTED suppliers |
| --- | --- | --- | --- | --- | --- |
| NC-1001-A | BCN | $3.95 [doc-beacon-8821:doc-beacon-8821-b1] | $1,975.00 [doc-beacon-8821:doc-beacon-8821-b1] | Unique lowest eligible bid | CDR [doc-cedar-cw-77:doc-cedar-cw-77-b1] |
| NC-1002-A | AST | $0.79 [doc-aster-qb-1047-rev2:doc-aster-qb-1047-rev2-b2] | $1,580.00 [doc-aster-qb-1047-rev2:doc-aster-qb-1047-rev2-b2] | Unique lowest eligible bid | CDR [doc-cedar-cw-77:doc-cedar-cw-77-b2] |
| NC-1003-B | EMB | $1.05 [doc-embar-quote:doc-embar-quote-b3] | $1,050.00 [doc-embar-quote:doc-embar-quote-b3] | Unique lowest eligible bid | CDR [doc-cedar-cw-77:doc-cedar-cw-77-b3] |
| NC-1004-A | AST | $6.40 [doc-aster-qb-1047-rev2:doc-aster-qb-1047-rev2-b4] | $160.00 [doc-aster-qb-1047-rev2:doc-aster-qb-1047-rev2-b4] | Unique lowest eligible bid | None |
| NC-1005-A | BCN | $0.19 [doc-beacon-8821:doc-beacon-8821-b5] | $950.00 [doc-beacon-8821:doc-beacon-8821-b5] | Unique lowest eligible bid | CDR [doc-cedar-cw-77:doc-cedar-cw-77-b5] |
CSV
supplier_code,buyer_part_id,rfq_rev,qty,unit_price_minor,price_basis,line_extension_minor,currency,status,ranking_eligible,source_document_id,source_quote_id,source_line_id,source_block_id
AST,NC-1001-A,B,500,410,PER_EACH,205000,USD,QUOTED,true,doc-aster-qb-1047-rev2,q-aster-qb-1047-rev2,doc-aster-qb-1047-rev2-L1,doc-aster-qb-1047-rev2-b1
AST,NC-1002-A,B,2000,79,PER_EACH,158000,USD,QUOTED,true,doc-aster-qb-1047-rev2,q-aster-qb-1047-rev2,doc-aster-qb-1047-rev2-L2,doc-aster-qb-1047-rev2-b2
AST,NC-1003-B,B,1000,115,PER_EACH,115000,USD,QUOTED,true,doc-aster-qb-1047-rev2,q-aster-qb-1047-rev2,doc-aster-qb-1047-rev2-L3,doc-aster-qb-1047-rev2-b3

Choose the NC-1001-A Beacon amount. Follow its [doc-beacon-8821:doc-beacon-8821-b1] citation to the Beacon row with the same supplier_code and buyer_part_id, then inspect validated-records.json and the matching envelope-beacon.json in the execution's agentRoot; the cited source block is under task-data/digitized/ or task-data/digitized-extracts/. The output copy has the first two files needed for this walk (out/award-brief.md and out/unified-records.csv), while intermediate files remain under exec/agentRoot. The four source columns are source_document_id, source_quote_id, source_line_id, and source_block_id; they are the chain-of-custody fields to inspect.

Check-it – citation chain: run the chapter check, then verify that the chosen amount has a [doc:block] citation and that its source reference reaches a digitizer block without a broken link:

⌁ Terminal
python3 ../../verify.py chapter 5 out
bun rigs/render-exceptions.ts out --check && bun rigs/render-award.ts out --check

render-exceptions.ts serializes the exception ledger; the financial projection is derived from unified-records.csv, while the agent supplies only the qualitative assessment. These checks therefore verify exported structure and source-based projections, not the semantic truth of the agent's narrative.

What happens at a cheaper model tier#

The last exercise changes one variable: the model behind the judgment codons. For an independent comparison, use a fresh execution and a separate output directory. The five mechanical codons already use haiku; --model haiku changes the two judgment-heavy codons, validate-and-repair and reconcile, from the Baseten model to haiku.

⌁ Terminal
bunx hankweave@0.10.0 hank.json task-data --headless --start-new --model haiku -y --execution exec-haiku --max-cost 9 --shim-idle-timeout 1800 --overwrite-output -o out-haiku

Check the fresh run independently, then compare its records and exception ledger with the mixed-model output. Do not treat a difference as proof that the cheaper model is always wrong; inspect which judgment-heavy artifact changed and why. The mixed-model chapter receipt records $0.71 in tracked codon cost for one complete execution; configured caps total $9.00, and neither number predicts the cost or accuracy of this new run.

Check-it – model comparison:

⌁ Terminal
python3 ../../verify.py chapter 5 out-haiku
diff -u out/unified-records.csv out-haiku/unified-records.csv || true
diff -u out/exception-ledger.json out-haiku/exception-ledger.json || true

Record the artifact-level differences, rather than a blanket model-quality verdict. The fresh --start-new and separate paths are what make this a comparison instead of a re-plan of the existing execution.

Account for all eight suppliers#

One structural detail of the hank deserves a closer look, because it explains where the full supplier count comes from. The three hand-digitized dialects cover 15 rows from the earlier chapters. To account for the remaining suppliers, we add five native exports – Dover, Embar, Fjord, Harbor, and Iris – through the pre-built survey-and-extracts codon at position four. rigs/native-inputs.ts deterministically parses those exports into envelopes and starts survey-notes.json with complete: false; the agent inspects unmatched intake and records quarantine decisions. It does not retype or re-parse the native exports. The broader contract is eight suppliers and 40 data rows, with GRN quarantined.

Check-it – coverage: run the deterministic chapter check after the run and inspect survey-notes.json; confirm that the structured output covers the eight named suppliers and that the unknown intake is represented in the exception path rather than guessed into a ninth supplier.

What can go wrong#

The failure modes in this chapter are mostly about timing and plan reuse. If we interrupt before any checkpoint seals, resume has no checkpoint to restore and starts again from the first codon. Wait for a completed: entry before pressing Ctrl-C. If we omit --start-new after a failed attempt, the existing execution's frozen plan wins. If rollback reports a missing manifest entry, use the explicit shadow-repository paths above and recover from the checkpoint commit whose subject begins error:<codonId> or completed:<codonId> in the shadow-repository log (commands above).

After checking a model-tier difference, we can return to the same evidence: roll back to validate-and-repair and run reconcile and award-brief again.

Check-it – chapter recap: confirm the checkpoint log, the structured output checks, the rollback diagnostic, and the side-by-side artifact comparison before repeating the rollback-and-rerun path.