@khanhspring/forge-spec 1.1.0 → 1.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/package.json
CHANGED
|
@@ -61,14 +61,15 @@ Before asking the user anything, research the existing codebase silently:
|
|
|
61
61
|
Note any patterns, naming conventions, or prior decisions relevant to this idea.
|
|
62
62
|
3. Scan `contracts/*/` — are there existing API contracts this feature will touch or extend?
|
|
63
63
|
Note existing endpoint shapes, error formats, auth patterns.
|
|
64
|
-
4. Read `
|
|
65
|
-
that will constrain design choices.
|
|
64
|
+
4. Read `CONTEXT.md` — note the actors, domain glossary, principles, conventions, and
|
|
65
|
+
forbidden patterns that will constrain design choices. Use glossary terms verbatim
|
|
66
|
+
in your questions and in the summary — never invent synonyms for existing domain terms.
|
|
66
67
|
|
|
67
68
|
Report your findings before starting questions:
|
|
68
69
|
|
|
69
70
|
> "Before we dive in, here's what I found in the codebase:
|
|
70
71
|
> - [relevant existing feature or contract, or "No related features found"]
|
|
71
|
-
> - [relevant principle from
|
|
72
|
+
> - [relevant principle or constraint from CONTEXT.md, or "No constraints found"]
|
|
72
73
|
>
|
|
73
74
|
> I'll use this as context. Here's my understanding of the feature: {1–2 sentence restatement}
|
|
74
75
|
> Is that right?"
|
|
@@ -210,7 +211,7 @@ apply the Research Handling pattern.
|
|
|
210
211
|
## Step 5 — Propose approaches
|
|
211
212
|
|
|
212
213
|
Propose **2–3 design approaches** with trade-offs. Base them on the researched context
|
|
213
|
-
from Step 1 — flag if an approach conflicts with existing patterns or
|
|
214
|
+
from Step 1 — flag if an approach conflicts with existing patterns or CONTEXT.md principles.
|
|
214
215
|
|
|
215
216
|
```
|
|
216
217
|
I see 2–3 ways to approach this:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: "forge-config"
|
|
3
|
-
description: "View and interactively update .forge/project.json
|
|
4
|
-
argument-hint: "Optional hint: 'add module', 'update user-service port', '
|
|
3
|
+
description: "View and interactively update .forge/project.json (add/remove modules and submodules, ports, stack, spec repo URL) and CONTEXT.md (actors, glossary, principles, conventions). Asks one question at a time and previews changes before writing."
|
|
4
|
+
argument-hint: "Optional hint: 'add module', 'add submodule to webapps', 'update user-service port', 'edit principles'"
|
|
5
5
|
compatibility: "Requires spec repo with .forge/project.json"
|
|
6
6
|
metadata:
|
|
7
7
|
author: "forge-workflow"
|
|
@@ -12,14 +12,16 @@ disable-model-invocation: true
|
|
|
12
12
|
|
|
13
13
|
# Forge Config
|
|
14
14
|
|
|
15
|
-
View and update the project configuration at `.forge/project.json
|
|
15
|
+
View and update the project configuration at `.forge/project.json`, and the
|
|
16
|
+
project-wide domain context at `CONTEXT.md`.
|
|
16
17
|
|
|
17
18
|
## Step 1 — Load & display
|
|
18
19
|
|
|
19
20
|
Read `.forge/project.json`.
|
|
20
21
|
If missing: "No project config found. Run `/forge-init` to set up this repo first."
|
|
21
22
|
|
|
22
|
-
Display the current config
|
|
23
|
+
Display the current config. Modules with submodules show one indented `↳` row per
|
|
24
|
+
submodule — the parent row has no port/stack (those belong to each submodule):
|
|
23
25
|
|
|
24
26
|
```
|
|
25
27
|
Project: {project-name}
|
|
@@ -28,13 +30,19 @@ Contract tool: {contract_tool}
|
|
|
28
30
|
|
|
29
31
|
Modules ({n}):
|
|
30
32
|
· user-service backend Spring Boot 3, Java 21 :8081
|
|
31
|
-
·
|
|
33
|
+
· webapps (3 submodules)
|
|
34
|
+
↳ admin frontend React :3001 apps/admin
|
|
35
|
+
↳ landing frontend Next.js :3000 apps/landing
|
|
36
|
+
↳ portal frontend React :3002 apps/portal
|
|
32
37
|
```
|
|
33
38
|
|
|
34
39
|
## Step 2 — Determine the change
|
|
35
40
|
|
|
36
|
-
From $ARGUMENTS, infer the intent if given (e.g. "add module", "
|
|
37
|
-
|
|
41
|
+
From $ARGUMENTS, infer the intent if given (e.g. "add module", "add submodule to webapps",
|
|
42
|
+
"update user-service port", "edit principles").
|
|
43
|
+
If empty, ask: "What do you want to change? (add a module / add a submodule to an existing
|
|
44
|
+
module / remove a module or submodule / update a field / change spec repo URL / edit project
|
|
45
|
+
context — actors, glossary, principles, conventions)"
|
|
38
46
|
|
|
39
47
|
## Step 3 — Collect details (one question at a time)
|
|
40
48
|
|
|
@@ -44,22 +52,68 @@ Ask one question per message — never batch.
|
|
|
44
52
|
1. "Module name? (kebab-case, must be unique)"
|
|
45
53
|
2. "Type? (backend / frontend / worker / gateway)"
|
|
46
54
|
3. "Tech stack? (e.g. 'Spring Boot 3, Java 21')"
|
|
47
|
-
4. "
|
|
48
|
-
5. "
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
+
4. "Git repo URL? (or 'none')"
|
|
56
|
+
5. "Does `{name}` contain multiple submodules — e.g. a monorepo with several apps,
|
|
57
|
+
or a Gradle multi-module build? (yes / no)"
|
|
58
|
+
- **If yes** → collect submodules one at a time (see below). Skip step 6 —
|
|
59
|
+
port and stack belong to each submodule, not the parent; drop the stack from step 3
|
|
60
|
+
if it was given for the parent.
|
|
61
|
+
- **If no** → continue.
|
|
62
|
+
6. "Local dev port?" _(skip when the module has submodules)_
|
|
63
|
+
7. "One-sentence description? (or 'none')"
|
|
64
|
+
|
|
65
|
+
**Adding a submodule** (to an existing module) — ask which module first if not given.
|
|
66
|
+
|
|
67
|
+
- If the parent is currently a **simple module** (no `submodules[]`), warn before converting:
|
|
68
|
+
> "`{module}` is currently a standalone module. Adding a submodule converts it:
|
|
69
|
+
> its `port` and `stack` move to the submodules — the parent keeps only `name`,
|
|
70
|
+
> `repo`, and `description`. If `{module}` already has tasks or contracts under its
|
|
71
|
+
> own name, those stay as-is and won't match a submodule name. Convert? (yes/no)"
|
|
72
|
+
If yes, ask whether the existing port/stack should become the first submodule
|
|
73
|
+
(asking for its `name` and `path`) or be discarded.
|
|
74
|
+
- Then collect each new submodule, one field at a time (same as `/forge-init`):
|
|
75
|
+
1. "Submodule name? (kebab-case, unique across the whole project — not just within `{module}`)"
|
|
76
|
+
2. "Type? (backend / frontend / worker)"
|
|
77
|
+
3. "Stack?"
|
|
78
|
+
4. "Port?"
|
|
79
|
+
5. "Path within the `{module}` repo? (e.g. `apps/admin` or `auth-ui`)"
|
|
80
|
+
6. "One sentence: what does it do? _(Skip with 'none')_"
|
|
81
|
+
- Confirm each: "`{sub}` — {type} — {stack} — :{port} — path: {path}. Another submodule? (yes / no)"
|
|
82
|
+
|
|
83
|
+
> **Submodule rules (same as `/forge-init`):**
|
|
84
|
+
> - No `repo` field on a submodule — it shares the parent module's repo
|
|
85
|
+
> - No `port` or `stack` on a parent that has submodules
|
|
86
|
+
> - Submodule names must be unique across the whole project — contracts live at
|
|
87
|
+
> `contracts/{submodule}/` and tasks.md uses `### {submodule}` headings directly
|
|
88
|
+
|
|
89
|
+
**Removing a module or submodule:**
|
|
90
|
+
- Check whether any `features/*/tasks.md` has a `### {name}` section (module name for
|
|
91
|
+
simple modules, submodule name for submodules).
|
|
92
|
+
If so, warn: "`{name}` has tasks in {feature(s)}. Removing it from config won't delete those tasks. Remove anyway? (yes/no)"
|
|
93
|
+
- Otherwise confirm: "Remove `{name}` from the project? (yes/no)"
|
|
94
|
+
- If removing the **last submodule** of a module, ask: "That's the last submodule of
|
|
95
|
+
`{module}`. Convert it back to a standalone module (needs a port and stack), or remove
|
|
96
|
+
the whole module?"
|
|
55
97
|
|
|
56
98
|
**Updating a field:**
|
|
57
99
|
- Show the current value, then ask for the new one:
|
|
58
100
|
"`{module}.{field}` is currently `{old}`. What should it be?"
|
|
101
|
+
- Submodule fields use the path `{module}.submodules[{sub}].{field}` — e.g.
|
|
102
|
+
"`webapps.submodules[admin].port` is currently `3001`. What should it be?"
|
|
103
|
+
- Refuse to set `port` or `stack` on a parent with submodules, or `repo` on a
|
|
104
|
+
submodule — explain the rule instead.
|
|
59
105
|
|
|
60
106
|
**Changing spec repo URL:**
|
|
61
107
|
- "Current spec_repo is `{old}`. New URL?"
|
|
62
108
|
|
|
109
|
+
**Editing project context (`CONTEXT.md`):**
|
|
110
|
+
- Read `CONTEXT.md`. If missing, offer to create it with the template from `/forge-init`
|
|
111
|
+
Phase 6, asking the Phase 2 and Phase 4 questions to fill it.
|
|
112
|
+
- Ask which section: "Which section? (What This Project Is / Business Goal / Actors /
|
|
113
|
+
Domain Glossary / Current State / Principles / Conventions / Out of Scope)"
|
|
114
|
+
- Show the section's current content, then ask what to add, change, or remove.
|
|
115
|
+
- Context edits go to `CONTEXT.md` only — never to CLAUDE.md or project.json.
|
|
116
|
+
|
|
63
117
|
## Step 4 — Preview & gate
|
|
64
118
|
|
|
65
119
|
Show the before/after of exactly what will change:
|
|
@@ -69,19 +123,36 @@ Change preview:
|
|
|
69
123
|
modules[user-service].port: 8081 → 8090
|
|
70
124
|
```
|
|
71
125
|
|
|
72
|
-
|
|
126
|
+
Adding a submodule:
|
|
127
|
+
```
|
|
128
|
+
Change preview:
|
|
129
|
+
modules[webapps].submodules + { name: reports, type: frontend,
|
|
130
|
+
stack: [React], port: 3003, path: apps/reports }
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Converting a simple module to one with submodules, show the moved fields too:
|
|
134
|
+
```
|
|
135
|
+
Change preview:
|
|
136
|
+
modules[webapps].port 3000 → (removed — moves to submodules)
|
|
137
|
+
modules[webapps].stack [React] → (removed — moves to submodules)
|
|
138
|
+
modules[webapps].submodules + { name: admin, ... }
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
For CONTEXT.md edits, show the section before/after instead.
|
|
142
|
+
|
|
143
|
+
> "Apply this change to `{file}`? Say **yes** to write, or tell me what to adjust."
|
|
73
144
|
|
|
74
145
|
Wait for confirmation. Do not write before the user says yes.
|
|
75
146
|
|
|
76
147
|
## Step 5 — Write & confirm
|
|
77
148
|
|
|
78
|
-
Apply the change, preserving all other fields and formatting.
|
|
79
|
-
Confirm: "Updated
|
|
149
|
+
Apply the change, preserving all other fields, sections, and formatting.
|
|
150
|
+
Confirm: "Updated `{file}` — {summary of what changed}."
|
|
80
151
|
|
|
81
|
-
If a module name changed, warn:
|
|
82
|
-
> "Heads up: `{
|
|
83
|
-
> `### {
|
|
84
|
-
> `/forge-close` will break."
|
|
152
|
+
If a module or submodule name changed, warn:
|
|
153
|
+
> "Heads up: `{name}` is referenced by the module repo's `.forge/module.json`, by
|
|
154
|
+
> `### {name}` headings in tasks.md, and by the `contracts/{name}/` folder. Update
|
|
155
|
+
> those to match, or `/forge-implement` and `/forge-close` will break."
|
|
85
156
|
|
|
86
157
|
## Schema Reference
|
|
87
158
|
|
|
@@ -90,6 +161,7 @@ If a module name changed, warn:
|
|
|
90
161
|
"project": "my-project", // short slug, no spaces
|
|
91
162
|
"version": "1.0",
|
|
92
163
|
"modules": [
|
|
164
|
+
// Module WITHOUT submodules — port and stack on the module itself:
|
|
93
165
|
{
|
|
94
166
|
"name": "user-service", // kebab-case, matches module.json in module repos
|
|
95
167
|
"repo": "git@github.com:org/user-service.git",
|
|
@@ -97,6 +169,23 @@ If a module name changed, warn:
|
|
|
97
169
|
"stack": ["Spring Boot 3", "Java 21"],
|
|
98
170
|
"port": 8081,
|
|
99
171
|
"description": "" // optional, one sentence
|
|
172
|
+
},
|
|
173
|
+
// Module WITH submodules — NO port/stack/type on the parent;
|
|
174
|
+
// each submodule owns type, stack, port, path; NO repo on submodules:
|
|
175
|
+
{
|
|
176
|
+
"name": "webapps",
|
|
177
|
+
"repo": "git@github.com:org/webapps.git",
|
|
178
|
+
"description": "Web app mono-repo",
|
|
179
|
+
"submodules": [
|
|
180
|
+
{
|
|
181
|
+
"name": "admin", // kebab-case, unique across the WHOLE project
|
|
182
|
+
"type": "frontend", // backend | frontend | worker
|
|
183
|
+
"stack": ["React"],
|
|
184
|
+
"port": 3001,
|
|
185
|
+
"path": "apps/admin", // relative path inside the parent repo
|
|
186
|
+
"description": "" // optional, one sentence
|
|
187
|
+
}
|
|
188
|
+
]
|
|
100
189
|
}
|
|
101
190
|
],
|
|
102
191
|
"spec_repo": "git@github.com:org/specs.git",
|
|
@@ -108,6 +197,10 @@ If a module name changed, warn:
|
|
|
108
197
|
## Rules
|
|
109
198
|
- One question per message — never batch
|
|
110
199
|
- Never write before the user confirms the preview in Step 4
|
|
111
|
-
- `module.name` must be kebab-case and unique
|
|
112
|
-
|
|
113
|
-
-
|
|
200
|
+
- `module.name` must be kebab-case and unique; submodule names must be unique across
|
|
201
|
+
the whole project (contracts and task headings use the submodule name directly)
|
|
202
|
+
- `module.name` must match the `module` field in the module repo's `.forge/module.json`;
|
|
203
|
+
submodule names must match the `submodules[].name` entries there
|
|
204
|
+
- A module has EITHER `port`+`stack` OR `submodules[]` — never both; submodules never
|
|
205
|
+
have a `repo` field
|
|
206
|
+
- Never silently remove a module or submodule that has tasks referencing it — warn first
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: "forge-init"
|
|
3
|
-
description: "One-time initialization for a Forge spec repo. Walks through setup conversationally one question at a time, then writes .forge/project.json, CLAUDE.md, and directory scaffolding on confirmation."
|
|
3
|
+
description: "One-time initialization for a Forge spec repo. Walks through setup conversationally one question at a time — project identity, project details, modules, principles — then writes .forge/project.json, CONTEXT.md, CLAUDE.md, and directory scaffolding on confirmation."
|
|
4
4
|
argument-hint: "Optional: project name to skip the first prompt"
|
|
5
5
|
compatibility: "Run once in a spec repo before any other forge skills. Safe to re-run — never overwrites existing files."
|
|
6
6
|
when_to_use: >
|
|
@@ -40,7 +40,40 @@ _(Skip with 'none' if it's not set up yet — you can add it later with `/forge-
|
|
|
40
40
|
|
|
41
41
|
---
|
|
42
42
|
|
|
43
|
-
## Phase 2 —
|
|
43
|
+
## Phase 2 — Project details
|
|
44
|
+
|
|
45
|
+
These answers become `CONTEXT.md` — the project-wide domain context that
|
|
46
|
+
`/forge-brainstorm` and `/forge-spec` read before planning, and that module repos
|
|
47
|
+
see at `specs/CONTEXT.md` during implementation. Getting this right once saves
|
|
48
|
+
re-explaining the project in every feature conversation.
|
|
49
|
+
|
|
50
|
+
Start by offering the shortcut:
|
|
51
|
+
> "If you have a project overview doc (README, pitch doc, Confluence page), paste it
|
|
52
|
+
> and I'll extract these answers — otherwise I'll ask a few short questions."
|
|
53
|
+
|
|
54
|
+
If a doc is pasted, extract what's covered and ask only about genuine gaps.
|
|
55
|
+
Otherwise ask one question at a time:
|
|
56
|
+
|
|
57
|
+
**Q1.** "Who uses this system? List the actors/roles and what each one does.
|
|
58
|
+
_(e.g. 'customer — places orders; admin — manages the catalog; billing-worker — system actor')_"
|
|
59
|
+
|
|
60
|
+
**Q2.** "What are the core domain concepts, in your team's own words?
|
|
61
|
+
_(e.g. 'Order, Quote, Fulfillment — a Quote becomes an Order when accepted')_
|
|
62
|
+
These become the domain glossary — the exact terms specs and contracts will use."
|
|
63
|
+
|
|
64
|
+
**Q3.** "What's the business goal — what does success look like for this project?
|
|
65
|
+
_(1–2 sentences, or 'skip')_"
|
|
66
|
+
|
|
67
|
+
**Q4.** "What's the current state? Greenfield, or are there existing systems this
|
|
68
|
+
replaces or integrates with?
|
|
69
|
+
_(e.g. 'replacing a legacy PHP monolith; auth stays in Keycloak')_"
|
|
70
|
+
|
|
71
|
+
Keep this phase capped at these four areas — deep per-feature questioning is
|
|
72
|
+
`/forge-brainstorm`'s job, not init's.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Phase 3 — Modules
|
|
44
77
|
|
|
45
78
|
Collect modules one at a time. Each module is gathered field by field.
|
|
46
79
|
|
|
@@ -93,11 +126,11 @@ Then ask:
|
|
|
93
126
|
> "Any more modules to add? (yes / no)"
|
|
94
127
|
|
|
95
128
|
If yes, repeat from step 1 of this phase for the next module.
|
|
96
|
-
If no, move to Phase
|
|
129
|
+
If no, move to Phase 4.
|
|
97
130
|
|
|
98
131
|
---
|
|
99
132
|
|
|
100
|
-
## Phase
|
|
133
|
+
## Phase 4 — Principles & conventions
|
|
101
134
|
|
|
102
135
|
Ask one at a time. "None" or "not yet" are valid answers — these sections can be filled
|
|
103
136
|
in later with `/forge-config`.
|
|
@@ -116,7 +149,7 @@ Say 'none yet' to skip._"
|
|
|
116
149
|
|
|
117
150
|
---
|
|
118
151
|
|
|
119
|
-
## Phase
|
|
152
|
+
## Phase 5 — Preview & gate
|
|
120
153
|
|
|
121
154
|
Show a full preview of what will be written:
|
|
122
155
|
|
|
@@ -128,13 +161,20 @@ Ready to initialize. Here's what I'll create:
|
|
|
128
161
|
modules: {n} module(s): {comma-separated names}
|
|
129
162
|
spec_repo: {url or "not set"}
|
|
130
163
|
|
|
131
|
-
|
|
164
|
+
CONTEXT.md
|
|
132
165
|
Description: {description}
|
|
133
|
-
|
|
166
|
+
Actors: {n} listed
|
|
167
|
+
Domain glossary: {n} terms
|
|
168
|
+
Business goal: {one line or "skipped"}
|
|
169
|
+
Current state: {one line}
|
|
134
170
|
Principles: {list or "none yet"}
|
|
135
171
|
Conventions: {list or "none yet"}
|
|
136
172
|
Out of scope: {list or "none yet"}
|
|
137
173
|
|
|
174
|
+
CLAUDE.md
|
|
175
|
+
Modules: {n} listed
|
|
176
|
+
Forge workflow + structure + pointer to CONTEXT.md
|
|
177
|
+
|
|
138
178
|
features/CHANGELOG.md
|
|
139
179
|
contracts/.gitkeep
|
|
140
180
|
.gitignore ← append Forge entries
|
|
@@ -146,7 +186,7 @@ Wait for confirmation. Do not write anything before the user says yes.
|
|
|
146
186
|
|
|
147
187
|
---
|
|
148
188
|
|
|
149
|
-
## Phase
|
|
189
|
+
## Phase 6 — Write files
|
|
150
190
|
|
|
151
191
|
Write `.forge/project.json`:
|
|
152
192
|
|
|
@@ -200,11 +240,55 @@ Module **with** submodules — no `port` on the module; each submodule owns its
|
|
|
200
240
|
}
|
|
201
241
|
```
|
|
202
242
|
|
|
203
|
-
Write `
|
|
243
|
+
Write `CONTEXT.md` — the single source of truth for project-wide domain context.
|
|
244
|
+
Fill every section from the Phase 1, 2, and 4 answers; write "None defined yet." only
|
|
245
|
+
where the user explicitly skipped:
|
|
246
|
+
```markdown
|
|
247
|
+
# {project-name} — Project Context
|
|
248
|
+
|
|
249
|
+
> Domain context for all planning and implementation. `/forge-brainstorm` and
|
|
250
|
+
> `/forge-spec` read this before any feature work; module repos see it at
|
|
251
|
+
> `specs/CONTEXT.md`. Keep it current via `/forge-config`.
|
|
252
|
+
|
|
253
|
+
## What This Project Is
|
|
254
|
+
{description — 2–4 sentences built from the user's answers, not just the one-liner}
|
|
255
|
+
|
|
256
|
+
## Business Goal
|
|
257
|
+
{goal — or "Not defined yet."}
|
|
258
|
+
|
|
259
|
+
## Actors
|
|
260
|
+
| Actor | Who they are | What they do in the system |
|
|
261
|
+
|-------|--------------|----------------------------|
|
|
262
|
+
| {role} | {description} | {responsibilities} |
|
|
263
|
+
|
|
264
|
+
## Domain Glossary
|
|
265
|
+
| Term | Meaning |
|
|
266
|
+
|------|---------|
|
|
267
|
+
| {term} | {definition in the team's own words} |
|
|
268
|
+
|
|
269
|
+
## Current State
|
|
270
|
+
{greenfield / existing systems, integrations, migration notes}
|
|
271
|
+
|
|
272
|
+
## Principles
|
|
273
|
+
{list each as a bullet — or "None defined yet."}
|
|
274
|
+
|
|
275
|
+
## Conventions
|
|
276
|
+
{list each as a bullet — or "None defined yet."}
|
|
277
|
+
|
|
278
|
+
## Out of Scope / Forbidden
|
|
279
|
+
{list each as a bullet — or "None defined yet."}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
Write `CLAUDE.md` — operational only; domain context lives in `CONTEXT.md`, never
|
|
283
|
+
duplicate it here:
|
|
204
284
|
```markdown
|
|
205
285
|
# {project-name}
|
|
206
286
|
|
|
207
|
-
{description}
|
|
287
|
+
{description — the 1–2 sentence version}
|
|
288
|
+
|
|
289
|
+
## Project Context
|
|
290
|
+
Actors, domain glossary, principles, and conventions live in `CONTEXT.md`.
|
|
291
|
+
Read it before any brainstorm, spec, or planning work.
|
|
208
292
|
|
|
209
293
|
## Modules
|
|
210
294
|
| Name | Type | Stack | Port |
|
|
@@ -226,18 +310,10 @@ Indent the submodule name with `↳` and omit port/stack from the parent row.)_
|
|
|
226
310
|
4. `/forge-contract` — generate Specmatic OpenAPI contracts
|
|
227
311
|
5. `/forge-close {slug} {module}` — mark a module's tasks done (after module repo ships)
|
|
228
312
|
|
|
229
|
-
Utilities: `/forge-status` (feature dashboard) · `/forge-config` (edit modules/ports)
|
|
230
|
-
|
|
231
|
-
## Principles
|
|
232
|
-
{list each as a bullet — or "None defined yet."}
|
|
233
|
-
|
|
234
|
-
## Conventions
|
|
235
|
-
{list each as a bullet — or "None defined yet."}
|
|
236
|
-
|
|
237
|
-
## Out of Scope / Forbidden
|
|
238
|
-
{list each as a bullet — or "None defined yet."}
|
|
313
|
+
Utilities: `/forge-status` (feature dashboard) · `/forge-config` (edit modules/ports/context)
|
|
239
314
|
|
|
240
315
|
## Structure
|
|
316
|
+
- `CONTEXT.md` — project-wide domain context (actors, glossary, principles)
|
|
241
317
|
- `features/{slug}/brainstorm.md` — approved brainstorm summary
|
|
242
318
|
- `features/{slug}/spec.md` — requirements, flows, API list
|
|
243
319
|
- `features/{slug}/tasks.md` — per-module task breakdown with checkboxes
|
|
@@ -271,7 +347,10 @@ Run `git status` and confirm:
|
|
|
271
347
|
|
|
272
348
|
## Rules
|
|
273
349
|
- One question per message — never ask multiple questions at once
|
|
274
|
-
- Never write files before the user says yes in Phase
|
|
350
|
+
- Never write files before the user says yes in Phase 5
|
|
351
|
+
- Each fact lives in exactly one file: domain context in `CONTEXT.md`, machine config
|
|
352
|
+
in `.forge/project.json`, workflow instructions in `CLAUDE.md` — never duplicate
|
|
353
|
+
content across them
|
|
275
354
|
- Never overwrite existing files
|
|
276
355
|
- All written files must be complete — no unfilled placeholders
|
|
277
356
|
- **Extract, don't re-ask**: if the user's answer contains information for upcoming fields
|
|
@@ -44,9 +44,10 @@ Before asking anything, research silently:
|
|
|
44
44
|
- How Non-Functional requirements are typically written
|
|
45
45
|
- Any related feature whose requirements this feature extends or depends on
|
|
46
46
|
|
|
47
|
-
2. **
|
|
47
|
+
2. **CONTEXT.md** — note the actors, domain glossary, principles, and conventions.
|
|
48
48
|
Any principle that implies a requirement for this feature?
|
|
49
49
|
(e.g. "API contract before implementation" → this feature needs a contract requirement)
|
|
50
|
+
Use glossary terms verbatim in requirements — never invent synonyms for existing domain terms.
|
|
50
51
|
|
|
51
52
|
3. **Brainstorm open items** — extract from the brainstorm summary:
|
|
52
53
|
- Any item listed under **Open Questions** that wasn't resolved
|
|
@@ -58,7 +59,7 @@ Report findings:
|
|
|
58
59
|
> "Before drafting, here's what I found:
|
|
59
60
|
> - Related features: {list or 'none'}
|
|
60
61
|
> - Unresolved from brainstorm: {open questions / assumptions — or 'none, all clear'}
|
|
61
|
-
> -
|
|
62
|
+
> - CONTEXT.md principles that apply: {list or 'none'}
|
|
62
63
|
> - Naming convention: {e.g. 'REQ-N restarts per feature'}"
|
|
63
64
|
|
|
64
65
|
---
|