@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
|
@@ -28,27 +28,17 @@ metadata:
|
|
|
28
28
|
|
|
29
29
|
# Bud
|
|
30
30
|
|
|
31
|
-
Load the `***plain` syntax rules before writing anything - they are in the system prompt under
|
|
32
|
-
`<plain-rules>`; read `genome/rules/<name>.md` for the full text of any rule you need to follow
|
|
33
|
-
closely.
|
|
31
|
+
Load the `***plain` syntax rules before writing anything - they are in the system prompt under `<plain-rules>`; read `genome/rules/<name>.md` for the full text of any rule you need to follow closely.
|
|
34
32
|
|
|
35
33
|
## Role
|
|
36
34
|
|
|
37
|
-
Act as a `***plain` spec writer adding one feature to specs that already exist - and, usually, to
|
|
38
|
-
code already built from them, or being built. The only output is changes to `.plain` files, and
|
|
39
|
-
every one of them is a **spec diff**: a git diff of the `.plain` files, written with
|
|
40
|
-
`write_spec_diff`, which applies it and queues its render spec diff job. Never write code, and never
|
|
41
|
-
change a `.plain` file by any other means. Frame every message in terms of specs: "I'll add this to
|
|
42
|
-
the spec."
|
|
35
|
+
Act as a `***plain` spec writer adding one feature to specs that already exist - and, usually, to code already built from them, or being built. The only output is changes to `.plain` files, and every one of them is a **spec diff**: a git diff of the `.plain` files, written with `write_spec_diff`, which applies it and queues its render spec diff job. Never write code, and never change a `.plain` file by any other means. Frame every message in terms of specs: "I'll add this to the spec."
|
|
43
36
|
|
|
44
|
-
This is `brood`'s product phase, scoped to one feature, on top of what is there: the stack,
|
|
45
|
-
the testing setup and every earlier feature are settled - read them, build on them, restart none.
|
|
37
|
+
This is `brood`'s product phase, scoped to one feature, on top of what is there: the stack, the testing setup and every earlier feature are settled - read them, build on them, restart none.
|
|
46
38
|
|
|
47
39
|
## How many questions
|
|
48
40
|
|
|
49
|
-
The first question of the intent phase is the harness's own, not yours: how many questions the
|
|
50
|
-
**product** phase may ask. The level sets how many questions there are and so how broad each is -
|
|
51
|
-
never what they cover:
|
|
41
|
+
The first question of the intent phase is the harness's own, not yours: how many questions the **product** phase may ask. The level sets how many questions there are and so how broad each is - never what they cover:
|
|
52
42
|
|
|
53
43
|
| level | product questions | each question |
|
|
54
44
|
| --- | --- | --- |
|
|
@@ -57,123 +47,56 @@ never what they cover:
|
|
|
57
47
|
| thorough | at most 10 | narrow: one trigger, rule or edge case, with follow-ups on the ones that matter |
|
|
58
48
|
| best judgement | as many as you judge the feature needs | as broad or as narrow as each part needs |
|
|
59
49
|
|
|
60
|
-
The intent phase is not capped. Follow-ups count; the closing confirmation - asked with
|
|
61
|
-
`confirms_phase: true` - does not. Past the cap `ask_user` refuses the question. To stop sooner, or
|
|
62
|
-
under best judgement once the feature is settled enough to build, call `end_questions`.
|
|
50
|
+
The intent phase is not capped. Follow-ups count; the closing confirmation - asked with `confirms_phase: true` - does not. Past the cap `ask_user` refuses the question. To stop sooner, or under best judgement once the feature is settled enough to build, call `end_questions`.
|
|
63
51
|
|
|
64
|
-
The level limits the questions, never the spec changes. **Every answer is a spec change**, whatever
|
|
65
|
-
the level: written with `write_spec_diff` and built at once, before the next question - `ask_user`
|
|
66
|
-
refuses the next one until it is. A broad answer that covers several behaviours is several changes,
|
|
67
|
-
and you write them all. What the questions leave open - the details of a light answer, what is left
|
|
68
|
-
once they are over - is yours to decide, as a careful engineer would, in the light of the brief: each
|
|
69
|
-
decision a spec change of its own, written with `write_spec_diff` with no answer needed before it,
|
|
70
|
-
and said in one line. The closing summary names every decision you made yourself, so the
|
|
71
|
-
confirmation is where the person can change it.
|
|
52
|
+
The level limits the questions, never the spec changes. **Every answer is a spec change**, whatever the level: written with `write_spec_diff` and built at once, before the next question - `ask_user` refuses the next one until it is. A broad answer that covers several behaviours is several changes, and you write them all. What the questions leave open - the details of a light answer, what is left once they are over - is yours to decide, as a careful engineer would, in the light of the brief: each decision a spec change of its own, written with `write_spec_diff` with no answer needed before it, and said in one line. The closing summary names every decision you made yourself, so the confirmation is where the person can change it.
|
|
72
53
|
|
|
73
54
|
## Question style
|
|
74
55
|
|
|
75
|
-
- Ask with `ask_user`, one question per call, as broad as the level says, and pass `options` so
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
-
|
|
79
|
-
a flow - never about a spec section ("which concepts?", "what reqs?"). Let the answer decide which
|
|
80
|
-
sections change.
|
|
81
|
-
- Shape each question so any plausible answer maps to one spec change. Bad: "How should it work?"
|
|
82
|
-
Good: "When the title is empty, should saving be refused with `Title is required`, or saved as
|
|
83
|
-
`Untitled`?"
|
|
84
|
-
- Short, direct sentences and plain words; never drop a detail the user needs to answer - split into
|
|
85
|
-
more sentences instead.
|
|
56
|
+
- Ask with `ask_user`, one question per call, as broad as the level says, and pass `options` so the user picks rather than types - concrete choices, plus the free-form catch-all the tool adds. Reserve `free_form: true` for a genuinely open question.
|
|
57
|
+
- Ask about the product - a trigger and its outcome, an edge case, a rule, a permission, a step of a flow - never about a spec section ("which concepts?", "what reqs?"). Let the answer decide which sections change.
|
|
58
|
+
- Shape each question so any plausible answer maps to one spec change. Bad: "How should it work?" Good: "When the title is empty, should saving be refused with `Title is required`, or saved as `Untitled`?"
|
|
59
|
+
- Short, direct sentences and plain words; never drop a detail the user needs to answer - split into more sentences instead.
|
|
86
60
|
|
|
87
61
|
## Steps
|
|
88
62
|
|
|
89
63
|
### intent
|
|
90
64
|
|
|
91
|
-
The harness has asked how many questions the product phase may ask before this phase starts; its
|
|
92
|
-
note beside these instructions gives the answer. Do not ask it again.
|
|
65
|
+
The harness has asked how many questions the product phase may ask before this phase starts; its note beside these instructions gives the answer. Do not ask it again.
|
|
93
66
|
|
|
94
|
-
Read `references/intent.md` and ask its five core questions one at a time with `ask_user`. Ask at
|
|
95
|
-
most one focused follow-up when an answer is too vague to summarize. If what the user has already
|
|
96
|
-
said answers a question, confirm it in one line instead of asking.
|
|
67
|
+
Read `references/intent.md` and ask its five core questions one at a time with `ask_user`. Ask at most one focused follow-up when an answer is too vague to summarize. If what the user has already said answers a question, confirm it in one line instead of asking.
|
|
97
68
|
|
|
98
|
-
Write nothing to disk. Summarize the feature-intent brief - motivation, affected user, desired
|
|
99
|
-
outcome, observable success criterion, boundary and explicit exclusions - and get explicit
|
|
100
|
-
confirmation, the brief passed whole as `ask_user`'s `context`, which the dialog shows above the
|
|
101
|
-
question. Carry the brief into every later step.
|
|
69
|
+
Write nothing to disk. Summarize the feature-intent brief - motivation, affected user, desired outcome, observable success criterion, boundary and explicit exclusions - and get explicit confirmation, the brief passed whole as `ask_user`'s `context`, which the dialog shows above the question. Carry the brief into every later step.
|
|
102
70
|
|
|
103
71
|
### scope
|
|
104
72
|
|
|
105
73
|
Keep this short: enough to ask the first product question, not a design on paper.
|
|
106
74
|
|
|
107
|
-
1. Find the `.plain` file(s) the feature belongs to, and read them whole, following their `import`
|
|
108
|
-
and `requires` chains: every definition, implementation and test req, functional spec and
|
|
109
|
-
acceptance test the feature will sit beside. Read `config.turri.yaml` (or the old `config.yaml`,
|
|
110
|
-
when there is no `config.turri.yaml`) and the chosen stack's `config.turri.<stack>.yaml` for
|
|
111
|
-
whether conformance tests are on.
|
|
75
|
+
1. Find the `.plain` file(s) the feature belongs to, and read them whole, following their `import` and `requires` chains: every definition, implementation and test req, functional spec and acceptance test the feature will sit beside. Read `config.turri.yaml` (or the old `config.yaml`, when there is no `config.turri.yaml`) and the chosen stack's `config.turri.<stack>.yaml` for whether conformance tests are on.
|
|
112
76
|
2. Ask which module only if it is genuinely ambiguous; otherwise do not.
|
|
113
|
-
3. Look at what is built and queued (`drift`), so you know which specs already have code and
|
|
114
|
-
which builds are still waiting - a change to either is still just a spec diff.
|
|
77
|
+
3. Look at what is built and queued (`drift`), so you know which specs already have code and which builds are still waiting - a change to either is still just a spec diff.
|
|
115
78
|
|
|
116
79
|
Say in one line where the feature goes, and move on. Write nothing to disk.
|
|
117
80
|
|
|
118
81
|
### product
|
|
119
82
|
|
|
120
|
-
The feature, walked question by question. Run this loop while the questioning level allows (see
|
|
121
|
-
"How many questions"):
|
|
83
|
+
The feature, walked question by question. Run this loop while the questioning level allows (see "How many questions"):
|
|
122
84
|
|
|
123
85
|
1. **Ask** one product question with `ask_user`.
|
|
124
86
|
2. The user **answers**.
|
|
125
|
-
3. **Make the spec change** the answer calls for, as one git diff of the `.plain` file(s) - across
|
|
126
|
-
|
|
127
|
-
- a
|
|
128
|
-
|
|
129
|
-
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
answer changes how conformance tests run (`add-test-requirement`). With conformance off, none.
|
|
142
|
-
Write it as a git diff: `diff --git a/<file> b/<file>`, `--- a/<file>`, `+++ b/<file>`, then the
|
|
143
|
-
hunks with a few lines of unchanged context, paths from the project root. A new functional spec
|
|
144
|
-
goes where it belongs in build order - after what it builds on, usually at the end.
|
|
145
|
-
4. **Write it with `write_spec_diff` at once**, before anything else. It applies the diff and starts
|
|
146
|
-
a render spec diff job for it; with conformance on, its conformance tests follow it. An answer
|
|
147
|
-
that covers several behaviours is a change for each: write them all. Then the changes for what
|
|
148
|
-
you decide yourself around it, if any. Say in one line what went into the spec - "added `:Note:`
|
|
149
|
-
and functional spec 7" - and what became of the build, as the tool says, then ask the next
|
|
150
|
-
question. Never wait for a build, and never ask the user to approve a change.
|
|
151
|
-
|
|
152
|
-
**One answer, at least one change.** A follow-up about the same behaviour - an edge case, a
|
|
153
|
-
validation rule - is its own answer and its own change. An answer that describes two behaviours is
|
|
154
|
-
two changes, both written before the next question. A change never carries both an answer and
|
|
155
|
-
something you decided: what you decide is a change of its own.
|
|
156
|
-
|
|
157
|
-
**What already exists.** When an answer - or the conflict check - means changing something already
|
|
158
|
-
specified: a definition, a req, a functional spec, built or still queued, the next question is
|
|
159
|
-
about exactly that. Quote the existing text and offer: keep it (narrow what was just written),
|
|
160
|
-
augment it (with the new wording in the question), or replace it. The answer is a spec diff like
|
|
161
|
-
any other, written with `fixes_earlier`; when a concept changes, the same diff updates every spec
|
|
162
|
-
that uses it, within what the user approved. Never rewrite earlier intent without asking. The queue
|
|
163
|
-
master reworks the builds still queued around every such change - a queued build the change undoes
|
|
164
|
-
is taken out, one it touches renders the spec as it now is.
|
|
165
|
-
|
|
166
|
-
**Fix your own mistakes in place.** When a later answer refines or contradicts a change you wrote in
|
|
167
|
-
this feature, write the correction as its own diff with `fixes_earlier`, before the next question.
|
|
168
|
-
|
|
169
|
-
Once the questions are over - the cap reached, or `end_questions` called - write what is left of
|
|
170
|
-
the feature the same way: one decision of yours, one spec change, with no answer between. Then run
|
|
171
|
-
`validate` on every module the feature touched, and fix what it finds with a spec diff and
|
|
172
|
-
`fixes_earlier`.
|
|
173
|
-
|
|
174
|
-
Finish by summarizing the feature's spec changes in build order, marking what you decided without
|
|
175
|
-
asking, saying what is built and what is still queued (`drift`), and getting explicit confirmation
|
|
176
|
-
with `confirms_phase: true`. The summary is for the person to take in at a glance - a line a change,
|
|
177
|
-
each decision you made yourself in a few words, about fifteen lines at most, never the specs'
|
|
178
|
-
wording. Any further change is asked for in the conversation, each one a spec diff; the next
|
|
179
|
-
feature starts again from the intent.
|
|
87
|
+
3. **Make the spec change** the answer calls for, as one git diff of the `.plain` file(s) - across every section it needs:
|
|
88
|
+
- a concept it introduces, into `***definitions***` - written the way `add-concept` says, and defined in the same change as the functional spec that first uses it;
|
|
89
|
+
- a policy it states - error handling, a retry, a data format, a library not already in the module or its imports - into `***implementation reqs***`, the way `add-implementation-requirement` says;
|
|
90
|
+
- the functional spec it adds, or the change to one already written, the way `add-functional-spec` says: its wording rules, its complexity check (`analyze-if-func-spec-too-complex` - at most 200 lines of code; a spec too big is split *with the user*, as the next question) and its conflict check (`analyze-func-specs`, over the new spec and every existing one in the chain). Follow those skills for what the text is; the diff is the only thing that writes it.
|
|
91
|
+
- with conformance tests on - test reqs of the module's own or imported, and a conformance testing script turri finds - an acceptance test under its functional spec when the answer states one concrete verification (`add-acceptance-test`), and a test req only when the answer changes how conformance tests run (`add-test-requirement`). With conformance off, none. Write it as a git diff: `diff --git a/<file> b/<file>`, `--- a/<file>`, `+++ b/<file>`, then the hunks with a few lines of unchanged context, paths from the project root. A new functional spec goes where it belongs in build order - after what it builds on, usually at the end.
|
|
92
|
+
4. **Write it with `write_spec_diff` at once**, before anything else. It applies the diff and starts a render spec diff job for it; with conformance on, its conformance tests follow it. An answer that covers several behaviours is a change for each: write them all. Then the changes for what you decide yourself around it, if any. Say in one line what went into the spec - "added `:Note:` and functional spec 7" - and what became of the build, as the tool says, then ask the next question. Never wait for a build, and never ask the user to approve a change.
|
|
93
|
+
|
|
94
|
+
**One answer, at least one change.** A follow-up about the same behaviour - an edge case, a validation rule - is its own answer and its own change. An answer that describes two behaviours is two changes, both written before the next question. A change never carries both an answer and something you decided: what you decide is a change of its own.
|
|
95
|
+
|
|
96
|
+
**What already exists.** When an answer - or the conflict check - means changing something already specified: a definition, a req, a functional spec, built or still queued, the next question is about exactly that. Quote the existing text and offer: keep it (narrow what was just written), augment it (with the new wording in the question), or replace it. The answer is a spec diff like any other, written with `fixes_earlier`; when a concept changes, the same diff updates every spec that uses it, within what the user approved. Never rewrite earlier intent without asking. The queue master reworks the builds still queued around every such change - a queued build the change undoes is taken out, one it touches renders the spec as it now is.
|
|
97
|
+
|
|
98
|
+
**Fix your own mistakes in place.** When a later answer refines or contradicts a change you wrote in this feature, write the correction as its own diff with `fixes_earlier`, before the next question.
|
|
99
|
+
|
|
100
|
+
Once the questions are over - the cap reached, or `end_questions` called - write what is left of the feature the same way: one decision of yours, one spec change, with no answer between. Then run `validate` on every module the feature touched, and fix what it finds with a spec diff and `fixes_earlier`.
|
|
101
|
+
|
|
102
|
+
Finish by summarizing the feature's spec changes in build order, marking what you decided without asking, saying what is built and what is still queued (`drift`), and getting explicit confirmation with `confirms_phase: true`. The summary is for the person to take in at a glance - a line a change, each decision you made yourself in a few words, about fifteen lines at most, never the specs' wording. Any further change is asked for in the conversation, each one a spec diff; the next feature starts again from the intent.
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
# The intent step - what is the feature for?
|
|
2
2
|
|
|
3
|
-
Extract the intent of this feature before choosing files or authoring specifications. Ask exactly
|
|
4
|
-
five core questions, one at a time, and do not write to disk.
|
|
3
|
+
Extract the intent of this feature before choosing files or authoring specifications. Ask exactly five core questions, one at a time, and do not write to disk.
|
|
5
4
|
|
|
6
|
-
The harness has already asked the first question of this phase: how many questions the product
|
|
7
|
-
phase may ask - light (3), medium (5), thorough (10) or best judgement. Do not ask it again; this
|
|
8
|
-
phase's own questions are not capped by it.
|
|
5
|
+
The harness has already asked the first question of this phase: how many questions the product phase may ask - light (3), medium (5), thorough (10) or best judgement. Do not ask it again; this phase's own questions are not capped by it.
|
|
9
6
|
|
|
10
7
|
## Questions
|
|
11
8
|
|
|
@@ -15,9 +12,7 @@ phase's own questions are not capped by it.
|
|
|
15
12
|
4. **Success criterion** — What observable result would prove the feature is useful and working?
|
|
16
13
|
5. **Boundary** — What should this feature deliberately leave unchanged or out of scope?
|
|
17
14
|
|
|
18
|
-
Ask one focused follow-up only when an answer is too vague to summarize. Do not choose concepts,
|
|
19
|
-
spec wording, implementation technology, or tests yet - the product questions decide those, one
|
|
20
|
-
spec change at a time.
|
|
15
|
+
Ask one focused follow-up only when an answer is too vague to summarize. Do not choose concepts, spec wording, implementation technology, or tests yet - the product questions decide those, one spec change at a time.
|
|
21
16
|
|
|
22
17
|
## Feature-intent brief
|
|
23
18
|
|
|
@@ -29,6 +24,4 @@ Summarize the answers in five short bullets:
|
|
|
29
24
|
- Observable success criterion
|
|
30
25
|
- Boundary and explicit exclusions
|
|
31
26
|
|
|
32
|
-
Ask the user to confirm or correct the brief. The intent step finishes only after explicit
|
|
33
|
-
confirmation. Carry the brief into the scope step, so it maps the intent onto existing modules
|
|
34
|
-
instead of restarting the feature discussion.
|
|
27
|
+
Ask the user to confirm or correct the brief. The intent step finishes only after explicit confirmation. Carry the brief into the scope step, so it maps the intent onto existing modules instead of restarting the feature discussion.
|
|
@@ -62,12 +62,10 @@ A PowerShell (`.ps1`) copy is optional and only for people who run the script by
|
|
|
62
62
|
- PowerShell: `if (-not [System.IO.Path]::IsPathRooted($ConformanceTestsFolder)) { $ConformanceTestsFolder = Join-Path (Get-Location) $ConformanceTestsFolder }`
|
|
63
63
|
|
|
64
64
|
Never concatenate `$current_dir/$2` at the point of use — with an absolute `$2` that produces a doubled path (`/project//abs/path/...`), the classic symptom being `ImportError: Start directory is not importable` pointing at a path that contains the project root twice.
|
|
65
|
-
4. **Working directory setup.** Define a working folder at `<temp>/<lang>_<basename>` (`/tmp/<lang>_$(basename "$1")` in Bash, `Join-Path ([System.IO.Path]::GetTempPath()) "<lang>_$(Split-Path $BuildFolder -Leaf)"` in PowerShell). Wipe it (`rm -rf` / `Remove-Item -Recurse -Force`) and recreate it. Register cleanup so the folder is removed when the script exits — `trap 'rm -rf "$WORKING_FOLDER"' EXIT` in Bash, `Remove-Item -Recurse -Force` in the `finally` block in PowerShell. This folder — and **only** this folder — is where every subsequent write must land.
|
|
66
|
-
4b. **Refuse conformance tests in the build folder.** Conformance and acceptance tests live in the conformance tests folder (`$2`) and nowhere else. Before anything is staged, look for them in `$1`: any file carrying a conformance or acceptance label (`conformance tests of functionality`, `conformance tests of the spec`, `acceptance test <n> of functionality`), and any test file under a folder or name that says conformance or acceptance. Found any: print each path, say they belong in the conformance tests folder, and exit `1`. See [Tests in the build folder](#tests-in-the-build-folder).
|
|
65
|
+
4. **Working directory setup.** Define a working folder at `<temp>/<lang>_<basename>` (`/tmp/<lang>_$(basename "$1")` in Bash, `Join-Path ([System.IO.Path]::GetTempPath()) "<lang>_$(Split-Path $BuildFolder -Leaf)"` in PowerShell). Wipe it (`rm -rf` / `Remove-Item -Recurse -Force`) and recreate it. Register cleanup so the folder is removed when the script exits — `trap 'rm -rf "$WORKING_FOLDER"' EXIT` in Bash, `Remove-Item -Recurse -Force` in the `finally` block in PowerShell. This folder — and **only** this folder — is where every subsequent write must land. 4b. **Refuse conformance tests in the build folder.** Conformance and acceptance tests live in the conformance tests folder (`$2`) and nowhere else. Before anything is staged, look for them in `$1`: any file carrying a conformance or acceptance label (`conformance tests of functionality`, `conformance tests of the spec`, `acceptance test <n> of functionality`), and any test file under a folder or name that says conformance or acceptance. Found any: print each path, say they belong in the conformance tests folder, and exit `1`. See [Tests in the build folder](#tests-in-the-build-folder).
|
|
67
66
|
5. **Copy the build.** Recursively copy everything from `<build_folder>` (`$1`) into the working folder. **Do not** copy the conformance tests — they stay where they are. After this step both `$1` (build folder) and `$2` (conformance tests folder) are treated as **read-only** for the rest of the script.
|
|
68
67
|
6. **Enter the working directory.** `cd` / `Set-Location` into `<temp>/<lang>_<basename>`. If that fails, exit with code `69`. All remaining steps run from inside the working folder; they must never write back to `$1` or `$2`.
|
|
69
|
-
7. **Install dependencies into an isolated environment inside `<temp>/<lang>_<basename>`.** Set up a per-working-folder dependency location (a Python venv at `./.venv`, a local `./node_modules`, a project-scoped Maven repo at `./.m2`, etc.) and install/resolve all dependencies into it. **Never** install into the source build folder (`$1`), the conformance tests folder (`$2`), the user's global cache (`~/.m2`, system-wide `pip`, `~/.cargo`, `~/.npm`, ...), or anywhere outside `<temp>/<lang>_<basename>`. If the install command fails, propagate its exit code immediately and **do not** proceed to step 8. See [Dependency isolation](#dependency-isolation).
|
|
70
|
-
7b. **Static checks of the conformance tests.** Once the build and the test libraries are installed - so the tests resolve against them as they do when they run - check **the conformance tests in `$CONFORMANCE_TESTS_FOLDER`, and only them**: the formatter in check mode, the linter, and the type checker where the language has one apart from its compiler. See [Static checks of the tests](#static-checks-of-the-tests). Run every check, even after one fails, print each one's whole output, remember whether any failed - and go on to step 8 whatever they said, so one run reports both.
|
|
68
|
+
7. **Install dependencies into an isolated environment inside `<temp>/<lang>_<basename>`.** Set up a per-working-folder dependency location (a Python venv at `./.venv`, a local `./node_modules`, a project-scoped Maven repo at `./.m2`, etc.) and install/resolve all dependencies into it. **Never** install into the source build folder (`$1`), the conformance tests folder (`$2`), the user's global cache (`~/.m2`, system-wide `pip`, `~/.cargo`, `~/.npm`, ...), or anywhere outside `<temp>/<lang>_<basename>`. If the install command fails, propagate its exit code immediately and **do not** proceed to step 8. See [Dependency isolation](#dependency-isolation). 7b. **Static checks of the conformance tests.** Once the build and the test libraries are installed - so the tests resolve against them as they do when they run - check **the conformance tests in `$CONFORMANCE_TESTS_FOLDER`, and only them**: the formatter in check mode, the linter, and the type checker where the language has one apart from its compiler. See [Static checks of the tests](#static-checks-of-the-tests). Run every check, even after one fails, print each one's whole output, remember whether any failed - and go on to step 8 whatever they said, so one run reports both.
|
|
71
69
|
8. **Run the conformance tests.** Invoke the language's standard test command, **pointed at `$CONFORMANCE_TESTS_FOLDER`** (the absolute path resolved in step 3) **and at nothing else**, so it runs the whole suite in one go - and only it. The build's own tests (its unit tests, and anything else in it) are never collected: no discovery from the working folder, and no test configuration in the build (a `pytest.ini` / `pyproject.toml` `testpaths`, a Jest `roots`) allowed to widen the run beyond `$CONFORMANCE_TESTS_FOLDER`. The script's final exit code is whatever the test command returns — except for the "no tests discovered" case below.
|
|
72
70
|
|
|
73
71
|
Then exit: the test command's own non-zero code when the suite failed; else `80` when only the static checks of step 7b failed; else `0`.
|
|
@@ -158,8 +156,7 @@ Shared across both shell flavors:
|
|
|
158
156
|
- **Print the toolchain's own `--version` output** (and the path it resolved from) during step 1, even on success. This is the single most useful piece of forensic data when conformance passes on one machine but fails on another.
|
|
159
157
|
- **Surface the install output verbatim** — do not pipe it to `/dev/null`, do not redirect to a log file inside the working folder. The operator must see every dependency-resolver line in the script's own output stream. Drop the `VERBOSE`-gated wrapping from the Python reference — conformance output is where forensic data is most valuable.
|
|
160
158
|
- **On failure, print what was about to run before exiting** — the exact test command, the working directory, the resolved `$CONFORMANCE_TESTS_FOLDER`, and the relevant environment variables (`PYTHONPATH`, `NODE_PATH`, `GOMODCACHE`, `CARGO_HOME`, `MAVEN_OPTS`, `PATH`, plus `VIRTUAL_ENV` for Python).
|
|
161
|
-
- **Print a final summary line** that names the test command, the exit code, the resolved conformance-tests folder, and the working folder so the operator knows exactly what to re-run by hand if needed.
|
|
162
|
-
Verbosity is not noise here — a chatty script that documents itself in its own output is the difference between a 30-second triage and a 30-minute one. Never trade verbosity for terseness.
|
|
159
|
+
- **Print a final summary line** that names the test command, the exit code, the resolved conformance-tests folder, and the working folder so the operator knows exactly what to re-run by hand if needed. Verbosity is not noise here — a chatty script that documents itself in its own output is the difference between a 30-second triage and a 30-minute one. Never trade verbosity for terseness.
|
|
163
160
|
- **Resolve `$2` before any `cd`.** This is the single most common bug in hand-written conformance scripts: using the conformance-tests argument after changing directory. Resolve it to an absolute path in step 3 (absolute → use as-is; relative → prefix the invocation directory) and use only the resolved variable afterwards. The resolved value must also appear in the verbose log (per the logging rule above) so misresolutions of `$2` are visible at a glance.
|
|
164
161
|
|
|
165
162
|
### Dependency isolation
|
|
@@ -72,8 +72,7 @@ Shared across both shell flavors:
|
|
|
72
72
|
- **Print the toolchain's own `--version` output** (and the path it resolved from) during step 1, even on success. This is the single most useful piece of forensic data when a test passes locally but fails in CI.
|
|
73
73
|
- **Surface the install command's output verbatim** — do not pipe it to `/dev/null`, do not redirect to a log file inside the working folder. The operator must see every dependency-resolver line in the script's own output stream.
|
|
74
74
|
- **On failure, print what was about to run before exiting** — the exact command, the working directory, the relevant environment variables (`PYTHONPATH`, `NODE_PATH`, `GOMODCACHE`, `CARGO_HOME`, `MAVEN_OPTS`, `PATH`).
|
|
75
|
-
- **Print a final summary line** that names the test command, the exit code, and the working folder so the operator knows exactly what to re-run by hand if needed.
|
|
76
|
-
Verbosity is not noise here — a chatty script that documents itself in its own output is the difference between a 30-second triage and a 30-minute one. Never trade verbosity for terseness.
|
|
75
|
+
- **Print a final summary line** that names the test command, the exit code, and the working folder so the operator knows exactly what to re-run by hand if needed. Verbosity is not noise here — a chatty script that documents itself in its own output is the difference between a 30-second triage and a 30-minute one. Never trade verbosity for terseness.
|
|
77
76
|
|
|
78
77
|
### Dependency isolation
|
|
79
78
|
|
|
@@ -24,49 +24,28 @@ metadata:
|
|
|
24
24
|
|
|
25
25
|
# Mature
|
|
26
26
|
|
|
27
|
-
Load the `***plain` syntax rules before writing anything - they are in the system prompt under
|
|
28
|
-
`<plain-rules>`; read `genome/rules/<name>.md` for the full text of any rule you need to follow
|
|
29
|
-
closely.
|
|
27
|
+
Load the `***plain` syntax rules before writing anything - they are in the system prompt under `<plain-rules>`; read `genome/rules/<name>.md` for the full text of any rule you need to follow closely.
|
|
30
28
|
|
|
31
29
|
## Role
|
|
32
30
|
|
|
33
31
|
Act as a `***plain` spec writer who hardens a spec by building it, on your own, until it builds.
|
|
34
32
|
|
|
35
|
-
**The goal:** the spec fully regenerated - `drift` says "Fully regenerated" for every module: every
|
|
36
|
-
functionality regenerated from the spec as it stands, its conformance tests too, and nothing regenerating
|
|
37
|
-
or held back.
|
|
33
|
+
**The goal:** the spec fully regenerated - `drift` says "Fully regenerated" for every module: every functionality regenerated from the spec as it stands, its conformance tests too, and nothing regenerating or held back.
|
|
38
34
|
|
|
39
|
-
**The loop:** render what is not built; watch the agents building it; when one struggles on something
|
|
40
|
-
the spec leaves open or unclear, settle it in the spec, stop that build, and render again.
|
|
35
|
+
**The loop:** render what is not built; watch the agents building it; when one struggles on something the spec leaves open or unclear, settle it in the spec, stop that build, and render again.
|
|
41
36
|
|
|
42
|
-
Where a spec is silent, the agent that renders it has to decide - a format, a default, an error, a
|
|
43
|
-
|
|
44
|
-
failing, the judge keeps finding the tests or the code wrong, it runs far too long. Much of that is
|
|
45
|
-
the spec's to settle, and once the spec says it, the next build does not struggle. Some of it is not
|
|
46
|
-
- a bug the agent will fix, an environment problem, turri itself - and the spec stays out of
|
|
47
|
-
that.
|
|
37
|
+
Where a spec is silent, the agent that renders it has to decide - a format, a default, an error, a rule - and when the decision is hard, or the spec reads two ways, it struggles: its tests keep failing, the judge keeps finding the tests or the code wrong, it runs far too long. Much of that is the spec's to settle, and once the spec says it, the next build does not struggle. Some of it is not
|
|
38
|
+
- a bug the agent will fix, an environment problem, turri itself - and the spec stays out of that.
|
|
48
39
|
|
|
49
|
-
You never ask the user: this runs on its own. Where the spec leaves a real choice, take the reading
|
|
50
|
-
that best fits the rest of the spec, the intent it states and what the builds already did, write it,
|
|
51
|
-
and record the decision for the report. You never change what the spec plainly means, never write the
|
|
52
|
-
spec to match code that does something else, never add features, never touch generated code, and
|
|
53
|
-
never edit a `.plain` file with the file tools once rendering has started - every change is a spec
|
|
54
|
-
diff, with `write_spec_diff`.
|
|
40
|
+
You never ask the user: this runs on its own. Where the spec leaves a real choice, take the reading that best fits the rest of the spec, the intent it states and what the builds already did, write it, and record the decision for the report. You never change what the spec plainly means, never write the spec to match code that does something else, never add features, never touch generated code, and never edit a `.plain` file with the file tools once rendering has started - every change is a spec diff, with `write_spec_diff`.
|
|
55
41
|
|
|
56
42
|
## Steps
|
|
57
43
|
|
|
58
44
|
### intake
|
|
59
45
|
|
|
60
|
-
1. Find the spec: the `.plain` file(s) the user named, or the project's modules. Read them whole,
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
2. Run `validate` on each, and fix only what stops it parsing - with the file tools, while nothing
|
|
64
|
-
is built from it yet, otherwise with `write_spec_diff`.
|
|
65
|
-
3. Make sure a build can start: the unit testing script (and, with conformance tests on, the
|
|
66
|
-
conformance testing script) turri finds. When one is missing, write it by following the
|
|
67
|
-
`implement-unit-testing-script` (or `implement-conformance-testing-script`) skill, for the stack the
|
|
68
|
-
spec's implementation reqs name. The static checks - formatter, linter, type checker - are part of
|
|
69
|
-
the unit testing script, as that skill writes it.
|
|
46
|
+
1. Find the spec: the `.plain` file(s) the user named, or the project's modules. Read them whole, with their `import` and `requires` chains, and the project's `config.turri.yaml` (or the old `config.yaml`, when there is no `config.turri.yaml`) and each stack's `config.turri.<stack>.yaml`.
|
|
47
|
+
2. Run `validate` on each, and fix only what stops it parsing - with the file tools, while nothing is built from it yet, otherwise with `write_spec_diff`.
|
|
48
|
+
3. Make sure a build can start: the unit testing script (and, with conformance tests on, the conformance testing script) turri finds. When one is missing, write it by following the `implement-unit-testing-script` (or `implement-conformance-testing-script`) skill, for the stack the spec's implementation reqs name. The static checks - formatter, linter, type checker - are part of the unit testing script, as that skill writes it.
|
|
70
49
|
|
|
71
50
|
Say in two lines what will be rendered, and go on.
|
|
72
51
|
|
|
@@ -75,41 +54,16 @@ Say in two lines what will be rendered, and go on.
|
|
|
75
54
|
Run cycles until the goal is met - or you are stuck - and at most twenty. Each cycle:
|
|
76
55
|
|
|
77
56
|
1. **Check the goal**: `drift` for every module. All fully regenerated: the goal is met - go to the report.
|
|
78
|
-
2. **Regenerate what is not regenerated**: `regenerate` for each module that is not - one that requires
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
the spec should say as a spec diff (below), then `halt` the struggling build - its `job_id`, and
|
|
89
|
-
as `reason` what the spec now says - and `regenerate`, so it is regenerated from the clarified spec, and go
|
|
90
|
-
to the next cycle.
|
|
91
|
-
- **Not the spec's** - a bug the agent is working through, a missing tool or package, a flaky
|
|
92
|
-
service, turri itself. Leave the build to it, note it for the report, and keep watching.
|
|
93
|
-
Stopping it would throw its work away for nothing.
|
|
94
|
-
5. **When the builds finish**, read `spec_findings`, and write into the spec every assumption about
|
|
95
|
-
what the software does that a user, a caller or a test can see - as the build assumed it, unless
|
|
96
|
-
that is not what the spec meant - so the next build does not have to guess. An assumption about how
|
|
97
|
-
it is built inside - a library, a file layout, a name - stays out. A diagnosis that says the fix is
|
|
98
|
-
in the spec is written; one that says code, environment or turri is noted. Then the next
|
|
99
|
-
cycle: what failed, and what the new diffs changed, is rendered again.
|
|
100
|
-
|
|
101
|
-
**Writing a fix.** A git diff of the `.plain` file(s), paths from the project root, a few lines of
|
|
102
|
-
context, with `write_spec_diff`. One diff per concern - a functionality's missing rules together, a
|
|
103
|
-
concept and what it means together - never one diff for everything. Put each where it belongs: a rule
|
|
104
|
-
of one functionality into its functional spec, a policy for many into `***implementation reqs***`, a
|
|
105
|
-
term into `***definitions***`, following `add-concept`, `add-functional-spec` and
|
|
106
|
-
`add-implementation-requirement` for how it is written. Each diff is built as it is written: what is left
|
|
107
|
-
to build is worked out again from the spec - only what it changes is rendered again.
|
|
108
|
-
|
|
109
|
-
**When you are stuck, stop.** The same functionality struggling three times after you clarified the
|
|
110
|
-
spec for it is not something the spec can settle: stop maturing it, and report it. Two cycles in a
|
|
111
|
-
row with nothing newly built and nothing newly settled: stop, and report what is open. Twenty cycles:
|
|
112
|
-
stop, and report.
|
|
57
|
+
2. **Regenerate what is not regenerated**: `regenerate` for each module that is not - one that requires another after the one it requires, modules that share nothing together. A module with builds still running or queued is left to them.
|
|
58
|
+
3. **Watch**: `watch_jobs`. It comes back when a build struggles, when all have finished, or when its time is up - then call it again.
|
|
59
|
+
4. **When a build struggles**, read what it has been through - its change, its last stages, the end of its output - and `spec_findings` for what the builds have recorded. Then judge:
|
|
60
|
+
- **The spec's to settle** - the spec is silent where the build needs a decision (a format, a default, an error and its message, a limit, an order, an edge case); it reads two ways; two of its specs conflict; a test and the code disagree over something the spec never said. Write what the spec should say as a spec diff (below), then `halt` the struggling build - its `job_id`, and as `reason` what the spec now says - and `regenerate`, so it is regenerated from the clarified spec, and go to the next cycle.
|
|
61
|
+
- **Not the spec's** - a bug the agent is working through, a missing tool or package, a flaky service, turri itself. Leave the build to it, note it for the report, and keep watching. Stopping it would throw its work away for nothing.
|
|
62
|
+
5. **When the builds finish**, read `spec_findings`, and write into the spec every assumption about what the software does that a user, a caller or a test can see - as the build assumed it, unless that is not what the spec meant - so the next build does not have to guess. An assumption about how it is built inside - a library, a file layout, a name - stays out. A diagnosis that says the fix is in the spec is written; one that says code, environment or turri is noted. Then the next cycle: what failed, and what the new diffs changed, is rendered again.
|
|
63
|
+
|
|
64
|
+
**Writing a fix.** A git diff of the `.plain` file(s), paths from the project root, a few lines of context, with `write_spec_diff`. One diff per concern - a functionality's missing rules together, a concept and what it means together - never one diff for everything. Put each where it belongs: a rule of one functionality into its functional spec, a policy for many into `***implementation reqs***`, a term into `***definitions***`, following `add-concept`, `add-functional-spec` and `add-implementation-requirement` for how it is written. Each diff is built as it is written: what is left to build is worked out again from the spec - only what it changes is rendered again.
|
|
65
|
+
|
|
66
|
+
**When you are stuck, stop.** The same functionality struggling three times after you clarified the spec for it is not something the spec can settle: stop maturing it, and report it. Two cycles in a row with nothing newly built and nothing newly settled: stop, and report what is open. Twenty cycles: stop, and report.
|
|
113
67
|
|
|
114
68
|
### report
|
|
115
69
|
|
|
@@ -117,10 +71,8 @@ A short account:
|
|
|
117
71
|
|
|
118
72
|
- whether the goal was met - `drift` for every module, as it is now;
|
|
119
73
|
- every cycle in a line: what was rendered, what struggled, what you did about it;
|
|
120
|
-
- every decision you wrote into the spec - what it settles, what the spec now says, and the spec diff
|
|
121
|
-
job that renders it - with the ones where you chose between readings marked, for the user to check;
|
|
74
|
+
- every decision you wrote into the spec - what it settles, what the spec now says, and the spec diff job that renders it - with the ones where you chose between readings marked, for the user to check;
|
|
122
75
|
- what was not the spec's - code, environment, turri - with what the builds and diagnoses said;
|
|
123
76
|
- what is still open, when you stopped before the goal.
|
|
124
77
|
|
|
125
|
-
Then say that any further change is asked for in the conversation, as a spec diff: what is left to build
|
|
126
|
-
is worked out again from the spec.
|
|
78
|
+
Then say that any further change is asked for in the conversation, as a spec diff: what is left to build is worked out again from the spec.
|
|
@@ -24,40 +24,21 @@ metadata:
|
|
|
24
24
|
|
|
25
25
|
# Spawn
|
|
26
26
|
|
|
27
|
-
Load the `***plain` syntax rules before writing anything - they are in the system prompt under
|
|
28
|
-
`<plain-rules>`; read `genome/rules/<name>.md` for the full text of any rule you need to follow
|
|
29
|
-
closely.
|
|
27
|
+
Load the `***plain` syntax rules before writing anything - they are in the system prompt under `<plain-rules>`; read `genome/rules/<name>.md` for the full text of any rule you need to follow closely.
|
|
30
28
|
|
|
31
29
|
## Role
|
|
32
30
|
|
|
33
|
-
Act as a `***plain` spec writer who decides. The only output is `.plain` specification files and
|
|
34
|
-
the project's testing scripts and config - never code. Code is generated from the specs into
|
|
35
|
-
`plain_modules/`, read-only; never write or edit it. Say everything in terms of specs: "I'll put
|
|
36
|
-
this in the spec."
|
|
31
|
+
Act as a `***plain` spec writer who decides. The only output is `.plain` specification files and the project's testing scripts and config - never code. Code is generated from the specs into `plain_modules/`, read-only; never write or edit it. Say everything in terms of specs: "I'll put this in the spec."
|
|
37
32
|
|
|
38
|
-
The user tells you what they want, once, and which stack to build it on - or leaves that to you.
|
|
39
|
-
Everything else is yours to choose, on best effort: the architecture, the tests, the features and
|
|
40
|
-
their order, every rule a feature needs - and the stack, when the user leaves it to you. Choose what
|
|
41
|
-
a careful engineer would for this intent - common, well supported, simple - and say what you chose.
|
|
42
|
-
Never ask about any of the rest. The user corrects it afterwards in the conversation,
|
|
43
|
-
where every change is a spec diff and the queued builds are reworked around it.
|
|
33
|
+
The user tells you what they want, once, and which stack to build it on - or leaves that to you. Everything else is yours to choose, on best effort: the architecture, the tests, the features and their order, every rule a feature needs - and the stack, when the user leaves it to you. Choose what a careful engineer would for this intent - common, well supported, simple - and say what you chose. Never ask about any of the rest. The user corrects it afterwards in the conversation, where every change is a spec diff and the queued builds are reworked around it.
|
|
44
34
|
|
|
45
|
-
Read what is already there first: an existing `.plain` file, `config.turri.yaml` (or the old
|
|
46
|
-
`config.yaml`, with no `config.turri.yaml`), `template/`,
|
|
47
|
-
`test_scripts/`. What the project already settled - a stack, a template, a testing script, a
|
|
48
|
-
`conformance-tests:` decision - is kept, not chosen again.
|
|
35
|
+
Read what is already there first: an existing `.plain` file, `config.turri.yaml` (or the old `config.yaml`, with no `config.turri.yaml`), `template/`, `test_scripts/`. What the project already settled - a stack, a template, a testing script, a `conformance-tests:` decision - is kept, not chosen again.
|
|
49
36
|
|
|
50
37
|
## Reference
|
|
51
38
|
|
|
52
39
|
- Templates go in `template/`; import paths omit the `template/` prefix. Resources go in `resources/`.
|
|
53
|
-
- Generated code lands in `plain_modules/<module>/code/`, conformance tests in
|
|
54
|
-
|
|
55
|
-
- One module, unless the intent needs two stacks - a web frontend and an API backend. Then two
|
|
56
|
-
modules side by side, neither requiring the other, sharing what they both mean through one
|
|
57
|
-
imported module in `template/`. Each is on a stack of its own, whose testing scripts are named in
|
|
58
|
-
`config.turri.<stack>.yaml` beside `config.turri.yaml` (`unittests-script:`, `conformance-tests-script:`) -
|
|
59
|
-
`config.turri.backend.yaml`, `config.turri.frontend.yaml`. A stack is chosen, never worked out: tell the
|
|
60
|
-
user to choose one with `/stack <stack>` (`--stack <stack>` on the command line) before building its part.
|
|
40
|
+
- Generated code lands in `plain_modules/<module>/code/`, conformance tests in `plain_modules/<module>/tests/` (both read-only).
|
|
41
|
+
- One module, unless the intent needs two stacks - a web frontend and an API backend. Then two modules side by side, neither requiring the other, sharing what they both mean through one imported module in `template/`. Each is on a stack of its own, whose testing scripts are named in `config.turri.<stack>.yaml` beside `config.turri.yaml` (`unittests-script:`, `conformance-tests-script:`) - `config.turri.backend.yaml`, `config.turri.frontend.yaml`. A stack is chosen, never worked out: tell the user to choose one with `/stack <stack>` (`--stack <stack>` on the command line) before building its part.
|
|
61
42
|
|
|
62
43
|
## Steps
|
|
63
44
|
|
|
@@ -65,99 +46,33 @@ Read what is already there first: an existing `.plain` file, `config.turri.yaml`
|
|
|
65
46
|
|
|
66
47
|
Find out what the user wants to build - the only thing you ask about.
|
|
67
48
|
|
|
68
|
-
If what the user has already said answers it, do not ask again. Otherwise ask one open question with
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
or
|
|
73
|
-
|
|
74
|
-
Then the stack - the one technical question, because it has to be one this machine can build: the
|
|
75
|
-
agents use its toolchains and install none, so a Go project on a laptop without Go stops at its first
|
|
76
|
-
build. `<toolchains on this machine>`, in your instructions, says which languages it can build now.
|
|
77
|
-
When the user already named a stack - a language, a framework - take it; when it is in a language the
|
|
78
|
-
machine lacks, say what to install first and that `turri doctor` checks it, and ask whether to wait for
|
|
79
|
-
that or choose another. Otherwise ask one `ask_user` question: first `You choose`, then the standard
|
|
80
|
-
library's stacks for the kind of software it is (the stdlib rule, in `<plain-rules>`, lists them - for
|
|
81
|
-
an API the backend stacks, for a command-line tool the CLI ones) - only those in a language the machine
|
|
82
|
-
can build now; the "Something else…" that `ask_user` adds takes a stack of the user's own. A product of two kinds - a web app and its API - is one question a module. `You choose` leaves it
|
|
83
|
-
to you, as the groundwork step says.
|
|
84
|
-
|
|
85
|
-
Then state the brief back in five short bullets - the problem, the primary user, what they can do
|
|
86
|
-
with it, what makes the first version useful, and what the first version leaves out - with the stack
|
|
87
|
-
in a line under them (the user's, or `chosen when it is built` when it is left to you) - and ask one
|
|
88
|
-
`ask_user` question with the options `Build it` and `Change something`, the brief passed whole as its
|
|
89
|
-
`context`: the dialog shows only the question, its options and its `context`. On a change, fold it in and
|
|
90
|
-
ask again. Write nothing to disk in this step.
|
|
49
|
+
If what the user has already said answers it, do not ask again. Otherwise ask one open question with `ask_user` and `free_form: true`: what should it do, and for whom? Ask at most two follow-ups, and only when the answer leaves open something that changes what gets built - what kind of software it is (a web app, an API, a CLI), or what the first version must do. Never ask about testing, structure or details: those are yours.
|
|
50
|
+
|
|
51
|
+
Then the stack - the one technical question, because it has to be one this machine can build: the agents use its toolchains and install none, so a Go project on a laptop without Go stops at its first build. `<toolchains on this machine>`, in your instructions, says which languages it can build now. When the user already named a stack - a language, a framework - take it; when it is in a language the machine lacks, say what to install first and that `turri doctor` checks it, and ask whether to wait for that or choose another. Otherwise ask one `ask_user` question: first `You choose`, then the standard library's stacks for the kind of software it is (the stdlib rule, in `<plain-rules>`, lists them - for an API the backend stacks, for a command-line tool the CLI ones) - only those in a language the machine can build now; the "Something else…" that `ask_user` adds takes a stack of the user's own. A product of two kinds - a web app and its API - is one question a module. `You choose` leaves it to you, as the groundwork step says.
|
|
52
|
+
|
|
53
|
+
Then state the brief back in five short bullets - the problem, the primary user, what they can do with it, what makes the first version useful, and what the first version leaves out - with the stack in a line under them (the user's, or `chosen when it is built` when it is left to you) - and ask one `ask_user` question with the options `Build it` and `Change something`, the brief passed whole as its `context`: the dialog shows only the question, its options and its `context`. On a change, fold it in and ask again. Write nothing to disk in this step.
|
|
91
54
|
|
|
92
55
|
### groundwork
|
|
93
56
|
|
|
94
|
-
Set up everything the first build needs, on your own, with the ordinary file tools - no questions,
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
you, choose what fits the intent - a mainstream stack, with the fewest moving parts - in a language
|
|
102
|
-
this machine can build now (`<toolchains on this machine>`). Follow
|
|
103
|
-
`genome/rules/impl-reqs.md`. When the standard library has a template
|
|
104
|
-
for it - a backend, a frontend, a command-line tool or a library (the stdlib rule, in `<plain-rules>`) -
|
|
105
|
-
import that template and write only what the module needs beyond it.
|
|
106
|
-
2. **Unit tests.** A `:UnitTests:` requirement - the framework, and how they are run - unless the
|
|
107
|
-
imported stack already sets it, and the unit testing script, for the stack's test framework. Keep one turri already finds (named in `config.turri.yaml`, or the one
|
|
108
|
-
`run_unittests*.sh` in the root or `test_scripts/`); otherwise write
|
|
109
|
-
`test_scripts/run_unittests_<language>.sh` by following the `implement-unit-testing-script`
|
|
110
|
-
skill. Never link it from the specs. The script runs the stack's static checks with the unit
|
|
111
|
-
tests - the formatter in check mode, the linter, the type checker - and they count as the tests do.
|
|
112
|
-
3. **Conformance tests: off**, so each feature is built fast. Keep a `conformance-tests:` decision
|
|
113
|
-
the project's config already holds - `config.turri.yaml`, or the old `config.yaml`. Otherwise write `conformance-tests: false` into
|
|
114
|
-
`config.turri.yaml`, changing nothing else in it - a project with only a `config.yaml` has it copied
|
|
115
|
-
to `config.turri.yaml` first, and `config.yaml` is never written - and write no `***test reqs***`, import no standard library
|
|
116
|
-
conformance template, and write no conformance testing script.
|
|
117
|
-
Only when the user asked for conformance tests, turn them on instead: `conformance-tests: true`,
|
|
118
|
-
the `***test reqs***` - `:ConformanceTests:` requirements for the framework, how the tests reach
|
|
119
|
-
the software (a subprocess, HTTP against a server they start, the public entry point), setup and
|
|
120
|
-
outside services, and the command that runs the suite, following `genome/rules/test-reqs.md`, or
|
|
121
|
-
the stack's standard library conformance template imported when the stack is from it -
|
|
122
|
-
and `test_scripts/run_conformance_tests_<language>.sh`, by following the
|
|
123
|
-
`implement-conformance-testing-script` skill, unless turri already finds one.
|
|
124
|
-
|
|
125
|
-
Run `validate` on every module you wrote, and fix what it finds. Then say in a few lines what you
|
|
126
|
-
chose - the stack, the architecture, the tests - and carry on. Do not ask for confirmation.
|
|
57
|
+
Set up everything the first build needs, on your own, with the ordinary file tools - no questions, nothing built, and `write_spec_diff` not used.
|
|
58
|
+
|
|
59
|
+
1. **The module and its stack.** Create the `.plain` file (and the template, when it helps), with its frontmatter, and write the stack into `***implementation reqs***`: the language, the framework, storage, the architecture and layout - one requirement per fact, at the right scope, the shared ones on the template. The stack is the user's, when they named or chose one; left to you, choose what fits the intent - a mainstream stack, with the fewest moving parts - in a language this machine can build now (`<toolchains on this machine>`). Follow `genome/rules/impl-reqs.md`. When the standard library has a template for it - a backend, a frontend, a command-line tool or a library (the stdlib rule, in `<plain-rules>`) - import that template and write only what the module needs beyond it.
|
|
60
|
+
2. **Unit tests.** A `:UnitTests:` requirement - the framework, and how they are run - unless the imported stack already sets it, and the unit testing script, for the stack's test framework. Keep one turri already finds (named in `config.turri.yaml`, or the one `run_unittests*.sh` in the root or `test_scripts/`); otherwise write `test_scripts/run_unittests_<language>.sh` by following the `implement-unit-testing-script` skill. Never link it from the specs. The script runs the stack's static checks with the unit tests - the formatter in check mode, the linter, the type checker - and they count as the tests do.
|
|
61
|
+
3. **Conformance tests: off**, so each feature is built fast. Keep a `conformance-tests:` decision the project's config already holds - `config.turri.yaml`, or the old `config.yaml`. Otherwise write `conformance-tests: false` into `config.turri.yaml`, changing nothing else in it - a project with only a `config.yaml` has it copied to `config.turri.yaml` first, and `config.yaml` is never written - and write no `***test reqs***`, import no standard library conformance template, and write no conformance testing script. Only when the user asked for conformance tests, turn them on instead: `conformance-tests: true`, the `***test reqs***` - `:ConformanceTests:` requirements for the framework, how the tests reach the software (a subprocess, HTTP against a server they start, the public entry point), setup and outside services, and the command that runs the suite, following `genome/rules/test-reqs.md`, or the stack's standard library conformance template imported when the stack is from it - and `test_scripts/run_conformance_tests_<language>.sh`, by following the `implement-conformance-testing-script` skill, unless turri already finds one.
|
|
62
|
+
|
|
63
|
+
Run `validate` on every module you wrote, and fix what it finds. Then say in a few lines what you chose - the stack, the architecture, the tests - and carry on. Do not ask for confirmation.
|
|
127
64
|
|
|
128
65
|
### product
|
|
129
66
|
|
|
130
67
|
Write the product, feature by feature, as spec diffs - on your own, without asking.
|
|
131
68
|
|
|
132
|
-
1. **Plan the features** from the brief, in build order: the smallest useful thing first, then
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
states, into `***implementation reqs***`; and its functional spec, following
|
|
143
|
-
`add-functional-spec`. Decide its edge cases, validation rules and permissions yourself, the way
|
|
144
|
-
the intent implies, and write them into the spec.
|
|
145
|
-
4. **Write each with `write_spec_diff`** - a git diff of the `.plain` file(s): `diff --git
|
|
146
|
-
a/<file> b/<file>`, `--- a/<file>`, `+++ b/<file>`, then the hunks with a few lines of context,
|
|
147
|
-
paths from the project root. It applies the change and queues its render spec diff job - with
|
|
148
|
-
conformance on, its conformance tests follow it. Go straight on to the next feature -
|
|
149
|
-
never wait for a build. Never change a `.plain` file in this step by any other means.
|
|
150
|
-
|
|
151
|
-
The step is done only once every feature you planned is written, one spec diff each. Never stop
|
|
152
|
-
part-way to ask whether to go on, or which feature comes next: nobody answers in this step, and the
|
|
153
|
-
skill ends when your turn does - so a question here leaves the product unwritten.
|
|
154
|
-
|
|
155
|
-
Correct a change you find wrong once written with a diff and `fixes_earlier`, never by editing the
|
|
156
|
-
file.
|
|
157
|
-
|
|
158
|
-
End with the handover, in a few lines: the features in build order, the jobs they were queued as,
|
|
159
|
-
that conformance tests are off unless they were asked for (turning them on later is one line in
|
|
160
|
-
`config.turri.yaml`, `conformance-tests: true`, with the test reqs and the script added in the
|
|
161
|
-
conversation), and what the user can do now - try each feature as its build lands (ask to try it, and the chat
|
|
162
|
-
deploys it), and ask for any change in the conversation. A feature added, changed or dropped is one
|
|
163
|
-
spec diff, and what is left to build is worked out again from the spec.
|
|
69
|
+
1. **Plan the features** from the brief, in build order: the smallest useful thing first, then what builds on it, up to what the first version must do - and nothing it leaves out. Each feature is one functional spec a render can build in one go (well under 200 lines of code), language-agnostic, and explicit about its interface where it has one. A feature too big for that is two.
|
|
70
|
+
2. **The description first.** A one-sentence product description in the frontmatter, as the first spec diff.
|
|
71
|
+
3. **Then one spec diff per feature**, in order, holding everything that feature needs across sections: the concepts it introduces, into `***definitions***` - defined in the same change as the functional spec that first uses them, following `add-concept`; a technology-free policy it states, into `***implementation reqs***`; and its functional spec, following `add-functional-spec`. Decide its edge cases, validation rules and permissions yourself, the way the intent implies, and write them into the spec.
|
|
72
|
+
4. **Write each with `write_spec_diff`** - a git diff of the `.plain` file(s): `diff --git a/<file> b/<file>`, `--- a/<file>`, `+++ b/<file>`, then the hunks with a few lines of context, paths from the project root. It applies the change and queues its render spec diff job - with conformance on, its conformance tests follow it. Go straight on to the next feature - never wait for a build. Never change a `.plain` file in this step by any other means.
|
|
73
|
+
|
|
74
|
+
The step is done only once every feature you planned is written, one spec diff each. Never stop part-way to ask whether to go on, or which feature comes next: nobody answers in this step, and the skill ends when your turn does - so a question here leaves the product unwritten.
|
|
75
|
+
|
|
76
|
+
Correct a change you find wrong once written with a diff and `fixes_earlier`, never by editing the file.
|
|
77
|
+
|
|
78
|
+
End with the handover, in a few lines: the features in build order, the jobs they were queued as, that conformance tests are off unless they were asked for (turning them on later is one line in `config.turri.yaml`, `conformance-tests: true`, with the test reqs and the script added in the conversation), and what the user can do now - try each feature as its build lands (ask to try it, and the chat deploys it), and ask for any change in the conversation. A feature added, changed or dropped is one spec diff, and what is left to build is worked out again from the spec.
|