@turri-dev/cli 0.1.4-next.318a98a → 0.1.4-next.5a8c6e5

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 (103) hide show
  1. package/.pi/themes/turri-dark.json +67 -66
  2. package/.pi/themes/turri-light.json +71 -73
  3. package/README.md +40 -128
  4. package/assets/jellyfish/dark-00.png +0 -0
  5. package/assets/jellyfish/dark-01.png +0 -0
  6. package/assets/jellyfish/dark-02.png +0 -0
  7. package/assets/jellyfish/dark-03.png +0 -0
  8. package/assets/jellyfish/dark-04.png +0 -0
  9. package/assets/jellyfish/dark-05.png +0 -0
  10. package/assets/jellyfish/dark-06.png +0 -0
  11. package/assets/jellyfish/dark-07.png +0 -0
  12. package/assets/jellyfish/dark-08.png +0 -0
  13. package/assets/jellyfish/dark-09.png +0 -0
  14. package/assets/jellyfish/dark-10.png +0 -0
  15. package/assets/jellyfish/dark-11.png +0 -0
  16. package/assets/jellyfish/light-00.png +0 -0
  17. package/assets/jellyfish/light-01.png +0 -0
  18. package/assets/jellyfish/light-02.png +0 -0
  19. package/assets/jellyfish/light-03.png +0 -0
  20. package/assets/jellyfish/light-04.png +0 -0
  21. package/assets/jellyfish/light-05.png +0 -0
  22. package/assets/jellyfish/light-06.png +0 -0
  23. package/assets/jellyfish/light-07.png +0 -0
  24. package/assets/jellyfish/light-08.png +0 -0
  25. package/assets/jellyfish/light-09.png +0 -0
  26. package/assets/jellyfish/light-10.png +0 -0
  27. package/assets/jellyfish/light-11.png +0 -0
  28. package/dist/ask.js +34 -15
  29. package/dist/brand.js +7 -7
  30. package/dist/cli-options.js +12 -6
  31. package/dist/config-edit.js +1 -0
  32. package/dist/config.js +5 -2
  33. package/dist/cultivate-cli.js +16 -23
  34. package/dist/extension.js +59 -67
  35. package/dist/init-config.js +5 -0
  36. package/dist/jellyfish.js +130 -0
  37. package/dist/loop-cli.js +19 -7
  38. package/dist/loop-tools.js +11 -5
  39. package/dist/module-report.js +5 -4
  40. package/dist/pi.js +76 -19
  41. package/dist/question-dialog.js +1 -0
  42. package/dist/regenerate/activity.js +21 -0
  43. package/dist/regenerate/list-arguments.js +121 -0
  44. package/dist/regenerate/loop.js +21 -8
  45. package/dist/regenerate/plain-palette.js +52 -37
  46. package/dist/regenerate/regenerate.js +4 -2
  47. package/dist/regenerate/self-check.js +13 -6
  48. package/dist/regenerate/side-panel.js +1 -1
  49. package/dist/regenerate/spec-map-view.js +9 -5
  50. package/dist/regenerate/test-scripts.js +54 -10
  51. package/dist/regenerate/unit-review.js +1 -1
  52. package/dist/regenerate-cli.js +11 -5
  53. package/dist/release-cli.js +3 -8
  54. package/dist/review/live.js +2 -1
  55. package/dist/run-report.js +39 -1
  56. package/dist/validate-cli.js +3 -8
  57. package/docs/README.md +5 -12
  58. package/docs/authoring-plain.md +37 -119
  59. package/docs/config.md +53 -178
  60. package/docs/deploy.md +21 -80
  61. package/docs/development.md +13 -41
  62. package/docs/headless.md +45 -121
  63. package/docs/images/how-turri-works.svg +29 -31
  64. package/docs/images/turri-banner.png +0 -0
  65. package/docs/installation.md +13 -40
  66. package/docs/parser.md +15 -43
  67. package/docs/regenerating.md +229 -938
  68. package/docs/sandbox.md +38 -152
  69. package/docs/skills-and-gates.md +50 -171
  70. package/docs/theming.md +45 -46
  71. package/docs/using.md +69 -345
  72. package/genome/rules/bullet-continuation.md +5 -13
  73. package/genome/rules/concise-specs-examples.md +2 -4
  74. package/genome/rules/concise-specs-integration-examples.md +2 -6
  75. package/genome/rules/concise-specs.md +1 -2
  76. package/genome/rules/func-specs.md +1 -0
  77. package/genome/rules/integration-embedded-testing.md +1 -4
  78. package/genome/rules/integrations.md +1 -2
  79. package/genome/rules/project-model.md +14 -35
  80. package/genome/rules/stdlib.md +14 -49
  81. package/genome/rules/turri-regeneration.md +48 -0
  82. package/genome/skills/add-implementation-requirement/SKILL.md +1 -2
  83. package/genome/skills/analyze-if-func-spec-too-complex/SKILL.md +3 -8
  84. package/genome/skills/brood/SKILL.md +37 -127
  85. package/genome/skills/brood/references/intent.md +4 -12
  86. package/genome/skills/brood/references/product.md +24 -76
  87. package/genome/skills/brood/references/stack.md +7 -29
  88. package/genome/skills/brood/references/testing.md +11 -42
  89. package/genome/skills/bud/SKILL.md +32 -109
  90. package/genome/skills/bud/references/intent.md +4 -11
  91. package/genome/skills/implement-conformance-testing-script/SKILL.md +3 -6
  92. package/genome/skills/implement-unit-testing-script/SKILL.md +1 -2
  93. package/genome/skills/mature/SKILL.md +21 -69
  94. package/genome/skills/refactor-module/SKILL.md +24 -2
  95. package/genome/skills/spawn/SKILL.md +28 -113
  96. package/package.json +1 -1
  97. package/assets/jellyfish/dark-12.png +0 -0
  98. package/assets/jellyfish/dark-13.png +0 -0
  99. package/assets/jellyfish/dark-14.png +0 -0
  100. package/assets/jellyfish/fallback.txt +0 -252
  101. package/assets/jellyfish/light-12.png +0 -0
  102. package/assets/jellyfish/light-13.png +0 -0
  103. package/assets/jellyfish/light-14.png +0 -0
@@ -1,11 +1,8 @@
1
1
  # the intent phase — What is the intent?
2
2
 
3
- Extract the user's intent before creating files or decomposing the product into specifications.
4
- Keep this phase short. Ask exactly five core questions, one at a time, and do not write to disk.
3
+ Extract the user's intent before creating files or decomposing the product into specifications. Keep this phase short. Ask exactly five core questions, one at a time, and do not write to disk.
5
4
 
6
- The harness has already asked the first question of this phase: how many questions the stack and
7
- product phases may ask - light (3), medium (5), thorough (10) or best judgement. Do not ask it
8
- again; this phase's own questions are not capped by it.
5
+ The harness has already asked the first question of this phase: how many questions the stack and product phases may ask - light (3), medium (5), thorough (10) or best judgement. Do not ask it again; this phase's own questions are not capped by it.
9
6
 
