@turri-dev/cli 0.1.4-next.afc43a8 → 0.1.4-next.d6e59a8
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 +67 -66
- package/.pi/themes/turri-light.json +71 -73
- package/README.md +41 -127
- 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/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/dist/brand.js +7 -7
- package/dist/cultivate-cli.js +16 -23
- package/dist/extension.js +33 -59
- package/dist/jellyfish.js +130 -0
- package/dist/loop-cli.js +8 -8
- package/dist/module-report.js +5 -4
- package/dist/regenerate/plain-palette.js +52 -37
- package/dist/regenerate/side-panel.js +1 -1
- package/dist/regenerate/spec-map-view.js +9 -5
- package/dist/release-cli.js +3 -8
- package/dist/validate-cli.js +3 -8
- package/docs/README.md +5 -12
- package/docs/authoring-plain.md +37 -121
- package/docs/config.md +50 -176
- package/docs/deploy.md +21 -80
- package/docs/development.md +13 -41
- package/docs/headless.md +30 -136
- package/docs/images/how-turri-works.svg +29 -31
- package/docs/images/turri-banner.png +0 -0
- package/docs/images/turri-screenshot.png +0 -0
- package/docs/installation.md +13 -40
- package/docs/parser.md +15 -43
- package/docs/regenerating.md +231 -964
- package/docs/sandbox.md +38 -152
- package/docs/skills-and-gates.md +50 -173
- package/docs/theming.md +45 -46
- package/docs/using.md +66 -356
- package/genome/rules/bullet-continuation.md +5 -13
- package/genome/rules/concise-specs-examples.md +2 -4
- package/genome/rules/concise-specs-integration-examples.md +2 -6
- package/genome/rules/concise-specs.md +1 -2
- package/genome/rules/integration-embedded-testing.md +1 -4
- package/genome/rules/integrations.md +1 -2
- package/genome/rules/project-model.md +14 -37
- package/genome/rules/stdlib.md +14 -49
- package/genome/rules/turri-regeneration.md +35 -23
- package/genome/skills/add-implementation-requirement/SKILL.md +1 -2
- package/genome/skills/analyze-if-func-spec-too-complex/SKILL.md +3 -8
- package/genome/skills/brood/SKILL.md +37 -127
- package/genome/skills/brood/references/intent.md +4 -12
- package/genome/skills/brood/references/product.md +24 -76
- package/genome/skills/brood/references/stack.md +7 -29
- package/genome/skills/brood/references/testing.md +11 -42
- package/genome/skills/bud/SKILL.md +32 -109
- package/genome/skills/bud/references/intent.md +4 -11
- package/genome/skills/implement-conformance-testing-script/SKILL.md +3 -6
- package/genome/skills/implement-unit-testing-script/SKILL.md +1 -2
- package/genome/skills/mature/SKILL.md +21 -69
- package/genome/skills/spawn/SKILL.md +28 -113
- package/package.json +1 -1
- 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 +0 -252
- package/assets/jellyfish/light-12.png +0 -0
- package/assets/jellyfish/light-13.png +0 -0
- package/assets/jellyfish/light-14.png +0 -0
|
@@ -15,19 +15,12 @@ These rules apply to every section and to concept explanations.
|
|
|
15
15
|
|
|
16
16
|
## One statement per line
|
|
17
17
|
|
|
18
|
-
This is the preferred `.plain` authoring convention, not something the renderer enforces. A line
|
|
19
|
-
break in a section means one of exactly two things: a new `- ` statement, or a nested `- `
|
|
20
|
-
clarification of the statement above it. There is no third, typographic reason to break a line.
|
|
18
|
+
This is the preferred `.plain` authoring convention, not something the renderer enforces. A line break in a section means one of exactly two things: a new `- ` statement, or a nested `- ` clarification of the statement above it. There is no third, typographic reason to break a line.
|
|
21
19
|
|
|
22
20
|
- Write each statement on a single line, however long
|
|
23
|
-
- Never break a line just for width: a bare continuation (an indented line without `- `) adds a
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
- The test: if content deserves its own line, it deserves its own `- ` bullet; if it doesn't,
|
|
27
|
-
keep it on the parent's line
|
|
28
|
-
- What the renderer does enforce is the top level: every statement in a section must be a `- `
|
|
29
|
-
list item — a flush-left prose line is a syntax error. A bare continuation, by contrast, is
|
|
30
|
-
accepted and folded into its parent item verbatim
|
|
21
|
+
- Never break a line just for width: a bare continuation (an indented line without `- `) adds a line break that carries no structure — to every future reader and editing agent it is indistinguishable from a deliberate sub-point
|
|
22
|
+
- The test: if content deserves its own line, it deserves its own `- ` bullet; if it doesn't, keep it on the parent's line
|
|
23
|
+
- What the renderer does enforce is the top level: every statement in a section must be a `- ` list item — a flush-left prose line is a syntax error. A bare continuation, by contrast, is accepted and folded into its parent item verbatim
|
|
31
24
|
|
|
32
25
|
BAD — line broken for width (bare continuation):
|
|
33
26
|
|
|
@@ -65,5 +58,4 @@ BEST — separate clarifications expressed as nested bullets:
|
|
|
65
58
|
|
|
66
59
|
## Content that belongs in resources
|
|
67
60
|
|
|
68
|
-
Long URLs, schema fragments, and example payloads belong in `resources/` because they are external
|
|
69
|
-
artifacts, not because of their character count. Follow `linked-resources.md`.
|
|
61
|
+
Long URLs, schema fragments, and example payloads belong in `resources/` because they are external artifacts, not because of their character count. Follow `linked-resources.md`.
|
|
@@ -208,8 +208,7 @@ GOOD:
|
|
|
208
208
|
- :ConformanceTests: mock every external HTTP call.
|
|
209
209
|
```
|
|
210
210
|
|
|
211
|
-
Every hedge hands the renderer a decision the spec was supposed to make. A spec states one
|
|
212
|
-
behavior.
|
|
211
|
+
Every hedge hands the renderer a decision the spec was supposed to make. A spec states one behavior.
|
|
213
212
|
|
|
214
213
|
## Ornate vocabulary
|
|
215
214
|
|
|
@@ -427,5 +426,4 @@ GOOD:
|
|
|
427
426
|
- :ProjectList: contains exactly one :Project:, named `Apollo`.
|
|
428
427
|
```
|
|
429
428
|
|
|
430
|
-
One narrated paragraph becomes an ordered set of checkable steps, and "everything worked as
|
|
431
|
-
expected" becomes an assertion.
|
|
429
|
+
One narrated paragraph becomes an ordered set of checkable steps, and "everything worked as expected" becomes an assertion.
|
|
@@ -221,9 +221,7 @@ GOOD:
|
|
|
221
221
|
- :ProviderClient: uses :AuthTokenManager: to cache and refresh :AccessToken:.
|
|
222
222
|
```
|
|
223
223
|
|
|
224
|
-
The grant type, endpoint, body encoding, and response fields are in the security scheme. What
|
|
225
|
-
survives is the policy the scheme does not describe: the env-var names, the refresh margin, the
|
|
226
|
-
retry-once-on-401 rule, and the concurrency behavior.
|
|
224
|
+
The grant type, endpoint, body encoding, and response fields are in the security scheme. What survives is the policy the scheme does not describe: the env-var names, the refresh margin, the retry-once-on-401 rule, and the concurrency behavior.
|
|
227
225
|
|
|
228
226
|
Almost all of it is implementation reqs — acquisition, caching, and refresh are machinery a caller never sees. Not all of it, though, and the rewrite has to name a component to say the rest. :ProviderAuth: performs the grant and has no observable surface; :AuthTokenManager: is what consumes it and hands tokens to :ProviderClient:, so it is the concept a functional spec can take as its subject. Without that consumer the section is left with a subject-less bullet, which `func-specs.md` rules out — and that one spec is the only line here a live conformance test can assert.
|
|
229
227
|
|
|
@@ -265,6 +263,4 @@ GOOD:
|
|
|
265
263
|
- The `429` and forced-`5xx` paths mock that endpoint alone; every other path is live.
|
|
266
264
|
```
|
|
267
265
|
|
|
268
|
-
A policy that holds for every endpoint is stated once. Enumerate an endpoint only where it departs
|
|
269
|
-
from the policy — here, the two paths that cannot be exercised live safely, which
|
|
270
|
-
`integrations.md` requires to be documented explicitly.
|
|
266
|
+
A policy that holds for every endpoint is stated once. Enumerate an endpoint only where it departs from the policy — here, the two paths that cannot be exercised live safely, which `integrations.md` requires to be documented explicitly.
|
|
@@ -27,8 +27,7 @@ Do not write:
|
|
|
27
27
|
- Anything about work the spec is not about ("no changes to the existing UI")
|
|
28
28
|
- Meta-commentary about the spec itself ("this spec is intentionally small", "as described above")
|
|
29
29
|
|
|
30
|
-
Worked pairs for every item above — padding, rationale, defaults, technology behavior,
|
|
31
|
-
meta-commentary, and duplication of an `import` — are in `concise-specs-examples.md`.
|
|
30
|
+
Worked pairs for every item above — padding, rationale, defaults, technology behavior, meta-commentary, and duplication of an `import` — are in `concise-specs-examples.md`.
|
|
32
31
|
|
|
33
32
|
## Use plain words
|
|
34
33
|
|
|
@@ -4,10 +4,7 @@ description: Rules for authoring the two test scripts that an embedded ***plain
|
|
|
4
4
|
|
|
5
5
|
# Rules for embedded-integration test scripts
|
|
6
6
|
|
|
7
|
-
When an embedded integration ships its two `test_scripts/` (unit, conformance), these
|
|
8
|
-
rules apply on top of the contracts in the corresponding
|
|
9
|
-
`implement-*-testing-script` skills. `project-model.md` covers the rendering and
|
|
10
|
-
testing workflow.
|
|
7
|
+
When an embedded integration ships its two `test_scripts/` (unit, conformance), these rules apply on top of the contracts in the corresponding `implement-*-testing-script` skills. `project-model.md` covers the rendering and testing workflow.
|
|
11
8
|
|
|
12
9
|
## Staging model (read this first)
|
|
13
10
|
|
|
@@ -63,8 +63,7 @@ Integrations exist to talk to a real third-party (or internal) API. Their `:Conf
|
|
|
63
63
|
- The integration's `:ConformanceTests:` **must** make real network calls to the provider (typically a sandbox / staging environment, occasionally production for read-only paths). Recorded responses may back unit tests, but they are **not** a substitute for live conformance
|
|
64
64
|
- The only exceptions are paths that **cannot** be exercised live safely:
|
|
65
65
|
- **Rate-limit (429) tests** — must not exhaust the live quota; use a local mock for that specific endpoint
|
|
66
|
-
- **Deliberately destructive failure modes** (forced 5xx) the provider doesn't let you trigger — same; mock the specific endpoint
|
|
67
|
-
Document each exception explicitly in `***test reqs***`; everything else is live by default
|
|
66
|
+
- **Deliberately destructive failure modes** (forced 5xx) the provider doesn't let you trigger — same; mock the specific endpoint Document each exception explicitly in `***test reqs***`; everything else is live by default
|
|
68
67
|
|
|
69
68
|
### Secrets come from the environment
|
|
70
69
|
|
|
@@ -4,15 +4,12 @@ description: The ***plain project model - the specs as source of truth, the repo
|
|
|
4
4
|
|
|
5
5
|
# The ***plain project model
|
|
6
6
|
|
|
7
|
-
This rule covers the project as a whole. Section content is owned by the per-section rule files;
|
|
8
|
-
file structure by `module-structure.md`.
|
|
7
|
+
This rule covers the project as a whole. Section content is owned by the per-section rule files; file structure by `module-structure.md`.
|
|
9
8
|
|
|
10
9
|
## Source of truth
|
|
11
10
|
|
|
12
|
-
- The `.plain` files are the source of truth. They state what the software does, how it is built,
|
|
13
|
-
|
|
14
|
-
- Every change to the software is a change to a `.plain` file, which the next render builds. A fix
|
|
15
|
-
made anywhere else is lost the next time the code is regenerated
|
|
11
|
+
- The `.plain` files are the source of truth. They state what the software does, how it is built, and how it is tested; the code is generated from them
|
|
12
|
+
- Every change to the software is a change to a `.plain` file, which the next render builds. A fix made anywhere else is lost the next time the code is regenerated
|
|
16
13
|
|
|
17
14
|
## Repository layout
|
|
18
15
|
|
|
@@ -27,37 +24,23 @@ plain_modules/ # generated - one folder per module
|
|
|
27
24
|
<module>/tests/ # the whole conformance suite of the module
|
|
28
25
|
```
|
|
29
26
|
|
|
30
|
-
Follow `module-structure.md`, `import-modules.md` and `linked-resources.md` for what these
|
|
31
|
-
directories may contain and how a spec refers to them.
|
|
27
|
+
Follow `module-structure.md`, `import-modules.md` and `linked-resources.md` for what these directories may contain and how a spec refers to them.
|
|
32
28
|
|
|
33
29
|
## The config records the build decisions
|
|
34
30
|
|
|
35
|
-
`config.turri.yaml`, at the project root beside the specs, is where the project's decisions about how it
|
|
36
|
-
|
|
37
|
-
it
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
- Settle a decision, write it into the config in the same step - never leave it to be inferred from
|
|
42
|
-
what is on disk. A testing script you write or keep is named by its key, by path
|
|
43
|
-
from the root (`unittests-script: test_scripts/run_unittests_python.sh`); conformance tests
|
|
44
|
-
turned on or off are `conformance-tests: true` or `false`
|
|
45
|
-
- Change only the keys you settled. Where the file has a key's example commented out, uncomment that
|
|
46
|
-
line and set it; keep every other line and comment as it is
|
|
47
|
-
- A project whose parts are on different stacks keeps each stack's scripts in its own
|
|
48
|
-
`config.turri.<stack>.yaml` beside it; what the stacks share stays in `config.turri.yaml`
|
|
49
|
-
- A project with only a `config.yaml` has it copied to `config.turri.yaml` first, and each
|
|
50
|
-
`config.<name>.yaml` to `config.turri.<name>.yaml`; `config.yaml` may be another tool's, and is never
|
|
51
|
-
written
|
|
31
|
+
`config.turri.yaml`, at the project root beside the specs, is where the project's decisions about how it is built live: the models, whether conformance tests are written (`conformance-tests:`), and the scripts it uses (`unittests-script:`, `conformance-tests-script:`, `prepare-environment-script:`). turri can find a script by its name, but the config is what a person reads to see how the project is set up, and what they change.
|
|
32
|
+
|
|
33
|
+
- Settle a decision, write it into the config in the same step - never leave it to be inferred from what is on disk. A testing script you write or keep is named by its key, by path from the root (`unittests-script: test_scripts/run_unittests_python.sh`); conformance tests turned on or off are `conformance-tests: true` or `false`
|
|
34
|
+
- Change only the keys you settled. Where the file has a key's example commented out, uncomment that line and set it; keep every other line and comment as it is
|
|
35
|
+
- A project whose parts are on different stacks keeps each stack's scripts in its own `config.turri.<stack>.yaml` beside it; what the stacks share stays in `config.turri.yaml`
|
|
36
|
+
- A project with only a `config.yaml` has it copied to `config.turri.yaml` first, and each `config.<name>.yaml` to `config.turri.<name>.yaml`; `config.yaml` may be another tool's, and is never written
|
|
52
37
|
- Say in your summary which lines you wrote
|
|
53
38
|
|
|
54
39
|
## Generated output is read-only
|
|
55
40
|
|
|
56
|
-
Everything under `plain_modules/` is generated - `code/` and `tests/` alike. Read it, run it, debug
|
|
57
|
-
it; never edit it. Fix the spec instead, in the section that owns the fact:
|
|
41
|
+
Everything under `plain_modules/` is generated - `code/` and `tests/` alike. Read it, run it, debug it; never edit it. Fix the spec instead, in the section that owns the fact:
|
|
58
42
|
|
|
59
|
-
- behaviour, implementation or unit-test guidance → definitions, functional specs, or implementation
|
|
60
|
-
reqs
|
|
43
|
+
- behaviour, implementation or unit-test guidance → definitions, functional specs, or implementation reqs
|
|
61
44
|
- conformance-test guidance → test reqs
|
|
62
45
|
- acceptance-test guidance → the acceptance tests nested under their functional spec
|
|
63
46
|
|
|
@@ -75,16 +58,10 @@ Parameters are key-value pairs; the template reads them as `{{ variable_name }}`
|
|
|
75
58
|
|
|
76
59
|
## When an earlier test fails after a render
|
|
77
60
|
|
|
78
|
-
Each functional spec is written knowing the ones before it and none after it - a required module's
|
|
79
|
-
specs count as before - so a spec may rely on what earlier ones say, never on later ones. This is
|
|
80
|
-
about what a spec may assume, not what a change costs (`turri-regeneration.md`). After each
|
|
81
|
-
render every conformance test so far runs again. A test that passed before and fails now means one
|
|
82
|
-
of:
|
|
61
|
+
Each functional spec is written knowing the ones before it and none after it - a required module's specs count as before - so a spec may rely on what earlier ones say, never on later ones. This is about what a spec may assume, not what a change costs (`turri-regeneration.md`). After each render every conformance test so far runs again. A test that passed before and fails now means one of:
|
|
83
62
|
|
|
84
63
|
1. the new code does not satisfy its spec;
|
|
85
64
|
2. the test does not test its spec accurately;
|
|
86
65
|
3. the new spec and an earlier one conflict.
|
|
87
66
|
|
|
88
|
-
The harness triages the first two and repairs the code. The third is a spec problem: resolve it in
|
|
89
|
-
the `.plain` files with `resolve-spec-conflict`, and trace a misbehaving build back to its spec with
|
|
90
|
-
`debug-specs` - never by editing generated output.
|
|
67
|
+
The harness triages the first two and repairs the code. The third is a spec problem: resolve it in the `.plain` files with `resolve-spec-conflict`, and trace a misbehaving build back to its spec with `debug-specs` - never by editing generated output.
|
package/genome/rules/stdlib.md
CHANGED
|
@@ -4,11 +4,7 @@ description: The ***plain standard library - import modules for a backend, a fro
|
|
|
4
4
|
|
|
5
5
|
# Rules for the standard library
|
|
6
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.
|
|
7
|
+
turri ships a standard library of import modules that settle everything about a generic piece of software on one stack except what it does: its language and framework, its layout, its configuration, how it handles errors, how it logs, how it stops, and how it is tested. A module that imports one writes only what is its own - its concepts and its functional specs - and a requirement only for what its stack does not settle.
|
|
12
8
|
|
|
13
9
|
```plain
|
|
14
10
|
---
|
|
@@ -20,54 +16,23 @@ import:
|
|
|
20
16
|
|
|
21
17
|
## How it is built up
|
|
22
18
|
|
|
23
|
-
- Each stack imports its language's template - `stdlib/lang/python` - and its kind's `common` -
|
|
24
|
-
|
|
25
|
-
-
|
|
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.
|
|
19
|
+
- Each stack imports its language's template - `stdlib/lang/python` - and its kind's `common` - `stdlib/backend/common` - so importing the stack brings all three.
|
|
20
|
+
- Each stack's conformance tests are a template of their own, `stdlib/<kind>/conformance/<stack>`, which imports `stdlib/<kind>/conformance/common`.
|
|
21
|
+
- The `common` of a kind settles what every stack of it shares. For a backend: settings from the environment, checked at start; handler, service and repository layers; domain errors turned into one error body `{"error": {"code", "message"}}` with fixed codes and statuses; JSON logs with a request id; shutdown on a signal. For a command-line tool: `Error: <message>` on standard error, exit codes 0, 1, 2 and 130, logs on standard error with `--verbose` and `--debug`. For a frontend: one API layer with an `ApiError`, errors shown in place or at the root, one logger module. For a library: one public entry point, one base error type, no output of its own.
|
|
34
22
|
|
|
35
23
|
## When to use it
|
|
36
24
|
|
|
37
|
-
- When the person wants a backend, a frontend, a command-line tool or a library, import the stack
|
|
38
|
-
|
|
39
|
-
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
-
|
|
43
|
-
|
|
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.
|
|
25
|
+
- When the person wants a backend, a frontend, a command-line tool or a library, import the stack that fits instead of writing its implementation reqs yourself.
|
|
26
|
+
- Pick the stack from what the person said, the project's other modules, and what the module talks to. With nothing to go on: `stdlib/backend/python-fastapi`, `stdlib/frontend/react-vite`, `stdlib/cli/python-typer`, `stdlib/library/python`.
|
|
27
|
+
- Import the conformance template only when the module has conformance tests - the person asked for them, and the project's config does not turn them off (`conformance-tests: false`). Without it the module has no test reqs, and no conformance tests are written or run for it. Turning them on later is adding that one import.
|
|
28
|
+
- Read the templates a module imports before writing its specs - the folder is named below - and write no requirement they already make (see `concise-specs.md`).
|
|
29
|
+
- Write a functional spec's errors in the templates' terms: a backend's failure by its status and `error.code` - `not_found`, `conflict`, `validation_error`, `unauthenticated`, `forbidden`, or a code of the module's own - and a command-line tool's by its exit code and message.
|
|
30
|
+
- Add a requirement on top for what the module needs beyond its stack - storage, an outside service, a library it must use. When the module differs from its stack on something the stack settles - another framework, another layout - write the stack yourself instead: an import cannot be taken back in part. For a language with no stack of the kind wanted, import its `stdlib/lang/<language>` and write the rest.
|
|
31
|
+
- `stdlib/` is a reserved name. An import that starts with it is always the standard library's template, and a project module at such a path - `stdlib/backend/python-fastapi.plain` in the spec's folder, its `template/` folder or `PLAIN_TEMPLATE_DIRS` - is an error. Never write a module under a `stdlib/` folder of the project; a project's own shared template goes in `template/` under a name of its own.
|
|
61
32
|
|
|
62
33
|
## What it does not do
|
|
63
34
|
|
|
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.
|
|
35
|
+
- It defines no concepts: its requirements are on the predefined `:Implementation:`, `:UnitTests:` and `:ConformanceTests:` only, so it never collides with the module's own definitions.
|
|
66
36
|
- 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
|
-
|
|
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.
|
|
37
|
+
- It holds no testing scripts. The module still needs its unit testing script, and its conformance testing script when it has conformance tests - written with the `implement-unit-testing-script` and `implement-conformance-testing-script` skills for the stack's language and test framework. Each runs the static checks of what it tests - the formatter, linter and type checker its language template names, on the code or on the conformance tests - and they count as the tests do.
|
|
38
|
+
- It names its stack's toolchain - Python 3.12, Node.js 24, Java 21, Go 1.25, Rust - which the agents use from the machine turri runs on; they install none, so `turri doctor` says when the machine lacks it.
|
|
@@ -1,36 +1,48 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: How turri regenerates the code from a spec change - by spec diff, in the chain's tip - so a spec is placed by what it means, never by what regenerating it
|
|
2
|
+
description: How turri regenerates the code from a spec change - by spec diff, in the chain's tip - what each kind of change sets off, what a coding agent sees, how bad code is fixed and where the cost really is, so a spec is placed and written by what it means, never by a guess at what regenerating it costs
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
# How turri regenerates the code
|
|
6
6
|
|
|
7
|
-
The other rules say what a spec means. This one says what turri does with a change to it, so that
|
|
8
|
-
where a change goes is never decided by a wrong idea of what it costs.
|
|
7
|
+
The other rules say what a spec means. This one says what turri does with a change to it, so that where a change goes, and how it is made, is never decided by a wrong idea of how turri works. Each section ends in the same place: decide by what the spec means.
|
|
9
8
|
|
|
10
9
|
## A change is regenerated as a spec diff
|
|
11
10
|
|
|
12
|
-
- turri regenerates the code from spec diffs: what changed between the spec the code was built from
|
|
13
|
-
|
|
14
|
-
-
|
|
15
|
-
|
|
16
|
-
- The specs around it are not regenerated because their position or numbering moved, and nothing after
|
|
17
|
-
it is built again. A spec inserted in the middle is one addition
|
|
18
|
-
- "Specs render top to bottom, each knowing only the ones before it" is about what a spec may assume
|
|
19
|
-
(`func-specs.md`), not about what a change costs
|
|
11
|
+
- turri regenerates the code from spec diffs: what changed between the spec the code was built from and the spec now
|
|
12
|
+
- A functional spec added, changed or taken out is that change alone, wherever it sits - first, in the middle or last of its module
|
|
13
|
+
- The specs around it are not regenerated because their position or numbering moved, and nothing after it is built again. A spec inserted in the middle is one addition
|
|
14
|
+
- "Specs render top to bottom, each knowing only the ones before it" is about what a spec may assume (`func-specs.md`), not about what a change costs
|
|
20
15
|
|
|
21
16
|
## A change is regenerated in the chain's tip
|
|
22
17
|
|
|
23
|
-
- A chain's code lives in its tip - the furthest module built on it. The modules below it keep the
|
|
24
|
-
|
|
25
|
-
-
|
|
26
|
-
|
|
27
|
-
- Putting a change in a lower module costs no more than putting it in the tip, and saves nothing
|
|
28
|
-
either
|
|
18
|
+
- A chain's code lives in its tip - the furthest module built on it. The modules below it keep the code they were built with
|
|
19
|
+
- A change to any module of the chain, the base's included, is regenerated in the tip's code - not in the module the change was made in
|
|
20
|
+
- Putting a change in a lower module costs no more than putting it in the tip, and saves nothing either
|
|
21
|
+
- Moving specs between modules of the chain renders nothing. Moving specs into a module the code was never built on is the exception: no change to the code brings that module in, so the chain has to be regenerated from scratch - never done without the person agreeing
|
|
29
22
|
|
|
30
|
-
##
|
|
23
|
+
## What each kind of change sets off
|
|
31
24
|
|
|
32
|
-
-
|
|
33
|
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
|
|
25
|
+
- A functional spec added is built, with its unit tests; one changed is patched in place; one taken out has its code, and the tests only it had, removed
|
|
26
|
+
- A definition changed patches every functional spec that uses its concept, directly or through other definitions. So does a change to a linked resource: the spec or definition linking it is changed though its text is not. A widely used definition is the costly edit - not a spec's position
|
|
27
|
+
- Implementation reqs alone, or definitions no functional spec uses, are a mechanical change: the code adapts, and no test is written or changes what it asserts
|
|
28
|
+
- Test reqs and acceptance tests reach the conformance tests only, never the code
|
|
29
|
+
- Definitions moved to a common module and reqs reordered are recorded, not rendered
|
|
30
|
+
|
|
31
|
+
## What a coding agent sees
|
|
32
|
+
|
|
33
|
+
- A coding agent sees its prompt and its module's code - nothing else. It cannot read `.plain` files, this conversation, AGENTS.md or the person
|
|
34
|
+
- What the code needs to know has to be in the spec. A fact said only in the conversation, AGENTS.md or notes never reaches the code, and is lost at the next regeneration
|
|
35
|
+
- Steering reaches the agents that plan the work - how it is cut and in what order - not what the code does. What the code does is changed in the spec
|
|
36
|
+
|
|
37
|
+
## How bad code is fixed
|
|
38
|
+
|
|
39
|
+
- Never edit the code under `plain_modules/`: the next regeneration does not keep it, and the code record no longer says what the code is
|
|
40
|
+
- In order of cost: change the spec where it is wrong or silent; regenerate the functional specs whose code went bad again, by name; regenerate the module from scratch, or its whole chain - only when the person asks for it or agrees to it
|
|
41
|
+
- A pulse that does not land is rolled back whole - code, tests and record together - and its module waits until the spec changes or the module is asked for again. Running it again unchanged usually ends the same way: look at why it did not land first
|
|
42
|
+
|
|
43
|
+
## Where the cost is
|
|
44
|
+
|
|
45
|
+
- The cost is the work regenerated: how many functional specs a change touches, directly or through the definitions they use, cut into pulses of at most `max-specs-per-pulse`
|
|
46
|
+
- Regenerating functional specs again, or a module or chain from scratch, costs most, and is only ever asked for outright
|
|
47
|
+
- Placement never adds cost. Put a functional spec in the module that owns the concern, at the point in its order where what it relies on has been said; never at the end of a module, or in the tip, only to spare regeneration - it spares none
|
|
48
|
+
- Never write placement for cost into AGENTS.md, a skill or notes: what is written there is read back later as how the project works
|
|
@@ -49,8 +49,7 @@ Implementation reqs are free-form instructions that steer code generation. Commo
|
|
|
49
49
|
|
|
50
50
|
## Key Principle: HOW vs WHAT
|
|
51
51
|
|
|
52
|
-
`***implementation reqs***` describe HOW the software should be built.
|
|
53
|
-
`***functional specs***` describe WHAT the software should do.
|
|
52
|
+
`***implementation reqs***` describe HOW the software should be built. `***functional specs***` describe WHAT the software should do.
|
|
54
53
|
|
|
55
54
|
If the requirement describes observable behavior (endpoints, business rules, user-facing features), it belongs in functional specs. If it describes internal structure, technology, or coding guidance, it belongs here.
|
|
56
55
|
|
|
@@ -32,14 +32,9 @@ Work through each indicator. A single "yes" does not automatically mean the spec
|
|
|
32
32
|
|
|
33
33
|
### 0. First-Spec Bootstrap Cost
|
|
34
34
|
|
|
35
|
-
Is this the first functional spec in a new root module with no implementation baseline supplied by
|
|
36
|
-
|
|
37
|
-
|
|
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.
|
|
35
|
+
Is this the first functional spec in a new root module with no implementation baseline supplied by `requires`? If so, include the implicit cost of creating the project structure, package metadata, framework configuration, entry point, initial source files, and unit-test infrastructure.
|
|
36
|
+
|
|
37
|
+
The first spec must be substantially simpler than a later spec. It should expose one minimal, deterministic capability that can be invoked and tested. Setup without an observable result is not acceptable, but combining bootstrap work with persistence, integrations, multiple interfaces, branching workflows, or cross-cutting behavior is a strong `TOO COMPLEX` signal.
|
|
43
38
|
|
|
44
39
|
### 1. Number of Distinct Behaviors
|
|
45
40
|
|