@jamie-tam/forge 6.0.0 → 6.1.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.
Files changed (61) hide show
  1. package/README.md +73 -59
  2. package/agents/dreamer.md +5 -6
  3. package/agents/gotcha-hunter.md +1 -1
  4. package/agents/prototype-codifier.md +2 -2
  5. package/commands/{forge.md → discover.md} +11 -9
  6. package/commands/feature.md +50 -8
  7. package/commands/{evolve.md → forge-evolve.md} +3 -3
  8. package/commands/greenfield.md +5 -5
  9. package/commands/note.md +64 -0
  10. package/commands/{task-force.md → parallel.md} +15 -15
  11. package/commands/resume.md +2 -2
  12. package/commands/setup.md +18 -17
  13. package/commands/status.md +2 -2
  14. package/dist/__tests__/hooks.test.js +334 -0
  15. package/dist/__tests__/init.test.js +110 -0
  16. package/dist/__tests__/work-manifest.test.js +48 -14
  17. package/dist/cli.js +0 -0
  18. package/dist/hooks.js +88 -6
  19. package/dist/init.js +39 -1
  20. package/dist/uninstall.js +11 -5
  21. package/dist/work-manifest.js +63 -24
  22. package/hooks/hooks.json +14 -1
  23. package/hooks/scripts/pre-compact.sh +3 -6
  24. package/hooks/scripts/session-start.sh +1 -1
  25. package/hooks/templates/CLAUDE.md.template +6 -3
  26. package/package.json +1 -1
  27. package/references/common/phases.md +8 -6
  28. package/references/common/skill-authoring.md +1 -1
  29. package/rules/common/forge-system.md +42 -4
  30. package/skills/build-prototype/SKILL.md +4 -4
  31. package/skills/build-tdd/SKILL.md +14 -0
  32. package/skills/concept-slides/SKILL.md +11 -11
  33. package/skills/deliver-deploy/SKILL.md +1 -1
  34. package/skills/harden/SKILL.md +6 -6
  35. package/skills/quality-test-execution/SKILL.md +26 -1
  36. package/skills/quality-test-plan/SKILL.md +21 -1
  37. package/skills/support-debug/SKILL.md +1 -1
  38. package/skills/support-dream/SKILL.md +5 -5
  39. package/skills/support-gotcha/SKILL.md +3 -3
  40. package/skills/{support-task-force → support-parallel}/SKILL.md +22 -22
  41. package/skills/{support-task-force → support-parallel}/references/dispatch-pattern.md +10 -10
  42. package/skills/{support-task-force → support-parallel}/references/synthesis-template.md +10 -10
  43. package/skills/support-skill-validator/SKILL.md +5 -5
  44. package/skills/support-skill-validator/references/validation-checks.md +1 -1
  45. package/skills/support-system-guide/SKILL.md +4 -3
  46. package/skills/support-wiki-lint/scripts/lint.mjs +52 -0
  47. package/templates/README.md +1 -1
  48. package/templates/aiwiki/schemas/session.md +15 -14
  49. package/templates/manifests/bugfix.yaml +1 -1
  50. package/templates/manifests/feature.yaml +1 -1
  51. package/templates/manifests/greenfield.yaml +1 -1
  52. package/templates/manifests/hotfix.yaml +1 -1
  53. package/templates/manifests/refactor.yaml +1 -1
  54. package/templates/manifests/v5/SCHEMA.md +14 -17
  55. package/templates/manifests/v5/feature.yaml +1 -1
  56. package/templates/manifests/v6/SCHEMA.md +14 -10
  57. package/commands/abort.md +0 -25
  58. package/dist/__tests__/active-manifest.test.js +0 -272
  59. package/dist/__tests__/gate-check.test.js +0 -384
  60. package/dist/active-manifest.js +0 -229
  61. package/dist/gate-check.js +0 -326
@@ -1,4 +1,4 @@
1
- # Task-Force Dispatch Pattern
1
+ # Parallel Dispatch Pattern
2
2
 
3
3
  Operational recipes for spawning per-task Claude+Codex teams.
4
4
 
@@ -101,7 +101,7 @@ complex → architect + tracer + builder + dispatch quality-code-review + spe
101
101
  ## Per-agent prompt template
102
102
 
103
103
  ```
104
- You are agent {role} in task-force task {n} of {N}, run-id {run-id}.
104
+ You are agent {role} in parallel-run task {n} of {N}, run-id {run-id}.
105
105
 
106
106
  Task type: {dev|research|debug|docs|review|security|quick|complex}
107
107
  Phase mode: {prototype|production}
@@ -120,10 +120,10 @@ Your scope: {paths, subsystem, or "whole repo"}
120
120
 
121
121
  OUTPUT:
122
122
  - Result of doing the task (code diffs, findings, document, etc.)
123
- - One-line verdict for the task-force aggregator: PASS / CONCERNS / FAIL
124
- - Hand off any followups by writing them to .forge/task-force/{run-id}/task-{n}/followups.md
123
+ - One-line verdict for the parallel-run aggregator: PASS / CONCERNS / FAIL
124
+ - Hand off any followups by writing them to .forge/parallel/{run-id}/task-{n}/followups.md
125
125
 
126
- Cap your output at {N} words. Save artifacts under .forge/task-force/{run-id}/task-{n}/{role}.{ext}.
126
+ Cap your output at {N} words. Save artifacts under .forge/parallel/{run-id}/task-{n}/{role}.{ext}.
127
127
  ```
