@jamie-tam/forge 6.0.0 → 6.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +77 -59
- package/agents/dreamer.md +10 -7
- package/agents/gotcha-hunter.md +1 -1
- package/agents/prototype-codifier.md +2 -2
- package/commands/{forge.md → discover.md} +13 -9
- package/commands/dream.md +71 -0
- package/commands/feature.md +57 -10
- package/commands/{evolve.md → forge-evolve.md} +3 -3
- package/commands/greenfield.md +5 -5
- package/commands/note.md +64 -0
- package/commands/{task-force.md → parallel.md} +15 -15
- package/commands/resume.md +2 -2
- package/commands/setup.md +18 -17
- package/commands/status.md +2 -2
- package/commands/wrap.md +130 -0
- package/dist/__tests__/hooks.test.js +334 -0
- package/dist/__tests__/init.test.js +110 -0
- package/dist/__tests__/work-manifest.test.js +48 -14
- package/dist/cli.js +0 -0
- package/dist/hooks.js +88 -6
- package/dist/init.js +39 -1
- package/dist/uninstall.js +11 -5
- package/dist/work-manifest.js +63 -24
- package/hooks/config/gate-requirements.json +1 -1
- package/hooks/hooks.json +14 -1
- package/hooks/scripts/gate-enforcer.sh +51 -6
- package/hooks/scripts/pre-compact.sh +120 -55
- package/hooks/scripts/session-start.sh +43 -4
- package/hooks/scripts/telemetry.sh +32 -2
- package/hooks/templates/CLAUDE.md.template +6 -3
- package/package.json +1 -1
- package/references/common/phases.md +8 -6
- package/references/common/skill-authoring.md +1 -1
- package/rules/common/forge-system.md +64 -6
- package/rules/common/quality-gates.md +2 -0
- package/skills/build-prototype/SKILL.md +4 -4
- package/skills/build-tdd/SKILL.md +14 -0
- package/skills/concept-slides/SKILL.md +11 -11
- package/skills/deliver-deploy/SKILL.md +10 -1
- package/skills/harden/SKILL.md +22 -8
- package/skills/iterate-prototype/SKILL.md +22 -0
- package/skills/quality-test-execution/SKILL.md +26 -1
- package/skills/quality-test-plan/SKILL.md +21 -1
- package/skills/support-debug/SKILL.md +1 -1
- package/skills/support-dream/SKILL.md +8 -7
- package/skills/support-gotcha/SKILL.md +3 -3
- package/skills/{support-task-force → support-parallel}/SKILL.md +22 -22
- package/skills/{support-task-force → support-parallel}/references/dispatch-pattern.md +10 -10
- package/skills/{support-task-force → support-parallel}/references/synthesis-template.md +10 -10
- package/skills/support-skill-validator/SKILL.md +5 -5
- package/skills/support-skill-validator/references/validation-checks.md +1 -1
- package/skills/support-system-guide/SKILL.md +4 -3
- package/skills/support-wiki-lint/scripts/lint.mjs +52 -0
- package/templates/README.md +1 -1
- package/templates/aiwiki/CLAUDE.md.template +48 -22
- package/templates/aiwiki/schemas/session.md +134 -49
- package/templates/manifests/bugfix.yaml +1 -1
- package/templates/manifests/feature.yaml +1 -1
- package/templates/manifests/greenfield.yaml +1 -1
- package/templates/manifests/hotfix.yaml +1 -1
- package/templates/manifests/refactor.yaml +1 -1
- package/templates/manifests/v5/SCHEMA.md +14 -17
- package/templates/manifests/v5/feature.yaml +1 -1
- package/templates/manifests/v6/SCHEMA.md +14 -10
- package/commands/abort.md +0 -25
- package/dist/__tests__/active-manifest.test.js +0 -272
- package/dist/__tests__/gate-check.test.js +0 -384
- package/dist/active-manifest.js +0 -229
- package/dist/gate-check.js +0 -326
|
@@ -16,22 +16,20 @@ The wiki is curated to answer recurring questions. **Use it before asking the us
|
|
|
16
16
|
|
|
17
17
|
## Writing
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
- Write an ADR in `aiwiki/decisions/`. Format per `aiwiki/schemas/decision.md`. Invoke `/second-opinion` to get adversarial review before marking `status: accepted`.
|
|
19
|
+
AI writes typed pages directly when the content meets the durability test for that page type. The user can edit or delete any page after the fact. `wiki-lint` (PostToolUse hook) validates schema on every save.
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
-
|
|
21
|
+
| Page type | Trigger | Skill that typically writes it | Adversarial review |
|
|
22
|
+
|---|---|---|---|
|
|
23
|
+
| ADR (`aiwiki/decisions/`) | Hard-to-reverse choice: architectural, public-surface naming (APIs / schemas / file paths users import), security or data-handling tradeoff, schema design, contracts other code depends on | `harden` (Phase 5, with inline adversarial review in each ADR's `review:` block per `aiwiki/schemas/decision.md`), `plan-brainstorm`, manual | Inline in the ADR `review:` block. When Codex is configured (`protocols/codex.md`), `harden` may dispatch Codex in verify mode; otherwise Claude performs the pass directly. |
|
|
24
|
+
| Gotcha (`aiwiki/gotchas/`) | Reproducible failure mode with a concrete fix | `support-gotcha`, `support-debug` (after closing a non-trivial bug) | None — gotchas are facts, not opinions. The `occurrences: 3+` auto-promotion path adds a `proposed_rule:` block and the next session-start hard-interrupts for user approval before the rule ships. |
|
|
25
|
+
| Convention (`aiwiki/conventions/`) | Pattern established across 2+ sites in this codebase | `iterate-prototype` (during Phase 4), `harden` (codify-time), manual | None — wiki-lint enforces schema; user reviews on read. |
|
|
26
|
+
| Architecture (`aiwiki/architecture/{topic}.md`) | System-shape change: new subsystem, new boundary, new contract between components. One file per topic — do NOT collapse multiple subsystems into a single mega-file. | `harden` (Phase 5), manual | None directly, but `harden` Step 2 runs adversarial review on any ADRs that drive the architecture write. |
|
|
27
|
+
| Oracle (`aiwiki/oracles/{slug}.md`) | Prototype behavior snapshot (setup → trigger → assertions) that Phase 6 production code must reproduce | `harden` Step 2.5 | None — oracles are observation of the prototype, not opinion. Tests in Phase 6 are written against the oracle. |
|
|
28
|
+
| Session (`aiwiki/sessions/{date}-{session_id_short}.md`) | First in-session writer creates the file lazily | `pre-compact.sh` (Checkpoints), `/wrap` (index sections), `harden` (codify-time session entry) | `/wrap` confirms content with user before setting `status: done`. |
|
|
25
29
|
|
|
26
|
-
|
|
27
|
-
- Write to `aiwiki/conventions/`. Format per `aiwiki/schemas/convention.md`.
|
|
30
|
+
**Raw (`aiwiki/raw/`) is user-gated.** Half-formed thoughts, research notes, deferred decisions, comparison sketches — these go to raw ONLY via `/note <text>`. The AI does not autonomously decide to write conversational content to raw; the user is the gate.
|
|
28
31
|
|
|
29
|
-
When
|
|
30
|
-
- Write to `aiwiki/architecture/{topic}.md`. Format per `aiwiki/schemas/architecture.md`.
|
|
31
|
-
- One file per topic — do NOT collapse multiple subsystems into a single mega-file.
|
|
32
|
-
|
|
33
|
-
When unsure where something belongs:
|
|
34
|
-
- Write to `aiwiki/raw/{YYYY-MM-DD}-{slug}.md`. Phase-close dream consolidates raw entries into typed pages.
|
|
32
|
+
When durability is uncertain (e.g. "is this a real gotcha or just a one-off?"), ask the user instead of speculating into a typed page. Speculation in `aiwiki/decisions/` poisons future retrieval more than the missing entry costs.
|
|
35
33
|
|
|
36
34
|
## Citations
|
|
37
35
|
|
|
@@ -46,12 +44,33 @@ When the cited code moves, LINT flags the citation as stale on the next wiki wri
|
|
|
46
44
|
|
|
47
45
|
The wiki is consolidated periodically by **dream** (forge's wiki-consolidation mechanism — see `support-dream` skill). Dream output goes to `aiwiki/proposed/{dream_id}/` and is **never auto-applied** to `aiwiki/`.
|
|
48
46
|
|
|
47
|
+
**Dream triggers:**
|
|
48
|
+
- **Manual** — `/dream [scope]` slash command. User-driven cleanup.
|
|
49
|
+
- **PreCompact (~85% context)** — `hooks/scripts/pre-compact.sh` appends a `**Dream directive (unconsumed)**` block to the active session file's `## Checkpoints` section (`aiwiki/sessions/{date}-{session_id_short}.md`, created lazily on first fire). The post-compact agent reads the session file, finds the directive, and invokes `support-dream`. Skipped when `aiwiki/` has no recent (last 24h) activity.
|
|
50
|
+
- **Phase-close** — the phase-locking skills (`iterate-prototype` on prototype-lock, `harden` on codify-lock, `feature.md` Step 8.5 per-slice on slice gate-pass, `deliver-deploy` on deliver-lock) dispatch `support-dream` immediately after writing their `artifacts.{phase}.locked_at`.
|
|
51
|
+
|
|
49
52
|
When pending dreams exist:
|
|
50
53
|
- Run `forge wiki status` to see the queue
|
|
51
|
-
- Run `forge wiki
|
|
54
|
+
- Run `forge wiki ui` to open the local web review at 127.0.0.1:8765, OR
|
|
55
|
+
- Run `forge wiki review [dream_id]` to step through per-page diffs in the terminal
|
|
52
56
|
- Run `forge wiki accept [dream_id]` or `forge wiki reject [dream_id] --reason "..."` to resolve
|
|
53
57
|
|
|
54
|
-
|
|
58
|
+
**Phase-close dreams hard-block the next phase** (iterate→codify, codify→production-build, all-slices-pass→deliver close). Per-slice dreams do not block — they're reviewed in bulk before Phase 7. PreCompact dreams do not block compaction; the proposal is durable on disk and you review whenever convenient.
|
|
59
|
+
|
|
60
|
+
## Session handoff (`aiwiki/sessions/`)
|
|
61
|
+
|
|
62
|
+
Each Claude session can produce a handoff file at `aiwiki/sessions/{date}-{session_id_short}.md`. Two writers populate different parts:
|
|
63
|
+
|
|
64
|
+
| Section | Writer | Style |
|
|
65
|
+
|---|---|---|
|
|
66
|
+
| `## Checkpoints` | `hooks/scripts/pre-compact.sh`, `support-dream` skill | Append-only event log. PreCompact events with recovery directives. |
|
|
67
|
+
| `## Files touched` / `## Decisions made` / `## Gotchas surfaced` / `## Open questions` / `## Next steps` | `/wrap` command | Index of links. Curated by the agent, confirmed by the user. |
|
|
68
|
+
|
|
69
|
+
**Lazy creation.** The file is NOT created at SessionStart (that would produce empty noise for trivial 30-second sessions). The first writer in the session creates it.
|
|
70
|
+
|
|
71
|
+
**`/wrap` to finalize.** Run `/wrap` at the natural end of a working session to fill the index sections and set `status: done`. This is the single most useful thing for next-session continuity — the SessionStart hook surfaces the latest session's focus and any unconsumed checkpoints.
|
|
72
|
+
|
|
73
|
+
**Active dream directives.** If a `## Checkpoints` entry has a header `**Dream directive (unconsumed):**`, it's an action item for the current agent (typically: invoke `support-dream`). After acting, change the entry's header from `**Dream directive (unconsumed):**` to `**Dream directive (consumed at {ISO-timestamp}):**`. The `session-start.sh` hook counts active directives by matching `(unconsumed):` literally — flipping the header is what makes the count accurate.
|
|
55
74
|
|
|
56
75
|
## Phase vocabulary
|
|
57
76
|
|
|
@@ -59,15 +78,22 @@ When a skill or agent states its phase context, the canonical numbering and name
|
|
|
59
78
|
|
|
60
79
|
## Rules and references — what applies when
|
|
61
80
|
|
|
62
|
-
Forge
|
|
81
|
+
Forge ships 8 common rules in `.claude/rules/common/`. Seven auto-load every session; one (`testing.md`) is paths-conditional via frontmatter `paths:` and loads only when an editor touches test files or source code in `src/`.
|
|
63
82
|
|
|
64
|
-
|
|
|
83
|
+
| Rule | Loading | Purpose |
|
|
65
84
|
|---|---|---|
|
|
66
|
-
|
|
|
67
|
-
|
|
|
68
|
-
|
|
|
69
|
-
|
|
70
|
-
|
|
85
|
+
| `forge-system.md` | Always-on | This file. Forge directory layout, aiwiki layer, dream + session-handoff mechanics. |
|
|
86
|
+
| `security.md` | Always-on | Injection, secret handling, auth/data-handling — safety floor. |
|
|
87
|
+
| `guardrails.md` | Always-on | Destructive-action gates, force-push refusals, sandbox boundaries. |
|
|
88
|
+
| `verification.md` | Always-on | Don't claim "done" without proof; verify completion before reporting. |
|
|
89
|
+
| `skill-selection.md` | Always-on | Routing logic: which skill fits a request given phase/scope/manifest state. |
|
|
90
|
+
| `quality-gates.md` | Always-on | Gate-state vocabulary + the per-gate pass criteria summary. |
|
|
91
|
+
| `git-workflow.md` | Always-on | Conventional Commits, bisectable commits, branch naming, hook-respect. |
|
|
92
|
+
| `testing.md` | Paths-conditional | TDD discipline (RED-GREEN-REFACTOR), coverage targets, mocking strategy. Loads only when editing test files or `src/` code. |
|
|
93
|
+
|
|
94
|
+
**References load on demand**, not automatically. `.claude/references/common/coding-standards.md` and language-specific standards (`typescript/`, `python/`, `react/`) are read by the `harden` skill, the `prototype-codifier` agent, and `quality-code-review`'s craft pass — when those subagents/skills choose to consult them. During prototype iteration (Phases 1-4), references are unread by default.
|
|
95
|
+
|
|
96
|
+
**The original v6 design** floated a phase-conditional loading tier (testing/quality-gates/git-workflow load only from Phase 5 onward). That was rejected after second-opinion review: the safety-floor + paths-conditional model above is what actually ships. Prototype iteration speed comes from skill-level discipline (e.g. `iterate-prototype` doesn't dispatch full code-review chains) rather than from suppressing always-on rules.
|
|
71
97
|
|
|
72
98
|
## Forbidden
|
|
73
99
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
schema_id: session
|
|
3
|
-
schema_version:
|
|
3
|
+
schema_version: 2
|
|
4
4
|
applies_to: aiwiki/sessions/**/*.md
|
|
5
|
-
filename_pattern: "{date}-{
|
|
6
|
-
hard_cap_lines:
|
|
7
|
-
soft_target_lines: [40,
|
|
5
|
+
filename_pattern: "{date}-{session_id_short}.md"
|
|
6
|
+
hard_cap_lines: 400
|
|
7
|
+
soft_target_lines: [40, 200]
|
|
8
8
|
required_frontmatter:
|
|
9
9
|
schema_id: { type: string, equals: session }
|
|
10
10
|
schema_version: { type: integer }
|
|
@@ -12,80 +12,142 @@ required_frontmatter:
|
|
|
12
12
|
date_start: { type: date }
|
|
13
13
|
date_end: { type: date, optional: true }
|
|
14
14
|
focus: { type: string }
|
|
15
|
+
session_id: { type: string, optional: true }
|
|
15
16
|
last_commit: { type: string, optional: true }
|
|
16
|
-
required_sections:
|
|
17
|
+
required_sections: []
|
|
18
|
+
optional_sections:
|
|
19
|
+
- "## Checkpoints"
|
|
17
20
|
- "## Files touched"
|
|
18
21
|
- "## Decisions made"
|
|
19
22
|
- "## Gotchas surfaced"
|
|
20
23
|
- "## Open questions"
|
|
21
24
|
- "## Next steps"
|
|
22
25
|
section_order: strict
|
|
23
|
-
citation_rule: required-in-files-touched
|
|
24
|
-
maintained_by:
|
|
26
|
+
citation_rule: required-in-files-touched-when-present
|
|
27
|
+
maintained_by: lazy-on-first-event
|
|
25
28
|
---
|
|
26
29
|
|
|
27
30
|
# Schema: session (per-session handoff)
|
|
28
31
|
|
|
29
32
|
## Purpose
|
|
30
33
|
|
|
31
|
-
A session file is
|
|
34
|
+
A session file is the **handoff artifact** for one Claude session — what events fired during the session (PreCompact, /dream, /wrap) and what knowledge the session produced (files touched, decisions, gotchas, open questions, next steps). The page answers two questions for a future session:
|
|
32
35
|
|
|
33
|
-
**
|
|
36
|
+
1. **What is the immediate recovery state?** — read `## Checkpoints` for in-session events the post-compact agent (or next session) needs to act on.
|
|
37
|
+
2. **What happened and where do I pick up?** — read the index-of-links sections (`## Files touched`, `## Decisions made`, etc.).
|
|
34
38
|
|
|
35
|
-
|
|
39
|
+
**Two patterns mixed in one file by design:**
|
|
36
40
|
|
|
37
|
-
|
|
41
|
+
- `## Checkpoints` is **event-log style** (append-only, chronological). Pre-compact and other hook-driven events write here. Each entry is timestamped and may include a recovery directive that the next agent should act on.
|
|
42
|
+
- The other sections are **index of links** (curated, written by `/wrap` or `harden`). No prose paragraphs, no narrative — just links to ADRs, gotchas, raw notes. Future sessions follow the links to the actual artifacts.
|
|
38
43
|
|
|
39
|
-
|
|
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`
|
|
44
|
+
## How it's maintained
|
|
43
45
|
|
|
44
|
-
|
|
46
|
+
**Lazy creation.** Session files are NOT created at SessionStart (that would produce empty noise for trivial 30-second sessions). Instead, the first writer creates the file:
|
|
47
|
+
|
|
48
|
+
| Writer | Triggers create? | Section written |
|
|
49
|
+
|---|---|---|
|
|
50
|
+
| `hooks/scripts/pre-compact.sh` | yes | `## Checkpoints` (appends event with recovery directive) |
|
|
51
|
+
| `/wrap` command | yes | `## Files touched`, `## Decisions made`, `## Gotchas surfaced`, `## Open questions`, `## Next steps` (filled by agent, user confirms) |
|
|
52
|
+
| `support-dream` skill | yes | `## Checkpoints` (appends dream-fired event with `dream_id`) |
|
|
53
|
+
| `harden` skill (Phase 5) | yes | All sections (codify-time session capture, similar to /wrap) |
|
|
54
|
+
|
|
55
|
+
`SessionStart` does NOT create the file — it READS the latest existing session file and surfaces a one-line summary to the agent, plus any unconsumed `## Checkpoints` directives.
|
|
45
56
|
|
|
46
57
|
## File location and naming
|
|
47
58
|
|
|
48
|
-
- Path: `aiwiki/sessions/{date}-{
|
|
49
|
-
- Date: ISO format (`YYYY-MM-DD`)
|
|
50
|
-
-
|
|
59
|
+
- Path: `aiwiki/sessions/{date}-{session_id_short}.md`
|
|
60
|
+
- Date: ISO format (`YYYY-MM-DD`) — date the session STARTED
|
|
61
|
+
- `session_id_short`: first 7 hex chars of Claude Code's session UUID (read from the hook payload on stdin). Functions like a git sha7 — short enough for filenames, long enough to disambiguate.
|
|
51
62
|
|
|
52
|
-
Examples: `2026-05-
|
|
63
|
+
Examples: `2026-05-18-7e8a3f2.md`, `2026-05-19-a1b2c3d.md`.
|
|
53
64
|
|
|
54
|
-
|
|
65
|
+
If multiple sessions start on the same date, the short-id keeps them distinct. If a session spans a date boundary (rare — sessions don't usually run >24h), the date_end frontmatter captures it.
|
|
66
|
+
|
|
67
|
+
The companion file `aiwiki/sessions/INDEX.md` (if present) is a sortable table of sessions; dream's session-refinement step appends a row when consolidating.
|
|
55
68
|
|
|
56
69
|
## Required frontmatter
|
|
57
70
|
|
|
58
71
|
| Field | Type | Notes |
|
|
59
72
|
|---|---|---|
|
|
60
73
|
| `schema_id` | string | Must equal `session` |
|
|
61
|
-
| `schema_version` | integer |
|
|
62
|
-
| `status` | enum | `active` (in progress) / `done` (handed off) / `abandoned` (orphaned) |
|
|
63
|
-
| `date_start` | ISO date | When
|
|
64
|
-
| `date_end` | ISO date (optional) | When SessionEnd
|
|
65
|
-
| `focus` | string | What this session is about
|
|
74
|
+
| `schema_version` | integer | `2` (was `1` in v6.1.0; v2 adds `session_id` field and `## Checkpoints` section) |
|
|
75
|
+
| `status` | enum | `active` (in progress) / `done` (handed off via /wrap) / `abandoned` (orphaned — pruned by dream) |
|
|
76
|
+
| `date_start` | ISO date | When the session began (first event triggered file creation) |
|
|
77
|
+
| `date_end` | ISO date (optional) | When /wrap fired or SessionEnd hook closed the file; null while active |
|
|
78
|
+
| `focus` | string | What this session is about — initially "unset" if file was created by pre-compact before /wrap fired; updated by /wrap |
|
|
79
|
+
| `session_id` | string (optional) | Full Claude session UUID. Pre-compact writes the short form into the filename; the full ID lives here for traceability. |
|
|
66
80
|
| `last_commit` | string (optional) | SHA of the last commit during this session |
|
|
67
81
|
|
|
68
|
-
##
|
|
82
|
+
## Optional sections
|
|
83
|
+
|
|
84
|
+
All sections are optional individually; at least one must be present (an empty session file is meaningless).
|
|
69
85
|
|
|
70
|
-
| Section |
|
|
86
|
+
| Section | Style | Writer |
|
|
71
87
|
|---|---|---|
|
|
72
|
-
| `##
|
|
73
|
-
| `##
|
|
74
|
-
| `##
|
|
75
|
-
| `##
|
|
76
|
-
| `##
|
|
88
|
+
| `## Checkpoints` | Event log (append-only) | `pre-compact.sh`, `support-dream` skill |
|
|
89
|
+
| `## Files touched` | Index of links (with citations) | `/wrap`, `harden` |
|
|
90
|
+
| `## Decisions made` | Index of links to ADRs | `/wrap`, `harden` |
|
|
91
|
+
| `## Gotchas surfaced` | Index of links to gotchas | `/wrap`, `harden` |
|
|
92
|
+
| `## Open questions` | Index of links to raw notes | `/wrap`, `harden` |
|
|
93
|
+
| `## Next steps` | Bullet list | `/wrap`; dream refines |
|
|
77
94
|
|
|
78
|
-
|
|
95
|
+
If `## Checkpoints` is present, it MUST be first (before the index sections).
|
|
96
|
+
|
|
97
|
+
## Section: ## Checkpoints (event log)
|
|
98
|
+
|
|
99
|
+
Append-only chronological list of in-session events. Each entry is a `###` subsection.
|
|
100
|
+
|
|
101
|
+
**Entry shape:**
|
|
102
|
+
|
|
103
|
+
```markdown
|
|
104
|
+
### PreCompact at 2026-05-18T14:23:00Z
|
|
105
|
+
|
|
106
|
+
Active work: feature/wire-dream
|
|
107
|
+
Manifest: .forge/work/feature/wire-dream/manifest.yaml
|
|
108
|
+
|
|
109
|
+
Phase status (from manifest):
|
|
110
|
+
```yaml
|
|
111
|
+
status: in-progress
|
|
112
|
+
artifacts.prototype.locked_at: 2026-05-17T11:00:00Z
|
|
113
|
+
artifacts.codify.locked_at: ~
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**Dream directive (unconsumed):**
|
|
117
|
+
|
|
118
|
+
- Scope: `aiwiki/raw/`, recently-touched typed pages
|
|
119
|
+
- Trigger: pre-compact, context ~85%
|
|
120
|
+
- Action: invoke `support-dream` skill before resuming other work
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
```
|
|
79
124
|
|
|
80
|
-
-
|
|
81
|
-
- Soft target: 40-100 lines
|
|
125
|
+
**Marking consumed.** After the agent acts on a `Dream directive (unconsumed)` entry, it changes the entry's bold-header from `**Dream directive (unconsumed):**` to `**Dream directive (consumed at {ISO-timestamp}):**`. The `session-start.sh` hook counts active directives by matching the exact `(unconsumed):` header — flipping the header is what makes the count accurate. Appending a separate "Status: consumed" line is wrong because it leaves the unconsumed-marked header still grep-matchable; the next session-start will surface the directive as a HARD-INTERRUPT again (dogfood-validated 2026-05-18).
|
|
82
126
|
|
|
83
|
-
|
|
127
|
+
## Section: ## Files touched (index of links)
|
|
128
|
+
|
|
129
|
+
Bullet list. Each entry cites the file with `file:line@<sha7>` (or `path` if file-level). LINT auto-fills `@<sha7>` on first save.
|
|
130
|
+
|
|
131
|
+
## Sections: ## Decisions made / ## Gotchas surfaced / ## Open questions
|
|
132
|
+
|
|
133
|
+
Bullet lists. Each entry is a link to a typed wiki page (ADR, gotcha, raw note). No `@<sha7>` needed for wiki-internal links.
|
|
134
|
+
|
|
135
|
+
## Section: ## Next steps
|
|
136
|
+
|
|
137
|
+
Bullet list. What the next session should do. Dream's session-refinement step (if it runs) may rewrite this section as it learns more about the work's state.
|
|
138
|
+
|
|
139
|
+
## Line caps
|
|
140
|
+
|
|
141
|
+
- Hard cap: 400 lines (raised from 200 in v1; `## Checkpoints` event log grows over a long session)
|
|
142
|
+
- Soft target: 40-200 lines
|
|
143
|
+
- A session file >200 lines that hasn't been touched by /wrap is probably pre-compact-heavy and ready for /wrap consolidation
|
|
144
|
+
- A session file >400 lines fails LINT — run `/wrap` to consolidate, OR `/dream` to refine the file
|
|
84
145
|
|
|
85
146
|
## Citation rules
|
|
86
147
|
|
|
87
|
-
- `## Files touched
|
|
148
|
+
- `## Files touched`: each line MUST cite `file:line@<sha7>` (or `path`)
|
|
88
149
|
- Other sections link to typed wiki pages (no `@<sha7>` needed for wiki-internal links)
|
|
150
|
+
- `## Checkpoints` entries don't require citations — they're event records, not knowledge claims
|
|
89
151
|
- LINT auto-fills missing code citations on first save
|
|
90
152
|
|
|
91
153
|
## Skeleton
|
|
@@ -93,33 +155,56 @@ A session file that grows past 100 lines without dream consolidation usually mea
|
|
|
93
155
|
```markdown
|
|
94
156
|
---
|
|
95
157
|
schema_id: session
|
|
96
|
-
schema_version:
|
|
158
|
+
schema_version: 2
|
|
97
159
|
status: active
|
|
98
|
-
date_start: 2026-05-
|
|
99
|
-
|
|
160
|
+
date_start: 2026-05-18
|
|
161
|
+
session_id: 7e8a3f2-9a4b-4c8d-b1e2-f5a6c7d8e9f0
|
|
162
|
+
focus: unset
|
|
100
163
|
last_commit: ~
|
|
101
164
|
---
|
|
102
165
|
|
|
166
|
+
## Checkpoints
|
|
167
|
+
|
|
168
|
+
### PreCompact at 2026-05-18T14:23:00Z
|
|
169
|
+
|
|
170
|
+
Active work: feature/wire-dream
|
|
171
|
+
Manifest: .forge/work/feature/wire-dream/manifest.yaml
|
|
172
|
+
|
|
173
|
+
Phase status (from manifest):
|
|
174
|
+
```yaml
|
|
175
|
+
status: in-progress
|
|
176
|
+
artifacts.prototype.locked_at: 2026-05-17T11:00:00Z
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**Dream directive (unconsumed):**
|
|
180
|
+
- Scope: `aiwiki/raw/`, recently-touched typed pages
|
|
181
|
+
- Trigger: pre-compact, context ~85%
|
|
182
|
+
- Action: invoke `support-dream` skill before resuming other work
|
|
183
|
+
- Status: unconsumed
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
103
187
|
## Files touched
|
|
104
188
|
|
|
105
|
-
|
|
106
|
-
- [src/auth/token.ts](src/auth/token.ts)
|
|
107
|
-
- [src/auth/middleware.ts:1-42@a3f2bc1](src/auth/middleware.ts)
|
|
189
|
+
(filled by /wrap)
|
|
108
190
|
|
|
109
191
|
## Decisions made
|
|
110
192
|
|
|
111
|
-
|
|
193
|
+
(filled by /wrap)
|
|
112
194
|
|
|
113
195
|
## Gotchas surfaced
|
|
114
196
|
|
|
115
|
-
|
|
197
|
+
(filled by /wrap)
|
|
116
198
|
|
|
117
199
|
## Open questions
|
|
118
200
|
|
|
119
|
-
|
|
201
|
+
(filled by /wrap)
|
|
120
202
|
|
|
121
203
|
## Next steps
|
|
122
204
|
|
|
123
|
-
|
|
124
|
-
- Update [aiwiki/architecture/auth-flow.md](aiwiki/architecture/auth-flow.md) once rotation lands
|
|
205
|
+
(filled by /wrap)
|
|
125
206
|
```
|
|
207
|
+
|
|
208
|
+
## Migration from v1
|
|
209
|
+
|
|
210
|
+
v1 session files (no `## Checkpoints`, no `session_id`) parse cleanly under v2 (all v2 sections are optional). LINT will surface "no `session_id`" as advisory, not blocking. Manual migration: add `session_id: ~` to frontmatter and bump `schema_version: 2`; or just leave v1 files and let dream consolidate them at next refinement pass.
|
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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`
|
|
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
|
|
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`
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
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.
|
|
142
|
-
|
|
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`
|
|
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`.
|
|
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
|
|
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
|
|
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
|
|
77
|
+
### 3.2 Key naming — strict enum per work type
|
|
79
78
|
|
|
80
|
-
Keys are
|
|
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
|
-
|
|
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
|
-
####
|
|
83
|
+
#### Allowed keys per work type
|
|
85
84
|
|
|
86
|
-
Commands
|
|
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 |
|
|
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
|
|
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
|
-
|
|
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.
|