plain-forge 1.0.23 → 1.0.24-next.019bba8
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 +14 -11
- package/bin/cli.mjs +5 -4
- package/forge/rules/plain-forge.md +10 -0
- package/forge/skills/add-concept/SKILL.md +1 -1
- package/forge/skills/add-feature/SKILL.md +8 -7
- package/forge/skills/add-feature/references/checklist.md +2 -2
- package/forge/skills/add-functional-spec/SKILL.md +14 -10
- package/forge/skills/add-functional-specs/SKILL.md +14 -10
- package/forge/skills/add-implementation-requirement/SKILL.md +1 -1
- package/forge/skills/add-resource/SKILL.md +3 -2
- package/forge/skills/add-template/SKILL.md +1 -1
- package/forge/skills/add-test-requirement/SKILL.md +4 -4
- package/forge/skills/add-test-scenarios/SKILL.md +98 -0
- package/forge/skills/analyze-2-func-specs/SKILL.md +1 -1
- package/forge/skills/analyze-func-specs/SKILL.md +2 -2
- package/forge/skills/analyze-if-func-spec-too-complex/SKILL.md +44 -24
- package/forge/skills/break-down-func-spec/SKILL.md +57 -33
- package/forge/skills/check-plain-env/SKILL.md +2 -2
- package/forge/skills/consolidate-concepts/SKILL.md +8 -8
- package/forge/skills/create-import-module/SKILL.md +1 -1
- package/forge/skills/create-requires-module/SKILL.md +6 -3
- package/forge/skills/debug-specs/SKILL.md +14 -8
- package/forge/skills/forge-plain/SKILL.md +3 -3
- package/forge/skills/forge-plain/references/checklist.md +3 -3
- package/forge/skills/forge-plain/references/phase-1-product.md +2 -2
- package/forge/skills/forge-plain/references/phase-2-tech.md +1 -1
- package/forge/skills/forge-plain/references/phase-3-testing.md +5 -5
- package/forge/skills/init-config-file/SKILL.md +2 -2
- package/forge/skills/init-plain-project/SKILL.md +6 -6
- package/forge/skills/load-plain-reference/SKILL.md +25 -25
- package/forge/skills/load-plain-reference/references/project-model.md +2 -1
- package/forge/skills/load-plain-reference/references/rendering-and-testing.md +7 -5
- package/forge/{rules → skills/load-plain-reference/rules}/bullet-continuation.md +11 -11
- package/forge/{rules → skills/load-plain-reference/rules}/concise-specs-examples.md +100 -69
- package/forge/{rules → skills/load-plain-reference/rules}/concise-specs-integration-examples.md +39 -24
- package/forge/{rules → skills/load-plain-reference/rules}/concise-specs.md +3 -2
- package/forge/{rules → skills/load-plain-reference/rules}/func-specs.md +37 -28
- package/forge/{rules → skills/load-plain-reference/rules}/impl-reqs.md +1 -1
- package/forge/{rules → skills/load-plain-reference/rules}/integration-embedded-testing.md +1 -1
- package/forge/{rules → skills/load-plain-reference/rules}/linked-resources.md +7 -4
- package/forge/{rules → skills/load-plain-reference/rules}/module-structure.md +16 -9
- package/forge/{rules → skills/load-plain-reference/rules}/requires-modules.md +1 -0
- package/forge/skills/load-plain-reference/rules/semantic-ids.md +47 -0
- package/forge/skills/load-plain-reference/rules/test-plain-files.md +67 -0
- package/forge/{rules → skills/load-plain-reference/rules}/test-reqs.md +6 -6
- package/forge/skills/plain-healthcheck/SKILL.md +31 -13
- package/forge/skills/refactor-module/SKILL.md +16 -16
- package/forge/skills/resolve-section-ownership/SKILL.md +3 -3
- package/forge/skills/resolve-spec-conflict/SKILL.md +14 -8
- package/package.json +1 -1
- package/forge/skills/add-acceptance-test/SKILL.md +0 -101
- /package/forge/{rules → skills/load-plain-reference/rules}/definitions.md +0 -0
- /package/forge/{rules → skills/load-plain-reference/rules}/examples/integration-embedded-testing/prepare_environment_java.sh +0 -0
- /package/forge/{rules → skills/load-plain-reference/rules}/examples/integration-embedded-testing/run_conformance_tests_java.sh +0 -0
- /package/forge/{rules → skills/load-plain-reference/rules}/examples/integration-embedded-testing/run_unittests_java.sh +0 -0
- /package/forge/{rules → skills/load-plain-reference/rules}/exported-concepts.md +0 -0
- /package/forge/{rules → skills/load-plain-reference/rules}/import-modules.md +0 -0
- /package/forge/{rules → skills/load-plain-reference/rules}/integration-embedded.md +0 -0
- /package/forge/{rules → skills/load-plain-reference/rules}/integration-standalone.md +0 -0
- /package/forge/{rules → skills/load-plain-reference/rules}/integrations.md +0 -0
- /package/forge/{rules → skills/load-plain-reference/rules}/required-concepts.md +0 -0
|
@@ -10,7 +10,7 @@ description: >-
|
|
|
10
10
|
|
|
11
11
|
# Analyze If Functional Spec Is Too Complex
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
**Load the rules first.** Before you read, edit, or write any `.plain` file, invoke the `load-plain-reference` skill and read the rule files it routes you to. Skip this only if `load-plain-reference` already ran in this conversation.
|
|
14
14
|
|
|
15
15
|
## Why This Matters
|
|
16
16
|
|
|
@@ -50,20 +50,25 @@ Too complex:
|
|
|
50
50
|
```plain
|
|
51
51
|
***functional specs***
|
|
52
52
|
|
|
53
|
-
-
|
|
53
|
+
# manage-tasks
|
|
54
|
+
A :User: can create, edit, delete, and archive :Task: items, with validation on all fields and confirmation dialogs for destructive actions.
|
|
54
55
|
```
|
|
55
56
|
|
|
56
57
|
Acceptable (one behavior each):
|
|
57
58
|
```plain
|
|
58
59
|
***functional specs***
|
|
59
60
|
|
|
60
|
-
|
|
61
|
+
# create-task
|
|
62
|
+
A :User: can create :Task:. Only valid :Task: items can be added.
|
|
61
63
|
|
|
62
|
-
|
|
64
|
+
# edit-task
|
|
65
|
+
A :User: can edit :Task:.
|
|
63
66
|
|
|
64
|
-
|
|
67
|
+
# delete-task
|
|
68
|
+
A :User: can delete :Task:.
|
|
65
69
|
|
|
66
|
-
|
|
70
|
+
# archive-task
|
|
71
|
+
A :User: can archive :Task:.
|
|
67
72
|
|
|
68
73
|
```
|
|
69
74
|
|
|
@@ -84,19 +89,23 @@ Too complex:
|
|
|
84
89
|
```plain
|
|
85
90
|
***functional specs***
|
|
86
91
|
|
|
87
|
-
|
|
92
|
+
# process-order
|
|
93
|
+
:Order: processing depends on :OrderType:. Standard orders are validated and stored. Express orders skip validation and are queued for immediate dispatch. Bulk orders are split into sub-orders of 100 items each, validated individually, and processed in parallel with progress tracking.
|
|
88
94
|
```
|
|
89
95
|
|
|
90
96
|
Acceptable (separate the modes):
|
|
91
97
|
```plain
|
|
92
98
|
***functional specs***
|
|
93
99
|
|
|
94
|
-
-
|
|
100
|
+
# process-standard-order
|
|
101
|
+
A standard :Order: is validated and stored.
|
|
95
102
|
|
|
96
|
-
-
|
|
103
|
+
# process-express-order
|
|
104
|
+
An express :Order: is queued for immediate dispatch without validation.
|
|
97
105
|
|
|
98
|
-
|
|
99
|
-
|
|
106
|
+
# split-bulk-order
|
|
107
|
+
A bulk :Order: is split into sub-orders of 100 items each.
|
|
108
|
+
- Each sub-order is processed individually.
|
|
100
109
|
```
|
|
101
110
|
|
|
102
111
|
### 4. Cross-Cutting Concerns
|
|
@@ -107,17 +116,21 @@ Too complex:
|
|
|
107
116
|
```plain
|
|
108
117
|
***functional specs***
|
|
109
118
|
|
|
110
|
-
-
|
|
119
|
+
# fetch-resources
|
|
120
|
+
:Resource: items are fetched from the external API with pagination support, retry on transient errors with exponential backoff, caching for 5 minutes, and logging of all API calls.
|
|
111
121
|
```
|
|
112
122
|
|
|
113
123
|
Acceptable (separate concerns):
|
|
114
124
|
```plain
|
|
115
125
|
***functional specs***
|
|
116
|
-
-
|
|
126
|
+
# fetch-resources
|
|
127
|
+
:Resource: items are fetched from the external API.
|
|
117
128
|
|
|
118
|
-
-
|
|
129
|
+
# fetch-resources-paged
|
|
130
|
+
:Resource: items are fetched from the external API in pages.
|
|
119
131
|
|
|
120
|
-
-
|
|
132
|
+
# retry-resource-fetch
|
|
133
|
+
Fetching :Resource: items is retried on transient errors using exponential backoff.
|
|
121
134
|
```
|
|
122
135
|
|
|
123
136
|
### 5. UI Complexity
|
|
@@ -128,18 +141,22 @@ Too complex:
|
|
|
128
141
|
```plain
|
|
129
142
|
***functional specs***
|
|
130
143
|
|
|
131
|
-
|
|
144
|
+
# dashboard
|
|
145
|
+
The dashboard shows :User: profile, recent :Task: items in a sortable table, a notification bell with unread count, and a sidebar with navigation links that highlights the active page.
|
|
132
146
|
```
|
|
133
147
|
|
|
134
148
|
Acceptable (build incrementally):
|
|
135
149
|
```plain
|
|
136
150
|
***functional specs***
|
|
137
151
|
|
|
138
|
-
|
|
152
|
+
# dashboard-page
|
|
153
|
+
A dashboard page is shown for :User:.
|
|
139
154
|
|
|
140
|
-
|
|
155
|
+
# dashboard-recent-tasks
|
|
156
|
+
Recent :Task: items are shown in a sortable table on the dashboard.
|
|
141
157
|
|
|
142
|
-
|
|
158
|
+
# dashboard-notifications
|
|
159
|
+
A notification indicator with the unread count is shown on the dashboard.
|
|
143
160
|
```
|
|
144
161
|
|
|
145
162
|
### 6. Data Transformation Complexity
|
|
@@ -157,18 +174,21 @@ Too complex (builds the component and uses it in one spec):
|
|
|
157
174
|
```plain
|
|
158
175
|
***functional specs***
|
|
159
176
|
|
|
160
|
-
|
|
177
|
+
# export-report-pdf
|
|
178
|
+
A :Report: is exported to PDF, laying out multi-page tables with repeating headers and page numbers, and charts rendered from :Report: data.
|
|
161
179
|
```
|
|
162
180
|
|
|
163
181
|
Acceptable (component in its own spec, then referenced):
|
|
164
182
|
```plain
|
|
165
183
|
***functional specs***
|
|
166
184
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
185
|
+
# pdf-renderer-tables
|
|
186
|
+
:PdfRenderer: lays out multi-page tables from structured content.
|
|
187
|
+
- Table headers repeat at the top of each page.
|
|
188
|
+
- Each page shows its page number.
|
|
170
189
|
|
|
171
|
-
-
|
|
190
|
+
# export-report-pdf
|
|
191
|
+
A :Report: is exported to PDF using :PdfRenderer:, embedding charts rendered from :Report: data.
|
|
172
192
|
```
|
|
173
193
|
|
|
174
194
|
When this indicator fires, the fix is `break-down-func-spec` Strategy 6 — extract the component into its own earlier spec and reference it.
|
|
@@ -8,7 +8,7 @@ description: >-
|
|
|
8
8
|
|
|
9
9
|
# Break Down Functional Spec
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
**Load the rules first.** Before you read, edit, or write any `.plain` file, invoke the `load-plain-reference` skill and read the rule files it routes you to. Skip this only if `load-plain-reference` already ran in this conversation.
|
|
12
12
|
|
|
13
13
|
## When to Use
|
|
14
14
|
|
|
@@ -36,12 +36,13 @@ The functional spec to break down, plus the full `.plain` file it belongs to.
|
|
|
36
36
|
- Independently meaningful (makes sense on its own with previous specs as context)
|
|
37
37
|
- Self-contained (does not require a later spec to be useful)
|
|
38
38
|
- Within the 200 LOC limit
|
|
39
|
-
5. **Draft the replacement specs** — write the smaller specs in chronological order. The first replacement spec typically sets up the foundation, and subsequent ones layer behavior on top.
|
|
39
|
+
5. **Draft the replacement specs** — write the smaller specs in chronological order, each with its own func-id per `semantic-ids.md`; the replacement that keeps the original's main behavior may keep the original's func-id. The first replacement spec typically sets up the foundation, and subsequent ones layer behavior on top.
|
|
40
40
|
6. **Verify functional completeness** — this is critical. The replacement specs taken together must cover **100% of the functionality** described in the original spec. Walk through every behavior, condition, and detail in the original and confirm it appears in exactly one of the replacement specs. Nothing may be lost, weakened, or left implicit. If any functionality from the original is missing, add it to the appropriate replacement spec or create an additional one.
|
|
41
41
|
7. **Verify each replacement spec** — run `analyze-if-func-spec-too-complex` on each to confirm it fits within the limit.
|
|
42
42
|
8. **Check for conflicts** — run `analyze-func-specs` **once** with the full set of replacement specs plus every existing spec in the file and its `requires` chain. The batched analyzer reports every conflicting pair (replacement × existing and replacement × replacement) in one call — do not loop over pairs. Resolve each reported pair with `resolve-spec-conflict`, then re-run `analyze-func-specs` over the touched set until the verdict is `COMPATIBLE`.
|
|
43
|
-
9. **Replace in the file** — remove the original
|
|
44
|
-
10. **
|
|
43
|
+
9. **Replace in the file** — remove the original functionality (heading and body) and insert the replacement functionalities, each as a `# <func-id>` heading with its body, in its position, preserving chronological order.
|
|
44
|
+
10. **Bring the test plain files in step** — invoke `add-test-scenarios` for each replacement functionality. It moves every scenario of the original's test plain file to the replacement it tests, writes scenarios for outcomes that have none, and deletes the original's file when its func-id no longer exists.
|
|
45
|
+
11. **Read the file again** to confirm correct placement and syntax.
|
|
45
46
|
|
|
46
47
|
## Splitting Strategies
|
|
47
48
|
|
|
@@ -53,18 +54,22 @@ If the spec bundles multiple independently testable actions, split each into its
|
|
|
53
54
|
```plain
|
|
54
55
|
***functional specs***
|
|
55
56
|
|
|
56
|
-
-
|
|
57
|
+
# manage-recipes
|
|
58
|
+
A :User: can create, edit, and delete :Recipe: items, with validation on all fields.
|
|
57
59
|
```
|
|
58
60
|
|
|
59
61
|
**After:**
|
|
60
62
|
```plain
|
|
61
63
|
***functional specs***
|
|
62
64
|
|
|
63
|
-
|
|
65
|
+
# create-recipe
|
|
66
|
+
A :User: can create a :Recipe:. Only valid :Recipe: items can be created.
|
|
64
67
|
|
|
65
|
-
|
|
68
|
+
# edit-recipe
|
|
69
|
+
A :User: can edit an existing :Recipe:. Validation rules apply to the edited fields.
|
|
66
70
|
|
|
67
|
-
|
|
71
|
+
# delete-recipe
|
|
72
|
+
A :User: can delete a :Recipe:.
|
|
68
73
|
```
|
|
69
74
|
|
|
70
75
|
### Strategy 2: Separate Setup from Behavior
|
|
@@ -75,18 +80,22 @@ If the spec introduces a new construct and immediately defines complex behavior
|
|
|
75
80
|
```plain
|
|
76
81
|
***functional specs***
|
|
77
82
|
|
|
78
|
-
|
|
83
|
+
# meal-plan-screen
|
|
84
|
+
The :MealPlan: screen displays a weekly grid of :Slot: items, allows drag-and-drop reordering, and shows nutritional totals per day.
|
|
79
85
|
```
|
|
80
86
|
|
|
81
87
|
**After:**
|
|
82
88
|
```plain
|
|
83
89
|
***functional specs***
|
|
84
90
|
|
|
85
|
-
-
|
|
91
|
+
# meal-plan-grid
|
|
92
|
+
The :MealPlan: screen displays a weekly grid of :Slot: items.
|
|
86
93
|
|
|
87
|
-
|
|
94
|
+
# reorder-slots
|
|
95
|
+
A :User: can reorder :Slot: items within a day on the :MealPlan: screen using drag-and-drop.
|
|
88
96
|
|
|
89
|
-
-
|
|
97
|
+
# daily-nutrition-totals
|
|
98
|
+
The :MealPlan: screen displays nutritional totals for each day.
|
|
90
99
|
```
|
|
91
100
|
|
|
92
101
|
### Strategy 3: Separate Core Logic from Cross-Cutting Concerns
|
|
@@ -97,18 +106,22 @@ If the spec mixes primary functionality with error handling, retries, caching, p
|
|
|
97
106
|
```plain
|
|
98
107
|
***functional specs***
|
|
99
108
|
|
|
100
|
-
-
|
|
109
|
+
# fetch-ingredients
|
|
110
|
+
:Ingredient: data is fetched from the external API with pagination, retry on transient errors, and caching for 10 minutes.
|
|
101
111
|
```
|
|
102
112
|
|
|
103
113
|
**After:**
|
|
104
114
|
```plain
|
|
105
115
|
***functional specs***
|
|
106
116
|
|
|
107
|
-
-
|
|
117
|
+
# fetch-ingredients
|
|
118
|
+
:Ingredient: data is fetched from the external API.
|
|
108
119
|
|
|
109
|
-
-
|
|
120
|
+
# fetch-ingredients-paged
|
|
121
|
+
:Ingredient: data is fetched from the external API in pages.
|
|
110
122
|
|
|
111
|
-
-
|
|
123
|
+
# retry-ingredient-fetch
|
|
124
|
+
Fetching :Ingredient: data is retried on transient errors.
|
|
112
125
|
```
|
|
113
126
|
|
|
114
127
|
### Strategy 4: Separate Conditional Paths
|
|
@@ -119,20 +132,24 @@ If the spec describes different modes or branches, give each its own spec.
|
|
|
119
132
|
```plain
|
|
120
133
|
***functional specs***
|
|
121
134
|
|
|
122
|
-
|
|
135
|
+
# generate-meal-plan
|
|
136
|
+
: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.
|
|
123
137
|
```
|
|
124
138
|
|
|
125
139
|
**After:**
|
|
126
140
|
```plain
|
|
127
141
|
***functional specs***
|
|
128
142
|
|
|
129
|
-
-
|
|
143
|
+
# generate-standard-plan
|
|
144
|
+
A standard :MealPlan: is generated using round-robin :Recipe: assignment.
|
|
130
145
|
|
|
131
|
-
-
|
|
132
|
-
|
|
133
|
-
|
|
146
|
+
# generate-restrictive-plan
|
|
147
|
+
A restrictive :MealPlan: is generated.
|
|
148
|
+
- Excluded :Ingredient: items are filtered out first.
|
|
149
|
+
- Round-robin :Recipe: assignment is then applied.
|
|
134
150
|
|
|
135
|
-
|
|
151
|
+
# assign-custom-plan
|
|
152
|
+
A :User: can manually assign :Recipe: items to :Slot: items for a custom :MealPlan:.
|
|
136
153
|
```
|
|
137
154
|
|
|
138
155
|
### Strategy 5: Build UI Incrementally
|
|
@@ -143,18 +160,22 @@ If the spec describes a full screen, split into layout + individual interactive
|
|
|
143
160
|
```plain
|
|
144
161
|
***functional specs***
|
|
145
162
|
|
|
146
|
-
-
|
|
163
|
+
# dashboard-screen
|
|
164
|
+
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.
|
|
147
165
|
```
|
|
148
166
|
|
|
149
167
|
**After:**
|
|
150
168
|
```plain
|
|
151
169
|
***functional specs***
|
|
152
170
|
|
|
153
|
-
-
|
|
171
|
+
# dashboard-summary-card
|
|
172
|
+
The :Dashboard: screen shows a summary card with :MealFrameStats:.
|
|
154
173
|
|
|
155
|
-
-
|
|
174
|
+
# dashboard-recent-plans
|
|
175
|
+
The :Dashboard: screen shows a scrollable list of recent :MealPlan: items.
|
|
156
176
|
|
|
157
|
-
-
|
|
177
|
+
# dashboard-new-plan-button
|
|
178
|
+
The :Dashboard: screen includes a button to create a new :MealPlan:.
|
|
158
179
|
```
|
|
159
180
|
|
|
160
181
|
### Strategy 6: Extract a Reusable Technical Component
|
|
@@ -167,18 +188,21 @@ Define the component concept in `***definitions***` (via `add-concept`) before t
|
|
|
167
188
|
```plain
|
|
168
189
|
***functional specs***
|
|
169
190
|
|
|
170
|
-
|
|
191
|
+
# export-report-pdf
|
|
192
|
+
A :Report: is exported to PDF, laying out multi-page tables with repeating headers, page numbers, and charts rendered from :Report: data.
|
|
171
193
|
```
|
|
172
194
|
|
|
173
195
|
**After:**
|
|
174
196
|
```plain
|
|
175
197
|
***functional specs***
|
|
176
198
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
199
|
+
# pdf-renderer-tables
|
|
200
|
+
:PdfRenderer: lays out multi-page tables from structured content.
|
|
201
|
+
- Table headers repeat at the top of each page.
|
|
202
|
+
- Each page shows its page number.
|
|
180
203
|
|
|
181
|
-
-
|
|
204
|
+
# export-report-pdf
|
|
205
|
+
A :Report: is exported to PDF using :PdfRenderer:, embedding charts rendered from :Report: data.
|
|
182
206
|
```
|
|
183
207
|
|
|
184
208
|
The extracted component spec and the rewritten original must together still cover 100% of the original functionality (step 6): the original must **reference** the component, never re-describe it. Keep the component's technology and architecture choices in `***implementation reqs***`, not in the functional spec. If the component is a self-contained subsystem or will be reused across modules, promote it to its own module with `create-requires-module` / `refactor-module` instead of a sibling spec.
|
|
@@ -187,7 +211,7 @@ The extracted component spec and the rewritten original must together still cove
|
|
|
187
211
|
|
|
188
212
|
The replacement specs take the position of the original spec. Earlier specs remain unchanged. The first replacement spec should make sense given only the specs above it. Each subsequent replacement spec can reference behavior from the ones before it.
|
|
189
213
|
|
|
190
|
-
|
|
214
|
+
The original functionality's test plain file is split the same way: each scenario moves to the replacement functionality it tests, a scenario that no longer fits one replacement is rewritten, and each replacement ends with at least one conformance scenario when conformance tests are enabled (see `add-test-scenarios`).
|
|
191
215
|
|
|
192
216
|
## Validation Checklist
|
|
193
217
|
|
|
@@ -203,4 +227,4 @@ If the original spec had acceptance tests, redistribute them to the most appropr
|
|
|
203
227
|
- [ ] Replacement specs are language-agnostic
|
|
204
228
|
- [ ] Replacement specs trimmed per `concise-specs.md` — a split is not a licence to re-add prose
|
|
205
229
|
- [ ] All external interfaces remain explicit
|
|
206
|
-
- [ ]
|
|
230
|
+
- [ ] Test plain files follow the split: one per replacement functionality, every original scenario moved or rewritten, none bound to a func-id that no longer exists
|
|
@@ -12,7 +12,7 @@ description: >-
|
|
|
12
12
|
|
|
13
13
|
# Check Plain Env
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
**Load the rules first.** Before you read, edit, or write any `.plain` file, invoke the `load-plain-reference` skill and read the rule files it routes you to. Skip this only if `load-plain-reference` already ran in this conversation.
|
|
16
16
|
|
|
17
17
|
This skill answers one question: **does the host machine have everything the ***plain project needs to render and test?** It reads the project, derives the requirement list, probes the machine, and returns a report. It never installs anything itself — that decision belongs to the user.
|
|
18
18
|
|
|
@@ -43,7 +43,7 @@ The skill is a **derive → probe → report** pass. It does not stop at the fir
|
|
|
43
43
|
### Step 1 — Inventory the project
|
|
44
44
|
|
|
45
45
|
1. **Detect the host OS** first. Run `uname -s 2>/dev/null || echo "$OS"`. Use the result to (a) pick the right script extensions to inspect (`.sh` vs `.ps1`) and (b) pick the right install commands later (Homebrew, apt, dnf, pacman, choco, scoop, winget).
|
|
46
|
-
2. **List every `.plain` file** in the repo root and in any subdirectory that contains them. Note which are top modules (not `requires`-ed by
|
|
46
|
+
2. **List every `.plain` file** in the repo root and in any subdirectory that contains them. Note which are top modules (not `requires`-ed by any other module) and which are import modules (under `template/`).
|
|
47
47
|
3. **List every `config.yaml`** in the repo and read each one. Note the `*-script` keys it sets and the values they point at.
|
|
48
48
|
4. **List every script under `test_scripts/`** (both `.sh` and `.ps1` — projects can ship both).
|
|
49
49
|
5. **List every file under `resources/`** if the directory exists. Schemas and protocol files there often imply running services (e.g. a Postgres `.sql` schema implies a Postgres server).
|
|
@@ -9,7 +9,7 @@ description: >-
|
|
|
9
9
|
|
|
10
10
|
# Consolidate Concepts
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
**Load the rules first.** Before you read, edit, or write any `.plain` file, invoke the `load-plain-reference` skill and read the rule files it routes you to. Skip this only if `load-plain-reference` already ran in this conversation.
|
|
13
13
|
|
|
14
14
|
## When to Use
|
|
15
15
|
|
|
@@ -72,7 +72,7 @@ For each affected module, determine the frontmatter changes:
|
|
|
72
72
|
|--------|------|
|
|
73
73
|
| Add the new import to `import` list | Module does not already import the target |
|
|
74
74
|
| Remove concepts from `exported_concepts` | Concepts that were exported only to share definitions — now handled by the import |
|
|
75
|
-
| Keep concepts in `exported_concepts` | Concepts that downstream
|
|
75
|
+
| Keep concepts in `exported_concepts` | Concepts that downstream modules still need via export (because those downstream modules do not import the new template) |
|
|
76
76
|
|
|
77
77
|
**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.
|
|
78
78
|
|
|
@@ -112,7 +112,7 @@ For each module that had concepts moved out:
|
|
|
112
112
|
|
|
113
113
|
### 3c. Update downstream modules (if applicable)
|
|
114
114
|
|
|
115
|
-
If concepts were removed from a module's `exported_concepts` and downstream
|
|
115
|
+
If concepts were removed from a module's `exported_concepts` and downstream modules relied on them:
|
|
116
116
|
1. Add the new import to the downstream module's `import` list so it gets the concepts directly.
|
|
117
117
|
2. Verify the downstream module's specs can still resolve all concept references.
|
|
118
118
|
|
|
@@ -141,7 +141,7 @@ For every affected module (source modules, downstream modules, and the import mo
|
|
|
141
141
|
- [ ] No `***functional specs***` were modified in any module
|
|
142
142
|
- [ ] No `***implementation reqs***` were modified in any module
|
|
143
143
|
- [ ] No `***test reqs***` were modified in any module
|
|
144
|
-
- [ ] No
|
|
144
|
+
- [ ] No test plain file was modified
|
|
145
145
|
|
|
146
146
|
### 4e. Structural validation
|
|
147
147
|
|
|
@@ -165,7 +165,7 @@ Read each modified `.plain` file in full and present the changes to the user for
|
|
|
165
165
|
### Moving a concept that is only used locally
|
|
166
166
|
If a concept is only referenced within a single module, consolidating it into a shared import adds unnecessary coupling. Keep it local.
|
|
167
167
|
|
|
168
|
-
### Forgetting to update downstream
|
|
168
|
+
### Forgetting to update downstream modules
|
|
169
169
|
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.
|
|
170
170
|
|
|
171
171
|
### Breaking concept ordering
|
|
@@ -175,7 +175,7 @@ Concepts in the import module must be topologically ordered. If `:Meal:` referen
|
|
|
175
175
|
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.
|
|
176
176
|
|
|
177
177
|
### Removing concepts from exported_concepts prematurely
|
|
178
|
-
Only remove a concept from `exported_concepts` if **every** downstream
|
|
178
|
+
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.
|
|
179
179
|
|
|
180
180
|
## Validation Checklist
|
|
181
181
|
|
|
@@ -186,8 +186,8 @@ Only remove a concept from `exported_concepts` if **every** downstream `requires
|
|
|
186
186
|
- [ ] Every affected module's `import` list includes the target import module
|
|
187
187
|
- [ ] `exported_concepts` updated correctly — no missing exports, no unnecessary exports
|
|
188
188
|
- [ ] All concept references in all affected modules resolve correctly
|
|
189
|
-
- [ ] No functional specs, implementation reqs, test reqs, or
|
|
189
|
+
- [ ] No functional specs, implementation reqs, test reqs, or test plain files were modified
|
|
190
190
|
- [ ] Import module is in `template/` and has no functional specs or requires
|
|
191
191
|
- [ ] No circular imports introduced
|
|
192
|
-
- [ ] Downstream
|
|
192
|
+
- [ ] Downstream modules updated if needed
|
|
193
193
|
- [ ] User approved the final result
|
|
@@ -9,7 +9,7 @@ description: >-
|
|
|
9
9
|
|
|
10
10
|
# Create Import Module
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
**Load the rules first.** Before you read, edit, or write any `.plain` file, invoke the `load-plain-reference` skill and read the rule files it routes you to. Skip this only if `load-plain-reference` already ran in this conversation.
|
|
13
13
|
|
|
14
14
|
## What an Import Module Is
|
|
15
15
|
|
|
@@ -9,7 +9,7 @@ description: >-
|
|
|
9
9
|
|
|
10
10
|
# Create Requires Module
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
**Load the rules first.** Before you read, edit, or write any `.plain` file, invoke the `load-plain-reference` skill and read the rule files it routes you to. Skip this only if `load-plain-reference` already ran in this conversation.
|
|
13
13
|
|
|
14
14
|
## What Requires Does
|
|
15
15
|
|
|
@@ -19,6 +19,7 @@ When this module is rendered:
|
|
|
19
19
|
- The required module's generated code (`plain_modules/<required_module>/code`) is copied as the starting point.
|
|
20
20
|
- The `***functional specs***` of the required module **and all its ancestors** become visible as **previous functional specs**.
|
|
21
21
|
- Of the required module's definitions, only the concepts in its `exported_concepts` are visible, each with its full definition text. Export visibility is **not** transitive — to see an ancestor's exports, list that ancestor in `requires` too.
|
|
22
|
+
- The required module's test plain files stay with the required module. The new module gets its own test plain files, one per functionality it adds (see `test-plain-files.md`).
|
|
22
23
|
|
|
23
24
|
All modules connected by `requires` form a single tree with a common root. **Diamond joins are prohibited**: multiple `requires` entries must lie on one root-to-tip ancestor path. The deepest entry is the attachment point; the other entries exist only to make those ancestors' exports visible.
|
|
24
25
|
|
|
@@ -34,7 +35,7 @@ If you only need shared definitions and reqs (no functional specs, no generated
|
|
|
34
35
|
2. **Create the `.plain` file at the repository root** with YAML frontmatter containing the `requires` field. Modules with functional specs live at the root, not in `template/`.
|
|
35
36
|
3. **Review the functional specs of the whole ancestor chain** — they will be treated as previous requirements. Your new functional specs must not conflict with any of them.
|
|
36
37
|
4. **Review each listed module's `exported_concepts`** — only those concepts are available to reference; an ancestor's exports require listing that ancestor.
|
|
37
|
-
5. **Add module-specific content** — definitions, implementation reqs, test reqs, and functional specs unique to this module.
|
|
38
|
+
5. **Add module-specific content** — definitions, implementation reqs, test reqs, and functional specs unique to this module. Add every functional spec through `add-functional-spec` or `add-functional-specs`, which also create its test plain file.
|
|
38
39
|
6. **Check for conflicts** between your new functional specs and any spec in the ancestor chain.
|
|
39
40
|
|
|
40
41
|
## Format
|
|
@@ -56,7 +57,8 @@ description: Extended module that builds on base_module
|
|
|
56
57
|
|
|
57
58
|
***functional specs***
|
|
58
59
|
|
|
59
|
-
-
|
|
60
|
+
# new-feature
|
|
61
|
+
:NewFeature: is available.
|
|
60
62
|
```
|
|
61
63
|
|
|
62
64
|
A module can use both `requires` and `import` together. `requires` points to other root-level modules; `import` resolves from the default `template/` directory (no prefix needed).
|
|
@@ -106,5 +108,6 @@ The current module may or may not be functionally related to the required module
|
|
|
106
108
|
- [ ] Every listed module's `exported_concepts` provide the concepts you need
|
|
107
109
|
- [ ] New functional specs do not conflict with any spec in the ancestor chain
|
|
108
110
|
- [ ] Module has at least one functional spec and one implementation req
|
|
111
|
+
- [ ] Every functional spec has its test plain file
|
|
109
112
|
- [ ] Both `requires` and `import` are used correctly (not mixed up)
|
|
110
113
|
- [ ] YAML frontmatter is correctly formatted between `---` markers
|
|
@@ -9,7 +9,7 @@ description: >-
|
|
|
9
9
|
|
|
10
10
|
# Debug Specs
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
**Load the rules first.** Before you read, edit, or write any `.plain` file, invoke the `load-plain-reference` skill and read the rule files it routes you to. Skip this only if `load-plain-reference` already ran in this conversation.
|
|
13
13
|
|
|
14
14
|
## When to Use
|
|
15
15
|
|
|
@@ -30,7 +30,7 @@ Generated code in `plain_modules/<module>/code/` and `plain_modules/<module>/tes
|
|
|
30
30
|
|
|
31
31
|
## Phase 1 — Understand the Context
|
|
32
32
|
|
|
33
|
-
1. **Read the `.plain` file(s)** for the module — frontmatter, definitions, implementation reqs, test reqs, and all functional specs. Also read `import` and `requires` chains.
|
|
33
|
+
1. **Read the `.plain` file(s)** for the module — frontmatter, definitions, implementation reqs, test reqs, and all functional specs. Also read `import` and `requires` chains, and the module's test plain files.
|
|
34
34
|
2. **Read the user's observation carefully.** Rephrase it back to confirm understanding. Identify:
|
|
35
35
|
- What is the expected behavior?
|
|
36
36
|
- What is the actual behavior?
|
|
@@ -60,13 +60,13 @@ For each relevant file:
|
|
|
60
60
|
### 2c. Check conformance tests and unit tests (if relevant)
|
|
61
61
|
|
|
62
62
|
If the bug manifests as a test failure:
|
|
63
|
-
1. Read the failing test — conformance tests in `plain_modules/<module_name>/tests/<
|
|
63
|
+
1. Read the failing test — conformance tests in `plain_modules/<module_name>/tests/<func-id>/`, each labelled with the scenario-id it implements, unit tests inside `plain_modules/<module_name>/code/`.
|
|
64
64
|
2. Understand what the test expects vs. what the implementation does.
|
|
65
65
|
3. Determine whether the test expectation is correct (matches the spec) or incorrect (doesn't match the spec).
|
|
66
66
|
|
|
67
67
|
## Phase 3 — Diagnose the Root Cause
|
|
68
68
|
|
|
69
|
-
Trace the issue from the generated code back to the specs. There are
|
|
69
|
+
Trace the issue from the generated code back to the specs. There are six possible root causes — determine which one applies **before** making changes:
|
|
70
70
|
|
|
71
71
|
| Root Cause | Symptom | Fix |
|
|
72
72
|
|------------|---------|-----|
|
|
@@ -74,6 +74,7 @@ Trace the issue from the generated code back to the specs. There are five possib
|
|
|
74
74
|
| **Missing spec** | The desired behavior is not covered by any spec. The renderer had no guidance and either did nothing or made an arbitrary choice. | Add a new functional spec using the `add-functional-spec` skill. |
|
|
75
75
|
| **Conflicting specs** | Two specs contradict each other, causing the renderer to produce inconsistent behavior. | Use the `resolve-spec-conflict` skill. |
|
|
76
76
|
| **Incorrect spec** | The spec explicitly describes the wrong behavior. The renderer implemented it faithfully, but the spec itself is wrong. | Rewrite the spec to describe the correct behavior. |
|
|
77
|
+
| **Incorrect scenario** | The spec is correct and the code matches it, but a scenario in the test plain file expects an outcome the spec does not state, or misses one it states. | Fix the scenario with `add-test-scenarios`. |
|
|
77
78
|
| **Missing implementation req** | The spec is correct, but the implementation req doesn't provide enough guidance for the renderer to produce the right code (e.g., missing library, missing architectural constraint, missing platform detail). | Add or update the implementation req using the `add-implementation-requirement` skill. |
|
|
78
79
|
|
|
79
80
|
### How to diagnose
|
|
@@ -85,7 +86,9 @@ Trace the issue from the generated code back to the specs. There are five possib
|
|
|
85
86
|
2. **Check for conflicts.** Could another spec be overriding or contradicting this behavior?
|
|
86
87
|
- Read all functional specs that touch the same concepts.
|
|
87
88
|
- If two specs are in tension → **conflicting specs**.
|
|
88
|
-
3. **Check
|
|
89
|
+
3. **Check the scenario.** When a conformance or acceptance test fails, find its scenario by the scenario-id in the test name and compare it with the spec.
|
|
90
|
+
- If the scenario contradicts or extends the spec → **incorrect scenario**.
|
|
91
|
+
4. **Check implementation reqs.** Is the renderer missing guidance on how to implement correctly?
|
|
89
92
|
- Does the implementation req specify the right library, pattern, or constraint?
|
|
90
93
|
- If a platform-specific or framework-specific detail is missing → **missing implementation req**.
|
|
91
94
|
|
|
@@ -95,10 +98,11 @@ Apply the fix based on the diagnosed root cause. Use the appropriate skill:
|
|
|
95
98
|
|
|
96
99
|
| Root Cause | Skill to Use |
|
|
97
100
|
|------------|-------------|
|
|
98
|
-
| Ambiguous spec | Edit the spec inline — add
|
|
101
|
+
| Ambiguous spec | Edit the spec inline — add detail under the statement line or reword for clarity |
|
|
99
102
|
| Missing spec | `add-functional-spec` |
|
|
100
103
|
| Conflicting specs | `resolve-spec-conflict` |
|
|
101
104
|
| Incorrect spec | Edit the spec inline — rewrite the incorrect part |
|
|
105
|
+
| Incorrect scenario | `add-test-scenarios` |
|
|
102
106
|
| Missing implementation req | `add-implementation-requirement` |
|
|
103
107
|
|
|
104
108
|
### Fix guidelines
|
|
@@ -107,6 +111,7 @@ Apply the fix based on the diagnosed root cause. Use the appropriate skill:
|
|
|
107
111
|
- **Preserve chronological order.** If adding a new spec, place it correctly relative to existing specs.
|
|
108
112
|
- **Stay language-agnostic.** Functional specs describe behavior, not implementation. Platform-specific guidance belongs in implementation reqs.
|
|
109
113
|
- **Respect the 200 LOC limit.** If a fix makes a spec too complex, use `break-down-func-spec` to split it.
|
|
114
|
+
- **Keep the test plain file in step.** After changing a functional spec, invoke `add-test-scenarios` for it so its scenarios still follow from the spec.
|
|
110
115
|
- **Check for new conflicts.** After editing, verify the fix doesn't conflict with other specs by running `analyze-func-specs` once with the edited spec(s) plus every existing spec that touches the same concepts. The batched analyzer reports all conflicting pairs in a single call; resolve each with `resolve-spec-conflict`.
|
|
111
116
|
|
|
112
117
|
## Phase 5 — Verify and Report
|
|
@@ -148,7 +153,7 @@ A test is failing. Use the test as the entry point.
|
|
|
148
153
|
```
|
|
149
154
|
Read failing test → Understand what it expects → Read the implementation →
|
|
150
155
|
Determine if the test or the implementation is wrong → Trace back to the spec →
|
|
151
|
-
Fix the spec (or test reqs/
|
|
156
|
+
Fix the spec (or the test reqs / the scenario in the test plain file if the test itself is wrong)
|
|
152
157
|
```
|
|
153
158
|
|
|
154
159
|
### Strategy 4: Differential
|
|
@@ -179,11 +184,12 @@ A spec fix may affect other specs that reference the same concepts. Always check
|
|
|
179
184
|
|
|
180
185
|
- [ ] User's observation is clearly understood (expected vs. actual behavior)
|
|
181
186
|
- [ ] Generated code has been read to understand the current implementation
|
|
182
|
-
- [ ] Root cause is diagnosed (ambiguous / missing / conflicting / incorrect / missing impl req)
|
|
187
|
+
- [ ] Root cause is diagnosed (ambiguous / missing / conflicting / incorrect / incorrect scenario / missing impl req)
|
|
183
188
|
- [ ] Fix is applied in the `.plain` file(s) only — no generated code modified
|
|
184
189
|
- [ ] Fix is minimal and targeted to the observed bug
|
|
185
190
|
- [ ] Fix does not introduce new conflicts with existing specs
|
|
186
191
|
- [ ] Modified specs respect the 200 LOC limit
|
|
187
192
|
- [ ] Modified specs remain language-agnostic
|
|
188
193
|
- [ ] Chronological ordering is preserved
|
|
194
|
+
- [ ] Test plain file of every changed functionality brought in step via `add-test-scenarios`
|
|
189
195
|
- [ ] Summary of findings and fix presented to the user
|
|
@@ -12,7 +12,7 @@ description: >-
|
|
|
12
12
|
|
|
13
13
|
# Forge Plain
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
**Load the rules first.** Before you read, edit, or write any `.plain` file, invoke the `load-plain-reference` skill and read the rule files it routes you to. Skip this only if `load-plain-reference` already ran in this conversation.
|
|
16
16
|
|
|
17
17
|
## Role
|
|
18
18
|
|
|
@@ -54,7 +54,7 @@ Use the dedicated edit skills for every write — never hand-author a `***plain`
|
|
|
54
54
|
|
|
55
55
|
## Review loop
|
|
56
56
|
|
|
57
|
-
After each authoring step, review **only what just changed** — never re-review the whole file. Pick the single most relevant snippet (one concept, one functional spec, the module frontmatter, one requirement, one
|
|
57
|
+
After each authoring step, review **only what just changed** — never re-review the whole file. Pick the single most relevant snippet (one concept, one functional spec, the module frontmatter, one requirement, one test plain file, one script change, one `config.yaml` entry) and embed it directly in the `AskUserQuestion` prompt so the user sees exactly what they approve. Frame each question around one of:
|
|
58
58
|
|
|
59
59
|
- **Missing parts** — something that should be in the snippet but isn't (an attribute, a validation rule, an edge case, a missing concept).
|
|
60
60
|
- **Possible extensions** — behavior or detail that could reasonably be expanded.
|
|
@@ -84,7 +84,7 @@ When entering a phase, read its reference file and walk its topics **in order**
|
|
|
84
84
|
| 0 — What is the intent? | `references/phase-0-intent.md` | a concise intent brief covering the problem, primary user and outcome, and initial boundary is explicitly confirmed; nothing is written to disk |
|
|
85
85
|
| 1 — What are we building? | `references/phase-1-product.md` | the new `***definitions***` and `***functional specs***`, plus any technology-free `***implementation reqs***`, are on disk and approved |
|
|
86
86
|
| 2 — What tech should it use? | `references/phase-2-tech.md` | the new `***implementation reqs***` are on disk and approved |
|
|
87
|
-
| 3 — How is testing done? | `references/phase-3-testing.md` | the `***test reqs***` (and
|
|
87
|
+
| 3 — How is testing done? | `references/phase-3-testing.md` | the `***test reqs***` (and the test plain files if conformance is on) are on disk, the `test_scripts/` and `config.yaml`(s) exist, and `check-plain-env` passed or each gap was acknowledged |
|
|
88
88
|
| 4 — Validate and hand off | `references/phase-4-validate-handoff.md` | `plain-healthcheck` returned `PASS`, and the user has the render target plus every side-channel command |
|
|
89
89
|
|
|
90
90
|
Between phases, summarize and get explicit overall confirmation before continuing — the intent brief
|