10
7
  ## Questions
11
8
 
@@ -15,8 +12,7 @@ again; this phase's own questions are not capped by it.
15
12
  4. **Success criterion** — What observable result would make the first version useful?
16
13
  5. **Initial boundary** — What should the first version deliberately leave out?
17
14
 
18
- Ask one focused follow-up only when an answer is too vague to summarize. Do not explore features,
19
- entities, technology, architecture, or testing yet; those belong to later phases.
15
+ Ask one focused follow-up only when an answer is too vague to summarize. Do not explore features, entities, technology, architecture, or testing yet; those belong to later phases.
20
16
 
21
17
  ## Intent brief
22
18
 
@@ -28,8 +24,4 @@ Summarize the answers in five short bullets:
28
24
  - Observable success criterion
29
25
  - Initial boundary and explicit exclusions
30
26
 
31
- Ask the user to confirm or correct the brief with one `ask_user` question, the five bullets passed whole as its
32
- `context` - the dialog shows only the question, its options and its `context`. The intent phase finishes only after
33
- explicit confirmation.
34
- Carry the confirmed brief into the stack and product phases so their questions refine it instead of restarting intent
35
- discovery.
27
+ Ask the user to confirm or correct the brief with one `ask_user` question, the five bullets passed whole as its `context` - the dialog shows only the question, its options and its `context`. The intent phase finishes only after explicit confirmation. Carry the confirmed brief into the stack and product phases so their questions refine it instead of restarting intent discovery.
@@ -1,101 +1,49 @@
1
1
  # the product phase — What does it do?
2
2
 
3
- The whole product interview, in one phase, walked **feature by feature** - not section by
4
- section. There is no pass that fills in the definitions and then another that writes the
5
- functional specs. Each question is about the product: a feature, a step in a flow, a rule.
6
- Its answer becomes one spec change that touches whatever sections that answer needs - the
7
- concepts the feature introduces, a policy it needs, its functional spec - and every spec change
8
- is built the moment it is written.
3
+ The whole product interview, in one phase, walked **feature by feature** - not section by section. There is no pass that fills in the definitions and then another that writes the functional specs. Each question is about the product: a feature, a step in a flow, a rule. Its answer becomes one spec change that touches whatever sections that answer needs - the concepts the feature introduces, a policy it needs, its functional spec - and every spec change is built the moment it is written.
9
4
 
10
5
  Carry the confirmed intent brief and the settled stack in. Do not restart either.
11
6
 
12
7
  ## How many questions
13
8
 
14
- The questioning level caps this phase's questions (light 3, medium 5, thorough 10, or best
15
- judgement - `SKILL.md`, "How many questions"), and so sets how broad each is. Every level walks
16
- all the topics below: light in a few broad questions - the features and their order in one, what
17
- they do end to end in another, with what fits the brief proposed for the person to confirm or
18
- correct; thorough in narrow ones, a feature, rule or edge case each. The level limits the
19
- questions, never the spec changes:
20
-
21
- - **Every answer is a spec change**, at every level: written with `write_spec_diff` and built at
22
- once, before the next question - `ask_user` refuses the next question until it is. A broad
23
- answer covering several features is a change for each.
24
- - **What the questions leave open is yours** - the details under a broad answer, and everything
25
- still open once the questions are over (the cap reached, or `end_questions` called). Each
26
- feature, edge case and rule you decide is its own spec change, written with `write_spec_diff`
27
- with no answer needed before it, and said in one line. Write as many as the product needs.
28
- Decide from the intent brief and the answers so far; leave out what they do not call for rather
29
- than invent scope.
9
+ The questioning level caps this phase's questions (light 3, medium 5, thorough 10, or best judgement - `SKILL.md`, "How many questions"), and so sets how broad each is. Every level walks all the topics below: light in a few broad questions - the features and their order in one, what they do end to end in another, with what fits the brief proposed for the person to confirm or correct; thorough in narrow ones, a feature, rule or edge case each. The level limits the questions, never the spec changes:
10
+
11
+ - **Every answer is a spec change**, at every level: written with `write_spec_diff` and built at once, before the next question - `ask_user` refuses the next question until it is. A broad answer covering several features is a change for each.
12
+ - **What the questions leave open is yours** - the details under a broad answer, and everything still open once the questions are over (the cap reached, or `end_questions` called). Each feature, edge case and rule you decide is its own spec change, written with `write_spec_diff` with no answer needed before it, and said in one line. Write as many as the product needs. Decide from the intent brief and the answers so far; leave out what they do not call for rather than invent scope.
30
13
 
31
14
  ## One question, one answer, a spec change, a render
32
15
 
33
16
  Every iteration is exactly this, at every questioning level:
34
17
 
35
- 1. **Ask one question** with `ask_user`, about the product: a feature, its trigger and outcome,
36
- one of its edge cases or rules, the next step of a flow - as broad as the level says. Never bundle two, and never ask about
37
- a spec section ("what concepts are there?", "what reqs apply?") - ask about what the product
38
- does, and let the answer decide which sections change.
18
+ 1. **Ask one question** with `ask_user`, about the product: a feature, its trigger and outcome, one of its edge cases or rules, the next step of a flow - as broad as the level says. Never bundle two, and never ask about a spec section ("what concepts are there?", "what reqs apply?") - ask about what the product does, and let the answer decide which sections change.
39
19
  2. **Turn the answer into a spec change** - one for each feature it covers - everything it calls for, across sections:
40
- - a concept the feature introduces, into `***definitions***`, following `add-concept`, defined
41
- in the same change as the functional spec that first uses it;
20
+ - a concept the feature introduces, into `***definitions***`, following `add-concept`, defined in the same change as the functional spec that first uses it;
42
21
  - a technology-free policy the answer states, into `***implementation reqs***`;