128
128
 
129
129
  ## Batched dispatch ceiling
@@ -155,7 +155,7 @@ else:
155
155
  | Codex sandbox can't write | "operation blocked in sandbox" | Codex outputs uncommitted; Claude commits or main session commits |
156
156
  | Two agents touch same file | Edit tool conflict | Partition more aggressively |
157
157
  | Classifier picks command-shaped but rest heterogeneous | Some routed, some not | Surface routing decisions, continue with remainder |
158
- | User cancels mid-run | Receives interrupt | Mark in-flight tasks abandoned; preserve completed outputs |
158
+ | User cancels mid-run | Receives interrupt | Stop in-flight tasks; preserve completed outputs |
159
159
 
160
160
  ## Sizing examples
161
161
 
@@ -172,7 +172,7 @@ else:
172
172
 
173
173
  ## Cleanup
174
174
 
175
- `.forge/task-force/{run-id}/` accumulates per-run. Prune via:
176
- - `/evolve` (include task-force cleanup as a step)
177
- - Manual: `find .forge/task-force -maxdepth 1 -mtime +30 -exec rm -rf {} +`
178
- - `support-dream` could consolidate task-force runs into aiwiki summary entries before prune
175
+ `.forge/parallel/{run-id}/` accumulates per-run. Prune via:
176
+ - `/forge-evolve` (include parallel-run cleanup as a step)
177
+ - Manual: `find .forge/parallel -maxdepth 1 -mtime +30 -exec rm -rf {} +`
178
+ - `support-dream` could consolidate parallel runs into aiwiki summary entries before prune
@@ -1,4 +1,4 @@
1
- # Task-Force Output Templates
1
+ # Parallel Run Output Templates
2
2
 
3
3
  Use these for per-task verdicts (Step 7) and run summaries (Step 8).
4
4
 
@@ -31,20 +31,20 @@ Use these for per-task verdicts (Step 7) and run summaries (Step 8).
31
31
 
32
32
  ## Artifacts
33
33
 
34
- - `.forge/task-force/{run-id}/task-{n}/builder.md`
35
- - `.forge/task-force/{run-id}/task-{n}/code-reviewer-claude.md`
36
- - `.forge/task-force/{run-id}/task-{n}/code-reviewer-codex.md`
37
- - `.forge/task-force/{run-id}/task-{n}/followups.md` (if any)
34
+ - `.forge/parallel/{run-id}/task-{n}/builder.md`
35
+ - `.forge/parallel/{run-id}/task-{n}/code-reviewer-claude.md`
36
+ - `.forge/parallel/{run-id}/task-{n}/code-reviewer-codex.md`
37
+ - `.forge/parallel/{run-id}/task-{n}/followups.md` (if any)
38
38
 
39
39
  ## Followups (if any)
40
40
 
41
- - <item> — owner: <user | next task-force run | /evolve>
41
+ - <item> — owner: <user | next parallel run | /forge-evolve>
42
42
  ```
43
43
 
44
44
  ## Run summary
45
45
 
46
46
  ```markdown
47
- # Task-Force Run {run-id}
47
+ # Parallel Run {run-id}
48
48
 
49
49
  **Started:** {ISO-8601}
50
50
  **Completed:** {ISO-8601}
@@ -95,9 +95,9 @@ Use these for per-task verdicts (Step 7) and run summaries (Step 8).
95
95
 
96
96
  ## Next steps
97
97
 
98
- If divergence > 30%, sample-check a few task-force outputs — your classifier or team-assembly might be miscalibrated.
98
+ If divergence > 30%, sample-check a few team outputs — your classifier or team-assembly might be miscalibrated.
99
99
 
