@turri-dev/cli 0.1.27 → 0.2.0
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/README.md +6 -6
- package/dist/advisor-chat.d.ts +63 -0
- package/dist/advisor-chat.js +290 -0
- package/dist/background-skills.d.ts +53 -0
- package/dist/background-skills.js +121 -0
- package/dist/bedrock-region.d.ts +66 -0
- package/dist/bedrock-region.js +144 -0
- package/dist/btw.d.ts +1 -1
- package/dist/btw.js +1 -1
- package/dist/change-plain-cli.js +20 -13
- package/dist/chat-idle.d.ts +7 -0
- package/dist/chat-idle.js +20 -0
- package/dist/chats.d.ts +10 -0
- package/dist/chats.js +23 -0
- package/dist/cli-options.d.ts +1 -2
- package/dist/cli-options.js +2 -7
- package/dist/cli.js +11 -3
- package/dist/config-command.d.ts +14 -0
- package/dist/config-command.js +35 -15
- package/dist/config-edit.d.ts +3 -3
- package/dist/config-edit.js +16 -12
- package/dist/config.d.ts +54 -34
- package/dist/config.js +40 -44
- package/dist/conform-cli.js +12 -10
- package/dist/conformance-switch.d.ts +34 -0
- package/dist/conformance-switch.js +108 -0
- package/dist/cultivate-cli.js +15 -5
- package/dist/drift-cli.js +2 -0
- package/dist/extension.d.ts +15 -0
- package/dist/extension.js +260 -83
- package/dist/host-session.d.ts +26 -0
- package/dist/host-session.js +30 -2
- package/dist/host.d.ts +5 -2
- package/dist/host.js +7 -1
- package/dist/init-config.d.ts +1 -1
- package/dist/init-config.js +20 -11
- package/dist/loop-cli.d.ts +3 -3
- package/dist/loop-cli.js +13 -16
- package/dist/loop-tools.js +18 -10
- package/dist/model-check.d.ts +8 -3
- package/dist/model-check.js +13 -8
- package/dist/new-project.js +12 -8
- package/dist/{validate-cli.js → parse-cli.js} +11 -5
- package/dist/parse-tool.d.ts +9 -0
- package/dist/parse-tool.js +33 -0
- package/dist/pi-launch.js +1 -1
- package/dist/plain/check.d.ts +53 -6
- package/dist/plain/check.js +217 -24
- package/dist/plain/concepts.d.ts +8 -0
- package/dist/plain/concepts.js +66 -23
- package/dist/plain/cycles.d.ts +21 -0
- package/dist/plain/cycles.js +190 -0
- package/dist/plain/errors.d.ts +4 -0
- package/dist/plain/errors.js +7 -0
- package/dist/plain/files.d.ts +18 -1
- package/dist/plain/files.js +39 -2
- package/dist/plain/graph.d.ts +33 -4
- package/dist/plain/graph.js +60 -12
- package/dist/plain/highlight.d.ts +3 -2
- package/dist/plain/highlight.js +4 -3
- package/dist/plain/index.d.ts +8 -5
- package/dist/plain/index.js +8 -5
- package/dist/plain/liquid.js +1 -6
- package/dist/plain/markdown.d.ts +32 -3
- package/dist/plain/markdown.js +146 -24
- package/dist/plain/module-concepts.js +2 -2
- package/dist/plain/parser.d.ts +83 -28
- package/dist/plain/parser.js +381 -260
- package/dist/plain/plain.tmLanguage.json +29 -3
- package/dist/plain/project.d.ts +48 -0
- package/dist/plain/project.js +155 -0
- package/dist/plain/spec.d.ts +90 -28
- package/dist/plain/spec.js +107 -133
- package/dist/plain/test-plain-file.d.ts +59 -0
- package/dist/plain/test-plain-file.js +232 -0
- package/dist/regenerate/activity.d.ts +20 -9
- package/dist/regenerate/activity.js +11 -4
- package/dist/regenerate/advisor-records.d.ts +93 -0
- package/dist/regenerate/advisor-records.js +110 -0
- package/dist/regenerate/advisor-runs.d.ts +87 -0
- package/dist/regenerate/advisor-runs.js +327 -0
- package/dist/regenerate/base-folder.d.ts +68 -0
- package/dist/regenerate/base-folder.js +168 -0
- package/dist/regenerate/cases.d.ts +9 -6
- package/dist/regenerate/cases.js +70 -14
- package/dist/regenerate/change-view.d.ts +8 -3
- package/dist/regenerate/change-view.js +71 -22
- package/dist/regenerate/chunk-plan.d.ts +36 -15
- package/dist/regenerate/chunk-plan.js +165 -59
- package/dist/regenerate/conform.d.ts +3 -0
- package/dist/regenerate/conform.js +6 -5
- package/dist/regenerate/conformance-agents.d.ts +18 -39
- package/dist/regenerate/conformance-agents.js +60 -88
- package/dist/regenerate/conformance.d.ts +23 -13
- package/dist/regenerate/conformance.js +119 -82
- package/dist/regenerate/diff-view.d.ts +1 -1
- package/dist/regenerate/diff-view.js +20 -4
- package/dist/regenerate/drift.d.ts +47 -15
- package/dist/regenerate/drift.js +101 -30
- package/dist/regenerate/jobs.d.ts +2 -2
- package/dist/regenerate/jobs.js +1 -1
- package/dist/regenerate/ledger.d.ts +19 -0
- package/dist/regenerate/loop.d.ts +62 -43
- package/dist/regenerate/loop.js +472 -341
- package/dist/regenerate/paths.d.ts +4 -0
- package/dist/regenerate/paths.js +7 -1
- package/dist/regenerate/plain-palette.js +2 -0
- package/dist/regenerate/prompt.d.ts +57 -19
- package/dist/regenerate/prompt.js +157 -122
- package/dist/regenerate/records.d.ts +43 -12
- package/dist/regenerate/records.js +102 -88
- package/dist/regenerate/regenerate.js +29 -11
- package/dist/regenerate/regression.d.ts +4 -4
- package/dist/regenerate/regression.js +14 -10
- package/dist/regenerate/renames.d.ts +42 -0
- package/dist/regenerate/renames.js +185 -0
- package/dist/regenerate/requires.d.ts +1 -1
- package/dist/regenerate/requires.js +10 -3
- package/dist/regenerate/resources.d.ts +5 -3
- package/dist/regenerate/resources.js +4 -4
- package/dist/regenerate/scripts-being-written.d.ts +19 -0
- package/dist/regenerate/scripts-being-written.js +30 -0
- package/dist/regenerate/spec-map-view.d.ts +2 -2
- package/dist/regenerate/spec-map-view.js +46 -15
- package/dist/regenerate/spec-map.d.ts +27 -5
- package/dist/regenerate/spec-map.js +92 -60
- package/dist/regenerate/spec-steps.d.ts +48 -5
- package/dist/regenerate/spec-steps.js +213 -28
- package/dist/regenerate/state.d.ts +4 -3
- package/dist/regenerate/stop-report.d.ts +1 -1
- package/dist/regenerate/stop-report.js +10 -10
- package/dist/regenerate/test-advisor.d.ts +101 -0
- package/dist/regenerate/test-advisor.js +379 -0
- package/dist/regenerate/test-kinds.d.ts +71 -28
- package/dist/regenerate/test-kinds.js +110 -63
- package/dist/regenerate/test-scripts.d.ts +2 -0
- package/dist/regenerate/test-scripts.js +4 -0
- package/dist/regenerate/testing-steps.d.ts +41 -0
- package/dist/regenerate/testing-steps.js +110 -0
- package/dist/regenerate/testing.d.ts +1 -1
- package/dist/regenerate/testing.js +5 -4
- package/dist/regenerate/unit-review.d.ts +1 -1
- package/dist/regenerate/unit-review.js +3 -3
- package/dist/regenerate-cli.js +11 -12
- package/dist/release-agent.js +4 -0
- package/dist/release-cli.js +2 -0
- package/dist/release-tools.js +2 -0
- package/dist/run-report.d.ts +2 -2
- package/dist/run-report.js +4 -3
- package/dist/self-invocation.d.ts +1 -1
- package/dist/self-invocation.js +1 -1
- package/dist/sentinel.js +1 -1
- package/dist/setup.d.ts +10 -0
- package/dist/setup.js +52 -4
- package/dist/skill.d.ts +10 -0
- package/dist/skill.js +6 -0
- package/dist/skills.js +3 -1
- package/dist/spec-tools.js +21 -31
- package/dist/test-plain-files.d.ts +41 -0
- package/dist/test-plain-files.js +177 -0
- package/docs/README.md +3 -1
- package/docs/authoring-plain.md +46 -13
- package/docs/chats.md +3 -1
- package/docs/config.md +20 -15
- package/docs/deploy.md +1 -1
- package/docs/development.md +2 -1
- package/docs/headless.md +15 -18
- package/docs/hosting.md +28 -12
- package/docs/installation.md +1 -0
- package/docs/parser.md +88 -27
- package/docs/regenerating.md +87 -52
- package/docs/sentinel.md +1 -1
- package/docs/skills-and-gates.md +3 -1
- package/docs/test-advisor.md +110 -0
- package/docs/theming.md +1 -1
- package/docs/using.md +17 -15
- package/genome/rules/bullet-continuation.md +8 -8
- package/genome/rules/concise-specs-examples.md +111 -80
- package/genome/rules/concise-specs-integration-examples.md +56 -41
- package/genome/rules/concise-specs.md +17 -16
- package/genome/rules/definitions.md +5 -5
- package/genome/rules/examples/integration-embedded-testing/run_conformance_tests_java.sh +1 -1
- package/genome/rules/func-specs.md +69 -74
- package/genome/rules/impl-reqs.md +4 -4
- package/genome/rules/integration-embedded-testing.md +20 -20
- package/genome/rules/integration-embedded.md +31 -31
- package/genome/rules/integration-standalone.md +9 -9
- package/genome/rules/integrations.md +18 -18
- package/genome/rules/linked-resources.md +19 -16
- package/genome/rules/module-structure.md +21 -14
- package/genome/rules/project-model.md +18 -17
- package/genome/rules/required-concepts.md +1 -1
- package/genome/rules/requires-modules.md +6 -5
- package/genome/rules/semantic-ids.md +49 -0
- package/genome/rules/stdlib.md +4 -5
- package/genome/rules/test-plain-files.md +130 -0
- package/genome/rules/test-reqs.md +8 -8
- package/genome/rules/turri-regeneration.md +23 -8
- package/genome/skills/analyze-2-func-specs/SKILL.md +36 -21
- package/genome/skills/analyze-func-specs/SKILL.md +46 -32
- package/genome/skills/break-down-func-spec/SKILL.md +91 -67
- package/genome/skills/consolidate-concepts/SKILL.md +10 -10
- package/genome/skills/convert-old-syntax/SKILL.md +68 -0
- package/genome/skills/convert-old-syntax/references/rubric.md +11 -0
- package/genome/skills/debug-specs/SKILL.md +62 -56
- package/genome/skills/implement-conformance-testing-script/SKILL.md +19 -15
- package/genome/skills/implement-conformance-testing-script/assets/run_conformance_tests_java.sh +2 -2
- package/genome/skills/implement-conformance-testing-script/assets/run_conformance_tests_python.sh +2 -2
- package/genome/skills/implement-unit-testing-script/SKILL.md +14 -10
- package/genome/skills/refactor-module/SKILL.md +35 -35
- package/genome/skills/resolve-section-ownership/SKILL.md +9 -9
- package/genome/skills/resolve-spec-conflict/SKILL.md +35 -29
- package/package.json +7 -6
- package/dist/regenerate/choose-conformance.d.ts +0 -32
- package/dist/regenerate/choose-conformance.js +0 -117
- /package/dist/{validate-cli.d.ts → parse-cli.d.ts} +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: analyze-func-specs
|
|
3
3
|
description: >-
|
|
4
|
-
Analyze a batch of functional specs from a
|
|
4
|
+
Analyze a batch of functional specs from a .plain file to determine
|
|
5
5
|
which pairs conflict. Replaces the pair-by-pair `analyze-2-func-specs` flow
|
|
6
|
-
when a caller wants to check many specs at once (e.g. a new
|
|
7
|
-
every existing
|
|
6
|
+
when a caller wants to check many functional specs at once (e.g. a new one against
|
|
7
|
+
every existing one, or a freshly inserted batch against itself).
|
|
8
8
|
allowed-tools: [read, ls, grep, find]
|
|
9
9
|
---
|
|
10
10
|
|
|
@@ -15,18 +15,18 @@ allowed-tools: [read, ls, grep, find]
|
|
|
15
15
|
A **set of two or more functional specs** to check against each other. Callers typically supply one of:
|
|
16
16
|
|
|
17
17
|
- A whole `***functional specs***` section to self-check.
|
|
18
|
-
- A new spec (or batch of
|
|
19
|
-
- An explicit list of spec snippets the user wants compared.
|
|
18
|
+
- A new functional spec (or batch of them) **plus** the existing functional specs from the same file and any `requires` modules.
|
|
19
|
+
- An explicit list of functional spec snippets the user wants compared.
|
|
20
20
|
|
|
21
|
-
Each spec must be identifiable.
|
|
21
|
+
Each functional spec must be identifiable. Use its func-id (`<module>:<func-id>` when the batch spans modules). A draft that has no func-id yet gets a **stable identifier** in order of appearance: `S1`, `S2`, `S3`, …. Use those identifiers in the output. If the caller provided its own labels or quoted snippets, use those instead and keep them verbatim.
|
|
22
22
|
|
|
23
23
|
The skill also needs the `***definitions***` section (and any imported definitions) so referenced `:Concepts:` can be resolved.
|
|
24
24
|
|
|
25
25
|
## Workflow
|
|
26
26
|
|
|
27
|
-
1. **Read all input specs and the relevant `***definitions***`** so every `:Concept:` is understood.
|
|
28
|
-
2. **Establish chronological order** across the batch. Earlier specs are considered to have been
|
|
29
|
-
3. **Generate the pair list.** Enumerate every unordered pair
|
|
27
|
+
1. **Read all input functional specs and the relevant `***definitions***`** so every `:Concept:` is understood.
|
|
28
|
+
2. **Establish chronological order** across the batch. Earlier functional specs are considered to have been regenerated first; later ones are evaluated with the earlier ones in context. If the caller already provided an order, preserve it.
|
|
29
|
+
3. **Generate the pair list.** Enumerate every unordered pair of functional specs, the earlier first. Skip pairs where the two share no `:Concept:` and no overlapping subject — they are trivially compatible and listing them adds noise.
|
|
30
30
|
4. **Run the conflict analysis below on each remaining pair.** Use the same checklist that the legacy `analyze-2-func-specs` skill used, but apply it pair by pair across the batch in a single pass — do not require the caller to invoke the analyzer once per pair.
|
|
31
31
|
5. **Record every CONFLICTING pair.** Compatible pairs are not listed individually; only the conflicts are emitted.
|
|
32
32
|
6. **Output the verdict** in the format below. No reasoning, no category labels, no resolution suggestions.
|
|
@@ -37,11 +37,14 @@ Work through each question for the pair under inspection. If any answer is "yes"
|
|
|
37
37
|
|
|
38
38
|
### 1. Direct Contradiction
|
|
39
39
|
|
|
40
|
-
Do the two specs make mutually exclusive assertions about the same behavior?
|
|
40
|
+
Do the two functional specs make mutually exclusive assertions about the same behavior?
|
|
41
41
|
|
|
42
42
|
```
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
# sort-by-name
|
|
44
|
+
:Resource: items are returned sorted by name in ascending order.
|
|
45
|
+
|
|
46
|
+
# sort-by-date
|
|
47
|
+
:Resource: items are returned sorted by creation date in descending order.
|
|
45
48
|
|
|
46
49
|
Verdict: CONFLICTING — both define the sort order for the same response,
|
|
47
50
|
but specify different fields and directions. A single implementation cannot
|
|
@@ -50,34 +53,43 @@ satisfy both unless scoped to different contexts.
|
|
|
50
53
|
|
|
51
54
|
### 2. State or Data Conflict
|
|
52
55
|
|
|
53
|
-
Does one spec set a state or value that the other
|
|
56
|
+
Does one functional spec set a state or value that the other assumes is different?
|
|
54
57
|
|
|
55
58
|
```
|
|
56
|
-
|
|
57
|
-
|
|
59
|
+
# empty-task-list
|
|
60
|
+
:TaskList: is initially empty.
|
|
61
|
+
|
|
62
|
+
# welcome-task
|
|
63
|
+
:TaskList: contains a default "Welcome" :Task: on first load.
|
|
58
64
|
|
|
59
65
|
Verdict: CONFLICTING — both define the initial state of :TaskList: differently.
|
|
60
66
|
```
|
|
61
67
|
|
|
62
68
|
### 3. Behavioral Override
|
|
63
69
|
|
|
64
|
-
Does the later spec silently replace behavior established by the earlier
|
|
70
|
+
Does the later functional spec silently replace behavior established by the earlier one without acknowledging it?
|
|
65
71
|
|
|
66
72
|
```
|
|
67
|
-
|
|
68
|
-
|
|
73
|
+
# api-key-auth
|
|
74
|
+
:User: credentials are validated using an API key.
|
|
75
|
+
|
|
76
|
+
# oauth-auth
|
|
77
|
+
:User: credentials are validated using OAuth 2.0.
|
|
69
78
|
|
|
70
79
|
Verdict: CONFLICTING — both define the authentication mechanism but pick
|
|
71
|
-
different approaches. The later
|
|
80
|
+
different approaches. The later one overrides the earlier one.
|
|
72
81
|
```
|
|
73
82
|
|
|
74
83
|
### 4. Scope Ambiguity
|
|
75
84
|
|
|
76
|
-
Are the two specs ambiguous enough that a
|
|
85
|
+
Are the two functional specs ambiguous enough that a coding agent could interpret them as conflicting, even if the user intends them to be complementary?
|
|
77
86
|
|
|
78
87
|
```
|
|
79
|
-
|
|
80
|
-
|
|
88
|
+
# list-resources
|
|
89
|
+
All :Resource: items are returned.
|
|
90
|
+
|
|
91
|
+
# list-active-resources
|
|
92
|
+
Only active :Resource: items are returned.
|
|
81
93
|
|
|
82
94
|
Verdict: CONFLICTING (ambiguous) — "all" vs "only active" appear contradictory.
|
|
83
95
|
Could be resolved by scoping each to different conditions (e.g., filtered vs unfiltered).
|
|
@@ -85,13 +97,16 @@ Could be resolved by scoping each to different conditions (e.g., filtered vs unf
|
|
|
85
97
|
|
|
86
98
|
### 5. Shared Concept, Different Constraints
|
|
87
99
|
|
|
88
|
-
Do both specs impose constraints on the same `:Concept:` that cannot coexist?
|
|
100
|
+
Do both functional specs impose constraints on the same `:Concept:` that cannot coexist?
|
|
89
101
|
|
|
90
102
|
```
|
|
91
|
-
|
|
92
|
-
|
|
103
|
+
# default-batch-size
|
|
104
|
+
:BatchSize: is 100 items.
|
|
105
|
+
|
|
106
|
+
# attachment-batch-size
|
|
107
|
+
:BatchSize: is 50 items for :Resource: types with attachments.
|
|
93
108
|
|
|
94
|
-
Verdict: COMPATIBLE —
|
|
109
|
+
Verdict: COMPATIBLE — attachment-batch-size adds a conditional refinement, not a contradiction.
|
|
95
110
|
```
|
|
96
111
|
|
|
97
112
|
## Output Format
|
|
@@ -104,20 +119,19 @@ If **no pair** is conflicting:
|
|
|
104
119
|
COMPATIBLE
|
|
105
120
|
```
|
|
106
121
|
|
|
107
|
-
If **one or more pairs** are conflicting, emit `CONFLICTING` followed by one line per conflicting pair, in
|
|
122
|
+
If **one or more pairs** are conflicting, emit `CONFLICTING` followed by one line per conflicting pair, in `<a> x <b>` form (the identifiers from step 1, the one that comes first in the input on the left), sorted lexicographically:
|
|
108
123
|
|
|
109
124
|
```
|
|
110
125
|
CONFLICTING
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
S3 x S5
|
|
126
|
+
add-task x import-tasks
|
|
127
|
+
list-tasks x S2
|
|
114
128
|
```
|
|
115
129
|
|
|
116
130
|
Rules for the output:
|
|
117
131
|
|
|
118
132
|
- Do **not** list compatible pairs.
|
|
119
133
|
- Do **not** include reasoning, checklist categories, or fixes — the caller decides what to do with each conflict (typically: invoke `resolve-spec-conflict` on each pair).
|
|
120
|
-
- If the input contained fewer than two specs, emit `COMPATIBLE` (nothing to compare).
|
|
121
|
-
- Identifiers must match exactly what the caller
|
|
134
|
+
- If the input contained fewer than two functional specs, emit `COMPATIBLE` (nothing to compare).
|
|
135
|
+
- Identifiers must match exactly what *Input* settled: the func-ids, the caller's own labels, or the `S1`, `S2`, … fallback for a draft.
|
|
122
136
|
|
|
123
137
|
The internal pairwise analysis informs the verdict but must not appear in the output.
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: break-down-func-spec
|
|
3
3
|
description: >-
|
|
4
|
-
Break down a functional spec that is too complex into smaller
|
|
5
|
-
each imply ≤ 200 lines of code. Use when a spec is judged too large against
|
|
4
|
+
Break down a functional spec that is too complex into smaller ones that
|
|
5
|
+
each imply ≤ 200 lines of code. Use when a functional spec is judged too large against
|
|
6
6
|
the complexity limit (`func-specs.md`), before or after it is written in.
|
|
7
7
|
allowed-tools: [read, write, edit, ls, grep, find]
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
# Break Down Functional
|
|
10
|
+
# Break Down Functional Functional spec
|
|
11
11
|
|
|
12
12
|
## When to Use
|
|
13
13
|
|
|
14
|
-
- A spec is judged to exceed the 200 LOC limit (`func-specs.md`, *Complexity limit*) and needs to be split before it is written in.
|
|
15
|
-
- A spec already written in turns out too large - its pulse could not get its unit tests to pass.
|
|
16
|
-
- A spec bundles multiple behaviors, constructs, or concerns that should be separated.
|
|
14
|
+
- A functional spec is judged to exceed the 200 LOC limit (`func-specs.md`, *Complexity limit*) and needs to be split before it is written in.
|
|
15
|
+
- A functional spec already written in turns out too large - its pulse could not get its unit tests to pass.
|
|
16
|
+
- A functional spec bundles multiple behaviors, constructs, or concerns that should be separated.
|
|
17
17
|
|
|
18
18
|
## Input
|
|
19
19
|
|
|
@@ -22,184 +22,208 @@ The functional spec to break down, plus the full `.plain` file it belongs to.
|
|
|
22
22
|
## Workflow
|
|
23
23
|
|
|
24
24
|
1. **Read the full `.plain` file** — definitions, implementation reqs, and all functional specs (including `requires` modules) to understand context.
|
|
25
|
-
2. **Identify the spec to break down** — the one flagged as too complex or pointed to by the user.
|
|
25
|
+
2. **Identify the functional spec to break down** — the one flagged as too complex or pointed to by the user.
|
|
26
26
|
3. **Analyze why it is too complex** — use the signs in `func-specs.md` (*Complexity limit*):
|
|
27
27
|
- Multiple distinct behaviors bundled together?
|
|
28
28
|
- Too many new constructs introduced at once?
|
|
29
29
|
- Complex branching logic or conditional paths?
|
|
30
|
-
- Cross-cutting concerns mixed with core
|
|
31
|
-
- A full UI screen described in one spec?
|
|
30
|
+
- Cross-cutting concerns mixed with core behaviour?
|
|
31
|
+
- A full UI screen described in one functional spec?
|
|
32
32
|
- Complex data transformations across multiple entities?
|
|
33
33
|
- Implies one substantial technical component (engine, parser, scheduler, algorithm, state machine, sync mechanism) that must be built in code?
|
|
34
|
-
4. **Identify the split boundaries** — find the natural seams where the spec can be divided. Each resulting
|
|
35
|
-
- Independently meaningful (makes sense on its own with
|
|
36
|
-
- Self-contained (does not require a later spec to be useful)
|
|
34
|
+
4. **Identify the split boundaries** — find the natural seams where the functional spec can be divided. Each resulting one must be:
|
|
35
|
+
- Independently meaningful (makes sense on its own with the functional specs before it as context)
|
|
36
|
+
- Self-contained (does not require a later functional spec to be useful)
|
|
37
37
|
- Within the 200 LOC limit
|
|
38
|
-
5. **Draft the
|
|
39
|
-
6. **Verify functional completeness** — this is critical. The
|
|
40
|
-
7. **Verify each replacement
|
|
41
|
-
8. **Check for conflicts** — run `analyze-func-specs` **once** with the full set of
|
|
42
|
-
9. **Replace in the file** — remove the original spec and insert the
|
|
43
|
-
10. **
|
|
38
|
+
5. **Draft the replacements** — write the smaller functional specs in chronological order, each with its own func-id per `semantic-ids.md`; the replacement that keeps the original's main behaviour may keep the original's func-id. The first replacement typically sets up the foundation, and subsequent ones layer behavior on top.
|
|
39
|
+
6. **Verify functional completeness** — this is critical. The replacements taken together must cover **100% of the behaviour** the original describes. Walk through every behavior, condition, and detail in the original and confirm it appears in exactly one of the replacements. Nothing may be lost, weakened, or left implicit. If any behaviour from the original is missing, add it to the appropriate replacement or create an additional one.
|
|
40
|
+
7. **Verify each replacement** — judge each against the complexity limit, and split again any that is still too large.
|
|
41
|
+
8. **Check for conflicts** — run `analyze-func-specs` **once** with the full set of replacements plus every existing functional spec in the file and its `requires` chain. The batched analyzer reports every conflicting pair (replacement × existing and replacement × replacement) in one call — do not loop over pairs. Resolve each reported pair with `resolve-spec-conflict`, then re-run `analyze-func-specs` over the touched set until the verdict is `COMPATIBLE`.
|
|
42
|
+
9. **Replace in the file** — remove the original functional spec (heading and body) and insert the replacements in its position, each as a `# <func-id>` heading with its body, preserving chronological order.
|
|
43
|
+
10. **Bring the test plain files in step**, in the same ***plain diff - every replacement gets its test plain file, each scenario of the original's moves to the replacement it tests, and the original's file is deleted when its func-id is gone (*Keeping test plain files in step* in `test-plain-files.md`). No scenario is written for a replacement that the original's did not have.
|
|
44
|
+
11. **Read the file again** to confirm correct placement and syntax.
|
|
44
45
|
|
|
45
46
|
## Splitting Strategies
|
|
46
47
|
|
|
47
48
|
### Strategy 1: Separate Distinct Behaviors
|
|
48
49
|
|
|
49
|
-
If the spec bundles multiple independently testable actions, split each into its own
|
|
50
|
+
If the functional spec bundles multiple independently testable actions, split each into its own.
|
|
50
51
|
|
|
51
52
|
**Before:**
|
|
52
53
|
```plain
|
|
53
54
|
***functional specs***
|
|
54
55
|
|
|
55
|
-
-
|
|
56
|
+
# manage-recipes
|
|
57
|
+
A :User: can create, edit, and delete :Recipe: items, with validation on all fields.
|
|
56
58
|
```
|
|
57
59
|
|
|
58
60
|
**After:**
|
|
59
61
|
```plain
|
|
60
62
|
***functional specs***
|
|
61
63
|
|
|
62
|
-
|
|
64
|
+
# create-recipe
|
|
65
|
+
A :User: can create a :Recipe:. Only valid :Recipe: items can be created.
|
|
63
66
|
|
|
64
|
-
|
|
67
|
+
# edit-recipe
|
|
68
|
+
A :User: can edit an existing :Recipe:. Validation rules apply to the edited fields.
|
|
65
69
|
|
|
66
|
-
|
|
70
|
+
# delete-recipe
|
|
71
|
+
A :User: can delete a :Recipe:.
|
|
67
72
|
```
|
|
68
73
|
|
|
69
74
|
### Strategy 2: Separate Setup from Behavior
|
|
70
75
|
|
|
71
|
-
If the spec introduces a new construct and immediately defines complex behavior on it, split into setup + behavior.
|
|
76
|
+
If the functional spec introduces a new construct and immediately defines complex behavior on it, split into setup + behavior.
|
|
72
77
|
|
|
73
78
|
**Before:**
|
|
74
79
|
```plain
|
|
75
80
|
***functional specs***
|
|
76
81
|
|
|
77
|
-
|
|
82
|
+
# meal-plan-screen
|
|
83
|
+
The :MealPlan: screen displays a weekly grid of :Slot: items, allows drag-and-drop reordering, and shows nutritional totals per day.
|
|
78
84
|
```
|
|
79
85
|
|
|
80
86
|
**After:**
|
|
81
87
|
```plain
|
|
82
88
|
***functional specs***
|
|
83
89
|
|
|
84
|
-
-
|
|
90
|
+
# meal-plan-grid
|
|
91
|
+
The :MealPlan: screen displays a weekly grid of :Slot: items.
|
|
85
92
|
|
|
86
|
-
|
|
93
|
+
# reorder-slots
|
|
94
|
+
A :User: can reorder :Slot: items within a day on the :MealPlan: screen using drag-and-drop.
|
|
87
95
|
|
|
88
|
-
-
|
|
96
|
+
# daily-nutrition-totals
|
|
97
|
+
The :MealPlan: screen displays nutritional totals for each day.
|
|
89
98
|
```
|
|
90
99
|
|
|
91
100
|
### Strategy 3: Separate Core Logic from Cross-Cutting Concerns
|
|
92
101
|
|
|
93
|
-
If the spec mixes primary
|
|
102
|
+
If the functional spec mixes primary behaviour with error handling, retries, caching, pagination, or logging, pull cross-cutting concerns into their own functional specs.
|
|
94
103
|
|
|
95
104
|
**Before:**
|
|
96
105
|
```plain
|
|
97
106
|
***functional specs***
|
|
98
107
|
|
|
99
|
-
-
|
|
108
|
+
# fetch-ingredients
|
|
109
|
+
:Ingredient: data is fetched from the external API with pagination, retry on transient errors, and caching for 10 minutes.
|
|
100
110
|
```
|
|
101
111
|
|
|
102
112
|
**After:**
|
|
103
113
|
```plain
|
|
104
114
|
***functional specs***
|
|
105
115
|
|
|
106
|
-
-
|
|
116
|
+
# fetch-ingredients
|
|
117
|
+
:Ingredient: data is fetched from the external API.
|
|
107
118
|
|
|
108
|
-
-
|
|
119
|
+
# fetch-ingredients-paged
|
|
120
|
+
:Ingredient: data is fetched from the external API in pages.
|
|
109
121
|
|
|
110
|
-
-
|
|
122
|
+
# retry-ingredient-fetch
|
|
123
|
+
Fetching :Ingredient: data is retried on transient errors.
|
|
111
124
|
```
|
|
112
125
|
|
|
113
126
|
### Strategy 4: Separate Conditional Paths
|
|
114
127
|
|
|
115
|
-
If the spec describes different modes or branches, give each its own
|
|
128
|
+
If the functional spec describes different modes or branches, give each its own.
|
|
116
129
|
|
|
117
130
|
**Before:**
|
|
118
131
|
```plain
|
|
119
132
|
***functional specs***
|
|
120
133
|
|
|
121
|
-
|
|
134
|
+
# generate-meal-plan
|
|
135
|
+
:MealPlan: generation depends on :DietType:. Standard plans use round-robin assignment. Restrictive plans filter out excluded ingredients first, then apply round-robin. Custom plans allow manual slot-by-slot selection.
|
|
122
136
|
```
|
|
123
137
|
|
|
124
138
|
**After:**
|
|
125
139
|
```plain
|
|
126
140
|
***functional specs***
|
|
127
141
|
|
|
128
|
-
-
|
|
142
|
+
# generate-standard-plan
|
|
143
|
+
A standard :MealPlan: is generated using round-robin :Recipe: assignment.
|
|
129
144
|
|
|
130
|
-
-
|
|
131
|
-
|
|
132
|
-
|
|
145
|
+
# generate-restrictive-plan
|
|
146
|
+
A restrictive :MealPlan: is generated.
|
|
147
|
+
- Excluded :Ingredient: items are filtered out first.
|
|
148
|
+
- Round-robin :Recipe: assignment is then applied.
|
|
133
149
|
|
|
134
|
-
|
|
150
|
+
# assign-custom-plan
|
|
151
|
+
A :User: can manually assign :Recipe: items to :Slot: items for a custom :MealPlan:.
|
|
135
152
|
```
|
|
136
153
|
|
|
137
154
|
### Strategy 5: Build UI Incrementally
|
|
138
155
|
|
|
139
|
-
If the spec describes a full screen, split into layout + individual interactive elements.
|
|
156
|
+
If the functional spec describes a full screen, split into layout + individual interactive elements.
|
|
140
157
|
|
|
141
158
|
**Before:**
|
|
142
159
|
```plain
|
|
143
160
|
***functional specs***
|
|
144
161
|
|
|
145
|
-
-
|
|
162
|
+
# dashboard-screen
|
|
163
|
+
The :Dashboard: screen shows a summary card with stats, a scrollable list of recent :MealPlan: items, a floating action button to create a new plan, and a bottom navigation bar.
|
|
146
164
|
```
|
|
147
165
|
|
|
148
166
|
**After:**
|
|
149
167
|
```plain
|
|
150
168
|
***functional specs***
|
|
151
169
|
|
|
152
|
-
-
|
|
170
|
+
# dashboard-summary-card
|
|
171
|
+
The :Dashboard: screen shows a summary card with :MealFrameStats:.
|
|
153
172
|
|
|
154
|
-
-
|
|
173
|
+
# dashboard-recent-plans
|
|
174
|
+
The :Dashboard: screen shows a scrollable list of recent :MealPlan: items.
|
|
155
175
|
|
|
156
|
-
-
|
|
176
|
+
# dashboard-new-plan-button
|
|
177
|
+
The :Dashboard: screen includes a button to create a new :MealPlan:.
|
|
157
178
|
```
|
|
158
179
|
|
|
159
180
|
### Strategy 6: Extract a Reusable Technical Component
|
|
160
181
|
|
|
161
|
-
Sometimes a spec is too complex not because it bundles many behaviors, but because it implies building one substantial technical component inline — an engine, parser, scheduler, layout algorithm, state machine, or sync mechanism. Splitting the behavior sideways does not help when the weight sits in that single component. Instead, pull the component out: define a concept for it, build it in its own dedicated spec placed **earlier** in the chain, then rewrite the original to use the component **by reference**. Because specs
|
|
182
|
+
Sometimes a functional spec is too complex not because it bundles many behaviors, but because it implies building one substantial technical component inline — an engine, parser, scheduler, layout algorithm, state machine, or sync mechanism. Splitting the behavior sideways does not help when the weight sits in that single component. Instead, pull the component out: define a concept for it, build it in its own dedicated functional spec placed **earlier** in the chain, then rewrite the original to use the component **by reference**. Because functional specs are regenerated incrementally top-to-bottom, the original now implies far less code — it wires up a component that already exists rather than implementing it from scratch.
|
|
162
183
|
|
|
163
|
-
Define the component concept in `***definitions***` (per `definitions.md`) before the first spec that references it.
|
|
184
|
+
Define the component concept in `***definitions***` (per `definitions.md`) before the first functional spec that references it.
|
|
164
185
|
|
|
165
186
|
**Before:**
|
|
166
187
|
```plain
|
|
167
188
|
***functional specs***
|
|
168
189
|
|
|
169
|
-
|
|
190
|
+
# export-report-pdf
|
|
191
|
+
A :Report: is exported to PDF, laying out multi-page tables with repeating headers, page numbers, and charts rendered from :Report: data.
|
|
170
192
|
```
|
|
171
193
|
|
|
172
194
|
**After:**
|
|
173
195
|
```plain
|
|
174
196
|
***functional specs***
|
|
175
197
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
198
|
+
# pdf-renderer-tables
|
|
199
|
+
:PdfRenderer: lays out multi-page tables from structured content.
|
|
200
|
+
- Table headers repeat at the top of each page.
|
|
201
|
+
- Each page shows its page number.
|
|
179
202
|
|
|
180
|
-
-
|
|
203
|
+
# export-report-pdf
|
|
204
|
+
A :Report: is exported to PDF using :PdfRenderer:, embedding charts rendered from :Report: data.
|
|
181
205
|
```
|
|
182
206
|
|
|
183
|
-
The extracted component spec and the rewritten original must together still cover 100% of the original
|
|
207
|
+
The extracted component's functional spec and the rewritten original must together still cover 100% of the original behaviour (step 6): the original must **reference** the component, never re-describe it. Keep the component's technology and architecture choices in `***implementation reqs***`, not in the functional spec. If the component is a self-contained subsystem or will be reused across modules, promote it to its own module - one that `requires` it, following `requires-modules.md`, or with `refactor-module` - instead of a sibling functional spec.
|
|
184
208
|
|
|
185
209
|
## Preserving Chronological Order
|
|
186
210
|
|
|
187
|
-
The
|
|
211
|
+
The replacements take the position of the original. Earlier functional specs remain unchanged. The first replacement should make sense given only the functional specs above it. Each subsequent replacement can reference behavior from the ones before it.
|
|
188
212
|
|
|
189
|
-
|
|
213
|
+
The original's test plain file is split the same way: each scenario moves to the replacement it tests, and one that no longer fits a single replacement is rewritten to fit the one it tests most. A replacement no scenario moves to gets no test plain file - never an empty one (see `test-plain-files.md`).
|
|
190
214
|
|
|
191
215
|
## Validation Checklist
|
|
192
216
|
|
|
193
|
-
- [ ]
|
|
194
|
-
- [ ]
|
|
195
|
-
- [ ] Each replacement
|
|
196
|
-
- [ ] No conflicts between
|
|
197
|
-
- [ ] No conflicts between the
|
|
198
|
-
- [ ]
|
|
199
|
-
- [ ] Each replacement
|
|
200
|
-
- [ ] All `:Concepts:` referenced in
|
|
201
|
-
- [ ] Any extracted technical component is defined as a concept, built by its own earlier spec, and only **referenced** (not re-described) by the original
|
|
202
|
-
- [ ]
|
|
203
|
-
- [ ]
|
|
217
|
+
- [ ] The original functional spec has been removed from the file
|
|
218
|
+
- [ ] The replacements together cover 100% of the original's behaviour — nothing lost
|
|
219
|
+
- [ ] Each replacement implies ≤ 200 LOC (judged against the complexity limit)
|
|
220
|
+
- [ ] No conflicts between the replacements and existing functional specs (verified via one batched `analyze-func-specs` call)
|
|
221
|
+
- [ ] No conflicts between the replacements themselves (covered by the same batched call)
|
|
222
|
+
- [ ] The replacements are in correct chronological order
|
|
223
|
+
- [ ] Each replacement is independently meaningful
|
|
224
|
+
- [ ] All `:Concepts:` referenced in the replacements are defined
|
|
225
|
+
- [ ] Any extracted technical component is defined as a concept, built by its own earlier functional spec, and only **referenced** (not re-described) by the original
|
|
226
|
+
- [ ] The replacements are language-agnostic
|
|
227
|
+
- [ ] The replacements trimmed per `concise-specs.md` — a split is not a licence to re-add prose
|
|
204
228
|
- [ ] All external interfaces remain explicit
|
|
205
|
-
- [ ]
|
|
229
|
+
- [ ] Test plain files follow the split: one per replacement, every original scenario moved or rewritten, none bound to a func-id that no longer exists
|
|
@@ -34,11 +34,11 @@ The set of modules to consolidate from, plus optionally the name for the new (or
|
|
|
34
34
|
- Whether it is currently in an `exported_concepts` list
|
|
35
35
|
- Which other concepts it references in its definition (dependency graph)
|
|
36
36
|
3. **Identify consolidation candidates.** A concept should be consolidated if:
|
|
37
|
-
- It is defined in one module but referenced by specs in another module (currently shared via `exported_concepts`)
|
|
37
|
+
- It is defined in one module but referenced by functional specs in another module (currently shared via `exported_concepts`)
|
|
38
38
|
- It is duplicated across multiple modules
|
|
39
39
|
- It is a foundational domain concept that logically belongs in a shared vocabulary
|
|
40
40
|
4. **Identify concepts that should stay local.** A concept should remain in its module if:
|
|
41
|
-
- It is only used within that single module's specs and definitions
|
|
41
|
+
- It is only used within that single module's functional specs and definitions
|
|
42
42
|
- It is an internal implementation detail not meaningful outside that module
|
|
43
43
|
|
|
44
44
|
## Phase 2 — Plan the Consolidation
|
|
@@ -71,7 +71,7 @@ For each affected module, determine the frontmatter changes:
|
|
|
71
71
|
|--------|------|
|
|
72
72
|
| Add the new import to `import` list | Module does not already import the target |
|
|
73
73
|
| Remove concepts from `exported_concepts` | Concepts that were exported only to share definitions — now handled by the import |
|
|
74
|
-
| Keep concepts in `exported_concepts` | Concepts that downstream
|
|
74
|
+
| Keep concepts in `exported_concepts` | Concepts that downstream modules still need via export (because those downstream modules do not import the new template) |
|
|
75
75
|
|
|
76
76
|
**Important:** `import` provides definitions to the importing module. `exported_concepts` on a `requires` module provides concepts to downstream modules in the build chain. If a downstream module will now `import` the shared template directly, the concept can be removed from `exported_concepts`. If a downstream module does **not** import the template, the concept must remain exported.
|
|
77
77
|
|
|
@@ -111,9 +111,9 @@ For each module that had concepts moved out:
|
|
|
111
111
|
|
|
112
112
|
### 3c. Update downstream modules (if applicable)
|
|
113
113
|
|
|
114
|
-
If concepts were removed from a module's `exported_concepts` and downstream
|
|
114
|
+
If concepts were removed from a module's `exported_concepts` and downstream modules relied on them:
|
|
115
115
|
1. Add the new import to the downstream module's `import` list so it gets the concepts directly.
|
|
116
|
-
2. Verify the downstream module's
|
|
116
|
+
2. Verify the downstream module's ***plain can still resolve all concept references.
|
|
117
117
|
|
|
118
118
|
## Phase 4 — Verify
|
|
119
119
|
|
|
@@ -140,7 +140,7 @@ For every affected module (source modules, downstream modules, and the import mo
|
|
|
140
140
|
- [ ] No `***functional specs***` were modified in any module
|
|
141
141
|
- [ ] No `***implementation reqs***` were modified in any module
|
|
142
142
|
- [ ] No `***test reqs***` were modified in any module
|
|
143
|
-
- [ ] No
|
|
143
|
+
- [ ] No test plain file was modified
|
|
144
144
|
|
|
145
145
|
### 4e. Structural validation
|
|
146
146
|
|
|
@@ -164,7 +164,7 @@ Read each modified `.plain` file in full and present the changes to the user for
|
|
|
164
164
|
### Moving a concept that is only used locally
|
|
165
165
|
If a concept is only referenced within a single module, consolidating it into a shared import adds unnecessary coupling. Keep it local.
|
|
166
166
|
|
|
167
|
-
### Forgetting to update downstream
|
|
167
|
+
### Forgetting to update downstream modules
|
|
168
168
|
When a concept is removed from `exported_concepts`, any module that `requires` the source module and references that concept will break — unless it now imports the shared template. Always trace the full dependency chain.
|
|
169
169
|
|
|
170
170
|
### Breaking concept ordering
|
|
@@ -174,7 +174,7 @@ Concepts in the import module must be topologically ordered. If `:Meal:` referen
|
|
|
174
174
|
An import module cannot `import` a module that directly or indirectly imports it back. If the shared concepts reference concepts from an existing template, the new import module should itself import that template — not the other way around.
|
|
175
175
|
|
|
176
176
|
### Removing concepts from exported_concepts prematurely
|
|
177
|
-
Only remove a concept from `exported_concepts` if **every** downstream
|
|
177
|
+
Only remove a concept from `exported_concepts` if **every** downstream module that needs it will now get it via `import`. If even one downstream module does not import the shared template, the export must stay.
|
|
178
178
|
|
|
179
179
|
## Validation Checklist
|
|
180
180
|
|
|
@@ -185,8 +185,8 @@ Only remove a concept from `exported_concepts` if **every** downstream `requires
|
|
|
185
185
|
- [ ] Every affected module's `import` list includes the target import module
|
|
186
186
|
- [ ] `exported_concepts` updated correctly — no missing exports, no unnecessary exports
|
|
187
187
|
- [ ] All concept references in all affected modules resolve correctly
|
|
188
|
-
- [ ] No functional specs, implementation reqs, test reqs, or
|
|
188
|
+
- [ ] No functional specs, implementation reqs, test reqs, or test plain files were modified
|
|
189
189
|
- [ ] Import module is in `template/` and has no functional specs or requires
|
|
190
190
|
- [ ] No circular imports introduced
|
|
191
|
-
- [ ] Downstream
|
|
191
|
+
- [ ] Downstream modules updated if needed
|
|
192
192
|
- [ ] User approved the final result
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: convert-old-syntax
|
|
3
|
+
description: >-
|
|
4
|
+
Convert one module from the old ***plain syntax - functional specs as `- `
|
|
5
|
+
bullets, acceptance tests nested under them - to `# <func-id>` headings and
|
|
6
|
+
test plain files, word for word, the ids confirmed by the person first. Use
|
|
7
|
+
when turri says a module is in the old ***plain syntax, or the person asks to
|
|
8
|
+
convert one. One run converts one module, the lowest of the chain first;
|
|
9
|
+
it never regenerates.
|
|
10
|
+
allowed-tools: [read, ls, grep, find, change_plain, parse]
|
|
11
|
+
metadata:
|
|
12
|
+
phases:
|
|
13
|
+
ids: "a func-id for each functional spec and a scenario-id for each acceptance test, proposed and confirmed"
|
|
14
|
+
rewrite: "the module and its test plain files, in one ***plain diff, word for word"
|
|
15
|
+
check: "parse, and which module is next"
|
|
16
|
+
gates:
|
|
17
|
+
- after: rewrite
|
|
18
|
+
review:
|
|
19
|
+
rubric: ./references/rubric.md
|
|
20
|
+
judges: 2
|
|
21
|
+
quorum: all
|
|
22
|
+
on_fail: retry
|
|
23
|
+
max_retries: 2
|
|
24
|
+
judge_tools: [read, ls, grep, find]
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
# Convert Old Syntax
|
|
28
|
+
|
|
29
|
+
Moves one module from the old ***plain syntax to the new one: each functional spec a `# <func-id>` heading with its body, and its acceptance tests in its test plain file. Nothing is reworded, added or dropped, and nothing is regenerated. The chat runs it again for the next module, asking the person in between.
|
|
30
|
+
|
|
31
|
+
## Steps
|
|
32
|
+
|
|
33
|
+
### ids
|
|
34
|
+
|
|
35
|
+
**Which module.** Convert one module in this run. When the person named one, start at the lowest module of its `requires` chain still in the old syntax - the first, from the bottom of the chain, whose functional specs are `- ` bullets - which may be the one they named. Read the modules of the chain as text to tell: a module in the old syntax has `- ` bullets right under `***functional specs***`, or `***acceptance tests***` nested in it, and no `# <func-id>` heading. Skip import modules, which have no functional specs, and the standard library's templates (`stdlib/...`): there is nothing in them to convert. When every module of the chain is in the new syntax already, change nothing: say so, and that the run is done.
|
|
36
|
+
|
|
37
|
+
**Read the module as text,** with `read` - the parser refuses the old syntax, so `parse` cannot read it yet. Change nothing in this step.
|
|
38
|
+
|
|
39
|
+
**Propose the ids:**
|
|
40
|
+
- A func-id for each functional spec - each top-level `- ` bullet under `***functional specs***`: short kebab-case from what it means (`add-task`), lowercase letters, digits and hyphens only, unique in the module (`semantic-ids.md`)
|
|
41
|
+
- A scenario-id for each acceptance test nested under one, the same way from its text, unique among that functional spec's acceptance tests
|
|
42
|
+
|
|
43
|
+
Ask the person once, with `ask_user`: the whole list in its `context` - each func-id with the first words of its bullet, and under it each scenario-id with the first words of its acceptance test - and options to accept the list or change ids. When they change some, apply the changes and ask again with the new list, until they accept it. Ask nothing else.
|
|
44
|
+
|
|
45
|
+
### rewrite
|
|
46
|
+
|
|
47
|
+
Write the whole conversion as one `change_plain` diff, with the confirmed ids:
|
|
48
|
+
|
|
49
|
+
- **The module.** Under `***functional specs***`, each bullet becomes its `# <func-id>` heading followed by its body: the bullet's text without its leading `- `, word for word. Its sub-bullets become `- ` bullets under that text, one level less indented, word for word and in the same order. Its nested `***acceptance tests***` are taken out of the module. The functional specs keep their order, one blank line between them. The frontmatter, every other section, the comments and any Liquid stay exactly as they are.
|
|
50
|
+
- **Its test plain files,** one for each functional spec that has acceptance tests, at `tests/<module>/<func-id>.plain`: frontmatter `module:` (the module's file name without `.plain`) and `func_id:`, then `***conformance tests***`, then `***acceptance tests***` (`test-plain-files.md`). Each acceptance test of the functional spec becomes a scenario under `***acceptance tests***`: its `# <scenario-id>` heading followed by its text without its `- `, word for word, and its sub-bullets as `- ` bullets under it. `***conformance tests***` stays empty. A functional spec with no acceptance tests gets no test plain file: it has no scenarios.
|
|
51
|
+
|
|
52
|
+
Nothing else: no word added, reworded or dropped, no conformance scenario, no fix to the ***plain however clear it seems. What the conversion shows to be wrong goes in the result, for the person to decide on later.
|
|
53
|
+
|
|
54
|
+
The change regenerates nothing: a module built before func-ids is not built on until its chain is regenerated from scratch, which the chat asks the person for.
|
|
55
|
+
|
|
56
|
+
The record for the review: the module as it was before the change, word for word as you read it; the confirmed ids; and every file the change wrote. When the review sends the step back, show the person what it found and your fix with `ask_user`, then write the fix with one `change_plain`.
|
|
57
|
+
|
|
58
|
+
### check
|
|
59
|
+
|
|
60
|
+
Run `parse` on the module and show what it says in your reply.
|
|
61
|
+
|
|
62
|
+
When it reports an error the conversion made, show it to the person with `ask_user`, with the fix, and write the fix with one `change_plain`; then run `parse` again. An error the module had before the conversion stays for the person.
|
|
63
|
+
|
|
64
|
+
End with the result:
|
|
65
|
+
- the module converted, its functional specs and scenarios counted, and the files written
|
|
66
|
+
- what `parse` said
|
|
67
|
+
- the next module of the chain still in the old syntax, for the chat to convert with this skill again - or that the chain is done
|
|
68
|
+
- that nothing was regenerated: once the whole chain is converted, its code in `plain_modules/` was built when functional specs were numbered, and the chain has to be regenerated from scratch - only with the person's go
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# The conversion lost, changed and added nothing
|
|
2
|
+
|
|
3
|
+
The artifact holds a module as it was in the old ***plain syntax, word for word, the func-ids and scenario-ids the person confirmed, and the files the conversion wrote. Read each file it names from disk, and check every criterion. One violation fails the review; name it, with the functional spec or scenario and the words that differ.
|
|
4
|
+
|
|
5
|
+
1. **Every functional spec is there.** Each top-level `- ` bullet under `***functional specs***` of the module as it was is one `# <func-id>` heading in the module now, with the confirmed func-id, in the same order. No functional spec is missing, and none was added or split.
|
|
6
|
+
2. **Every body is its bullet, word for word.** Under each heading, the text is the bullet's text without its leading `- `, word for word, and its sub-bullets follow as `- ` bullets, word for word and in the same order. Nothing is reworded, shortened, merged, reordered or added - not a word, not a full stop.
|
|
7
|
+
3. **Every acceptance test is a scenario, word for word.** Each acceptance test nested under a bullet is a scenario under `***acceptance tests***` in that functional spec's test plain file: a `# <scenario-id>` heading with the confirmed scenario-id, then the acceptance test's text without its `- `, word for word, its sub-bullets as `- ` bullets.
|
|
8
|
+
4. **Nothing was added to the tests.** No scenario that was not an acceptance test: `***conformance tests***` is empty in every test plain file, and `***acceptance tests***` holds only the converted acceptance tests.
|
|
9
|
+
5. **A test plain file for every functional spec with acceptance tests, and none for the rest.** Each is at `tests/<module>/<func-id>.plain`, with frontmatter `module:` set to the module's name and `func_id:` to its func-id, then `***conformance tests***`, then `***acceptance tests***`, each heading at the start of a line. A functional spec with no acceptance tests has no test plain file - an empty one fails this point.
|
|
10
|
+
6. **The rest of the module is untouched.** The frontmatter, `***definitions***`, `***implementation reqs***`, `***test reqs***`, comments and Liquid read exactly as they did, and no `***acceptance tests***` is left in the module.
|
|
11
|
+
7. **The ids are well formed.** Every func-id and scenario-id is lowercase letters, digits and hyphens only; func-ids are unique in the module, and scenario-ids unique within their functional spec.
|