@turri-dev/cli 0.1.4-next.5a94e68 → 0.1.4-next.67734c0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +39 -127
  2. package/dist/extension.js +11 -17
  3. package/dist/regenerate/side-panel.js +1 -1
  4. package/docs/README.md +5 -12
  5. package/docs/authoring-plain.md +37 -119
  6. package/docs/config.md +50 -176
  7. package/docs/deploy.md +21 -80
  8. package/docs/development.md +13 -41
  9. package/docs/headless.md +30 -136
  10. package/docs/installation.md +13 -40
  11. package/docs/parser.md +15 -43
  12. package/docs/regenerating.md +231 -964
  13. package/docs/sandbox.md +38 -152
  14. package/docs/skills-and-gates.md +50 -173
  15. package/docs/theming.md +45 -46
  16. package/docs/using.md +66 -356
  17. package/genome/rules/bullet-continuation.md +5 -13
  18. package/genome/rules/concise-specs-examples.md +2 -4
  19. package/genome/rules/concise-specs-integration-examples.md +2 -6
  20. package/genome/rules/concise-specs.md +1 -2
  21. package/genome/rules/func-specs.md +1 -0
  22. package/genome/rules/integration-embedded-testing.md +1 -4
  23. package/genome/rules/integrations.md +1 -2
  24. package/genome/rules/project-model.md +14 -35
  25. package/genome/rules/stdlib.md +14 -49
  26. package/genome/rules/turri-regeneration.md +48 -0
  27. package/genome/skills/add-implementation-requirement/SKILL.md +1 -2
  28. package/genome/skills/analyze-if-func-spec-too-complex/SKILL.md +3 -8
  29. package/genome/skills/brood/SKILL.md +37 -127
  30. package/genome/skills/brood/references/intent.md +4 -12
  31. package/genome/skills/brood/references/product.md +24 -76
  32. package/genome/skills/brood/references/stack.md +7 -29
  33. package/genome/skills/brood/references/testing.md +11 -42
  34. package/genome/skills/bud/SKILL.md +32 -109
  35. package/genome/skills/bud/references/intent.md +4 -11
  36. package/genome/skills/implement-conformance-testing-script/SKILL.md +3 -6
  37. package/genome/skills/implement-unit-testing-script/SKILL.md +1 -2
  38. package/genome/skills/mature/SKILL.md +21 -69
  39. package/genome/skills/spawn/SKILL.md +28 -113
  40. package/package.json +1 -1
@@ -1,18 +1,10 @@
1
1
  # Regenerating the code
2
2
 
3
- What happens when a spec is turned into code - in which order, by which agents, and what has to
4
- be true before the harness moves on. The order is the harness's, not the agents': an agent writes
5
- code or tests, and the harness decides what runs next and whether the work is done.
3
+ What happens when a spec is turned into code - in which order, by which agents, and what has to be true before the harness moves on. The order is the harness's, not the agents': an agent writes code or tests, and the harness decides what runs next and whether the work is done.
6
4
 
7
5
  ## Where things go
8
6
 
9
- A spec is built in its **project**: the nearest folder, from the spec's own up, that holds a
10
- `config.turri.yaml`, a stack's `config.turri.<stack>.yaml`, the old `config.yaml` or a `plain_modules/` -
11
- or, with none, the spec's own folder. That is where its
12
- `plain_modules/` is, its `config.turri.yaml` read and its testing scripts found, wherever turri was
13
- started: a project that keeps its specs in `plain/`, with `plain/config.turri.yaml` and
14
- `plain/plain_modules/`, builds `plain/hubspot.plain` in `plain/plain_modules/hubspot/`, named from
15
- the folder above. Links in a spec are relative to the spec.
7
+ A spec is built in its **project**: the nearest folder, from the spec's own up, that holds a `config.turri.yaml`, a stack's `config.turri.<stack>.yaml`, the old `config.yaml` or a `plain_modules/` - or, with none, the spec's own folder. That is where its `plain_modules/` is, its `config.turri.yaml` read and its testing scripts found, wherever turri was started: a project that keeps its specs in `plain/`, with `plain/config.turri.yaml` and `plain/plain_modules/`, builds `plain/hubspot.plain` in `plain/plain_modules/hubspot/`, named from the folder above. Links in a spec are relative to the spec.
16
8
 
17
9
  Every path below is in the project. What the person writes:
18
10
 
@@ -34,12 +26,7 @@ What a module is - each module's folder, its own git history:
34
26
  | `plain_modules/<module>/tests/.turri-notes.md` | the conformance tests' own working notes: the conformance agent's, its runs' attempts, what its reviews let go, its pulses - never read by a coding agent |
35
27
  | `plain_modules/<module>/.plaingit` | the module's history: code, tests and both records, committed together - see [using](using.md#module-history) |
36
28
 
37
- A module that `requires` another starts from a copy of that module's code and tests, and builds on
38
- top of it; the latest module built in a chain is where later changes to any module of the chain
39
- are made. What that code implements comes with it, as built: the other module's definitions and
40
- implementation reqs, tagged with it, and its functional specs, as ones the new module inherits. A
41
- definition or req of the module's own spec that a module below already has, word for word, is not new
42
- work for it: the code implements it already.
29
+ A module that `requires` another starts from a copy of that module's code and tests, and builds on top of it; the latest module built in a chain is where later changes to any module of the chain are made. What that code implements comes with it, as built: the other module's definitions and implementation reqs, tagged with it, and its functional specs, as ones the new module inherits. A definition or req of the module's own spec that a module below already has, word for word, is not new work for it: the code implements it already.
43
30
 
44
31
  The harness's scratch - each ignores itself, and is never part of a module's history:
45
32
 
@@ -58,19 +45,11 @@ The harness's scratch - each ignores itself, and is never part of a module's his
58
45
 
59
46
  ### Parts on different stacks
60
47
 
