How throughline was used · a worked example · 20 September 2026

A Postal Box on a Throughline

The technical account

One graph of 71 items, all written by the AI and all signed by the person before the code they govern; a tool built to it in forty-three minutes with one test per test item; a design change that narrowed a signed non-goal and went through the graph first; five rounds of ratification, and thirteen items that moved after signing, every one reported.

Two pagesThis page is for a reader who wants the machinery. The account for a general reader tells what happened, who did what and what it cost.
1graph, eight registers, composing no source
71items, all of AI origin, all ratified by the person: 66 before the code, 5 for the change of mind
5rounds of ratification: 66 on a hand-off, 3 on instruction, 12 read in a terminal, then 1 and 1
13items amended after ratification, each reported by the tool at the amend
35test items, one test function each; 43 pass, 1 skipped for the network, 0 fail

The tool, and the contract

Throughline is a Git-native requirements tool: one small YAML file per item, a permanent UID, typed links, and a validator that fails the build on an orphan, a dangling link or an unaccepted item. The first example's technical page sets out the working contract in full. Here it ran in its specification-first form: the whole graph was written from the person's one paragraph, handed over, read and ratified, and only then implemented; every commit names the items it serves; a change of mind was authored on the graph, ratified, and only then coded. The repository's own check runs in its build, non-strict so that a proposed item waits rather than breaks the build, together with the test suite.

proposedborn from the AI, counts for nothing
ratifieda human's name and a fingerprint of the words
stalethe words moved after the signature; re-ratify or revert

One graph, eight registers

The box tool's graph: registers and the links between them derives_from ×2 derives_from ×1 derives_from ×2 derives_from ×20 mitigates ×12 verifies ×2 verifies ×33 ASM · 1 assumption CON · 1 constraint INT · 1 intent NFR · 2 nfr NG · 3 non goal REQ · 21 requirement RISK · 7 risk TEST · 35 test The box tool's graph: registers and the links between them
The tool's graph at the end of the day: one intent, one constraint (a desktop printer, no support material), one assumption (millimetres), seven risks, three non-goals, twenty-one requirements, two non-functional requirements and thirty-five tests. Requirements derive from the intent, the constraint or the assumption; twelve of them also mitigate a named risk; every requirement and NFR has at least one test verifying it. Nothing is borrowed, so no moved source can mark an item suspect; every suspect status in the history was put there by hand when a signed item was re-worded ahead of its code.
INT · 1a printed box that carries one model safely through the post
CON · 1parts print on a desktop FDM printer without support
ASM · 1model files are in millimetres
RISK · 7lid crushes; cradle grips; cavity too small; poor orientation; rattle; open walls; the cut-back box tips
NG · 3no hinge, latch or snap; not a packaging designer; no undercut that holds the model in
REQ · 21one per behaviour a person could want changed, from the file formats read to the tipping angle
NFR · 2a typical model within a minute; installs with pipx, wheels only
TEST · 35one function each in the suite, named after its item

The graph is what tl init --no-demo lays down plus three registers added at birth for risks, constraints and assumptions, so that a requirement can mitigate a named risk rather than derive from the intent alone. The one coverage rule, that every live requirement needs an incoming verifies link, was treated as a floor: several requirements carry two or three tests, one per distinct failure worth catching.

Item before code, then code to the item

tl -C idd init --name box --no-demo tl -C idd register new RISK risks --title Risks tl -C idd new REQ --type requirement --origin ai --ground INT-0001 --attr priority=must --title "…" --text "…" --no-interactive tl -C idd link REQ-0008 RISK-0002 --type mitigates tl -C idd new TEST --type test --origin ai --ground REQ-0008 --ground-type verifies --title "…" --text "…" --no-interactive tl -C idd check 0 error(s), 66 warning(s) — graph is sound

The sixty-six warnings were the sixty-six unratified items, which is the expected state of a graph nobody has read yet; the commit that carried them said so, and the hand-over named the design calls the AI had made alone. Ratification arrived as one command over all sixty-six, eighteen minutes of reading later, and was committed on its own under the person's name before the implementation began.

git add tests README.md CLAUDE.md .github/workflows/idd-check.yml idd git commit # "Implement the tool against the graph … box INT-0001, REQ-0001..REQ-0020, NFR-0001..NFR-0002, TEST-0001..TEST-0032"

Every module opens by naming the items it implements; every test function is named test_0014_… after its TEST item, with the item's UID in its docstring, so the mapping is greppable in both directions. When the implementation was green the requirements, NFRs and tests were moved ratified → implemented in one commit and implemented → verified in the next, because the check compares each item's status with the committed one and a two-step hop in one commit reads as an illegal transition.

Three tolerances the grid cannot promise

REQ-0009 says the cavity is computed on a grid that only ever rounds outward: each cell takes the lowest point of the grown model over the whole cell, less half a cell diagonal, and the outline is grown by one cell. While implementing it the AI worked through the slack that guarantee costs, up to three cells a side (the cell the outline falls in, the cell the clearance reaches into, and the cell of growth), and found that three tests it had written and the person had signed asked for "within one grid pitch". No implementation of the ratified requirement could pass them.

tl -C idd amend TEST-0003 --text "… at most three grid pitches wider than that on each side." ratification by [the person] no longer matches this content — `tl ratify TEST-0003` shows what moved and asks again tl -C idd check --strict -q [ERROR] TEST-0003 ratified-stale normative content changed since [the person] ratified it — re-ratify to accept the new wording, or revert it

