You're reading the 0.10.0 archive.

Discover the workflow before you freeze a hank

A hank is a frozen workflow. Freezing one well means knowing what the workflow actually is: which prompts produced good output, what information the agent needed but lacked, and where one task should end and the next begin. None of that is visible from a blank hank.json. It becomes visible when you do the task with a coding agent and pay attention to what happens.

This page walks through that process in the order you will do it: run the task until it works, study what the session needed, sketch a structure, freeze the smallest working piece, and iterate until the run no longer needs you watching it. By the end you will have a validated hank built from evidence rather than guesses, plus a clear signal for when to stop adding to it.

Start with the coding agent, not the hank file#

Work with a coding agent until something works, observe what helped, freeze it into structure, and iterate. We discover the workflow before we decide how to preserve it.

Think of Hankweave as amber and the working workflow as the mosquito: what matters is the information we preserve. A useful sequence of operations, a prompt that gets good results, or a clarification that prevents a wrong turn can otherwise disappear with the conversation. A hank gives those discoveries a form we can share, run again, and improve together. Preserving the workflow does not make every future model response identical.

The loop looks like this, and it repeats as often as needed:

FIG. 1 CCEPL loop
Read the diagram as text
Output
Work with a coding agent
          |
          v
Observe what worked
  most failures are missing information
          |
          v
Distill into a prompt
          |
          v
Freeze into a codon
  mostly copying prompts you already proved — boring on purpose
          |
          v
Run & iterate
          |
          +-------- repeat if needed -------->
                       Work with a coding agent

This practice has a name: CCEPL, the Claude Code Eval Print Loop. It works with any coding agent; the name stuck. The acronym names the practice, not an extra stage in the loop.

The original CCEPL practice starts with a folder containing process.md and workspace/. Load process.md into the agent. When the task fails, route missing documentation or fragile code to workspace/, and route direction or instruction problems to process.md. Restart the agent after the fix. When the work is done, write a hank.json that links those two artifacts.

Two terms carry the rest of this page. A codon is the smallest working piece you freeze: one sealed agent task in the sequence. A checkpoint seals the files a later codon needs to carry forward. Freezing a codon is mostly copying prompts you already proved in a session–boring on purpose; designing checkpoint boundaries is the thinking part.

If you are still deciding whether to write a hank or keep working interactively, start with whether Hankweave is right for you. The rest of this page assumes you have a workflow you want to use again.

Do the task until it works#

Do not start by writing a hank. Do the task yourself with a coding agent and ignore structure while you explore. You cannot freeze something that does not exist, and a hank encoding an undiscovered workflow is a guess.

For repeat work, do the task two or three times when possible. Each pass surfaces prompts that worked, information you had to supply, and where the agent went wrong. Those observations become the hank's structure in the later steps.

While you explore, track problems instead of TODOs. Ask, "Where does data come from?" and "What output does the user need?" A sequential TODO list linearizes interdependent tasks and becomes fragile when one task depends on another.

For a simpler task, use this named pattern; the fence is a label, not a command:

Output
Just Do It First
  1. Do the task directly, as a coding agent normally would.
  2. See the process, the decisions, and the outputs.
  3. If it worked well, freeze it into a hank.
  4. Base the hank on real experience, not speculation.

This catches one-off tasks that do not need hank complexity. If you are unsure whether the task is repeat work at all, decide that in whether Hankweave is right for you before continuing here.

The anchor hank's first attempt shows why the direct pass matters. It was written against the corpus specification without first trying the real data. Rig paths, a richer corpus than the plan, budget sizing, and hazard rules all needed attention once it ran. A specification describes intent; a session reveals the work.

Check-it: Review your exploration notes and list the prompts that worked, information you supplied, wrong turns, and problems you saw. If the list contains assumptions you have not tested, do another direct pass before freezing them.

Observe what the session needed#

Once something works, stop and look at what happened before you freeze anything. Three questions turn a transcript into design decisions.

What did the agent need to know? Go through the conversation. Every time you provided information–context, constraints, preferences, clarifications–that is something the agent needed but did not have.

The most common failure class when an agent goes wrong is an information failure, not an intelligence failure: it did not know one of your preferences and made a judgment call in a different direction. It used Python instead of TypeScript, structured code differently, or chose a different library. These are failures of information, not intelligence, and they are the failures a hank can actually prevent.

What did the agent do that you could have given it? Did it write a setup script? You could provide one. Did it figure out an API? You could give it documentation. Anything the agent had to figure out is a source of variance.

At freeze time, decide whether to make deterministic work a rig–a script for setup that needs no judgment–or prompt content for work that needs judgment.

Where are the natural breakpoints? If you were handing this off to someone else, where would you draw the line? "I'll do research, you implement." "I'll set up, you code." These handoff points are where codon boundaries probably should be.

Use the boundary checklist to weigh model tier, failure policy, and whether a person needs to inspect the intermediate artifact.