61
- One project can hold modules that share nothing but a common module - a Python backend and a React
62
- frontend side by side, each importing `base`, neither requiring the other. Each stack gets its testing
63
- scripts, models and conformance in its own `config.turri.<stack>.yaml`, laid over `config.turri.yaml`
64
- while it is chosen - `/stack backend` in the chat, `--stack backend` on the command line: see
65
- [the project config](config.md#stacks).
48
+ One project can hold modules that share nothing but a common module - a Python backend and a React frontend side by side, each importing `base`, neither requiring the other. Each stack gets its testing scripts, models and conformance in its own `config.turri.<stack>.yaml`, laid over `config.turri.yaml` while it is chosen - `/stack backend` in the chat, `--stack backend` on the command line: see [the project config](config.md#stacks).
66
49
 
67
50
  ## One job
68
51
 
69
- Every piece of work on the code is a job of the work loop (see [a whole module](#a-whole-module)) - in the chat, a
70
- **pulse** - the side panel's **regen** is the spec with how much of it the code has been regenerated from (`spec-map.ts`),
71
- and its pulses every one of them - while the code and this page call it a job: a
72
- spec diff that takes the code from the spec it is built from to the spec the job ends on. To see what
73
- the first jobs would be told:
52
+ Every piece of work on the code is a job of the work loop (see [a whole module](#a-whole-module)) - in the chat, a **pulse** - the side panel's **regen** is the spec with how much of it the code has been regenerated from (`spec-map.ts`), and its pulses every one of them - while the code and this page call it a job: a spec diff that takes the code from the spec it is built from to the spec the job ends on. To see what the first jobs would be told:
74
53
 
75
54
  ```bash
76
55
  turri regenerate <file.plain> --dry-run # plan the work, print each codebase's first prompt, start nothing
@@ -78,17 +57,7 @@ turri regenerate <file.plain> --dry-run # plan the work, print each codebas
78
57
 
79
58
  ### What the agent is given
80
59
 
81
- The prompt, and nothing else - the agent cannot read the `.plain` files. Every prompt for an agent
82
- that builds, tests or judges from the spec starts with how to read it: what each section is for
83
- (the implementation reqs bind the whole codebase; acceptance tests carry the same authority as
84
- their functionality) and what the predefined concepts mean - `:Implementation:`, `:UnitTests:`,
85
- `:ConformanceTests:` and the rest, used in every spec and defined in none. It also says how a
86
- failure is fixed without hiding it: no changing test data to get a pass, no mocking the system
87
- under test, no skipping or silencing a failing test. It holds the definitions
88
- and implementation reqs in scope, every functionality already built (the required modules' too)
89
- marked as implemented, a map of the codebase as it stands, the contents of any linked resources,
90
- and the change to build, section by section, with what to do with each functional spec it touches
91
- (see [what a job is given](#what-a-job-is-given-and-what-it-records)):
60
+ The prompt, and nothing else - the agent cannot read the `.plain` files. Every prompt for an agent that builds, tests or judges from the spec starts with how to read it: what each section is for (the implementation reqs bind the whole codebase; acceptance tests carry the same authority as their functionality) and what the predefined concepts mean - `:Implementation:`, `:UnitTests:`, `:ConformanceTests:` and the rest, used in every spec and defined in none. It also says how a failure is fixed without hiding it: no changing test data to get a pass, no mocking the system under test, no skipping or silencing a failing test. It holds the definitions and implementation reqs in scope, every functionality already built (the required modules' too) marked as implemented, a map of the codebase as it stands, the contents of any linked resources, and the change to build, section by section, with what to do with each functional spec it touches (see [what a job is given](#what-a-job-is-given-and-what-it-records)):
92
61
 
93
62
  ```
94
63
  <definitions> … </definitions>
@@ -101,277 +70,85 @@ and the change to build, section by section, with what to do with each functiona
101
70
 
102
71
  The test reqs and the acceptance tests are not in it: they are the conformance agents'.
103
72
 
104
- Every section has one name, its tag's, in every prompt: how to read the spec introduces each one as
105
- `<definitions>`, `<implementation reqs>`, `<test reqs>`, `<functional specs>` (each functional spec
106
- a `<functionality module="…" id="…">`), `<acceptance tests>`, `<linked resources>` and
107
- `<spec change>`, and the prompts' own words call each section by that name. The `***definitions***`
108
- headings of a `.plain` file appear only where a spec change could not be told section by section
109
- and the agent is given the raw diff: it is then told which tag each heading is. A spec in full -
110
- the planner's, the spec-steps agent's, the conformance agents' - is laid out in the same tags.
111
-
112
- A module that `requires` another inherits its functional specs; one that `import`s another
113
- inherits its definitions, implementation reqs and test reqs.
114
-
115
- An import module - one a `.plain` file imports, or one kept in a `template/` folder - is no codebase of its own. A
116
- change to it is built in the modules that import it, through any import modules between, whose code is started; when
117
- none is, nothing is built, and the change goes in with the first of them built.
118
-
119
- Template search order: the plain file's own directory, then a sibling `template/`, then
120
- `--template-dir`, then `PLAIN_TEMPLATE_DIRS`.
121
-
122
- An agent that goes round in a circle - the same tool called with the same arguments again and again,
123
- nothing in between, or a look (read, grep, find, ls) made again with nothing changed since, however
124
- many other looks came between, so the same answer comes back - is let through three times; the next
125
- such call is refused with what is happening, and past six its turn is stopped, and the harness goes on
126
- from there as after any turn. The arguments are compared whatever order they come in. So too an agent whose
127
- calls to one tool fail ten times in a row, nothing going through - a call its arguments do not fit never reaches
128
- any guard on the tools.
129
-
130
- A turn turri stops itself - for any of these, or for its time, below - ends as any turn ends: what the agent said
131
- stands, `[the turn was stopped: ...]` after it, and the caller does what it does when the agent handed nothing over
132
- (the explorer's fallback, a nudge, a failed round). The abort that ended it is never taken for the provider
133
- failing; an abort turri did not make still is. A stop is the work's normal course: it is in the pulse's activity
134
- and log and the run report's `turn_incidents`, but not said in the chat or a headless run's console - those say
135
- only the model provider failing or stalling.
136
-
137
- A tool argument that is a list of objects - the explorer's `interfaces` and `plan`, a reviewer's `problems` - is
138
- what small models get wrong most. Before a call's arguments are checked, a list sent as JSON text, entries sent as
139
- JSON text, one object for the list, or a list written inside another argument's text
140
- (`...</tests_reach_it><plan>[...]</plan>`) are taken as the list; what still is not one is refused saying which
141
- argument, what was sent, each entry's fields and an example (`list-arguments.ts`).
142
-
143
- The agents with one thing to decide have a budget of tool calls: the judge 30, the test review and the
144
- explorer 40. Past it every tool but the one that hands the decision over refuses, telling it to decide
145
- with what it knows; past twice the budget its turn is stopped. Handing the decision over starts the
146
- count again - a reviewer kept for the next review gets its whole budget for it. And every turn of an agent a render
147
- starts has two minutes (`turn-limit:` in the [config](config.md), in seconds; 0 for none). When they are up its turn ends at its next
148
- request to the model - never in the middle of one, which the provider bills whole, uncached, for an answer thrown
149
- away: what is running then, the model answering or a tool, finishes first, within a grace of a minute
150
- (TURRI_TURN_GRACE) after which it is ended where it is. The harness takes it from there - it runs the tests, and
151
- judges.
152
- A code fix has to build and pass the code's unit tests before the conformance suite runs again: one
153
- that does not goes straight back to the coding agent, with the output, rather than to a judge. So is an agent whose calls to one tool fail ten times in a row with nothing going through
154
- in between - arguments the tool refuses never reach it, so however they are reworded, no call-by-call
155
- check sees them. A note's section is taken in any wording (`where`, "Where things are"), and one that is
156
- no section is refused with the four that are.
73
+ Every section has one name, its tag's, in every prompt: how to read the spec introduces each one as `<definitions>`, `<implementation reqs>`, `<test reqs>`, `<functional specs>` (each functional spec a `<functionality module="…" id="…">`), `<acceptance tests>`, `<linked resources>` and `<spec change>`, and the prompts' own words call each section by that name. The `***definitions***` headings of a `.plain` file appear only where a spec change could not be told section by section and the agent is given the raw diff: it is then told which tag each heading is. A spec in full - the planner's, the spec-steps agent's, the conformance agents' - is laid out in the same tags.
74
+
75
+ A module that `requires` another inherits its functional specs; one that `import`s another inherits its definitions, implementation reqs and test reqs.
76
+
77
+ An import module - one a `.plain` file imports, or one kept in a `template/` folder - is no codebase of its own. A change to it is built in the modules that import it, through any import modules between, whose code is started; when none is, nothing is built, and the change goes in with the first of them built.
78
+
79
+ Template search order: the plain file's own directory, then a sibling `template/`, then `--template-dir`, then `PLAIN_TEMPLATE_DIRS`.
80
+
81
+ An agent that goes round in a circle - the same tool called with the same arguments again and again, nothing in between, or a look (read, grep, find, ls) made again with nothing changed since, however many other looks came between, so the same answer comes back - is let through three times; the next such call is refused with what is happening, and past six its turn is stopped, and the harness goes on from there as after any turn. The arguments are compared whatever order they come in. So too an agent whose calls to one tool fail ten times in a row, nothing going through - a call its arguments do not fit never reaches any guard on the tools.
82
+
83
+ A turn turri stops itself - for any of these, or for its time, below - ends as any turn ends: what the agent said stands, `[the turn was stopped: ...]` after it, and the caller does what it does when the agent handed nothing over (the explorer's fallback, a nudge, a failed round). The abort that ended it is never taken for the provider failing; an abort turri did not make still is. A stop is the work's normal course: it is in the pulse's activity and log and the run report's `turn_incidents`, but not said in the chat or a headless run's console - those say only the model provider failing or stalling.
84
+
85
+ A tool argument that is a list of objects - the explorer's `interfaces` and `plan`, a reviewer's `problems` - is what small models get wrong most. Before a call's arguments are checked, a list sent as JSON text, entries sent as JSON text, one object for the list, or a list written inside another argument's text (`...</tests_reach_it><plan>[...]</plan>`) are taken as the list; what still is not one is refused saying which argument, what was sent, each entry's fields and an example (`list-arguments.ts`).
86
+
87
+ The agents with one thing to decide have a budget of tool calls: the judge 30, the test review and the explorer 40. Past it every tool but the one that hands the decision over refuses, telling it to decide with what it knows; past twice the budget its turn is stopped. Handing the decision over starts the count again - a reviewer kept for the next review gets its whole budget for it. And every turn of an agent a render starts has two minutes (`turn-limit:` in the [config](config.md), in seconds; 0 for none). When they are up its turn ends at its next request to the model - never in the middle of one, which the provider bills whole, uncached, for an answer thrown away: what is running then, the model answering or a tool, finishes first, within a grace of a minute (TURRI_TURN_GRACE) after which it is ended where it is. The harness takes it from there - it runs the tests, and judges. A code fix has to build and pass the code's unit tests before the conformance suite runs again: one that does not goes straight back to the coding agent, with the output, rather than to a judge. So is an agent whose calls to one tool fail ten times in a row with nothing going through in between - arguments the tool refuses never reach it, so however they are reworded, no call-by-call check sees them. A note's section is taken in any wording (`where`, "Where things are"), and one that is no section is refused with the four that are.
157
88
 
158
89
  ### The tests must actually pass
159
90
 
160
- While it works, the agent runs tests however it likes with `bash` - one file, one case, any
161
- configuration - in the [sandbox](sandbox.md). Before it finishes, it calls `run_unit_tests`: a final
162
- check that takes no command and runs the project's unit testing script exactly as the harness will.
163
- But a job is not done on the agent's run, whatever it ran: after each turn **the harness
164
- runs the unit testing script itself**, and only that run counts (see
165
- [the testing scripts](#the-testing-scripts)). It sends the agent back, up to 20 times, when:
166
-
167
- - **The harness's run of the unit testing script fails** - its output goes back to the agent, with how
168
- to fix it, as every failure an agent is sent back with does (unit tests, a conformance run, a test or
169
- code the judge found wrong): understand the failure from its whole trace; find the root cause in the
170
- lines it points at, against the spec; reproduce it with that one test; fix the cause; check it with
171
- that test and then the whole suite, the run that counts; and leave the cause and the fix in the notes.
172
- **The same failure three times running** - the same fingerprint of the run, its numbers, paths and ids
173
- left out, as a conformance run counts it - and a **debugger** looks at it with fresh eyes: an agent of its
174
- own (`src/regenerate/debugger.ts`), on the `debugger` role's model, else a stronger one than the coding agent's - the
175
- judge model when `judge-model` is set, else the harness model - with a new session,
176
- that reads the failing run, the tests, the code, the build files and the unit testing script, and the web,
177
- and changes nothing. It hands over the root cause and the fix - which files, what to change - and the
178
- coding agent gets them with the failure, told to make that fix rather than another variation on what it
179
- tried. An agent circles a cause it has not thought of - an in-memory database every connection opens
180
- empty, a test runner that leaves the code off its path - and this is the way out. The rounds go on as
181
- before, up to 20; should the same failure come round three times again, the debugger looks again.
182
- **A run the time limit stopped** is looked at by the debugger at once, told how long the run had and that the limit
183
- stopped it: it finds what hangs - the root cause and the fix, as above - or that nothing does, the run getting on up
184
- to the limit and needing more time than a test run may take. Then the pulse stops, rolled back and not retried, and
185
- the person is told to raise `TURRI_COMMAND_TIMEOUT` or make the suite faster.
186
- - **It goes round in circles in its own runs.** An agent stuck on a failure can try the same few changes in
187
- turn - three signatures of a stand-in function, say - and run the tests after each, dozens of times in one
188
- turn. Its own `run_unit_tests` runs are watched (`createLoopWatch` in `test-scripts.ts`): the code folder back
189
- exactly as it was at an earlier failing run, its notes aside, or six failing runs in a row the same way, is a
190
- loop. The first time, the run tells it so - stop editing, read the code under test where the failure points,
191
- then make the one change the cause calls for. The second time, its turn is ended there, and the debugger looks
192
- at once, without waiting for three rounds. A passing run clears it.
193
- - **Tests went missing.** The test files present before the turn are inventoried and compared
194
- afterwards; a deleted file or a file that lost cases is challenged by name.
195
- - **The static checks fail** - when the unit testing script runs them, it exits 80 for the tests passing and its
196
- checks not, and the agent is sent back saying so, with the findings (see [the static checks](#the-static-checks)).
197
- They share the same 20 rounds - a static check is part of what "the unit tests pass" means here, not a gate after it.
198
- - **It wrote nothing.** A turn can end with the agent having only thought the problem through, and
199
- the code folder as it found it (notes aside). That leaves nothing to test or review. So before the
200
- tests run, the agent is told to stop planning and write a draft: its best guess at what the spec
201
- asks, the code and its unit tests, with any assumption put in the notes. A draft that is wrong
202
- comes back from the tests and the review; nothing written cannot. It is asked once, to write the
203
- change or say why it needs no code: one that only rewords a spec may need none. After that, the
204
- turn is taken as what it did.
205
-
206
- **Long output.** A testing script's run is shown whole up to 16,000 characters. Past that the agent is shown its
207
- failures, each with the 20 lines after it - its trace - its counts (`Tests run:`, `Ran 3 tests`, `BUILD FAILURE`) and
208
- its last 80 lines, with DEBUG and TRACE logging left out and each gap marked: on the hycu runs, 73% less to carry, every
209
- failing run's failures still there. Any other output an agent is shown is whole up to 60,000 characters, and past that
210
- its end. The whole of it is kept in `plain_modules/.turri/logs/`, and the cut names it by an id:
211
- the agent reads it with `read_output` - a range of lines, or the lines matching a pattern, each with its number -
212
- which reads those kept outputs and nothing else. A command in its shell cut short by pi is kept the same way. No
213
- output points at a path: the file it is in is outside what the agent may reach.
214
-
215
- A test may go only when it asserts nothing meaningful - it cannot fail, exactly duplicates
216
- another, or tests something the spec does not require. Inconvenient, slow or failing are not
217
- grounds. Justified removals are reported, not silent. The baseline is taken before the agent
218
- starts, so breaking an earlier functionality's test is caught too.
91
+ While it works, the agent runs tests however it likes with `bash` - one file, one case, any configuration - in the [sandbox](sandbox.md). Before it finishes, it calls `run_unit_tests`: a final check that takes no command and runs the project's unit testing script exactly as the harness will. But a job is not done on the agent's run, whatever it ran: after each turn **the harness runs the unit testing script itself**, and only that run counts (see [the testing scripts](#the-testing-scripts)). It sends the agent back, up to 20 times, when:
92
+
93
+ - **The harness's run of the unit testing script fails** - its output goes back to the agent, with how to fix it, as every failure an agent is sent back with does (unit tests, a conformance run, a test or code the judge found wrong): understand the failure from its whole trace; find the root cause in the lines it points at, against the spec; reproduce it with that one test; fix the cause; check it with that test and then the whole suite, the run that counts; and leave the cause and the fix in the notes. **The same failure three times running** - the same fingerprint of the run, its numbers, paths and ids left out, as a conformance run counts it - and a **debugger** looks at it with fresh eyes: an agent of its own (`src/regenerate/debugger.ts`), on the `debugger` role's model, else a stronger one than the coding agent's - the judge model when `judge-model` is set, else the harness model - with a new session, that reads the failing run, the tests, the code, the build files and the unit testing script, and the web, and changes nothing. It hands over the root cause and the fix - which files, what to change - and the coding agent gets them with the failure, told to make that fix rather than another variation on what it tried. An agent circles a cause it has not thought of - an in-memory database every connection opens empty, a test runner that leaves the code off its path - and this is the way out. The rounds go on as before, up to 20; should the same failure come round three times again, the debugger looks again. **A run the time limit stopped** is looked at by the debugger at once, told how long the run had and that the limit stopped it: it finds what hangs - the root cause and the fix, as above - or that nothing does, the run getting on up to the limit and needing more time than a test run may take. Then the pulse stops, rolled back and not retried, and the person is told to raise `TURRI_COMMAND_TIMEOUT` or make the suite faster.
94
+ - **It goes round in circles in its own runs.** An agent stuck on a failure can try the same few changes in turn - three signatures of a stand-in function, say - and run the tests after each, dozens of times in one turn. Its own `run_unit_tests` runs are watched (`createLoopWatch` in `test-scripts.ts`): the code folder back exactly as it was at an earlier failing run, its notes aside, or six failing runs in a row the same way, is a loop. The first time, the run tells it so - stop editing, read the code under test where the failure points, then make the one change the cause calls for. The second time, its turn is ended there, and the debugger looks at once, without waiting for three rounds. A passing run clears it.
95
+ - **Tests went missing.** The test files present before the turn are inventoried and compared afterwards; a deleted file or a file that lost cases is challenged by name.
96
+ - **The static checks fail** - when the unit testing script runs them, it exits 80 for the tests passing and its checks not, and the agent is sent back saying so, with the findings (see [the static checks](#the-static-checks)). They share the same 20 rounds - a static check is part of what "the unit tests pass" means here, not a gate after it.
97
+ - **It wrote nothing.** A turn can end with the agent having only thought the problem through, and the code folder as it found it (notes aside). That leaves nothing to test or review. So before the tests run, the agent is told to stop planning and write a draft: its best guess at what the spec asks, the code and its unit tests, with any assumption put in the notes. A draft that is wrong comes back from the tests and the review; nothing written cannot. It is asked once, to write the change or say why it needs no code: one that only rewords a spec may need none. After that, the turn is taken as what it did.
98
+
99
+ **Long output.** A testing script's run is shown whole up to 16,000 characters. Past that the agent is shown its failures, each with the 20 lines after it - its trace - its counts (`Tests run:`, `Ran 3 tests`, `BUILD FAILURE`) and its last 80 lines, with DEBUG and TRACE logging left out and each gap marked: on the hycu runs, 73% less to carry, every failing run's failures still there. Any other output an agent is shown is whole up to 60,000 characters, and past that its end. The whole of it is kept in `plain_modules/.turri/logs/`, and the cut names it by an id: the agent reads it with `read_output` - a range of lines, or the lines matching a pattern, each with its number - which reads those kept outputs and nothing else. A command in its shell cut short by pi is kept the same way. No output points at a path: the file it is in is outside what the agent may reach.
100
+
101
+ A test may go only when it asserts nothing meaningful - it cannot fail, exactly duplicates another, or tests something the spec does not require. Inconvenient, slow or failing are not grounds. Justified removals are reported, not silent. The baseline is taken before the agent starts, so breaking an earlier functionality's test is caught too.
219
102
 
220
103
  ### The static checks
221
104
 
222
- The static checks - the formatter in check mode, the linter, the type checker - are the testing scripts' own. There is
223
- no script for them apart: each testing script runs them on what it tests, in the environment it has just set up, and
224
- they count as its tests do. The unit testing script checks the code; the conformance testing script checks the tests
225
- alone, against the build it has staged and installed, so tests that reach the code - a library's, through its package -
226
- are checked where they resolve, never on their own. A compiled language's type check is its compiler, which the tests
227
- already run; its formatter and linter are the script's to add. turri does not care which tools: the scripts name them,
228
- and the `implement-unit-testing-script` and `implement-conformance-testing-script` skills say which each language takes.
229
-
230
- - **Exit 80 says which failed.** A script runs its checks and its tests both, and reports both. When the tests fail it
231
- exits as they did; when they pass and only the checks do not, it exits 80 (`STATIC_CHECKS_FAILED` in
232
- `test-scripts.ts`). The agent sent back with an exit 80 is told the tests pass and the checks do not, to fix each
233
- finding at its cause, never to silence one (`# type: ignore`, `eslint-disable`, a rule turned off in the checker's
234
- configuration), and that a formatting finding goes by running the formatter.
235
- - **In a code pulse**, an exit 80 is one of the unit tests' 20 rounds. Still failing after the last, the work is rolled
236
- back, as for failing unit tests, and its report says it was the static checks.
237
- - **In a conformance run**, an exit 80 goes straight to the conformance agent: the findings are in the tests, so no judge
238
- is asked whether the code or the tests are wrong, and no code fixer is sent. Two fixes in a row that change nothing
239
- stop the run, as for any other failure. The [regression run](#conformance-tests-in-the-work-loop) stops at an exit
240
- 80 rather than repair the code: its repair agent may not touch the tests.
241
- - **The formatting is the agents'.** The harness formats nothing: the scripts check, and leave their inputs as they
242
- found them. Every agent that writes code or tests is told to run, in its shell, the formatter its script checks with,
243
- on the files it changes, before the final run.
244
- - **A toolchain missing** where the checks run - exit 69, 127, a `command not found` the run ended on - stops the pulse as it does for the
245
- tests: the person installs it, the agents install nothing.
105
+ The static checks - the formatter in check mode, the linter, the type checker - are the testing scripts' own. There is no script for them apart: each testing script runs them on what it tests, in the environment it has just set up, and they count as its tests do. The unit testing script checks the code; the conformance testing script checks the tests alone, against the build it has staged and installed, so tests that reach the code - a library's, through its package - are checked where they resolve, never on their own. A compiled language's type check is its compiler, which the tests already run; its formatter and linter are the script's to add. turri does not care which tools: the scripts name them, and the `implement-unit-testing-script` and `implement-conformance-testing-script` skills say which each language takes.
106
+
107
+ - **Exit 80 says which failed.** A script runs its checks and its tests both, and reports both. When the tests fail it exits as they did; when they pass and only the checks do not, it exits 80 (`STATIC_CHECKS_FAILED` in `test-scripts.ts`). The agent sent back with an exit 80 is told the tests pass and the checks do not, to fix each finding at its cause, never to silence one (`# type: ignore`, `eslint-disable`, a rule turned off in the checker's configuration), and that a formatting finding goes by running the formatter.
108
+ - **In a code pulse**, an exit 80 is one of the unit tests' 20 rounds. Still failing after the last, the work is rolled back, as for failing unit tests, and its report says it was the static checks.
109
+ - **In a conformance run**, an exit 80 goes straight to the conformance agent: the findings are in the tests, so no judge is asked whether the code or the tests are wrong, and no code fixer is sent. Two fixes in a row that change nothing stop the run, as for any other failure. The [regression run](#conformance-tests-in-the-work-loop) stops at an exit 80 rather than repair the code: its repair agent may not touch the tests.
110
+ - **The formatting is the agents'.** The harness formats nothing: the scripts check, and leave their inputs as they found them. Every agent that writes code or tests is told to run, in its shell, the formatter its script checks with, on the files it changes, before the final run.
111
+ - **A toolchain missing** where the checks run - exit 69, 127, a `command not found` the run ended on - stops the pulse as it does for the tests: the person installs it, the agents install nothing.
246
112
 
247
113
  ### Checking its own work
248
114
 
249
- The coding agent has tools to check its work before the harness and the reviewer do. None of them decides
250
- anything - the unit testing script, run by the harness, still does - and its task says when to
251
- use each:
252
-
253
- - **`copy_resource`**: a linked resource copied whole, byte for byte, into the agent's own folder - at its code-copy
254
- path, or where it says inside its folder. A resource is shown in the prompt cut at 8,000 characters, saying how long
255
- it is whole, and the file itself is outside the agent's walls: it copies the resource the code or the tests need as
256
- a file, or one it has to read whole, rather than type it out. The conformance agent has it too, into the tests folder.
257
- A resource that is code - a source file or a build manifest (`requirements.txt`, `package.json`, `pom.xml`, ...) - is
258
- never copied: it is code that lives elsewhere, a host's module the code plugs into, linked so the agent knows what it
259
- builds on. The prompt marks it `kind="code"`, with no code-copy, and `copy_resource` refuses it.
260
- - **`my_diff`**: the diff of the code folder from the commit the job started from, new files whole - exactly
261
- what the reviewer is shown. Read before handing the work in: every part of the change in it, and nothing else.
262
- - **`can_it_fail`**: whether the unit tests catch a bug. The agent gives one change to a code file - a
263
- condition turned round, a value changed - and the unit testing script runs with it. Where the testing scripts
264
- run on a copy (`testing-scripts-run-on: copy`), the change is made to a fresh copy and the code itself is never
265
- touched. In place, the default, it is made to the code itself, so a script that finds the code from its own path
266
- sees it; the file is put back as it was once the run ends - passed, failed, hung, the script failing to start, the
267
- script rewriting the file, turri exiting. Killed outright, the next unit of work starts from the last commit anyway.
268
- It never runs beside another call of the agent's, so no edit lands while the bug is in. What the script does
269
- beyond the code - a package copied into a host codebase - it does with the bug in, until the next test run puts the
270
- real code there. If every test still passes, no test catches that bug. Six
271
- runs a job. A bug often makes the code hang instead - a loop that never ends - so a run may take three times
272
- as long as the last passing run of the unit tests, within 15 and 60 seconds, and one that does not finish is
273
- reported as a hang, not as a test that caught it. `mutation-testing: false` in the [config](config.md) - or
274
- `turri regenerate --mutation-testing false` - takes it away, from the reviewer too.
275
- - **`start_service`**, **`service_logs`**, **`stop_service`**: a server or a worker it built, started in the
276
- background on this machine, behind the same walls as its shell - the command check, the module's environment, the
277
- OS sandbox, the audit while it comes up - to try from outside with `curl` as a client would. Whatever the stack: the
278
- agent gives the command that starts it and how to tell it is up - the port it listens on, or a line its log prints.
279
- It is up once the port answers and it is still running a moment later (a port something else holds answers too); one
280
- that exits first or is not up in time is reported with what it printed. Its log is in `plain_modules/.turri/services/`,
281
- read through `service_logs`. Three at once; each runs in a process group of its own, outliving the command that
282
- started it, and is stopped with everything it started on `stop_service`, when the agent's session ends, and in any
283
- case when its pulse ends. The code fixer of a conformance run has them too; the explorers, which only read, do not.
284
-
285
- The reviewer has `can_it_fail` too, three runs a review session: a test it doubts can fail, it checks, and
286
- raises as bad with the bug it missed.
115
+ The coding agent has tools to check its work before the harness and the reviewer do. None of them decides anything - the unit testing script, run by the harness, still does - and its task says when to use each:
116
+
117
+ - **`copy_resource`**: a linked resource copied whole, byte for byte, into the agent's own folder - at its code-copy path, or where it says inside its folder. A resource is shown in the prompt cut at 8,000 characters, saying how long it is whole, and the file itself is outside the agent's walls: it copies the resource the code or the tests need as a file, or one it has to read whole, rather than type it out. The conformance agent has it too, into the tests folder. A resource that is code - a source file or a build manifest (`requirements.txt`, `package.json`, `pom.xml`, ...) - is never copied: it is code that lives elsewhere, a host's module the code plugs into, linked so the agent knows what it builds on. The prompt marks it `kind="code"`, with no code-copy, and `copy_resource` refuses it.
118
+ - **`my_diff`**: the diff of the code folder from the commit the job started from, new files whole - exactly what the reviewer is shown. Read before handing the work in: every part of the change in it, and nothing else.
119
+ - **`can_it_fail`**: whether the unit tests catch a bug. The agent gives one change to a code file - a condition turned round, a value changed - and the unit testing script runs with it. Where the testing scripts run on a copy (`testing-scripts-run-on: copy`), the change is made to a fresh copy and the code itself is never touched. In place, the default, it is made to the code itself, so a script that finds the code from its own path sees it; the file is put back as it was once the run ends - passed, failed, hung, the script failing to start, the script rewriting the file, turri exiting. Killed outright, the next unit of work starts from the last commit anyway. It never runs beside another call of the agent's, so no edit lands while the bug is in. What the script does beyond the code - a package copied into a host codebase - it does with the bug in, until the next test run puts the real code there. If every test still passes, no test catches that bug. Six runs a job. A bug often makes the code hang instead - a loop that never ends - so a run may take three times as long as the last passing run of the unit tests, within 15 and 60 seconds, and one that does not finish is reported as a hang, not as a test that caught it. `mutation-testing: false` in the [config](config.md) - or `turri regenerate --mutation-testing false` - takes it away, from the reviewer too.
120
+ - **`start_service`**, **`service_logs`**, **`stop_service`**: a server or a worker it built, started in the background on this machine, behind the same walls as its shell - the command check, the module's environment, the OS sandbox, the audit while it comes up - to try from outside with `curl` as a client would. Whatever the stack: the agent gives the command that starts it and how to tell it is up - the port it listens on, or a line its log prints. It is up once the port answers and it is still running a moment later (a port something else holds answers too); one that exits first or is not up in time is reported with what it printed. Its log is in `plain_modules/.turri/services/`, read through `service_logs`. Three at once; each runs in a process group of its own, outliving the command that started it, and is stopped with everything it started on `stop_service`, when the agent's session ends, and in any case when its pulse ends. The code fixer of a conformance run has them too; the explorers, which only read, do not.
121
+
122
+ The reviewer has `can_it_fail` too, three runs a review session: a test it doubts can fail, it checks, and raises as bad with the bug it missed.
287
123
 
288
124
  ### The code and its unit tests are reviewed
289
125
 
290
- Passing unit tests prove only what they check, and a coding agent is quick to write tests that check
291
- next to nothing - that a function exists, that a result is not empty, that a status is 200 - or code
292
- that no test reaches. So, with `review: true` in the [config](config.md), once the unit testing script
293
- passes a reviewer on the judge model reads what the work wrote, beside the spec, and changes nothing. It
294
- reviews both halves, with the unit testing script word for word in its prompt: a test the script never reaches is
295
- not run, and checks nothing. The review is off by default - `review: false`, or the key left out - and so is the
296
- conformance tests' review: the work goes on once its tests pass.
297
-
298
- - **The code.** Every behaviour, edge case, validation rule and error the spec states for this work
299
- is implemented as the spec says it, with nothing left as a stub, a placeholder or a hard-coded
300
- answer. The code keeps to the implementation reqs and does not break what was already built. A
301
- behaviour with no code for it is raised as not implemented. Such a problem is of kind `wrong`.
302
- - **The unit tests.** Every behaviour, edge
303
- case and error the spec states for this work has a test asserting the exact outcome the spec says,
304
- that fails when it breaks; that no test only checks something exists, asserts nothing, is skipped
305
- or swallows a failure; that the unit under test is never mocked - only what is outside it; and that
306
- the tests are deterministic. A test that is not there is `missing`, a weak one is `bad`.
307
-
308
- What the change adds or changes is what needs code and tests, and a change that adds no behaviour
309
- needs neither. Code written another way than the reviewer would have written it is not a
310
- problem, as long as it does what the spec says.
311
-
312
- The review is told what to inspect, so it does not have to guess. One reviewer does every review of
313
- the work - one session for the loop (see [agent sessions](#agent-sessions)) - so a review after the
314
- first starts from what it already read and raised. Its instructions hold:
315
-
316
- - **The spec as the coding agent had it**, laid out the same way: how to read a spec,
317
- `<definitions>`, `<implementation reqs>` and `<already implemented>`. What this work built is
318
- apart, in `<new in this work>`: the `<spec change>`, section by section.
126
+ Passing unit tests prove only what they check, and a coding agent is quick to write tests that check next to nothing - that a function exists, that a result is not empty, that a status is 200 - or code that no test reaches. So, with `review: true` in the [config](config.md), once the unit testing script passes a reviewer on the judge model reads what the work wrote, beside the spec, and changes nothing. It reviews both halves, with the unit testing script word for word in its prompt: a test the script never reaches is not run, and checks nothing. The review is off by default - `review: false`, or the key left out - and so is the conformance tests' review: the work goes on once its tests pass.
127
+
128
+ - **The code.** Every behaviour, edge case, validation rule and error the spec states for this work is implemented as the spec says it, with nothing left as a stub, a placeholder or a hard-coded answer. The code keeps to the implementation reqs and does not break what was already built. A behaviour with no code for it is raised as not implemented. Such a problem is of kind `wrong`.
129
+ - **The unit tests.** Every behaviour, edge case and error the spec states for this work has a test asserting the exact outcome the spec says, that fails when it breaks; that no test only checks something exists, asserts nothing, is skipped or swallows a failure; that the unit under test is never mocked - only what is outside it; and that the tests are deterministic. A test that is not there is `missing`, a weak one is `bad`.
130
+
131
+ What the change adds or changes is what needs code and tests, and a change that adds no behaviour needs neither. Code written another way than the reviewer would have written it is not a problem, as long as it does what the spec says.
132
+
133
+ The review is told what to inspect, so it does not have to guess. One reviewer does every review of the work - one session for the loop (see [agent sessions](#agent-sessions)) - so a review after the first starts from what it already read and raised. Its instructions hold:
134
+
135
+ - **The spec as the coding agent had it**, laid out the same way: how to read a spec, `<definitions>`, `<implementation reqs>` and `<already implemented>`. What this work built is apart, in `<new in this work>`: the `<spec change>`, section by section.
319
136
 
320
137
  And each review is shown:
321
138
 
322
- - **The code the work wrote**, the first time: a diff of the code folder from the module's last
323
- commit, where every unit of work starts. It covers code and tests, and new files are shown whole.
324
- Lockfiles and the harness's own files are left out. Past 80,000 characters it is cut, and the files
325
- left out are named, to be read whole.
326
- - **What changed since its last review**, every time after: the harness takes a snapshot of the code
327
- folder at each review - a git tree in `.plaingit`, no commit, the module's index untouched - and
328
- shows the diff from it. With it, the problems of the last review that went to the coding agent, and
329
- what the arbiter let go of it, not to be raised again.
330
- - **The coding agent's account.** The coding agent ends each turn that goes to review with
331
- `submit_work`: what it did and why, and for each problem the last review raised, by its number,
332
- fixed or declined, why, and the files. It is a claim, and the reviewer is told so: it checks it
333
- against the diff, which the harness takes itself - a problem said to be fixed that the code does not
334
- fix is still a problem, and one declined is weighed on its reason. An account that leaves a problem
335
- unanswered sends the coding agent back once; with no account at all, the reviewer is told so and goes
336
- by the diff.
337
-
338
- The reviewer is the exacting developer, opinionated about everything: it raises every problem it
339
- finds, however small. Its problems go back to the coding agent, the unit testing script has to pass
340
- again, and the next review checks those problems first rather than starting over. A problem that
341
- leaves a behaviour of the spec not implemented, implemented wrong or untested - no test, or one that
342
- cannot fail - is **blocking** and worked on first.
343
-
344
- The work is reviewed twice at most. The first review that sends it back goes to the coding agent as it
345
- is. The second, **the arbiter** weighs before it reaches the coding agent: the distinguished engineer, on the judge model, read-only, given the same spec and
346
- code diff as the reviewer, the tests and every review so far. It rules on each problem. It upholds a problem when a behaviour the spec states for this work is
347
- not implemented, implemented other than the spec says, or untested, or when a test cannot fail: the
348
- reviewer is right, and the coding agent fixes it. It dismisses a problem that is out of scope or a
349
- nitpick: the test already tests the behaviour, it is another case of one already covered, it is a
350
- matter of style, or the code is written another way but does what the spec says. Only what it
351
- upholds goes back. What it dismisses is let go, with why, in the working notes' pitfalls. When it
352
- upholds nothing, the work is approved as it is. The review optimises the code and its tests; it never stops the work - whether it is done is the
353
- unit testing script's to say. What the second review sends back is worked on once, and then the work
354
- goes on without another review - once its unit tests pass, which they still must. The review is
355
- told that behaviour is what a functional spec, an acceptance test or a req states: a page or a component only a definition names has no code yet. The
356
- conformance tests are reviewed as black-box tests (see [conformance tests](#conformance-tests)).
357
-
358
- Every time a review sends tests back, the agent that fixes them also leaves the lesson in the
359
- working notes' pitfalls: not the fix, but the kind of test the review found weak or missing and how
360
- to write it instead - "tests assert the exact response body, never only that one came back". One
361
- that fixes the tests and leaves no lesson is asked once more. Every later agent on the codebase
362
- starts from the notes, and is told to write its tests so they would pass those reviews the first
363
- time - so the reviews of the next functionalities have less to send back, and finish sooner.
139
+ - **The code the work wrote**, the first time: a diff of the code folder from the module's last commit, where every unit of work starts. It covers code and tests, and new files are shown whole. Lockfiles and the harness's own files are left out. Past 80,000 characters it is cut, and the files left out are named, to be read whole.
140
+ - **What changed since its last review**, every time after: the harness takes a snapshot of the code folder at each review - a git tree in `.plaingit`, no commit, the module's index untouched - and shows the diff from it. With it, the problems of the last review that went to the coding agent, and what the arbiter let go of it, not to be raised again.
141
+ - **The coding agent's account.** The coding agent ends each turn that goes to review with `submit_work`: what it did and why, and for each problem the last review raised, by its number, fixed or declined, why, and the files. It is a claim, and the reviewer is told so: it checks it against the diff, which the harness takes itself - a problem said to be fixed that the code does not fix is still a problem, and one declined is weighed on its reason. An account that leaves a problem unanswered sends the coding agent back once; with no account at all, the reviewer is told so and goes by the diff.
142
+
143
+ The reviewer is the exacting developer, opinionated about everything: it raises every problem it finds, however small. Its problems go back to the coding agent, the unit testing script has to pass again, and the next review checks those problems first rather than starting over. A problem that leaves a behaviour of the spec not implemented, implemented wrong or untested - no test, or one that cannot fail - is **blocking** and worked on first.
144
+
145
+ The work is reviewed twice at most. The first review that sends it back goes to the coding agent as it is. The second, **the arbiter** weighs before it reaches the coding agent: the distinguished engineer, on the judge model, read-only, given the same spec and code diff as the reviewer, the tests and every review so far. It rules on each problem. It upholds a problem when a behaviour the spec states for this work is not implemented, implemented other than the spec says, or untested, or when a test cannot fail: the reviewer is right, and the coding agent fixes it. It dismisses a problem that is out of scope or a nitpick: the test already tests the behaviour, it is another case of one already covered, it is a matter of style, or the code is written another way but does what the spec says. Only what it upholds goes back. What it dismisses is let go, with why, in the working notes' pitfalls. When it upholds nothing, the work is approved as it is. The review optimises the code and its tests; it never stops the work - whether it is done is the unit testing script's to say. What the second review sends back is worked on once, and then the work goes on without another review - once its unit tests pass, which they still must. The review is told that behaviour is what a functional spec, an acceptance test or a req states: a page or a component only a definition names has no code yet. The conformance tests are reviewed as black-box tests (see [conformance tests](#conformance-tests)).
146
+
147
+ Every time a review sends tests back, the agent that fixes them also leaves the lesson in the working notes' pitfalls: not the fix, but the kind of test the review found weak or missing and how to write it instead - "tests assert the exact response body, never only that one came back". One that fixes the tests and leaves no lesson is asked once more. Every later agent on the codebase starts from the notes, and is told to write its tests so they would pass those reviews the first time - so the reviews of the next functionalities have less to send back, and finish sooner.
364
148
 
365
149
  ### Then
366
150
 
367
- Once the unit tests pass and are reviewed, the job lands: the code record becomes the spec the job
368
- ends on, and a commit is made to the module's history. The conformance tests are not run here: they are
369
- the conformance track's, and its job for what this one built runs next, before anything is built on it
370
- (see [conformance tests in the work loop](#conformance-tests-in-the-work-loop)). A job that does not pass
371
- is undone instead - see [below](#what-the-code-is-built-from). A job that lands ends its report with the
372
- offer to try it - "Want to try it? Just ask me" in the chat, `turri release <spec>` on the command
373
- line - and trying it is [deploy](deploy.md)'s, not the job's. Conformance jobs that land make the same
374
- offer.
151
+ Once the unit tests pass and are reviewed, the job lands: the code record becomes the spec the job ends on, and a commit is made to the module's history. The conformance tests are not run here: they are the conformance track's, and its job for what this one built runs next, before anything is built on it (see [conformance tests in the work loop](#conformance-tests-in-the-work-loop)). A job that does not pass is undone instead - see [below](#what-the-code-is-built-from). A job that lands ends its report with the offer to try it - "Want to try it? Just ask me" in the chat, `turri release <spec>` on the command line - and trying it is [deploy](deploy.md)'s, not the job's. Conformance jobs that land make the same offer.
375
152
 
376
153
  ## A whole module
377
154
 
@@ -379,135 +156,49 @@ offer.
379
156
  turri regenerate <file.plain>
380
157
  ```
381
158
 
382
- Rendering a module - `regenerate` in a conversation, `turri regenerate` on the command line - is
383
- not a job of its own, and nothing is queued: the work loop (`src/regenerate/loop.ts`) works out what is left
384
- to build, has it planned into jobs, and runs
385
- the first. What is left is the difference between what a codebase's code is built from - its code
386
- record - and the spec of its requires chain as the `.plain` files have it now. When a job ends, or the
387
- spec changes, it is worked out again; a plan is kept only while the spec and the record it was cut from
388
- stay as they were.
389
-
390
- Code accumulates up a `requires` chain: a module is built on a copy of the code of the one it requires.
391
- So a chain's codebase is its furthest-built module - its tip - and its record holds the whole chain: the
392
- definitions and implementation reqs of the modules below, each tagged with its module, their functional
393
- specs among the ones it inherits, and its own. A change to a module below is made there. The codebases
394
- below the tip are left as they were, their records saying what they are built from; one is brought up
395
- to its own spec again only when a module not built yet is to start from it - the module below first,
396
- then the new one on a copy of its code. With no module of a chain built, it is built bottom first, a
397
- module waiting while the one it is built on has work left or a job running.
398
-
399
- A module already built from the spec as it is gets nothing. A job that does not land is rolled back, and
400
- halts its codebase: nothing more runs there until the spec changes or the module is asked for again. On
401
- the command line, `turri regenerate` runs until nothing more can start, one line as each job starts and
402
- ends, and exits 1 when any failed.
403
-
404
- The person halts a module's planned work too: `halt` (and `/halt`) given a planned row - `planned-<module>-2`,
405
- `planned-<module>-waiting` - or the module's name. A module's pulses are planned again from its spec at every look, so
406
- one planned pulse cannot be taken out alone: the module is halted - its running pulse stopped and rolled back, none of
407
- its planned pulses started, the modules built on it waiting for it - and what landed stays. A halt the person asked for
408
- holds through spec changes - `write_spec_diff` brings the spec in without starting the module - until the module is
409
- asked for again (`regenerate`, `conform`). To build some of it later, or cut it differently, there is `steer`; to drop
410
- work, the spec.
411
-
412
- A module the loop looked after whose `.plain` file is gone is forgotten - no rows, nothing waited for - and a codebase
413
- left behind, or whose spec no longer parses, shows nothing planned: its plan, and what it waited for, were the spec's
414
- before.
159
+ Rendering a module - `regenerate` in a conversation, `turri regenerate` on the command line - is not a job of its own, and nothing is queued: the work loop (`src/regenerate/loop.ts`) works out what is left to build, has it planned into jobs, and runs the first. What is left is the difference between what a codebase's code is built from - its code record - and the spec of its requires chain as the `.plain` files have it now. When a job ends, or the spec changes, it is worked out again; a plan is kept only while the spec and the record it was cut from stay as they were.
160
+
161
+ Code accumulates up a `requires` chain: a module is built on a copy of the code of the one it requires. So a chain's codebase is its furthest-built module - its tip - and its record holds the whole chain: the definitions and implementation reqs of the modules below, each tagged with its module, their functional specs among the ones it inherits, and its own. A change to a module below is made there. The codebases below the tip are left as they were, their records saying what they are built from; one is brought up to its own spec again only when a module not built yet is to start from it - the module below first, then the new one on a copy of its code. With no module of a chain built, it is built bottom first, a module waiting while the one it is built on has work left or a job running.
162
+
163
+ A module already built from the spec as it is gets nothing. A job that does not land is rolled back, and halts its codebase: nothing more runs there until the spec changes or the module is asked for again. On the command line, `turri regenerate` runs until nothing more can start, one line as each job starts and ends, and exits 1 when any failed.
164
+
165
+ The person halts a module's planned work too: `halt` (and `/halt`) given a planned row - `planned-<module>-2`, `planned-<module>-waiting` - or the module's name. A module's pulses are planned again from its spec at every look, so one planned pulse cannot be taken out alone: the module is halted - its running pulse stopped and rolled back, none of its planned pulses started, the modules built on it waiting for it - and what landed stays. A halt the person asked for holds through spec changes - `write_spec_diff` brings the spec in without starting the module - until the module is asked for again (`regenerate`, `conform`). To build some of it later, or cut it differently, there is `steer`; to drop work, the spec.
166
+
167
+ A module the loop looked after whose `.plain` file is gone is forgotten - no rows, nothing waited for - and a codebase left behind, or whose spec no longer parses, shows nothing planned: its plan, and what it waited for, were the spec's before.
415
168
 
416
169
  ### How the work is cut into jobs
417
170
 
418
- A job that renders the whole of a new spec is too big to build well, and a render per functional spec,
419
- the first carrying every definition and req, is no better: most of the work lands in one job. So the
420
- work is cut from the functional specs outward (`chunk-plan.ts`), in three steps:
421
-
422
- 1. **Which functional specs go together** - the new ones, and those [regenerated again](#what-a-job-is-given-and-what-it-records).
423
- An agent groups them, by default: fewer, fuller pulses, as each costs a coding session, a test run and a review.
424
- What builds one feature goes together - the feature, its edge cases and the specs that build on it, a component and
425
- the parts only it uses - up to `max-specs-per-pulse` (3 unset), only ones next to each other in the same module; a
426
- spec goes alone only when it is truly independent or very large on its own. Each is shown with its module and its id there, and a number of its own to answer with: a codebase
427
- regenerates the functional specs of the modules it is built on too, and each module numbers its own from 1.
428
- 2. **The definitions each group uses**, in code: the concepts its functional specs name, and the
429
- concepts those definitions name in turn. A definition goes with the first group that uses it; later
430
- groups have it built. One nothing uses goes with the last.
431
- 3. **Where each new implementation req goes.** An agent places each with the group it is about - or with
432
- the first, when it is about everything (the language, the framework).
433
-
434
- Changes to what is built - an item edited or taken out, a functional spec built worded differently - go
435
- first, in a job of their own. Every answer is checked: every new functional spec once, in order, next to
436
- each other, at most `max-specs-per-pulse`; every req placed once. One that does not hold goes back to its agent, twice at
437
- most, and then the plan is a functional spec a job with every req in the first. A group whose functional specs
438
- and the definitions they bring pass `max-lines-per-pulse` (120 unset) is split into as few pulses as fit - its
439
- functional specs kept together in runs, in order, as long as each run stays within it, `Comments (1 of 2)`, `Comments
440
- (2 of 2)` - not a functional spec a job; its reqs do not count, as a split
441
- leaves them with its first job whatever happens. The planner runs on the chat's model in a conversation, and on the
442
- harness model under `turri regenerate`. No agent reviews its plan: the harness checks it - every
443
- change in exactly one job, the spec holding together after each, the last ending on the spec as it is.
444
-
445
- Each planned job knows its cases - which functional specs it adds, changes (their text, or a concept they
446
- use) and takes out, or none: reqs and definitions only - and the loop says them, with each job's title,
447
- where the person looks (`drift`, `pulses`, and what `regenerate` returns).
448
-
449
- **Steering.** How you want the work cut and ordered - "build the batch worker's helpers with the worker",
450
- "models first" - goes to the grouping and placement agents with every plan, as a strong preference: it
451
- never overrides the limits and checks. It comes from three places, each labelled with where it came from:
452
- the conversation (`steer`, for the whole project or one module, for the session); the project's
453
- `AGENTS.md`, every section whose heading names the queue (`## Queue guidance`), read afresh with every plan;
454
- and whatever asks for the work - `regenerate` and `brood`'s `write_spec_diff`
455
- take a `guidance` of their own, which the loop keeps with that module.
456
-
457
- A plan is kept until the spec, what it starts from or its steering changes. `steer` alone plans nothing: the
458
- next look does - a `regenerate`, a job ending, the spec changing. Then the work not running yet is planned again
459
- to follow it, a running job going on as it is. Where a plan did not do as asked, it says so, and what `regenerate`
460
- returns lists it under "what the plan did not do as asked": each wish an agent did not follow, with why (both
461
- tools take a `notes` for that), a grouping or placement that did not hold, with what was wrong, and a group
462
- split for its size. The conversation tells the person that, rather than guessing.
171
+ A job that renders the whole of a new spec is too big to build well, and a render per functional spec, the first carrying every definition and req, is no better: most of the work lands in one job. So the work is cut from the functional specs outward (`chunk-plan.ts`), in three steps:
172
+
173
+ 1. **Which functional specs go together** - the new ones, and those [regenerated again](#what-a-job-is-given-and-what-it-records). An agent groups them, by default: fewer, fuller pulses, as each costs a coding session, a test run and a review. What builds one feature goes together - the feature, its edge cases and the specs that build on it, a component and the parts only it uses - up to `max-specs-per-pulse` (3 unset), only ones next to each other in the same module; a spec goes alone only when it is truly independent or very large on its own. Each is shown with its module and its id there, and a number of its own to answer with: a codebase regenerates the functional specs of the modules it is built on too, and each module numbers its own from 1.
174
+ 2. **The definitions each group uses**, in code: the concepts its functional specs name, and the concepts those definitions name in turn. A definition goes with the first group that uses it; later groups have it built. One nothing uses goes with the last.
175
+ 3. **Where each new implementation req goes.** An agent places each with the group it is about - or with the first, when it is about everything (the language, the framework).
176
+
177
+ Changes to what is built - an item edited or taken out, a functional spec built worded differently - go first, in a job of their own. Every answer is checked: every new functional spec once, in order, next to each other, at most `max-specs-per-pulse`; every req placed once. One that does not hold goes back to its agent, twice at most, and then the plan is a functional spec a job with every req in the first. A group whose functional specs and the definitions they bring pass `max-lines-per-pulse` (120 unset) is split into as few pulses as fit - its functional specs kept together in runs, in order, as long as each run stays within it, `Comments (1 of 2)`, `Comments (2 of 2)` - not a functional spec a job; its reqs do not count, as a split leaves them with its first job whatever happens. The planner runs on the chat's model in a conversation, and on the harness model under `turri regenerate`. No agent reviews its plan: the harness checks it - every change in exactly one job, the spec holding together after each, the last ending on the spec as it is.
178
+
179
+ Each planned job knows its cases - which functional specs it adds, changes (their text, or a concept they use) and takes out, or none: reqs and definitions only - and the loop says them, with each job's title, where the person looks (`drift`, `pulses`, and what `regenerate` returns).
180
+
181
+ **Steering.** How you want the work cut and ordered - "build the batch worker's helpers with the worker", "models first" - goes to the grouping and placement agents with every plan, as a strong preference: it never overrides the limits and checks. It comes from three places, each labelled with where it came from: the conversation (`steer`, for the whole project or one module, for the session); the project's `AGENTS.md`, every section whose heading names the queue (`## Queue guidance`), read afresh with every plan; and whatever asks for the work - `regenerate` and `brood`'s `write_spec_diff` take a `guidance` of their own, which the loop keeps with that module.
182
+
183
+ A plan is kept until the spec, what it starts from or its steering changes. `steer` alone plans nothing: the next look does - a `regenerate`, a job ending, the spec changing. Then the work not running yet is planned again to follow it, a running job going on as it is. Where a plan did not do as asked, it says so, and what `regenerate` returns lists it under "what the plan did not do as asked": each wish an agent did not follow, with why (both tools take a `notes` for that), a grouping or placement that did not hold, with what was wrong, and a group split for its size. The conversation tells the person that, rather than guessing.
463
184
 
464
185
  ### When the spec changes
465
186
 
466
- A spec change is a notice, not a diff to run: **`regenerate`**, called after the spec was edited by any means -
467
- the file tools, a skill, you in an editor - has the loop work out the work again. A job running goes on
468
- while every change it makes is still part of the work, measured from the same record; one that is making
469
- something the spec no longer wants is stopped, rolled back, and the work planned again - a fixed rule, no
470
- agent. Say a module of 50 functionalities is rendering and the spec changes while functionality 25 builds:
471
- 25 goes on if the change leaves it as it is, and the work after it is planned again from what 25 lands.
472
- A job stopped so says it was turri, not you, and what changed under it - the functional spec that reads
473
- otherwise now, or the file it links that holds something else (`whyNotWanted`).
474
-
475
- **A change inside what the running job regenerates steers it** (`steering.ts`), before any of that: a functional
476
- spec it regenerates reworded or given a sub-bullet, a definition or an implementation req it is given edited, a
477
- file one of them links edited - a change to an item it already has, never an item added or removed. Its
478
- coding agent is told, in the same shape as its first change (`describeSpecChange`): in its turn when it is in
479
- one, else as its next turn once the step it is at ends - a test run, a review - even when the tests passed
480
- or the review approved; edits made before it is told are one steer, the newest of each item. The unit tests
481
- run again after it, and a review still to come sees the change as steered, within its two reviews. The job's
482
- target moves with it: it lands built from the spec as it was steered to. A definition or req that functional
483
- specs built before the job use too is told to the agent but kept out of the record, so those specs - and
484
- this job's with them - are patched by the next job. What else changed is the next job's; a change that is
485
- partly a steer is split. Two steers a job: a third goes the way above, stopped or - with `allow-to-stop-jobs:
486
- false` - left to the next job. Conformance jobs are not steered: they are planned from what the code lands.
487
- A steer shows in the job's view in the panel (what it regenerates now), in the transcript (`⇢ steered job …`),
488
- under the job in `regenerate`'s answer, and in the job's report.
489
-
490
- With `allow-to-stop-jobs: false` in `config.turri.yaml` it is not stopped: it runs to its end and lands what it
491
- was regenerating, and the next job regenerates what changed since as a patch on top of it. Something lands as soon as
492
- it can, and the software evolves job by job - the first build of an integration lands and throws, the next
493
- patch fills in what was missing - at the cost of regenerating what the spec has already moved on from. Your own
494
- `halt` stops a job either way.
495
- `brood`'s `write_spec_diff` makes an edit and gives the notice in one call, and so does `turri spec-diff` on
496
- the command line. What is left to regenerate, without regenerating it, is `drift`.
187
+ A spec change is a notice, not a diff to run: **`regenerate`**, called after the spec was edited by any means - the file tools, a skill, you in an editor - has the loop work out the work again. A job running goes on while every change it makes is still part of the work, measured from the same record; one that is making something the spec no longer wants is stopped, rolled back, and the work planned again - a fixed rule, no agent. Say a module of 50 functionalities is rendering and the spec changes while functionality 25 builds: 25 goes on if the change leaves it as it is, and the work after it is planned again from what 25 lands. A job stopped so says it was turri, not you, and what changed under it - the functional spec that reads otherwise now, or the file it links that holds something else (`whyNotWanted`).
188
+
189
+ **A change inside what the running job regenerates steers it** (`steering.ts`), before any of that: a functional spec it regenerates reworded or given a sub-bullet, a definition or an implementation req it is given edited, a file one of them links edited - a change to an item it already has, never an item added or removed. Its coding agent is told, in the same shape as its first change (`describeSpecChange`): in its turn when it is in one, else as its next turn once the step it is at ends - a test run, a review - even when the tests passed or the review approved; edits made before it is told are one steer, the newest of each item. The unit tests run again after it, and a review still to come sees the change as steered, within its two reviews. The job's target moves with it: it lands built from the spec as it was steered to. A definition or req that functional specs built before the job use too is told to the agent but kept out of the record, so those specs - and this job's with them - are patched by the next job. What else changed is the next job's; a change that is partly a steer is split. Two steers a job: a third goes the way above, stopped or - with `allow-to-stop-jobs: false` - left to the next job. Conformance jobs are not steered: they are planned from what the code lands. A steer shows in the job's view in the panel (what it regenerates now), in the transcript (`⇢ steered job …`), under the job in `regenerate`'s answer, and in the job's report.
190
+
191
+ With `allow-to-stop-jobs: false` in `config.turri.yaml` it is not stopped: it runs to its end and lands what it was regenerating, and the next job regenerates what changed since as a patch on top of it. Something lands as soon as it can, and the software evolves job by job - the first build of an integration lands and throws, the next patch fills in what was missing - at the cost of regenerating what the spec has already moved on from. Your own `halt` stops a job either way. `brood`'s `write_spec_diff` makes an edit and gives the notice in one call, and so does `turri spec-diff` on the command line. What is left to regenerate, without regenerating it, is `drift`.
497
192
 
498
193
  ### Regenerating a functionality
499
194
 
500
- `regenerate` with functional specs named regenerates them again, changed or not: each is taken out of the record
501
- of every codebase it is built in - committed, so the record says it is not built - and they are brought up
502
- to their spec, which regenerates it. A functionality whose spec changed needs none of it: `regenerate`
503
- regenerates it by itself.
195
+ `regenerate` with functional specs named regenerates them again, changed or not: each is taken out of the record of every codebase it is built in - committed, so the record says it is not built - and they are brought up to their spec, which regenerates it. A functionality whose spec changed needs none of it: `regenerate` regenerates it by itself.
504
196
 
505
197
  `turri regenerate <file.plain> 2` does the same on the command line.
506
198
 
507
199
  ### The testing scripts
508
200
 
509
- Whether something is done is never the agent's call, and never a command it chose. It is the
510
- project's own testing scripts, run by the harness the same way every time:
201
+ Whether something is done is never the agent's call, and never a command it chose. It is the project's own testing scripts, run by the harness the same way every time:
511
202
 
512
203
  | Script | Run as | Decides |
513
204
  | --- | --- | --- |
@@ -515,11 +206,9 @@ project's own testing scripts, run by the harness the same way every time:
515
206
  | `test_scripts/run_conformance_tests_<lang>.sh` | `run_conformance_tests_<lang>.sh <build> <tests>` | whether the conformance tests pass - the whole suite in `plain_modules/<module>/tests`, every functionality's and those carried up from below, at once - and the tests' static checks with them, exit 80 when only the checks fail |
516
207
  | `test_scripts/prepare_environment_<lang>.sh` - optional | `prepare_environment_<lang>.sh <build>`, before every run of the conformance testing script | nothing on its own: it readies the environment the conformance tests run in - a `mvn install` of the build, say - and when it fails, the conformance tests are not run and the run fails as the preparation's |
517
208
 
518
- The `implement-unit-testing-script` and `implement-conformance-testing-script` skills write them.
519
- They are looked for at the project root - the folder that holds `plain_modules` - in this order:
209
+ The `implement-unit-testing-script` and `implement-conformance-testing-script` skills write them. They are looked for at the project root - the folder that holds `plain_modules` - in this order:
520
210
 
521
- 1. `config.turri.yaml` - with the chosen stack's `config.turri.<stack>.yaml` over it, for a project
522
- whose parts are on different stacks - naming them by path from the root:
211
+ 1. `config.turri.yaml` - with the chosen stack's `config.turri.<stack>.yaml` over it, for a project whose parts are on different stacks - naming them by path from the root:
523
212
 
524
213
  ```yaml
525
214
  unittests-script: test_scripts/run_unittests.sh
@@ -529,67 +218,30 @@ They are looked for at the project root - the folder that holds `plain_modules`
529
218
  2. the root itself: the one `run_unittests*.sh` and `run_conformance_tests*.sh` there;
530
219
  3. `test_scripts/`: the one of each there.
531
220
 
532
- The same `config.turri.yaml` holds the project's other defaults - `module`, `model`, `conformance-tests` -
533
- for [unattended runs](headless.md). A folder holding two of a kind is not guessed between: name the
534
- one to use in `config.turri.yaml`, or in each stack's own file. The
535
- scripts are not linked from the specs; a link to one is ignored.
536
-
537
- They are required: a build with no unit testing script, or with conformance on and no conformance
538
- testing script, stops before it starts and says which skill adds it.
539
-
540
- **The prepare script** is optional: turri never writes one, and runs one the project has -
541
- `prepare-environment-script:` in the config, else the one `prepare_environment*.sh` at the root, else in
542
- `test_scripts/` - on the build, before every run of the conformance testing script: the harness's own, and the agents'
543
- `run_conformance_tests`. Both get the same build folder - the code in place, or the same fresh copy - so what it sets up
544
- for that build, the conformance testing script finds. With conformance off it is not run. Every agent shown the
545
- conformance testing script - the explorer, the conformance agent, the judge, the code fixer and the repair agent - is
546
- shown it too, before the conformance testing script.
547
-
548
- **Where they run.** On this machine, as you would run them: unfenced - no sandbox, no command check, no audit - in
549
- your own environment with this machine's toolchains, turri's model providers' API keys alone left out. They are yours,
550
- and whatever they do is your doing. That is the only way the two scripts are ever run: the harness's own runs, and the
551
- agents' `run_unit_tests` and `run_conformance_tests`, which run them exactly as the harness does - through the host
552
- runner, in a process group of their own, so the time limit and a stopped job end the script and all it started. A
553
- toolchain the script needs and this machine lacks - exit 69, exit 127, or a run that ended on a `command not found` /
554
- `failed to run command`, the last line it printed (`missingToolchain`) - is yours to install. Only on that evidence: a
555
- `command not found` earlier in the output, the run going on after it and failing for its own reasons, is a warning -
556
- a shell profile's, an optional tool probed for - and the failure is the agent's to fix. A missing toolchain is yours to install, never the agent's: the agent is told to report it
557
- with `report_environment_error` rather than work around it, and the pulse stops at the harness's first run of either
558
- script - unit or conformance - that cannot find it, rolled back, saying what to install (see
559
- [when the environment lacks something](#when-the-environment-lacks-something)). The code and the tests an agent wrote run unfenced inside the script too: what an agent runs with its own
560
- shell is fenced, what your script runs is not - an accepted gap.
561
-
562
- **A script that does not fit where it runs.** When a line of the script itself fails - a command or file it names is
563
- not there, or not runnable, as bash reports it (`run_unittests.sh: line 6: /usr/libexec/java_home: No such file or
564
- directory`, a macOS-only line run in Linux) - the agent's output starts with a note that the line is the person's
565
- script, not its code, and not to go looking for what it names; the person is told once, in the job's log, that the
566
- script is theirs to fix. A failure of what the script runs is left alone: that may well be the code's.
567
-
568
- **What they run on.** By default, the code in place: the project's own script at its own path, from the project's
569
- folder, on the real build and tests folders. A script that finds things from its own path - an integration embedded in
570
- a host codebase, whose scripts merge the generated code into the host and find the host from where they sit - finds
571
- them. What the script does to the host - copying the package into it - it does, as it is written to.
572
-
573
- `testing-scripts-run-on: copy` in the project's `config.turri.yaml` runs them on a fresh copy of the code instead, and of the
574
- whole conformance suite, in `plain_modules/.turri/scripts/`, named for its module and the run, with the project's script
575
- copied in beside it: the scripts work in `/tmp/<lang>_<basename of the build>`, and every module's build is called
576
- `code`, so two modules testing at once never share that folder, build output stays out of the code, and nothing a test
577
- writes reaches it. A script copied there no longer sits beside the project, so one that finds things from its own path
578
- does not find them:
221
+ The same `config.turri.yaml` holds the project's other defaults - `module`, `model`, `conformance-tests` - for [unattended runs](headless.md). A folder holding two of a kind is not guessed between: name the one to use in `config.turri.yaml`, or in each stack's own file. The scripts are not linked from the specs; a link to one is ignored.
222
+
223
+ They are required: a build with no unit testing script, or with conformance on and no conformance testing script, stops before it starts and says which skill adds it.
224
+
225
+ **The prepare script** is optional: turri never writes one, and runs one the project has - `prepare-environment-script:` in the config, else the one `prepare_environment*.sh` at the root, else in `test_scripts/` - on the build, before every run of the conformance testing script: the harness's own, and the agents' `run_conformance_tests`. Both get the same build folder - the code in place, or the same fresh copy - so what it sets up for that build, the conformance testing script finds. With conformance off it is not run. Every agent shown the conformance testing script - the explorer, the conformance agent, the judge, the code fixer and the repair agent - is shown it too, before the conformance testing script.
226
+
227
+ **Where they run.** On this machine, as you would run them: unfenced - no sandbox, no command check, no audit - in your own environment with this machine's toolchains, turri's model providers' API keys alone left out. They are yours, and whatever they do is your doing. That is the only way the two scripts are ever run: the harness's own runs, and the agents' `run_unit_tests` and `run_conformance_tests`, which run them exactly as the harness does - through the host runner, in a process group of their own, so the time limit and a stopped job end the script and all it started. A toolchain the script needs and this machine lacks - exit 69, exit 127, or a run that ended on a `command not found` / `failed to run command`, the last line it printed (`missingToolchain`) - is yours to install. Only on that evidence: a `command not found` earlier in the output, the run going on after it and failing for its own reasons, is a warning - a shell profile's, an optional tool probed for - and the failure is the agent's to fix. A missing toolchain is yours to install, never the agent's: the agent is told to report it with `report_environment_error` rather than work around it, and the pulse stops at the harness's first run of either script - unit or conformance - that cannot find it, rolled back, saying what to install (see [when the environment lacks something](#when-the-environment-lacks-something)). The code and the tests an agent wrote run unfenced inside the script too: what an agent runs with its own shell is fenced, what your script runs is not - an accepted gap.
228
+
229
+ **A script that does not fit where it runs.** When a line of the script itself fails - a command or file it names is not there, or not runnable, as bash reports it (`run_unittests.sh: line 6: /usr/libexec/java_home: No such file or directory`, a macOS-only line run in Linux) - the agent's output starts with a note that the line is the person's script, not its code, and not to go looking for what it names; the person is told once, in the job's log, that the script is theirs to fix. A failure of what the script runs is left alone: that may well be the code's.
230
+
231
+ **What they run on.** By default, the code in place: the project's own script at its own path, from the project's folder, on the real build and tests folders. A script that finds things from its own path - an integration embedded in a host codebase, whose scripts merge the generated code into the host and find the host from where they sit - finds them. What the script does to the host - copying the package into it - it does, as it is written to.
232
+
233
+ `testing-scripts-run-on: copy` in the project's `config.turri.yaml` runs them on a fresh copy of the code instead, and of the whole conformance suite, in `plain_modules/.turri/scripts/`, named for its module and the run, with the project's script copied in beside it: the scripts work in `/tmp/<lang>_<basename of the build>`, and every module's build is called `code`, so two modules testing at once never share that folder, build output stays out of the code, and nothing a test writes reaches it. A script copied there no longer sits beside the project, so one that finds things from its own path does not find them:
579
234
 
580
235
  ```yaml
581
236
  # plain/config.turri.yaml
582
237
  testing-scripts-run-on: copy
583
238
  ```
584
239
 
585
- `can_it_fail` works either way: on a copy it changes the copy; in place it changes the code for the one run and puts
586
- it back.
240
+ `can_it_fail` works either way: on a copy it changes the copy; in place it changes the code for the one run and puts it back.
587
241
 
588
242
  ### When the environment lacks something
589
243
 
590
- No agent installs anything on the machine, and none makes up a credential. When the machine lacks what the work needs,
591
- the pulse stops instead - rolled back, as any failed pulse is - its module's later pulses wait, unrelated modules go on,
592
- and you are told:
244
+ No agent installs anything on the machine, and none makes up a credential. When the machine lacks what the work needs, the pulse stops instead - rolled back, as any failed pulse is - its module's later pulses wait, unrelated modules go on, and you are told:
593
245
 
594
246
  > **d365_version_api stopped: the environment lacks JDK 21.**
595
247
  > Needed by: `run_unittests.sh` (it could not find `java`).
@@ -598,85 +250,31 @@ and you are told:
598
250
 
599
251
  It is raised two ways:
600
252
 
601
- - **by an agent**, which calls `report_environment_error` - only the agents that write and run code have it: the
602
- coding agent, the code fixer, the repair agent and the conformance agent; explorers, reviewers and judges observe,
603
- and never stop a pulse this way -
604
- with what is missing, what needs it and the command that showed it. Its shell runs behind walls the testing scripts
605
- do not, so what failed there may run here: the harness first runs the testing script itself - the unit one, the
606
- conformance one for the conformance agent. If it passes, the report does not stand: the agent is told the machine has
607
- what the work needs and goes on. If it cannot find its toolchain, the report stands. If it fails otherwise, the agent
608
- is shown its output once, and a report made again after that stands. A report that stands ends its turn, the pulse
609
- stops, and what it said goes to you as it is;
610
- - **by the harness itself**: a testing script - the unit or the conformance one, in a code pulse, a conformance pulse or
611
- the whole-suite run - that cannot find its toolchain (exit 69 or 127, a `command not found` the run ended on), or
612
- a credential `agent-env:` names that is not there when the pulse starts - before any agent does. What the harness
613
- found it works out at once - the diagnosis, not after a second failure - to say how to fix it on this machine.
614
-
615
- **Hidden by turri's own sandbox, not missing.** An agent's commands run behind the OS sandbox, which reads only the
616
- toolchain folders it knows; a toolchain kept somewhere else - a version manager's install it does not recognise - is
617
- on the machine, but out of the agent's sight. When a report names a file that is on this machine, outside the project
618
- and the system's folders (`sandboxGapOf` in `environment-error.ts`), the stop says so, and the fix is a line of config,
619
- not an install:
253
+ - **by an agent**, which calls `report_environment_error` - only the agents that write and run code have it: the coding agent, the code fixer, the repair agent and the conformance agent; explorers, reviewers and judges observe, and never stop a pulse this way - with what is missing, what needs it and the command that showed it. Its shell runs behind walls the testing scripts do not, so what failed there may run here: the harness first runs the testing script itself - the unit one, the conformance one for the conformance agent. If it passes, the report does not stand: the agent is told the machine has what the work needs and goes on. If it cannot find its toolchain, the report stands. If it fails otherwise, the agent is shown its output once, and a report made again after that stands. A report that stands ends its turn, the pulse stops, and what it said goes to you as it is;
254
+ - **by the harness itself**: a testing script - the unit or the conformance one, in a code pulse, a conformance pulse or the whole-suite run - that cannot find its toolchain (exit 69 or 127, a `command not found` the run ended on), or a credential `agent-env:` names that is not there when the pulse starts - before any agent does. What the harness found it works out at once - the diagnosis, not after a second failure - to say how to fix it on this machine.
255
+
256
+ **Hidden by turri's own sandbox, not missing.** An agent's commands run behind the OS sandbox, which reads only the toolchain folders it knows; a toolchain kept somewhere else - a version manager's install it does not recognise - is on the machine, but out of the agent's sight. When a report names a file that is on this machine, outside the project and the system's folders (`sandboxGapOf` in `environment-error.ts`), the stop says so, and the fix is a line of config, not an install:
620
257
 
621
258
  > **lunch stopped: turri's sandbox kept its agents from reading `…/mise/installs/node/24.16.0/lib/node_modules/npm/bin/npm-cli.js` - it is on this machine; nothing is missing.**
622
259
  > To fix: let the agents read that toolchain - add its folder to `toolchains:` in config.turri.yaml, keeping what is there: `toolchains: [/Users/…/mise/installs/node/24.16.0]`. Nothing needs installing.
623
260
 
624
- A write the sandbox refused is told apart from a read - a report naming a lock file (`*.lock`, `*.lck`, `lockfile`, even
625
- one never made), or saying a write, a create or a lock not taken. No setting lets the agents write outside their
626
- module's folders, their own home and temporary folder and the package caches, and `toolchains:` only lets them read; so
627
- the stop names the lock and what fixes it instead. In your home - a tool that found it without `$HOME`, as a JVM does for
628
- `user.home` - it is having the tool use `$HOME` (`-Duser.home=$HOME` where the build starts its JVM); in a toolchain's own
629
- install, it is a setting of the tool's that keeps the write elsewhere, or a copy of the toolchain that keeps its writes in
630
- its cache. The agents are told such a refusal is the sandbox's, to report at once - not to work around it for half an
631
- hour.
632
-
633
- **The conversation heals it.** Told of the stop, it never regenerates the module again before the cause is fixed - a pulse
634
- stopped on its environment stops the same way again - and fixes what it can:
635
-
636
- - **hidden by the sandbox**: it adds the folder to `toolchains:` itself, says so in a line, and resumes - a refused
637
- write, which no setting fixes, it fixes in the project's own files when it can, and otherwise tells you what to do;
638
- - **a toolchain or a tool missing** - a JDK, Maven, Go, uv: it looks first for one installed off the PATH - Homebrew's opt
639
- folders, `/Library/Java/JavaVirtualMachines`, mise, asdf, sdkman, nvm - then asks you, with the exact command for this
640
- machine (`brew install openjdk@21`, `mise use -g java@21`), and on your yes runs it in its shell, checks the command is
641
- found now as the testing script would find it, and resumes. One installed where turri's own PATH does not reach needs
642
- turri restarted, and it says so. On a no - or where it cannot do it, sudo with a password, a licence - it tells you
643
- exactly what to do;
261
+ A write the sandbox refused is told apart from a read - a report naming a lock file (`*.lock`, `*.lck`, `lockfile`, even one never made), or saying a write, a create or a lock not taken. No setting lets the agents write outside their module's folders, their own home and temporary folder and the package caches, and `toolchains:` only lets them read; so the stop names the lock and what fixes it instead. In your home - a tool that found it without `$HOME`, as a JVM does for `user.home` - it is having the tool use `$HOME` (`-Duser.home=$HOME` where the build starts its JVM); in a toolchain's own install, it is a setting of the tool's that keeps the write elsewhere, or a copy of the toolchain that keeps its writes in its cache. The agents are told such a refusal is the sandbox's, to report at once - not to work around it for half an hour.
262
+
263
+ **The conversation heals it.** Told of the stop, it never regenerates the module again before the cause is fixed - a pulse stopped on its environment stops the same way again - and fixes what it can:
264
+
265
+ - **hidden by the sandbox**: it adds the folder to `toolchains:` itself, says so in a line, and resumes - a refused write, which no setting fixes, it fixes in the project's own files when it can, and otherwise tells you what to do;
266
+ - **a toolchain or a tool missing** - a JDK, Maven, Go, uv: it looks first for one installed off the PATH - Homebrew's opt folders, `/Library/Java/JavaVirtualMachines`, mise, asdf, sdkman, nvm - then asks you, with the exact command for this machine (`brew install openjdk@21`, `mise use -g java@21`), and on your yes runs it in its shell, checks the command is found now as the testing script would find it, and resumes. One installed where turri's own PATH does not reach needs turri restarted, and it says so. On a no - or where it cannot do it, sudo with a password, a licence - it tells you exactly what to do;
644
267
  - **a credential missing**: never made up - you are told where `agent-env:` reads it from.
645
268
 
646
- Either way the pulse is not tried again: no second run would find what is missing. The message is in the chat, at the
647
- end of `turri regenerate`, and in the job's log; after the fix the pulse runs again from the start. The re-run line names the spec that was regenerated, as the folder it was run from reaches it.
269
+ Either way the pulse is not tried again: no second run would find what is missing. The message is in the chat, at the end of `turri regenerate`, and in the job's log; after the fix the pulse runs again from the start. The re-run line names the spec that was regenerated, as the folder it was run from reaches it.
648
270
 
649
271
  ### What a job is given, and what it records
650
272
 
651
- Every job is a spec diff: the agent that renders it is given the spec the code is built from - its
652
- functional specs in `<already implemented>` - and the change to it, in `<spec change>`, section by
653
- section - not the raw diff: each of `<definitions>`, `<implementation reqs>` and `<functional specs>` in
654
- its own tag, `<definitions change="1 added, 2 changed">`, saying what is added, what changed with its text
655
- before and now, and what is removed, measured from what is built to the spec the job ends on. A
656
- definition is itself by its concept: one reworded or moved is shown as changed, not as removed and added.
657
- Test reqs and acceptance tests are for conformance only: the code record holds neither, and no coding
658
- agent is shown them.
659
-
660
- **Every part of the spec is given with its module.** A codebase is built from the spec of its whole requires chain,
661
- and each module numbers its functional specs from 1, so every agent is shown each section grouped under the module
662
- each item belongs to - `<module name="base">`, then `<module name="app" role="current">` - as `<already implemented>`
663
- groups the functional specs (`moduleSection`, `functionalitiesByModule` in `prompt.ts`). A module's own items, and
664
- what it imports, are the current module's. `<spec change>` names a functional spec as "functionality 2 of module
665
- `app`", and a definition or req of a module below with its module; each case line does too ("fs 2 of module `app`").
666
- The primer every agent reads first says that modules are how the \*\*\*plain spec is written, not how the code is laid
667
- out: the agent works only in the current module's codebase, which holds the code of every module it requires, and
668
- organises the code as the implementation reqs say.
669
-
670
- It is told, too, what to do with each functional spec the job touches, by its case (`src/regenerate/cases.ts`): a
671
- fresh project is set up first, with its unit tests where the unit
672
- testing script runs them; a new functional spec is built and unit tested; a changed one - its text, or a concept
673
- it uses - is changed in place, its code and tests to match, never built again from scratch; one regenerated again is
674
- replaced, not patched - rewritten or started over, what it replaces taken out; one taken out has its
675
- code and the tests only it had removed. A job holding several cases has a line for each. A job that touches no
676
- functional spec - implementation reqs, or definitions none uses - is mechanical: the code adapts, no new test is
677
- written, and an existing one may change only mechanically, never what it asserts. The unit test review holds each
678
- part to its case, and a mechanical job only to its reqs and to no test removed or weakened. A conformance job's
679
- agent and its reviewer are told the same, for the tests:
273
+ Every job is a spec diff: the agent that renders it is given the spec the code is built from - its functional specs in `<already implemented>` - and the change to it, in `<spec change>`, section by section - not the raw diff: each of `<definitions>`, `<implementation reqs>` and `<functional specs>` in its own tag, `<definitions change="1 added, 2 changed">`, saying what is added, what changed with its text before and now, and what is removed, measured from what is built to the spec the job ends on. A definition is itself by its concept: one reworded or moved is shown as changed, not as removed and added. Test reqs and acceptance tests are for conformance only: the code record holds neither, and no coding agent is shown them.
274
+
275
+ **Every part of the spec is given with its module.** A codebase is built from the spec of its whole requires chain, and each module numbers its functional specs from 1, so every agent is shown each section grouped under the module each item belongs to - `<module name="base">`, then `<module name="app" role="current">` - as `<already implemented>` groups the functional specs (`moduleSection`, `functionalitiesByModule` in `prompt.ts`). A module's own items, and what it imports, are the current module's. `<spec change>` names a functional spec as "functionality 2 of module `app`", and a definition or req of a module below with its module; each case line does too ("fs 2 of module `app`"). The primer every agent reads first says that modules are how the \*\*\*plain spec is written, not how the code is laid out: the agent works only in the current module's codebase, which holds the code of every module it requires, and organises the code as the implementation reqs say.
276
+
277
+ It is told, too, what to do with each functional spec the job touches, by its case (`src/regenerate/cases.ts`): a fresh project is set up first, with its unit tests where the unit testing script runs them; a new functional spec is built and unit tested; a changed one - its text, or a concept it uses - is changed in place, its code and tests to match, never built again from scratch; one regenerated again is replaced, not patched - rewritten or started over, what it replaces taken out; one taken out has its code and the tests only it had removed. A job holding several cases has a line for each. A job that touches no functional spec - implementation reqs, or definitions none uses - is mechanical: the code adapts, no new test is written, and an existing one may change only mechanically, never what it asserts. The unit test review holds each part to its case, and a mechanical job only to its reqs and to no test removed or weakened. A conformance job's agent and its reviewer are told the same, for the tests:
680
278
 
681
279
  | case | when | code | conformance |
682
280
  | --- | --- | --- | --- |
@@ -687,161 +285,53 @@ agent and its reviewer are told the same, for the tests:
687
285
  | delete | a functional spec is gone | take out its code and the tests only it had | take out its tests |
688
286
  | mechanical | no functional spec is touched - only reqs, or definitions none uses | adapt the code; write no new test; an existing one may change only mechanically - an import, a fixture, its setup - never what it asserts | the same, for test reqs, definitions or implementation reqs alone |
689
287
 
690
- **Regenerating again.** `regenerate` with functionalities named regenerates them again though their spec did not change -
691
- made better, on another model, after many patches. Each is marked in the code record of every codebase it is built
692
- in (`regenerate_again`, committed), and nothing else changes: the record now differs from the spec at that item, so the
693
- work loop plans it as it plans any change. A functional spec of a module below is regenerated again where its code
694
- lives - the codebase at the tip of each chain built on it, never the module's own codebase left behind - marked
695
- among that codebase's required functional specs. The planner groups the ones regenerated again as it groups new ones - up
696
- to three a job, only those next to each other in one module together - and the job is given the definitions and
697
- implementation reqs as every job is; `<spec change>` lists each under "To regenerate again", with its text as it is now. The job that regenerates it
698
- records it as the spec has it, without the mark. Its conformance tests compare its text, which did not change: they
699
- stay as they are, and are not rewritten.
700
-
701
- A functional spec is patched when a concept it uses changed as well as when its own text did: the
702
- harness follows each functional spec's concepts through the definitions. Fresh is only where nothing
703
- exists: a module that requires another starts from what it inherits, and its first job adds or patches.
704
-
705
- **Linked resources.** A file the spec links is part of it, so what it holds is compared too: each linked
706
- resource is hashed on its own (sha256 of its content) beside its link, in the trees the loop compares and in
707
- both records. A change to the file - an API surface `openapi.yaml` defines - changes the item that links it,
708
- with no change to the `.plain` text: a functional spec linking it is patched, and a definition linking it
709
- patches every functional spec using its concept. The job's diff has a hunk of its own for each such file,
710
- under the file's name - shown as a file of its own where the job is shown - saying which item links it, in which
711
- spec file (`resources/hubspot/openapi.yaml, linked by :HubSpotRestAPI: in hubspot.plain`), and that its content
712
- changed, with both hashes; the agent is told which file holds something else now, beside the item's
713
- unchanged text, and reads the file as it is now in `<linked resources>`. The records keep the hash, not the
714
- content, so what the file held before is not shown. A record written before resources were hashed is taken
715
- as built from the files as they are now: the loop hashes its links and commits it, building nothing again.
716
-
717
- **Where a linked resource goes in the code.** A linked resource is not in the agent's workspace; it reaches the agent
718
- only in `<linked resources>`. Each text resource is given a `code-copy` - its path, without steps up - and the
719
- agent is told that when the code needs what the resource holds while it runs, it keeps exactly one copy there (or
720
- where the implementation reqs put such files) and reads it from there, and otherwise copies none, so one file is
721
- not written to every place it might be read from.
722
-
723
- **Linked images.** A linked `.png`, `.jpg` or `.jpeg` is an image, not text (`resources.ts`). The coding agent
724
- and the conformance agent are sent it with their first message - and again after each compaction, which sums
725
- the conversation up without its images - and `<linked resources>` lists it with its type and its number among
726
- the attachments (`<resource name="checkout mockup" path="resources/checkout.png" type="image/png">`). Their
727
- model has to read images: a job whose spec links one refuses a model that does not before any agent starts
728
- (`refuseIfModelIsBlind`; `createExecutor` refuses pi's default model the same way), saying which model and to
729
- set `coding-model` to one that reads images or describe the image in text. An image over 5 MB stops the job,
730
- naming the file. The reviewers do not see linked resources, text or images. An image is hashed like any linked
731
- file, so a new mockup patches the functional specs that link it.
732
-
733
- A job lands once its unit tests pass and are reviewed: the code record becomes the spec the job ends on,
734
- committed with the code. Its conformance tests are not the code job's: they are a track of their own
735
- ([conformance tests in the work loop](#conformance-tests-in-the-work-loop)).
736
-
737
- A change that renders nothing - definitions moved to a common module, reqs reordered, specs moved between
738
- modules of the chain - is recorded, not rendered: the spec is recorded as it is now laid out and committed,
739
- with no agent and no testing script. Moving specs into a module the code was not built on is different: no
740
- change to the code brings that module's code in, so the codebase stops: it has to be started over - its code
741
- and conformance tests taken out, committed so its history keeps them, and the chain built again from the
742
- bottom. That is never done unasked. In the chat the model asks the person, saying why, and calls
743
- `regenerate` with `from_scratch: "module"` once they agree; `turri regenerate` and `spec-diff` ask at the terminal, and
744
- `--start-over` agrees in advance - with no terminal and no flag, the run stops there, exit 1, saying so.
288
+ **Regenerating again.** `regenerate` with functionalities named regenerates them again though their spec did not change - made better, on another model, after many patches. Each is marked in the code record of every codebase it is built in (`regenerate_again`, committed), and nothing else changes: the record now differs from the spec at that item, so the work loop plans it as it plans any change. A functional spec of a module below is regenerated again where its code lives - the codebase at the tip of each chain built on it, never the module's own codebase left behind - marked among that codebase's required functional specs. The planner groups the ones regenerated again as it groups new ones - up to three a job, only those next to each other in one module together - and the job is given the definitions and implementation reqs as every job is; `<spec change>` lists each under "To regenerate again", with its text as it is now. The job that regenerates it records it as the spec has it, without the mark. Its conformance tests compare its text, which did not change: they stay as they are, and are not rewritten.
289
+
290
+ A functional spec is patched when a concept it uses changed as well as when its own text did: the harness follows each functional spec's concepts through the definitions. Fresh is only where nothing exists: a module that requires another starts from what it inherits, and its first job adds or patches.
291
+
292
+ **Linked resources.** A file the spec links is part of it, so what it holds is compared too: each linked resource is hashed on its own (sha256 of its content) beside its link, in the trees the loop compares and in both records. A change to the file - an API surface `openapi.yaml` defines - changes the item that links it, with no change to the `.plain` text: a functional spec linking it is patched, and a definition linking it patches every functional spec using its concept. The job's diff has a hunk of its own for each such file, under the file's name - shown as a file of its own where the job is shown - saying which item links it, in which spec file (`resources/hubspot/openapi.yaml, linked by :HubSpotRestAPI: in hubspot.plain`), and that its content changed, with both hashes; the agent is told which file holds something else now, beside the item's unchanged text, and reads the file as it is now in `<linked resources>`. The records keep the hash, not the content, so what the file held before is not shown. A record written before resources were hashed is taken as built from the files as they are now: the loop hashes its links and commits it, building nothing again.
293
+
294
+ **Where a linked resource goes in the code.** A linked resource is not in the agent's workspace; it reaches the agent only in `<linked resources>`. Each text resource is given a `code-copy` - its path, without steps up - and the agent is told that when the code needs what the resource holds while it runs, it keeps exactly one copy there (or where the implementation reqs put such files) and reads it from there, and otherwise copies none, so one file is not written to every place it might be read from.
295
+
296
+ **Linked images.** A linked `.png`, `.jpg` or `.jpeg` is an image, not text (`resources.ts`). The coding agent and the conformance agent are sent it with their first message - and again after each compaction, which sums the conversation up without its images - and `<linked resources>` lists it with its type and its number among the attachments (`<resource name="checkout mockup" path="resources/checkout.png" type="image/png">`). Their model has to read images: a job whose spec links one refuses a model that does not before any agent starts (`refuseIfModelIsBlind`; `createExecutor` refuses pi's default model the same way), saying which model and to set `coding-model` to one that reads images or describe the image in text. An image over 5 MB stops the job, naming the file. The reviewers do not see linked resources, text or images. An image is hashed like any linked file, so a new mockup patches the functional specs that link it.
297
+
298
+ A job lands once its unit tests pass and are reviewed: the code record becomes the spec the job ends on, committed with the code. Its conformance tests are not the code job's: they are a track of their own ([conformance tests in the work loop](#conformance-tests-in-the-work-loop)).
299
+
300
+ A change that renders nothing - definitions moved to a common module, reqs reordered, specs moved between modules of the chain - is recorded, not rendered: the spec is recorded as it is now laid out and committed, with no agent and no testing script. Moving specs into a module the code was not built on is different: no change to the code brings that module's code in, so the codebase stops: it has to be started over - its code and conformance tests taken out, committed so its history keeps them, and the chain built again from the bottom. That is never done unasked. In the chat the model asks the person, saying why, and calls `regenerate` with `from_scratch: "module"` once they agree; `turri regenerate` and `spec-diff` ask at the terminal, and `--start-over` agrees in advance - with no terminal and no flag, the run stops there, exit 1, saying so.
745
301
 
746
302
  ## Conformance tests
747
303
 
748
- The unit tests are written by the agent that wrote the code. Conformance tests are the other half:
749
- black box, end to end, written from the spec.
304
+ The unit tests are written by the agent that wrote the code. Conformance tests are the other half: black box, end to end, written from the spec.
750
305
 
751
306
  ```bash
752
307
  turri conform <file.plain> # every functional spec the code is built from
753
308
  turri conform <file.plain> 1 3 # functional specs 1 and 3
754
309
  ```
755
310
 
756
- They follow the code: a functional spec gets conformance tests once its code is built. Conformance is
757
- off by default: `conformance-tests: all` (or `chosen`, or `module`) in the [config](config.md) turns it on, for modules
758
- with `***test reqs***`, and `conform` asks for it in a session. Once a codebase has conformance tests,
759
- they are always run and kept passing, whether or not the current render writes new ones, and they
760
- are carried up to the modules built on top of it.
311
+ They follow the code: a functional spec gets conformance tests once its code is built. Conformance is off by default: `conformance-tests: all` (or `chosen`, or `module`) in the [config](config.md) turns it on, for modules with `***test reqs***`, and `conform` asks for it in a session. Once a codebase has conformance tests, they are always run and kept passing, whether or not the current render writes new ones, and they are carried up to the modules built on top of it.
761
312
 
762
313
  ### Conformance tests in the work loop
763
314
 
764
- In the work loop, conformance is a track beside the code's. What the conformance tests are written for is
765
- recorded apart - `tests/.turri.json`: the functional specs they test, as built, with their acceptance
766
- tests, the definitions and implementation reqs they were written against, and the test reqs they follow -
767
- and the work is from that record to what they are to be: of the functional specs the code is built from,
768
- those chosen - every one, or those `conform` names - as the spec has them, with its test reqs. A
769
- functional spec whose code is behind the spec - built from other text, or not in the code record at all, as while
770
- `regenerate` regenerates it again by name - keeps its tests until the code lands; they are taken out only once the spec and the
771
- code have both dropped it. The harness cuts the work into jobs, and no agent is asked: every functional spec
772
- tested - added or changed, asked for by `conform`, chosen, or left by the code jobs - is in one conformance job, a
773
- module's own together, as far as a guardrail lets: a new job begins only where the next functional spec would take
774
- the job's functional specs and the definitions they bring past 120 lines. The reqs they are written against go
775
- with the first job, and do not count. When the person asks for it - one at a time, separately - `conform`'s
776
- `one_by_one` (`turri conform --one-by-one`) makes it a job a functional spec instead, until conformance tests are asked
777
- for again without it. And when the person asks for them in pulses of their own grouping - 1-3 and 4-6 - `conform`'s
778
- `groups` gives each group a job of its own: a job never takes functional specs of two groups, and within a group the
779
- guardrail still cuts. Only work that
780
- touches no functional spec at all, the test reqs changed say, is a job without one. A module's conformance jobs run
781
- on its lane once its code is built - every code job of it landed - so the module is tested once, as built: one
782
- explorer, one run of the whole suite, rather than a conformance cycle after each code job; and they pass before
783
- anything is built on it. Until then they are not planned, but what is planned lists them last - `conformance tests -
784
- planned once the code is built` - wherever they are on for the whole module, so asking for them is seen to have worked;
785
- `conform` asked again for a module they are on for already says so, and changes nothing.
786
-
787
- A conformance job is a spec diff's conformance run: the tests of its change written, changed or taken out,
788
- a failure judged - the test or the code wrong - and fixed, then the whole suite with the unit tests, the
789
- tests the module inherits with them. The run that passed already was of the whole suite - the module's tests
790
- folder holds the chain's, copied up - so the suite is run once more only when the code or the tests changed after
791
- it passed with the unit tests; otherwise it is not run again. Passing, the tests record is written and committed with the tests;
792
- otherwise all of it - code fixes included - is rolled back, and the module halts until the spec or the code
793
- changes, or `conform` asks again: its conformance tests, its code - nothing more is built on code whose conformance
794
- tests did not pass - and every module built on it, which waits.
795
-
796
- **Up the chain.** A module built on another starts from its code and its conformance tests, copied up, and its
797
- conformance testing script runs those with its own. So a module waits for the one below it until that one's code
798
- is built and its conformance tests - those wanted, chosen or scheduled - are written and pass; only then is its
799
- codebase started from there.
800
-
801
- **Who chooses, and when.** With `conformance-tests: all` every functional spec is tested, and with `false` none is
802
- unless the person asks with `conform`, for the session. With `chosen` or `module`, every one with acceptance tests - the
803
- author said what to check - and those the chooser picks: an agent on `harness-model` (or `models: chooser`), in the chat
804
- and on the command line alike. It reads the module's spec and names those worth black-box tests - what a user or a
805
- client relies on, not a detail the unit tests cover - and why.
806
-
807
- - `chosen`: it is asked as each code pulse ends, as the pulse's last stage, of what that pulse regenerated that no
808
- conformance test is for.
809
- - `module`: it is asked once, when the module's last code pulse lands, of every functional spec of the module that is
810
- built and has none - and it plans them too, into groups, each a conformance pulse of its own.
811
-
812
- Either way the choice is made inside the pulse, so it is made - and its conformance pulse scheduled - before anything
813
- can be built on the module: nothing ever has to be stopped for it. The pulse's report says what it chose and why
814
- (`conformance: fs 1, 3 chosen - ...`), and the chat is told, not asked: it calls `conform` only when the person asks.
815
- One the chooser passed over is not offered again while its text is the same. `conformance-budget:` caps how many of a
816
- module's functional specs are chosen, beside those with acceptance tests - a count, or a share of them: every choice for
817
- the module counts against it, and the chooser is told what is left and can choose no more; the person's own `conform`
818
- is not limited. The ones named are added to those chosen before, and a functional spec that has conformance tests
819
- keeps them: they are rewritten when it changes, never taken out because others were named.
820
-
821
- **What the person asks for comes first.** `conform` changes the module named alone, never the modules below it. For a
822
- module not regenerated yet - one above the module being regenerated, say - its tests are scheduled now and written once
823
- its code is built, before anything is built on it. For a module already regenerated whose tests are not written, while
824
- a module above it was started from it - its first pulse running, or code of its own built - the codebase above is
825
- disposable: a pulse running there is stopped, whatever `allow-to-stop-jobs` says, as the person asked; the codebase is
826
- deleted whole, its history with it; the tests are written in the module's own codebase; and the module above is
827
- regenerated from it once they pass. Asked for tests it has already, nothing is touched.
828
-
829
- **Scheduled ahead of the code.** `conform` may name functional specs whose code is not built yet:
830
- each call schedules them as one group, shown at once in what is planned, after the module's last code job. Its
831
- functional specs are chosen once the code record has every one as the spec has it, and its tests are written once
832
- the module's code is built. A functional spec the spec does not have - built by no code job - or a module with no
833
- test reqs is refused, and nothing is scheduled; one taken out of the spec later is dropped from its group.
834
- Groups whose code is built by then are tested together, in one job with the rest, as far as the guardrail lets.
835
-
836
- While a codebase's work is being planned into jobs, with nothing running there, what is planned says so - the
837
- conformance tests of the groups being planned, or the work - rather than showing nothing until the plan is made.
838
-
839
- **What a conformance job tests is built.** As a conformance job starts, the harness reads the code record,
840
- `code/.turri.json`, and checks that it has every functional spec the job adds or changes tests for, as the
841
- job has it. One it does not have stops the job before any agent runs: its report says which are not built, the
842
- conformance tests halt, and the chat model tells the person. They are tried again once the code or the spec
843
- changes. Code jobs and conformance jobs are planned apart, each track on its own: a job is one or the other. A module built on another starts with an empty tests record: the tests it inherits are the
844
- module below's, and none of its own is written yet.
315
+ In the work loop, conformance is a track beside the code's. What the conformance tests are written for is recorded apart - `tests/.turri.json`: the functional specs they test, as built, with their acceptance tests, the definitions and implementation reqs they were written against, and the test reqs they follow - and the work is from that record to what they are to be: of the functional specs the code is built from, those chosen - every one, or those `conform` names - as the spec has them, with its test reqs. A functional spec whose code is behind the spec - built from other text, or not in the code record at all, as while `regenerate` regenerates it again by name - keeps its tests until the code lands; they are taken out only once the spec and the code have both dropped it. The harness cuts the work into jobs, and no agent is asked: every functional spec tested - added or changed, asked for by `conform`, chosen, or left by the code jobs - is in one conformance job, a module's own together, as far as a guardrail lets: a new job begins only where the next functional spec would take the job's functional specs and the definitions they bring past 120 lines. The reqs they are written against go with the first job, and do not count. When the person asks for it - one at a time, separately - `conform`'s `one_by_one` (`turri conform --one-by-one`) makes it a job a functional spec instead, until conformance tests are asked for again without it. And when the person asks for them in pulses of their own grouping - 1-3 and 4-6 - `conform`'s `groups` gives each group a job of its own: a job never takes functional specs of two groups, and within a group the guardrail still cuts. Only work that touches no functional spec at all, the test reqs changed say, is a job without one. A module's conformance jobs run on its lane once its code is built - every code job of it landed - so the module is tested once, as built: one explorer, one run of the whole suite, rather than a conformance cycle after each code job; and they pass before anything is built on it. Until then they are not planned, but what is planned lists them last - `conformance tests - planned once the code is built` - wherever they are on for the whole module, so asking for them is seen to have worked; `conform` asked again for a module they are on for already says so, and changes nothing.
316
+
317
+ A conformance job is a spec diff's conformance run: the tests of its change written, changed or taken out, a failure judged - the test or the code wrong - and fixed, then the whole suite with the unit tests, the tests the module inherits with them. The run that passed already was of the whole suite - the module's tests folder holds the chain's, copied up - so the suite is run once more only when the code or the tests changed after it passed with the unit tests; otherwise it is not run again. Passing, the tests record is written and committed with the tests; otherwise all of it - code fixes included - is rolled back, and the module halts until the spec or the code changes, or `conform` asks again: its conformance tests, its code - nothing more is built on code whose conformance tests did not pass - and every module built on it, which waits.
318
+
319
+ **Up the chain.** A module built on another starts from its code and its conformance tests, copied up, and its conformance testing script runs those with its own. So a module waits for the one below it until that one's code is built and its conformance tests - those wanted, chosen or scheduled - are written and pass; only then is its codebase started from there.
320
+
321
+ **Who chooses, and when.** With `conformance-tests: all` every functional spec is tested, and with `false` none is unless the person asks with `conform`, for the session. With `chosen` or `module`, every one with acceptance tests - the author said what to check - and those the chooser picks: an agent on `harness-model` (or `models: chooser`), in the chat and on the command line alike. It reads the module's spec and names those worth black-box tests - what a user or a client relies on, not a detail the unit tests cover - and why.
322
+
323
+ - `chosen`: it is asked as each code pulse ends, as the pulse's last stage, of what that pulse regenerated that no conformance test is for.
324
+ - `module`: it is asked once, when the module's last code pulse lands, of every functional spec of the module that is built and has none - and it plans them too, into groups, each a conformance pulse of its own.
325
+
326
+ Either way the choice is made inside the pulse, so it is made - and its conformance pulse scheduled - before anything can be built on the module: nothing ever has to be stopped for it. The pulse's report says what it chose and why (`conformance: fs 1, 3 chosen - ...`), and the chat is told, not asked: it calls `conform` only when the person asks. One the chooser passed over is not offered again while its text is the same. `conformance-budget:` caps how many of a module's functional specs are chosen, beside those with acceptance tests - a count, or a share of them: every choice for the module counts against it, and the chooser is told what is left and can choose no more; the person's own `conform` is not limited. The ones named are added to those chosen before, and a functional spec that has conformance tests keeps them: they are rewritten when it changes, never taken out because others were named.
327
+
328
+ **What the person asks for comes first.** `conform` changes the module named alone, never the modules below it. For a module not regenerated yet - one above the module being regenerated, say - its tests are scheduled now and written once its code is built, before anything is built on it. For a module already regenerated whose tests are not written, while a module above it was started from it - its first pulse running, or code of its own built - the codebase above is disposable: a pulse running there is stopped, whatever `allow-to-stop-jobs` says, as the person asked; the codebase is deleted whole, its history with it; the tests are written in the module's own codebase; and the module above is regenerated from it once they pass. Asked for tests it has already, nothing is touched.
329
+
330
+ **Scheduled ahead of the code.** `conform` may name functional specs whose code is not built yet: each call schedules them as one group, shown at once in what is planned, after the module's last code job. Its functional specs are chosen once the code record has every one as the spec has it, and its tests are written once the module's code is built. A functional spec the spec does not have - built by no code job - or a module with no test reqs is refused, and nothing is scheduled; one taken out of the spec later is dropped from its group. Groups whose code is built by then are tested together, in one job with the rest, as far as the guardrail lets.
331
+
332
+ While a codebase's work is being planned into jobs, with nothing running there, what is planned says so - the conformance tests of the groups being planned, or the work - rather than showing nothing until the plan is made.
333
+
334
+ **What a conformance job tests is built.** As a conformance job starts, the harness reads the code record, `code/.turri.json`, and checks that it has every functional spec the job adds or changes tests for, as the job has it. One it does not have stops the job before any agent runs: its report says which are not built, the conformance tests halt, and the chat model tells the person. They are tried again once the code or the spec changes. Code jobs and conformance jobs are planned apart, each track on its own: a job is one or the other. A module built on another starts with an empty tests record: the tests it inherits are the module below's, and none of its own is written yet.
845
335
 
846
336
  ### Conformance tests and acceptance tests, kept apart
847
337
 
@@ -852,214 +342,58 @@ The step writes two kinds of test, and never lets one stand in for the other:
852
342
  | Conformance tests | the functional spec itself - what it says the functionality does, its edge cases, its errors - as if no acceptance tests had been given | files whose names say conformance, each starting with a comment `conformance tests of functionality 3` |
853
343
  | Acceptance tests | each acceptance test in the spec, implemented as a test of its own, doing what it says | files whose names say acceptance, each test with a comment `acceptance test 2 of functionality 3:` and the acceptance test's text |
854
344
 
855
- Even when the acceptance tests seem to cover the functionality, the conformance tests are written
856
- independently: tests drawn only from the acceptance tests check what the author thought to check,
857
- and nothing the spec says beyond that. The acceptance tests reach the agent numbered, as their
858
- labels number them.
345
+ Even when the acceptance tests seem to cover the functionality, the conformance tests are written independently: tests drawn only from the acceptance tests check what the author thought to check, and nothing the spec says beyond that. The acceptance tests reach the agent numbered, as their labels number them.
859
346
 
860
- The labels are checked, not trusted: before a passing run counts, the harness reads the tests and
861
- sends the agent back for a functionality with no labelled conformance tests, or for any acceptance
862
- test that has no test of its own. Each functionality has a label of its own, on a line of its own: a
863
- file that tests several carries one line for each, and a label naming several at once - `conformance tests
864
- of functionality 1, 2 and 3` - counts for the first alone. For a spec change that touches several
865
- functionalities, everything missing - every functionality's - is asked for in one request, the agent told
866
- to keep the labels there already, and the whole set checked again after each answer. Anyone reading the
867
- tests - or the next agent - sees at a glance which is which, and which acceptance test a test implements.
347
+ The labels are checked, not trusted: before a passing run counts, the harness reads the tests and sends the agent back for a functionality with no labelled conformance tests, or for any acceptance test that has no test of its own. Each functionality has a label of its own, on a line of its own: a file that tests several carries one line for each, and a label naming several at once - `conformance tests of functionality 1, 2 and 3` - counts for the first alone. For a spec change that touches several functionalities, everything missing - every functionality's - is asked for in one request, the agent told to keep the labels there already, and the whole set checked again after each answer. Anyone reading the tests - or the next agent - sees at a glance which is which, and which acceptance test a test implements.
868
348
 
869
349
  ### Rendered apart from the code
870
350
 
871
- The code and its conformance tests are rendered apart, each in its own folder (see
872
- [the sandbox](sandbox.md#what-an-agent-can-reach)). The test author writes only the tests folder; its file
873
- tools can read the code too, and it is told so - read access, never write access - and to take how the
874
- software is reached from the code, never what it should do. Its shell holds the tests folder only. The
875
- coding agent that fixes the code is told the same of the tests: it can read them, never change them.
876
- Before the test author starts, an explorer - an agent in
877
- the code's folder with the file tools alone: it reads the code, runs nothing and changes nothing - hands over everything
878
- the author needs, in parts: how to build and run it; how the conformance tests reach it as the project's
879
- conformance testing script runs them - the explorer is given the script, and the prepare script before it where there
880
- is one, and says what they build or
881
- installs and what the tests depend on or start (a package, a module, an entry point, by its exact name);
882
- how each functionality is reached from outside
883
- (the command, or the route, method and the request and response fields); what it needs around it; and
884
- a plan for the conformance tests, its expectations taken from the spec. The account is checked before
885
- it is used: it has to say how the functionality under test is reached and what to test for it (for a
886
- spec diff, some of the module the change touches), and the plan has to carry out every acceptance test
887
- of it (for a spec diff, of every functionality the change touches), each named "acceptance test N", with
888
- how each of its steps is done from outside and what it asserts. One that does not is sent back saying
889
- what is missing. It is kept focused: the interface to what is under test, not a survey of the codebase, in
890
- words rather than code, under 12,000 characters. Each hand-over ends its turn, and it hands over three
891
- times at most. If it never completes it, what it wrote as it worked goes along with it, so nothing it
892
- found is lost. The tests are written from that account and the spec, and every assertion comes from the
893
- spec. `run_conformance_tests` puts
894
- the whole suite together with a copy of the build in a throwaway directory, so
895
- tests cannot accumulate state between attempts and nothing they write reaches the code.
896
-
897
- While it writes the tests, the conformance agent can put a question to the explorer - `ask_explorer`, three
898
- times a run: how a functionality is reached, what a field is called. A fresh explorer, in the code's folder,
899
- given the account it handed over and the question, reads the code and answers in words; it runs and changes
900
- nothing. And `my_diff` shows it the tests folder's diff from where the run started, as its reviewer is shown it.
351
+ The code and its conformance tests are rendered apart, each in its own folder (see [the sandbox](sandbox.md#what-an-agent-can-reach)). The test author writes only the tests folder; its file tools can read the code too, and it is told so - read access, never write access - and to take how the software is reached from the code, never what it should do. Its shell holds the tests folder only. The coding agent that fixes the code is told the same of the tests: it can read them, never change them. Before the test author starts, an explorer - an agent in the code's folder with the file tools alone: it reads the code, runs nothing and changes nothing - hands over everything the author needs, in parts: how to build and run it; how the conformance tests reach it as the project's conformance testing script runs them - the explorer is given the script, and the prepare script before it where there is one, and says what they build or installs and what the tests depend on or start (a package, a module, an entry point, by its exact name); how each functionality is reached from outside (the command, or the route, method and the request and response fields); what it needs around it; and a plan for the conformance tests, its expectations taken from the spec. The account is checked before it is used: it has to say how the functionality under test is reached and what to test for it (for a spec diff, some of the module the change touches), and the plan has to carry out every acceptance test of it (for a spec diff, of every functionality the change touches), each named "acceptance test N", with how each of its steps is done from outside and what it asserts. One that does not is sent back saying what is missing. It is kept focused: the interface to what is under test, not a survey of the codebase, in words rather than code, under 12,000 characters. Each hand-over ends its turn, and it hands over three times at most. If it never completes it, what it wrote as it worked goes along with it, so nothing it found is lost. The tests are written from that account and the spec, and every assertion comes from the spec. `run_conformance_tests` puts the whole suite together with a copy of the build in a throwaway directory, so tests cannot accumulate state between attempts and nothing they write reaches the code.
352
+
353
+ While it writes the tests, the conformance agent can put a question to the explorer - `ask_explorer`, three times a run: how a functionality is reached, what a field is called. A fresh explorer, in the code's folder, given the account it handed over and the question, reads the code and answers in words; it runs and changes nothing. And `my_diff` shows it the tests folder's diff from where the run started, as its reviewer is shown it.
901
354
 
902
355
  ### When a conformance test fails
903
356
 
904
- The harness runs the project's conformance testing script on the whole suite. When it passes, the
905
- unit testing script runs too - and then, with `review: true` in the config, the review gate: a reviewer reads the tests this run added or
906
- changed, and the code, and checks that they test black box - through the entry points the test reqs
907
- allow, never mocking or replacing any part of the software under test - that every test asserts what
908
- the spec says, with no placeholder that cannot fail, and that each acceptance test does every step it
909
- lists and asserts every expectation it states. It must pass, as the suite and the unit tests must:
910
- when it does not, the conformance agent gets exactly what is missing and what is bad, file by file, and
911
- the round goes again. One reviewer does every review of the run, as the unit tests' does: the first time
912
- it is shown the diff of the tests folder from the module's last commit, each time after the diff since its
913
- last review, and every time the conformance agent's account through `submit_work` - checked against the
914
- diff, never taken instead of it. The first review is asked for every problem at once; each after it is
915
- given what the last one found, checks that first, and raises something new only when it is serious - a test that
916
- cannot fail, mocks the software, or leaves out what the spec asks for. It asks only for what can be seen
917
- from outside: where the spec says one part calls another, the outcome, never the call. The reviewer is
918
- the exacting developer, as the unit tests' is, and marks each problem blocking or not: blocking when the
919
- functionality is not yet tested black box - a test or an acceptance test missing, cut down or skipping
920
- what it checks, the software mocked or not reached from outside, a test that cannot fail.
921
-
922
- The tests are reviewed twice at most, as the unit tests are: the first review that sends them back goes to
923
- the conformance agent as it is, and the second the arbiter weighs first, as it does the unit
924
- tests' (see [the code and its unit tests are reviewed](#the-code-and-its-unit-tests-are-reviewed)): it upholds what leaves the
925
- functionality not tested black box, and dismisses what is out of scope or a nitpick. Only what it
926
- upholds goes back to the conformance agent; when it upholds nothing, the tests are approved as they
927
- are, and what it let go is kept in the result and the notes' pitfalls. The review optimises the tests,
928
- it does not stop the run: what the second review sends back is worked on once, and then the tests go on
929
- without another review - once the suite and the unit tests pass, which they still must. All three passing
930
- is done.
931
-
932
- A spec diff's conformance run holds its tests to the same bar. The functionalities the change touches -
933
- a line of their functional spec, or of one of their acceptance tests, added or removed - are worked
934
- out from the diff. The conformance agent is shown their acceptance tests, numbered as they are labelled;
935
- the run does not finish until each one is a labelled test of its own; and the review checks each of
936
- them as it would a functionality's own.
937
-
938
- A failing run's output goes to the judge and whoever fixes it whole when it is up to 60,000 characters,
939
- and otherwise its last 60,000 - where a test run says what failed and why - with the file the whole of
940
- it is kept in.
941
-
942
- Why something failed is never lost. Every agent that writes or fixes code is told that where the code
943
- catches an error and turns it into a response, a status, a result or a retry, it logs the error with its
944
- whole trace, and what it hands on names the cause - never a bare "failed". When the output does not show
945
- why the software failed, the judge says the code is what is wrong, for hiding it, and the coding agent
946
- makes the cause show first, then fixes it. No agent may make the code behave differently when a test runs
947
- it. Both the conformance agent
948
- and the coding agent can run the conformance suite themselves, to reproduce a failure and check their
949
- fix - three times a turn: the third ends the turn, and the harness runs it and judges. The conformance
950
- agent is told that a failure of the software itself - it does not build or start, or does what the
951
- spec says it must not - is not the tests' to work around. When it fails, a judge - an agent that reads
952
- the code and the tests, changes neither, and holds both to the spec - decides which is wrong. It has the
953
- file tools and the web (`web_search`, `web_fetch`), to look up what a service the code calls answers - no shell: it
954
- judges from the code, the tests, the spec, the conformance testing script word for word and the failing run's output,
955
- and its file tools write nothing. The explorer's account of how the code is invoked is in its prompt too, marked as
956
- written before the run and possibly wrong: the judge checks what it uses of it against the script and the files, and
957
- gives in `evidence` what it found itself. The script is fixed - neither agent can change it - so it is never the
958
- culprit: what it does with the tests, the tests fit; what it needs of the build, the code provides.
959
-
960
- - **the code:** the coding agent - in the code's folder, reading the tests but never changing them - fixes it,
961
- and keeps its unit tests passing. The judge quotes the spec's own words the code does not meet, or the testing
962
- script's for what it needs of the build (`script_needs`: a build output, an entry point, a module) - each checked
963
- by the harness against the text it quotes. The acceptance tests are in that text, labelled as their tests are:
964
- for a spec change, those of every functional spec it touches, not only the last one's;
357
+ The harness runs the project's conformance testing script on the whole suite. When it passes, the unit testing script runs too - and then, with `review: true` in the config, the review gate: a reviewer reads the tests this run added or changed, and the code, and checks that they test black box - through the entry points the test reqs allow, never mocking or replacing any part of the software under test - that every test asserts what the spec says, with no placeholder that cannot fail, and that each acceptance test does every step it lists and asserts every expectation it states. It must pass, as the suite and the unit tests must: when it does not, the conformance agent gets exactly what is missing and what is bad, file by file, and the round goes again. One reviewer does every review of the run, as the unit tests' does: the first time it is shown the diff of the tests folder from the module's last commit, each time after the diff since its last review, and every time the conformance agent's account through `submit_work` - checked against the diff, never taken instead of it. The first review is asked for every problem at once; each after it is given what the last one found, checks that first, and raises something new only when it is serious - a test that cannot fail, mocks the software, or leaves out what the spec asks for. It asks only for what can be seen from outside: where the spec says one part calls another, the outcome, never the call. The reviewer is the exacting developer, as the unit tests' is, and marks each problem blocking or not: blocking when the functionality is not yet tested black box - a test or an acceptance test missing, cut down or skipping what it checks, the software mocked or not reached from outside, a test that cannot fail.
358
+
359
+ The tests are reviewed twice at most, as the unit tests are: the first review that sends them back goes to the conformance agent as it is, and the second the arbiter weighs first, as it does the unit tests' (see [the code and its unit tests are reviewed](#the-code-and-its-unit-tests-are-reviewed)): it upholds what leaves the functionality not tested black box, and dismisses what is out of scope or a nitpick. Only what it upholds goes back to the conformance agent; when it upholds nothing, the tests are approved as they are, and what it let go is kept in the result and the notes' pitfalls. The review optimises the tests, it does not stop the run: what the second review sends back is worked on once, and then the tests go on without another review - once the suite and the unit tests pass, which they still must. All three passing is done.
360
+
361
+ A spec diff's conformance run holds its tests to the same bar. The functionalities the change touches - a line of their functional spec, or of one of their acceptance tests, added or removed - are worked out from the diff. The conformance agent is shown their acceptance tests, numbered as they are labelled; the run does not finish until each one is a labelled test of its own; and the review checks each of them as it would a functionality's own.
362
+
363
+ A failing run's output goes to the judge and whoever fixes it whole when it is up to 60,000 characters, and otherwise its last 60,000 - where a test run says what failed and why - with the file the whole of it is kept in.
364
+
365
+ Why something failed is never lost. Every agent that writes or fixes code is told that where the code catches an error and turns it into a response, a status, a result or a retry, it logs the error with its whole trace, and what it hands on names the cause - never a bare "failed". When the output does not show why the software failed, the judge says the code is what is wrong, for hiding it, and the coding agent makes the cause show first, then fixes it. No agent may make the code behave differently when a test runs it. Both the conformance agent and the coding agent can run the conformance suite themselves, to reproduce a failure and check their fix - three times a turn: the third ends the turn, and the harness runs it and judges. The conformance agent is told that a failure of the software itself - it does not build or start, or does what the spec says it must not - is not the tests' to work around. When it fails, a judge - an agent that reads the code and the tests, changes neither, and holds both to the spec - decides which is wrong. It has the file tools and the web (`web_search`, `web_fetch`), to look up what a service the code calls answers - no shell: it judges from the code, the tests, the spec, the conformance testing script word for word and the failing run's output, and its file tools write nothing. The explorer's account of how the code is invoked is in its prompt too, marked as written before the run and possibly wrong: the judge checks what it uses of it against the script and the files, and gives in `evidence` what it found itself. The script is fixed - neither agent can change it - so it is never the culprit: what it does with the tests, the tests fit; what it needs of the build, the code provides.
366
+
367
+ - **the code:** the coding agent - in the code's folder, reading the tests but never changing them - fixes it, and keeps its unit tests passing. The judge quotes the spec's own words the code does not meet, or the testing script's for what it needs of the build (`script_needs`: a build output, an entry point, a module) - each checked by the harness against the text it quotes. The acceptance tests are in that text, labelled as their tests are: for a spec change, those of every functional spec it touches, not only the last one's;
965
368
  - **the tests:** the conformance agent corrects them to what the spec says;
966
369
  - **the spec:** two functional specs cannot both hold, whatever the code does;
967
- - **the environment:** neither the code nor the tests can fix it - only the person can, in what the run is given:
968
- a credential missing, empty or rejected (a 401 from a provider for a token no test made up), an account or quota
969
- a service refuses, a service the spec names that cannot be reached. What a test sets up itself - a credential, a
970
- variable, a fixture - is the tests'.
971
-
972
- The environment is judged what is wrong twice in a row before it counts. The first time, the conformance agent
973
- checks that the tests do not cause it themselves and, when they do not, changes nothing; the second, the run
974
- stops, and the person is told what to provide and where the run read it from - the testing scripts run in their own
975
- environment, so a credential comes from their shell's variables or a `.env` the script loads.
976
-
977
- When the code and the tests could both be wrong, the judge is told to choose the tests. A spec
978
- conflict has to name the two functionalities, each by its module and id - they can be in different
979
- modules, since a module's codebase and its conformance suite hold the functionalities of the modules
980
- it requires too (functionality 1 of `accounts` and functionality 4 of `cognio`). In a functionality's
981
- conformance run one of them must be the functionality under test - a conflict between two earlier ones would have
982
- come up when the later of them was tested (a spec diff's run may name any two). One that breaks
983
- these rules is sent back to the judge. A valid one is recorded, and the tests go back to the
984
- conformance agent, so the next judgement is of a new run. It counts only once the same two
985
- functionalities have been named three times. Then the run stops, and the person gets the conflict
986
- whole: both functional specs as they read, and each time what could not hold. The conversation's
987
- agent runs `analyze-2-func-specs` on the pair, then `resolve-spec-conflict` for the ways out, and
988
- puts the decision to the person - it changes nothing in the spec before they have decided.
989
-
990
- The judge holds only what the spec says against the code: anything it leaves open - a name,
991
- coordinates, a version, a path, a package - is what the code already has, and the tests follow it.
992
- The coding agents keep the build's identity - name, coordinates, version, package, main class - as it
993
- is unless the spec asks for another. And the conformance agent is given the code's build files
994
- (`pom.xml`, `package.json`, `pyproject.toml`, `go.mod`...) word for word, read by the harness: the one
995
- place to take what its tests' build points at from, never a guess from a folder name.
996
-
997
- When nothing changes - the same failure seen three times in the run, in a row or not, so a run
998
- swinging between two failures counts too (runs that hang until the time limit count as well) - the
999
- explorer is asked again, shown its last account and the failure,
1000
- for what the tests lack; most often it is how they reach the software. Its new account goes to the
1001
- conformance agent. If the same happens three rounds more, the run stops and says so, instead of
1002
- spending the rest of its 20 attempts on it. Two failures are the same once what changes from run to run is
1003
- taken out of their lines - numbers, times, paths, colour codes, and the ids a service makes up for each
1004
- response, a UUID or a correlation id. Nothing changes either when the agent sent to fix the code or the tests
1005
- changes no file: two such fixes in a row, and the run stops. The conformance agent has the testing script in its prompt,
1006
- and is told to fit the tests' own build to it. The code fixer has the testing scripts its fixes are run by - the
1007
- conformance testing script, the prepare script before it, and the unit testing script - word for word in its task:
1008
- what the conformance testing script needs of the build, it reads there, not only in the judge's quote of it.
1009
-
1010
- **Escalation.** A failure judged the tests' goes to the conformance agent first: it owns the tests. When the run then
1011
- fails the same way - the fix changed nothing, or nothing that mattered - the judge is asked again, now whether the
1012
- failure belongs to the code rather than the tests: the run failing on something the code is meant to produce (a build
1013
- output, an entry point, a module the testing script needs), or the tests running and the behaviour itself being
1014
- wrong. Its verdict, either way, has to rest on evidence it gathered: each piece from a file it opened (the harness
1015
- keeps track of what it read, listed and searched), the testing script or the failing run - and not the run alone.
1016
- A verdict without it is sent back; a verdict of code still without it is taken as the tests'. Judged the tests'
1017
- again, the failure stays with the conformance agent, and a fix that changes nothing counts towards stopping as
1018
- before. Judged the code's, it is escalated to the coding agent, handed the script's error, the conformance tests as
1019
- they stand and the judge's reason and evidence (`the script runs dist/cli.js; the build emits dist/src/cli.js`). Its
1020
- fix has to build and pass the unit tests, then the suite runs again. Should the run still fail the same way - or the
1021
- fix change nothing - the run stops there, with the judge's reasoning and evidence in what the person is told. Each of
1022
- these runs is one of the run's 20 attempts, so a failure neither agent can fix stops in three of them.
1023
-
1024
- Every attempt is written into the working notes' pitfalls by the harness as cause and effect - what
1025
- the run failed with, how it was judged, and which files the agent sent to fix it changed; the next
1026
- attempt's line says what came of it - and each judge reads them first, so it does not send a
1027
- failure the way that already failed. A run that does not pass is undone whole, its notes with it.
1028
-
1029
- Then the suite runs again. A run that exits 80 goes back to the conformance agent without a judge - the tests pass and
1030
- only their static checks do not (see [the static checks](#the-static-checks)): the findings are the tests'.
1031
-
1032
- **Timing.** Every run is shown to the judge, the debugger and whoever fixes it with how long it ran against its time
1033
- limit (`runTiming` in `test-scripts.ts`): `This run ended on its own - exit 1, after 37.2s of the 120.0s a test run
1034
- may take`, or `The time limit stopped this run: it had run 120.0s of the 120.0s ...` - so none takes a run that
1035
- ended on its own for one the limit stopped, or the other way. A run the time limit stopped is judged like any other,
1036
- and the judge is told what keeps a run from finishing: the code hangs (it waits on input, keeps a server in the
1037
- foreground, never exits) - the code's; a test waits for what never comes - the tests'; or nothing hangs, the output
1038
- showing the run getting on up to the limit, and it needs more time than a test run may take - the environment. That
1039
- verdict stops the pulse at once, rolled back and not retried, and the person is told to raise `TURRI_COMMAND_TIMEOUT`
1040
- or make the suite faster - no agent can give a run more time. A run whose script cannot find its
1041
- toolchain stops the pulse instead - see [when the environment lacks something](#when-the-environment-lacks-something).
1042
- Unit tests failing after the suite passes go to the coding agent. It goes round up to 20 times; still failing, the work is undone.
1043
-
1044
- Before each run the harness checks for itself: both kinds of test are there and labelled, none of
1045
- them is in the code folder, and no test went missing without being justified.
1046
-
1047
- Conformance and acceptance tests live in the module's `tests` folder and nowhere else. One found in
1048
- the code folder - by its label, or as a test file under a name or folder that says conformance or
1049
- acceptance - is sent back: to the agent writing the tests, to move it; to an agent writing the code,
1050
- to remove it, since those tests are not its to write. The conformance testing script refuses them too
1051
- (see `implement-conformance-testing-script`), so a suite in the wrong place fails rather than
1052
- passing unnoticed.
1053
-
1054
- No agent runs the testing scripts itself. They are in its prompt so it knows what judges its work,
1055
- but they are not in its workspace: it calls `run_unit_tests` and `run_conformance_tests`, which run
1056
- them as the harness does. Its file tools refuse to write a copy of them, or a `.plain` spec, into the
1057
- codebase, and its working notes refuse a line telling the next agent to run them.
370
+ - **the environment:** neither the code nor the tests can fix it - only the person can, in what the run is given: a credential missing, empty or rejected (a 401 from a provider for a token no test made up), an account or quota a service refuses, a service the spec names that cannot be reached. What a test sets up itself - a credential, a variable, a fixture - is the tests'.
371
+
372
+ The environment is judged what is wrong twice in a row before it counts. The first time, the conformance agent checks that the tests do not cause it themselves and, when they do not, changes nothing; the second, the run stops, and the person is told what to provide and where the run read it from - the testing scripts run in their own environment, so a credential comes from their shell's variables or a `.env` the script loads.
373
+
374
+ When the code and the tests could both be wrong, the judge is told to choose the tests. A spec conflict has to name the two functionalities, each by its module and id - they can be in different modules, since a module's codebase and its conformance suite hold the functionalities of the modules it requires too (functionality 1 of `accounts` and functionality 4 of `cognio`). In a functionality's conformance run one of them must be the functionality under test - a conflict between two earlier ones would have come up when the later of them was tested (a spec diff's run may name any two). One that breaks these rules is sent back to the judge. A valid one is recorded, and the tests go back to the conformance agent, so the next judgement is of a new run. It counts only once the same two functionalities have been named three times. Then the run stops, and the person gets the conflict whole: both functional specs as they read, and each time what could not hold. The conversation's agent runs `analyze-2-func-specs` on the pair, then `resolve-spec-conflict` for the ways out, and puts the decision to the person - it changes nothing in the spec before they have decided.
375
+
376
+ The judge holds only what the spec says against the code: anything it leaves open - a name, coordinates, a version, a path, a package - is what the code already has, and the tests follow it. The coding agents keep the build's identity - name, coordinates, version, package, main class - as it is unless the spec asks for another. And the conformance agent is given the code's build files (`pom.xml`, `package.json`, `pyproject.toml`, `go.mod`...) word for word, read by the harness: the one place to take what its tests' build points at from, never a guess from a folder name.
377
+
378
+ When nothing changes - the same failure seen three times in the run, in a row or not, so a run swinging between two failures counts too (runs that hang until the time limit count as well) - the explorer is asked again, shown its last account and the failure, for what the tests lack; most often it is how they reach the software. Its new account goes to the conformance agent. If the same happens three rounds more, the run stops and says so, instead of spending the rest of its 20 attempts on it. Two failures are the same once what changes from run to run is taken out of their lines - numbers, times, paths, colour codes, and the ids a service makes up for each response, a UUID or a correlation id. Nothing changes either when the agent sent to fix the code or the tests changes no file: two such fixes in a row, and the run stops. The conformance agent has the testing script in its prompt, and is told to fit the tests' own build to it. The code fixer has the testing scripts its fixes are run by - the conformance testing script, the prepare script before it, and the unit testing script - word for word in its task: what the conformance testing script needs of the build, it reads there, not only in the judge's quote of it.
379
+
380
+ **Escalation.** A failure judged the tests' goes to the conformance agent first: it owns the tests. When the run then fails the same way - the fix changed nothing, or nothing that mattered - the judge is asked again, now whether the failure belongs to the code rather than the tests: the run failing on something the code is meant to produce (a build output, an entry point, a module the testing script needs), or the tests running and the behaviour itself being wrong. Its verdict, either way, has to rest on evidence it gathered: each piece from a file it opened (the harness keeps track of what it read, listed and searched), the testing script or the failing run - and not the run alone. A verdict without it is sent back; a verdict of code still without it is taken as the tests'. Judged the tests' again, the failure stays with the conformance agent, and a fix that changes nothing counts towards stopping as before. Judged the code's, it is escalated to the coding agent, handed the script's error, the conformance tests as they stand and the judge's reason and evidence (`the script runs dist/cli.js; the build emits dist/src/cli.js`). Its fix has to build and pass the unit tests, then the suite runs again. Should the run still fail the same way - or the fix change nothing - the run stops there, with the judge's reasoning and evidence in what the person is told. Each of these runs is one of the run's 20 attempts, so a failure neither agent can fix stops in three of them.
381
+
382
+ Every attempt is written into the working notes' pitfalls by the harness as cause and effect - what the run failed with, how it was judged, and which files the agent sent to fix it changed; the next attempt's line says what came of it - and each judge reads them first, so it does not send a failure the way that already failed. A run that does not pass is undone whole, its notes with it.
383
+
384
+ Then the suite runs again. A run that exits 80 goes back to the conformance agent without a judge - the tests pass and only their static checks do not (see [the static checks](#the-static-checks)): the findings are the tests'.
385
+
386
+ **Timing.** Every run is shown to the judge, the debugger and whoever fixes it with how long it ran against its time limit (`runTiming` in `test-scripts.ts`): `This run ended on its own - exit 1, after 37.2s of the 120.0s a test run may take`, or `The time limit stopped this run: it had run 120.0s of the 120.0s ...` - so none takes a run that ended on its own for one the limit stopped, or the other way. A run the time limit stopped is judged like any other, and the judge is told what keeps a run from finishing: the code hangs (it waits on input, keeps a server in the foreground, never exits) - the code's; a test waits for what never comes - the tests'; or nothing hangs, the output showing the run getting on up to the limit, and it needs more time than a test run may take - the environment. That verdict stops the pulse at once, rolled back and not retried, and the person is told to raise `TURRI_COMMAND_TIMEOUT` or make the suite faster - no agent can give a run more time. A run whose script cannot find its toolchain stops the pulse instead - see [when the environment lacks something](#when-the-environment-lacks-something). Unit tests failing after the suite passes go to the coding agent. It goes round up to 20 times; still failing, the work is undone.
387
+
388
+ Before each run the harness checks for itself: both kinds of test are there and labelled, none of them is in the code folder, and no test went missing without being justified.
389
+
390
+ Conformance and acceptance tests live in the module's `tests` folder and nowhere else. One found in the code folder - by its label, or as a test file under a name or folder that says conformance or acceptance - is sent back: to the agent writing the tests, to move it; to an agent writing the code, to remove it, since those tests are not its to write. The conformance testing script refuses them too (see `implement-conformance-testing-script`), so a suite in the wrong place fails rather than passing unnoticed.
391
+
392
+ No agent runs the testing scripts itself. They are in its prompt so it knows what judges its work, but they are not in its workspace: it calls `run_unit_tests` and `run_conformance_tests`, which run them as the harness does. Its file tools refuse to write a copy of them, or a `.plain` spec, into the codebase, and its working notes refuse a line telling the next agent to run them.
1058
393
 
1059
394
  ### Verified
1060
395
 
1061
- After rendering a hello-world Python spec's functionality 1, the conformance test runs
1062
- the app as a subprocess and asserts on stdout, exit code and time - no import of internals:
396
+ After rendering a hello-world Python spec's functionality 1, the conformance test runs the app as a subprocess and asserts on stdout, exit code and time - no import of internals:
1063
397
 
1064
398
  ```python
1065
399
  completed = subprocess.run([sys.executable, str(executable)], capture_output=True, text=True, timeout=1)
@@ -1067,45 +401,21 @@ self.assertEqual(completed.returncode, 0, msg=completed.stderr)
1067
401
  self.assertEqual(completed.stdout.strip(), "hello, world")
1068
402
  ```
1069
403
 
1070
- Code that prints `goodbye` instead fails the test; the agent fixes the code, and the harness's own
1071
- runs - the suite, then the unit tests - pass (`tests/regenerate/conformance-loop.test.ts`).
404
+ Code that prints `goodbye` instead fails the test; the agent fixes the code, and the harness's own runs - the suite, then the unit tests - pass (`tests/regenerate/conformance-loop.test.ts`).
1072
405
 
1073
406
  ## Agent sessions
1074
407
 
1075
- An agent's task - the spec, how to read it, what to do, the rules, the working notes as they were - is
1076
- its **system prompt**, not its first message: every agent turri starts opens with a one-line
1077
- "begin". Compaction sums up the conversation and never the system prompt, so however long an agent
1078
- works, what it works from stays word for word as it was, and stays in the cached prefix of every call.
1079
- The one exception is a skill's executor, which is given a step at a time.
1080
-
1081
- The agents that work through a job keep **one session for it**: the coding agent of a render or a spec
1082
- change, its unit test reviewer, the conformance agent, its test reviewer, the code fixer of a
1083
- conformance run, and the regression repair agent. The code fixer used to start fresh for every fix; now
1084
- each fix starts from what the ones before it tried. The agents whose value is having taken no side stay
1085
- fresh, given what they need as text: the arbiter, the judge that says whether the code, the tests or the
1086
- spec is wrong, the explorer, the planners, the diagnosis and a skill's review judges. A job that fails
1087
- and is retried is undone whole, and every agent of the retry starts fresh.
1088
-
1089
- An agent kept through a job re-reads everything it has done on every call. So between turns, once its
1090
- conversation - what it has done, past its instructions - passes `compact-at` tokens (100,000 unless
1091
- [the project config](config.md) says otherwise), the harness compacts it, with instructions for its role:
1092
- the coding agent and the fixer keep what is done, what still fails and why, the decisions and every
1093
- review problem's fate; a reviewer keeps every problem it raised and where each stands, and what it has
1094
- already checked. pi's own compaction, when the context window is nearly full, stays on beneath it.
1095
-
1096
- What each agent of a job did - its turns, its compactions, its tokens and cost - is at the end of the
1097
- job's log in `.turri/jobs/`, and in `pulses`.
408
+ An agent's task - the spec, how to read it, what to do, the rules, the working notes as they were - is its **system prompt**, not its first message: every agent turri starts opens with a one-line "begin". Compaction sums up the conversation and never the system prompt, so however long an agent works, what it works from stays word for word as it was, and stays in the cached prefix of every call. The one exception is a skill's executor, which is given a step at a time.
409
+
410
+ The agents that work through a job keep **one session for it**: the coding agent of a render or a spec change, its unit test reviewer, the conformance agent, its test reviewer, the code fixer of a conformance run, and the regression repair agent. The code fixer used to start fresh for every fix; now each fix starts from what the ones before it tried. The agents whose value is having taken no side stay fresh, given what they need as text: the arbiter, the judge that says whether the code, the tests or the spec is wrong, the explorer, the planners, the diagnosis and a skill's review judges. A job that fails and is retried is undone whole, and every agent of the retry starts fresh.
411
+
412
+ An agent kept through a job re-reads everything it has done on every call. So between turns, once its conversation - what it has done, past its instructions - passes `compact-at` tokens (100,000 unless [the project config](config.md) says otherwise), the harness compacts it, with instructions for its role: the coding agent and the fixer keep what is done, what still fails and why, the decisions and every review problem's fate; a reviewer keeps every problem it raised and where each stands, and what it has already checked. pi's own compaction, when the context window is nearly full, stays on beneath it.
413
+
414
+ What each agent of a job did - its turns, its compactions, its tokens and cost - is at the end of the job's log in `.turri/jobs/`, and in `pulses`.
1098
415
 
1099
416
  ## Working notes
1100
417
 
1101
- Every job's agents start fresh, and without help each one would spend its first turns finding its
1102
- bearings. So each agent working on a codebase - render, spec change, conformance, regression repair -
1103
- starts with the notes the agents before it left, and before it finishes it updates them: a line
1104
- added, changed or removed, never the whole thing rewritten. There are two sets: the code's, in `code/`, for the
1105
- agents that change the code, and the conformance tests', in `tests/`, for the conformance agent. What one learns of
1106
- testing the module black box - where the tests are, what they assume - would steer a coding agent towards the tests
1107
- rather than the spec, so it is never in the code's notes; the judge, which weighs the tests against the code, reads
1108
- both. Each set goes where its folder goes - copied up the chain, committed, rolled back. Six sections:
418
+ Every job's agents start fresh, and without help each one would spend its first turns finding its bearings. So each agent working on a codebase - render, spec change, conformance, regression repair - starts with the notes the agents before it left, and before it finishes it updates them: a line added, changed or removed, never the whole thing rewritten. There are two sets: the code's, in `code/`, for the agents that change the code, and the conformance tests', in `tests/`, for the conformance agent. What one learns of testing the module black box - where the tests are, what they assume - would steer a coding agent towards the tests rather than the spec, so it is never in the code's notes; the judge, which weighs the tests against the code, reads both. Each set goes where its folder goes - copied up the chain, committed, rolled back. Six sections:
1109
419
 
1110
420
  | | |
1111
421
  | --- | --- |
@@ -1115,33 +425,18 @@ both. Each set goes where its folder goes - copied up the chain, committed, roll
1115
425
  | Pitfalls | what went wrong and what fixed it - and what the debugger found, filed by turri itself |
1116
426
  | Pulses | written by turri alone, as each pulse ends: the last ten, a line each |
1117
427
 
1118
- A pulse's line says what it regenerated, whether it landed, how it went - the rounds of the unit tests, the test runs, what
1119
- the debugger found - how long it took, what it cost, and where its log is, for the whole of what its agents did:
428
+ A pulse's line says what it regenerated, whether it landed, how it went - the rounds of the unit tests, the test runs, what the debugger found - how long it took, what it cost, and where its log is, for the whole of what its agents did:
1120
429
 
1121
430
  ```
1122
431
  - [2026-10-08 11:19 · hubspot pulse 2] HubSpot contact reading and mapping - landed; 4 rounds of the unit tests,
1123
432
  92 test runs; the debugger: the stand-in replaces a method, so it is given self · 7m 52s · $1.35 · log .turri/jobs/….log
1124
433
  ```
1125
434
 
1126
- It is written once anything the pulse did not land is rolled back, and committed - into the pulse's own commit when
1127
- it landed, a commit of its own (`pulse 3 rolled back: …`) when it did not - so the next pulse, starting from the last
1128
- commit, keeps it. `update_notes` refuses the section. What the debugger finds is filed in the pitfalls the moment it
1129
- finds it, not left to the coding agent to write down.
1130
-
1131
- A spec gap - what the spec should say and does not, a behaviour you would want to decide - is not a note: the notes
1132
- are the next agent's, and a gap is yours. An agent reports one with `report_spec_gap`, giving the question it leaves
1133
- and the assumption it made meanwhile; turri writes that assumption into the notes' assumptions, so the code built on
1134
- it is known for what it is. The gaps a pulse's agents report are said in its report - "Spec gaps its agents met ... Put
1135
- each to the user", each with its assumption - so the conversation asks you, and writes the ones you decide into the
1136
- spec; the pulse that builds the answer finds the assumption it replaces in the notes, and the tests it names.
1137
- A headless run has no one to ask: it prints each gap under its pulse, and lists them in its run report's
1138
- `spec_gaps` ([running unattended](headless.md#the-run-report)). However many gaps a pulse's agents report, they
1139
- are put to you - never a reason to stop the pulse; the tool is guarded like any other. A notes
1140
- file from before keeps no spec gaps section: its lines are dropped as it is read.
1141
-
1142
- Stubborn on the specs, flexible on the assumptions: the spec is never an assumption and never
1143
- copied into the notes, and where the two disagree the spec wins. An agent builds on the assumptions
1144
- already there, and changes one the moment the code or the spec shows it wrong.
435
+ It is written once anything the pulse did not land is rolled back, and committed - into the pulse's own commit when it landed, a commit of its own (`pulse 3 rolled back: …`) when it did not - so the next pulse, starting from the last commit, keeps it. `update_notes` refuses the section. What the debugger finds is filed in the pitfalls the moment it finds it, not left to the coding agent to write down.
436
+
437
+ A spec gap - what the spec should say and does not, a behaviour you would want to decide - is not a note: the notes are the next agent's, and a gap is yours. An agent reports one with `report_spec_gap`, giving the question it leaves and the assumption it made meanwhile; turri writes that assumption into the notes' assumptions, so the code built on it is known for what it is. The gaps a pulse's agents report are said in its report - "Spec gaps its agents met ... Put each to the user", each with its assumption - so the conversation asks you, and writes the ones you decide into the spec; the pulse that builds the answer finds the assumption it replaces in the notes, and the tests it names. A headless run has no one to ask: it prints each gap under its pulse, and lists them in its run report's `spec_gaps` ([running unattended](headless.md#the-run-report)). However many gaps a pulse's agents report, they are put to you - never a reason to stop the pulse; the tool is guarded like any other. A notes file from before keeps no spec gaps section: its lines are dropped as it is read.
438
+
439
+ Stubborn on the specs, flexible on the assumptions: the spec is never an assumption and never copied into the notes, and where the two disagree the spec wins. An agent builds on the assumptions already there, and changes one the moment the code or the spec shows it wrong.
1145
440
 
1146
441
  Every line says when and where it came from, stamped by the harness rather than written by the agent:
1147
442
 
@@ -1152,23 +447,11 @@ Every line says when and where it came from, stamped by the harness rather than
1152
447
  - [2026-09-24 16:52 · auth 1] Token responses carry `access_token` and `expires_in`
1153
448
  ```
1154
449
 
1155
- A line that is changed is stamped again, so an assumption one agent revised shows as newer than the
1156
- ones around it. Where two lines disagree, the later one is right. A line that says nothing - "none",
1157
- "N/A", "no new assumptions" - is refused: a section with nothing new is left alone.
450
+ A line that is changed is stamped again, so an assumption one agent revised shows as newer than the ones around it. Where two lines disagree, the later one is right. A line that says nothing - "none", "N/A", "no new assumptions" - is refused: a section with nothing new is left alone.
1158
451
 
1159
- Leaving notes is required, and only through the `update_notes` tool. The file tools refuse the
1160
- notes file, and a change made to it any other way - from the shell, by a script - is undone. An agent
1161
- that finishes without calling `update_notes` is asked again, up to three times; if it still has not,
1162
- the activity log says so. The turn that asks is for the notes alone: the work is done - its testing script's run
1163
- passed, and the agent is told so first, so its notes speak of work that succeeded - so every tool but `update_notes` and
1164
- `report_spec_gap` is refused, and an agent that keeps calling the refused ones has its turn stopped. What
1165
- landed is what the harness checked; nothing changes after it. Only work that lands is asked: a job whose code or tests do not pass - or whose
1166
- testing script cannot run - is rolled back, notes and all, so its agent is not asked to leave any.
452
+ Leaving notes is required, and only through the `update_notes` tool. The file tools refuse the notes file, and a change made to it any other way - from the shell, by a script - is undone. An agent that finishes without calling `update_notes` is asked again, up to three times; if it still has not, the activity log says so. The turn that asks is for the notes alone: the work is done - its testing script's run passed, and the agent is told so first, so its notes speak of work that succeeded - so every tool but `update_notes` and `report_spec_gap` is refused, and an agent that keeps calling the refused ones has its turn stopped. What landed is what the harness checked; nothing changes after it. Only work that lands is asked: a job whose code or tests do not pass - or whose testing script cannot run - is rolled back, notes and all, so its agent is not asked to leave any.
1167
453
 
1168
- The notes are disposable - delete the file and nothing breaks; the next agent just explores a little
1169
- more. They live in the code folder, so they are committed with it, reset with it after an
1170
- interrupted run, and copied up with it to a module that requires this one. They are not part of the
1171
- codebase: they are left out of the code map, the file lists and what `deploy` puts in `dist/`.
454
+ The notes are disposable - delete the file and nothing breaks; the next agent just explores a little more. They live in the code folder, so they are committed with it, reset with it after an interrupted run, and copied up with it to a module that requires this one. They are not part of the codebase: they are left out of the code map, the file lists and what `deploy` puts in `dist/`.
1172
455
 
1173
456
  ## What the code is built from
1174
457
 
@@ -1179,33 +462,17 @@ Two records per module, each committed with what it describes in the module's `.
1179
462
  | `code/.turri.json` | the code record: the spec the code is built from - its whole requires chain's: the definitions and implementation reqs of the modules below, each tagged with its module, their functional specs among the ones it inherits, and its own - without the test reqs and the acceptance tests, which are for conformance only |
1180
463
  | `tests/.turri.json` | the tests record: the functional specs the conformance tests are written for - of the code record's, with their acceptance tests - the definitions and implementation reqs they were written against, and the test reqs they follow |
1181
464
 
1182
- Nothing about how a build went: whether tests passed and which files a job touched are in the
1183
- history. And nothing else is stored: what is left to build is worked out from the records whenever a
1184
- job ends or the spec changes - the code work from the code record to the spec now (`src/regenerate/drift.ts`),
1185
- the conformance work from the tests record to what the tests are to be written for. Only the running
1186
- job is kept; what the panel shows as planned is worked out again. The tests record never goes ahead of
1187
- the code's: a conformance test exercises functionality, and only what is in the code can be tested.
465
+ Nothing about how a build went: whether tests passed and which files a job touched are in the history. And nothing else is stored: what is left to build is worked out from the records whenever a job ends or the spec changes - the code work from the code record to the spec now (`src/regenerate/drift.ts`), the conformance work from the tests record to what the tests are to be written for. Only the running job is kept; what the panel shows as planned is worked out again. The tests record never goes ahead of the code's: a conformance test exercises functionality, and only what is in the code can be tested.
1188
466
 
1189
467
  What goes into them:
1190
468
 
1191
469
  - **A code job landed:** the code record becomes the spec the job ends on.
1192
470
  - **A conformance job landed:** the tests record becomes what its tests are written for.
1193
- - **A module started from another's code:** that code's record, as a lower module's - see
1194
- [where things go](#where-things-go) - and an empty tests record: the tests it inherits are the module
1195
- below's.
1196
- - **A functional spec named to `regenerate`:** it is marked to be regenerated again in the code record, so the next job regenerates it
1197
- again; that job's record drops the mark.
1198
-
1199
- A unit of work - a code job, a conformance job - lands whole or is undone whole. It starts from the
1200
- module's last commit, putting back whatever an interrupted run left; a module with no commit yet is
1201
- given one first. When it does not pass, the module goes back to that commit: its changes, the files it
1202
- added and any commit it made on the way are gone, with the record they came with. Installed
1203
- dependencies and caches stay. So the code, its tests and the records of what they were built from never
1204
- disagree.
1205
-
1206
- The record is the harness's alone. No agent writes it: the file tools refuse it, and what the
1207
- harness records next is built on the record as its last commit has it, not the file on disk - so a
1208
- change an agent's shell made to it is never carried on.
1209
-
1210
- A record written by an earlier version of turri is read as the tree it describes, up to the
1211
- first functionality that did not build; the next job writes it anew.
471
+ - **A module started from another's code:** that code's record, as a lower module's - see [where things go](#where-things-go) - and an empty tests record: the tests it inherits are the module below's.
472
+ - **A functional spec named to `regenerate`:** it is marked to be regenerated again in the code record, so the next job regenerates it again; that job's record drops the mark.
473
+
474
+ A unit of work - a code job, a conformance job - lands whole or is undone whole. It starts from the module's last commit, putting back whatever an interrupted run left; a module with no commit yet is given one first. When it does not pass, the module goes back to that commit: its changes, the files it added and any commit it made on the way are gone, with the record they came with. Installed dependencies and caches stay. So the code, its tests and the records of what they were built from never disagree.
475
+
476
+ The record is the harness's alone. No agent writes it: the file tools refuse it, and what the harness records next is built on the record as its last commit has it, not the file on disk - so a change an agent's shell made to it is never carried on.
477
+
478
+ A record written by an earlier version of turri is read as the tree it describes, up to the first functionality that did not build; the next job writes it anew.