43
- - the functional spec for the feature, or the change to one already written, following
44
- `add-functional-spec`.
45
- Write it as a git diff of the `.plain` file(s): `diff --git a/<file> b/<file>`,
46
- `--- a/<file>`, `+++ b/<file>`, then the hunks with a few lines of unchanged context. Paths
47
- are relative to the project root.
48
- 3. **Write it with `write_spec_diff`.** It applies the diff and starts a render spec diff job for
49
- it in the same call - whatever the change touches, a definition alone included. Write every
50
- change the answer calls for before the next question - `ask_user` refuses it until then - and
51
- any you decide yourself beside them. Move straight on to the next question; never wait for a
52
- build.
53
-
54
- **One answer, at least one change.** A follow-up about the same feature - an edge case, a
55
- validation rule - is its own answer and its own change to that feature's spec. An answer that
56
- describes two features is two changes, both written before the next question. A change never
57
- carries both an answer and something you decided: what you decide is a change of its own.
58
-
59
- **Fix contradictions in place.** When a later answer refines or contradicts something already
60
- written, write the correction as its own diff with `fixes_earlier` set, before the next
61
- question. It is rendered like any other change.
62
-
63
- **Never edit the `.plain` files with `write` or `edit` in this phase.** A change that does not
64
- go through `write_spec_diff` is a change nothing renders.
22
+ - the functional spec for the feature, or the change to one already written, following `add-functional-spec`. Write it as a git diff of the `.plain` file(s): `diff --git a/<file> b/<file>`, `--- a/<file>`, `+++ b/<file>`, then the hunks with a few lines of unchanged context. Paths are relative to the project root.
23
+ 3. **Write it with `write_spec_diff`.** It applies the diff and starts a render spec diff job for it in the same call - whatever the change touches, a definition alone included. Write every change the answer calls for before the next question - `ask_user` refuses it until then - and any you decide yourself beside them. Move straight on to the next question; never wait for a build.
24
+
25
+ **One answer, at least one change.** A follow-up about the same feature - an edge case, a validation rule - is its own answer and its own change to that feature's spec. An answer that describes two features is two changes, both written before the next question. A change never carries both an answer and something you decided: what you decide is a change of its own.
26
+
27
+ **Fix contradictions in place.** When a later answer refines or contradicts something already written, write the correction as its own diff with `fixes_earlier` set, before the next question. It is rendered like any other change.
28
+
29
+ **Never edit the `.plain` files with `write` or `edit` in this phase.** A change that does not go through `write_spec_diff` is a change nothing renders.
65
30
 
66
31
  ## What a change may contain
67
32
 
68
- - **`***definitions***`** - the concepts the change needs, each defined before, or in the same
69
- change as, what first uses it.
70
- - **`***functional specs***`** - at most one new functionality per change: ≤200 lines of code
71
- change, language-agnostic, in chronological build order, externally explicit where it has an
72
- interface.
73
- - **`***implementation reqs***`** - only technology-free policy: an error-handling or retry
74
- policy, an ordering guarantee, a data-format rule. The technology was settled in the stack
75
- phase; an answer that needs a new technology is a stack answer - note it and steer back.
33
+ - **`***definitions***`** - the concepts the change needs, each defined before, or in the same change as, what first uses it.
34
+ - **`***functional specs***`** - at most one new functionality per change: ≤200 lines of code change, language-agnostic, in chronological build order, externally explicit where it has an interface.
35
+ - **`***implementation reqs***`** - only technology-free policy: an error-handling or retry policy, an ordering guarantee, a data-format rule. The technology was settled in the stack phase; an answer that needs a new technology is a stack answer - note it and steer back.
76
36
 
77
- Leave the `***test reqs***` as the testing phase wrote them, and write no `***acceptance tests***`.
78
- With conformance on, every change is built with its conformance tests - from the test reqs as they
79
- stand.
37
+ Leave the `***test reqs***` as the testing phase wrote them, and write no `***acceptance tests***`. With conformance on, every change is built with its conformance tests - from the test reqs as they stand.
80
38
 
81
39
  ## Topics (in order)
82
40
 
83
- 1. **Product description** - propose a one-sentence description from the confirmed intent brief,
84
- state it back in one line, and write it into the frontmatter as the first change.
85
- 2. **Features, one at a time, in build order** - the smallest thing that is useful first, then
86
- what builds on it. For each feature: one question for what triggers it and what comes out,
87
- then one per edge case, validation rule or permission that is not obvious. Each answer is a
88
- change: the first brings the feature's concepts and its functional spec; the follow-ups refine
89
- them. A feature too large for one functional spec is split *with the user* - that is the next
90
- question.
91
- 3. **User flows** - walk the product from the user's side: what happens first, what next, and at
92
- each decision point. Each missing step is a feature, taken the same way.
93
- 4. **User interface (optional)** - skip entirely if there is none. Otherwise per screen or
94
- interaction: what the user sees and what it does, still language- and framework-agnostic.
41
+ 1. **Product description** - propose a one-sentence description from the confirmed intent brief, state it back in one line, and write it into the frontmatter as the first change.
42
+ 2. **Features, one at a time, in build order** - the smallest thing that is useful first, then what builds on it. For each feature: one question for what triggers it and what comes out, then one per edge case, validation rule or permission that is not obvious. Each answer is a change: the first brings the feature's concepts and its functional spec; the follow-ups refine them. A feature too large for one functional spec is split *with the user* - that is the next question.
43
+ 3. **User flows** - walk the product from the user's side: what happens first, what next, and at each decision point. Each missing step is a feature, taken the same way.
44
+ 4. **User interface (optional)** - skip entirely if there is none. Otherwise per screen or interaction: what the user sees and what it does, still language- and framework-agnostic.
95
45
  5. **Anything else** - anything the user wants to add or change that has not been covered.
96
46
 
97
47
  ## Reporting builds
98
48
 
99
- Report each build result between questions, in one sentence. A failed build does not stop the
100
- interview - note it and carry on, unless it shows the spec itself is wrong, in which case fix
101
- the spec with a diff and `fixes_earlier`.
49
+ Report each build result between questions, in one sentence. A failed build does not stop the interview - note it and carry on, unless it shows the spec itself is wrong, in which case fix the spec with a diff and `fixes_earlier`.
@@ -2,14 +2,7 @@
2
2
 
3
3
  Gather the technical stack **and** the project's structure/architecture. This phase affects only `***implementation reqs***`, and ends with the unit testing script every build needs — the rest of testing comes later. Run the core loop from `SKILL.md` for each topic below, in order: ask, then write the requirement into the `.plain` file with the ordinary file tools. Nothing is built in this phase. When the user has no preference, propose a sensible default that fits earlier answers and ask them to confirm.
4
4
 
5
- The questioning level caps this phase's questions (light 3, medium 5, thorough 10, or best
6
- judgement - `SKILL.md`, "How many questions"), and so sets how broad each is. Every level reaches
7
- all the topics, in order: light in a few broad questions - the stack, say, then storage and
8
- outside services together, then the remaining constraints, each with what fits the brief
9
- proposed; thorough a topic or two a question, with follow-ups. Every topic left unasked once the
10
- questions are over gets the default that fits the intent brief and the answers so far, written as a
11
- requirement like any other and named as your choice in the closing summary. The unit testing script
12
- is written whatever the level.
5
+ The questioning level caps this phase's questions (light 3, medium 5, thorough 10, or best judgement - `SKILL.md`, "How many questions"), and so sets how broad each is. Every level reaches all the topics, in order: light in a few broad questions - the stack, say, then storage and outside services together, then the remaining constraints, each with what fits the brief proposed; thorough a topic or two a question, with follow-ups. Every topic left unasked once the questions are over gets the default that fits the intent brief and the answers so far, written as a requirement like any other and named as your choice in the closing summary. The unit testing script is written whatever the level.
13
6
 
14
7
  ## Author target for this phase
15
8
 
@@ -22,27 +15,12 @@ Do **not** add `***test reqs***` or `***acceptance tests***` in this phase — t
22
15
 
23
16
  ## First: a stack from the standard library
24
17
 
