HEDDLE

Architecture

Operating principles

Five principles the CLI ships by. Every command in the CLI reference is auditable against them. They're the behaviour contract — what callers (humans, agents, scripts, CI) can rely on without reading the source.

1. Trust

Outputs say what they mean. Field names are stable across verbs — a thread called thread in heddle thread show is called thread in heddle review show too. Optional fields serialise as explicit null, not by omission; empty collections as [], not omitted. JSON consumers can rely on shape.

Failure quality is part of the contract. Predicates like is_out_of_space and is_permission_denied reflect actual kernel signals on every supported platform — they don't squint at error message strings. CI can branch on them confidently.

2. Disposability

Speculation has no cost. heddle try spins up an ephemeral thread with an isolated checkout — failed, you drop it; succeeded, you promote it. heddle attempt N runs the same task N times in parallel and ranks the outputs. Forking, branching, restarting are cheap by design.

When trying ten things costs about the same as trying one, the agent's strategy changes.

This is the principle behind fork from capture: the cost of exploration is what shapes what agents try.

3. Composability

The same primitives appear in multiple verbs because the right ones were chosen first. A thread is a thread whether it came from heddle start, heddle try, heddle attempt, or heddle delegate. State ID specifiers — full change ID, 4-char prefix, marker name, HEAD, HEAD~N, thread name — all work across 15 verbs. One acceptance rule, fifteen verbs.

Practical consequence: if you write a tool that consumes Heddle output, you don't need a per-verb parser. The shapes that appear in one place appear in all places.

4. Restraint

Everyday heddle help curates eleven verbs — the ones a new user actually needs. heddle help advanced reveals the rest. The intent is that the surface a first-time user sees is the surface that supports their first hour, not the full 40+ command catalog all at once.

The 4-char short ID for states works for the same reason — nobody types a full BLAKE3 hash in practice, so the everyday surface defaults to the short form, and the full form is available when an integration needs it.

5. Honesty

Claims match behaviour. MergeOutput separates blockers (the merge can't proceed) from warnings (the merge proceeded but flagged something). The status field follows the truth — it doesn't lie when there's a partial failure.

heddle capture --confidence is honest by convention: ≥0.9 only when every signal passed, 0.75–0.89 when most did, <0.75 for drafts. The number is operator-supplied, but it's expected to mean what it says.

Auditing against the principles

When reviewing a new verb or a behaviour change, walk it against the five:

  • Trust — are field names consistent with existing verbs? Are nulls / empties explicit?
  • Disposability — can a caller speculate cheaply? Does abandonment cost real time?
  • Composability — does this take the same state-spec / thread-spec arguments the rest of the surface does?
  • Restraint — is this an everyday verb or an advanced one? Did heddle help get longer than 11 lines?
  • Honesty — does the output's status reflect what actually happened?

A "no" on any of them is a signal to revisit the design, not necessarily a blocker. The principles are the contract we ship to — the goal is that the contract holds across the whole catalog.