@turri-dev/cli 0.0.0-stage → 0.1.1

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 (315) hide show
  1. package/.pi/themes/turri-dark.json +80 -0
  2. package/.pi/themes/turri-light.json +82 -0
  3. package/LICENSE +21 -0
  4. package/README.md +272 -2
  5. package/assets/jellyfish/dark-00.png +0 -0
  6. package/assets/jellyfish/dark-01.png +0 -0
  7. package/assets/jellyfish/dark-02.png +0 -0
  8. package/assets/jellyfish/dark-03.png +0 -0
  9. package/assets/jellyfish/dark-04.png +0 -0
  10. package/assets/jellyfish/dark-05.png +0 -0
  11. package/assets/jellyfish/dark-06.png +0 -0
  12. package/assets/jellyfish/dark-07.png +0 -0
  13. package/assets/jellyfish/dark-08.png +0 -0
  14. package/assets/jellyfish/dark-09.png +0 -0
  15. package/assets/jellyfish/dark-10.png +0 -0
  16. package/assets/jellyfish/dark-11.png +0 -0
  17. package/assets/jellyfish/dark-12.png +0 -0
  18. package/assets/jellyfish/dark-13.png +0 -0
  19. package/assets/jellyfish/dark-14.png +0 -0
  20. package/assets/jellyfish/fallback.txt +252 -0
  21. package/assets/jellyfish/light-00.png +0 -0
  22. package/assets/jellyfish/light-01.png +0 -0
  23. package/assets/jellyfish/light-02.png +0 -0
  24. package/assets/jellyfish/light-03.png +0 -0
  25. package/assets/jellyfish/light-04.png +0 -0
  26. package/assets/jellyfish/light-05.png +0 -0
  27. package/assets/jellyfish/light-06.png +0 -0
  28. package/assets/jellyfish/light-07.png +0 -0
  29. package/assets/jellyfish/light-08.png +0 -0
  30. package/assets/jellyfish/light-09.png +0 -0
  31. package/assets/jellyfish/light-10.png +0 -0
  32. package/assets/jellyfish/light-11.png +0 -0
  33. package/assets/jellyfish/light-12.png +0 -0
  34. package/assets/jellyfish/light-13.png +0 -0
  35. package/assets/jellyfish/light-14.png +0 -0
  36. package/bin/turri.mjs +29 -0
  37. package/dist/ask.js +149 -0
  38. package/dist/brand.js +50 -0
  39. package/dist/btw.js +174 -0
  40. package/dist/chat-models.js +37 -0
  41. package/dist/chat-skills.js +18 -0
  42. package/dist/cli.js +178 -0
  43. package/dist/config-command.js +197 -0
  44. package/dist/config-edit.js +367 -0
  45. package/dist/config.js +489 -0
  46. package/dist/conform-cli.js +29 -0
  47. package/dist/cultivate-cli.js +110 -0
  48. package/dist/drift-cli.js +25 -0
  49. package/dist/environment.js +70 -0
  50. package/dist/extension.js +2372 -0
  51. package/dist/genome.js +301 -0
  52. package/dist/graph.js +246 -0
  53. package/dist/identity.js +35 -0
  54. package/dist/init-config.js +511 -0
  55. package/dist/judge.js +62 -0
  56. package/dist/lineage-cli.js +13 -0
  57. package/dist/loop-cli.js +132 -0
  58. package/dist/loop-tools.js +225 -0
  59. package/dist/mature-tools.js +193 -0
  60. package/dist/model-check.js +117 -0
  61. package/dist/module-report.js +9 -0
  62. package/dist/pi-launch.js +31 -0
  63. package/dist/pi.js +813 -0
  64. package/dist/plain/check.js +76 -0
  65. package/dist/plain/concepts.js +213 -0
  66. package/dist/plain/errors.js +43 -0
  67. package/dist/plain/files.js +57 -0
  68. package/dist/plain/highlight.js +195 -0
  69. package/dist/plain/index.js +15 -0
  70. package/dist/plain/liquid.js +129 -0
  71. package/dist/plain/markdown.js +208 -0
  72. package/dist/plain/parser.js +752 -0
  73. package/dist/plain/plain.tmLanguage.json +124 -0
  74. package/dist/plain/spec.js +291 -0
  75. package/dist/plain/stdlib.js +44 -0
  76. package/dist/question-dialog.js +125 -0
  77. package/dist/questioning.js +109 -0
  78. package/dist/quiet.js +125 -0
  79. package/dist/regenerate/activity.js +187 -0
  80. package/dist/regenerate/agent-env.js +190 -0
  81. package/dist/regenerate/agent-shell.js +114 -0
  82. package/dist/regenerate/arbiter.js +133 -0
  83. package/dist/regenerate/audit.js +203 -0
  84. package/dist/regenerate/cases.js +83 -0
  85. package/dist/regenerate/change-view.js +102 -0
  86. package/dist/regenerate/choose-conformance.js +117 -0
  87. package/dist/regenerate/chunk-plan.js +625 -0
  88. package/dist/regenerate/codebase.js +75 -0
  89. package/dist/regenerate/command-check.js +312 -0
  90. package/dist/regenerate/compaction.js +20 -0
  91. package/dist/regenerate/confine.js +310 -0
  92. package/dist/regenerate/conform.js +133 -0
  93. package/dist/regenerate/conformance-agents.js +955 -0
  94. package/dist/regenerate/conformance.js +936 -0
  95. package/dist/regenerate/conversation-writes.js +100 -0
  96. package/dist/regenerate/credentials.js +88 -0
  97. package/dist/regenerate/debug-log.js +228 -0
  98. package/dist/regenerate/debugger.js +90 -0
  99. package/dist/regenerate/delivery.js +19 -0
  100. package/dist/regenerate/diagnose-job.js +40 -0
  101. package/dist/regenerate/diagnose.js +81 -0
  102. package/dist/regenerate/diff-view.js +240 -0
  103. package/dist/regenerate/drift.js +194 -0
  104. package/dist/regenerate/engine.js +118 -0
  105. package/dist/regenerate/environment-error.js +220 -0
  106. package/dist/regenerate/job-log.js +102 -0
  107. package/dist/regenerate/job-panel.js +336 -0
  108. package/dist/regenerate/jobs-tree.js +300 -0
  109. package/dist/regenerate/jobs.js +427 -0
  110. package/dist/regenerate/lanes.js +32 -0
  111. package/dist/regenerate/lineage.js +384 -0
  112. package/dist/regenerate/loop.js +1435 -0
  113. package/dist/regenerate/masking.js +95 -0
  114. package/dist/regenerate/notes.js +397 -0
  115. package/dist/regenerate/os-sandbox.js +243 -0
  116. package/dist/regenerate/paths.js +165 -0
  117. package/dist/regenerate/plain-palette.js +83 -0
  118. package/dist/regenerate/prompt.js +704 -0
  119. package/dist/regenerate/records.js +294 -0
  120. package/dist/regenerate/regenerate.js +598 -0
  121. package/dist/regenerate/regression.js +181 -0
  122. package/dist/regenerate/release.js +262 -0
  123. package/dist/regenerate/requires.js +241 -0
  124. package/dist/regenerate/resources.js +164 -0
  125. package/dist/regenerate/self-check.js +111 -0
  126. package/dist/regenerate/services.js +155 -0
  127. package/dist/regenerate/shell.js +319 -0
  128. package/dist/regenerate/side-panel.js +278 -0
  129. package/dist/regenerate/spec-map-view.js +574 -0
  130. package/dist/regenerate/spec-map.js +561 -0
  131. package/dist/regenerate/spec-steps.js +527 -0
  132. package/dist/regenerate/state.js +10 -0
  133. package/dist/regenerate/steer.js +91 -0
  134. package/dist/regenerate/steering.js +119 -0
  135. package/dist/regenerate/stop-report.js +161 -0
  136. package/dist/regenerate/submit-work.js +71 -0
  137. package/dist/regenerate/test-kinds.js +124 -0
  138. package/dist/regenerate/test-scripts.js +695 -0
  139. package/dist/regenerate/testing.js +406 -0
  140. package/dist/regenerate/transcript-view.js +1 -0
  141. package/dist/regenerate/unit-gate.js +20 -0
  142. package/dist/regenerate/unit-review.js +347 -0
  143. package/dist/regenerate/web.js +256 -0
  144. package/dist/regenerate/workspace.js +99 -0
  145. package/dist/regenerate-cli.js +68 -0
  146. package/dist/release-agent.js +114 -0
  147. package/dist/release-cli.js +131 -0
  148. package/dist/release-tools.js +148 -0
  149. package/dist/review/live.js +165 -0
  150. package/dist/rules.js +47 -0
  151. package/dist/self-invocation.js +110 -0
  152. package/dist/setup.js +245 -0
  153. package/dist/skill-progress.js +78 -0
  154. package/dist/skill.js +149 -0
  155. package/dist/skills.js +74 -0
  156. package/dist/spec-diff-cli.js +37 -0
  157. package/dist/spec-tools.js +155 -0
  158. package/dist/stack.js +158 -0
  159. package/dist/stacks.js +97 -0
  160. package/dist/stdlib.js +100 -0
  161. package/dist/terminal-images.js +46 -0
  162. package/dist/tools.js +242 -0
  163. package/dist/validate-cli.js +52 -0
  164. package/docs/README.md +58 -0
  165. package/docs/authoring-plain.md +245 -0
  166. package/docs/config.md +353 -0
  167. package/docs/deploy.md +109 -0
  168. package/docs/development.md +75 -0
  169. package/docs/headless.md +148 -0
  170. package/docs/images/how-turri-works.svg +50 -0
  171. package/docs/images/turri-banner.png +0 -0
  172. package/docs/installation.md +118 -0
  173. package/docs/parser.md +108 -0
  174. package/docs/regenerating.md +1116 -0
  175. package/docs/sandbox.md +233 -0
  176. package/docs/skills-and-gates.md +254 -0
  177. package/docs/theming.md +76 -0
  178. package/docs/using.md +454 -0
  179. package/genome/rules/bullet-continuation.md +69 -0
  180. package/genome/rules/concise-specs-examples.md +431 -0
  181. package/genome/rules/concise-specs-integration-examples.md +270 -0
  182. package/genome/rules/concise-specs.md +80 -0
  183. package/genome/rules/definitions.md +107 -0
  184. package/genome/rules/examples/integration-embedded-testing/run_conformance_tests_java.sh +163 -0
  185. package/genome/rules/examples/integration-embedded-testing/run_unittests_java.sh +51 -0
  186. package/genome/rules/exported-concepts.md +39 -0
  187. package/genome/rules/func-specs.md +129 -0
  188. package/genome/rules/impl-reqs.md +68 -0
  189. package/genome/rules/import-modules.md +48 -0
  190. package/genome/rules/integration-embedded-testing.md +276 -0
  191. package/genome/rules/integration-embedded.md +171 -0
  192. package/genome/rules/integration-standalone.md +135 -0
  193. package/genome/rules/integrations.md +137 -0
  194. package/genome/rules/linked-resources.md +69 -0
  195. package/genome/rules/module-structure.md +105 -0
  196. package/genome/rules/project-model.md +88 -0
  197. package/genome/rules/required-concepts.md +44 -0
  198. package/genome/rules/requires-modules.md +80 -0
  199. package/genome/rules/stdlib.md +73 -0
  200. package/genome/rules/test-reqs.md +57 -0
  201. package/genome/skills/add-acceptance-test/SKILL.md +100 -0
  202. package/genome/skills/add-concept/SKILL.md +71 -0
  203. package/genome/skills/add-functional-spec/SKILL.md +84 -0
  204. package/genome/skills/add-functional-specs/SKILL.md +118 -0
  205. package/genome/skills/add-implementation-requirement/SKILL.md +86 -0
  206. package/genome/skills/add-resource/SKILL.md +105 -0
  207. package/genome/skills/add-template/SKILL.md +64 -0
  208. package/genome/skills/add-test-requirement/SKILL.md +73 -0
  209. package/genome/skills/analyze-2-func-specs/SKILL.md +101 -0
  210. package/genome/skills/analyze-func-specs/SKILL.md +123 -0
  211. package/genome/skills/analyze-if-func-spec-too-complex/SKILL.md +211 -0
  212. package/genome/skills/break-down-func-spec/SKILL.md +205 -0
  213. package/genome/skills/brood/SKILL.md +229 -0
  214. package/genome/skills/brood/references/intent.md +35 -0
  215. package/genome/skills/brood/references/product.md +101 -0
  216. package/genome/skills/brood/references/stack.md +61 -0
  217. package/genome/skills/brood/references/testing.md +56 -0
  218. package/genome/skills/bud/SKILL.md +148 -0
  219. package/genome/skills/bud/references/checklist.md +44 -0
  220. package/genome/skills/bud/references/intent.md +30 -0
  221. package/genome/skills/check-plain-env/SKILL.md +285 -0
  222. package/genome/skills/consolidate-concepts/SKILL.md +192 -0
  223. package/genome/skills/create-import-module/SKILL.md +104 -0
  224. package/genome/skills/create-requires-module/SKILL.md +109 -0
  225. package/genome/skills/debug-specs/SKILL.md +188 -0
  226. package/genome/skills/implement-conformance-testing-script/SKILL.md +238 -0
  227. package/genome/skills/implement-conformance-testing-script/assets/run_conformance_tests_cypress.ps1 +337 -0
  228. package/genome/skills/implement-conformance-testing-script/assets/run_conformance_tests_golang.ps1 +111 -0
  229. package/genome/skills/implement-conformance-testing-script/assets/run_conformance_tests_java.sh +136 -0
  230. package/genome/skills/implement-conformance-testing-script/assets/run_conformance_tests_python.ps1 +103 -0
  231. package/genome/skills/implement-conformance-testing-script/assets/run_conformance_tests_python.sh +150 -0
  232. package/genome/skills/implement-unit-testing-script/SKILL.md +160 -0
  233. package/genome/skills/implement-unit-testing-script/assets/run_unittests_flutter.ps1 +87 -0
  234. package/genome/skills/implement-unit-testing-script/assets/run_unittests_golang.ps1 +73 -0
  235. package/genome/skills/implement-unit-testing-script/assets/run_unittests_java.sh +72 -0
  236. package/genome/skills/implement-unit-testing-script/assets/run_unittests_python.ps1 +81 -0
  237. package/genome/skills/implement-unit-testing-script/assets/run_unittests_python.sh +98 -0
  238. package/genome/skills/implement-unit-testing-script/assets/run_unittests_react.ps1 +87 -0
  239. package/genome/skills/init-plain-project/SKILL.md +117 -0
  240. package/genome/skills/init-plain-project/references/checklist.md +30 -0
  241. package/genome/skills/mature/SKILL.md +126 -0
  242. package/genome/skills/refactor-module/SKILL.md +196 -0
  243. package/genome/skills/resolve-section-ownership/SKILL.md +64 -0
  244. package/genome/skills/resolve-spec-conflict/SKILL.md +96 -0
  245. package/genome/skills/spawn/SKILL.md +163 -0
  246. package/package.json +68 -4
  247. package/stdlib/backend/common.plain +25 -0
  248. package/stdlib/backend/conformance/common.plain +12 -0
  249. package/stdlib/backend/conformance/go-gin.plain +9 -0
  250. package/stdlib/backend/conformance/go-nethttp.plain +9 -0
  251. package/stdlib/backend/conformance/java-springboot.plain +9 -0
  252. package/stdlib/backend/conformance/python-django.plain +9 -0
  253. package/stdlib/backend/conformance/python-fastapi.plain +9 -0
  254. package/stdlib/backend/conformance/python-flask.plain +9 -0
  255. package/stdlib/backend/conformance/rust-axum.plain +9 -0
  256. package/stdlib/backend/conformance/typescript-express.plain +9 -0
  257. package/stdlib/backend/conformance/typescript-fastify.plain +9 -0
  258. package/stdlib/backend/conformance/typescript-nestjs.plain +9 -0
  259. package/stdlib/backend/go-gin.plain +18 -0
  260. package/stdlib/backend/go-nethttp.plain +18 -0
  261. package/stdlib/backend/java-springboot.plain +19 -0
  262. package/stdlib/backend/python-django.plain +19 -0
  263. package/stdlib/backend/python-fastapi.plain +23 -0
  264. package/stdlib/backend/python-flask.plain +23 -0
  265. package/stdlib/backend/rust-axum.plain +17 -0
  266. package/stdlib/backend/typescript-express.plain +19 -0
  267. package/stdlib/backend/typescript-fastify.plain +19 -0
  268. package/stdlib/backend/typescript-nestjs.plain +19 -0
  269. package/stdlib/cli/common.plain +17 -0
  270. package/stdlib/cli/conformance/common.plain +11 -0
  271. package/stdlib/cli/conformance/go-cobra.plain +9 -0
  272. package/stdlib/cli/conformance/go-flag.plain +9 -0
  273. package/stdlib/cli/conformance/java-picocli.plain +9 -0
  274. package/stdlib/cli/conformance/python-argparse.plain +9 -0
  275. package/stdlib/cli/conformance/python-click.plain +9 -0
  276. package/stdlib/cli/conformance/python-typer.plain +9 -0
  277. package/stdlib/cli/conformance/rust-clap.plain +9 -0
  278. package/stdlib/cli/conformance/typescript-commander.plain +9 -0
  279. package/stdlib/cli/go-cobra.plain +14 -0
  280. package/stdlib/cli/go-flag.plain +14 -0
  281. package/stdlib/cli/java-picocli.plain +15 -0
  282. package/stdlib/cli/python-argparse.plain +18 -0
  283. package/stdlib/cli/python-click.plain +16 -0
  284. package/stdlib/cli/python-typer.plain +16 -0
  285. package/stdlib/cli/rust-clap.plain +14 -0
  286. package/stdlib/cli/typescript-commander.plain +17 -0
  287. package/stdlib/frontend/angular.plain +17 -0
  288. package/stdlib/frontend/common.plain +17 -0
  289. package/stdlib/frontend/conformance/angular.plain +5 -0
  290. package/stdlib/frontend/conformance/common.plain +11 -0
  291. package/stdlib/frontend/conformance/react-vite.plain +5 -0
  292. package/stdlib/frontend/conformance/sveltekit-spa.plain +5 -0
  293. package/stdlib/frontend/conformance/vue-vite.plain +5 -0
  294. package/stdlib/frontend/react-vite.plain +16 -0
  295. package/stdlib/frontend/sveltekit-spa.plain +16 -0
  296. package/stdlib/frontend/vue-vite.plain +16 -0
  297. package/stdlib/lang/go.plain +13 -0
  298. package/stdlib/lang/java.plain +12 -0
  299. package/stdlib/lang/python.plain +18 -0
  300. package/stdlib/lang/rust.plain +12 -0
  301. package/stdlib/lang/typescript.plain +13 -0
  302. package/stdlib/library/common.plain +15 -0
  303. package/stdlib/library/conformance/common.plain +9 -0
  304. package/stdlib/library/conformance/go.plain +9 -0
  305. package/stdlib/library/conformance/java-gradle.plain +9 -0
  306. package/stdlib/library/conformance/java-maven.plain +9 -0
  307. package/stdlib/library/conformance/python.plain +9 -0
  308. package/stdlib/library/conformance/rust.plain +9 -0
  309. package/stdlib/library/conformance/typescript.plain +9 -0
  310. package/stdlib/library/go.plain +12 -0
  311. package/stdlib/library/java-gradle.plain +13 -0
  312. package/stdlib/library/java-maven.plain +13 -0
  313. package/stdlib/library/python.plain +13 -0
  314. package/stdlib/library/rust.plain +12 -0
  315. package/stdlib/library/typescript.plain +15 -0
