How recite works
How Haiku turns a .haiku file into a runnable test, and how the cache keeps repeated runs fast.
haiku recite is the single command you run. Behind it, every spec passes
through two internal stages: a compile step (English → native test
artifact) and a run step (execute that artifact through your language's
real test runner). Recite handles both, transparently, and caches the
compile output so repeated runs are instant.
The compile step
Compilation takes a .haiku source and produces the artifact its target
runner expects:
| Input | Output | Runner |
|---|---|---|
login.ios.haiku | login.ios.sim | xctest-driver |
test_foo.py.haiku | test_foo.py | pytest |
cache.rs.haiku | cache_test.rs | cargo test |
auth.go.haiku | auth_test.go | go test |
invoice.ts.haiku | invoice.test.ts | (TS runner — experimental) |
The output is written next to the input file. Compilation uses local AI
inference — your .haiku content never leaves the machine.
The compile cache
Compilation is the slow part. Once a spec has been compiled, Haiku caches the output and keeps using it until the source changes.
The cache lives in two places:
- For iOS, the compiled
.simfile next to the.haikusource carries a hash of the source in its header. If the source's hash still matches, the cache is fresh. - For backend specs, the generated test file (e.g.
test_foo.py) carries a# haiku-source-hash: <sha256>header for the same purpose.
Pass --fresh (alias --no-cache) to bypass the cache and re-run
inference from scratch. Useful when you want to retry compilation after
editing the spec or swapping coder models.
The cache has a default 7-day TTL. Override with HAIKU_CACHE_TTL_DAYS.
The run step
After compile (or cache hit), Haiku hands the artifact to your language's real test runner. The output is a step-by-step verdict with an exit code:
| Exit code | Meaning |
|---|---|
0 | All steps passed |
1 | One or more steps failed |
2 | I/O, parse, or infrastructure error |
haiku recite accepts three input shapes:
- A
.haikusource — Haiku compiles if needed (or hits the cache), then runs - A
.simaction sequence — runs directly (iOS only) - A generated backend test file (e.g.
test_foo.py) — runs directly
Trace logs
Every recite and record invocation produces a forensic trace log. By
default it lands in /tmp/haiku-<cmd>-<timestamp>.log and the path is
printed to stderr at the start of the run. Pass --trace for a sticky
path next to the compiled output, or --trace=PATH for a custom location.
tail -f works live — every write is flushed.