# connector-build-test A Clausetta-derived polymorphic build fixture: a fixed spec + a deterministic `bun test` eval suite + an agentic build loop that starts fresh each iteration and reads the failing test output from disk. The fixture behind `examples/connector-build-test` and the build-loop object quoted by `author/patterns/composition`. ## Tree ``` hank.json research → build loop (implement codon) → document spec.md fixed connector contract (≤60 lines) tests/connector.test.ts deterministic eval suite (bun test, zero deps) prompts/research.md haiku — reads spec + tests, writes notes.md prompts/build.md haiku — "check for existing work" preamble, writes connector.ts prompts/document.md haiku — writes IMPLEMENTATION.md data/input.json fictional records (the connector's fixture input) expected/ captured validate output + MANIFEST.md ``` There is deliberately **no `connector.ts`** in the fixture: the build loop discovers it. The eval suite imports `../connector` and fails (iteration 0) until the agent writes it. ## Per-codon rationale - `research` (haiku, fresh) — gathers the contract. Its rig copies `spec.md` and `tests/` into the agent workspace (command rigs run in the workspace, so the files must be copied first), then the codon writes `notes.md`. - `build` loop, one `implement` codon (haiku, fresh) — each iteration starts a new session. Its rig re-copies `spec.md` + `tests/` and runs `bun test 2>&1 | tee test-output.txt` with `allowFailure: true`; the prompt's "check for existing work" preamble tells the agent to read `connector.ts` and `test-output.txt` before writing, so it resumes rather than restarts. - `document` (haiku, fresh) — writes `IMPLEMENTATION.md`; its `outputFiles` copy (`IMPLEMENTATION.md`, `connector.ts`) is gated by a `beforeCopy` `bun test` run, so only passing code is copied out (and only when the run is given `-o`). ## Run + validate ```sh bunx hankweave@0.10.0 hank.json data/ --validate # prints the GOOD TO RUN! box bunx hankweave@0.10.0 hank.json data/ --headless --start-new -o out ``` Expected: `research` → `implement#0` (tests fail) → `implement#1` (tests pass) → `implement#2` (tests still pass, agent leaves the file alone) → `document`, exit 0. `bun test` should be green by iteration 2 on haiku. See `expected/MANIFEST.md`. ## Notes / tensions - **Loop id vs codon id**: the runtime rejects a loop and its child codon sharing an id (`Duplicate codon ID`), so the loop is `build` and its single codon is `implement` (runtime ids `implement#0…implement#2`). The fixture spec that named both "build" is satisfied by the loop keeping the `build` id. - **The `tee` pipe**: `bun test 2>&1 | tee test-output.txt` puts the test output on disk for the agent, but the pipe makes the rig command's own exit status `tee`'s (0) — so `allowFailure: true` is retained per the schema's loop-rig recommendation but is effectively a no-op guard here. The test result is read from `test-output.txt`, not the exit code. (This is the `|| true` + `allowFailure` double-guard smell the reliability brief flags; the pipe is required here for the disk handoff.) - `--validate` emits a warning that loop rigs should use `allowFailure: true`; the two copy rigs always succeed (their sources live in the hank dir), so only the test command carries `allowFailure`.