The three were re-worded to what the design guarantees, the rationale of REQ-0009 was corrected to say the same (a rationale is not normative, so its signature held), and the hand-over asked for three re-signatures. The reply was "Ratify and continue", and the AI ran tl ratify … --accept-change with the person's name on his instruction, recording in the commit that it had. The assessment counts those three among thirteen items amended after ratification; none of the thirteen moved silently.

The change of mind, as the graph saw it

"Cut away the box looking down from the top so that the wall thickness is only a parameter defaulting at max 5mm" contradicted NG-0002 as ratified ("does not shape the outside of the box to the model") and changed REQ-0012 (a cuboid), REQ-0011 (a rectangle's wording), REQ-0003 (the option list) and REQ-0015 (lattice panels that would no longer be flat). Nothing was coded. The AI narrowed the non-goal to the top and the underside, amended the four requirements, added RISK-0007 (a cut-back box tips over), REQ-0021 (the tipping angle from the footprint's convex hull, a twenty-degree floor, the rectangle kept when it does better) and three tests, moved the amended verified items to suspect so that their status told the truth, and pushed the proposal with the check at zero errors and twelve warnings.

tl -C idd ratify NG-0002 REQ-0003 REQ-0011 REQ-0012 REQ-0015 TEST-0020 TEST-0024 RISK-0007 REQ-0021 TEST-0033 TEST-0034 TEST-0035 NG-0002 [non_goal/ratified] Not a general packaging designer … changed since it was ratified by [the person] (stamp sha256:e296cc…, ratified content from the record): - … does not shape the outside of the box to the model … + … does not shape the top or the underside of the box to the model … ratify NG-0002 as [the person]? [y/N]: y

The person ran that in his own terminal and confirmed each item after reading its diff; the transcript shows twelve prompts and twelve answers. The implementation followed: the outline traced from the cavity's cells, a rounded rectangle intersected with the outline offset by the bounded wall, offsets of that for the wall below the lip and the skirt, a printed lid built from the mirror image of the outline so that it seats after being turned over, lattice holes sampled along the outline and cut inward along its normal, and the tipping check. Two of the three new tests were physically wrong as written: an L bracket's convex hull is never narrow enough to tip where the rectangle does not, and a post on a block does not raise the cradle. Both were re-worded, both went stale, and both were signed again, one of them in the terminal while the AI was still working.

Ratification, in five rounds

Sixty-six items in one command on a hand-off, committed alone under the person's name. Three re-worded tests with --accept-change on his instruction, the commit saying so. Twelve items read one at a time in his terminal, committed alone. Then two singles: TEST-0034 re-signed in the terminal mid-session, and TEST-0035 the next morning before this page was written.

The fault: the mid-session re-signature of TEST-0034 was swept into the implementation commit by git add idd. The rule from the third example, stage explicit paths in a repository that holds a graph, was in the AI's feedback and was still broken, because "explicit paths" was read as "not -A" and a directory felt explicit. It now says never to add a graph directory whole, and to read git status for item files before staging. The signature itself is intact.

The gate, in the pipeline this time

tl -C idd check --strict 0 error(s), 0 warning(s) — graph is sound (strict)

Unlike the third example, the check is in the build: a graph job runs tl -C idd check on every push, non-strict so that a proposed item waits for a signature rather than breaking the build, and a test job installs the tool with wheels only, as its NFR requires, and runs the suite. The first two builds failed in the test job, not the graph job: a library the working copy had carried since an API probe was never declared, so the suite that read 3MF files passed on the workstation and failed on the runner. The same job then measured the NFR's timing test at nine seconds where the loaded workstation had measured forty.

The assessment

Assessed at "done" with the assessment script of the tool's skill: strict check clean, nothing proposed, working tree clean, no test failed. The session record was cut at the last commit of the day's work; the same session went on the next morning to write this example, and those turns are not in the figures. Commits naming an item in the subject line read 9 of 19: every commit cites its items, but the subject lines that the script reads carried the citation only when it fitted, as the third example also found.

MeasureThe box tool
Items, live71
Accepted by a human71 (1.0)
OriginAI, 71
Sources composed; links into themnone; 0
Commits, whole repository19
Commits naming an item in the subject9
Items amended after ratification13
Lines added / removed5,962 / 559
Test files; results4; 43 pass, 0 fail, 1 skipped
Wall clock / active3.6 h / 2.4 h
Human turns / AI turns9 / 245
Tool calls118
Tokens out (of which thinking)2,195,666 (1,213,442)
Tokens in: fresh / cache written / cache read6,972 / 1,881,255 / 99,969,709
Doneyes

What the tooling taught

Author the whole graph, then hand it over, then build. Sixty-six items in eighteen minutes, read in forty, built in forty-three. The reading is the expensive step and the one that makes the rest cheap.
Every commit cites its items, but put the citation where the script reads. 9 of 19 subject lines carried one. Either the habit moves to the subject or the script reads the body; the third example said the same.
A ratified test is a promise the AI made in the person's name. Five of thirty-five were wrong: three over-precise, two physically mistaken. Writing the code found them; the tool only reported the amendments.
Move amended items to suspect before their code exists. A verified item whose words have changed is not verified; the status said so until the signature and the code caught up.
Never stage a graph directory whole. The third example's rule, still broken with a directory name. The rule now names the directory.
Probe in a throwaway environment. Two builds were lost to a library the working copy carried and the package never declared; the build is the only thing that tests the declared list.
Cut the session record at the work's last commit. The assessment measures a window, not a session; this one was cut so that the writing of the example did not count as the building of the tool.