@turri-dev/cli 0.1.27 → 0.1.28-next.d5f2680

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 (216) hide show
  1. package/README.md +6 -6
  2. package/dist/advisor-chat.d.ts +63 -0
  3. package/dist/advisor-chat.js +290 -0
  4. package/dist/background-skills.d.ts +53 -0
  5. package/dist/background-skills.js +121 -0
  6. package/dist/bedrock-region.d.ts +66 -0
  7. package/dist/bedrock-region.js +144 -0
  8. package/dist/btw.d.ts +1 -1
  9. package/dist/btw.js +1 -1
  10. package/dist/change-plain-cli.js +20 -13
  11. package/dist/chat-idle.d.ts +7 -0
  12. package/dist/chat-idle.js +20 -0
  13. package/dist/chats.d.ts +10 -0
  14. package/dist/chats.js +23 -0
  15. package/dist/cli-options.d.ts +1 -2
  16. package/dist/cli-options.js +2 -7
  17. package/dist/cli.js +11 -3
  18. package/dist/config-command.d.ts +14 -0
  19. package/dist/config-command.js +35 -15
  20. package/dist/config-edit.d.ts +3 -3
  21. package/dist/config-edit.js +16 -12
  22. package/dist/config.d.ts +54 -34
  23. package/dist/config.js +40 -44
  24. package/dist/conform-cli.js +12 -10
  25. package/dist/conformance-switch.d.ts +34 -0
  26. package/dist/conformance-switch.js +108 -0
  27. package/dist/cultivate-cli.js +15 -5
  28. package/dist/drift-cli.js +2 -0
  29. package/dist/extension.d.ts +15 -0
  30. package/dist/extension.js +260 -83
  31. package/dist/host-session.d.ts +26 -0
  32. package/dist/host-session.js +30 -2
  33. package/dist/host.d.ts +5 -2
  34. package/dist/host.js +7 -1
  35. package/dist/init-config.d.ts +1 -1
  36. package/dist/init-config.js +20 -11
  37. package/dist/loop-cli.d.ts +3 -3
  38. package/dist/loop-cli.js +13 -16
  39. package/dist/loop-tools.js +18 -10
  40. package/dist/model-check.d.ts +8 -3
  41. package/dist/model-check.js +13 -8
  42. package/dist/new-project.js +12 -8
  43. package/dist/{validate-cli.js → parse-cli.js} +11 -5
  44. package/dist/parse-tool.d.ts +9 -0
  45. package/dist/parse-tool.js +33 -0
  46. package/dist/pi-launch.js +1 -1
  47. package/dist/plain/check.d.ts +53 -6
  48. package/dist/plain/check.js +217 -24
  49. package/dist/plain/concepts.d.ts +8 -0
  50. package/dist/plain/concepts.js +66 -23
  51. package/dist/plain/cycles.d.ts +21 -0
  52. package/dist/plain/cycles.js +190 -0
  53. package/dist/plain/errors.d.ts +4 -0
  54. package/dist/plain/errors.js +7 -0
  55. package/dist/plain/files.d.ts +18 -1
  56. package/dist/plain/files.js +39 -2
  57. package/dist/plain/graph.d.ts +33 -4
  58. package/dist/plain/graph.js +60 -12
  59. package/dist/plain/highlight.d.ts +3 -2
  60. package/dist/plain/highlight.js +4 -3
  61. package/dist/plain/index.d.ts +8 -5
  62. package/dist/plain/index.js +8 -5
  63. package/dist/plain/liquid.js +1 -6
  64. package/dist/plain/markdown.d.ts +32 -3
  65. package/dist/plain/markdown.js +146 -24
  66. package/dist/plain/module-concepts.js +2 -2
  67. package/dist/plain/parser.d.ts +83 -28
  68. package/dist/plain/parser.js +381 -260
  69. package/dist/plain/plain.tmLanguage.json +29 -3
  70. package/dist/plain/project.d.ts +48 -0
  71. package/dist/plain/project.js +155 -0
  72. package/dist/plain/spec.d.ts +90 -28
  73. package/dist/plain/spec.js +107 -133
  74. package/dist/plain/test-plain-file.d.ts +59 -0
  75. package/dist/plain/test-plain-file.js +232 -0
  76. package/dist/regenerate/activity.d.ts +20 -9
  77. package/dist/regenerate/activity.js +11 -4
  78. package/dist/regenerate/advisor-records.d.ts +93 -0
  79. package/dist/regenerate/advisor-records.js +110 -0
  80. package/dist/regenerate/advisor-runs.d.ts +87 -0
  81. package/dist/regenerate/advisor-runs.js +327 -0
  82. package/dist/regenerate/base-folder.d.ts +68 -0
  83. package/dist/regenerate/base-folder.js +168 -0
  84. package/dist/regenerate/cases.d.ts +9 -6
  85. package/dist/regenerate/cases.js +70 -14
  86. package/dist/regenerate/change-view.d.ts +8 -3
  87. package/dist/regenerate/change-view.js +71 -22
  88. package/dist/regenerate/chunk-plan.d.ts +36 -15
  89. package/dist/regenerate/chunk-plan.js +165 -59
  90. package/dist/regenerate/conform.d.ts +3 -0
  91. package/dist/regenerate/conform.js +6 -5
  92. package/dist/regenerate/conformance-agents.d.ts +18 -39
  93. package/dist/regenerate/conformance-agents.js +60 -88
  94. package/dist/regenerate/conformance.d.ts +23 -13
  95. package/dist/regenerate/conformance.js +119 -82
  96. package/dist/regenerate/diff-view.d.ts +1 -1
  97. package/dist/regenerate/diff-view.js +20 -4
  98. package/dist/regenerate/drift.d.ts +47 -15
  99. package/dist/regenerate/drift.js +101 -30
  100. package/dist/regenerate/jobs.d.ts +2 -2
  101. package/dist/regenerate/jobs.js +1 -1
  102. package/dist/regenerate/ledger.d.ts +19 -0
  103. package/dist/regenerate/loop.d.ts +62 -43
  104. package/dist/regenerate/loop.js +472 -341
  105. package/dist/regenerate/paths.d.ts +4 -0
  106. package/dist/regenerate/paths.js +7 -1
  107. package/dist/regenerate/plain-palette.js +2 -0
  108. package/dist/regenerate/prompt.d.ts +57 -19
  109. package/dist/regenerate/prompt.js +157 -122
  110. package/dist/regenerate/records.d.ts +43 -12
  111. package/dist/regenerate/records.js +102 -88
  112. package/dist/regenerate/regenerate.js +29 -11
  113. package/dist/regenerate/regression.d.ts +4 -4
  114. package/dist/regenerate/regression.js +14 -10
  115. package/dist/regenerate/renames.d.ts +42 -0
  116. package/dist/regenerate/renames.js +185 -0
  117. package/dist/regenerate/requires.d.ts +1 -1
  118. package/dist/regenerate/requires.js +10 -3
  119. package/dist/regenerate/resources.d.ts +5 -3
  120. package/dist/regenerate/resources.js +4 -4
  121. package/dist/regenerate/scripts-being-written.d.ts +19 -0
  122. package/dist/regenerate/scripts-being-written.js +30 -0
  123. package/dist/regenerate/spec-map-view.d.ts +2 -2
  124. package/dist/regenerate/spec-map-view.js +46 -15
  125. package/dist/regenerate/spec-map.d.ts +27 -5
  126. package/dist/regenerate/spec-map.js +92 -60
  127. package/dist/regenerate/spec-steps.d.ts +48 -5
  128. package/dist/regenerate/spec-steps.js +213 -28
  129. package/dist/regenerate/state.d.ts +4 -3
  130. package/dist/regenerate/stop-report.d.ts +1 -1
  131. package/dist/regenerate/stop-report.js +10 -10
  132. package/dist/regenerate/test-advisor.d.ts +101 -0
  133. package/dist/regenerate/test-advisor.js +379 -0
  134. package/dist/regenerate/test-kinds.d.ts +71 -28
  135. package/dist/regenerate/test-kinds.js +110 -63
  136. package/dist/regenerate/test-scripts.d.ts +2 -0
  137. package/dist/regenerate/test-scripts.js +4 -0
  138. package/dist/regenerate/testing-steps.d.ts +41 -0
  139. package/dist/regenerate/testing-steps.js +110 -0
  140. package/dist/regenerate/testing.d.ts +1 -1
  141. package/dist/regenerate/testing.js +5 -4
  142. package/dist/regenerate/unit-review.d.ts +1 -1
  143. package/dist/regenerate/unit-review.js +3 -3
  144. package/dist/regenerate-cli.js +11 -12
  145. package/dist/release-agent.js +4 -0
  146. package/dist/release-cli.js +2 -0
  147. package/dist/release-tools.js +2 -0
  148. package/dist/run-report.d.ts +2 -2
  149. package/dist/run-report.js +4 -3
  150. package/dist/self-invocation.d.ts +1 -1
  151. package/dist/self-invocation.js +1 -1
  152. package/dist/sentinel.js +1 -1
  153. package/dist/setup.d.ts +10 -0
  154. package/dist/setup.js +52 -4
  155. package/dist/skill.d.ts +10 -0
  156. package/dist/skill.js +6 -0
  157. package/dist/skills.js +3 -1
  158. package/dist/spec-tools.js +21 -31
  159. package/dist/test-plain-files.d.ts +41 -0
  160. package/dist/test-plain-files.js +177 -0
  161. package/docs/README.md +3 -1
  162. package/docs/authoring-plain.md +46 -13
  163. package/docs/chats.md +3 -1
  164. package/docs/config.md +20 -15
  165. package/docs/deploy.md +1 -1
  166. package/docs/development.md +2 -1
  167. package/docs/headless.md +15 -18
  168. package/docs/hosting.md +28 -12
  169. package/docs/installation.md +1 -0
  170. package/docs/parser.md +88 -27
  171. package/docs/regenerating.md +87 -52
  172. package/docs/sentinel.md +1 -1
  173. package/docs/skills-and-gates.md +3 -1
  174. package/docs/test-advisor.md +110 -0
  175. package/docs/theming.md +1 -1
  176. package/docs/using.md +17 -15
  177. package/genome/rules/bullet-continuation.md +8 -8
  178. package/genome/rules/concise-specs-examples.md +111 -80
  179. package/genome/rules/concise-specs-integration-examples.md +56 -41
  180. package/genome/rules/concise-specs.md +17 -16
  181. package/genome/rules/definitions.md +5 -5
  182. package/genome/rules/examples/integration-embedded-testing/run_conformance_tests_java.sh +1 -1
  183. package/genome/rules/func-specs.md +69 -74
  184. package/genome/rules/impl-reqs.md +4 -4
  185. package/genome/rules/integration-embedded-testing.md +20 -20
  186. package/genome/rules/integration-embedded.md +31 -31
  187. package/genome/rules/integration-standalone.md +9 -9
  188. package/genome/rules/integrations.md +18 -18
  189. package/genome/rules/linked-resources.md +19 -16
  190. package/genome/rules/module-structure.md +21 -14
  191. package/genome/rules/project-model.md +18 -17
  192. package/genome/rules/required-concepts.md +1 -1
  193. package/genome/rules/requires-modules.md +6 -5
  194. package/genome/rules/semantic-ids.md +49 -0
  195. package/genome/rules/stdlib.md +4 -5
  196. package/genome/rules/test-plain-files.md +130 -0
  197. package/genome/rules/test-reqs.md +8 -8
  198. package/genome/rules/turri-regeneration.md +23 -8
  199. package/genome/skills/analyze-2-func-specs/SKILL.md +36 -21
  200. package/genome/skills/analyze-func-specs/SKILL.md +46 -32
  201. package/genome/skills/break-down-func-spec/SKILL.md +91 -67
  202. package/genome/skills/consolidate-concepts/SKILL.md +10 -10
  203. package/genome/skills/convert-old-syntax/SKILL.md +68 -0
  204. package/genome/skills/convert-old-syntax/references/rubric.md +11 -0
  205. package/genome/skills/debug-specs/SKILL.md +62 -56
  206. package/genome/skills/implement-conformance-testing-script/SKILL.md +19 -15
  207. package/genome/skills/implement-conformance-testing-script/assets/run_conformance_tests_java.sh +2 -2
  208. package/genome/skills/implement-conformance-testing-script/assets/run_conformance_tests_python.sh +2 -2
  209. package/genome/skills/implement-unit-testing-script/SKILL.md +14 -10
  210. package/genome/skills/refactor-module/SKILL.md +35 -35
  211. package/genome/skills/resolve-section-ownership/SKILL.md +9 -9
  212. package/genome/skills/resolve-spec-conflict/SKILL.md +35 -29
  213. package/package.json +7 -6
  214. package/dist/regenerate/choose-conformance.d.ts +0 -32
  215. package/dist/regenerate/choose-conformance.js +0 -117
  216. /package/dist/{validate-cli.d.ts → parse-cli.d.ts} +0 -0
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: The ***plain project model - the specs as source of truth, the repository layout, generated output, template parameters, and what an earlier test failing after a render means
2
+ description: The ***plain project model - the ***plain as source of truth, the repository layout, generated output, template parameters, and what an earlier test failing after a regeneration means
3
3
  ---
