@turri-dev/cli 0.1.3-next.f74e98a → 0.1.4-next.01530aa
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.
- package/README.md +22 -1
- package/dist/ask.js +34 -15
- package/dist/cli-options.js +12 -6
- package/dist/config-edit.js +1 -0
- package/dist/config.js +5 -2
- package/dist/extension.js +97 -42
- package/dist/genome.js +1 -1
- package/dist/init-config.js +5 -0
- package/dist/loop-cli.js +13 -1
- package/dist/loop-tools.js +31 -12
- package/dist/pi-launch.js +5 -0
- package/dist/pi.js +76 -19
- package/dist/question-dialog.js +9 -3
- package/dist/questioning.js +1 -1
- package/dist/regenerate/activity.js +23 -0
- package/dist/regenerate/conform.js +5 -5
- package/dist/regenerate/conformance-agents.js +28 -8
- package/dist/regenerate/conformance.js +24 -10
- package/dist/regenerate/list-arguments.js +121 -0
- package/dist/regenerate/loop.js +137 -18
- package/dist/regenerate/notes.js +66 -17
- package/dist/regenerate/prompt.js +3 -1
- package/dist/regenerate/regenerate.js +16 -10
- package/dist/regenerate/regression.js +2 -1
- package/dist/regenerate/requires.js +55 -2
- package/dist/regenerate/self-check.js +13 -6
- package/dist/regenerate/side-panel.js +1 -1
- package/dist/regenerate/test-scripts.js +54 -10
- package/dist/regenerate/unit-review.js +12 -1
- package/dist/regenerate-cli.js +11 -5
- package/dist/release-tools.js +1 -1
- package/dist/resume-line.js +4 -0
- package/dist/review/live.js +2 -1
- package/dist/run-report.js +39 -1
- package/dist/spec-tools.js +10 -45
- package/docs/authoring-plain.md +12 -7
- package/docs/config.md +3 -2
- package/docs/headless.md +33 -3
- package/docs/installation.md +3 -0
- package/docs/regenerating.md +70 -20
- package/docs/skills-and-gates.md +5 -3
- package/docs/using.md +28 -14
- package/genome/rules/func-specs.md +1 -0
- package/genome/rules/project-model.md +5 -3
- package/genome/rules/turri-regeneration.md +76 -0
- package/genome/skills/bud/SKILL.md +67 -36
- package/genome/skills/bud/references/intent.md +4 -0
- package/genome/skills/refactor-module/SKILL.md +24 -2
- package/package.json +3 -3
- package/genome/skills/bud/references/checklist.md +0 -44
package/docs/using.md
CHANGED
|
@@ -50,7 +50,7 @@ where it stopped. A project can have skills of its own, in `.turri/skills/` or `
|
|
|
50
50
|
|
|
51
51
|
| tool | |
|
|
52
52
|
| --- | --- |
|
|
53
|
-
| `regenerate` | regenerate a module and its chain from the spec as it is now - after any change to it, by any means: what is left to regenerate is planned into pulses of one to three functional specs, each with the definitions and reqs it uses, and a pulse regenerating what the spec no longer wants is stopped. With functionalities named, those are regenerated though their spec did not change - rewritten or started over, planned into pulses as any change is; with `from_scratch`, the whole module, its code deleted first - only when you ask, or agree |
|
|
53
|
+
| `regenerate` | regenerate a module and its chain from the spec as it is now - after any change to it, by any means: what is left to regenerate is planned into pulses of one to three functional specs, each with the definitions and reqs it uses, and a pulse regenerating what the spec no longer wants is stopped. With functionalities named, those are regenerated though their spec did not change - rewritten or started over, planned into pulses as any change is; with `from_scratch`, the whole module, its code deleted first - `"chain"` for every module of its requires chain too, built again from the bottom - only when you ask, or agree |
|
|
54
54
|
| `drift` | what is left to regenerate: how far the code and its conformance tests have drifted from the spec, starting nothing |
|
|
55
55
|
| `glimpse` | the pulse a module's codebases would start next, and the whole prompt its coding agent would get - starting nothing |
|
|
56
56
|
| `steer` | say how the work is planned - which functional specs go together, what first - for the project or one module, for the session; the next plan follows it, beside what AGENTS.md says under a heading naming the queue |
|
|
@@ -58,12 +58,12 @@ where it stopped. A project can have skills of its own, in `.turri/skills/` or `
|
|
|
58
58
|
| `validate` | validate a spec, regenerating nothing |
|
|
59
59
|
| `engine` | show or choose the model the code is regenerated on - see [below](#choosing-a-model) |
|
|
60
60
|
| `pulses` | the pulses - running, planned and finished - or one of them |
|
|
61
|
-
| `halt` | halt a pulse, or what `activate` started |
|
|
61
|
+
| `halt` | halt a pulse, a module's planned pulses, or what `activate` started |
|
|
62
62
|
| `diagnose` | why a pulse did not land, from its transcript: how it ended, the stages that went wrong, the last failing test run, the last review, the tool calls that failed |
|
|
63
63
|
| `lineage` | a module's lineage: what each regeneration and conformance run changed in it, and what it was regenerated from |
|
|
64
64
|
| `cultivate` | run a gated skill, its steps and review gates enforced |
|
|
65
65
|
| `release`, `activate` | try what is regenerated: release it to `dist/<module>` and activate it on this machine, installing what it needs - see [deploy](deploy.md) |
|
|
66
|
-
| `ask_user` | put a question to you as a dialog to pick from - several at once, "Something else…" to type, or "Chat about this" to talk it over first; Esc in either goes back to the options |
|
|
66
|
+
| `ask_user` | put a question to you as a dialog to pick from - several at once, each a box you tick and untick, "Something else…" to type, or "Chat about this" to talk it over first; Esc in either goes back to the options |
|
|
67
67
|
| `web_search`, `web_fetch` | search the web and read a page as text - documentation, an API, an error; `curl` and the like run in its `bash` |
|
|
68
68
|
|
|
69
69
|
What each render does, in order, is in [regenerating the code](regenerating.md).
|
|
@@ -217,11 +217,10 @@ come waits for a free slot, and says so.
|
|
|
217
217
|
closes when it moves to another section. What is open is kept while the panel is closed. What the agents
|
|
218
218
|
said and did is not shown - it is in each pulse's log (see [Agent logs](#agent-logs)).
|
|
219
219
|
|
|
220
|
-
`ctrl+h` again, or `esc`, closes it and goes back to the chat. Beside the chat,
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
following the pulses; `ctrl+h` gives the panel the keys again, and from the panel closes it. (pi's regular screen,
|
|
220
|
+
`ctrl+h` again, or `esc`, closes it and goes back to the chat. Beside the chat, one side has the keys and the
|
|
221
|
+
other is drawn faint: `ctrl+h` switches sides - from the chat to the panel, from the panel to the chat, the panel
|
|
222
|
+
staying and following the pulses - `esc` gives the chat the keys too, and a click gives them to the side clicked.
|
|
223
|
+
`ctrl+c` closes the panel; so do `s`, over the whole screen, then `esc`. (pi's regular screen,
|
|
225
224
|
`--tui-mode regular`, reads no mouse: there it is the keys alone.)
|
|
226
225
|
While the panel has the keys, every key is the panel's,
|
|
227
226
|
whatever else happens: a question the chat model asks in the background (`ask_user`) waits in the chat,
|
|
@@ -238,7 +237,7 @@ come waits for a free slot, and says so.
|
|
|
238
237
|
is laid over `config.turri.yaml` - its testing scripts, toolchains, models - for the session; a pulse already
|
|
239
238
|
running keeps the stack it started with. The chat model switches it too when you ask. See
|
|
240
239
|
[stacks](config.md#stacks).
|
|
241
|
-
- **`/regenerate [module | file.plain] [functionality ...] [from scratch] [how to cut the work]`** regenerates a module from its spec as it is now, as
|
|
240
|
+
- **`/regenerate [module | file.plain] [functionality ...] [from scratch [whole chain]] [how to cut the work]`** regenerates a module from its spec as it is now, as
|
|
242
241
|
the `regenerate` tool does: what is left to regenerate is planned into pulses - one functional spec at a time, a few
|
|
243
242
|
together or the whole module in one, as the planner judges - and the first starts. Words after the module are
|
|
244
243
|
guidance for that plan (`/regenerate app models first`). A module's name typed with spaces for its underscores is
|
|
@@ -246,13 +245,19 @@ come waits for a free slot, and says so.
|
|
|
246
245
|
`config.turri.yaml` names, else the folder's top modules, to pick from. Asked for from scratch - `from scratch`,
|
|
247
246
|
`start over`, `delete the module` - it asks first, then deletes the module's code and conformance tests in every
|
|
248
247
|
codebase where they live, committed so `/lineage` keeps them, and regenerates the whole module from its spec,
|
|
249
|
-
built though nothing in it changed: `/regenerate shorty from scratch`. The
|
|
250
|
-
|
|
248
|
+
built though nothing in it changed: `/regenerate shorty from scratch`. The modules below it keep their code, and
|
|
249
|
+
the module starts again from a copy of the code below it. Asked for its chain too - `/regenerate shorty from scratch,
|
|
250
|
+
the whole chain` - the code of every module of its requires chain is deleted, the base's included, and the whole
|
|
251
|
+
chain is regenerated from the bottom: what to do after modules were split, merged or moved, when the code below was
|
|
252
|
+
laid out for modules that are no more. The chat's `regenerate` does the same with `from_scratch: "module"` or
|
|
253
|
+
`"chain"`, when you ask for it; `turri regenerate --from-scratch` or `--from-scratch-chain` on the command line, not
|
|
254
|
+
with `--dry-run`.
|
|
251
255
|
Functionalities named after the module - `/regenerate shorty 3 5` - are regenerated though their spec did not
|
|
252
256
|
change, on the model chosen for functionalities: as `turri regenerate shorty.plain 3 5` does, and the chat's
|
|
253
257
|
`regenerate` with `functionalities`.
|
|
254
|
-
- **`/halt <id>`** halts a pulse - a queued one never starts -
|
|
255
|
-
|
|
258
|
+
- **`/halt <id>`** halts a pulse - a queued one never starts - **`/halt <module>`** (or a planned row's id) halts a
|
|
259
|
+
module's planned pulses until you ask for it again, a spec change not starting it, and **`/halt activated <name>`**
|
|
260
|
+
halts a server `activate` started; it lists all three when no id is given.
|
|
256
261
|
- **What these commands show you, the chat knows.** What `/regenerate` and `/halt activated` tell you - a spec that
|
|
257
262
|
does not parse, the pulses planned, a server halted - stays in the chat under the command, and since a slash command
|
|
258
263
|
runs outside the conversation, it is put in the conversation as well: say "fix it" next and turri knows what you are
|
|
@@ -389,7 +394,15 @@ To change pi's own default, in `~/.pi/agent/settings.json`:
|
|
|
389
394
|
```
|
|
390
395
|
|
|
391
396
|
A provider failure - no credits, bad key, rate limit - is raised with the provider's own message,
|
|
392
|
-
rather than surfacing as an agent that said nothing.
|
|
397
|
+
rather than surfacing as an agent that said nothing. One that passes - overloaded, rate limited, unreachable,
|
|
398
|
+
timed out - is waited out first, after pi's own retries: six more tries, the wait doubled each time from 15
|
|
399
|
+
seconds up to five minutes (15s, 30s, 1m, 2m, 4m, 5m, a tenth either way so parallel jobs do not all come back
|
|
400
|
+
at once), the agent carrying on where it was. Each wait - pi's own retries too - is shown as it happens - a
|
|
401
|
+
notification in the chat and the job panel's status, a yellow line in a headless run - and listed in the run
|
|
402
|
+
report's `turn_incidents`. So is a provider stalling: a request to the model that nothing has come back on for two
|
|
403
|
+
minutes (`TURRI_PROVIDER_STALL`, in seconds; 0 never), said once for each silence while the turn goes on waiting.
|
|
404
|
+
A turn turri stops itself - its time up, the agent going round in a circle - is the work's normal course and is not
|
|
405
|
+
said, only listed.
|
|
393
406
|
|
|
394
407
|
## Module history
|
|
395
408
|
|
|
@@ -452,6 +465,7 @@ turri regenerate <file.plain> # regenerate what the code is not bui
|
|
|
452
465
|
turri glimpse <file.plain> # plan it, and print the first job's prompt - starts nothing
|
|
453
466
|
turri regenerate <file.plain> 2 # regenerate functionality 2 again, changed or not
|
|
454
467
|
turri regenerate <file.plain> --from-scratch # delete the module's code and tests (its lineage keeps them), regenerate all of it
|
|
468
|
+
turri regenerate <file.plain> --from-scratch-chain # the same for every module of its requires chain, from the bottom
|
|
455
469
|
turri spec-diff <file.plain> <diff> # apply a spec diff, and regenerate it
|
|
456
470
|
turri conform <file.plain> 1 # black-box tests for functionality 1
|
|
457
471
|
turri lineage <module> # what each regeneration changed in a module, and when
|
|
@@ -65,6 +65,7 @@ GOOD — statements of fact with concrete subjects:
|
|
|
65
65
|
- The renderer has **no knowledge of future specs** — only previously rendered specs are in context
|
|
66
66
|
- A new spec can reference behavior from earlier specs but cannot assume anything about specs that come after it
|
|
67
67
|
- Functional specs from `requires` modules are treated as previous requirements — transitively, across the whole ancestor chain
|
|
68
|
+
- This order is about what a spec may assume, not what a change costs: turri regenerates a change as a spec diff wherever it sits (`turri-regeneration.md`)
|
|
68
69
|
|
|
69
70
|
## No conflicts
|
|
70
71
|
- The new spec must not contradict any existing functional spec
|
|
@@ -75,9 +75,11 @@ Parameters are key-value pairs; the template reads them as `{{ variable_name }}`
|
|
|
75
75
|
|
|
76
76
|
## When an earlier test fails after a render
|
|
77
77
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
Each functional spec is written knowing the ones before it and none after it - a required module's
|
|
79
|
+
specs count as before - so a spec may rely on what earlier ones say, never on later ones. This is
|
|
80
|
+
about what a spec may assume, not what a change costs (`turri-regeneration.md`). After each
|
|
81
|
+
render every conformance test so far runs again. A test that passed before and fails now means one
|
|
82
|
+
of:
|
|
81
83
|
|
|
82
84
|
1. the new code does not satisfy its spec;
|
|
83
85
|
2. the test does not test its spec accurately;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: How turri regenerates the code from a spec change - by spec diff, in the chain's tip - what each kind of change sets off, what a coding agent sees, how bad code is fixed and where the cost really is, so a spec is placed and written by what it means, never by a guess at what regenerating it costs
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# How turri regenerates the code
|
|
6
|
+
|
|
7
|
+
The other rules say what a spec means. This one says what turri does with a change to it, so that
|
|
8
|
+
where a change goes, and how it is made, is never decided by a wrong idea of how turri works. Each
|
|
9
|
+
section ends in the same place: decide by what the spec means.
|
|
10
|
+
|
|
11
|
+
## A change is regenerated as a spec diff
|
|
12
|
+
|
|
13
|
+
- turri regenerates the code from spec diffs: what changed between the spec the code was built from
|
|
14
|
+
and the spec now
|
|
15
|
+
- A functional spec added, changed or taken out is that change alone, wherever it sits - first, in the
|
|
16
|
+
middle or last of its module
|
|
17
|
+
- The specs around it are not regenerated because their position or numbering moved, and nothing after
|
|
18
|
+
it is built again. A spec inserted in the middle is one addition
|
|
19
|
+
- "Specs render top to bottom, each knowing only the ones before it" is about what a spec may assume
|
|
20
|
+
(`func-specs.md`), not about what a change costs
|
|
21
|
+
|
|
22
|
+
## A change is regenerated in the chain's tip
|
|
23
|
+
|
|
24
|
+
- A chain's code lives in its tip - the furthest module built on it. The modules below it keep the
|
|
25
|
+
code they were built with
|
|
26
|
+
- A change to any module of the chain, the base's included, is regenerated in the tip's code - not in
|
|
27
|
+
the module the change was made in
|
|
28
|
+
- Putting a change in a lower module costs no more than putting it in the tip, and saves nothing
|
|
29
|
+
either
|
|
30
|
+
- Moving specs between modules of the chain renders nothing. Moving specs into a module the code was
|
|
31
|
+
never built on is the exception: no change to the code brings that module in, so the chain has to be
|
|
32
|
+
regenerated from scratch - never done without the person agreeing
|
|
33
|
+
|
|
34
|
+
## What each kind of change sets off
|
|
35
|
+
|
|
36
|
+
- A functional spec added is built, with its unit tests; one changed is patched in place; one taken
|
|
37
|
+
out has its code, and the tests only it had, removed
|
|
38
|
+
- A definition changed patches every functional spec that uses its concept, directly or through other
|
|
39
|
+
definitions. So does a change to a linked resource: the spec or definition linking it is changed
|
|
40
|
+
though its text is not. A widely used definition is the costly edit - not a spec's position
|
|
41
|
+
- Implementation reqs alone, or definitions no functional spec uses, are a mechanical change: the code
|
|
42
|
+
adapts, and no test is written or changes what it asserts
|
|
43
|
+
- Test reqs and acceptance tests reach the conformance tests only, never the code
|
|
44
|
+
- Definitions moved to a common module and reqs reordered are recorded, not rendered
|
|
45
|
+
|
|
46
|
+
## What a coding agent sees
|
|
47
|
+
|
|
48
|
+
- A coding agent sees its prompt and its module's code - nothing else. It cannot read `.plain` files,
|
|
49
|
+
this conversation, AGENTS.md or the person
|
|
50
|
+
- What the code needs to know has to be in the spec. A fact said only in the conversation, AGENTS.md or
|
|
51
|
+
notes never reaches the code, and is lost at the next regeneration
|
|
52
|
+
- Steering reaches the agents that plan the work - how it is cut and in what order - not what the code
|
|
53
|
+
does. What the code does is changed in the spec
|
|
54
|
+
|
|
55
|
+
## How bad code is fixed
|
|
56
|
+
|
|
57
|
+
- Never edit the code under `plain_modules/`: the next regeneration does not keep it, and the code
|
|
58
|
+
record no longer says what the code is
|
|
59
|
+
- In order of cost: change the spec where it is wrong or silent; regenerate the functional specs whose
|
|
60
|
+
code went bad again, by name; regenerate the module from scratch, or its whole chain - only when the
|
|
61
|
+
person asks for it or agrees to it
|
|
62
|
+
- A pulse that does not land is rolled back whole - code, tests and record together - and its module
|
|
63
|
+
waits until the spec changes or the module is asked for again. Running it again unchanged usually
|
|
64
|
+
ends the same way: look at why it did not land first
|
|
65
|
+
|
|
66
|
+
## Where the cost is
|
|
67
|
+
|
|
68
|
+
- The cost is the work regenerated: how many functional specs a change touches, directly or through
|
|
69
|
+
the definitions they use, cut into pulses of at most `max-specs-per-pulse`
|
|
70
|
+
- Regenerating functional specs again, or a module or chain from scratch, costs most, and is only ever
|
|
71
|
+
asked for outright
|
|
72
|
+
- Placement never adds cost. Put a functional spec in the module that owns the concern, at the point
|
|
73
|
+
in its order where what it relies on has been said; never at the end of a module, or in the tip,
|
|
74
|
+
only to spare regeneration - it spares none
|
|
75
|
+
- Never write placement for cost into AGENTS.md, a skill or notes: what is written there is read back
|
|
76
|
+
later as how the project works
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: bud
|
|
3
3
|
description: >-
|
|
4
|
-
Add a feature to an existing ***plain project the way `brood` builds one:
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
Add a feature to an existing ***plain project the way `brood` builds one: it first asks how many
|
|
5
|
+
questions the product phase may ask - light, medium, thorough or best judgement, broader with
|
|
6
|
+
fewer - then a short feature-intent interview, then product questions - a trigger and its outcome,
|
|
7
|
+
an edge case, a rule - where every answer becomes a spec change, written as a git diff of the
|
|
7
8
|
.plain files and built the moment it is written, so the feature appears while the interview is
|
|
8
|
-
still going.
|
|
9
|
+
still going. What the questions leave open it decides itself, each decision a spec change of its
|
|
10
|
+
own. A change that touches what is already specified or being built is a spec diff too: what
|
|
9
11
|
is left to build is worked out again from the spec. Use when the user wants to add a
|
|
10
12
|
feature to an existing project. Not for starting a new project (use `brood`, or `spawn`
|
|
11
13
|
to start fast) or for editing generated code (the .plain specs are the source of truth).
|
|
@@ -16,7 +18,12 @@ metadata:
|
|
|
16
18
|
intent: "what the feature is for, who it serves, and what it leaves out"
|
|
17
19
|
scope: "finds where the feature goes in the spec, and what is built already"
|
|
18
20
|
product: "the feature, question by question - each answer starts a regenerate pulse"
|
|
19
|
-
|
|
21
|
+
# The phase the questioning level caps, asked by the harness as the first question: light 3,
|
|
22
|
+
# medium 5, thorough 10, best judgement as many as turri judges the phase needs.
|
|
23
|
+
questioning: [product]
|
|
24
|
+
# Every answer in the product phase is a spec change: the next question waits until it is
|
|
25
|
+
# written with write_spec_diff. Changes turri decides itself need no answer before them.
|
|
26
|
+
spec-diff-per-answer: [product]
|
|
20
27
|
---
|
|
21
28
|
|
|
22
29
|
# Bud
|
|
@@ -37,10 +44,36 @@ the spec."
|
|
|
37
44
|
This is `brood`'s product phase, scoped to one feature, on top of what is there: the stack,
|
|
38
45
|
the testing setup and every earlier feature are settled - read them, build on them, restart none.
|
|
39
46
|
|
|
47
|
+
## How many questions
|
|
48
|
+
|
|
49
|
+
The first question of the intent phase is the harness's own, not yours: how many questions the
|
|
50
|
+
**product** phase may ask. The level sets how many questions there are and so how broad each is -
|
|
51
|
+
never what they cover:
|
|
52
|
+
|
|
53
|
+
| level | product questions | each question |
|
|
54
|
+
| --- | --- | --- |
|
|
55
|
+
| light | at most 3 | broad: the whole feature at once - what it does end to end, its main rules - with what fits the brief proposed, for the person to confirm or correct |
|
|
56
|
+
| medium | at most 5 | one part of the feature, with its main rules |
|
|
57
|
+
| thorough | at most 10 | narrow: one trigger, rule or edge case, with follow-ups on the ones that matter |
|
|
58
|
+
| best judgement | as many as you judge the feature needs | as broad or as narrow as each part needs |
|
|
59
|
+
|
|
60
|
+
The intent phase is not capped. Follow-ups count; the closing confirmation - asked with
|
|
61
|
+
`confirms_phase: true` - does not. Past the cap `ask_user` refuses the question. To stop sooner, or
|
|
62
|
+
under best judgement once the feature is settled enough to build, call `end_questions`.
|
|
63
|
+
|
|
64
|
+
The level limits the questions, never the spec changes. **Every answer is a spec change**, whatever
|
|
65
|
+
the level: written with `write_spec_diff` and built at once, before the next question - `ask_user`
|
|
66
|
+
refuses the next one until it is. A broad answer that covers several behaviours is several changes,
|
|
67
|
+
and you write them all. What the questions leave open - the details of a light answer, what is left
|
|
68
|
+
once they are over - is yours to decide, as a careful engineer would, in the light of the brief: each
|
|
69
|
+
decision a spec change of its own, written with `write_spec_diff` with no answer needed before it,
|
|
70
|
+
and said in one line. The closing summary names every decision you made yourself, so the
|
|
71
|
+
confirmation is where the person can change it.
|
|
72
|
+
|
|
40
73
|
## Question style
|
|
41
74
|
|
|
42
|
-
- Ask with `ask_user`, one question per call, and pass `options` so
|
|
43
|
-
types - concrete choices, plus the free-form catch-all the tool adds. Reserve `free_form: true`
|
|
75
|
+
- Ask with `ask_user`, one question per call, as broad as the level says, and pass `options` so
|
|
76
|
+
the user picks rather than types - concrete choices, plus the free-form catch-all the tool adds. Reserve `free_form: true`
|
|
44
77
|
for a genuinely open question.
|
|
45
78
|
- Ask about the product - a trigger and its outcome, an edge case, a rule, a permission, a step of
|
|
46
79
|
a flow - never about a spec section ("which concepts?", "what reqs?"). Let the answer decide which
|
|
@@ -55,6 +88,9 @@ the testing setup and every earlier feature are settled - read them, build on th
|
|
|
55
88
|
|
|
56
89
|
### intent
|
|
57
90
|
|
|
91
|
+
The harness has asked how many questions the product phase may ask before this phase starts; its
|
|
92
|
+
note beside these instructions gives the answer. Do not ask it again.
|
|
93
|
+
|
|
58
94
|
Read `references/intent.md` and ask its five core questions one at a time with `ask_user`. Ask at
|
|
59
95
|
most one focused follow-up when an answer is too vague to summarize. If what the user has already
|
|
60
96
|
said answers a question, confirm it in one line instead of asking.
|
|
@@ -81,8 +117,8 @@ Say in one line where the feature goes, and move on. Write nothing to disk.
|
|
|
81
117
|
|
|
82
118
|
### product
|
|
83
119
|
|
|
84
|
-
The feature, walked question by question. Run this loop
|
|
85
|
-
|
|
120
|
+
The feature, walked question by question. Run this loop while the questioning level allows (see
|
|
121
|
+
"How many questions"):
|
|
86
122
|
|
|
87
123
|
1. **Ask** one product question with `ask_user`.
|
|
88
124
|
2. The user **answers**.
|
|
@@ -106,14 +142,17 @@ covered:
|
|
|
106
142
|
Write it as a git diff: `diff --git a/<file> b/<file>`, `--- a/<file>`, `+++ b/<file>`, then the
|
|
107
143
|
hunks with a few lines of unchanged context, paths from the project root. A new functional spec
|
|
108
144
|
goes where it belongs in build order - after what it builds on, usually at the end.
|
|
109
|
-
4. **Write it with `write_spec_diff
|
|
110
|
-
it; with conformance on, its conformance tests follow it.
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
145
|
+
4. **Write it with `write_spec_diff` at once**, before anything else. It applies the diff and starts
|
|
146
|
+
a render spec diff job for it; with conformance on, its conformance tests follow it. An answer
|
|
147
|
+
that covers several behaviours is a change for each: write them all. Then the changes for what
|
|
148
|
+
you decide yourself around it, if any. Say in one line what went into the spec - "added `:Note:`
|
|
149
|
+
and functional spec 7" - and what became of the build, as the tool says, then ask the next
|
|
150
|
+
question. Never wait for a build, and never ask the user to approve a change.
|
|
151
|
+
|
|
152
|
+
**One answer, at least one change.** A follow-up about the same behaviour - an edge case, a
|
|
153
|
+
validation rule - is its own answer and its own change. An answer that describes two behaviours is
|
|
154
|
+
two changes, both written before the next question. A change never carries both an answer and
|
|
155
|
+
something you decided: what you decide is a change of its own.
|
|
117
156
|
|
|
118
157
|
**What already exists.** When an answer - or the conflict check - means changing something already
|
|
119
158
|
specified: a definition, a req, a functional spec, built or still queued, the next question is
|
|
@@ -127,22 +166,14 @@ is taken out, one it touches renders the spec as it now is.
|
|
|
127
166
|
**Fix your own mistakes in place.** When a later answer refines or contradicts a change you wrote in
|
|
128
167
|
this feature, write the correction as its own diff with `fixes_earlier`, before the next question.
|
|
129
168
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
2. Run `validate` on every module the feature touched.
|
|
142
|
-
3. Fix what either finds with a spec diff and `fixes_earlier` - never by editing the file. Ask the
|
|
143
|
-
user only when a fix is a decision the brief and the answers do not settle.
|
|
144
|
-
|
|
145
|
-
Walk `references/checklist.md` once, as a self-audit. Then hand over in a few lines: the feature's
|
|
146
|
-
spec changes in order, the builds they queued and how they stand (`drift`), and that any
|
|
147
|
-
further change is asked for in the conversation - each one a spec diff, and what is left to build is
|
|
148
|
-
worked out again from the spec. The next feature starts again from the intent.
|
|
169
|
+
Once the questions are over - the cap reached, or `end_questions` called - write what is left of
|
|
170
|
+
the feature the same way: one decision of yours, one spec change, with no answer between. Then run
|
|
171
|
+
`validate` on every module the feature touched, and fix what it finds with a spec diff and
|
|
172
|
+
`fixes_earlier`.
|
|
173
|
+
|
|
174
|
+
Finish by summarizing the feature's spec changes in build order, marking what you decided without
|
|
175
|
+
asking, saying what is built and what is still queued (`drift`), and getting explicit confirmation
|
|
176
|
+
with `confirms_phase: true`. The summary is for the person to take in at a glance - a line a change,
|
|
177
|
+
each decision you made yourself in a few words, about fifteen lines at most, never the specs'
|
|
178
|
+
wording. Any further change is asked for in the conversation, each one a spec diff; the next
|
|
179
|
+
feature starts again from the intent.
|
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
Extract the intent of this feature before choosing files or authoring specifications. Ask exactly
|
|
4
4
|
five core questions, one at a time, and do not write to disk.
|
|
5
5
|
|
|
6
|
+
The harness has already asked the first question of this phase: how many questions the product
|
|
7
|
+
phase may ask - light (3), medium (5), thorough (10) or best judgement. Do not ask it again; this
|
|
8
|
+
phase's own questions are not capped by it.
|
|
9
|
+
|
|
6
10
|
## Questions
|
|
7
11
|
|
|
8
12
|
1. **Motivation** — What problem or limitation should this feature address?
|
|
@@ -21,6 +21,8 @@ allowed-tools: [read, write, edit, bash, ls, grep, find]
|
|
|
21
21
|
|
|
22
22
|
The refactoring is purely structural. The **combined behavior** of the resulting modules must be **identical** to the original module. No functional spec is added, removed, or weakened. The split is semantic — grouping related specs together — not behavioral.
|
|
23
23
|
|
|
24
|
+
The spec is structural; the code is not. Once modules are split and specs move between them, the code already built no longer matches the module layout: specs move into modules the code was never built on, and no change to that code brings them in. **After a refactor, the whole requires chain is regenerated from scratch** — the existing code and conformance tests are taken out (their lineage keeps them) and every module is built again from the base of the chain upward. Say so up front: it is part of what the user agrees to (Phase 2e), and it is the last step of the skill (Phase 5).
|
|
25
|
+
|
|
24
26
|
## Input
|
|
25
27
|
|
|
26
28
|
The `.plain` file to refactor, plus guidance from the user on the desired grouping (or ask the user to confirm your proposed grouping).
|
|
@@ -90,8 +92,9 @@ Summarize for the user:
|
|
|
90
92
|
- Any new import module being created
|
|
91
93
|
- Which concepts are exported from each module
|
|
92
94
|
- Confirmation that all original specs are accounted for (none lost)
|
|
95
|
+
- That the whole chain will be **regenerated from scratch** once the split is done: the code and conformance tests built so far are taken out (kept in the lineage) and everything is built again from the base module up — this takes as long and costs as much as building the original module did
|
|
93
96
|
|
|
94
|
-
Get explicit user confirmation before proceeding.
|
|
97
|
+
Get explicit user confirmation before proceeding — of the split and of regenerating from scratch.
|
|
95
98
|
|
|
96
99
|
## Phase 3 — Execute the Split
|
|
97
100
|
|
|
@@ -162,6 +165,19 @@ For each new module:
|
|
|
162
165
|
|
|
163
166
|
Read each new `.plain` file in full and present the final structure to the user for approval. If the user requests changes, apply them and re-verify.
|
|
164
167
|
|
|
168
|
+
Validate each new module with `turri validate <module>.plain` (or the `validate` tool) before going on: a module that does not parse cannot be regenerated.
|
|
169
|
+
|
|
170
|
+
## Phase 5 — Regenerate the Chain from Scratch
|
|
171
|
+
|
|
172
|
+
The split moves specs between modules, so the code built from the original module cannot be patched into the new layout: the chain is regenerated from scratch. Do not try to keep or reuse the existing code, and do not regenerate only what looks changed — modules have moved, and a codebase built without a module it now requires has to be started over anyway.
|
|
173
|
+
|
|
174
|
+
1. **Remind the user** what regenerating from scratch does — the code and conformance tests built so far are taken out, committed so the lineage keeps them, and the whole chain is built again from the base up — and that they already agreed to it in Phase 2e. Proceed only on that agreement.
|
|
175
|
+
2. **Regenerate the tip of the chain from scratch, with its whole chain** — the last module, the one everything else is required by. From scratch for the tip alone is not enough: the modules below keep their code, and the tip starts from a copy of it, laid out for the old modules. With the whole chain, every module's code is taken out, the base's included, and the chain is built again from the bottom:
|
|
176
|
+
- in the chat: the `regenerate` tool on the tip's `.plain` file with `from_scratch: "chain"`, or `/regenerate <tip> from scratch, the whole chain`;
|
|
177
|
+
- on the command line: `turri regenerate <tip>.plain --from-scratch-chain`.
|
|
178
|
+
3. **Modules that require the chain** (updated in 3d) are regenerated after it, from scratch too (`from_scratch: "module"`): the modules they require are not the ones their code was built on. When the tip's whole chain is regenerated, a module built on top of it is a chain of its own — regenerating it from scratch with its whole chain instead covers the tip's chain too, in one go.
|
|
179
|
+
4. **The original module's codebase** (`plain_modules/<original-module>/`), when the original module was deleted or renamed, is no longer built from anything. Tell the user it is there; it is theirs to delete. Do not delete it unasked.
|
|
180
|
+
|
|
165
181
|
## Common Pitfalls
|
|
166
182
|
|
|
167
183
|
### Splitting too aggressively
|
|
@@ -179,9 +195,12 @@ This is a refactoring, not a rewrite. Spec text must be copied verbatim. If a sp
|
|
|
179
195
|
### Losing acceptance tests
|
|
180
196
|
Acceptance tests are nested under their parent functional spec. When moving a spec to a new module, its acceptance tests must move with it.
|
|
181
197
|
|
|
198
|
+
### Regenerating only what changed
|
|
199
|
+
After a split the existing code was built for a module layout that no longer exists. Regenerating incrementally either stops at a codebase that has to be started over or builds on code laid out for the old modules. Regenerate the whole chain from scratch.
|
|
200
|
+
|
|
182
201
|
## Validation Checklist
|
|
183
202
|
|
|
184
|
-
- [ ] User confirmed the split plan before execution
|
|
203
|
+
- [ ] User confirmed the split plan before execution, including regenerating the whole chain from scratch
|
|
185
204
|
- [ ] All original functional specs are present in exactly one new module — none lost
|
|
186
205
|
- [ ] Spec text is identical to the original — no rewording
|
|
187
206
|
- [ ] Acceptance tests moved with their parent specs
|
|
@@ -194,3 +213,6 @@ Acceptance tests are nested under their parent functional spec. When moving a sp
|
|
|
194
213
|
- [ ] Original module removed or updated
|
|
195
214
|
- [ ] Downstream modules (if any) updated to require the chain tip, plus any earlier chain modules whose exported concepts they reference
|
|
196
215
|
- [ ] User approved the final result
|
|
216
|
+
- [ ] Every new module validates
|
|
217
|
+
- [ ] The tip of the chain regenerated from scratch with its whole chain, then any module that requires it
|
|
218
|
+
- [ ] User told about the original module's leftover codebase, if there is one
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@turri-dev/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4-next.01530aa",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
"grammar:sync": "node scripts/sync-plyn-grammar.mjs"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@earendil-works/pi-coding-agent": "^1.
|
|
37
|
-
"@earendil-works/pi-tui": "^1.
|
|
36
|
+
"@earendil-works/pi-coding-agent": "^1.2.0",
|
|
37
|
+
"@earendil-works/pi-tui": "^1.2.0",
|
|
38
38
|
"@langchain/langgraph": "1.4.15",
|
|
39
39
|
"gray-matter": "^4.0.3",
|
|
40
40
|
"js-yaml": "^5.4.2",
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
# Bud Checklist
|
|
2
|
-
|
|
3
|
-
Use this to verify the workflow was followed - never as a substitute for it. Walk it once in the
|
|
4
|
-
review step, before the handover. A box counts only when the change is in the `.plain` files, not
|
|
5
|
-
merely discussed; an unmet box is completed with a spec diff before finishing.
|
|
6
|
-
|
|
7
|
-
## Intent
|
|
8
|
-
|
|
9
|
-
- [ ] Asked the five core questions of `references/intent.md` one at a time - or confirmed in one
|
|
10
|
-
line what the user had already said - with at most one clarification for a vague answer.
|
|
11
|
-
- [ ] Wrote nothing to disk before the brief was confirmed.
|
|
12
|
-
- [ ] Summarized motivation, affected user, desired outcome, observable success criterion, and
|
|
13
|
-
boundary with explicit exclusions; got explicit confirmation.
|
|
14
|
-
|
|
15
|
-
## Scope
|
|
16
|
-
|
|
17
|
-
- [ ] Read the target `.plain` file(s) whole, with their `import` and `requires` chains, and the
|
|
18
|
-
config that says whether conformance tests are on.
|
|
19
|
-
- [ ] Asked which module only when it was genuinely ambiguous.
|
|
20
|
-
|
|
21
|
-
## Every product question
|
|
22
|
-
|
|
23
|
-
- [ ] Asked exactly one question via `ask_user`, about the product - a trigger and outcome, an edge
|
|
24
|
-
case, a rule, a permission, a step of a flow - never about a spec section.
|
|
25
|
-
- [ ] Turned the answer into exactly one spec change, across every section it needed, and wrote it
|
|
26
|
-
with `write_spec_diff` - never with `write` or `edit`.
|
|
27
|
-
- [ ] Concepts defined in the same change as, or before, what first uses them; no cycles.
|
|
28
|
-
- [ ] Every functional spec follows `add-functional-spec`'s rules, passed its complexity and
|
|
29
|
-
conflict checks, and sits in build order; one too big was split with the user.
|
|
30
|
-
- [ ] Every change to something already specified - built or still queued - was put to the user
|
|
31
|
-
first (keep / augment / replace) and written as a diff with `fixes_earlier`.
|
|
32
|
-
- [ ] Every correction of this feature's own changes was a diff with `fixes_earlier`, before the
|
|
33
|
-
next question.
|
|
34
|
-
- [ ] `***test reqs***` and `***acceptance tests***` only with conformance tests on.
|
|
35
|
-
- [ ] Asked whether the feature is fully covered before leaving the loop.
|
|
36
|
-
|
|
37
|
-
## Review
|
|
38
|
-
|
|
39
|
-
- [ ] Read the modified `.plain` file(s) whole and checked: concepts defined before use, no cycles,
|
|
40
|
-
build order right end to end, functional specs language-agnostic, every external interface
|
|
41
|
-
explicit, acceptance tests consistent with their functional specs.
|
|
42
|
-
- [ ] Ran `validate` on every module touched, and fixed what it reported with spec diffs.
|
|
43
|
-
- [ ] Handed over: the spec changes in order, the builds they queued and how they stand, and that
|
|
44
|
-
further changes are asked for in the conversation as spec diffs.
|