@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.
- package/.pi/themes/turri-dark.json +80 -0
- package/.pi/themes/turri-light.json +82 -0
- package/LICENSE +21 -0
- package/README.md +272 -2
- package/assets/jellyfish/dark-00.png +0 -0
- package/assets/jellyfish/dark-01.png +0 -0
- package/assets/jellyfish/dark-02.png +0 -0
- package/assets/jellyfish/dark-03.png +0 -0
- package/assets/jellyfish/dark-04.png +0 -0
- package/assets/jellyfish/dark-05.png +0 -0
- package/assets/jellyfish/dark-06.png +0 -0
- package/assets/jellyfish/dark-07.png +0 -0
- package/assets/jellyfish/dark-08.png +0 -0
- package/assets/jellyfish/dark-09.png +0 -0
- package/assets/jellyfish/dark-10.png +0 -0
- package/assets/jellyfish/dark-11.png +0 -0
- package/assets/jellyfish/dark-12.png +0 -0
- package/assets/jellyfish/dark-13.png +0 -0
- package/assets/jellyfish/dark-14.png +0 -0
- package/assets/jellyfish/fallback.txt +252 -0
- package/assets/jellyfish/light-00.png +0 -0
- package/assets/jellyfish/light-01.png +0 -0
- package/assets/jellyfish/light-02.png +0 -0
- package/assets/jellyfish/light-03.png +0 -0
- package/assets/jellyfish/light-04.png +0 -0
- package/assets/jellyfish/light-05.png +0 -0
- package/assets/jellyfish/light-06.png +0 -0
- package/assets/jellyfish/light-07.png +0 -0
- package/assets/jellyfish/light-08.png +0 -0
- package/assets/jellyfish/light-09.png +0 -0
- package/assets/jellyfish/light-10.png +0 -0
- package/assets/jellyfish/light-11.png +0 -0
- package/assets/jellyfish/light-12.png +0 -0
- package/assets/jellyfish/light-13.png +0 -0
- package/assets/jellyfish/light-14.png +0 -0
- package/bin/turri.mjs +29 -0
- package/dist/ask.js +149 -0
- package/dist/brand.js +50 -0
- package/dist/btw.js +174 -0
- package/dist/chat-models.js +37 -0
- package/dist/chat-skills.js +18 -0
- package/dist/cli.js +178 -0
- package/dist/config-command.js +197 -0
- package/dist/config-edit.js +367 -0
- package/dist/config.js +489 -0
- package/dist/conform-cli.js +29 -0
- package/dist/cultivate-cli.js +110 -0
- package/dist/drift-cli.js +25 -0
- package/dist/environment.js +70 -0
- package/dist/extension.js +2372 -0
- package/dist/genome.js +301 -0
- package/dist/graph.js +246 -0
- package/dist/identity.js +35 -0
- package/dist/init-config.js +511 -0
- package/dist/judge.js +62 -0
- package/dist/lineage-cli.js +13 -0
- package/dist/loop-cli.js +132 -0
- package/dist/loop-tools.js +225 -0
- package/dist/mature-tools.js +193 -0
- package/dist/model-check.js +117 -0
- package/dist/module-report.js +9 -0
- package/dist/pi-launch.js +31 -0
- package/dist/pi.js +813 -0
- package/dist/plain/check.js +76 -0
- package/dist/plain/concepts.js +213 -0
- package/dist/plain/errors.js +43 -0
- package/dist/plain/files.js +57 -0
- package/dist/plain/highlight.js +195 -0
- package/dist/plain/index.js +15 -0
- package/dist/plain/liquid.js +129 -0
- package/dist/plain/markdown.js +208 -0
- package/dist/plain/parser.js +752 -0
- package/dist/plain/plain.tmLanguage.json +124 -0
- package/dist/plain/spec.js +291 -0
- package/dist/plain/stdlib.js +44 -0
- package/dist/question-dialog.js +125 -0
- package/dist/questioning.js +109 -0
- package/dist/quiet.js +125 -0
- package/dist/regenerate/activity.js +187 -0
- package/dist/regenerate/agent-env.js +190 -0
- package/dist/regenerate/agent-shell.js +114 -0
- package/dist/regenerate/arbiter.js +133 -0
- package/dist/regenerate/audit.js +203 -0
- package/dist/regenerate/cases.js +83 -0
- package/dist/regenerate/change-view.js +102 -0
- package/dist/regenerate/choose-conformance.js +117 -0
- package/dist/regenerate/chunk-plan.js +625 -0
- package/dist/regenerate/codebase.js +75 -0
- package/dist/regenerate/command-check.js +312 -0
- package/dist/regenerate/compaction.js +20 -0
- package/dist/regenerate/confine.js +310 -0
- package/dist/regenerate/conform.js +133 -0
- package/dist/regenerate/conformance-agents.js +955 -0
- package/dist/regenerate/conformance.js +936 -0
- package/dist/regenerate/conversation-writes.js +100 -0
- package/dist/regenerate/credentials.js +88 -0
- package/dist/regenerate/debug-log.js +228 -0
- package/dist/regenerate/debugger.js +90 -0
- package/dist/regenerate/delivery.js +19 -0
- package/dist/regenerate/diagnose-job.js +40 -0
- package/dist/regenerate/diagnose.js +81 -0
- package/dist/regenerate/diff-view.js +240 -0
- package/dist/regenerate/drift.js +194 -0
- package/dist/regenerate/engine.js +118 -0
- package/dist/regenerate/environment-error.js +220 -0
- package/dist/regenerate/job-log.js +102 -0
- package/dist/regenerate/job-panel.js +336 -0
- package/dist/regenerate/jobs-tree.js +300 -0
- package/dist/regenerate/jobs.js +427 -0
- package/dist/regenerate/lanes.js +32 -0
- package/dist/regenerate/lineage.js +384 -0
- package/dist/regenerate/loop.js +1435 -0
- package/dist/regenerate/masking.js +95 -0
- package/dist/regenerate/notes.js +397 -0
- package/dist/regenerate/os-sandbox.js +243 -0
- package/dist/regenerate/paths.js +165 -0
- package/dist/regenerate/plain-palette.js +83 -0
- package/dist/regenerate/prompt.js +704 -0
- package/dist/regenerate/records.js +294 -0
- package/dist/regenerate/regenerate.js +598 -0
- package/dist/regenerate/regression.js +181 -0
- package/dist/regenerate/release.js +262 -0
- package/dist/regenerate/requires.js +241 -0
- package/dist/regenerate/resources.js +164 -0
- package/dist/regenerate/self-check.js +111 -0
- package/dist/regenerate/services.js +155 -0
- package/dist/regenerate/shell.js +319 -0
- package/dist/regenerate/side-panel.js +278 -0
- package/dist/regenerate/spec-map-view.js +574 -0
- package/dist/regenerate/spec-map.js +561 -0
- package/dist/regenerate/spec-steps.js +527 -0
- package/dist/regenerate/state.js +10 -0
- package/dist/regenerate/steer.js +91 -0
- package/dist/regenerate/steering.js +119 -0
- package/dist/regenerate/stop-report.js +161 -0
- package/dist/regenerate/submit-work.js +71 -0
- package/dist/regenerate/test-kinds.js +124 -0
- package/dist/regenerate/test-scripts.js +695 -0
- package/dist/regenerate/testing.js +406 -0
- package/dist/regenerate/transcript-view.js +1 -0
- package/dist/regenerate/unit-gate.js +20 -0
- package/dist/regenerate/unit-review.js +347 -0
- package/dist/regenerate/web.js +256 -0
- package/dist/regenerate/workspace.js +99 -0
- package/dist/regenerate-cli.js +68 -0
- package/dist/release-agent.js +114 -0
- package/dist/release-cli.js +131 -0
- package/dist/release-tools.js +148 -0
- package/dist/review/live.js +165 -0
- package/dist/rules.js +47 -0
- package/dist/self-invocation.js +110 -0
- package/dist/setup.js +245 -0
- package/dist/skill-progress.js +78 -0
- package/dist/skill.js +149 -0
- package/dist/skills.js +74 -0
- package/dist/spec-diff-cli.js +37 -0
- package/dist/spec-tools.js +155 -0
- package/dist/stack.js +158 -0
- package/dist/stacks.js +97 -0
- package/dist/stdlib.js +100 -0
- package/dist/terminal-images.js +46 -0
- package/dist/tools.js +242 -0
- package/dist/validate-cli.js +52 -0
- package/docs/README.md +58 -0
- package/docs/authoring-plain.md +245 -0
- package/docs/config.md +353 -0
- package/docs/deploy.md +109 -0
- package/docs/development.md +75 -0
- package/docs/headless.md +148 -0
- package/docs/images/how-turri-works.svg +50 -0
- package/docs/images/turri-banner.png +0 -0
- package/docs/installation.md +118 -0
- package/docs/parser.md +108 -0
- package/docs/regenerating.md +1116 -0
- package/docs/sandbox.md +233 -0
- package/docs/skills-and-gates.md +254 -0
- package/docs/theming.md +76 -0
- package/docs/using.md +454 -0
- package/genome/rules/bullet-continuation.md +69 -0
- package/genome/rules/concise-specs-examples.md +431 -0
- package/genome/rules/concise-specs-integration-examples.md +270 -0
- package/genome/rules/concise-specs.md +80 -0
- package/genome/rules/definitions.md +107 -0
- package/genome/rules/examples/integration-embedded-testing/run_conformance_tests_java.sh +163 -0
- package/genome/rules/examples/integration-embedded-testing/run_unittests_java.sh +51 -0
- package/genome/rules/exported-concepts.md +39 -0
- package/genome/rules/func-specs.md +129 -0
- package/genome/rules/impl-reqs.md +68 -0
- package/genome/rules/import-modules.md +48 -0
- package/genome/rules/integration-embedded-testing.md +276 -0
- package/genome/rules/integration-embedded.md +171 -0
- package/genome/rules/integration-standalone.md +135 -0
- package/genome/rules/integrations.md +137 -0
- package/genome/rules/linked-resources.md +69 -0
- package/genome/rules/module-structure.md +105 -0
- package/genome/rules/project-model.md +88 -0
- package/genome/rules/required-concepts.md +44 -0
- package/genome/rules/requires-modules.md +80 -0
- package/genome/rules/stdlib.md +73 -0
- package/genome/rules/test-reqs.md +57 -0
- package/genome/skills/add-acceptance-test/SKILL.md +100 -0
- package/genome/skills/add-concept/SKILL.md +71 -0
- package/genome/skills/add-functional-spec/SKILL.md +84 -0
- package/genome/skills/add-functional-specs/SKILL.md +118 -0
- package/genome/skills/add-implementation-requirement/SKILL.md +86 -0
- package/genome/skills/add-resource/SKILL.md +105 -0
- package/genome/skills/add-template/SKILL.md +64 -0
- package/genome/skills/add-test-requirement/SKILL.md +73 -0
- package/genome/skills/analyze-2-func-specs/SKILL.md +101 -0
- package/genome/skills/analyze-func-specs/SKILL.md +123 -0
- package/genome/skills/analyze-if-func-spec-too-complex/SKILL.md +211 -0
- package/genome/skills/break-down-func-spec/SKILL.md +205 -0
- package/genome/skills/brood/SKILL.md +229 -0
- package/genome/skills/brood/references/intent.md +35 -0
- package/genome/skills/brood/references/product.md +101 -0
- package/genome/skills/brood/references/stack.md +61 -0
- package/genome/skills/brood/references/testing.md +56 -0
- package/genome/skills/bud/SKILL.md +148 -0
- package/genome/skills/bud/references/checklist.md +44 -0
- package/genome/skills/bud/references/intent.md +30 -0
- package/genome/skills/check-plain-env/SKILL.md +285 -0
- package/genome/skills/consolidate-concepts/SKILL.md +192 -0
- package/genome/skills/create-import-module/SKILL.md +104 -0
- package/genome/skills/create-requires-module/SKILL.md +109 -0
- package/genome/skills/debug-specs/SKILL.md +188 -0
- package/genome/skills/implement-conformance-testing-script/SKILL.md +238 -0
- package/genome/skills/implement-conformance-testing-script/assets/run_conformance_tests_cypress.ps1 +337 -0
- package/genome/skills/implement-conformance-testing-script/assets/run_conformance_tests_golang.ps1 +111 -0
- package/genome/skills/implement-conformance-testing-script/assets/run_conformance_tests_java.sh +136 -0
- package/genome/skills/implement-conformance-testing-script/assets/run_conformance_tests_python.ps1 +103 -0
- package/genome/skills/implement-conformance-testing-script/assets/run_conformance_tests_python.sh +150 -0
- package/genome/skills/implement-unit-testing-script/SKILL.md +160 -0
- package/genome/skills/implement-unit-testing-script/assets/run_unittests_flutter.ps1 +87 -0
- package/genome/skills/implement-unit-testing-script/assets/run_unittests_golang.ps1 +73 -0
- package/genome/skills/implement-unit-testing-script/assets/run_unittests_java.sh +72 -0
- package/genome/skills/implement-unit-testing-script/assets/run_unittests_python.ps1 +81 -0
- package/genome/skills/implement-unit-testing-script/assets/run_unittests_python.sh +98 -0
- package/genome/skills/implement-unit-testing-script/assets/run_unittests_react.ps1 +87 -0
- package/genome/skills/init-plain-project/SKILL.md +117 -0
- package/genome/skills/init-plain-project/references/checklist.md +30 -0
- package/genome/skills/mature/SKILL.md +126 -0
- package/genome/skills/refactor-module/SKILL.md +196 -0
- package/genome/skills/resolve-section-ownership/SKILL.md +64 -0
- package/genome/skills/resolve-spec-conflict/SKILL.md +96 -0
- package/genome/skills/spawn/SKILL.md +163 -0
- package/package.json +68 -4
- package/stdlib/backend/common.plain +25 -0
- package/stdlib/backend/conformance/common.plain +12 -0
- package/stdlib/backend/conformance/go-gin.plain +9 -0
- package/stdlib/backend/conformance/go-nethttp.plain +9 -0
- package/stdlib/backend/conformance/java-springboot.plain +9 -0
- package/stdlib/backend/conformance/python-django.plain +9 -0
- package/stdlib/backend/conformance/python-fastapi.plain +9 -0
- package/stdlib/backend/conformance/python-flask.plain +9 -0
- package/stdlib/backend/conformance/rust-axum.plain +9 -0
- package/stdlib/backend/conformance/typescript-express.plain +9 -0
- package/stdlib/backend/conformance/typescript-fastify.plain +9 -0
- package/stdlib/backend/conformance/typescript-nestjs.plain +9 -0
- package/stdlib/backend/go-gin.plain +18 -0
- package/stdlib/backend/go-nethttp.plain +18 -0
- package/stdlib/backend/java-springboot.plain +19 -0
- package/stdlib/backend/python-django.plain +19 -0
- package/stdlib/backend/python-fastapi.plain +23 -0
- package/stdlib/backend/python-flask.plain +23 -0
- package/stdlib/backend/rust-axum.plain +17 -0
- package/stdlib/backend/typescript-express.plain +19 -0
- package/stdlib/backend/typescript-fastify.plain +19 -0
- package/stdlib/backend/typescript-nestjs.plain +19 -0
- package/stdlib/cli/common.plain +17 -0
- package/stdlib/cli/conformance/common.plain +11 -0
- package/stdlib/cli/conformance/go-cobra.plain +9 -0
- package/stdlib/cli/conformance/go-flag.plain +9 -0
- package/stdlib/cli/conformance/java-picocli.plain +9 -0
- package/stdlib/cli/conformance/python-argparse.plain +9 -0
- package/stdlib/cli/conformance/python-click.plain +9 -0
- package/stdlib/cli/conformance/python-typer.plain +9 -0
- package/stdlib/cli/conformance/rust-clap.plain +9 -0
- package/stdlib/cli/conformance/typescript-commander.plain +9 -0
- package/stdlib/cli/go-cobra.plain +14 -0
- package/stdlib/cli/go-flag.plain +14 -0
- package/stdlib/cli/java-picocli.plain +15 -0
- package/stdlib/cli/python-argparse.plain +18 -0
- package/stdlib/cli/python-click.plain +16 -0
- package/stdlib/cli/python-typer.plain +16 -0
- package/stdlib/cli/rust-clap.plain +14 -0
- package/stdlib/cli/typescript-commander.plain +17 -0
- package/stdlib/frontend/angular.plain +17 -0
- package/stdlib/frontend/common.plain +17 -0
- package/stdlib/frontend/conformance/angular.plain +5 -0
- package/stdlib/frontend/conformance/common.plain +11 -0
- package/stdlib/frontend/conformance/react-vite.plain +5 -0
- package/stdlib/frontend/conformance/sveltekit-spa.plain +5 -0
- package/stdlib/frontend/conformance/vue-vite.plain +5 -0
- package/stdlib/frontend/react-vite.plain +16 -0
- package/stdlib/frontend/sveltekit-spa.plain +16 -0
- package/stdlib/frontend/vue-vite.plain +16 -0
- package/stdlib/lang/go.plain +13 -0
- package/stdlib/lang/java.plain +12 -0
- package/stdlib/lang/python.plain +18 -0
- package/stdlib/lang/rust.plain +12 -0
- package/stdlib/lang/typescript.plain +13 -0
- package/stdlib/library/common.plain +15 -0
- package/stdlib/library/conformance/common.plain +9 -0
- package/stdlib/library/conformance/go.plain +9 -0
- package/stdlib/library/conformance/java-gradle.plain +9 -0
- package/stdlib/library/conformance/java-maven.plain +9 -0
- package/stdlib/library/conformance/python.plain +9 -0
- package/stdlib/library/conformance/rust.plain +9 -0
- package/stdlib/library/conformance/typescript.plain +9 -0
- package/stdlib/library/go.plain +12 -0
- package/stdlib/library/java-gradle.plain +13 -0
- package/stdlib/library/java-maven.plain +13 -0
- package/stdlib/library/python.plain +13 -0
- package/stdlib/library/rust.plain +12 -0
- package/stdlib/library/typescript.plain +15 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: analyze-if-func-spec-too-complex
|
|
3
|
+
description: >-
|
|
4
|
+
Analyze a functional spec to determine if it is too complex for the renderer.
|
|
5
|
+
A spec is too complex if it would produce more than 200 lines of code changes.
|
|
6
|
+
Use after drafting a new functional spec (during `add-functional-spec`, or
|
|
7
|
+
per spec during `add-functional-specs`) to verify it fits within the
|
|
8
|
+
complexity limit before inserting it.
|
|
9
|
+
allowed-tools: [read, ls, grep, find]
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Analyze If Functional Spec Is Too Complex
|
|
13
|
+
|
|
14
|
+
## Why This Matters
|
|
15
|
+
|
|
16
|
+
The renderer enforces a hard complexity limit: each functional spec must imply a **maximum of 200 changed lines of code**. If a spec exceeds this, the renderer rejects it with "Functional spec too complex!" and the spec must be broken down. Catching this before insertion saves a failed render cycle.
|
|
17
|
+
|
|
18
|
+
## Input
|
|
19
|
+
|
|
20
|
+
A drafted functional spec (not yet inserted into the file), plus the full context of the `.plain` file it will be added to — definitions, implementation reqs, and existing functional specs.
|
|
21
|
+
|
|
22
|
+
## Workflow
|
|
23
|
+
|
|
24
|
+
1. **Read the full `.plain` file** (and any `requires`/`import` modules) to understand the current codebase context — what already exists and what the new spec builds on.
|
|
25
|
+
2. **Read the drafted functional spec** carefully.
|
|
26
|
+
3. **Run the complexity analysis** using the checklist below.
|
|
27
|
+
4. **Output the verdict and nothing else** — either `ACCEPTABLE` or `TOO COMPLEX`. No reasoning, no LOC estimate, no breakdown.
|
|
28
|
+
|
|
29
|
+
## Complexity Analysis Checklist
|
|
30
|
+
|
|
31
|
+
Work through each indicator. A single "yes" does not automatically mean the spec is too complex, but multiple "yes" answers are a strong signal.
|
|
32
|
+
|
|
33
|
+
### 0. First-Spec Bootstrap Cost
|
|
34
|
+
|
|
35
|
+
Is this the first functional spec in a new root module with no implementation baseline supplied by
|
|
36
|
+
`requires`? If so, include the implicit cost of creating the project structure, package metadata,
|
|
37
|
+
framework configuration, entry point, initial source files, and unit-test infrastructure.
|
|
38
|
+
|
|
39
|
+
The first spec must be substantially simpler than a later spec. It should expose one minimal,
|
|
40
|
+
deterministic capability that can be invoked and tested. Setup without an observable result is not
|
|
41
|
+
acceptable, but combining bootstrap work with persistence, integrations, multiple interfaces,
|
|
42
|
+
branching workflows, or cross-cutting behavior is a strong `TOO COMPLEX` signal.
|
|
43
|
+
|
|
44
|
+
### 1. Number of Distinct Behaviors
|
|
45
|
+
|
|
46
|
+
Does the spec describe more than one independently testable behavior?
|
|
47
|
+
|
|
48
|
+
Too complex:
|
|
49
|
+
```plain
|
|
50
|
+
***functional specs***
|
|
51
|
+
|
|
52
|
+
- A :User: can create, edit, delete, and archive :Task: items, with validation on all fields and confirmation dialogs for destructive actions.
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Acceptable (one behavior each):
|
|
56
|
+
```plain
|
|
57
|
+
***functional specs***
|
|
58
|
+
|
|
59
|
+
- A :User: can create :Task:. Only valid :Task: items can be added.
|
|
60
|
+
|
|
61
|
+
- A :User: can edit :Task:.
|
|
62
|
+
|
|
63
|
+
- A :User: can delete :Task:.
|
|
64
|
+
|
|
65
|
+
- A :User: can archive :Task:.
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### 2. Number of Concepts Introduced or Modified
|
|
70
|
+
|
|
71
|
+
Does the spec require introducing new data structures, UI components, API endpoints, or other constructs that don't already exist? Count them.
|
|
72
|
+
|
|
73
|
+
- 0–1 new constructs → likely fine
|
|
74
|
+
- 2–3 new constructs → borderline, examine closely
|
|
75
|
+
- 4+ new constructs → almost certainly too complex
|
|
76
|
+
|
|
77
|
+
### 3. Branching Logic and Conditions
|
|
78
|
+
|
|
79
|
+
Does the spec describe multiple conditional paths, modes, or special cases?
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
Too complex:
|
|
83
|
+
```plain
|
|
84
|
+
***functional specs***
|
|
85
|
+
|
|
86
|
+
- :Order: processing depends on :OrderType:. Standard orders are validated and stored. Express orders skip validation and are queued for immediate dispatch. Bulk orders are split into sub-orders of 100 items each, validated individually, and processed in parallel with progress tracking.
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Acceptable (separate the modes):
|
|
90
|
+
```plain
|
|
91
|
+
***functional specs***
|
|
92
|
+
|
|
93
|
+
- A standard :Order: is validated and stored.
|
|
94
|
+
|
|
95
|
+
- An express :Order: is queued for immediate dispatch without validation.
|
|
96
|
+
|
|
97
|
+
- A bulk :Order: is split into sub-orders of 100 items each.
|
|
98
|
+
- Each sub-order is processed individually.
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### 4. Cross-Cutting Concerns
|
|
102
|
+
|
|
103
|
+
Does the spec bundle core functionality with cross-cutting concerns like error handling, logging, retry logic, pagination, or caching?
|
|
104
|
+
|
|
105
|
+
Too complex:
|
|
106
|
+
```plain
|
|
107
|
+
***functional specs***
|
|
108
|
+
|
|
109
|
+
- :Resource: items are fetched from the external API with pagination support, retry on transient errors with exponential backoff, caching for 5 minutes, and logging of all API calls.
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Acceptable (separate concerns):
|
|
113
|
+
```plain
|
|
114
|
+
***functional specs***
|
|
115
|
+
- :Resource: items are fetched from the external API.
|
|
116
|
+
|
|
117
|
+
- :Resource: items are fetched from the external API in pages.
|
|
118
|
+
|
|
119
|
+
- Fetching :Resource: items is retried on transient errors using exponential backoff.
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### 5. UI Complexity
|
|
123
|
+
|
|
124
|
+
Does the spec describe a complete screen or page with multiple interactive elements, layouts, and state transitions?
|
|
125
|
+
|
|
126
|
+
Too complex:
|
|
127
|
+
```plain
|
|
128
|
+
***functional specs***
|
|
129
|
+
|
|
130
|
+
- The dashboard shows :User: profile, recent :Task: items in a sortable table, a notification bell with unread count, and a sidebar with navigation links that highlights the active page.
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Acceptable (build incrementally):
|
|
134
|
+
```plain
|
|
135
|
+
***functional specs***
|
|
136
|
+
|
|
137
|
+
- A dashboard page is shown for :User:.
|
|
138
|
+
|
|
139
|
+
- Recent :Task: items are shown in a sortable table on the dashboard.
|
|
140
|
+
|
|
141
|
+
- A notification indicator with the unread count is shown on the dashboard.
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### 6. Data Transformation Complexity
|
|
145
|
+
|
|
146
|
+
Does the spec involve complex data mapping, aggregation, or transformation across multiple entities?
|
|
147
|
+
|
|
148
|
+
- Simple field mapping or filtering → likely fine
|
|
149
|
+
- Multi-step transformations, joins across entities, or aggregations → likely too complex
|
|
150
|
+
|
|
151
|
+
### 7. Implied Technical Component
|
|
152
|
+
|
|
153
|
+
Does the spec imply building a substantial technical component — an engine, parser, scheduler, layout algorithm, state machine, or sync mechanism — **in addition to** the behavior it describes? A component is not a free primitive: code must be generated for it too, so it counts toward the 200-LOC budget and must be evaluated as part of the estimate. A spec that needs a component **and** wires up behavior on top of it is really two bodies of code in one spec — a strong "too complex" signal. Count the component's implementation, not just the glue that calls it.
|
|
154
|
+
|
|
155
|
+
Too complex (builds the component and uses it in one spec):
|
|
156
|
+
```plain
|
|
157
|
+
***functional specs***
|
|
158
|
+
|
|
159
|
+
- A :Report: is exported to PDF, laying out multi-page tables with repeating headers and page numbers, and charts rendered from :Report: data.
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Acceptable (component in its own spec, then referenced):
|
|
163
|
+
```plain
|
|
164
|
+
***functional specs***
|
|
165
|
+
|
|
166
|
+
- :PdfRenderer: lays out multi-page tables from structured content.
|
|
167
|
+
- Table headers repeat at the top of each page.
|
|
168
|
+
- Each page shows its page number.
|
|
169
|
+
|
|
170
|
+
- A :Report: is exported to PDF using :PdfRenderer:, embedding charts rendered from :Report: data.
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
When this indicator fires, the fix is `break-down-func-spec` Strategy 6 — extract the component into its own earlier spec and reference it.
|
|
174
|
+
|
|
175
|
+
### 8. Rough LOC Estimation
|
|
176
|
+
|
|
177
|
+
Mentally estimate the implementation. Consider:
|
|
178
|
+
- New files that need to be created
|
|
179
|
+
- New functions/methods
|
|
180
|
+
- Code for any implied technical component (engine, parser, algorithm), not just the glue that uses it
|
|
181
|
+
- Data model changes (schema, migrations, types)
|
|
182
|
+
- UI components (if applicable)
|
|
183
|
+
- Test setup and assertions (unit tests are auto-generated alongside)
|
|
184
|
+
- For the first spec in a new root module, all project and test scaffold implied by implementation requirements
|
|
185
|
+
- Error handling paths
|
|
186
|
+
- Import statements and boilerplate
|
|
187
|
+
|
|
188
|
+
If the estimate exceeds ~150 LOC, the spec is at high risk of being too complex (leave headroom for the renderer to add necessary boilerplate).
|
|
189
|
+
|
|
190
|
+
## Output Format
|
|
191
|
+
|
|
192
|
+
The skill emits exactly one of these two strings, with no surrounding text, explanation, estimate, or breakdown:
|
|
193
|
+
|
|
194
|
+
```
|
|
195
|
+
ACCEPTABLE
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
or
|
|
199
|
+
|
|
200
|
+
```
|
|
201
|
+
TOO COMPLEX
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
The internal analysis (checklist, LOC estimation, reasoning) informs the verdict but must not appear in the output. The caller decides what to do with the result.
|
|
205
|
+
|
|
206
|
+
## Integration with add-functional-spec / add-functional-specs
|
|
207
|
+
|
|
208
|
+
This skill is called during step 3 of the `add-functional-spec` workflow (or per spec during `add-functional-specs`), after drafting a spec but **before** inserting it into the file. The caller acts on the one-word verdict:
|
|
209
|
+
|
|
210
|
+
- **ACCEPTABLE** — proceed to insert the spec.
|
|
211
|
+
- **TOO COMPLEX** — invoke `break-down-func-spec` to produce smaller specs, then insert each one individually (running conflict checks on each).
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: break-down-func-spec
|
|
3
|
+
description: >-
|
|
4
|
+
Break down a functional spec that is too complex into smaller specs that
|
|
5
|
+
each imply ≤ 200 lines of code. Use when analyze-if-func-spec-too-complex
|
|
6
|
+
flags a spec as TOO COMPLEX, or when a spec is suspected of being too large.
|
|
7
|
+
allowed-tools: [read, write, edit, bash, ls, grep, find]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Break Down Functional Spec
|
|
11
|
+
|
|
12
|
+
## When to Use
|
|
13
|
+
|
|
14
|
+
- `analyze-if-func-spec-too-complex` flagged a spec as TOO COMPLEX.
|
|
15
|
+
- A spec is suspected of exceeding the 200 LOC limit and needs to be split preemptively.
|
|
16
|
+
- A spec bundles multiple behaviors, constructs, or concerns that should be separated.
|
|
17
|
+
|
|
18
|
+
## Input
|
|
19
|
+
|
|
20
|
+
The functional spec to break down, plus the full `.plain` file it belongs to.
|
|
21
|
+
|
|
22
|
+
## Workflow
|
|
23
|
+
|
|
24
|
+
1. **Read the full `.plain` file** — definitions, implementation reqs, and all functional specs (including `requires` modules) to understand context.
|
|
25
|
+
2. **Identify the spec to break down** — the one flagged as too complex or pointed to by the user.
|
|
26
|
+
3. **Analyze why it is too complex** — use the indicators from `analyze-if-func-spec-too-complex`:
|
|
27
|
+
- Multiple distinct behaviors bundled together?
|
|
28
|
+
- Too many new constructs introduced at once?
|
|
29
|
+
- Complex branching logic or conditional paths?
|
|
30
|
+
- Cross-cutting concerns mixed with core functionality?
|
|
31
|
+
- A full UI screen described in one spec?
|
|
32
|
+
- Complex data transformations across multiple entities?
|
|
33
|
+
- Implies one substantial technical component (engine, parser, scheduler, algorithm, state machine, sync mechanism) that must be built in code?
|
|
34
|
+
4. **Identify the split boundaries** — find the natural seams where the spec can be divided. Each resulting spec must be:
|
|
35
|
+
- Independently meaningful (makes sense on its own with previous specs as context)
|
|
36
|
+
- Self-contained (does not require a later spec to be useful)
|
|
37
|
+
- Within the 200 LOC limit
|
|
38
|
+
5. **Draft the replacement specs** — write the smaller specs in chronological order. The first replacement spec typically sets up the foundation, and subsequent ones layer behavior on top.
|
|
39
|
+
6. **Verify functional completeness** — this is critical. The replacement specs taken together must cover **100% of the functionality** described in the original spec. Walk through every behavior, condition, and detail in the original and confirm it appears in exactly one of the replacement specs. Nothing may be lost, weakened, or left implicit. If any functionality from the original is missing, add it to the appropriate replacement spec or create an additional one.
|
|
40
|
+
7. **Verify each replacement spec** — run `analyze-if-func-spec-too-complex` on each to confirm it fits within the limit.
|
|
41
|
+
8. **Check for conflicts** — run `analyze-func-specs` **once** with the full set of replacement specs plus every existing spec in the file and its `requires` chain. The batched analyzer reports every conflicting pair (replacement × existing and replacement × replacement) in one call — do not loop over pairs. Resolve each reported pair with `resolve-spec-conflict`, then re-run `analyze-func-specs` over the touched set until the verdict is `COMPATIBLE`.
|
|
42
|
+
9. **Replace in the file** — remove the original spec and insert the replacement specs in its position, preserving chronological order.
|
|
43
|
+
10. **Read the file again** to confirm correct placement and syntax.
|
|
44
|
+
|
|
45
|
+
## Splitting Strategies
|
|
46
|
+
|
|
47
|
+
### Strategy 1: Separate Distinct Behaviors
|
|
48
|
+
|
|
49
|
+
If the spec bundles multiple independently testable actions, split each into its own spec.
|
|
50
|
+
|
|
51
|
+
**Before:**
|
|
52
|
+
```plain
|
|
53
|
+
***functional specs***
|
|
54
|
+
|
|
55
|
+
- A :User: can create, edit, and delete :Recipe: items, with validation on all fields.
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**After:**
|
|
59
|
+
```plain
|
|
60
|
+
***functional specs***
|
|
61
|
+
|
|
62
|
+
- A :User: can create a :Recipe:. Only valid :Recipe: items can be created.
|
|
63
|
+
|
|
64
|
+
- A :User: can edit an existing :Recipe:. Validation rules apply to the edited fields.
|
|
65
|
+
|
|
66
|
+
- A :User: can delete a :Recipe:.
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Strategy 2: Separate Setup from Behavior
|
|
70
|
+
|
|
71
|
+
If the spec introduces a new construct and immediately defines complex behavior on it, split into setup + behavior.
|
|
72
|
+
|
|
73
|
+
**Before:**
|
|
74
|
+
```plain
|
|
75
|
+
***functional specs***
|
|
76
|
+
|
|
77
|
+
- The :MealPlan: screen displays a weekly grid of :Slot: items, allows drag-and-drop reordering, and shows nutritional totals per day.
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**After:**
|
|
81
|
+
```plain
|
|
82
|
+
***functional specs***
|
|
83
|
+
|
|
84
|
+
- The :MealPlan: screen displays a weekly grid of :Slot: items.
|
|
85
|
+
|
|
86
|
+
- A :User: can reorder :Slot: items within a day on the :MealPlan: screen using drag-and-drop.
|
|
87
|
+
|
|
88
|
+
- The :MealPlan: screen displays nutritional totals for each day.
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Strategy 3: Separate Core Logic from Cross-Cutting Concerns
|
|
92
|
+
|
|
93
|
+
If the spec mixes primary functionality with error handling, retries, caching, pagination, or logging, pull cross-cutting concerns into their own specs.
|
|
94
|
+
|
|
95
|
+
**Before:**
|
|
96
|
+
```plain
|
|
97
|
+
***functional specs***
|
|
98
|
+
|
|
99
|
+
- :Ingredient: data is fetched from the external API with pagination, retry on transient errors, and caching for 10 minutes.
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**After:**
|
|
103
|
+
```plain
|
|
104
|
+
***functional specs***
|
|
105
|
+
|
|
106
|
+
- :Ingredient: data is fetched from the external API.
|
|
107
|
+
|
|
108
|
+
- :Ingredient: data is fetched from the external API in pages.
|
|
109
|
+
|
|
110
|
+
- Fetching :Ingredient: data is retried on transient errors.
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Strategy 4: Separate Conditional Paths
|
|
114
|
+
|
|
115
|
+
If the spec describes different modes or branches, give each its own spec.
|
|
116
|
+
|
|
117
|
+
**Before:**
|
|
118
|
+
```plain
|
|
119
|
+
***functional specs***
|
|
120
|
+
|
|
121
|
+
- :MealPlan: generation depends on :DietType:. Standard plans use round-robin assignment. Restrictive plans filter out excluded ingredients first, then apply round-robin. Custom plans allow manual slot-by-slot selection.
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**After:**
|
|
125
|
+
```plain
|
|
126
|
+
***functional specs***
|
|
127
|
+
|
|
128
|
+
- A standard :MealPlan: is generated using round-robin :Recipe: assignment.
|
|
129
|
+
|
|
130
|
+
- A restrictive :MealPlan: is generated.
|
|
131
|
+
- Excluded :Ingredient: items are filtered out first.
|
|
132
|
+
- Round-robin :Recipe: assignment is then applied.
|
|
133
|
+
|
|
134
|
+
- A :User: can manually assign :Recipe: items to :Slot: items for a custom :MealPlan:.
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Strategy 5: Build UI Incrementally
|
|
138
|
+
|
|
139
|
+
If the spec describes a full screen, split into layout + individual interactive elements.
|
|
140
|
+
|
|
141
|
+
**Before:**
|
|
142
|
+
```plain
|
|
143
|
+
***functional specs***
|
|
144
|
+
|
|
145
|
+
- The :Dashboard: screen shows a summary card with stats, a scrollable list of recent :MealPlan: items, a floating action button to create a new plan, and a bottom navigation bar.
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**After:**
|
|
149
|
+
```plain
|
|
150
|
+
***functional specs***
|
|
151
|
+
|
|
152
|
+
- The :Dashboard: screen shows a summary card with :MealFrameStats:.
|
|
153
|
+
|
|
154
|
+
- The :Dashboard: screen shows a scrollable list of recent :MealPlan: items.
|
|
155
|
+
|
|
156
|
+
- The :Dashboard: screen includes a button to create a new :MealPlan:.
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Strategy 6: Extract a Reusable Technical Component
|
|
160
|
+
|
|
161
|
+
Sometimes a spec is too complex not because it bundles many behaviors, but because it implies building one substantial technical component inline — an engine, parser, scheduler, layout algorithm, state machine, or sync mechanism. Splitting the behavior sideways does not help when the weight sits in that single component. Instead, pull the component out: define a concept for it, build it in its own dedicated spec placed **earlier** in the chain, then rewrite the original to use the component **by reference**. Because specs render incrementally top-to-bottom, the original now implies far less code — it wires up a component that already exists rather than implementing it from scratch.
|
|
162
|
+
|
|
163
|
+
Define the component concept in `***definitions***` (via `add-concept`) before the first spec that references it.
|
|
164
|
+
|
|
165
|
+
**Before:**
|
|
166
|
+
```plain
|
|
167
|
+
***functional specs***
|
|
168
|
+
|
|
169
|
+
- A :Report: is exported to PDF, laying out multi-page tables with repeating headers, page numbers, and charts rendered from :Report: data.
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
**After:**
|
|
173
|
+
```plain
|
|
174
|
+
***functional specs***
|
|
175
|
+
|
|
176
|
+
- :PdfRenderer: lays out multi-page tables from structured content.
|
|
177
|
+
- Table headers repeat at the top of each page.
|
|
178
|
+
- Each page shows its page number.
|
|
179
|
+
|
|
180
|
+
- A :Report: is exported to PDF using :PdfRenderer:, embedding charts rendered from :Report: data.
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
The extracted component spec and the rewritten original must together still cover 100% of the original functionality (step 6): the original must **reference** the component, never re-describe it. Keep the component's technology and architecture choices in `***implementation reqs***`, not in the functional spec. If the component is a self-contained subsystem or will be reused across modules, promote it to its own module with `create-requires-module` / `refactor-module` instead of a sibling spec.
|
|
184
|
+
|
|
185
|
+
## Preserving Chronological Order
|
|
186
|
+
|
|
187
|
+
The replacement specs take the position of the original spec. Earlier specs remain unchanged. The first replacement spec should make sense given only the specs above it. Each subsequent replacement spec can reference behavior from the ones before it.
|
|
188
|
+
|
|
189
|
+
If the original spec had acceptance tests, redistribute them to the most appropriate replacement spec — or drop tests that no longer apply to a single smaller spec and rewrite them.
|
|
190
|
+
|
|
191
|
+
## Validation Checklist
|
|
192
|
+
|
|
193
|
+
- [ ] Original spec has been removed from the file
|
|
194
|
+
- [ ] Replacement specs together cover 100% of the original spec's functionality — nothing lost
|
|
195
|
+
- [ ] Each replacement spec implies ≤ 200 LOC (verified via `analyze-if-func-spec-too-complex`)
|
|
196
|
+
- [ ] No conflicts between replacement specs and existing specs (verified via one batched `analyze-func-specs` call)
|
|
197
|
+
- [ ] No conflicts between the replacement specs themselves (covered by the same batched call)
|
|
198
|
+
- [ ] Replacement specs are in correct chronological order
|
|
199
|
+
- [ ] Each replacement spec is independently meaningful
|
|
200
|
+
- [ ] All `:Concepts:` referenced in replacement specs are defined
|
|
201
|
+
- [ ] Any extracted technical component is defined as a concept, built by its own earlier spec, and only **referenced** (not re-described) by the original
|
|
202
|
+
- [ ] Replacement specs are language-agnostic
|
|
203
|
+
- [ ] Replacement specs trimmed per `concise-specs.md` — a split is not a licence to re-add prose
|
|
204
|
+
- [ ] All external interfaces remain explicit
|
|
205
|
+
- [ ] Acceptance tests (if any) have been redistributed or rewritten
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: brood
|
|
3
|
+
description: >-
|
|
4
|
+
`***plain` spec authoring in four phases - intent, stack, testing, product - where every answer
|
|
5
|
+
in the product interview becomes one spec change, written as a git diff of the .plain files and
|
|
6
|
+
built the moment it is written, so code appears while the interview is still going. It first asks
|
|
7
|
+
how many questions the stack and product phases may ask - light, medium, thorough or best
|
|
8
|
+
judgement, broader with fewer - and decides what they leave open itself, each decision a spec
|
|
9
|
+
change of its own. The testing
|
|
10
|
+
phase comes first, so each change is conformance tested as it is built: it decides on
|
|
11
|
+
conformance tests and writes the test reqs and the conformance testing script. Use when the user starts a new project or wants to build
|
|
12
|
+
something new from scratch and settle it with you step by step; when they want it built fast from
|
|
13
|
+
what they want alone, use its quick twin, `spawn`. Not for adding a
|
|
14
|
+
feature to an existing project (use `bud`) or for editing generated code (the .plain
|
|
15
|
+
specs are the source of truth).
|
|
16
|
+
allowed-tools: [read, write, edit, bash, ls, grep, find, write_spec_diff]
|
|
17
|
+
metadata:
|
|
18
|
+
# What each phase does, in a line - shown under the skill's progress while it runs.
|
|
19
|
+
phases:
|
|
20
|
+
intent: "what problem this solves, for whom, and how you will know it works"
|
|
21
|
+
stack: "the language, frameworks, storage and architecture"
|
|
22
|
+
testing: "whether there are conformance tests, and how they are written and run"
|
|
23
|
+
product: "the product, feature by feature - each answer starts a regenerate pulse"
|
|
24
|
+
# The phases the questioning level caps, asked by the harness as the first question: light 3,
|
|
25
|
+
# medium 5, thorough 10, best judgement as many as turri judges the phase needs.
|
|
26
|
+
questioning: [stack, product]
|
|
27
|
+
# Every answer in the product phase is a spec change: the next question waits until it is
|
|
28
|
+
# written with write_spec_diff. Changes turri decides itself need no answer before them.
|
|
29
|
+
spec-diff-per-answer: [product]
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
# Brood
|
|
33
|
+
|
|
34
|
+
Load the `***plain` syntax rules before writing anything — they are in the system prompt
|
|
35
|
+
under `<plain-rules>`; read `genome/rules/<name>.md` for the full text of any rule you need
|
|
36
|
+
to quote or follow closely.
|
|
37
|
+
|
|
38
|
+
## Role
|
|
39
|
+
|
|
40
|
+
Act as a `***plain` spec writer. The only output is `.plain` specification files — never code. Code is generated from the specs and lives in `plain_modules/` as a read-only artifact; never write or edit it. Frame every message to the user in terms of specs: "I'll add this to the spec," "Let me change the spec to fix that." The user must always understand they are building `***plain` specs that render into code, not writing code themselves.
|
|
41
|
+
|
|
42
|
+
In the product phase, every change you make to the specs is a **spec diff**: a git diff of the `.plain` files, written with `write_spec_diff`, which applies it and starts building it. The spec diffs are the output of the interview; the builds follow from them.
|
|
43
|
+
|
|
44
|
+
The testing phase is the exception: it changes only `***test reqs***`, and comes before anything is built, so it writes them with the ordinary file tools and never with `write_spec_diff`. It comes before the product phase so that every spec change the product phase writes is conformance tested as it is built: with conformance on, each build writes and runs the change's conformance tests, and keeps every earlier one passing.
|
|
45
|
+
|
|
46
|
+
## Phase discipline
|
|
47
|
+
|
|
48
|
+
**Finish each phase — its specs on disk and the user's confirmation given — before starting
|
|
49
|
+
the next.** Do not draft, or even ask about, later-phase content while a phase is open: if an
|
|
50
|
+
answer drifts ahead, acknowledge it briefly, note it for later, and steer back.
|
|
51
|
+
|
|
52
|
+
When entering a phase, read its reference file and walk its topics **in order**. Skip a
|
|
53
|
+
topic only if it genuinely does not apply, and say so explicitly.
|
|
54
|
+
|
|
55
|
+
Between phases — and only between phases — summarize what was written and get one explicit
|
|
56
|
+
confirmation before continuing. That single confirmation replaces per-change approval; do
|
|
57
|
+
not ask for both. Do not ask the user to approve each spec change: they are answering
|
|
58
|
+
questions, not running a review queue. After each change, say in one line what went into the
|
|
59
|
+
spec, and carry straight on.
|
|
60
|
+
|
|
61
|
+
## How many questions
|
|
62
|
+
|
|
63
|
+
The first question of the intent phase is the harness's own, not yours: how many questions the
|
|
64
|
+
**stack** and **product** phases may ask. The person picks one level, and it holds for each of
|
|
65
|
+
them. The level sets how many questions there are and so how broad each is - never what they
|
|
66
|
+
cover:
|
|
67
|
+
|
|
68
|
+
| level | questions a phase | each question |
|
|
69
|
+
| --- | --- | --- |
|
|
70
|
+
| light | at most 3 | broad: a whole area at once - the features and their order, what the product does end to end - with what fits the brief proposed, for the person to confirm or correct |
|
|
71
|
+
| medium | at most 5 | one feature or topic, with its main rules |
|
|
72
|
+
| thorough | at most 10 | narrow: one feature, rule or edge case, with follow-ups on the ones that matter |
|
|
73
|
+
| best judgement | as many as you judge the phase needs | as broad or as narrow as each area needs |
|
|
74
|
+
|
|
75
|
+
At every level the questions reach all of the phase's topics; fewer questions only go less deep.
|
|
76
|
+
The intent and testing phases are not capped. Follow-ups count; the closing confirmation of a
|
|
77
|
+
phase - asked with `confirms_phase: true` - does not. Past the cap `ask_user` refuses the question.
|
|
78
|
+
To stop sooner, or under best judgement once the phase is settled enough to build, call
|
|
79
|
+
`end_questions`.
|
|
80
|
+
|
|
81
|
+
The level limits the questions, never the spec changes. In the product phase **every answer is a
|
|
82
|
+
spec change**, whatever the level: written with `write_spec_diff` and built at once, before the
|
|
83
|
+
next question - `ask_user` refuses the next one until it is. A broad answer that covers several
|
|
84
|
+
features is several changes, one a feature, and you write them all. What the questions leave
|
|
85
|
+
open - the details of a light answer, what is left once they are over - is yours to decide, as a
|
|
86
|
+
careful engineer would, in the light of the intent brief: each decision a spec change of its own,
|
|
87
|
+
written with `write_spec_diff` with no answer needed before it, and said in one line. Write as many
|
|
88
|
+
as the product needs. The phase's summary names every decision you made yourself, so the
|
|
89
|
+
confirmation is where the person can change it.
|
|
90
|
+
|
|
91
|
+
## Question style
|
|
92
|
+
|
|
93
|
+
- Ask with `ask_user`, one question per call, and always pass `options` so the user picks rather than types; reserve `free_form: true` for genuinely open prompts.
|
|
94
|
+
- Shape every question so any plausible answer maps directly to one spec change.
|
|
95
|
+
- Prefer short, direct sentences over compound or nested clauses, and plain words over jargon.
|
|
96
|
+
- Never drop detail to simplify — keep every constraint, edge case, option, and piece of context the user needs to answer accurately, splitting into more sentences instead.
|
|
97
|
+
|
|
98
|
+
## Reference
|
|
99
|
+
|
|
100
|
+
- Templates go in `template/`, but import paths omit the `template/` prefix. Resources go in `resources/`.
|
|
101
|
+
- Generated code lands in `plain_modules/<module>/code/` and generated conformance tests in `plain_modules/<module>/tests/` (both read-only, never edit).
|
|
102
|
+
|
|
103
|
+
## Steps
|
|
104
|
+
|
|
105
|
+
### intent
|
|
106
|
+
|
|
107
|
+
The harness has asked how many questions the stack and product phases may ask before this phase
|
|
108
|
+
starts; its note beside these instructions gives the answer. Do not ask it again.
|
|
109
|
+
|
|
110
|
+
Read `references/intent.md` and ask its five core questions one at a time via `ask_user`.
|
|
111
|
+
Ask at most one focused follow-up when an answer is too vague to summarize.
|
|
112
|
+
|
|
113
|
+
Write nothing to disk in this phase — no project files, no specification files. Keep
|
|
114
|
+
entities, features, technology and testing for the phases that own them.
|
|
115
|
+
|
|
116
|
+
Summarize the problem, the primary user, the desired outcome, the observable success
|
|
117
|
+
criterion, and the initial boundary with its explicit exclusions. Get explicit confirmation
|
|
118
|
+
of that brief - the bullets passed whole as `ask_user`'s `context`, which the dialog shows above the
|
|
119
|
+
question - and carry it into every later phase.
|
|
120
|
+
|
|
121
|
+
This phase ends on the user's confirmation.
|
|
122
|
+
|
|
123
|
+
### stack
|
|
124
|
+
|
|
125
|
+
**This comes before any functionality, so that every spec change in the product phase can be
|
|
126
|
+
built the moment it is written.** A functionality cannot be rendered without knowing the
|
|
127
|
+
language it is written in and the framework its tests use.
|
|
128
|
+
|
|
129
|
+
Read `references/stack.md` and walk its topics in order, within the questioning level (see "How
|
|
130
|
+
many questions"): language, frameworks, storage,
|
|
131
|
+
external services, structure and architecture, other constraints, anything else, and last the
|
|
132
|
+
unit tests - generated code needs them from the first functionality onward.
|
|
133
|
+
|
|
134
|
+
Offer the standard library's stacks first, those in a language this machine can build now (the stdlib
|
|
135
|
+
rule, in `<plain-rules>`, `<toolchains on this machine>`, and the first section of
|
|
136
|
+
`references/stack.md`): a stack from it is one import, and only what it leaves open -
|
|
137
|
+
storage, external services, other constraints - is asked and written.
|
|
138
|
+
|
|
139
|
+
Create the module structure and frontmatter so there is a `.plain` file to build into, and
|
|
140
|
+
author every requirement into `***implementation reqs***` at the right scope — shared
|
|
141
|
+
requirements into the template, module-specific ones into the module. Write these with the
|
|
142
|
+
ordinary file tools; **nothing is built in this phase**, and `write_spec_diff` is not used here.
|
|
143
|
+
|
|
144
|
+
Write no definitions, no functional specs, no `***test reqs***` and no `***acceptance tests***`.
|
|
145
|
+
|
|
146
|
+
End the phase with the unit tests: their framework, as a `:UnitTests:` requirement, and the unit
|
|
147
|
+
testing script, which every build needs from the first one on. If turri already finds a
|
|
148
|
+
script - named by `unittests-script:` in `config.turri.yaml` at the project root, or the one
|
|
149
|
+
`run_unittests*.sh` in the root or in `test_scripts/` - keep it. Otherwise write
|
|
150
|
+
`test_scripts/run_unittests_<language>.sh` with the `implement-unit-testing-script` skill, for the
|
|
151
|
+
language and framework just settled. Do not link it from the specs. Without it, every build stops
|
|
152
|
+
before it starts. When this module sits in a project beside another on a different stack - a
|
|
153
|
+
frontend beside a backend, sharing only an imported module - its script is its stack's: name it in
|
|
154
|
+
that stack's `config.turri.<stack>.yaml` beside `config.turri.yaml` (`unittests-script:`) -
|
|
155
|
+
`config.turri.frontend.yaml` for the stack `frontend` - not in `config.turri.yaml`, which is the
|
|
156
|
+
project's and holds what the stacks share. A stack is chosen, never worked out: tell the user to
|
|
157
|
+
choose it with `/stack <stack>` (`--stack <stack>` on the command line) before building this module.
|
|
158
|
+
|
|
159
|
+
The unit testing script runs the static checks too - the formatter, linter and type checker the stack
|
|
160
|
+
names, which count as the unit tests do; `implement-unit-testing-script` says which for each language.
|
|
161
|
+
There is no separate static checks script.
|
|
162
|
+
|
|
163
|
+
Run `turri validate` on the module before finishing, so the product phase does not start
|
|
164
|
+
on top of a file that does not parse.
|
|
165
|
+
|
|
166
|
+
Finish by summarizing the stack, the architecture, the unit testing script and the static checks it runs - marking each
|
|
167
|
+
choice you made without asking - and getting explicit confirmation, with `confirms_phase: true`. The user
|
|
168
|
+
reading the stack back is the check.
|
|
169
|
+
|
|
170
|
+
### testing
|
|
171
|
+
|
|
172
|
+
Read `references/testing.md`. Carry the intent brief and the stack in; ask about neither again. Walk
|
|
173
|
+
its topics in order. Nothing is built yet, and nothing is built in this phase.
|
|
174
|
+
|
|
175
|
+
First the decision: are there conformance tests at all? Ask it explicitly - even when
|
|
176
|
+
`config.turri.yaml` already says, ask, offering what it says first - and write the answer to
|
|
177
|
+
`config.turri.yaml` as `conformance-tests:` - the chat and every build follow it. A project with
|
|
178
|
+
only a `config.yaml` has it copied to `config.turri.yaml` first; never write `config.yaml`. Off, and the phase is
|
|
179
|
+
done once the user confirms: the product phase's builds then write and run no conformance tests.
|
|
180
|
+
|
|
181
|
+
On: when the stack came from the standard library, import its conformance template
|
|
182
|
+
(`stdlib/<kind>/conformance/<stack>`) and ask only about what it does not settle. Each answer about how the
|
|
183
|
+
tests are written and run becomes a `:ConformanceTests:` requirement in `***test reqs***`, written
|
|
184
|
+
with the ordinary file tools. A change to the test reqs is not a spec
|
|
185
|
+
diff: never use `write_spec_diff` in this phase. Then make sure the project has its conformance
|
|
186
|
+
testing script - `implement-conformance-testing-script` writes it into `test_scripts/` when
|
|
187
|
+
turri finds none - and run `validate` on what you changed. Without both, the first build of
|
|
188
|
+
the product phase stops before it starts.
|
|
189
|
+
|
|
190
|
+
Finish by summarizing the decision, the test reqs and the script, and saying that from the first
|
|
191
|
+
spec change on, every build writes and runs its conformance tests. Get explicit confirmation.
|
|
192
|
+
|
|
193
|
+
### product
|
|
194
|
+
|
|
195
|
+
Read `references/product.md`. Carry the intent brief, the stack and the testing decisions in;
|
|
196
|
+
restart none of them. This
|
|
197
|
+
is the whole product interview, walked **feature by feature** - never section by section. Do
|
|
198
|
+
not fill in the definitions first and the functional specs after: that is not this skill.
|
|
199
|
+
|
|
200
|
+
Walk its topics in order, and run this loop while the questioning level allows (see "How many
|
|
201
|
+
questions") - each question as broad as the level says:
|
|
202
|
+
|
|
203
|
+
1. **Ask** one question with `ask_user` - about a feature, a step of a flow, a rule; never about
|
|
204
|
+
a spec section.
|
|
205
|
+
2. The user **answers**.
|
|
206
|
+
3. **Make the spec change** the answer calls for, as one git diff of the `.plain` files - across
|
|
207
|
+
every section it needs: the concepts it introduces, a policy it states, the functional spec it
|
|
208
|
+
adds or changes.
|
|
209
|
+
4. **Write it with `write_spec_diff`**, which applies it and starts a render spec diff job for it,
|
|
210
|
+
whatever it touches. With conformance on, that build also writes and runs the change's
|
|
211
|
+
conformance tests. An answer that covers several features is a change for each: write them
|
|
212
|
+
all. Then the changes for what you decide yourself around it, if any.
|
|
213
|
+
5. Move straight on to the next question; never wait for a build.
|
|
214
|
+
|
|
215
|
+
Every answer, at least one spec change and one render spec diff job, written before the next
|
|
216
|
+
question - at every level. Once the questions are over, write what is left of the product the same
|
|
217
|
+
way - one decision of yours, one spec change - with no answer between. Correct something already
|
|
218
|
+
written with
|
|
219
|
+
a diff and `fixes_earlier`, before the next question. Never change a `.plain` file in this
|
|
220
|
+
phase by any other means than `write_spec_diff`.
|
|
221
|
+
|
|
222
|
+
Report each build result between questions, in one sentence. Use `drift` when the
|
|
223
|
+
user asks how the builds are going.
|
|
224
|
+
|
|
225
|
+
Finish by summarizing the concepts and the features in build order, marking what you decided without
|
|
226
|
+
asking, saying what is built and what is still queued, getting explicit confirmation with
|
|
227
|
+
`confirms_phase: true`. The summary is for the person to take in at a glance: a line a feature, a few
|
|
228
|
+
words a concept, each decision you made yourself in a few words - about fifteen lines at most, never
|
|
229
|
+
the specs' wording or every rule; they are in the spec.
|