25
- Before the topics, settle what kind of software each module is - a backend, a frontend, a
26
- command-line tool, a library - and offer the standard library's stacks for that kind (the stdlib
27
- rule, in `<plain-rules>`, lists them) that this machine can build: `<toolchains on this machine>`, in
28
- your instructions, says which languages it can build now. The agents use its toolchains and install
29
- none, so a stack in a language it lacks stops at its first build. Ask with `ask_user`: those stacks
30
- as options, the one that fits earlier answers first, and "Something else…" for a stack of the user's
31
- own. A stack the user names in a language the machine lacks: say what to install first and that
32
- `turri doctor` checks it, and ask whether to wait for that or choose another.
33
-
34
- - **A stack from the standard library.** Import it into the module's frontmatter as
35
- `stdlib/<kind>/<stack>`, and read the templates it brings: the stack, its `stdlib/lang/<language>`
36
- and its kind's `common` - the folder is in the stdlib rule. They settle topics 1, 2 and 5, error handling and
37
- logging in topic 6, and the unit-test framework in topic 8: do not ask about those, and write no
38
- requirement that restates them. Say in one line what the stack settles - its language, framework,
39
- layout, how it reports errors and logs - so the user knows what they chose. Then walk only topics
40
- 3, 4, 6 (what the stack leaves open), 7, and the unit testing script in 8.
41
- - **Something else.** Walk every topic below. When the language is one the standard library has, its
42
- `stdlib/lang/<language>` template can still be imported for the language-wide conventions.
43
-
44
- A user who wants something the stack settles done differently - another framework, another layout -
45
- has chosen something else: an import cannot be taken back in part.
18
+ Before the topics, settle what kind of software each module is - a backend, a frontend, a command-line tool, a library - and offer the standard library's stacks for that kind (the stdlib rule, in `<plain-rules>`, lists them) that this machine can build: `<toolchains on this machine>`, in your instructions, says which languages it can build now. The agents use its toolchains and install none, so a stack in a language it lacks stops at its first build. Ask with `ask_user`: those stacks as options, the one that fits earlier answers first, and "Something else…" for a stack of the user's own. A stack the user names in a language the machine lacks: say what to install first and that `turri doctor` checks it, and ask whether to wait for that or choose another.
19
+
20
+ - **A stack from the standard library.** Import it into the module's frontmatter as `stdlib/<kind>/<stack>`, and read the templates it brings: the stack, its `stdlib/lang/<language>` and its kind's `common` - the folder is in the stdlib rule. They settle topics 1, 2 and 5, error handling and logging in topic 6, and the unit-test framework in topic 8: do not ask about those, and write no requirement that restates them. Say in one line what the stack settles - its language, framework, layout, how it reports errors and logs - so the user knows what they chose. Then walk only topics 3, 4, 6 (what the stack leaves open), 7, and the unit testing script in 8.
21
+ - **Something else.** Walk every topic below. When the language is one the standard library has, its `stdlib/lang/<language>` template can still be imported for the language-wide conventions.
22
+
23
+ A user who wants something the stack settles done differently - another framework, another layout - has chosen something else: an import cannot be taken back in part.
46
24
 
47
25
  ## Topics (in order)
48
26
 
@@ -1,56 +1,25 @@
1
1
  # the testing phase — How is what was built checked from the outside?
2
2
 
3
- Decide whether the project has conformance tests, and if it does, say in `***test reqs***` how they
4
- are written and run, and give it the script that runs them. This comes before the product phase, and
5
- nothing here is built: a change to the test reqs is not a spec diff, so it is written with the
6
- ordinary file tools, never `write_spec_diff`. What is settled here is what every build of the
7
- product phase follows - with conformance on, each spec change is built with its conformance tests.
8
- Run the core loop for each topic below, in order: ask, then write. When the user has no preference,
9
- propose a default that fits the stack and the intent brief and ask them to confirm.
10
-
11
- Conformance tests are black-box tests written from the spec: for each functional spec, tests that
12
- run the built software from the outside - as a command, over HTTP, through its public entry point -
13
- and check it does what the spec says, kept apart from the spec's acceptance tests. The harness runs
14
- the whole suite after every spec change, so they catch one change breaking another. They cost time
15
- and tokens on every build.
3
+ Decide whether the project has conformance tests, and if it does, say in `***test reqs***` how they are written and run, and give it the script that runs them. This comes before the product phase, and nothing here is built: a change to the test reqs is not a spec diff, so it is written with the ordinary file tools, never `write_spec_diff`. What is settled here is what every build of the product phase follows - with conformance on, each spec change is built with its conformance tests. Run the core loop for each topic below, in order: ask, then write. When the user has no preference, propose a default that fits the stack and the intent brief and ask them to confirm.
4
+
5
+ Conformance tests are black-box tests written from the spec: for each functional spec, tests that run the built software from the outside - as a command, over HTTP, through its public entry point - and check it does what the spec says, kept apart from the spec's acceptance tests. The harness runs the whole suite after every spec change, so they catch one change breaking another. They cost time and tokens on every build.
16
6
 
17
7
  ## Author target for this phase
18
8
 
19
- - `***test reqs***` - one `:ConformanceTests:` requirement per fact, on the template if one exists
20
- (shared by every module), otherwise on the module. Follow `genome/rules/test-reqs.md`.
21
- - `config.turri.yaml` at the project root - the `conformance-tests:` decision. Change only that key, and
22
- create the file if there is none; everything else in it stays as it is. When the project has only a
23
- `config.yaml`, copy it to `config.turri.yaml` first - and each `config.<name>.yaml` to
24
- `config.turri.<name>.yaml` - and write the copy: `config.yaml` may be another tool's, and is never
25
- written.
9
+ - `***test reqs***` - one `:ConformanceTests:` requirement per fact, on the template if one exists (shared by every module), otherwise on the module. Follow `genome/rules/test-reqs.md`.
10
+ - `config.turri.yaml` at the project root - the `conformance-tests:` decision. Change only that key, and create the file if there is none; everything else in it stays as it is. When the project has only a `config.yaml`, copy it to `config.turri.yaml` first - and each `config.<name>.yaml` to `config.turri.<name>.yaml` - and write the copy: `config.yaml` may be another tool's, and is never written.
26
11
  - `test_scripts/` - the conformance testing script.
27
12
 
28
13
  Write no `***acceptance tests***`, no functional specs and no `***implementation reqs***` here.
29
14
 
30
15
  ## Topics (in order)
31
16
 