4
4
 
5
5
  # The ***plain project model
@@ -9,28 +9,29 @@ This rule covers the project as a whole. Section content is owned by the per-sec
9
9
  ## Source of truth
10
10
 
11
11
  - The `.plain` files are the source of truth. They state what the software does, how it is built, and how it is tested; the code is generated from them
12
- - Every change to the software is a change to a `.plain` file, which the next render builds. A fix made anywhere else is lost the next time the code is regenerated
12
+ - Every change to the software is a change to a `.plain` file, which the next regeneration builds. A fix made anywhere else is lost the next time the code is regenerated
13
13
 
14
14
  ## Repository layout
15
15
 
16
16
  ```text
17
17
  *.plain # root modules: what the software does
18
18
  template/*.plain # import modules: shared definitions and reqs
19
- resources/ # files specs link to: schemas, API specs, fixtures
19
+ tests/<module>/<func-id>.plain # test plain files: the scenarios of each functional spec
20
+ resources/ # files ***plain links to: schemas, API specs, fixtures
20
21
  test_scripts/ # unit and conformance runners, found by turri (not linked)
21
- config.turri.yaml # the project's build decisions: models, conformance tests, the scripts in use
22
+ config.turri.yaml # the project's build decisions: models, the scripts in use
22
23
  plain_modules/ # generated - one folder per module
23
24
  <module>/code/ # implementation and unit tests
24
25
  <module>/tests/ # the whole conformance suite of the module
25
26
  ```