@@ -0,0 +1,80 @@
1
+ ---
2
+ description: Rules for creating and using requires modules in .plain files
3
+ ---
4
+
5
+ # Rules for requires modules
6
+
7
+ When creating or editing a `.plain` file that uses `requires`, or one that is referenced in another `.plain` file's `requires` directive, always follow these rules:
8
+
9
+ ## What requires does
10
+
11
+ - `requires` attaches the current module to the project's **build chain**: the required module is built first, and its generated code is copied as the starting point for the current module
12
+ - The copied code is the required module's **accumulated** output — it already contains the code of all of that module's own ancestors
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
+ - 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
+ - Export visibility **is not transitive**: an ancestor's exports are visible only if that ancestor is itself listed in `requires`
16
+
17
+ ## Chain topology
18
+
19
+ - All modules connected by `requires` form a single **tree** with a common root: code accumulates along each branch, and branches never reconverge
20
+ - **Diamond joins are prohibited.** A module must not require two modules from divergent branches — there is no way to merge two divergent codebases into one starting point
21
+ - When `requires` lists multiple modules, every entry must lie on **one root-to-tip ancestor path**: each listed module must be an ancestor of the deepest one
22
+ - The **deepest entry is the attachment point** — it alone determines the build order and the starting code. The other entries add nothing to ordering; they exist **only** to make those ancestors' `exported_concepts` visible
23
+ - Branching outward is fine: two modules may each require the same parent, creating independent branches (and therefore independent top modules)
24
+
25
+ ## Tech stack must match (hard rule)
26
+
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
+ - A runtime / network dependency between systems is **not** a reason to use `requires`
29
+ - Example of the mistake: a React frontend that talks to a Python/FastAPI backend over HTTP must **not** `requires: [backend]` — the stacks differ
30
+ - 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`
31
+
32
+ ## Building upon but not necessarily extension
33
+
34
+ - The current module does not need to functionally extend the required module — it may address a completely different concern
35
+ - 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
+
38
+ ## Conflict prevention
39
+
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
42
+ - Review the ancestor chain's functional specs before adding new ones
43
+
44
+ ## Exports are the only visible definitions
45
+
46
+ - Only concepts listed in a required module's `exported_concepts` are available, and only for modules explicitly listed in `requires`
47
+ - Each exported concept is available with its full definition text
48
+ - Other concepts from required modules are internal and invisible
49
+ - To reference a concept exported by an ancestor deeper in the chain, list that ancestor in `requires` as well
50
+ - If you need shared definitions across branches or stacks, use `import` for that — not `requires`
51
+
52
+ ## File locations
53
+
54
+ - Modules that use `requires` live at the **repository root** — they are functional modules with specs
55
+ - `requires` paths point to other root-level modules (e.g., `auth`, `messaging`)
56
+ - Never `require` an import module — import modules are for `import` only
57
+
58
+ ## Format
59
+
60
+ ```plain
61
+ ---
62
+ requires:
63
+ - auth
64
+ import:
65
+ - airplain
66
+ description: Module built on top of auth, importing shared definitions
67
+ ---
68
+ ```
69
+
70
+ A module can list multiple required modules **only when they lie on one ancestor path**. Here `messaging` itself requires `auth`, so `auth` is an ancestor of `messaging`; the module attaches after `messaging` and lists `auth` only to see its exports:
71
+
72
+ ```plain
73
+ ---
74
+ requires:
75
+ - auth
76
+ - messaging
77
+ import:
78
+ - airplain
79
+ ---
80
+ ```
@@ -0,0 +1,73 @@
1
+ ---
2
+ description: The ***plain standard library - import modules for a backend, a frontend, a command-line tool or a library, on a known stack
3
+ ---
4
+
5
+ # Rules for the standard library
6
+
7
+ turri ships a standard library of import modules that settle everything about a generic piece
8
+ of software on one stack except what it does: its language and framework, its layout, its
9
+ configuration, how it handles errors, how it logs, how it stops, and how it is tested. A module that
10
+ imports one writes only what is its own - its concepts and its functional specs - and a requirement
11
+ only for what its stack does not settle.
12
+
13
+ ```plain
14
+ ---
15
+ import:
16
+ - stdlib/backend/python-flask
17
+ - stdlib/backend/conformance/python-flask
18
+ ---
19
+ ```
20
+
21
+ ## How it is built up
22
+
23
+ - Each stack imports its language's template - `stdlib/lang/python` - and its kind's `common` -
24
+ `stdlib/backend/common` - so importing the stack brings all three.
25
+ - Each stack's conformance tests are a template of their own, `stdlib/<kind>/conformance/<stack>`,
26
+ which imports `stdlib/<kind>/conformance/common`.
27
+ - The `common` of a kind settles what every stack of it shares. For a backend: settings from the
28
+ environment, checked at start; handler, service and repository layers; domain errors turned into
29
+ one error body `{"error": {"code", "message"}}` with fixed codes and statuses; JSON logs with a
30
+ request id; shutdown on a signal. For a command-line tool: `Error: <message>` on standard error,
31
+ exit codes 0, 1, 2 and 130, logs on standard error with `--verbose` and `--debug`. For a frontend:
32
+ one API layer with an `ApiError`, errors shown in place or at the root, one logger module. For a
33
+ library: one public entry point, one base error type, no output of its own.
34
+
35
+ ## When to use it
36
+
37
+ - When the person wants a backend, a frontend, a command-line tool or a library, import the stack
38
+ that fits instead of writing its implementation reqs yourself.
39
+ - Pick the stack from what the person said, the project's other modules, and what the module talks
40
+ to. With nothing to go on: `stdlib/backend/python-fastapi`, `stdlib/frontend/react-vite`,
41
+ `stdlib/cli/python-typer`, `stdlib/library/python`.
42
+ - Import the conformance template only when the module has conformance tests - the person asked for
43
+ them, and the project's config does not turn them off (`conformance-tests: false`). Without it
44
+ the module has no test reqs, and no conformance tests are written or run for it. Turning them on
45
+ later is adding that one import.
46
+ - Read the templates a module imports before writing its specs - the folder is named below - and
47
+ write no requirement they already make (see `concise-specs.md`).
48
+ - Write a functional spec's errors in the templates' terms: a backend's failure by its status and
49
+ `error.code` - `not_found`, `conflict`, `validation_error`, `unauthenticated`, `forbidden`, or a
50
+ code of the module's own - and a command-line tool's by its exit code and message.
51
+ - Add a requirement on top for what the module needs beyond its stack - storage, an outside
52
+ service, a library it must use. When the module differs from its stack on something the stack
53
+ settles - another framework, another layout - write the stack yourself instead: an import cannot
54
+ be taken back in part. For a language with no stack of the kind wanted, import its
55
+ `stdlib/lang/<language>` and write the rest.
56
+ - `stdlib/` is a reserved name. An import that starts with it is always the standard library's
57
+ template, and a project module at such a path - `stdlib/backend/python-fastapi.plain` in the
58
+ spec's folder, its `template/` folder or `PLAIN_TEMPLATE_DIRS` - is an error. Never write a module
59
+ under a `stdlib/` folder of the project; a project's own shared template goes in `template/`
60
+ under a name of its own.
61
+
62
+ ## What it does not do
63
+
64
+ - It defines no concepts: its requirements are on the predefined `:Implementation:`, `:UnitTests:`
65
+ and `:ConformanceTests:` only, so it never collides with the module's own definitions.
66
+ - It holds no storage: a module with a database says which, and how it is reached, on top.
67
+ - It holds no testing scripts. The module still needs its unit testing script, and its conformance
68
+ testing script when it has conformance tests - written with the `implement-unit-testing-script`
69
+ and `implement-conformance-testing-script` skills for the stack's language and test framework. Each
70
+ runs the static checks of what it tests - the formatter, linter and type checker its language template
71
+ names, on the code or on the conformance tests - and they count as the tests do.
72
+ - It names its stack's toolchain - Python 3.12, Node.js 24, Java 21, Go 1.25, Rust - which the agents use from the
73
+ machine turri runs on; they install none, so `turri doctor` says when the machine lacks it.
@@ -0,0 +1,57 @@
1
+ ---
2
+ description: Rules for writing ***test reqs*** sections in .plain files
3
+ ---
4
+
5
+ # Rules for writing `***test reqs***`
6
+
7
+ When writing or editing a `***test reqs***` section in a `.plain` file, always follow these rules:
8
+
9
+ ## Conformance tests only
10
+ - Test reqs specify how **conformance tests** should be written and run
11
+ - Unit test guidance goes in `***implementation reqs***`, not here
12
+ - Acceptance tests are nested under individual functional specs, not here
13
+ - Behavioral requirements go in `***functional specs***`, not here
14
+
15
+ ## `:ConformanceTests:` lives here (hard rule)
16
+ - **Everything** about `:ConformanceTests:` goes in `***test reqs***` — paths, approach, packages, framework, execution command, mocking / network policy, fixtures, pass criteria, environment prerequisites
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
19
+ - Author each `:ConformanceTests:` requirement via `add-test-requirement` and phrase it 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
21
+
22
+ ## What belongs here
23
+ - Test framework: which framework to use (e.g., pytest, Unittest, xUnit)
24
+ - Execution method: the command to run the tests
25
+ - Testing constraints: what must or must not be done in tests (e.g., no skipping, mock requirements)
26
+ - Test data: how test fixtures or mock data should be structured
27
+ - Environment setup: any prerequisites for running conformance tests
28
+
29
+ ## Test type reference
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 |
36
+
37
+ ## No duplication
38
+ - Do not duplicate guidance already present in the file or its imports
39
+ - Check imported modules before adding a new test req
40
+
41
+ ## Concept references
42
+ - Reference predefined concepts like `:ConformanceTests:` where appropriate
43
+ - All other referenced `:Concepts:` must be defined in `***definitions***`
44
+
45
+ ## Conciseness
46
+ - State each req in the fewest plain words that stay exact — see `concise-specs.md`
47
+ - Do not restate the default behavior of the test framework this section already names
48
+
49
+ ## Format
50
+
51
+ ```plain
52
+ ***test reqs***
53
+ - :ConformanceTests: should be implemented using pytest framework.
54
+ - :ConformanceTests: will be run using "pytest" command.
55
+ - :ConformanceTests: must be implemented and executed - do not skip tests.
56
+ - :ConformanceTests: should mock all external HTTP calls.
57
+ ```
@@ -0,0 +1,100 @@
1
+ ---
2
+ name: add-acceptance-test
3
+ description: >-
4
+ Add acceptance tests under a functional spec in a ***plain spec file. Use
5
+ when the user wants to add verification criteria for a specific functional
6
+ spec, or after adding a functional spec that needs testable success criteria.
7
+ allowed-tools: [read, write, edit, bash, ls, grep, find]
8
+ ---
9
+
10
+ # Add Acceptance Test
11
+
12
+ ## Workflow
13
+
14
+ 1. **Identify the target `.plain` file and the functional spec** to attach the acceptance test to. If ambiguous, ask the user.
15
+ 2. **Read the file** to understand the functional spec, existing acceptance tests (if any), and the `***test reqs***` section (acceptance tests are implemented according to test reqs).
16
+ 3. **Draft the acceptance test(s)** following the rules below.
17
+ 4. **Nest them** under the target functional spec using a `***acceptance tests***` subsection.
18
+ 5. **Read the file again** to confirm correct placement, indentation, and syntax.
19
+
20
+ ## When to Add Acceptance Tests
21
+
22
+ - The functional spec's correct behavior is **non-obvious** or easily misinterpreted.
23
+ - The spec involves **edge cases**, boundary conditions, or specific numeric outcomes.
24
+ - The user explicitly requests verification criteria.
25
+ - The spec was added via the `add-functional-spec` skill and warrants testable success criteria.
26
+
27
+ ## Format
28
+
29
+ Acceptance tests are nested under the functional spec they verify, using a `***acceptance tests***` subsection:
30
+
31
+ ```plain
32
+ ***functional specs***
33
+
34
+ - :Task: items are processed in batches of 100.
35
+
36
+ ***acceptance tests***
37
+ - Processing 250 :Task: items should result in 3 batches.
38
+
39
+ - Each batch should contain at most 100 items.
40
+ ```
41
+
42
+ Key formatting rules:
43
+ - The `***acceptance tests***` header is indented under the functional spec it belongs to.
44
+ - Each test bullet is indented under the `***acceptance tests***` header.
45
+ - Multiple acceptance tests can be listed under a single functional spec.
46
+
47
+
48
+ ## Rules
49
+
50
+ ### Conformance with the Functional Spec
51
+
52
+ An acceptance test is essentially an **example that illustrates** the functional spec — it clarifies intent by showing a concrete scenario. It may imply minor code changes, but those should not be substantial. The acceptance test **must be consistent with** the functional spec it is nested under. If the acceptance test asserts behavior that contradicts, narrows, or extends the functional spec in ways not implied by it, the system will reject it as a conflicting acceptance test. Before writing, re-read the parent functional spec and ensure every assertion in the acceptance test is a direct, logical consequence of what the spec states.
53
+
54
+ ```
55
+ Functional spec:
56
+ - :Resource: items are returned sorted by creation date in descending order.
57
+
58
+ Good (consistent):
59
+ - The first :Resource: in the response should have the most recent creation date.
60
+
61
+ Bad (contradicts the spec — the spec says descending, not ascending):
62
+ - The first :Resource: in the response should have the oldest creation date.
63
+
64
+ Bad (extends beyond the spec — the spec says nothing about limiting results):
65
+ - The response should contain at most 50 :Resource: items.
66
+ ```
67
+
68
+ ### Scope
69
+
70
+ Each acceptance test verifies a specific, observable aspect of the functional spec it's nested under. Do not test behavior from other functional specs.
71
+
72
+ ### Testability
73
+
74
+ Every acceptance test must describe a concrete, verifiable outcome — not a vague quality. The test should be implementable as an automated conformance test.
75
+
76
+ ```
77
+ Good: - The response should contain exactly 3 items.
78
+ Bad: - The response should be correct.
79
+ ```
80
+
81
+ ### Language Agnosticism
82
+
83
+ Like functional specs, acceptance tests must be written in terms of behavior and outcomes — not language-specific constructs.
84
+
85
+ ### Relationship to Test Reqs
86
+
87
+ Acceptance tests extend conformance tests and are implemented according to the `***test reqs***` specification. They do not replace test reqs — they add spec-specific verification on top of the general testing framework defined there.
88
+
89
+ ## Validation Checklist
90
+
91
+ - [ ] Every assertion is a direct logical consequence of the parent functional spec
92
+ - [ ] No assertion contradicts, narrows, or extends beyond the parent spec
93
+ - [ ] Acceptance test illustrates the spec via example, not introducing substantial new behavior
94
+ - [ ] Nested under the correct functional spec
95
+ - [ ] Indentation is correct (`***acceptance tests***` indented under the spec)
96
+ - [ ] Each test describes a concrete, verifiable outcome
97
+ - [ ] Trimmed per `concise-specs.md`: plain words, no obvious steps, no restatement of the parent spec
98
+ - [ ] Tests are scoped to the parent functional spec only
99
+ - [ ] Written in language-agnostic terms
100
+ - [ ] No duplication with existing acceptance tests on the same spec
@@ -0,0 +1,71 @@
1
+ ---
2
+ name: add-concept
3
+ description: >-
4
+ Add a concept to the ***definitions*** section of a ***plain spec file. Use
5
+ when the user wants to define a new concept, entity, or domain term in a
6
+ .plain file.
7
+ allowed-tools: [read, write, edit, bash, ls, grep, find]
8
+ ---
9
+
10
+ # Add Concept
11
+
12
+ ## Workflow
13
+
14
+ 1. **Identify the target `.plain` file.** If ambiguous, ask the user.
15
+ 2. **Read the file** to understand existing definitions, imports, and concepts.
16
+ 3. **Validate the concept name** against the syntax rules below.
17
+ 4. **Check for uniqueness** — the concept name must not already exist in the file or its imports.
18
+ 5. **Check referenced concepts** — any `:ConceptName:` used in the definition must already be defined above it (in this file or via `import`/`requires`). Concept references must not form cycles (e.g., A references B and B references A).
19
+ 6. **Check for circular references** — if the new concept references `:B:`, then `:B:` must not reference the new concept (directly or indirectly). Example of a circular definition to avoid:
20
+ ```plain
21
+ - :Order: is placed by :Customer: and contains :OrderItem: entries.
22
+ - :Customer: is a user who has placed at least one :Order:.
23
+ ```
24
+ Fix by removing the back-reference:
25
+ ```plain
26
+ - :Customer: is a user of the system.
27
+ - :Order: is placed by :Customer: and contains :OrderItem: entries.
28
+ ```
29
+ 7. **Insert the concept** into the `***definitions***` section, after any concepts it references.
30
+ 8. **Read the file again** to confirm correct placement and syntax.
31
+
32
+ ## Concept Syntax Rules
33
+
34
+ - Wrapped in colons: `:ConceptName:`
35
+ - CamelCase, starting with an uppercase letter
36
+ - Valid characters: letters, digits, `+`, `-`, `.`, `_`
37
+ - Must be globally unique across the spec and all its imports
38
+ - Exported concepts from `requires` modules are **not transitive** — to reference an ancestor's export, list that ancestor in `requires`; if a concept is shared across branches, define it in a common import module instead
39
+
40
+ ## Definition Format
41
+
42
+ A concept definition is a bullet in `***definitions***` that starts with the concept name:
43
+
44
+ ```plain
45
+ ***definitions***
46
+
47
+ - :ConceptName: is a description of what it represents.
48
+ ```
49
+
50
+ Attributes and constraints are nested sub-bullets:
51
+
52
+ ```plain
53
+ ***definitions***
54
+
55
+ - :Task: describes an activity that needs to be done by :User:. :Task: has:
56
+ - Name - a short description (required)
57
+ - Notes - additional details (optional)
58
+ - Due Date - completion deadline (optional)
59
+ ```
60
+
61
+
62
+ ## Validation Checklist
63
+
64
+ - [ ] Name uses `:CamelCase:` notation
65
+ - [ ] Name is globally unique (not defined elsewhere in the file or imports)
66
+ - [ ] Definition starts with the concept name
67
+ - [ ] All referenced concepts (`:OtherConcept:`) are already defined above
68
+ - [ ] No circular references between concepts
69
+ - [ ] Description is clear, concise, and language-agnostic
70
+ - [ ] Trimmed per `concise-specs.md`: one plain sentence, no restatement of the name, no rationale
71
+ - [ ] Placed inside a `***definitions***` section
@@ -0,0 +1,84 @@
1
+ ---
2
+ name: add-functional-spec
3
+ description: >-
4
+ Add a single functional spec to the ***functional specs*** section of a
5
+ ***plain spec file. Use whenever exactly one new functional spec is being
6
+ added — whether the user explicitly asks, or another skill/workflow
7
+ (e.g. `brood`, `bud`) needs to author a new functional spec.
8
+ Every new entry under ***functional specs*** must go through either this
9
+ skill or `add-functional-specs` (the bulk variant for adding multiple specs
10
+ in one pass); hand-authoring functional specs without invoking one of these
11
+ skills is forbidden.
12
+ allowed-tools: [read, write, edit, bash, ls, grep, find]
13
+ ---
14
+
15
+ # Add Functional Spec
16
+
17
+ ## Workflow
18
+
19
+ 1. **Identify the target `.plain` file.** If ambiguous, ask the user.
20
+ 2. **Read the entire file** to understand existing definitions, implementation reqs, and all current functional specs (including those in `requires` modules).
21
+ 3. **Draft the functional spec** following the rules below, then run the review pass in `concise-specs.md` over the draft — trim it to the shortest wording that keeps every fact before any other check.
22
+ 4. **Analyze complexity** — use the `analyze-if-func-spec-too-complex` skill to verify the drafted spec implies ≤ 200 LOC. If too complex, use the `break-down-func-spec` skill to split it, then repeat from step 3 for each resulting spec.
23
+ 5. **Check for conflicts** with every existing functional spec — this is critical. Run `analyze-func-specs` **once** with the new spec plus all existing specs (in the file and in any `requires` chain) as a single batch. The batched analyzer returns every conflicting pair in one call — do **not** invoke a pair-by-pair analyzer. For each conflicting pair it reports, run `resolve-spec-conflict` on that pair; re-run `analyze-func-specs` over the touched set after each resolution until the verdict is `COMPATIBLE`.
24
+ 6. **Append the spec** to the end of the `***functional specs***` section (specs are chronological; new ones go last).
25
+ 7. **Read the file again** to confirm correct placement and syntax.
26
+
27
+ ## Rules
28
+
29
+ ### Complexity Limit
30
+
31
+ Each functional spec must imply a **maximum of 200 changed lines of code**. If the requirement is too large, use the `break-down-func-spec` skill to split it into multiple smaller, independent specs. Do not include LOC estimates in the spec text.
32
+
33
+ ### Chronological Ordering
34
+
35
+ Specs are rendered incrementally, top to bottom. The renderer has **no knowledge of future specs** — only previously rendered specs are in context. This means:
36
+ - A new spec can reference behavior defined by earlier specs.
37
+ - A new spec **cannot** assume anything about specs that come after it.
38
+ - Place the new spec at the correct position if it must come before a future spec; otherwise append at the end.
39
+
40
+ ### Language Agnosticism
41
+
42
+ Write in terms of behavior, concepts, and domain logic — not implementation constructs. Avoid language-specific types, generics syntax, framework annotations, or other constructs tied to a particular language or framework. General technical terms (null values, JSON types, HTTP status codes) are fine. Language-specific guidance belongs in `***implementation reqs***`.
43
+
44
+ ### No Conflicts
45
+
46
+ The new spec must not contradict any existing functional spec. Conflicting specs are the most costly outcome. Before adding, review all existing specs and verify the new one is compatible. Use `analyze-func-specs` to check the new spec against every existing spec in **one batched call** — it lists every conflicting pair, so a pair-by-pair analyzer is not needed. If ambiguity exists, add explicit detail to eliminate any conflicting interpretation. For each conflicting pair the batched analyzer reports, use the `resolve-spec-conflict` skill to diagnose and fix it before proceeding.
47
+
48
+ ### Disambiguation
49
+
50
+ Each functional spec must be unambiguous — the renderer should have only one reasonable interpretation. If a single line is not enough to fully disambiguate the behavior, use **nested sub-bullets** to add detail. Nested lines clarify the parent spec; they do not introduce separate functionality. Even with nested detail, the spec must still imply ≤ 200 LOC.
51
+
52
+ ```plain
53
+ ***functional specs***
54
+
55
+ - A :User: can send a :Message: to a :Conversation:.
56
+ - A :Message: must have non-empty content.
57
+ - The :Message: is appended to the end of the :Conversation:.
58
+ - All :Participant: members of the :Conversation: can see the new :Message:.
59
+ ```
60
+
61
+
62
+ ### Deterministic Interface
63
+
64
+ Specs must be detailed enough that a developer can use the built software without reading the generated code. All external interfaces must be explicit — REST endpoint paths and HTTP methods, CLI command names and arguments, file formats, message schemas, etc. Never leave interface details up to the renderer's discretion.
65
+
66
+ ### Encapsulation
67
+
68
+ Functionality must be self-contained in the spec text. `requires` modules only import functional specs, so do not rely on implementation reqs to convey behavior — they won't be visible in downstream modules.
69
+
70
+ ## Acceptance Tests
71
+
72
+ If the functional spec needs verification, use the `add-acceptance-test` skill to add acceptance tests after inserting the spec.
73
+
74
+ ## Validation Checklist
75
+
76
+ - [ ] Spec implies ≤ 200 lines of code changes
77
+ - [ ] No conflict with any existing functional spec
78
+ - [ ] Written in language-agnostic terms (no language/framework specifics)
79
+ - [ ] All external interfaces are explicit (endpoint paths, methods, CLI args, formats, etc.)
80
+ - [ ] All referenced `:Concepts:` are defined in `***definitions***`
81
+ - [ ] Sentences are short, clear, and unambiguous
82
+ - [ ] Trimmed per `concise-specs.md`: nothing obvious, no rationale, no uncheckable adjectives or hedges, plain words throughout
83
+ - [ ] No redundancy with existing specs
84
+ - [ ] Placed in correct chronological position (usually at the end)
@@ -0,0 +1,118 @@
1
+ ---
2
+ name: add-functional-specs
3
+ description: >-
4
+ Add multiple functional specs to the ***functional specs*** section of a
5
+ ***plain spec file in a single batch. Use whenever more than one new
6
+ functional spec is being added — whether the user explicitly asks, or
7
+ another skill/workflow (e.g. `brood`, `bud`) needs to author
8
+ several specs in one pass. Bulk-writing or hand-authoring functional
9
+ specs without invoking this skill is forbidden; for adding a single spec,
10
+ use add-functional-spec instead.
11
+ allowed-tools: [read, write, edit, bash, ls, grep, find]
12
+ ---
13
+
14
+ # Add Functional Specs
15
+
16
+ ## When to Use
17
+
18
+ - The user asks for several functional specs to be added in one go (e.g. "add these three specs", "spec out this feature in a few bullets").
19
+ - A higher-level skill or workflow (`brood`, `bud`, `debug-specs`) needs to author a tight group of related specs.
20
+ - Anywhere you would otherwise be tempted to write more than one functional spec without running per-spec analysis.
21
+
22
+ If you only need to add a single spec, use the `add-functional-spec` skill instead. Either way, **never** edit the `***functional specs***` section by hand — every new entry must go through one of these two skills so the complexity and conflict checks actually run.
23
+
24
+ ## Workflow
25
+
26
+ This skill is `add-functional-spec` applied **one spec at a time, in order**, with no shortcuts. The batch never escapes per-spec rigor.
27
+
28
+ 1. **Identify the target `.plain` file.** If ambiguous, ask the user.
29
+ 2. **Read the entire file** to understand existing definitions, implementation reqs, and all current functional specs (including those reachable via `import` / `requires`).
30
+ 3. **Draft all the specs you intend to add**, in the chronological order they should appear. Keep the drafts in a working list — nothing is inserted yet. Run the review pass in `concise-specs.md` over every draft before continuing; trim each to the shortest wording that keeps every fact.
31
+ 4. **For each drafted spec, in order:**
32
+ 1. **Analyze complexity.** Run `analyze-if-func-spec-too-complex` on the spec. If the verdict is `TOO COMPLEX`, run `break-down-func-spec`, replace the entry in the working list with the resulting smaller specs (preserving order), and restart this step on the first of the replacements.
33
+ 2. **Check for conflicts.** Run `analyze-func-specs` **once** with this single input set:
34
+ - the new spec, plus
35
+ - every existing functional spec in the file and its `requires` chain, plus
36
+ - every spec from this batch that has already been inserted.
37
+
38
+ The batched analyzer returns every conflicting pair in one call — do **not** loop over pairs invoking a per-pair analyzer. For each conflicting pair it reports, run `resolve-spec-conflict`. Apply the resolution — which may revise the new spec, an existing spec, or both — then re-run `analyze-func-specs` once over the touched set until the verdict is `COMPATIBLE`.
39
+ 3. **Append the spec** to the `***functional specs***` section. Specs are chronological; the new entry goes at the end (unless an earlier existing spec must come *after* it — in that rare case, insert at the correct position).
40
+ 5. **Read the file again** to confirm correct placement, ordering, and syntax for the full batch.
41
+
42
+ Order matters: each new spec is inserted only after its complexity and conflict checks pass, so subsequent specs in the batch are always checked against an already-validated file.
43
+
44
+ ## Rules
45
+
46
+ All the rules from `add-functional-spec` apply per individual spec. They are restated here so this skill is self-contained.
47
+
48
+ ### Complexity Limit (per spec)
49
+
50
+ Each functional spec must imply a **maximum of 200 changed lines of code**. If a spec is too large, use `break-down-func-spec` to split it into multiple smaller, independent specs. Do not include LOC estimates in the spec text.
51
+
52
+ ### Chronological Ordering
53
+
54
+ Specs are rendered incrementally, top to bottom. The renderer has **no knowledge of future specs** — only previously rendered specs are in context.
55
+ - A new spec can reference behavior defined by earlier specs.
56
+ - A new spec **cannot** assume anything about specs that come after it.
57
+ - Order the batch so that each spec only depends on specs that precede it. If two new specs would otherwise reference each other, the dependent one comes second.
58
+
59
+ ### Language Agnosticism
60
+
61
+ Write in terms of behavior, concepts, and domain logic — not implementation constructs. Avoid language-specific types, generics syntax, framework annotations, or other constructs tied to a particular language or framework. General technical terms (null values, JSON types, HTTP status codes) are fine. Language-specific guidance belongs in `***implementation reqs***`.
62
+
63
+ ### No Conflicts (full coverage via one batched call per spec)
64
+
65
+ The new specs must not contradict each other **and** must not contradict any existing functional spec. Conflicting specs are the most costly outcome. The conflict check must cover:
66
+ - every (new × existing) pair, and
67
+ - every (new × new) pair within the batch.
68
+
69
+ That coverage is achieved by running `analyze-func-specs` **once per spec being inserted**, with the new spec plus every existing spec plus every already-inserted spec from this batch passed in as a single set. The batched analyzer lists every conflicting pair in one call — do not invoke a pair-by-pair analyzer. If ambiguity exists, add explicit detail to eliminate any conflicting interpretation. For each conflicting pair the batched analyzer reports, use the `resolve-spec-conflict` skill to diagnose and fix it before proceeding.
70
+
71
+ ### Disambiguation (per spec)
72
+
73
+ Each functional spec must be unambiguous — the renderer should have only one reasonable interpretation. If a single line is not enough to fully disambiguate the behavior, use **nested sub-bullets** to add detail. Nested lines clarify the parent spec; they do not introduce separate functionality. Even with nested detail, the spec must still imply ≤ 200 LOC.
74
+
75
+ ```plain
76
+ ***functional specs***
77
+
78
+ - A :User: can send a :Message: to a :Conversation:.
79
+ - A :Message: must have non-empty content.
80
+ - The :Message: is appended to the end of the :Conversation:.
81
+ - All :Participant: members of the :Conversation: can see the new :Message:.
82
+ ```
83
+
84
+
85
+ ### Deterministic Interface
86
+
87
+ Specs must be detailed enough that a developer can use the built software without reading the generated code. All external interfaces must be explicit — REST endpoint paths and HTTP methods, CLI command names and arguments, file formats, message schemas, etc. Never leave interface details up to the renderer's discretion.
88
+
89
+ ### Encapsulation
90
+
91
+ Functionality must be self-contained in the spec text. `requires` modules only import functional specs, so do not rely on implementation reqs to convey behavior — they won't be visible in downstream modules.
92
+
93
+ ## Acceptance Tests
94
+
95
+ If any of the newly added functional specs need verification, use the `add-acceptance-test` skill to add acceptance tests after the batch has been inserted. Do this per spec, not as part of the bulk pass.
96
+
97
+ ## Anti-Patterns
98
+
99
+ - **Don't skip per-spec checks because the batch "feels" small.** Even two specs require two complexity checks and a batched conflict check that includes both new specs.
100
+ - **Don't fall back to pair-by-pair conflict analysis.** Use `analyze-func-specs` with the full relevant set once per inserted spec — not `analyze-2-func-specs` across every pair.
101
+ - **Don't run all complexity checks first and all conflict checks last.** Interleave them per spec, as described in the Workflow — a failed complexity check earlier would otherwise waste later conflict checks.
102
+ - **Don't insert every spec first and then analyze.** A bad spec already in the file pollutes subsequent conflict analyses.
103
+ - **Don't fall back to hand-authoring** because there are "a lot" of specs to add. The right answer is more analyzer calls, not fewer.
104
+ - **Don't use this skill for a single spec.** Use `add-functional-spec` — it's the same checks without the bulk bookkeeping.
105
+
106
+ ## Validation Checklist
107
+
108
+ - [ ] Every spec in the batch implies ≤ 200 lines of code changes (verified via `analyze-if-func-spec-too-complex`)
109
+ - [ ] No conflict between any new spec and any existing spec (verified via batched `analyze-func-specs` calls)
110
+ - [ ] No conflict between any two new specs in the batch (covered by the same batched `analyze-func-specs` calls)
111
+ - [ ] Every conflicting pair the batched analyzer reported was resolved via `resolve-spec-conflict` before the batch completed
112
+ - [ ] All specs written in language-agnostic terms (no language/framework specifics)
113
+ - [ ] All external interfaces explicit (endpoint paths, methods, CLI args, formats, etc.)
114
+ - [ ] All referenced `:Concepts:` are defined in `***definitions***`
115
+ - [ ] Sentences are short, clear, and unambiguous
116
+ - [ ] Every spec trimmed per `concise-specs.md`: nothing obvious, no rationale, no uncheckable adjectives or hedges, plain words throughout
117
+ - [ ] No redundancy with existing specs or within the batch
118
+ - [ ] Specs placed in correct chronological positions