Observation also catches failures that a successful-looking transcript hides. One observed attempt ended "success" after 15k tokens of thinking but wrote no file. The next attempt required the agent to create a skeleton first, write in increments, and verify the file before finishing. That protocol came from the failure; it would have been difficult to predict from a blank hank file.

Check-it: Find the first failed attempt in your session notes and state what information or verification was missing. Decide whether the fix belongs in a prompt, a rig, or a prerequisite check.

Sketch the skeleton before any prompt#

The observations from the last step need a shape before they become prompts. Sketch the overall structure in a planning document with four sections: Input, Phases, Key Decisions, and Open Questions. Mark every phase tight or loose to record how much freedom it gets, and record model-tier choices under Key Decisions.

A worked sketch can look like this:

MARKDOWN
# Code Review Hank - Structure

## Input to collect

- Code to review

## Phases to run

1. **Analyze** (tight) - Categorize files and identify entry points
2. **Deep Review** (loose) - Explore and follow useful threads
3. **Synthesize** (tight) - Generate a structured report
4. **Refine Loop** (2-3 iterations) - Use fresh context each time

## Key Decisions to record

- Use a lower-cost model for structured analysis
- Reserve a stronger model for synthesis when the pilot shows it helps

## Open Questions to resolve

- What still needs an answer before the prompts are written?

Notice that the sketch names inputs and decisions without writing any prompt text. That is the point: with the skeleton on paper, we can check dependencies and decide where tight or loose constraints fit before writing the details. It also leaves our decisions available to the next person who changes the hank. For tight-versus-loose semantics and codon-weight estimation, see designing codons and handoffs.

Then test the sketch against the work you actually observed. The anchor hank began with three supplier-normalization steps. A live pass found five more native exports and one unmatched Granite intake, so the plan gained survey-and-extracts instead of stretching an existing prompt to hide the extra work.

That new codon draws a useful boundary. Its native-inputs.ts rig parses the five recognized exports and creates an incomplete intake survey. The model reviews only the unmatched file and records the quarantine decision. survey-notes.json and the five generated envelopes make the handoff inspectable, and bun pipeline/native-inputs.ts --check verifies the generated envelopes and complete intake coverage before validation proceeds.

The result is the current seven-codon hank: five codons use Haiku, and two judgment codons use pi/baseten/deepseek-ai/DeepSeek-V4-Pro. Here is the added codon as shipped; note how the rig setup, retry policy, budget, and checkpointed files each correspond to a decision from the sketch:

JSON
    {
      "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"
      ],

The word "mechanical" describes the decisions assigned to a normalization codon; it does not make model extraction infallible. A model can still misread a value, omit a field, or fail to write its file. The current three normalization codons therefore use onFailure: "abort" and onExceeded: "fail". The survey codon uses onExceeded: "complete" only because interrupted output may be preserved for inspection and is checked before downstream use. A cap does not grant the model more time to finish; the runtime requests interruption first, then records the outcome selected by onExceeded.

The fixture's historical design notes remain available if you want to see the earlier plan. Treat them as an iteration record, not as the current contract.

Check-it: For every phase in your planning document, name its input, output, tight-or-loose constraint, and verification step. Confirm that the document still has Input, Phases, Key Decisions, and Open Questions.

Freeze the smallest working piece#

With a tested sketch in hand, freeze the smallest thing that works: one codon, one prompt, and a basic rig. Do not anticipate every case; you do not know what will break until you run it.

A rig is a script for deterministic setup or other work that does not need judgment. Keep the rig and the checkpoint small at first.

Before spending tokens on a run, validate the hank:

⌁ Terminal
bunx hankweave@0.10.0 ./hank.json ./task-data --validate

At 0.10.0, --validate hashes the input, resolves and validates the configuration, and performs harness setup, credential, and model-catalog checks. Its provider registry disables provider health checks for this command, and validation does not execute a codon or make a model-generation self-test. It may add $schema to the hank and writes a temporary validation log. It is not a universal offline or connectivity guarantee: Bedrock credential discovery can probe instance metadata. Runtime startup health checks are separate and can make provider calls.

A passing validation prints a GOOD TO RUN! box summarizing what the hank contains:

Output
╭─ GOOD TO RUN! ─────────────────────────────────────────────────────╮
│  1 codons • 1 prompts • 0 system prompts • 0 rigs • 1 checkpoints  │
╰────────────────────────────────────────────────────────────────────╯

The captured minimal run recorded actual service output and a tracked codon cost of $0.01394590; provider health checks and sentinel calls are separate. See the quickstart for the full cost explanation.

When you write the prompt itself, prefer a single-shot prompt to freezing only the final turn of a multi-turn transcript. If you freeze a prompt-response-correction conversation as that final turn, you lose the correction turns, so the codon lacks part of the information it needed.