100
- If all tasks PASSED with no divergence, run a `/evolve` to consider whether patterns recurred enough to warrant capturing as a gotcha or rule.
100
+ If all tasks PASSED with no divergence, run a `/forge-evolve` to consider whether patterns recurred enough to warrant capturing as a gotcha or rule.
101
101
  ```
102
102
 
103
103
  ## Severity / verdict definitions
@@ -123,4 +123,4 @@ After run summary, if any task is `complete-divergent` AND the divergence is ove
123
123
  - Debug task with divergent verdicts → `support-debug` skill standalone
124
124
  - Research task with divergent verdicts → user adjudication required
125
125
 
126
- Task-force is for parallel speed. When agreement breaks down, the right tool is depth, not parallelism.
126
+ `/parallel` is for parallel speed. When agreement breaks down, the right tool is depth, not parallelism.
@@ -16,7 +16,7 @@ As the forge harness grows -- skills added, rules promoted from gotchas, command
16
16
  | Trigger | Validation Scope | Performance Target |
17
17
  |---|---|---|
18
18
  | `/validate` command | Full scan (all 5 checks) | Under 30 seconds |
19
- | `/evolve` modifies a skill | Pre-apply check (modified skill vs all others) | Under 10 seconds |
19
+ | `/forge-evolve` modifies a skill | Pre-apply check (modified skill vs all others) | Under 10 seconds |
20
20
  | Session start | Lightweight I/O graph check only | Under 3 seconds |
21
21
  | Manual request | Full scan or targeted check | Depends on scope |
22
22
  | After gotcha promotion | Promoted rule vs existing rules and skills | Under 10 seconds |
@@ -32,7 +32,7 @@ As the forge harness grows -- skills added, rules promoted from gotchas, command
32
32
  |---|---|
33
33
  | **Requires** | All `SKILL.md` files + all `rules/*.md` files + all `commands/*.md` files |
34
34
  | **Produces** | Validation report (structured, actionable) |
35
- | **Feeds into** | `/evolve` command (fix contradictions before applying changes) |
35
+ | **Feeds into** | `/forge-evolve` command (fix contradictions before applying changes) |
36
36
  | **Updates** | Nothing directly -- produces a report for human/AI action |
37
37
 
38
38
  ### Input Files
@@ -127,9 +127,9 @@ No blocking errors. System is consistent.
127
127
  Warnings should be reviewed when convenient.
128
128
  ```
129
129
 
130
- ### /evolve Command (Pre-Apply Check)
130
+ ### /forge-evolve Command (Pre-Apply Check)
131
131
 
132
- Before `/evolve` applies any skill modification:
132
+ Before `/forge-evolve` applies any skill modification:
133
133
 
134
134
  1. Receive the proposed change
135
135
  2. Apply the change to a temporary copy
@@ -139,7 +139,7 @@ Before `/evolve` applies any skill modification:
139
139
  6. If clean: ALLOW the change
140
140
 
141
141
  ```
142
- /evolve proposes modifying build-tdd...
142
+ /forge-evolve proposes modifying build-tdd...
143
143
 
144
144
  Pre-apply validation:
145
145
  [PASS] No directive conflicts
@@ -267,7 +267,7 @@ Only escalate to WARNING/ERROR when you can name the downstream skill that fails
267
267
  ```
268
268
  DRIFT:
269
269
 
270
- [ERROR] D-001: New Contradiction After /evolve
270
+ [ERROR] D-001: New Contradiction After /forge-evolve
271
271
  Modified: support-debug (added "ALWAYS verify with context7 before debugging")
272
272
  Conflicts with: rules/common/verification.md ("verify when UNCERTAIN, not always")
273
273
  Analysis: New directive is stricter than existing rule.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: support-system-guide
3
- description: "Use when the user opens a fresh session, asks 'what should I run', 'where do I start', 'which command for X', 'is this a /feature or /greenfield', or describes intent without naming a command. Routes them to the right command (/feature, /greenfield, /task-force, /harden, etc.) and explains the phase model. Skip if the user has already invoked a specific command."
3
+ description: "Use when the user opens a fresh session, asks 'what should I run', 'where do I start', 'which command for X', 'is this a /feature or /greenfield', or describes intent without naming a command. Routes them to the right command (/feature, /greenfield, /parallel, /harden, etc.) and explains the phase model. Skip if the user has already invoked a specific command."
4
4
  ---
5
5
 
6
6
  <EXTREMELY-IMPORTANT>
@@ -71,13 +71,14 @@ When the user describes what they want to do, route them to the correct command.
71
71
 
72
72
  | User Intent | Command | What It Does |
73
73
  |---|---|---|
74
- | "What does this project have?" / "Show me forge" / "What can I run?" | `/forge` | One-screen discovery — installed capabilities, active work, suggested next |
74
+ | "What does this project have?" / "Show me forge" / "What can I run?" | `/discover` | One-screen discovery — installed capabilities, active work, suggested next |
75
+ | "Capture this thought" / "Note this for later" / "Save this research" | `/note <text>` | Append to `aiwiki/raw/{date}.md` — for Phase 1-2 research, ad-hoc brainstorm, anything not yet a typed page |
75
76
  | "Add a feature" / "Implement X" / "Build Y" | `/feature` | Full lifecycle: discover -> plan -> build -> quality -> deliver |
76
77
  | "New project" / "Start from scratch" / "Greenfield" | `/greenfield` | Scaffold + full lifecycle for a new project |
77
78
  | "Fix this bug" / "Something is broken" / "Error when..." | `/bugfix` | Debug -> fix -> test -> PR |
78
79
  | "Clean up" / "Refactor" / "Improve code quality" | `/refactor` | Analyze -> refactor -> review -> PR |
79
80
  | "Production is down" / "Emergency fix" / "Critical bug" | `/hotfix` | Emergency: debug -> fix -> test -> deploy (expedited gates) |
80
- | "Improve the skills" / "Update a skill" / "System enhancement" | `/evolve` | Self-improvement: review skills, propose changes, validate |
81
+ | "Improve the skills" / "Update a skill" / "System enhancement" | `/forge-evolve` | Self-improvement: review skills, propose changes, validate |
81
82
  | "Check consistency" / "Validate skills" / "Run validator" | `/validate` | Validate all skills/rules for contradictions and gaps |
82
83
 
83
84
  ### Command vs. Direct Skill Use
@@ -23,8 +23,23 @@ const FRONTMATTER_RE = /^---\n([\s\S]*?)\n---\n([\s\S]*)$/;
23
23
  const CITATION_HASHED_RE = /([\w./@~-]+\.\w+):(\d+)@([0-9a-f]{7})\b/g;
24
24
  const CITATION_BARE_RE = /([\w./@~-]+\.\w+):(\d+)(?!@?[0-9a-f]{7})\b/g;
25
25
  const ACK_STALE_RE = /\/\/\s*ack-stale\s*:|#\s*ack-stale\s*:/;
26
+ const ACK_SECRET_RE = /\back-secret\s*:/;
26
27
  const SECTION_RE = /^##\s+(.+?)\s*$/gm;
27
28
 
29
+ // Possible-secret patterns. Advisory only — emitted as warnings, not errors.
30
+ // Lint hook is non-blocking (`hooks/scripts/wiki-lint.sh` returns continue:true
31
+ // unconditionally), so these never block a write — they surface on stderr so
32
+ // the next edit can address them. False positives are downgraded to info if
33
+ // the same line carries an `ack-secret: <reason>` annotation.
34
+ const SECRET_PATTERNS = [
35
+ { name: 'aws_access_key', re: /AKIA[0-9A-Z]{16}/g },
36
+ { name: 'private_key_block', re: /-----BEGIN (?:[A-Z ]+ )?PRIVATE KEY-----/g },
37
+ { name: 'password_assignment', re: /\b(?:password|passwd|pwd)\s*[=:]\s*['"][^'"\s$][^'"\s]{3,}['"]/gi },
38
+ { name: 'api_key_assignment', re: /\b(?:api[_-]?key|apikey|secret[_-]?key|access[_-]?token|bearer[_-]?token)\s*[=:]\s*['"][^'"\s$][^'"\s]{7,}['"]/gi },
39
+ { name: 'jwt_token', re: /\beyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g },
40
+ { name: 'url_credentials', re: /\b[a-z][a-z0-9+.-]*:\/\/[^\s/:@]+:[^\s/@]+@/gi },
41
+ ];
42
+
28
43
  // ---- Minimal YAML parser ---------------------------------------------------
29
44
  // Handles only what our schema + frontmatter files use:
30
45
  // - Top-level mapping
@@ -389,6 +404,43 @@ export function lint({ file, schemasDir, root }) {
389
404
  fs.writeFileSync(absFile, newContent, 'utf8');
390
405
  }
391
406
 
407
+ // Secrets scan — advisory only, never an error. The wiki-lint hook is
408
+ // non-blocking; these warnings surface on stderr so the next edit can
409
+ // address them. Scan the FINAL post-backfill content (after citation hash
410
+ // updates). Skip lines annotated with `ack-secret: <reason>`.
411
+ const finalContent = updates.length > 0
412
+ ? `---\n${modifiedFm}\n---\n${modifiedBody}`
413
+ : original;
414
+ const finalLines = finalContent.split('\n');
415
+ const finalLineOffsets = computeLineOffsets(finalContent);
416
+ for (const { name, re } of SECRET_PATTERNS) {
417
+ re.lastIndex = 0;
418
+ let m;
419
+ while ((m = re.exec(finalContent)) !== null) {
420
+ const matchOffset = m.index;
421
+ // Find the line number (1-based).
422
+ let lineNum = 1;
423
+ for (let i = 0; i < finalLineOffsets.length; i++) {
424
+ if (finalLineOffsets[i] > matchOffset) break;
425
+ lineNum = i + 1;
426
+ }
427
+ const lineText = finalLines[lineNum - 1] || '';
428
+ const ackedOnSameLine = ACK_SECRET_RE.test(lineText);
429
+ const finding = {
430
+ kind: 'possible_secret',
431
+ type: name,
432
+ line: lineNum,
433
+ preview: m[0].slice(0, 40),
434
+ message: `Possible ${name} on line ${lineNum} (preview: ${m[0].slice(0, 40)}). If this is an intentional example or test fixture, add an \`ack-secret: <reason>\` annotation on the same line to downgrade to info.`,
435
+ };
436
+ if (ackedOnSameLine) {
437
+ warnings.push({ ...finding, kind: 'possible_secret_acked' });
438
+ } else {
439
+ warnings.push(finding);
440
+ }
441
+ }
442
+ }
443
+
392
444
  return {
393
445
  ok: errors.length === 0,
394
446
  file,
@@ -12,7 +12,7 @@ Installed into the target project by `npx @jamie-tam/forge init` (or kept in-syn
12
12
 
13
13
  ## Legacy
14
14
 
15
- Kept on-disk so older manifests still parse and so `/evolve` can migrate them forward. Not installed into new projects.
15
+ Kept on-disk so older manifests still parse and so `/forge-evolve` can migrate them forward. Not installed into new projects.
16
16
 
17
17
  - **`manifests/v5/`** — v5 schema (`SCHEMA.md` plus a `feature.yaml` reference). v5 manifests still parse against the v6 reader (see `manifests/v6/SCHEMA.md` §4). v4 manifests also still parse but no template is retained — the reader synthesizes the missing fields.
18
18
 
@@ -21,7 +21,7 @@ required_sections:
21
21
  - "## Next steps"
22
22
  section_order: strict
23
23
  citation_rule: required-in-files-touched
24
- maintained_by: hooks-and-dream
24
+ maintained_by: manual-or-harden
25
25
  ---
26
26
 
27
27
  # Schema: session (per-session handoff)
@@ -32,16 +32,17 @@ A session file is an **index of links** for one work session — what files were
32
32
 
33
33
  **Index of links, not distilled summary.** No prose paragraphs. No narrative. No screenshots-from-the-moment. Future sessions follow the links to actual artifacts (ADRs, gotchas, raw notes); the session file is just the routing layer.
34
34
 
35
- ## How it's maintained (NOT by hand)
35
+ ## How it's maintained
36
36
 
37
- This page type is unusual: it's maintained by **hooks and dream**, not by humans typing.
37
+ **Current state (2026-05-15):** session files are maintained manually or by the `harden` skill at Phase 5 (codify). The original design called for hook-driven maintenance, but the session-checkpoint hook layer (SessionStart creating the file, PostToolUse appending events, SessionEnd marking done) is **deferred** — not yet shipped.
38
38
 
39
- - `SessionStart` hook creates the file from this schema's skeleton (frontmatter + empty sections)
40
- - `PostToolUse` hooks append event lines to the appropriate sections (commit / gotcha / decision / raw)
41
- - `PreCompact` dream consolidates the event log into the schema sections (deduplicates, summarises bullet sequences, prunes noise)
42
- - `SessionEnd` (manual `/handoff` or detected) marks `status: done`
39
+ Until the hooks ship, write session files by either:
40
+ - **Manually**, when a session produced durable handoff signal worth persisting. The AI should OFFER to write a session file before ending a long session; the user accepts or declines.
41
+ - **Via `harden`** at codify (Phase 5), which writes one session entry summarising the prototype-to-production work.
43
42
 
44
- Do NOT manually edit a session file unless correcting a hook misfire. Manual edits should be rare.
43
+ Once the session-checkpoint hooks ship, this section will be updated to reflect the auto-maintenance contract: SessionStart creates the file from this schema's skeleton, PostToolUse hooks append event lines under the appropriate sections, PreCompact dream consolidates the event log, and `SessionEnd` marks `status: done`. Dependents (`support-dream`, `dreamer`) already include a graceful fallback: if `aiwiki/sessions/{current}.md` does not exist, session-file refinement is skipped (no `SESSION_FILE_MISSING` failure).
44
+
45
+ Do NOT speculate-write a session file in the meantime. Empty `## Decisions made` / `## Gotchas surfaced` / `## Open questions` sections are signal-free noise.
45
46
 
46
47
  ## File location and naming
47
48
 
@@ -67,13 +68,13 @@ The companion file `aiwiki/sessions/INDEX.md` is a sortable table of all session
67
68
 
68
69
  ## Required sections
69
70
 
70
- | Section | Purpose | Maintained by |
71
+ | Section | Purpose | Maintained by (current) |
71
72
  |---|---|---|
72
- | `## Files touched` | Bullet list of files modified, with citations | PostToolUse hooks (append-only) |
73
- | `## Decisions made` | Links to ADRs in `aiwiki/decisions/` written this session | PostToolUse hook on `aiwiki/decisions/` write |
74
- | `## Gotchas surfaced` | Links to gotchas captured this session | PostToolUse hook on `aiwiki/gotchas/` write |
75
- | `## Open questions` | Links to raw context in `aiwiki/raw/` for unresolved items | PostToolUse hook on `aiwiki/raw/` write |
76
- | `## Next steps` | What the next session should do | Dream at PreCompact / SessionEnd |
73
+ | `## Files touched` | Bullet list of files modified, with citations | manual or `harden` — will be auto-appended once PostToolUse session-checkpoint hook ships |
74
+ | `## Decisions made` | Links to ADRs in `aiwiki/decisions/` written this session | manual or `harden` same |
75
+ | `## Gotchas surfaced` | Links to gotchas captured this session | manual or `harden` same |
76
+ | `## Open questions` | Links to raw context in `aiwiki/raw/` for unresolved items | manual or `harden` same |
77
+ | `## Next steps` | What the next session should do | manual; dream will refine once session-checkpoint hooks ship |
77
78
 
78
79
  ## Line caps
79
80
 
@@ -11,7 +11,7 @@ schema_version: "6"
11
11
  name: {name}
12
12
  type: bugfix
13
13
  description: "{description}"
14
- status: in-progress # in-progress | paused | completed | escalated | abandoned
14
+ status: in-progress # in-progress | paused | completed | escalated
15
15
  created: "{date}"
16
16
  command: bugfix
17
17
  escalated_from: null
@@ -18,7 +18,7 @@ schema_version: "6"
18
18
  name: {name}
19
19
  type: feature
20
20
  description: "{description}"
21
- status: in-progress # in-progress | paused | completed | escalated | abandoned
21
+ status: in-progress # in-progress | paused | completed | escalated
22
22
  created: "{date}"
23
23
  command: feature
24
24
  complexity: standard # trivial | standard | major
@@ -12,7 +12,7 @@ schema_version: "6"
12
12
  name: {name}
13
13
  type: greenfield
14
14
  description: "{description}"
15
- status: in-progress # in-progress | paused | completed | escalated | abandoned
15
+ status: in-progress # in-progress | paused | completed | escalated
16
16
  created: "{date}"
17
17
  command: greenfield
18
18
  complexity: standard # trivial | standard | major
@@ -11,7 +11,7 @@ schema_version: "6"
11
11
  name: {name}
12
12
  type: hotfix
13
13
  description: "{description}"
14
- status: in-progress # in-progress | paused | completed | escalated | abandoned
14
+ status: in-progress # in-progress | paused | completed | escalated
15
15
  created: "{date}"
16
16
  command: hotfix
17
17
  escalated_from: null
@@ -7,7 +7,7 @@ schema_version: "6"
7
7
  name: {name}
8
8
  type: refactor
9
9
  description: "{description}"
10
- status: in-progress # in-progress | paused | completed | escalated | abandoned
10
+ status: in-progress # in-progress | paused | completed | escalated
11
11
  created: "{date}"
12
12
  command: refactor
13
13
  coverage-baseline: null # recorded in Step 0
@@ -16,7 +16,7 @@ Required:
16
16
  | `name` | string | kebab-case identifier; matches `.forge/work/{type}/{name}/` |
17
17
  | `type` | enum | `feature` \| `bugfix` \| `hotfix` \| `refactor` \| `greenfield` |
18
18
  | `description` | string | one-line human description |
19
- | `status` | enum | `in-progress` \| `paused` \| `completed` \| `escalated` \| `abandoned` |
19
+ | `status` | enum | `in-progress` \| `paused` \| `completed` \| `escalated` |
20
20
  | `created` | ISO-8601 date | |
21
21
  | `command` | string | which slash command produced the manifest |
22
22
  | `phases` | object | pre-build (discover, plan) and post-build (quality, deliver, support) gates |
@@ -64,7 +64,7 @@ slice_graph:
64
64
  type: skeleton | feature-slice | refactor-slice
65
65
  variant: <string> # only for type: skeleton; identifies stack
66
66
  depends_on: [<slice-id>...]
67
- status: pending | in-progress | gated | complete | abandoned
67
+ status: pending | in-progress | gated | complete
68
68
  gates:
69
69
  <gate-name>: { status: <enum>, gate-passed: <bool> }
70
70
  ```
@@ -127,25 +127,23 @@ Lifecycle path (recommended; skills are written to follow this):
127
127
 
128
128
  ```
129
129
  pending → in-progress → gated → complete
130
- ↘ abandoned
131
130
  gated → in-progress (gate failed; rework)
132
131
  ```
133
132
 
134
- `complete` and `abandoned` are conventionally terminal. If a downstream
135
- change invalidates a completed slice's work, the convention is to add a
136
- NEW slice that supersedes the old (preserving the audit trail) rather
137
- than mutate the completed slice's status. Skills enforce this in their
133
+ `complete` is the conventional terminal state. If a downstream change
134
+ invalidates a completed slice's work, the convention is to add a NEW
135
+ slice that supersedes the old (preserving the audit trail) rather than
136
+ mutate the completed slice's status. Skills enforce this in their
138
137
  prompts; the verifier does not.
139
138
 
140
139
  A slice should enter `in-progress` only when every slice in its
141
- `depends_on` is in `complete` status. `abandoned` does not satisfy a
142
- dependency — descendants of an abandoned slice block. Skills check this
143
- before advancing.
140
+ `depends_on` is in `complete` status. Skills check this before
141
+ advancing.
144
142
 
145
143
  ### 3.6 Fan-out / fan-in completion (planning convention)
146
144
 
147
145
  The slice graph is **terminally settled** when every slice is in
148
- `complete` or `abandoned` status. Skills running the post-build
146
+ `complete` status. Skills running the post-build
149
147
  `phases.quality.code-review-final` gate check this convention before
150
148
  proceeding.
151
149
 
@@ -153,8 +151,7 @@ Fan-out: a slice with multiple non-dependent successors creates parallel
153
151
  branches. Each branch advances independently when its own gates pass.
154
152
 
155
153
  Fan-in: a slice with multiple `depends_on` entries waits for ALL of them
156
- to reach `complete` before entering `in-progress`. An `abandoned`
157
- dependency does NOT satisfy fan-in.
154
+ to reach `complete` before entering `in-progress`.
158
155
 
159
156
  `current_slice` is a single global pointer in v5.0; multi-active-slice
160
157
  (per-worker pointer for parallel terminal tabs) is deferred to v6.0
@@ -223,7 +220,7 @@ type ErrorCode =
223
220
  | 'E_GATE_COLLISION' | 'E_BAD_SLICE_ID' | 'E_BAD_CURRENT_SLICE'
224
221
  | 'E_MISSING_REQUIRED_FIELD' | 'E_BAD_ENUM_VALUE'
225
222
  | 'E_PHASE_GATE_PREMATURE' // §3.6: phases.quality.code-review-final.gate-passed = true
226
- // while any slice is not in terminal state (complete/abandoned)
223
+ // while any slice is not in terminal state (complete)
227
224
  | 'E_YAML_PARSE' | 'E_FILE_NOT_FOUND';
228
225
  ```
229
226
 
@@ -292,7 +289,7 @@ duplicated into the synthesized slice). They run at v4-style "post-build"
292
289
  time — after `legacy-build` slice completes.
293
290
 
294
291
  The migration is a **read-time synthesis**, not an on-disk rewrite. v4
295
- manifests on disk stay v4-shaped until `/evolve` runs, which writes a
292
+ manifests on disk stay v4-shaped until `/forge-evolve` runs, which writes a
296
293
  true v5 `slice_graph` block.
297
294
 
298
295
  ### 6.1 Migration semantic limitation (acknowledged)
@@ -307,11 +304,11 @@ followed.
307
304
  Consequence: a v4-migrated manifest read by v5 tooling will show
308
305
  `build-tdd: passed` even if no TDD occurred. This is acceptable because
309
306
  (a) the v4 work has already shipped — re-litigating the gate would
310
- block all in-flight v4 features, and (b) `/evolve` prompts the user to
307
+ block all in-flight v4 features, and (b) `/forge-evolve` prompts the user to
311
308
  review the synthesis and rewrite the slice graph if they want true
312
309
  v5 gate semantics for ongoing work.
313
310
 
314
- `/evolve` shows the synthesized slice graph alongside the v4 task list
311
+ `/forge-evolve` shows the synthesized slice graph alongside the v4 task list
315
312
  and asks: "Accept this synthesis (treat as legacy build), or rewrite as
316
313
  v5 slice graph (re-run gates per slice)?". The default is "accept".
317
314
 
@@ -58,7 +58,7 @@ slice_graph:
58
58
  type: skeleton # skeleton | feature-slice | refactor-slice
59
59
  variant: {skeleton_variant} # backend-server | frontend-spa | cli-tool | library | mobile-app — set during stack selection
60
60
  depends_on: []
61
- status: pending # pending | in-progress | gated | complete | abandoned
61
+ status: pending # pending | in-progress | gated | complete
62
62
  gates:
63
63
  skeleton-runs: { status: pending, gate-passed: false }
64
64
  wiki-lint: { status: pending, gate-passed: false }
@@ -27,7 +27,6 @@ The two blocks are complementary, not redundant. A phase with `phase_plan.X: act
27
27
  | `phase_plan` | (absent) | **required** at top level |
28
28
  | `phases` | required | required (unchanged — still tracks gate state per phase/sub-phase) |
29
29
  | `slice_graph` | required by parser | optional (the v5 SCHEMA already documented this as optional; v6 aligns the parser) |
30
- | `status` enum | `in-progress` \| `paused` \| `completed` \| `escalated` | adds `abandoned` (terminal state recorded by `/abort`; preserves artifacts) |
31
30
  | Everything else | — | unchanged |
32
31
 
33
32
  The `slice_graph` change is a parser fix: v5's SCHEMA §1 listed `slice_graph` as optional but the verifier rejected its absence. v6 manifests can ship without a slice graph — it is populated at codify, not at preflight. v4 and v5 manifests continue to require it (v4 synthesizes one; v5 always shipped one in practice).
@@ -75,17 +74,17 @@ phase_plan:
75
74
 
76
75
  The verifier rejects any other value with `E_BAD_PHASE_PLAN_STATUS`.
77
76
 
78
- ### 3.2 Key naming convention
77
+ ### 3.2 Key naming — strict enum per work type
79
78
 
80
- Keys are free-form strings — the verifier does NOT validate them against any canonical vocabulary. This is intentional: `/bugfix`, `/hotfix`, `/refactor` workflows have different shapes than `/feature` or `/greenfield`, and each command enumerates its own plannable steps.
79
+ Keys are validated against a per-work-type allow-list. An unknown key produces `E_UNKNOWN_PHASE_PLAN_KEY` with a "did you mean?" suggestion when a near-match exists.
81
80
 
82
- **This means typos in keys are silent failures.** A misspelled `prototpe` produces no parse error but breaks any downstream routing that reads `phase_plan.prototype` including the mode-detection signals in `rules/common/skill-selection.md` and command preflight redirects. Treat phase_plan keys as load-bearing identifiers: copy them from the templates exactly, do not invent variants.
81
+ This was a convention through early v6 the verifier accepted any string and a `W_UNKNOWN_PHASE_PLAN_KEY` warning surfaced typos. Dogfood signal (a misspelled `prototpe` parsed fine but broke `rules/common/skill-selection.md`'s mode-detection read of `phase_plan.prototype`) drove the 2026-05-17 promotion to a hard error.
83
82
 
84
- #### Recommended keys per work type
83
+ #### Allowed keys per work type
85
84
 
86
- Commands should use these keys (kebab-case, match the templates verbatim):
85
+ Commands MUST use these keys (kebab-case, match the templates verbatim). The list in `src/work-manifest.ts` (`ALLOWED_PHASE_PLAN_KEYS`) is the source of truth — this table must stay in sync.
87
86
 
88
- | Work type | Recommended `phase_plan` keys |
87
+ | Work type | Allowed `phase_plan` keys |
89
88
  |---|---|
90
89
  | `feature` | `discover-codebase`, `concept`, `wireframe`, `plan-design-system`, `prototype`, `iterate`, `codify`, `worktree`, `production-build`, `test-plan`, `uiux-review`, `code-review-final`, `deliver`, `onboarding`, `gotchas` |
91
90
  | `greenfield` | `discover-requirements`, `concept`, `wireframe`, `plan-design-system`, `prototype`, `iterate`, `codify`, `scaffold`, `production-build`, `test-plan`, `uiux-review`, `code-review-final`, `deliver`, `onboarding`, `gotchas` |
@@ -93,11 +92,16 @@ Commands should use these keys (kebab-case, match the templates verbatim):
93
92
  | `hotfix` | `debug-root-cause`, `production-build`, `smoke-tests`, `code-review-critical`, `deliver`, `gotchas`, `followup-ticket` |
94
93
  | `refactor` | `discover-codebase`, `brainstorm`, `task-decompose`, `production-build`, `test-execution`, `assessment`, `deliver`, `gotchas` |
95
94
 
96
- `plan-design-system` is a workflow-specific gate that runs at Step 4.5 of `/feature` and `/greenfield` (post-wireframe-lock, pre-prototype). It is not in `references/common/phases.md` because it is a step within Phase 3-4 rather than its own canonical phase. Backend-only / CLI work skips it (`status: skipped` with a reason); frontend work uses `status: active`.
95
+ `plan-design-system` is a workflow-specific gate that runs at Step 4.5 of `/feature` and `/greenfield` (post-wireframe-lock, pre-prototype). It is not in `references/common/phases.md` because it is a step within Phases 2-3 rather than its own canonical phase. Backend-only / CLI work skips it (`status: skipped` with a reason); frontend work uses `status: active`.
97
96
 
98
97
  The seven canonical phase names from `references/common/phases.md` (`concept`, `wireframe`, `prototype`, `iterate`, `codify`, `production-build`, `deliver`) MUST match the canonical spelling when used. Other keys are workflow-specific gates or sub-phases.
99
98
 
100
- If real usage shows typos causing failures, harden this from convention to per-type enum validation — the parser knows `manifest.type`, so a per-type allowed-keys map is a single Set lookup.
99
+ #### Adding a new key
100
+
101
+ To extend a workflow with a new phase_plan key:
102
+ 1. Add it to the appropriate `ManifestType` entry in `ALLOWED_PHASE_PLAN_KEYS` (`src/work-manifest.ts`).
103
+ 2. Add it to the table above.
104
+ 3. Update the relevant command's preflight planner so it emits the new key.
101
105
 
102
106
  ### 3.3 gate-passed discipline
103
107
 
@@ -113,7 +117,7 @@ This convention is enforced by skills (they read phase_plan and choose not to se
113
117
 
114
118
  A v5 manifest read by the v6 parser is accepted as-is. The parser returns `schema: 'v5'` and the synthesized in-memory manifest has `phase_plan: undefined`. Tools that need a phase_plan can synthesize a default: every phase in `phases.{block}.{gate}` becomes `phase_plan.{gate}: active`.
115
119
 
116
- `/evolve` (when it lands) will offer to rewrite v5 manifests on-disk into v6 shape, prompting for plan-status per phase. v5 manifests parse forever; no forced migration.
120
+ `/forge-evolve` (when it lands) will offer to rewrite v5 manifests on-disk into v6 shape, prompting for plan-status per phase. v5 manifests parse forever; no forced migration.
117
121
 
118
122
  ---
119
123
 
package/commands/abort.md DELETED
@@ -1,25 +0,0 @@
1
- ---
2
- name: abort
3
- description: "Mark a .forge/work item abandoned without deleting files."
4
- argument-hint: "[type/name] [reason]"
5
- ---
6
-
7
- # /abort — Abandon Work Item
8
-
9
- Mark a work item abandoned while preserving every artifact for audit and future reference.
10
-
11
- ## Scope
12
-
13
- Marks a `.forge/work/` item `status: abandoned` in its manifest. Preserves every artifact — work directory, branches, logs, prototypes, wiki entries — so the abandonment is auditable. Does NOT delete files, close branches, prune the wiki, or reset gate state. Invoke when work is being walked away from (replaced by a different approach, blocked indefinitely, or pivoted) and the user wants the trail kept for future reference.
14
-
15
- ## Input
16
-
17
- Accept `type/name` and an optional reason. If no work item is provided, run `/status` first and ask the user which item to abandon.
18
-
19
- ## Steps
20
-
21
- 1. Read `.forge/work/{type}/{name}/manifest.yaml`.
22
- 2. Confirm with the user before changing status.
23
- 3. Set `status: abandoned`, `abandoned_at: <ISO-8601 UTC timestamp>` (executing agent fills this — e.g. `2026-05-12T15:42:00Z`; not a literal placeholder), and `abandon_reason: {reason}` in the manifest. Preserve all existing phase, gate, and artifact fields.
24
- 4. Do not delete the work directory, branches, logs, prototypes, wiki entries, or any generated artifacts.
25
- 5. Report the manifest path and the reason recorded.