32
- 1. **Conformance on or off** - ask it explicitly, with what it costs and what it catches; it is a
33
- recorded decision, never an inference. Ask it even when `config.turri.yaml` already has
34
- `conformance-tests:` - offer what it says as the first option. Write it to `config.turri.yaml` as `conformance-tests: true` or
35
- `conformance-tests: false`. Off: say that no conformance tests will be written or run until it
36
- is turned on, and go to the end of the phase.
37
- 2. **Framework** - e.g. pytest, JUnit, Jest, Go's `testing`; one that fits the stack. Author it as a
38
- `:ConformanceTests:` requirement.
39
- 3. **How the tests reach the software** - as a subprocess of the CLI, over HTTP against a server the
40
- tests start, through the public entry point it exports. Author it.
41
- 4. **Setup and outside services** - fixtures, test data, databases, third-party APIs: started for
42
- real, faked, or mocked at the boundary. Author each decision as its own requirement.
17
+ 1. **Conformance on or off** - ask it explicitly, with what it costs and what it catches; it is a recorded decision, never an inference. Ask it even when `config.turri.yaml` already has `conformance-tests:` - offer what it says as the first option. Write it to `config.turri.yaml` as `conformance-tests: true` or `conformance-tests: false`. Off: say that no conformance tests will be written or run until it is turned on, and go to the end of the phase.
18
+ 2. **Framework** - e.g. pytest, JUnit, Jest, Go's `testing`; one that fits the stack. Author it as a `:ConformanceTests:` requirement.
19
+ 3. **How the tests reach the software** - as a subprocess of the CLI, over HTTP against a server the tests start, through the public entry point it exports. Author it.
20
+ 4. **Setup and outside services** - fixtures, test data, databases, third-party APIs: started for real, faked, or mocked at the boundary. Author each decision as its own requirement.
43
21
  5. **How the whole suite is run** - the one command that discovers every test. Author it.
44
- 6. **The conformance testing script** - if turri already finds one (named by
45
- `conformance-tests-script:` in `config.turri.yaml`, or the one `run_conformance_tests*.sh` in the
46
- project root or in `test_scripts/`), check it runs the suite the way the test reqs now say, and
47
- keep it. Otherwise write `test_scripts/run_conformance_tests_<language>.sh` with
48
- `implement-conformance-testing-script`, to match the test reqs. Never link it from the specs.
49
- If `test_scripts/` would hold two of a kind, name the one to use in `config.turri.yaml`. In a
50
- project whose parts are on different stacks, name each stack's script in its own
51
- `config.turri.<stack>.yaml` (`conformance-tests-script:`), and tell the user to choose the stack
52
- with `/stack <stack>` (`--stack <stack>` on the command line) before building that part.
22
+ 6. **The conformance testing script** - if turri already finds one (named by `conformance-tests-script:` in `config.turri.yaml`, or the one `run_conformance_tests*.sh` in the project root or in `test_scripts/`), check it runs the suite the way the test reqs now say, and keep it. Otherwise write `test_scripts/run_conformance_tests_<language>.sh` with `implement-conformance-testing-script`, to match the test reqs. Never link it from the specs. If `test_scripts/` would hold two of a kind, name the one to use in `config.turri.yaml`. In a project whose parts are on different stacks, name each stack's script in its own `config.turri.<stack>.yaml` (`conformance-tests-script:`), and tell the user to choose the stack with `/stack <stack>` (`--stack <stack>` on the command line) before building that part.
53
23
  7. **Anything else** - anything about testing the user wants to add or change.
54
24
 
55
- Run `validate` on every module you changed. The product phase's first build needs the test reqs
56
- and the conformance testing script both there: without them it stops before it starts.
25
+ Run `validate` on every module you changed. The product phase's first build needs the test reqs and the conformance testing script both there: without them it stops before it starts.
@@ -28,27 +28,17 @@ metadata:
28
28
 
29
29
  # Bud
30
30
 
31
- Load the `***plain` syntax rules before writing anything - they are in the system prompt under
32
- `<plain-rules>`; read `genome/rules/<name>.md` for the full text of any rule you need to follow
33
- closely.
31
+ Load the `***plain` syntax rules before writing anything - they are in the system prompt under `<plain-rules>`; read `genome/rules/<name>.md` for the full text of any rule you need to follow closely.
34
32
 
35
33
  ## Role
36
34
 
37
- Act as a `***plain` spec writer adding one feature to specs that already exist - and, usually, to
38
- code already built from them, or being built. The only output is changes to `.plain` files, and
39
- every one of them is a **spec diff**: a git diff of the `.plain` files, written with
40
- `write_spec_diff`, which applies it and queues its render spec diff job. Never write code, and never
41
- change a `.plain` file by any other means. Frame every message in terms of specs: "I'll add this to
42
- the spec."
35
+ Act as a `***plain` spec writer adding one feature to specs that already exist - and, usually, to code already built from them, or being built. The only output is changes to `.plain` files, and every one of them is a **spec diff**: a git diff of the `.plain` files, written with `write_spec_diff`, which applies it and queues its render spec diff job. Never write code, and never change a `.plain` file by any other means. Frame every message in terms of specs: "I'll add this to the spec."
43
36
 
44
- This is `brood`'s product phase, scoped to one feature, on top of what is there: the stack,
45
- the testing setup and every earlier feature are settled - read them, build on them, restart none.
37
+ This is `brood`'s product phase, scoped to one feature, on top of what is there: the stack, the testing setup and every earlier feature are settled - read them, build on them, restart none.
46
38
 
47
39
  ## How many questions
48
40
 
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:
41
+ The first question of the intent phase is the harness's own, not yours: how many questions the **product** phase may ask. The level sets how many questions there are and so how broad each is - never what they cover:
52
42
 
53
43
  | level | product questions | each question |
54
44
  | --- | --- | --- |
@@ -57,123 +47,56 @@ never what they cover:
57
47
  | thorough | at most 10 | narrow: one trigger, rule or edge case, with follow-ups on the ones that matter |
58
48
  | best judgement | as many as you judge the feature needs | as broad or as narrow as each part needs |
59
49
 
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`.
50
+ The intent phase is not capped. Follow-ups count; the closing confirmation - asked with `confirms_phase: true` - does not. Past the cap `ask_user` refuses the question. To stop sooner, or under best judgement once the feature is settled enough to build, call `end_questions`.
63
51
 
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.
52
+ The level limits the questions, never the spec changes. **Every answer is a spec change**, whatever the level: written with `write_spec_diff` and built at once, before the next question - `ask_user` refuses the next one until it is. A broad answer that covers several behaviours is several changes, and you write them all. What the questions leave open - the details of a light answer, what is left once they are over - is yours to decide, as a careful engineer would, in the light of the brief: each decision a spec change of its own, written with `write_spec_diff` with no answer needed before it, and said in one line. The closing summary names every decision you made yourself, so the confirmation is where the person can change it.
72
53
 
73
54
  ## Question style
74
55
 
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`
77
- for a genuinely open question.
78
- - Ask about the product - a trigger and its outcome, an edge case, a rule, a permission, a step of
79
- a flow - never about a spec section ("which concepts?", "what reqs?"). Let the answer decide which
80
- sections change.
81
- - Shape each question so any plausible answer maps to one spec change. Bad: "How should it work?"
82
- Good: "When the title is empty, should saving be refused with `Title is required`, or saved as
83
- `Untitled`?"
84
- - Short, direct sentences and plain words; never drop a detail the user needs to answer - split into
85
- more sentences instead.
56
+ - Ask with `ask_user`, one question per call, as broad as the level says, and pass `options` so the user picks rather than types - concrete choices, plus the free-form catch-all the tool adds. Reserve `free_form: true` for a genuinely open question.
57
+ - Ask about the product - a trigger and its outcome, an edge case, a rule, a permission, a step of a flow - never about a spec section ("which concepts?", "what reqs?"). Let the answer decide which sections change.
58
+ - Shape each question so any plausible answer maps to one spec change. Bad: "How should it work?" Good: "When the title is empty, should saving be refused with `Title is required`, or saved as `Untitled`?"
59
+ - Short, direct sentences and plain words; never drop a detail the user needs to answer - split into more sentences instead.
86
60
 
