forge-orkes 0.3.4 → 0.3.6
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/bin/create-forge.js
CHANGED
|
@@ -8,6 +8,11 @@ const templateDir = path.join(__dirname, '..', 'template');
|
|
|
8
8
|
const targetDir = process.cwd();
|
|
9
9
|
const pkgVersion = require('../package.json').version;
|
|
10
10
|
|
|
11
|
+
// --- Section markers for CLAUDE.md ---
|
|
12
|
+
|
|
13
|
+
const FORGE_START = '<!-- forge:start -->';
|
|
14
|
+
const FORGE_END = '<!-- forge:end -->';
|
|
15
|
+
|
|
11
16
|
// --- File classification for upgrades ---
|
|
12
17
|
|
|
13
18
|
// Framework-owned: Forge controls these entirely
|
|
@@ -16,9 +21,6 @@ const FRAMEWORK_OWNED_DIRS = ['.claude/agents', '.claude/skills'];
|
|
|
16
21
|
// Template-only: reference templates Forge controls
|
|
17
22
|
const TEMPLATE_ONLY_DIRS = ['.forge/templates'];
|
|
18
23
|
|
|
19
|
-
// Merge-owned: never auto-overwrite, stage for review
|
|
20
|
-
const MERGE_OWNED_FILES = ['CLAUDE.md'];
|
|
21
|
-
|
|
22
24
|
// Settings file gets smart-merge (overwrite forge.* keys, preserve user hooks)
|
|
23
25
|
const SETTINGS_FILE = '.claude/settings.json';
|
|
24
26
|
|
|
@@ -128,27 +130,62 @@ function upgradeDir(relDir) {
|
|
|
128
130
|
}
|
|
129
131
|
|
|
130
132
|
/**
|
|
131
|
-
*
|
|
133
|
+
* Smart-merge CLAUDE.md using section markers.
|
|
134
|
+
* - If markers exist: replace the forge section, preserve everything else
|
|
135
|
+
* - If no markers but forge content exists: replace it and add markers
|
|
136
|
+
* - If no forge content: append with markers
|
|
137
|
+
* Returns 'replaced' | 'appended' | 'unchanged' | 'created'
|
|
132
138
|
*/
|
|
133
|
-
function
|
|
134
|
-
const srcPath = path.join(templateDir,
|
|
135
|
-
const destPath = path.join(targetDir,
|
|
139
|
+
function mergeClaudeMd() {
|
|
140
|
+
const srcPath = path.join(templateDir, 'CLAUDE.md');
|
|
141
|
+
const destPath = path.join(targetDir, 'CLAUDE.md');
|
|
136
142
|
|
|
137
143
|
if (!fs.existsSync(srcPath)) return null;
|
|
138
|
-
if (!fs.existsSync(destPath)) return null;
|
|
139
144
|
|
|
140
|
-
const
|
|
141
|
-
|
|
145
|
+
const forgeContent = fs.readFileSync(srcPath, 'utf-8');
|
|
146
|
+
|
|
147
|
+
// No existing CLAUDE.md — just copy
|
|
148
|
+
if (!fs.existsSync(destPath)) {
|
|
149
|
+
fs.writeFileSync(destPath, forgeContent);
|
|
150
|
+
return 'created';
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const existing = fs.readFileSync(destPath, 'utf-8');
|
|
142
154
|
|
|
143
|
-
if
|
|
155
|
+
// Check if content is already identical
|
|
156
|
+
if (existing === forgeContent) return 'unchanged';
|
|
144
157
|
|
|
145
|
-
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
158
|
+
const startIdx = existing.indexOf(FORGE_START);
|
|
159
|
+
const endIdx = existing.indexOf(FORGE_END);
|
|
160
|
+
|
|
161
|
+
if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {
|
|
162
|
+
// Markers found — replace the section between them (inclusive)
|
|
163
|
+
const before = existing.substring(0, startIdx);
|
|
164
|
+
const after = existing.substring(endIdx + FORGE_END.length);
|
|
165
|
+
const merged = before + forgeContent + after;
|
|
166
|
+
|
|
167
|
+
// Clean up any double newlines at the seams
|
|
168
|
+
const cleaned = merged.replace(/\n{3,}/g, '\n\n');
|
|
169
|
+
fs.writeFileSync(destPath, cleaned);
|
|
170
|
+
return 'replaced';
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// No markers — check if there's an old forge section (starts with "# Forge")
|
|
174
|
+
const forgeHeaderIdx = existing.indexOf('# Forge\n');
|
|
175
|
+
if (forgeHeaderIdx !== -1) {
|
|
176
|
+
// Old install without markers — replace from "# Forge" to end of file
|
|
177
|
+
// (Forge content is always appended at the end in old installs)
|
|
178
|
+
const before = existing.substring(0, forgeHeaderIdx);
|
|
179
|
+
const merged = before + forgeContent;
|
|
180
|
+
const cleaned = merged.replace(/\n{3,}/g, '\n\n');
|
|
181
|
+
fs.writeFileSync(destPath, cleaned);
|
|
182
|
+
return 'replaced';
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// No forge content at all — append with markers
|
|
186
|
+
const merged = existing.trimEnd() + '\n\n' + forgeContent + '\n';
|
|
187
|
+
fs.writeFileSync(destPath, merged);
|
|
188
|
+
return 'appended';
|
|
152
189
|
}
|
|
153
190
|
|
|
154
191
|
/**
|
|
@@ -178,49 +215,40 @@ function upgradeSettings() {
|
|
|
178
215
|
return 'updated';
|
|
179
216
|
}
|
|
180
217
|
|
|
218
|
+
/**
|
|
219
|
+
* Detect if Forge is already installed in this project.
|
|
220
|
+
*/
|
|
221
|
+
function isForgeInstalled() {
|
|
222
|
+
const settingsPath = path.join(targetDir, SETTINGS_FILE);
|
|
223
|
+
if (!fs.existsSync(settingsPath)) return false;
|
|
224
|
+
|
|
225
|
+
try {
|
|
226
|
+
const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
|
|
227
|
+
return !!settings.forge;
|
|
228
|
+
} catch {
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
181
233
|
// --- Commands ---
|
|
182
234
|
|
|
183
235
|
async function install() {
|
|
184
236
|
console.log('\n Forge - Meta-prompting framework for Claude Code\n');
|
|
185
237
|
|
|
186
|
-
// Handle CLAUDE.md
|
|
187
|
-
const
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
' What would you like to do? (a)ppend / (r)eplace / (s)kip: '
|
|
195
|
-
);
|
|
196
|
-
|
|
197
|
-
if (answer === 'a' || answer === 'append') {
|
|
198
|
-
claudeMdAction = 'append';
|
|
199
|
-
} else if (answer === 'r' || answer === 'replace') {
|
|
200
|
-
claudeMdAction = 'replace';
|
|
201
|
-
} else {
|
|
202
|
-
claudeMdAction = 'skip';
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
const srcContent = fs.readFileSync(srcClaudeMd, 'utf-8');
|
|
207
|
-
|
|
208
|
-
switch (claudeMdAction) {
|
|
209
|
-
case 'copy':
|
|
210
|
-
case 'replace':
|
|
211
|
-
fs.writeFileSync(destClaudeMd, srcContent);
|
|
212
|
-
console.log(
|
|
213
|
-
` ${claudeMdAction === 'replace' ? 'Replaced' : 'Created'} CLAUDE.md`
|
|
214
|
-
);
|
|
238
|
+
// Handle CLAUDE.md — use smart merge
|
|
239
|
+
const claudeStatus = mergeClaudeMd();
|
|
240
|
+
switch (claudeStatus) {
|
|
241
|
+
case 'created':
|
|
242
|
+
console.log(' Created CLAUDE.md');
|
|
243
|
+
break;
|
|
244
|
+
case 'replaced':
|
|
245
|
+
console.log(' Updated Forge section in CLAUDE.md (user content preserved)');
|
|
215
246
|
break;
|
|
216
|
-
case '
|
|
217
|
-
const existing = fs.readFileSync(destClaudeMd, 'utf-8');
|
|
218
|
-
fs.writeFileSync(destClaudeMd, existing + '\n\n' + srcContent);
|
|
247
|
+
case 'appended':
|
|
219
248
|
console.log(' Appended Forge config to existing CLAUDE.md');
|
|
220
249
|
break;
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
console.log(' Skipped CLAUDE.md');
|
|
250
|
+
case 'unchanged':
|
|
251
|
+
console.log(' CLAUDE.md already up to date');
|
|
224
252
|
break;
|
|
225
253
|
}
|
|
226
254
|
|
|
@@ -274,7 +302,6 @@ async function upgrade() {
|
|
|
274
302
|
added: [],
|
|
275
303
|
unchanged: [],
|
|
276
304
|
removed: [],
|
|
277
|
-
needsReview: [],
|
|
278
305
|
};
|
|
279
306
|
|
|
280
307
|
// 1. Process framework-owned directories
|
|
@@ -295,14 +322,14 @@ async function upgrade() {
|
|
|
295
322
|
results.removed.push(...dirResult.removed);
|
|
296
323
|
}
|
|
297
324
|
|
|
298
|
-
// 3.
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
325
|
+
// 3. Smart-merge CLAUDE.md using section markers
|
|
326
|
+
const claudeStatus = mergeClaudeMd();
|
|
327
|
+
if (claudeStatus === 'replaced' || claudeStatus === 'appended') {
|
|
328
|
+
results.updated.push('CLAUDE.md');
|
|
329
|
+
} else if (claudeStatus === 'unchanged') {
|
|
330
|
+
results.unchanged.push('CLAUDE.md');
|
|
331
|
+
} else if (claudeStatus === 'created') {
|
|
332
|
+
results.added.push('CLAUDE.md');
|
|
306
333
|
}
|
|
307
334
|
|
|
308
335
|
// 4. Smart-merge settings.json
|
|
@@ -314,8 +341,7 @@ async function upgrade() {
|
|
|
314
341
|
}
|
|
315
342
|
|
|
316
343
|
// Report results
|
|
317
|
-
const totalChanges =
|
|
318
|
-
results.updated.length + results.added.length + results.needsReview.length;
|
|
344
|
+
const totalChanges = results.updated.length + results.added.length;
|
|
319
345
|
|
|
320
346
|
if (totalChanges === 0 && results.removed.length === 0) {
|
|
321
347
|
console.log(' Already up to date.\n');
|
|
@@ -338,14 +364,6 @@ async function upgrade() {
|
|
|
338
364
|
console.log();
|
|
339
365
|
}
|
|
340
366
|
|
|
341
|
-
if (results.needsReview.length > 0) {
|
|
342
|
-
console.log(` Needs manual review (${results.needsReview.length}):`);
|
|
343
|
-
for (const f of results.needsReview) {
|
|
344
|
-
console.log(` ${f} → .forge/upgrade/${path.basename(f)}.new`);
|
|
345
|
-
}
|
|
346
|
-
console.log();
|
|
347
|
-
}
|
|
348
|
-
|
|
349
367
|
if (results.removed.length > 0) {
|
|
350
368
|
console.log(` Removed from template (${results.removed.length}):`);
|
|
351
369
|
for (const f of results.removed) {
|
|
@@ -366,6 +384,13 @@ if (subcommand === 'upgrade') {
|
|
|
366
384
|
console.error('Error:', err.message);
|
|
367
385
|
process.exit(1);
|
|
368
386
|
});
|
|
387
|
+
} else if (isForgeInstalled()) {
|
|
388
|
+
// Auto-detect: Forge already installed, run upgrade instead
|
|
389
|
+
console.log(' Forge detected — running upgrade automatically.\n');
|
|
390
|
+
upgrade().catch((err) => {
|
|
391
|
+
console.error('Error:', err.message);
|
|
392
|
+
process.exit(1);
|
|
393
|
+
});
|
|
369
394
|
} else {
|
|
370
395
|
install().catch((err) => {
|
|
371
396
|
console.error('Error:', err.message);
|
package/package.json
CHANGED
|
@@ -42,22 +42,63 @@ After 3 auto-fix attempts on a single task → STOP fixing. Document remaining i
|
|
|
42
42
|
### Scope Boundary
|
|
43
43
|
Only fix issues DIRECTLY caused by the current task. Pre-existing warnings, tech debt, unrelated bugs → log to `.forge/deferred-issues.md`, don't fix.
|
|
44
44
|
|
|
45
|
+
## Native Task Tracking (Hybrid Approach)
|
|
46
|
+
|
|
47
|
+
Use Claude Code's native task tools (`TaskCreate`, `TaskUpdate`, `TaskList`) for **in-session visibility** during execution. The `.forge/state/milestone-{id}.yml` remains the **cross-session source of truth** — native tasks are a UI layer on top.
|
|
48
|
+
|
|
49
|
+
### On Plan Start
|
|
50
|
+
|
|
51
|
+
After loading the plan file, create native tasks from the XML task blocks:
|
|
52
|
+
|
|
53
|
+
1. Parse all `<task>` XML blocks from the plan
|
|
54
|
+
2. For each task, call `TaskCreate`:
|
|
55
|
+
- `subject`: The task's `<name>` value
|
|
56
|
+
- `description`: Combine `<action>`, `<verify>`, and `<done>` fields
|
|
57
|
+
- `activeForm`: Present-continuous form of the task name (e.g., "Implementing login form")
|
|
58
|
+
3. If the plan has ordered tasks (task 2 depends on task 1), set dependencies via `TaskUpdate` with `addBlockedBy`
|
|
59
|
+
4. Store the mapping: native task ID → plan task number (track mentally or in first task's metadata)
|
|
60
|
+
|
|
61
|
+
### On Task Start
|
|
62
|
+
|
|
63
|
+
Before implementing each task:
|
|
64
|
+
1. Call `TaskUpdate` with `status: "in_progress"` on the current native task
|
|
65
|
+
2. This gives the user a visible spinner with the `activeForm` text
|
|
66
|
+
|
|
67
|
+
### On Task Complete
|
|
68
|
+
|
|
69
|
+
After each task's commit:
|
|
70
|
+
1. Call `TaskUpdate` with `status: "completed"` on the finished native task
|
|
71
|
+
2. The next task automatically becomes unblocked (if dependencies were set)
|
|
72
|
+
|
|
73
|
+
### On Plan Complete
|
|
74
|
+
|
|
75
|
+
Native tasks are session-scoped — they disappear on `/clear` or session end. No cleanup needed. The authoritative state has already been written to `.forge/state/milestone-{id}.yml`.
|
|
76
|
+
|
|
77
|
+
### When NOT to Create Native Tasks
|
|
78
|
+
|
|
79
|
+
- **Spawned fresh agents**: Subagents don't share the parent's task list. The parent agent creates the native tasks; the subagent just does the work.
|
|
80
|
+
- **Single-task plans**: If the plan has only 1 task, skip native task creation — the overhead isn't worth it.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
45
84
|
## Task Execution Flow
|
|
46
85
|
|
|
47
86
|
For each task in the plan:
|
|
48
87
|
|
|
49
88
|
1. **Read** the task XML (name, files, action, verify, done)
|
|
50
|
-
2. **
|
|
51
|
-
3. **
|
|
52
|
-
4. **
|
|
53
|
-
5. **
|
|
54
|
-
6. **
|
|
89
|
+
2. **Mark in-progress** — `TaskUpdate` the native task to `in_progress`
|
|
90
|
+
3. **Check** context.md — does this task touch a locked decision? Honor it exactly.
|
|
91
|
+
4. **Implement** following the action instructions
|
|
92
|
+
5. **Verify** using the verify step (run tests, inspect output)
|
|
93
|
+
6. **Confirm** done criteria are met
|
|
94
|
+
7. **Commit** atomically
|
|
95
|
+
8. **Mark complete** — `TaskUpdate` the native task to `completed`
|
|
55
96
|
|
|
56
97
|
## TDD Flow (When task type="tdd")
|
|
57
98
|
|
|
58
99
|
### With Test Spec (from planning Step 7)
|
|
59
100
|
When the task has a `<spec>` field, test specs already exist:
|
|
60
|
-
1. **Copy spec to test location:** Move from `.forge/phases/` to the project's test directory
|
|
101
|
+
1. **Copy spec to test location:** Move from `.forge/phases/m{M}-{N}-{name}/specs/` to the project's test directory
|
|
61
102
|
2. **RED:** Remove `skip` markers from the first test. Confirm it fails. Commit: `test({scope}): activate spec tests for {feature}`
|
|
62
103
|
3. **GREEN:** Write minimal code to make it pass. Repeat for each test in the spec.
|
|
63
104
|
4. **REFACTOR:** Clean up. Commit: `feat({scope}): implement {feature}`
|
|
@@ -112,7 +153,7 @@ After each task, mentally assess context usage:
|
|
|
112
153
|
After completing all tasks in a plan, create a summary:
|
|
113
154
|
|
|
114
155
|
```markdown
|
|
115
|
-
# Execution Summary:
|
|
156
|
+
# Execution Summary: m{M}-{N}-{name}, Plan {NN}
|
|
116
157
|
|
|
117
158
|
## Completed Tasks
|
|
118
159
|
1. [Task name] — [one-line result]
|
|
@@ -498,22 +498,24 @@ If user explicitly says "Use Quick/Standard/Full tier" — honor it. No argument
|
|
|
498
498
|
|
|
499
499
|
## Step 3: Route to Next Skill
|
|
500
500
|
|
|
501
|
-
Based on detected tier and current state, tell the user which skill comes next and invoke it
|
|
501
|
+
Based on detected tier and current state, tell the user which skill comes next and **invoke it using the `Skill` tool**.
|
|
502
|
+
|
|
503
|
+
**CRITICAL: NEVER use `EnterPlanMode` or Claude Code's native plan mode.** All Forge phases are handled by Forge skills invoked via the `Skill` tool. When the workflow says "planning", that means invoke `Skill(planning)` — not enter native plan mode. Native plan mode writes to a different file format and bypasses Forge's constitutional gates, state management, and structured plan output.
|
|
502
504
|
|
|
503
505
|
If resuming mid-workflow:
|
|
504
506
|
- Read the selected milestone's state file (`.forge/state/milestone-{id}.yml`) for current position
|
|
505
507
|
- **Use `current.status` to determine the next skill** — this is the authoritative workflow position:
|
|
506
508
|
|
|
507
|
-
| `current.status` | Next Action |
|
|
509
|
+
| `current.status` | Next Action (invoke via `Skill` tool) |
|
|
508
510
|
|-------------------|-------------|
|
|
509
511
|
| `not_started` | Detect tier, start workflow |
|
|
510
|
-
| `researching` |
|
|
511
|
-
| `discussing` |
|
|
512
|
-
| `planning` |
|
|
513
|
-
| `executing` |
|
|
514
|
-
| `verifying` |
|
|
515
|
-
| `auditing` |
|
|
516
|
-
| `refactoring` |
|
|
512
|
+
| `researching` | Invoke `Skill(researching)`, then → `discussing` |
|
|
513
|
+
| `discussing` | Invoke `Skill(discussing)`, then → `planning` (or `architecting` for Full) |
|
|
514
|
+
| `planning` | Invoke `Skill(planning)`, then → `executing` |
|
|
515
|
+
| `executing` | Invoke `Skill(executing)`, then → `verifying` |
|
|
516
|
+
| `verifying` | Invoke `Skill(verifying)`, then → `auditing` |
|
|
517
|
+
| `auditing` | Invoke `Skill(auditing)`, then → `refactoring` |
|
|
518
|
+
| `refactoring` | Invoke `Skill(refactoring)`, then → `complete` |
|
|
517
519
|
| `complete` | Milestone is done. Ask user what's next. |
|
|
518
520
|
|
|
519
521
|
- **Never treat a milestone as complete just because `overall_percent` is 100%.** Task completion and workflow completion are different. All planned tasks being done (100%) means execution is finished — verification, auditing, and refactoring still need to run.
|
|
@@ -581,7 +583,7 @@ Each skill ends with a standard handoff message. The pattern is:
|
|
|
581
583
|
| researching | Research summary (markdown in conversation or `.forge/` files) | discussing reads research findings |
|
|
582
584
|
| discussing | Decision summary → carried into planning via context.md | planning reads context.md |
|
|
583
585
|
| architecting | ADRs in `.forge/decisions/`, data models, API contracts | planning reads decisions |
|
|
584
|
-
| planning | Plans in `.forge/phases/`, requirements.yml, roadmap.yml, context.md | executing reads plans |
|
|
586
|
+
| planning | Plans in `.forge/phases/m{M}-{N}-{name}/`, requirements.yml, roadmap.yml, context.md | executing reads plans |
|
|
585
587
|
| executing | Committed code, execution summary, milestone state updated | verifying reads must_haves from plans |
|
|
586
588
|
| verifying | Verification report, desire paths updated | auditing reads project.yml + source files |
|
|
587
589
|
| auditing | Health report in `.forge/audits/` | refactoring reads health report + git diff |
|
|
@@ -7,6 +7,8 @@ description: "Use when you need to break work into executable tasks with verific
|
|
|
7
7
|
|
|
8
8
|
Turn research and requirements into executable, verifiable plans.
|
|
9
9
|
|
|
10
|
+
> **IMPORTANT:** This skill replaces Claude Code's native plan mode. Do NOT use `EnterPlanMode` — all planning output goes to `.forge/phases/` as structured plan files, not to the native plan file. Follow the steps below directly in the conversation.
|
|
11
|
+
|
|
10
12
|
## Step 1: Resolution Gate
|
|
11
13
|
|
|
12
14
|
Read `.forge/context.md`. Check the **Needs Resolution** section.
|
package/template/CLAUDE.md
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
|
+
<!-- forge:start -->
|
|
1
2
|
# Forge
|
|
2
3
|
|
|
3
4
|
A lean meta-prompting framework for Claude Code. Synthesizes context engineering (GSD) and constitutional governance (Spec-Kit) on Claude Code's native primitives.
|
|
4
5
|
|
|
6
|
+
## Critical: No Native Plan Mode
|
|
7
|
+
|
|
8
|
+
**NEVER use the `EnterPlanMode` tool when the Forge framework is active** (i.e., when `.forge/` exists or a Forge skill is running). Forge has its own `planning` skill that writes structured plans to `.forge/phases/`. Claude Code's native plan mode writes to a separate plan file with a different format — this conflicts with Forge's workflow and state management.
|
|
9
|
+
|
|
10
|
+
When the workflow reaches the planning phase, **invoke the `planning` skill using the `Skill` tool** — do not enter native plan mode. This applies to all tiers (Standard and Full). The same rule applies to all other Forge phases: always invoke the corresponding Forge skill, never substitute a native Claude Code behavior.
|
|
11
|
+
|
|
5
12
|
## Core Principles
|
|
6
13
|
|
|
7
14
|
1. **Lean by default, powerful when needed.** Quick fixes skip ceremony. Complex features get full governance. The framework adapts — you don't.
|
|
8
|
-
2. **Native-first.** Skills, agents, hooks, plugins — use Claude Code's built-in systems. No custom JavaScript, no reinvented orchestration.
|
|
15
|
+
2. **Native-first.** Skills, agents, hooks, plugins — use Claude Code's built-in systems. No custom JavaScript, no reinvented orchestration. Periodically audit Forge features against Claude Code's current native capabilities — if a native tool now handles what a Forge feature does, deprecate the Forge version. Use native tools for session-scoped concerns (task UI, exploration) and Forge state for cross-session persistence. When in doubt, prefer native.
|
|
9
16
|
3. **Context is sacred.** Every token earns its place. Size-gate all artifacts, lazy-load skills, spawn fresh agents for isolated work.
|
|
10
17
|
4. **Decisions are contracts.** User decisions lock before building begins. Downstream agents honor contracts or flag violations — never silently override.
|
|
11
18
|
5. **Verify against goals, not tasks.** "Does it work?" beats "Did we complete the checklist?" Goal-backward verification at every tier.
|
|
@@ -155,3 +162,4 @@ Every task gets its own commit. Format: `{type}({scope}): {description}`
|
|
|
155
162
|
Types: `feat`, `fix`, `test`, `refactor`, `chore`, `docs`
|
|
156
163
|
Scope: phase-plan or feature area
|
|
157
164
|
Never use `git add .` or `git add -A` — stage files individually.
|
|
165
|
+
<!-- forge:end -->
|