26
27
 
27
- Follow `module-structure.md`, `import-modules.md` and `linked-resources.md` for what these directories may contain and how a spec refers to them.
28
+ Follow `module-structure.md`, `import-modules.md` and `linked-resources.md` for what these directories may contain and how ***plain refers to them.
28
29
 
29
30
  ## The config records the build decisions
30
31
 
31
- `config.turri.yaml`, at the project root beside the specs, is where the project's decisions about how it is built live: the models, whether conformance tests are written (`conformance-tests:`), and the scripts it uses (`unittests-script:`, `conformance-tests-script:`, `prepare-environment-script:`). turri can find a script by its name, but the config is what a person reads to see how the project is set up, and what they change.
32
+ `config.turri.yaml`, at the project root beside the ***plain, is where the project's decisions about how it is built live: the models, and the scripts it uses (`unittests-script:`, `conformance-tests-script:`, `prepare-environment-script:`). turri can find a script by its name, but the config is what a person reads to see how the project is set up, and what they change.
32
33
 
33
- - Settle a decision, write it into the config in the same step - never leave it to be inferred from what is on disk. A testing script you write or keep is named by its key, by path from the root (`unittests-script: test_scripts/run_unittests_python.sh`); conformance tests turned on or off are `conformance-tests: true` or `false`
34
+ - Settle a decision, write it into the config in the same step - never leave it to be inferred from what is on disk. A testing script you write or keep is named by its key, by path from the root (`unittests-script: test_scripts/run_unittests_python.sh`)
34
35
  - Change only the keys you settled. Where the file has a key's example commented out, uncomment that line and set it; keep every other line and comment as it is
35
36
  - A project whose parts are on different stacks keeps each stack's scripts in its own `config.turri.<stack>.yaml` beside it; what the stacks share stays in `config.turri.yaml`
36
37
  - A project with only a `config.yaml` has it copied to `config.turri.yaml` first, and each `config.<name>.yaml` to `config.turri.<name>.yaml`; `config.yaml` may be another tool's, and is never written
@@ -38,13 +39,13 @@ Follow `module-structure.md`, `import-modules.md` and `linked-resources.md` for
38
39
 
39
40
  ## Generated output is read-only
40
41
 
41
- Everything under `plain_modules/` is generated - `code/` and `tests/` alike. Read it, run it, debug it; never edit it. Fix the spec instead, in the section that owns the fact:
42
+ Everything under `plain_modules/` is generated - `code/` and `tests/` alike. Read it, run it, debug it; never edit it. Fix the ***plain instead, in the section that owns the fact:
42
43
 
43
44
  - behaviour, implementation or unit-test guidance → definitions, functional specs, or implementation reqs
44
- - conformance-test guidance → test reqs
45
- - acceptance-test guidance → the acceptance tests nested under their functional spec
45
+ - how conformance and acceptance tests are written and run → test reqs
46
+ - what a conformance or acceptance test checks → the scenarios in its functional spec's test plain file (`test-plain-files.md`)
46
47
 
47
- Then render again.
48
+ Then regenerate.
48
49
 
49
50
  ## Template inclusion with parameters
50
51
 
@@ -56,12 +57,12 @@ Besides frontmatter `import`, a template can be included with parameters:
56
57
 
57
58
  Parameters are key-value pairs; the template reads them as `{{ variable_name }}`. Templates live in `template/`. One is worth writing only for text more than one `.plain` file repeats, differing only in values the parameters carry; text used once stays inline.
58
59
 
59
- ## When an earlier test fails after a render
60
+ ## When an earlier test fails after a regeneration
60
61
 
61
- Each functional spec is written knowing the ones before it and none after it - a required module's specs count as before - so a spec may rely on what earlier ones say, never on later ones. This is about what a spec may assume, not what a change costs (`turri-regeneration.md`). After each render every conformance test so far runs again. A test that passed before and fails now means one of:
62
+ Each functional spec is written knowing the ones before it and none after it - a required module's functional specs count as before - so a functional spec may rely on what earlier ones say, never on later ones. This is about what a functional spec may assume, not what a change costs (`turri-regeneration.md`). After each regeneration every conformance test so far runs again. A test that passed before and fails now means one of:
62
63
 
63
- 1. the new code does not satisfy its spec;
64
- 2. the test does not test its spec accurately;
65
- 3. the new spec and an earlier one conflict.
64
+ 1. the new code does not satisfy its functional spec;
65
+ 2. the test does not test its scenario accurately;
66
+ 3. the new functional spec and an earlier one conflict.
66
67
 
67
- The harness triages the first two and repairs the code. The third is a spec problem: resolve it in the `.plain` files with `resolve-spec-conflict`, and trace a misbehaving build back to its spec with `debug-specs` - never by editing generated output.
68
+ turri triages the first two and repairs the code. The third is a problem in the ***plain: resolve it in the `.plain` files with `resolve-spec-conflict`, and trace a misbehaving build back to its ***plain with `debug-specs` - never by editing generated output.
@@ -17,7 +17,7 @@ When adding or editing `required_concepts` in a `.plain` file's frontmatter, alw
17
17
 
18
18
  ## Importing module must satisfy the contract
19
19
  - Every concept listed in `required_concepts` must be defined somewhere visible to the importing module — in its own `***definitions***` section or in another module it imports
20
- - If the importing module does not define a required concept, the spec is invalid
20
+ - If the importing module does not define a required concept, the module is invalid
21
21
  - Check `required_concepts` of all imported modules before finalizing a module
22
22
 
23
23
  ## Do not define required concepts locally
@@ -13,6 +13,7 @@ When creating or editing a `.plain` file that uses `requires`, or one that is re
13
13
  - The `***functional specs***` of the required module **and of all its ancestors** become visible as **previous functional specs** — this visibility **is transitive** down the whole chain
14
14
  - Of a required module's definitions, only the concepts listed in its `exported_concepts` are visible; the module's other definitions stay internal. Each exported concept arrives with its full definition text
15
15
  - Export visibility **is not transitive**: an ancestor's exports are visible only if that ancestor is itself listed in `requires`
16
+ - The test plain files of a required module stay with that module; the current module never holds scenarios for a required module's functional spec (see `test-plain-files.md`)
16
17
 
17
18
  ## Chain topology
18
19
 
@@ -24,7 +25,7 @@ When creating or editing a `.plain` file that uses `requires`, or one that is re
24
25
 
25
26
  ## Tech stack must match (hard rule)
26
27
 
27
- - Because the required module's generated code is copied as the starting point and the renderer continues building on top of it with a single toolchain, two modules can only be linked with `requires` when they target the **same language, framework, and runtime**
28
+ - Because the required module's generated code is copied as the starting point and the coding agent continues building on top of it with a single toolchain, two modules can only be linked with `requires` when they target the **same language, framework, and runtime**
28
29
  - A runtime / network dependency between systems is **not** a reason to use `requires`
29
30
  - Example of the mistake: a React frontend that talks to a Python/FastAPI backend over HTTP must **not** `requires: [backend]` — the stacks differ
30
31
  - Model that pair as two independent root modules (each with its own test scripts) and express the contract through a shared API schema in `resources/` or shared concepts in an `import`ed module — never through `requires`
@@ -33,12 +34,12 @@ When creating or editing a `.plain` file that uses `requires`, or one that is re
33
34
 
34
35
  - The current module does not need to functionally extend the required module — it may address a completely different concern