87
61
  ## Steps
88
62
 
89
63
  ### intent
90
64
 
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.
65
+ The harness has asked how many questions the product phase may ask before this phase starts; its note beside these instructions gives the answer. Do not ask it again.
93
66
 
94
- Read `references/intent.md` and ask its five core questions one at a time with `ask_user`. Ask at
95
- most one focused follow-up when an answer is too vague to summarize. If what the user has already
96
- said answers a question, confirm it in one line instead of asking.
67
+ Read `references/intent.md` and ask its five core questions one at a time with `ask_user`. Ask at most one focused follow-up when an answer is too vague to summarize. If what the user has already said answers a question, confirm it in one line instead of asking.
97
68
 
98
- Write nothing to disk. Summarize the feature-intent brief - motivation, affected user, desired
99
- outcome, observable success criterion, boundary and explicit exclusions - and get explicit
100
- confirmation, the brief passed whole as `ask_user`'s `context`, which the dialog shows above the
101
- question. Carry the brief into every later step.
69
+ Write nothing to disk. Summarize the feature-intent brief - motivation, affected user, desired outcome, observable success criterion, boundary and explicit exclusions - and get explicit confirmation, the brief passed whole as `ask_user`'s `context`, which the dialog shows above the question. Carry the brief into every later step.
102
70
 
103
71
  ### scope
104
72
 
105
73
  Keep this short: enough to ask the first product question, not a design on paper.
106
74
 
107
- 1. Find the `.plain` file(s) the feature belongs to, and read them whole, following their `import`
108
- and `requires` chains: every definition, implementation and test req, functional spec and
109
- acceptance test the feature will sit beside. Read `config.turri.yaml` (or the old `config.yaml`,
110
- when there is no `config.turri.yaml`) and the chosen stack's `config.turri.<stack>.yaml` for
111
- whether conformance tests are on.
75
+ 1. Find the `.plain` file(s) the feature belongs to, and read them whole, following their `import` and `requires` chains: every definition, implementation and test req, functional spec and acceptance test the feature will sit beside. Read `config.turri.yaml` (or the old `config.yaml`, when there is no `config.turri.yaml`) and the chosen stack's `config.turri.<stack>.yaml` for whether conformance tests are on.
112
76
  2. Ask which module only if it is genuinely ambiguous; otherwise do not.
113
- 3. Look at what is built and queued (`drift`), so you know which specs already have code and
114
- which builds are still waiting - a change to either is still just a spec diff.
77
+ 3. Look at what is built and queued (`drift`), so you know which specs already have code and which builds are still waiting - a change to either is still just a spec diff.
115
78
 
116
79
  Say in one line where the feature goes, and move on. Write nothing to disk.
117
80
 
118
81
  ### product
119
82
 
120
- The feature, walked question by question. Run this loop while the questioning level allows (see
121
- "How many questions"):
83
+ The feature, walked question by question. Run this loop while the questioning level allows (see "How many questions"):
122
84
 
123
85
  1. **Ask** one product question with `ask_user`.
124
86
  2. The user **answers**.
125
- 3. **Make the spec change** the answer calls for, as one git diff of the `.plain` file(s) - across
126
- every section it needs:
127
- - a concept it introduces, into `***definitions***` - written the way `add-concept` says, and
128
- defined in the same change as the functional spec that first uses it;
129
- - a policy it states - error handling, a retry, a data format, a library not already in the
130
- module or its imports - into `***implementation reqs***`, the way
131
- `add-implementation-requirement` says;
132
- - the functional spec it adds, or the change to one already written, the way
133
- `add-functional-spec` says: its wording rules, its complexity check
134
- (`analyze-if-func-spec-too-complex` - at most 200 lines of code; a spec too big is split *with
135
- the user*, as the next question) and its conflict check (`analyze-func-specs`, over the new
136
- spec and every existing one in the chain). Follow those skills for what the text is; the diff
137
- is the only thing that writes it.
138
- - with conformance tests on - test reqs of the module's own or imported, and a conformance
139
- testing script turri finds - an acceptance test under its functional spec when the
140
- answer states one concrete verification (`add-acceptance-test`), and a test req only when the
141
- answer changes how conformance tests run (`add-test-requirement`). With conformance off, none.
142
- Write it as a git diff: `diff --git a/<file> b/<file>`, `--- a/<file>`, `+++ b/<file>`, then the
143
- hunks with a few lines of unchanged context, paths from the project root. A new functional spec
144
- goes where it belongs in build order - after what it builds on, usually at the end.
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.
156
-
157
- **What already exists.** When an answer - or the conflict check - means changing something already
158
- specified: a definition, a req, a functional spec, built or still queued, the next question is
159
- about exactly that. Quote the existing text and offer: keep it (narrow what was just written),
160
- augment it (with the new wording in the question), or replace it. The answer is a spec diff like
161
- any other, written with `fixes_earlier`; when a concept changes, the same diff updates every spec
162
- that uses it, within what the user approved. Never rewrite earlier intent without asking. The queue
163
- master reworks the builds still queued around every such change - a queued build the change undoes
164
- is taken out, one it touches renders the spec as it now is.
165
-
166
- **Fix your own mistakes in place.** When a later answer refines or contradicts a change you wrote in
167
- this feature, write the correction as its own diff with `fixes_earlier`, before the next question.
168
-
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.
87
+ 3. **Make the spec change** the answer calls for, as one git diff of the `.plain` file(s) - across every section it needs:
88
+ - a concept it introduces, into `***definitions***` - written the way `add-concept` says, and defined in the same change as the functional spec that first uses it;
89
+ - a policy it states - error handling, a retry, a data format, a library not already in the module or its imports - into `***implementation reqs***`, the way `add-implementation-requirement` says;
90
+ - the functional spec it adds, or the change to one already written, the way `add-functional-spec` says: its wording rules, its complexity check (`analyze-if-func-spec-too-complex` - at most 200 lines of code; a spec too big is split *with the user*, as the next question) and its conflict check (`analyze-func-specs`, over the new spec and every existing one in the chain). Follow those skills for what the text is; the diff is the only thing that writes it.
91
+ - with conformance tests on - test reqs of the module's own or imported, and a conformance testing script turri finds - an acceptance test under its functional spec when the answer states one concrete verification (`add-acceptance-test`), and a test req only when the answer changes how conformance tests run (`add-test-requirement`). With conformance off, none. Write it as a git diff: `diff --git a/<file> b/<file>`, `--- a/<file>`, `+++ b/<file>`, then the hunks with a few lines of unchanged context, paths from the project root. A new functional spec goes where it belongs in build order - after what it builds on, usually at the end.
92
+ 4. **Write it with `write_spec_diff` at once**, before anything else. It applies the diff and starts a render spec diff job for it; with conformance on, its conformance tests follow it. An answer that covers several behaviours is a change for each: write them all. Then the changes for what you decide yourself around it, if any. Say in one line what went into the spec - "added `:Note:` and functional spec 7" - and what became of the build, as the tool says, then ask the next question. Never wait for a build, and never ask the user to approve a change.
93
+
94
+ **One answer, at least one change.** A follow-up about the same behaviour - an edge case, a validation rule - is its own answer and its own change. An answer that describes two behaviours is two changes, both written before the next question. A change never carries both an answer and something you decided: what you decide is a change of its own.
95
+
96
+ **What already exists.** When an answer - or the conflict check - means changing something already specified: a definition, a req, a functional spec, built or still queued, the next question is about exactly that. Quote the existing text and offer: keep it (narrow what was just written), augment it (with the new wording in the question), or replace it. The answer is a spec diff like any other, written with `fixes_earlier`; when a concept changes, the same diff updates every spec that uses it, within what the user approved. Never rewrite earlier intent without asking. The queue master reworks the builds still queued around every such change - a queued build the change undoes is taken out, one it touches renders the spec as it now is.
97
+
98
+ **Fix your own mistakes in place.** When a later answer refines or contradicts a change you wrote in this feature, write the correction as its own diff with `fixes_earlier`, before the next question.
99
+
100
+ Once the questions are over - the cap reached, or `end_questions` called - write what is left of the feature the same way: one decision of yours, one spec change, with no answer between. Then run `validate` on every module the feature touched, and fix what it finds with a spec diff and `fixes_earlier`.
101
+
102
+ Finish by summarizing the feature's spec changes in build order, marking what you decided without asking, saying what is built and what is still queued (`drift`), and getting explicit confirmation with `confirms_phase: true`. The summary is for the person to take in at a glance - a line a change, each decision you made yourself in a few words, about fifteen lines at most, never the specs' wording. Any further change is asked for in the conversation, each one a spec diff; the next feature starts again from the intent.
@@ -1,11 +1,8 @@
1
1
  # The intent step - what is the feature for?