Place each discovered piece of knowledge in its natural home:

  • Global system prompt: what every codon needs.
  • Codon system prompts: conventions shared by some codons.
  • Codon prompts: situation-specific steps and the growing guidelines block.
  • Rigs: scripts born in the session.
  • Prerequisite checks: environment expectations that should fail early.

Put deterministic work in rigs and judgment work in prompts. See rigs for the setup contract.

Build incrementally from there. Make codon 1 work, then add codon 2 and run both. When the new codon needs outputs you have already verified, stage those files in a named execution's agentRoot/ and start a fresh run against the same hank and data:

⌁ Terminal
mkdir -p ./incremental-exec/agentRoot
cp envelope-aster.json ./incremental-exec/agentRoot/
bunx hankweave@0.10.0 ./hank.json ./task-data --execution ./incremental-exec --start-new --force --no-wipe

This example names the hank (./hank.json), prepared data (./task-data), and execution (./incremental-exec). --no-wipe is intentional: with an explicitly selected execution, --start-new --force backs up existing .hankweave/ state, while --no-wipe retains the staged agentRoot/ files. Without --execution, --start-new creates a new managed directory; it does not select or wipe the previous workspace. Otherwise, resume the recorded execution instead of expecting a new codon list to re-plan it automatically. Use the minimal-valid first file when you need the first valid hank.json.

Check-it: Run validation and confirm that the output includes GOOD TO RUN! and reports 1 codons • 1 prompts • 0 system prompts • 0 rigs • 1 checkpoints.

Iterate to the Control-C point, then stop#

A frozen codon is a hypothesis. Running it tells you whether the hypothesis holds, and the first runs usually fail. When they do, diagnose the symptom rather than adding structure at random:

Scroll to explore the table →
SymptomLikely causeFix
Rig errorsSetup did not workImprove the rig
Agent confusionCodon is doing too muchSplit it into multiple codons
Wrong outputPrompt is unclearRevise the prompt
Different from expectedMissing preferencesAdd them explicitly

Each fix moves the Control-C point: the moment when you watch a run and want to stop it. As you iterate, that point should move further out: the first run may reach it at 30 seconds, the second at 2 minutes, and the third at 5 minutes. When you can let the codon complete without intervention, it is frozen enough.

A codon is done when it completes reliably, finishes within context, leaves clean logs, and lets you walk away. It is not done when it works only sometimes, needs intervention, or does something you do not understand.

Add complexity only when evidence calls for it: a consistent failure or a clear missing step. Stop when the codon works reliably or when you are adding protection for a problem you have not seen. When in doubt, stop; more can be added later.

Iteration means running, and running has a few mechanics worth knowing before you start. Run from the directory containing the hank and pass the data directory as the positional argument. Hankweave mounts that directory under read_only_data_source/ inside the execution directory, so prompts use read_only_data_source/... paths regardless of the corpus's real location. The read_only name is semantic; the runtime symlinks or copies the data and does not provide OS-level write protection.

Each run creates a managed execution directory under ~/.hankweave-executions/<id>. Its state is at <exec>/.hankweave/state.json, and its event journal is at <exec>/.hankweave/events/events.jsonl. For output-directory behavior, use the runbook.

During a learning run, the headless console is quiet while codons run. Monitor files in agentRoot/ and events.jsonl. Each completed codon emits a codon.completed event like this one from the captured journal:

Output
{"id": "<id>", "timestamp": "<ts>", "type": "codon.completed", "data": {"codonId": "summarize-notes", "success": true, "cost":"<n>", "duration":"<n>", "exitStatus": {"type": "success"}}}

The run closes with a RunCompleted transition. The headless console prints nothing after ➜ Listening on; first-run.txt ends at exit=0, while [<ts>] [INFO] Shutdown: all codons completed (exit code: 0) appears only in .hankweave/logs/server.log.

A hank can pass validation and still fail before its first codon when a required key is missing. The startup self-test reports authentication: No authentication found (set ANTHROPIC_API_KEY) before any codon runs. See the quickstart failure step for that expected capture.

Budget caps deserve the same evidence-based treatment as codon structure. Size freeze-time budget caps at least twice your estimate for expensive codons; an estimate-equal cap can interrupt work after you have already paid for model output. When any cap trips, the runtime requests interruption. onExceeded: "complete" then records the codon as completed, while onExceeded: "fail" records a failure. Neither policy gives the model extra reasoning time.

Choose complete only when partial output is useful and an explicit check protects downstream work. In the anchor, survey-and-extracts can preserve an interrupted survey, but bun pipeline/native-inputs.ts --check must verify complete coverage before validate-and-repair begins. reconcile uses fail because a truncated 40-row table must not pass as complete. See what happens when a cap trips for the full policy.

When every codon is past its Control-C point, the hank graduates to testing and hardening, then to maturing and versioning.

Check-it: Let a full run complete without intervention. Confirm one codon.completed event per codon and a closing RunCompleted transition in events.jsonl. Use the captured journal line above for the completion observable; the headless console's shutdown wording is not part of that capture.