35
36
  - Even so, the two are never independent artifacts: the current module's output physically contains the required module's code, because both are stages of one accumulating codebase
36
- - Use `requires` to place a module at the right point in that lineage, whether or not it builds on the required module's functionality
37
+ - Use `requires` to place a module at the right point in that lineage, whether or not it builds on the required module's functional specs
37
38
 
38
39
  ## Conflict prevention
39
40
 
40
- - The current module's functional specs must not conflict with the specs of **any module in its ancestor chain** — all of them are previous functional specs
41
- - The renderer sees the whole chain's specs as prior requirements/context when rendering the current module
41
+ - The current module's functional specs must not conflict with the functional specs of **any module in its ancestor chain** — all of them are previous functional specs
42
+ - The coding agent sees the whole chain's functional specs as prior requirements/context when regenerating the current module
42
43
  - Review the ancestor chain's functional specs before adding new ones
43
44
 
44
45
  ## Exports are the only visible definitions
@@ -51,7 +52,7 @@ When creating or editing a `.plain` file that uses `requires`, or one that is re
51
52
 
52
53
  ## File locations
53
54
 
54
- - Modules that use `requires` live at the **repository root** — they are functional modules with specs
55
+ - Modules that use `requires` live at the **repository root** — they are functional modules with functional specs
55
56
  - `requires` paths point to other root-level modules (e.g., `auth`, `messaging`)
56
57
  - Never `require` an import module — import modules are for `import` only
57
58
 