2
2
 
3
- Extract the intent of this feature before choosing files or authoring specifications. Ask exactly
4
- five core questions, one at a time, and do not write to disk.
3
+ Extract the intent of this feature before choosing files or authoring specifications. Ask exactly five core questions, one at a time, and do not write to disk.
5
4
 
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.
5
+ The harness has already asked the first question of this phase: how many questions the product phase may ask - light (3), medium (5), thorough (10) or best judgement. Do not ask it again; this phase's own questions are not capped by it.
9
6
 
10
7
  ## Questions
11
8
 
@@ -15,9 +12,7 @@ phase's own questions are not capped by it.
15
12
  4. **Success criterion** — What observable result would prove the feature is useful and working?
16
13
  5. **Boundary** — What should this feature deliberately leave unchanged or out of scope?
17
14
 
18
- Ask one focused follow-up only when an answer is too vague to summarize. Do not choose concepts,
19
- spec wording, implementation technology, or tests yet - the product questions decide those, one
20
- spec change at a time.
15
+ Ask one focused follow-up only when an answer is too vague to summarize. Do not choose concepts, spec wording, implementation technology, or tests yet - the product questions decide those, one spec change at a time.
21
16
 
22
17
  ## Feature-intent brief
23
18
 
@@ -29,6 +24,4 @@ Summarize the answers in five short bullets:
29
24
  - Observable success criterion
30
25
  - Boundary and explicit exclusions
31
26
 
32
- Ask the user to confirm or correct the brief. The intent step finishes only after explicit
33
- confirmation. Carry the brief into the scope step, so it maps the intent onto existing modules
34
- instead of restarting the feature discussion.
27
+ Ask the user to confirm or correct the brief. The intent step finishes only after explicit confirmation. Carry the brief into the scope step, so it maps the intent onto existing modules instead of restarting the feature discussion.
@@ -62,12 +62,10 @@ A PowerShell (`.ps1`) copy is optional and only for people who run the script by
62
62
  - PowerShell: `if (-not [System.IO.Path]::IsPathRooted($ConformanceTestsFolder)) { $ConformanceTestsFolder = Join-Path (Get-Location) $ConformanceTestsFolder }`
63
63
 
64
64
  Never concatenate `$current_dir/$2` at the point of use — with an absolute `$2` that produces a doubled path (`/project//abs/path/...`), the classic symptom being `ImportError: Start directory is not importable` pointing at a path that contains the project root twice.
65
- 4. **Working directory setup.** Define a working folder at `<temp>/<lang>_<basename>` (`/tmp/<lang>_$(basename "$1")` in Bash, `Join-Path ([System.IO.Path]::GetTempPath()) "<lang>_$(Split-Path $BuildFolder -Leaf)"` in PowerShell). Wipe it (`rm -rf` / `Remove-Item -Recurse -Force`) and recreate it. Register cleanup so the folder is removed when the script exits — `trap 'rm -rf "$WORKING_FOLDER"' EXIT` in Bash, `Remove-Item -Recurse -Force` in the `finally` block in PowerShell. This folder — and **only** this folder — is where every subsequent write must land.
66
- 4b. **Refuse conformance tests in the build folder.** Conformance and acceptance tests live in the conformance tests folder (`$2`) and nowhere else. Before anything is staged, look for them in `$1`: any file carrying a conformance or acceptance label (`conformance tests of functionality`, `conformance tests of the spec`, `acceptance test <n> of functionality`), and any test file under a folder or name that says conformance or acceptance. Found any: print each path, say they belong in the conformance tests folder, and exit `1`. See [Tests in the build folder](#tests-in-the-build-folder).
65
+ 4. **Working directory setup.** Define a working folder at `<temp>/<lang>_<basename>` (`/tmp/<lang>_$(basename "$1")` in Bash, `Join-Path ([System.IO.Path]::GetTempPath()) "<lang>_$(Split-Path $BuildFolder -Leaf)"` in PowerShell). Wipe it (`rm -rf` / `Remove-Item -Recurse -Force`) and recreate it. Register cleanup so the folder is removed when the script exits — `trap 'rm -rf "$WORKING_FOLDER"' EXIT` in Bash, `Remove-Item -Recurse -Force` in the `finally` block in PowerShell. This folder — and **only** this folder — is where every subsequent write must land. 4b. **Refuse conformance tests in the build folder.** Conformance and acceptance tests live in the conformance tests folder (`$2`) and nowhere else. Before anything is staged, look for them in `$1`: any file carrying a conformance or acceptance label (`conformance tests of functionality`, `conformance tests of the spec`, `acceptance test <n> of functionality`), and any test file under a folder or name that says conformance or acceptance. Found any: print each path, say they belong in the conformance tests folder, and exit `1`. See [Tests in the build folder](#tests-in-the-build-folder).
67
66
  5. **Copy the build.** Recursively copy everything from `<build_folder>` (`$1`) into the working folder. **Do not** copy the conformance tests — they stay where they are. After this step both `$1` (build folder) and `$2` (conformance tests folder) are treated as **read-only** for the rest of the script.
68
67
  6. **Enter the working directory.** `cd` / `Set-Location` into `<temp>/<lang>_<basename>`. If that fails, exit with code `69`. All remaining steps run from inside the working folder; they must never write back to `$1` or `$2`.
69
- 7. **Install dependencies into an isolated environment inside `<temp>/<lang>_<basename>`.** Set up a per-working-folder dependency location (a Python venv at `./.venv`, a local `./node_modules`, a project-scoped Maven repo at `./.m2`, etc.) and install/resolve all dependencies into it. **Never** install into the source build folder (`$1`), the conformance tests folder (`$2`), the user's global cache (`~/.m2`, system-wide `pip`, `~/.cargo`, `~/.npm`, ...), or anywhere outside `<temp>/<lang>_<basename>`. If the install command fails, propagate its exit code immediately and **do not** proceed to step 8. See [Dependency isolation](#dependency-isolation).
70
- 7b. **Static checks of the conformance tests.** Once the build and the test libraries are installed - so the tests resolve against them as they do when they run - check **the conformance tests in `$CONFORMANCE_TESTS_FOLDER`, and only them**: the formatter in check mode, the linter, and the type checker where the language has one apart from its compiler. See [Static checks of the tests](#static-checks-of-the-tests). Run every check, even after one fails, print each one's whole output, remember whether any failed - and go on to step 8 whatever they said, so one run reports both.
68
+ 7. **Install dependencies into an isolated environment inside `<temp>/<lang>_<basename>`.** Set up a per-working-folder dependency location (a Python venv at `./.venv`, a local `./node_modules`, a project-scoped Maven repo at `./.m2`, etc.) and install/resolve all dependencies into it. **Never** install into the source build folder (`$1`), the conformance tests folder (`$2`), the user's global cache (`~/.m2`, system-wide `pip`, `~/.cargo`, `~/.npm`, ...), or anywhere outside `<temp>/<lang>_<basename>`. If the install command fails, propagate its exit code immediately and **do not** proceed to step 8. See [Dependency isolation](#dependency-isolation). 7b. **Static checks of the conformance tests.** Once the build and the test libraries are installed - so the tests resolve against them as they do when they run - check **the conformance tests in `$CONFORMANCE_TESTS_FOLDER`, and only them**: the formatter in check mode, the linter, and the type checker where the language has one apart from its compiler. See [Static checks of the tests](#static-checks-of-the-tests). Run every check, even after one fails, print each one's whole output, remember whether any failed - and go on to step 8 whatever they said, so one run reports both.
71
69
  8. **Run the conformance tests.** Invoke the language's standard test command, **pointed at `$CONFORMANCE_TESTS_FOLDER`** (the absolute path resolved in step 3) **and at nothing else**, so it runs the whole suite in one go - and only it. The build's own tests (its unit tests, and anything else in it) are never collected: no discovery from the working folder, and no test configuration in the build (a `pytest.ini` / `pyproject.toml` `testpaths`, a Jest `roots`) allowed to widen the run beyond `$CONFORMANCE_TESTS_FOLDER`. The script's final exit code is whatever the test command returns — except for the "no tests discovered" case below.
72
70
 
73
71
  Then exit: the test command's own non-zero code when the suite failed; else `80` when only the static checks of step 7b failed; else `0`.
@@ -158,8 +156,7 @@ Shared across both shell flavors:
158
156
  - **Print the toolchain's own `--version` output** (and the path it resolved from) during step 1, even on success. This is the single most useful piece of forensic data when conformance passes on one machine but fails on another.
159
157
  - **Surface the install output verbatim** — do not pipe it to `/dev/null`, do not redirect to a log file inside the working folder. The operator must see every dependency-resolver line in the script's own output stream. Drop the `VERBOSE`-gated wrapping from the Python reference — conformance output is where forensic data is most valuable.
160
158
  - **On failure, print what was about to run before exiting** — the exact test command, the working directory, the resolved `$CONFORMANCE_TESTS_FOLDER`, and the relevant environment variables (`PYTHONPATH`, `NODE_PATH`, `GOMODCACHE`, `CARGO_HOME`, `MAVEN_OPTS`, `PATH`, plus `VIRTUAL_ENV` for Python).
161
- - **Print a final summary line** that names the test command, the exit code, the resolved conformance-tests folder, and the working folder so the operator knows exactly what to re-run by hand if needed.
162
- Verbosity is not noise here — a chatty script that documents itself in its own output is the difference between a 30-second triage and a 30-minute one. Never trade verbosity for terseness.
159
+ - **Print a final summary line** that names the test command, the exit code, the resolved conformance-tests folder, and the working folder so the operator knows exactly what to re-run by hand if needed. Verbosity is not noise here — a chatty script that documents itself in its own output is the difference between a 30-second triage and a 30-minute one. Never trade verbosity for terseness.
163
160
  - **Resolve `$2` before any `cd`.** This is the single most common bug in hand-written conformance scripts: using the conformance-tests argument after changing directory. Resolve it to an absolute path in step 3 (absolute → use as-is; relative → prefix the invocation directory) and use only the resolved variable afterwards. The resolved value must also appear in the verbose log (per the logging rule above) so misresolutions of `$2` are visible at a glance.
164
161
 
165
162
  ### Dependency isolation
@@ -72,8 +72,7 @@ Shared across both shell flavors:
72
72
  - **Print the toolchain's own `--version` output** (and the path it resolved from) during step 1, even on success. This is the single most useful piece of forensic data when a test passes locally but fails in CI.
73
73
  - **Surface the install command's output verbatim** — do not pipe it to `/dev/null`, do not redirect to a log file inside the working folder. The operator must see every dependency-resolver line in the script's own output stream.
74
74
  - **On failure, print what was about to run before exiting** — the exact command, the working directory, the relevant environment variables (`PYTHONPATH`, `NODE_PATH`, `GOMODCACHE`, `CARGO_HOME`, `MAVEN_OPTS`, `PATH`).
75
- - **Print a final summary line** that names the test command, the exit code, and the working folder so the operator knows exactly what to re-run by hand if needed.
76
- Verbosity is not noise here — a chatty script that documents itself in its own output is the difference between a 30-second triage and a 30-minute one. Never trade verbosity for terseness.
75
+ - **Print a final summary line** that names the test command, the exit code, and the working folder so the operator knows exactly what to re-run by hand if needed. Verbosity is not noise here — a chatty script that documents itself in its own output is the difference between a 30-second triage and a 30-minute one. Never trade verbosity for terseness.
77
76
 
78
77
  ### Dependency isolation
79
78