@@ -0,0 +1,49 @@
1
+ ---
2
+ description: Syntax, uniqueness and use of func-ids and scenario-ids in .plain files
3
+ ---
4
+
5
+ # Rules for func-ids and scenario-ids
6
+
7
+ Every functional spec in `***functional specs***` and every scenario in a test plain file carries an id: its name, given by the author and never by its position. turri knows a functional spec by its func-id - in the code record, in its pulses, in the conformance tests' labels and in what it tells the person - and a scenario by its scenario-id. Always follow these rules when writing or reading one.
8
+
9
+ ## Two kinds of id
10
+
11
+ | id | Written as | Names | Unique within |
12
+ |---|---|---|---|
13
+ | func-id | a `# <func-id>` heading in `***functional specs***` of a module | one functional spec | its module |
14
+ | scenario-id | a `# <scenario-id>` heading in `***conformance tests***` or `***acceptance tests***` of a test plain file | one scenario | its functional spec, across every test plain file bound to it |
15
+
16
+ ## Syntax
17
+ - Lowercase letters, digits and hyphens only: `add-task`, `export-csv-2`, `ctrl-d-exit`
18
+ - The heading is `# ` (a hash and one space) followed by the id and nothing else
19
+ - Make the id short kebab-case from what the functional spec or scenario means (`add-task`, never `spec-3`)
20
+
21
+ ## Uniqueness
22
+ - A func-id is unique in its module; two modules may use the same func-id
23
+ - A scenario-id is unique among its functional spec's scenarios, once every test plain file bound to it is merged; two functional specs may use the same scenario-id
24
+ - Before adding an id, search the module (or the functional spec's test plain files) for the same heading; a duplicate is an error `turri parse` reports
25
+
26
+ ## Stability
27
+ - An id is an identity, not a label: a functional spec keeps its func-id for as long as it exists, even when its text changes
28
+ - A pure rename is cheap: a func-id renamed with nothing else changed - its body, its links and its scenarios as they were, only the `# <func-id>` heading and `func_id:` in its test plain files - is renamed by turri in its records and its tests' labels, and nothing is regenerated. The same holds for a scenario-id renamed with its text as it was
29
+ - A rename together with any other change rebuilds: to turri it is one functional spec taken out and another added, its code built anew and its tests written anew (`turri-regeneration.md`). So rename in a ***plain diff of its own, never in the same edit as a change to the body or the scenarios
30
+ - Rename only when the person asks, then rename `func_id:` in every test plain file bound to it, and the file with it
31
+ - Never renumber or reorder ids: the order of the headings in the module is the order of its functional specs, and the id carries no order
32
+
33
+ ## Naming a functional spec
34
+ - Name a functional spec by its func-id - `<module>:<func-id>` outside its module (`todo:add-task`) - in questions to the person, in what you show them and in turri's tools; never by its position ("the third functional spec")
35
+ - Pick the func-id before writing the functional spec, check that it is unique in the module, then write the heading and the body (see `func-specs.md`)
36
+ - Everything about one functional spec is found through its func-id: its heading, the test plain files whose frontmatter names it, and the conformance tests labelled with it
37
+ - A conformance or acceptance test carries the scenario-id of the scenario it implements: when one fails, its label leads back to the scenario
38
+
39
+ ## Format
40
+
41
+ ```plain
42
+ ***functional specs***
43
+
44
+ # add-task
45
+ A :User: can add a :Task:. Only valid :Task: items are added.
46
+
47
+ # delete-task
48
+ A :User: can delete a :Task:.
49
+ ```
@@ -10,7 +10,6 @@ turri ships a standard library of import modules that settle everything about a
10
10
  ---
11
11
  import:
12
12
  - stdlib/backend/python-flask
13
- - stdlib/backend/conformance/python-flask
14
13
  ---
15
14
  ```
16
15
 
@@ -24,15 +23,15 @@ import:
24
23
 
25
24
  - When the person wants a backend, a frontend, a command-line tool or a library, import the stack that fits instead of writing its implementation reqs yourself.
26
25
  - Pick the stack from what the person said, the project's other modules, and what the module talks to. With nothing to go on: `stdlib/backend/python-fastapi`, `stdlib/frontend/react-vite`, `stdlib/cli/python-typer`, `stdlib/library/python`.
27
- - Import the conformance template only when the module has conformance tests - the person asked for them, and the project's config does not turn them off (`conformance-tests: false`). Without it the module has no test reqs, and no conformance tests are written or run for it. Turning them on later is adding that one import.
28
- - Read the templates a module imports before writing its specs - the folder is named below - and write no requirement they already make (see `concise-specs.md`).
26
+ - Import the stack alone. Nothing about testing exists until the person asks for it: the first time they ask for tests in a module, import the stack's conformance template, `stdlib/<kind>/conformance/<stack>` - the module's test reqs - then write the conformance testing script if the project has none for the stack, then the scenarios, in that order (*Writing scenarios* in `test-plain-files.md`).
27
+ - Read the templates a module imports before writing its ***plain - the folder is named below - and write no requirement they already make (see `concise-specs.md`).
29
28
  - Write a functional spec's errors in the templates' terms: a backend's failure by its status and `error.code` - `not_found`, `conflict`, `validation_error`, `unauthenticated`, `forbidden`, or a code of the module's own - and a command-line tool's by its exit code and message.
30
29
  - Add a requirement on top for what the module needs beyond its stack - storage, an outside service, a library it must use. When the module differs from its stack on something the stack settles - another framework, another layout - write the stack yourself instead: an import cannot be taken back in part. For a language with no stack of the kind wanted, import its `stdlib/lang/<language>` and write the rest.
31
- - `stdlib/` is a reserved name. An import that starts with it is always the standard library's template, and a project module at such a path - `stdlib/backend/python-fastapi.plain` in the spec's folder, its `template/` folder or `PLAIN_TEMPLATE_DIRS` - is an error. Never write a module under a `stdlib/` folder of the project; a project's own shared template goes in `template/` under a name of its own.
30
+ - `stdlib/` is a reserved name. An import that starts with it is always the standard library's template, and a project module at such a path - `stdlib/backend/python-fastapi.plain` in the module's folder, its `template/` folder or `PLAIN_TEMPLATE_DIRS` - is an error. Never write a module under a `stdlib/` folder of the project; a project's own shared template goes in `template/` under a name of its own.
32
31
 
33
32
  ## What it does not do
34
33
 
35
34
  - It defines no concepts: its requirements are on the predefined `:Implementation:`, `:UnitTests:` and `:ConformanceTests:` only, so it never collides with the module's own definitions.
36
35
  - It holds no storage: a module with a database says which, and how it is reached, on top.
37
- - It holds no testing scripts. The module still needs its unit testing script, and its conformance testing script when it has conformance tests - written with the `implement-unit-testing-script` and `implement-conformance-testing-script` skills for the stack's language and test framework. Each runs the static checks of what it tests - the formatter, linter and type checker its language template names, on the code or on the conformance tests - and they count as the tests do.
36
+ - It holds no testing scripts. The module still needs its unit testing script, written with the `implement-unit-testing-script` skill for the stack's language and test framework; its conformance testing script is written with `implement-conformance-testing-script` when its first tests are asked for. Each runs the static checks of what it tests - the formatter, linter and type checker its language template names, on the code or on the conformance tests - and they count as the tests do.
38
37
  - It names its stack's toolchain - Python 3.12, Node.js 24, Java 21, Go 1.25, Rust - which the agents use from the machine turri runs on; they install none, so `turri doctor` says when the machine lacks it.
@@ -0,0 +1,130 @@
1
+ ---
2
+ description: Test plain files - where they live, their two sections, their scenarios, keeping them in step with the functional specs, and writing scenarios when the person asks for tests
3
+ ---
4
+
5
+ # Rules for test plain files
6
+
7
+ A test plain file holds the test scenarios of one functional spec. Conformance scenarios test its expected use; acceptance scenarios, the use that is not expected. The conformance agent writes the conformance and acceptance tests from these scenarios and from nothing else: each scenario becomes at least one test that does what it says, and it invents none. A functional spec whose test plain file is empty is not tested. Always follow these rules when creating or editing one.
8
+
9
+ ## Where it lives
10
+ - Every test plain file of a module lives in `tests/<module>/`, with `tests/` beside the module (`test-dir:` in `config.turri.yaml` can name another folder). This is a rule, not a convention: a file's folder matches its `module:`, and a `.plain` file in `tests/` outside a module's folder is an error `turri parse` reports
11
+ - Name the file after its functional spec, `tests/<module>/<func-id>.plain`; the name is convention, the frontmatter is what binds it
12
+ - A functional spec with no scenarios has no test plain file: it is not tested. Write one only to give a functional spec scenarios, and never an empty one - an empty file is a syntax error, as an empty section is
13
+ - When turri's test advisor's yes arrives for a functional spec, you add its test plain file, with the test reqs and conformance testing script it needs (see `turri-regeneration.md`) - as below, asking nothing
14
+ - More than one test plain file may bind to one functional spec: their scenarios are merged, and the scenario-ids must be unique across them. Write one file per functional spec, and keep a person's extra files as they are
15
+ - A test plain file is never a module: never import or require one, and never name one where a module is asked for
16
+
17
+ ## File skeleton
18
+ - YAML frontmatter, then `***conformance tests***`, then `***acceptance tests***`, each section heading at the start of a line
19
+ - A section is there only with at least one scenario under it: a section with none is a syntax error - leave it out. A file with no section at all is one too: a functional spec with no scenarios has no test plain file
20
+ - The frontmatter has exactly two keys, both required:
21
+ - `module:` - the module the functional spec is in: its file name without `.plain`
22
+ - `func_id:` - the functional spec's func-id (see `semantic-ids.md`)
23
+ - The two must name a functional spec that exists
24
+ - No other section: no `***definitions***`, `***implementation reqs***`, `***test reqs***` or `***functional specs***`
25
+ - Comment lines starting with `>` are allowed, as in a module
26
+
27
+ The minimum - one scenario, its section alone:
28
+
29
+ ```plain
30
+ ---
31
+ module: todo
32
+ func_id: add-task
33
+ ---
34
+
35
+ ***conformance tests***
36
+
37
+ # add-valid-task
38
+ Adding a :Task: named "Buy milk" to an empty :TaskList: shows one :Task: named "Buy milk".
39
+ ```
40
+
41
+ ## Scenarios
42
+ - A scenario is a `# <scenario-id>` heading (see `semantic-ids.md`) followed by free text that says what is done and what result is expected
43
+ - No line of its body starts with `# ` (that starts the next scenario) or with `***`
44
+ - A scenario may use every concept its module sees: its own definitions, its `import` modules' and the `exported_concepts` of its `requires` modules. It defines none
45
+ - Scenarios are language-agnostic and black box: they act through the interface the functional spec names - a command line, HTTP, files, a UI - and never name a function, class or file of the code
46
+ - A scenario is a direct consequence of its functional spec: it does not contradict, narrow or extend it
47
+ - Each scenario states one concrete, checkable outcome; "works correctly" is not an outcome
48
+ - Values that matter to the check are concrete (`named "Buy milk"`, `exits with status 0`), never descriptive (`a valid name`)
49
+ - Scenario text follows `concise-specs.md`: no narration, no rationale, no step a reader would assume
50
+ - `***conformance tests***` holds the expected use: the main path, with valid input, the expected caller and the data present
51
+ - `***acceptance tests***` holds the use that is not expected: invalid input, wrong or missing authentication, missing data, a dependency that fails
52
+ - The kind of use decides the section, not how many functional specs a scenario touches
53
+
54
+ ## Scenarios across functional specs
55
+ - A scenario may use functional specs written before the one it is bound to, for its setup or as steps of a longer path
56
+ - It is bound to the last functional spec it exercises, since the earlier ones exist when it runs
57
+ - It goes under `***conformance tests***` when every step is expected use, and under `***acceptance tests***` when any step is not; write one only when the person asks for it
58
+
59
+ ## Keeping test plain files in step
60
+ Only scenarios that exist are kept in step: a change to a functional spec never calls for new ones. In the same ***plain diff as the change:
61
+ - A new functional spec gets no test plain file, unless the person asks for its tests
62
+ - A functional spec whose body changes has its scenarios, if it has any, reviewed: one that no longer follows from it is changed or taken out, and your reply says so
63
+ - The last scenario of a section taken out: the section is taken out with it. The last scenario of the file: the file is deleted
64
+ - A functional spec split into several: each part gets its own test plain file, and each scenario moves to the part it tests
65
+ - A functional spec taken out: its test plain file, if it has one, is deleted
66
+ - A functional spec moved to another module: its test plain file moves to that module's folder, with `module:` changed
67
+ - A func-id renamed: `func_id:` is renamed in every test plain file bound to it, and the file with it
68
+
69
+ ## Writing scenarios
70
+ Nothing about testing exists until the person asks for it, or the test advisor's yes arrives: a module imports no conformance template, and its functional specs have no test plain files. The first time the person asks for tests in a module, or the advisor's yes arrives for one of its functional specs, do three things, in this order, each a visible change - only what is missing:
71
+ 1. **Test reqs:** import the stack's conformance template, `stdlib/<kind>/conformance/<stack>` (see `stdlib.md`), or write the module's own `***test reqs***` when it has no stack from the standard library (see `test-reqs.md`)
72
+ 2. **The conformance testing script:** write it with `implement-conformance-testing-script`, if the project has none for the module's stack
73
+ 3. **The scenarios**, as below
74
+
75
+ Then, and for every later request:
76
+ - Decide in prose which scenarios each functional spec named needs, then write them with `change_plain`, conformance and acceptance in one change where both were asked for. Ask for no further confirmation: the change is visible, and turri starts the conformance pulses itself
77
+ - Write scenarios only for the functional specs the person named. Scenarios in one functional spec imply nothing about another, in the same module or not: the person may test one thoroughly and leave the rest untested
78
+ - Write acceptance scenarios only when the person asks for them
79
+ - On the test advisor's yes, the functional spec it names is named, and its report says what to cover: each input that is this functional spec's, an agreed one with the readers' output and never a placeholder, a split one by the reading most consistent with the functional spec and its module - say which you took. Leave out an input it does not settle rather than ask; ask the person nothing
80
+ - One conformance scenario per expected use the functional spec states: its main path first, then each valid variant it names - another input shape, an optional parameter. Stop when each has one, and never write the same outcome twice in different words
81
+ - Write no outcome the functional spec does not state. When a needed one is missing, ask the person, and put the answer in the functional spec first
82
+ - A scenario that needs a dependency to fail - a backend that does not answer, a database that is down - is written only when the test reqs let a test cause that failure, with a local mock of it, say; otherwise ask the person whether to add such a test req or leave the scenario out
83
+ - The body is one statement line naming the action and its expected result, with concrete values; when that is not enough, `- ` bullets under it, in order: the state before, the one action under test, then each observable result, one fact a bullet
84
+ - A framework, a run command or a network policy belongs in `***test reqs***`, never in a scenario
85
+
86
+ ```plain
87
+ Functional spec:
88
+ # list-resources
89
+ :Resource: items are returned sorted by creation date in descending order.
90
+
91
+ Good - follows from the functional spec:
92
+ # newest-first
93
+ After three :Resource: items are created one after another, listing them returns the last one created first.
94
+
95
+ Bad - contradicts it (the functional spec says descending):
96
+ # oldest-first
97
+ The first :Resource: listed is the oldest.
98
+
99
+ Bad - extends it (the functional spec says nothing about a limit):
100
+ # at-most-fifty
101
+ At most 50 :Resource: items are listed.
102
+ ```
103
+
104
+ The conformance agent writes exactly the scenarios: each one becomes at least one test, labelled with its scenario-id, and no test is written from the functional spec itself or invented beside them.
105
+
106
+ ## Relation to `***test reqs***`
107
+ - The module's `***test reqs***` - its own, or a conformance template's - say how `:ConformanceTests:` and `:AcceptanceTests:` are written and run: framework, command, network policy. The scenarios say what they check
108
+ - Test reqs and scenarios reach the conformance agent only, never the coding agent
109
+ - A fact about the framework or the run command never goes into a scenario, and a scenario never goes into `***test reqs***`
110
+
111
+ ## Format
112
+
113
+ ```plain
114
+ ---
115
+ module: todo
116
+ func_id: add-task
117
+ ---
118
+
119
+ ***conformance tests***
120
+
121
+ # add-valid-task
122
+ Adding a :Task: named "Buy milk" to an empty :TaskList: shows one :Task: named "Buy milk".
123
+
124
+ ***acceptance tests***
125
+
126
+ # reject-short-name
127
+ Adding a :Task: named "Go" to an empty :TaskList: is rejected.
128
+ - :App: shows the error "Name must be at least 3 characters".
129
+ - :TaskList: stays empty.
130
+ ```
@@ -9,15 +9,15 @@ When writing or editing a `***test reqs***` section in a `.plain` file, always f
9
9
  ## Conformance tests only
10
10
  - Test reqs specify how **conformance tests** should be written and run
11
11
  - Unit test guidance goes in `***implementation reqs***`, not here
12
- - Acceptance tests are nested under individual functional specs, not here
12
+ - Test scenarios, conformance and acceptance, live in test plain files, not here - see `test-plain-files.md`
13
13
  - Behavioral requirements go in `***functional specs***`, not here
14
14
 
15
15
  ## `:ConformanceTests:` lives here (hard rule)
16
16
  - **Everything** about `:ConformanceTests:` goes in `***test reqs***` — paths, approach, packages, framework, execution command, mocking / network policy, fixtures, pass criteria, environment prerequisites
17
17
  - `:ConformanceTests:` live outside the generated codebase, in one folder, `plain_modules/<module>/tests/` - the module's whole conformance suite, so requirements that shape them belong in test reqs by definition
18
- - The conformance-test generator reads **only** `***test reqs***` — anything about `:ConformanceTests:` placed elsewhere (e.g. `***implementation reqs***`) is silently ignored
18
+ - The conformance agent reads how to write and run the tests **only** from `***test reqs***` — anything about `:ConformanceTests:` placed elsewhere (e.g. `***implementation reqs***`) is silently ignored
19
19
  - Phrase each `:ConformanceTests:` requirement in terms of `:ConformanceTests:` so the partition stays visible at a glance
20
- - Do not link the conformance testing script here (or anywhere in the specs; a link to it is ignored). turri finds it in the project root - `conformance-tests-script:` in `config.turri.yaml`, else the one `run_conformance_tests*.sh` in the root, else the one in `test_scripts/` - and shows it to the agents that write the conformance tests itself. Describe the framework and execution command here in words
20
+ - Do not link the conformance testing script here (or anywhere in the ***plain; a link to it is ignored). turri finds it in the project root - `conformance-tests-script:` in `config.turri.yaml`, else the one `run_conformance_tests*.sh` in the root, else the one in `test_scripts/` - and shows it to the agents that write the conformance tests itself. Describe the framework and execution command here in words
21
21
 
22
22
  ## What belongs here
23
23
  - Test framework: which framework to use (e.g., pytest, Unittest, xUnit)
@@ -28,11 +28,11 @@ When writing or editing a `***test reqs***` section in a `.plain` file, always f
28
28
 
29
29
  ## Test type reference
30
30
 
31
- | Test type | Where to specify | Generated | Purpose |
32
- |-----------|-----------------|-----------|---------|
33
- | Unit tests | `***implementation reqs***` | Automatically | Test individual functionalities in isolation |
34
- | Conformance tests | `***test reqs***` | Automatically | Verify each functionality's implementation against its functional spec |
35
- | Acceptance tests | `***acceptance tests***` under a functional spec | Manually | Verify implementation of a functional spec through a specific end-to-end scenario |
31
+ | Test type | Where to specify | Written from | Purpose |
32
+ |-----------|-----------------|--------------|---------|
33
+ | Unit tests | `***implementation reqs***` | the functional specs, by the coding agent with the code | Test each functional spec's code in isolation |
34
+ | Conformance tests | how: `***test reqs***`; what: `***conformance tests***` of the functional spec's test plain file | exactly its conformance scenarios, by the conformance agent - at least one test each, none invented | Verify the expected use of one functional spec, its main path |
35
+ | Acceptance tests | how: `***test reqs***`; what: `***acceptance tests***` of the functional spec's test plain file | exactly its acceptance scenarios, the same way | Verify one functional spec under use that is not expected: invalid input, wrong or missing authentication, missing data |
36
36
 
37
37
  ## No duplication
38
38
  - Do not duplicate guidance already present in the file or its imports
@@ -10,33 +10,48 @@ The other rules say what a spec means. This one says what turri does with a chan
10
10
 
11
11
  - turri regenerates the code from spec diffs: what changed between the spec the code was built from and the spec now
12
12
  - A functional spec added, changed or taken out is that change alone, wherever it sits - first, in the middle or last of its module
13
- - The specs around it are not regenerated because their position or numbering moved, and nothing after it is built again. A spec inserted in the middle is one addition
13
+ - A functional spec is known by its module and its func-id, `<module>:<func-id>`: the specs around it are not regenerated because their position moved, and nothing after it is built again. A spec inserted in the middle is one addition; one moved to another place with its text as it was is no change at all
14
+ - A func-id renamed, and nothing else with it, regenerates nothing: turri renames it in its records and relabels its tests itself. Renamed together with any other change - its text, a scenario - it is a functional spec taken out and another added: its code is removed and built anew. Keep a func-id once it is built, and change the text under it
15
+ - Code built before functional specs had func-ids is never built on: its whole chain is regenerated from scratch, never done without the person agreeing
14
16
  - "Specs render top to bottom, each knowing only the ones before it" is about what a spec may assume (`func-specs.md`), not about what a change costs
15
17
 
16
18
  ## A change is regenerated in the chain's tip
17
19
 
18
20
  - A chain's code lives in its tip - the furthest module built on it. The modules below it keep the code they were built with
19
21
  - A change to any module of the chain, the base's included, is regenerated in the tip's code - not in the module the change was made in
22
+ - A functional spec of a module below is added, patched or taken out in the tip just as the tip's own are, named `<module>:<func-id>`. Its conformance tests are in the tip's suite too, and are kept up to date there
20
23
  - Putting a change in a lower module costs no more than putting it in the tip, and saves nothing either
21
- - Moving specs between modules of the chain renders nothing. Moving specs into a module the code was never built on is the exception: no change to the code brings that module in, so the chain has to be regenerated from scratch - never done without the person agreeing
24
+ - Moving specs between modules of the chain regenerates nothing. Moving specs into a module the code was never built on is the exception: no change to the code brings that module in, so the chain has to be regenerated from scratch - never done without the person agreeing
22
25
 
23
26
  ## What each kind of change sets off
24
27
 
25
28
  - A functional spec added is built, with its unit tests; one changed is patched in place; one taken out has its code, and the tests only it had, removed
26
- - A definition changed patches every functional spec that uses its concept, directly or through other definitions. So does a change to a linked resource: the spec or definition linking it is changed though its text is not. A widely used definition is the costly edit - not a spec's position
27
- - Implementation reqs alone, or definitions no functional spec uses, are a mechanical change: the code adapts, and no test is written or changes what it asserts
28
- - Test reqs and acceptance tests reach the conformance tests only, never the code
29
+ - A definition changed patches every functional spec of the chain that uses its concept, directly or through other definitions - a module below's as well as the tip's own. So does a change to a linked resource: the spec or definition linking it is changed though its text is not. A widely used definition is the costly edit - not a spec's position
30
+ - Implementation reqs alone, or definitions no functional spec of the chain uses, are a mechanical change: the code adapts, and no test is written or changes what it asserts
31
+ - Test reqs and scenarios - a functional spec's conformance and acceptance scenarios, in its test plain file - reach the conformance tests only, never the code. A scenario changed alone regenerates no code
29
32
  - A functional spec regenerated again by name has its code taken out and built anew - never left as it was, even where it already does what the spec says; a pulse that changes nothing does not land. Its conformance tests, when it has them, are run on its new code once it lands: those that pass are kept as they are; one that fails is judged against the spec - what it checks that the spec leaves open, a path, a field, a message the old code chose, goes by the new code
30
- - `conformance-tests: false` writes no new conformance tests, but keeps those there are up to date: a functional spec that has conformance tests and is changed, regenerated again or taken out gets a conformance pulse for it alone once its code lands. One with none gets none
31
- - Definitions moved to a common module and reqs reordered are recorded, not rendered
33
+ - What is conformance tested is the scenarios: each conformance and acceptance scenario of a functional spec gets at least one test, and nothing else is tested - a functional spec with no test plain file, or an empty one, has no conformance tests. Its tests are written or changed once its code lands, whenever a scenario is added, changed or taken out, its text changes, it is regenerated again or taken out; one whose scenarios are all taken out loses its tests. It goes scenario by scenario, by scenario-id: a scenario added gets its tests, one changed has them rewritten, one taken out loses them, and an unchanged one keeps them - run on the new code when the functional spec's code changed. A scenario-id renamed with its text as it was has its tests relabelled, nothing rewritten; renamed with any other change, or moved between conformance and acceptance, it is one taken out and one added. To have something checked end to end, write it as a scenario
34
+ - Scenarios are tested only once the module has test reqs - its own, or the stack's conformance template imported - and the project has a conformance testing script for its stack. For a module another requires, that is the tip of the chain: its conformance tests are written there, from the tip's test reqs, so the template goes into the tip. Without either, turri starts no conformance pulse there, by itself or from `conform`: it refuses, naming the step missing, the module waits on it until the `.plain` files or the scripts change, and `turri parse` warns. Take the steps in order - test reqs, the script, then the scenarios - and a module with no scenarios needs neither
35
+ - Definitions moved to a common module and reqs reordered are recorded, not regenerated
32
36
  - A functional spec written on its happy path and hardened later - its validation, edge cases and errors added to it - is patched in place each time: growing a spec a step at a time costs no more than writing it whole up front
33
37
  - A module's first pulse, when it builds one functional spec - the project set up and the smallest thing that runs - lands on its unit tests with no review
34
38
 
39
+ ## The test advisor
40
+
41
+ - Conformance tests are the project's choice: `conformance-tests:` in config.turri.yaml, off when unset. Off, no scenarios are tested and the test advisor is off - write no test plain file, test reqs or conformance testing script unless the person asks for tests; their asking, or their yes when the chat offers them, turns them on first
42
+ - In the chat and a host, turri's test advisor looks at each functional spec that is new, or whose text changed since its code was built, and that has no scenarios - in the background, beside the pulses, taking no slot of theirs and never stopping one. It asks whether a wrong implementation could give output that looks right, whether two reasonable readings give different outputs for some input, whether it is likely to be built on later, and whether a bug in it would be costly. A yes to the first, the second or the last, with evidence, means the functional spec needs testing; built on later alone does not
43
+ - It writes nothing in the ***plain: you are its only writer. A functional spec with scenarios of any kind is not looked at by it; its scenarios go through the usual review when its text changes
44
+ - A change's result names the functional specs the advisor is checking: tell the person in a line that testing scenarios are being evaluated for them, and go on
45
+ - Its yes comes to you as a message, once the chat is idle, with its report: tell the person in a line, then write with `change_plain` what testing the functional spec needs - its test reqs, the conformance testing script, its scenarios, in that order and only what is missing - the script written in the background, so you go straight on to the scenarios - as the rules on test plain files say, asking the person nothing. Its no is a line turri draws: nothing for you to do
46
+ - `evaluate_tests` asks the advisor yourself, for functional specs you name with why, even a text it judged already: it returns at once, and the verdict comes back the same way. Call it when the person asks whether a functional spec needs tests, and on your own as another way of expressing intent - when pulses keep failing on a complicated functional spec, scenarios may pin down what it should do. A functional spec with scenarios is not evaluated
47
+ - When the person asks for scenarios, write them yourself, as the rules on test plain files say. `test-advisor: false` turns off only what a change starts, never `evaluate_tests`; the advisor never runs in a headless run
48
+
35
49
  ## What a coding agent sees
36
50
 
37
- - A coding agent sees its prompt and its module's code - nothing else. It cannot read `.plain` files, this conversation, AGENTS.md or the person
51
+ - A coding agent sees its prompt and its module's code - nothing else. It cannot read `.plain` files, this conversation, AGENTS.md or the person. It never sees a functional spec's scenarios: those are the conformance tests'
38
52
  - What the code needs to know has to be in the spec. A fact said only in the conversation, AGENTS.md or notes never reaches the code, and is lost at the next regeneration
39
53
  - Steering reaches the agents that plan the work - how it is cut and in what order - not what the code does. What the code does is changed in the spec
54
+ - A codebase that requires no module may start from a base folder (`base-folder:` in config.turri.yaml): an existing codebase, files to use - images, animations - or both, copied in once before its first pulse and up the chain with the code. The agents that change and review its code are told what came from it, and keep it unless a functional spec asks otherwise. Refer to what is in it in the spec - in words, or by a link into the folder, relative to the module's file as every link is - for the code to use it: a file it holds that no functional spec names is kept, never used. A change to the folder later reaches the code only when the module is regenerated from scratch
40
55
 
41
56
  ## How bad code is fixed
42
57
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: analyze-2-func-specs
3
3
  description: >-
4
- Analyze two functional specs from a ***plain spec file to determine if they
4
+ Analyze two functional specs from a .plain file to determine if they
5
5
  conflict. Use when the user wants to check whether two specific functional
6
6
  requirements are compatible, or when debugging a suspected conflict between
7
7
  two specs.
@@ -12,26 +12,29 @@ allowed-tools: [read, ls, grep, find]
12
12
 
13
13
  ## Input
14
14
 
15
- Two functional specs from a `.plain` file (or across `requires` modules). The user provides them directly or points to them by location in a file.
15
+ Two functional specs from a `.plain` file (or across `requires` modules). The user provides them directly or names them by func-id - `<module>:<func-id>` across modules. Name each by its func-id while you work; a draft that has none yet is Spec A or Spec B.
16
16
 
17
17
  ## Workflow
18
18
 
19
19
  1. **Read both functional specs** and the `***definitions***` section so all referenced `:Concepts:` are understood.
20
- 2. **Determine chronological order** — which spec comes first? The earlier spec was rendered first and the later spec was rendered with the earlier one in context.
20
+ 2. **Determine chronological order** — which functional spec comes first? The earlier one was regenerated first and the later one was regenerated with the earlier one in context.
21
21
  3. **Run the conflict analysis** using the checklist below.
22
22
  4. **Output the verdict and nothing else** — either `COMPATIBLE` or `CONFLICTING`. No reasoning, no category labels, no resolution suggestions.
23
23
 
24
24
  ## Conflict Analysis Checklist
25
25
 
26
- Work through each question. If any answer is "yes", the specs likely conflict.
26
+ Work through each question. If any answer is "yes", the functional specs likely conflict.
27
27
 
28
28
  ### 1. Direct Contradiction
29
29
 
30
- Do the two specs make mutually exclusive assertions about the same behavior?
30
+ Do the two functional specs make mutually exclusive assertions about the same behavior?
31
31
 
32
32
  ```
33
- Spec A: :Resource: items are returned sorted by name in ascending order.
34
- Spec B: :Resource: items are returned sorted by creation date in descending order.
33
+ # sort-by-name
34
+ :Resource: items are returned sorted by name in ascending order.
35
+
36
+ # sort-by-date
37
+ :Resource: items are returned sorted by creation date in descending order.
35
38
 
36
39
  Verdict: CONFLICTING — both define the sort order for the same response,
37
40
  but specify different fields and directions. A single implementation cannot
@@ -40,34 +43,43 @@ satisfy both unless scoped to different contexts.
40
43
 
41
44
  ### 2. State or Data Conflict
42
45
 
43
- Does one spec set a state or value that the other spec assumes is different?
46
+ Does one functional spec set a state or value that the other assumes is different?
44
47
 
45
48
  ```
46
- Spec A: :TaskList: is initially empty.
47
- Spec B: :TaskList: contains a default "Welcome" :Task: on first load.
49
+ # empty-task-list
50
+ :TaskList: is initially empty.
51
+
52
+ # welcome-task
53
+ :TaskList: contains a default "Welcome" :Task: on first load.
48
54
 
49
55
  Verdict: CONFLICTING — both define the initial state of :TaskList: differently.
50
56
  ```
51
57
 
52
58
  ### 3. Behavioral Override
53
59
 
54
- Does the later spec silently replace behavior established by the earlier spec without acknowledging it?
60
+ Does the later functional spec silently replace behavior established by the earlier one without acknowledging it?
55
61
 
56
62
  ```
57
- Spec A: :User: credentials are validated using an API key.
58
- Spec B: :User: credentials are validated using OAuth 2.0.
63
+ # api-key-auth
64
+ :User: credentials are validated using an API key.
65
+
66
+ # oauth-auth
67
+ :User: credentials are validated using OAuth 2.0.
59
68
 
60
69
  Verdict: CONFLICTING — both define the authentication mechanism but pick
61
- different approaches. The later spec overrides the earlier one.
70
+ different approaches. The later one overrides the earlier one.
62
71
  ```
63
72
 
64
73
  ### 4. Scope Ambiguity
65
74
 
66
- Are the two specs ambiguous enough that a renderer could interpret them as conflicting, even if the user intends them to be complementary?
75
+ Are the two functional specs ambiguous enough that a coding agent could interpret them as conflicting, even if the user intends them to be complementary?
67
76
 
68
77
  ```
69
- Spec A: All :Resource: items are returned.
70
- Spec B: Only active :Resource: items are returned.
78
+ # list-resources
79
+ All :Resource: items are returned.
80
+
81
+ # list-active-resources
82
+ Only active :Resource: items are returned.
71
83
 
72
84
  Verdict: CONFLICTING (ambiguous) — "all" vs "only active" appear contradictory.
73
85
  Could be resolved by scoping each to different conditions (e.g., filtered vs unfiltered).
@@ -75,13 +87,16 @@ Could be resolved by scoping each to different conditions (e.g., filtered vs unf
75
87
 
76
88
  ### 5. Shared Concept, Different Constraints
77
89
 
78
- Do both specs impose constraints on the same `:Concept:` that cannot coexist?
90
+ Do both functional specs impose constraints on the same `:Concept:` that cannot coexist?
79
91
 
80
92
  ```
81
- Spec A: :BatchSize: is 100 items.
82
- Spec B: :BatchSize: is 50 items for :Resource: types with attachments.
93
+ # default-batch-size
94
+ :BatchSize: is 100 items.
95
+
96
+ # attachment-batch-size
97
+ :BatchSize: is 50 items for :Resource: types with attachments.
83
98
 
84
- Verdict: COMPATIBLE — Spec B adds a conditional refinement, not a contradiction.
99
+ Verdict: COMPATIBLE — attachment-batch-size adds a conditional refinement, not a contradiction.
85
100
  ```
86
101
 
87
102
  ## Output Format