forge-orkes 0.10.0 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/template/.claude/skills/discussing/SKILL.md +12 -2
- package/template/.claude/skills/forge/SKILL.md +34 -1
- package/template/.claude/skills/planning/SKILL.md +28 -2
- package/template/.claude/skills/reviewing/SKILL.md +18 -6
- package/template/.forge/migrations/0.10.0-per-milestone-requirements.md +2 -0
- package/template/.forge/templates/state/milestone.yml +1 -0
- package/template/CLAUDE.md +1 -1
package/package.json
CHANGED
|
@@ -27,6 +27,8 @@ Structured conversation: approach, trade-offs, decisions. Clarity, not artifacts
|
|
|
27
27
|
> Write to `.forge/context.md` after EVERY confirmed decision, before asking the next question.
|
|
28
28
|
> If you reach convergence without having written each decision individually — you already violated this rule.
|
|
29
29
|
|
|
30
|
+
> **Advisory mode (no milestone yet):** Storage still exists. Use `### M? — {topic} (drafting)` heading. Do NOT wait for milestone creation in Step A to start writing. First decision → create heading → append. Same protocol as milestone-bound discussions.
|
|
31
|
+
|
|
30
32
|
After each user response that confirms a decision:
|
|
31
33
|
|
|
32
34
|
1. **STOP** — do not continue the discussion
|
|
@@ -96,12 +98,14 @@ options:
|
|
|
96
98
|
If fresh (after `/clear`):
|
|
97
99
|
|
|
98
100
|
```
|
|
99
|
-
Read: .forge/state/milestone-{id}.yml → current position, progress
|
|
101
|
+
Read: .forge/state/milestone-{id}.yml → current position, progress (skip if no milestone — advisory mode)
|
|
100
102
|
Read: .forge/project.yml → tech stack, project description
|
|
101
103
|
Read: .forge/context.md → existing locked decisions (if exists)
|
|
102
104
|
Read: .forge/constitution.md → active gates (if exists)
|
|
103
105
|
```
|
|
104
106
|
|
|
107
|
+
**Advisory mode (no milestone):** Skip milestone state load. Progressive persistence still applies — writes go to `.forge/context.md` under `### M? — {topic} (drafting)` heading from the first decision. Milestone gets created in Step A only if scope warrants it.
|
|
108
|
+
|
|
105
109
|
Check `.forge/phases/` for research. If inline-only: *"Summarize findings, or re-scan?"*
|
|
106
110
|
|
|
107
111
|
### Step 1: Present Decisions with AskUserQuestion
|
|
@@ -306,6 +310,12 @@ If milestone exists → skip to Step B.
|
|
|
306
310
|
|
|
307
311
|
### Step B: Standard Handoff
|
|
308
312
|
|
|
313
|
+
> **HARD GATE — VERIFY BEFORE HANDOFF.**
|
|
314
|
+
> Read `.forge/context.md` now. Count decisions under the active milestone heading. Compare against decisions confirmed in this conversation.
|
|
315
|
+
> - **If counts match** → proceed to handoff steps below.
|
|
316
|
+
> - **If file is missing, heading absent, or decisions undercount** → progressive persistence failed. STOP. Do NOT recommend `/clear`. Write the missing decisions now from conversation memory, then re-verify. Only then proceed.
|
|
317
|
+
> - **Never claim "state written" without having just read the file.** The recommendation `/clear` is destructive to working memory — earn it.
|
|
318
|
+
|
|
309
319
|
1. **Promote decisions in `context.md`** -- Rename milestone heading from `(drafting)` → `(locked {date})`. Decisions already written progressively — just finalize:
|
|
310
320
|
- Verify all confirmed decisions present under `## Locked Decisions`
|
|
311
321
|
- Verify deferred items under `## Deferred Ideas`
|
|
@@ -313,4 +323,4 @@ If milestone exists → skip to Step B.
|
|
|
313
323
|
- Add any unresolved items to `## Needs Resolution`
|
|
314
324
|
- If `context.md` already exists (post-planning discussion), update relevant sections + log amendments
|
|
315
325
|
2. **Update state** -- `current.status` = `planning` (`architecting` for Full) in milestone yml
|
|
316
|
-
3. **Recommend clear:** *"State written. `/clear` then `/forge` for {planning/architecting}."*
|
|
326
|
+
3. **Recommend clear:** *"State written and verified ({N} decisions in context.md). `/clear` then `/forge` for {planning/architecting}."*
|
|
@@ -37,7 +37,40 @@ Read `.forge/context.md`. **Needs Resolution** unchecked → warn: *"{N} unresol
|
|
|
37
37
|
|
|
38
38
|
Check `.forge/refactor-backlog.yml`:
|
|
39
39
|
- *"{N} refactors ({Q} quick, {S} standard). Tackle first?"*
|
|
40
|
-
- Pick →
|
|
40
|
+
- Pick item → branch on `effort`:
|
|
41
|
+
- `effort: quick` → `quick-tasking`, set `status: in_progress`. Unchanged.
|
|
42
|
+
- `effort: standard` → **Promote to milestone** (procedure below), then fall through to Step 3 Standard routing.
|
|
43
|
+
- Decline → proceed.
|
|
44
|
+
|
|
45
|
+
**Promotion procedure (effort: standard only):**
|
|
46
|
+
|
|
47
|
+
1. Read backlog item `id` (e.g. `R61-002`). Synthesize milestone id `m-{R-id}` (e.g. `m-R61-002`).
|
|
48
|
+
2. Copy `.forge/templates/state/milestone.yml` → `.forge/state/milestone-{m-R-id}.yml`. Populate:
|
|
49
|
+
- `milestone.id: m-{R-id}`
|
|
50
|
+
- `milestone.name: "Promoted from {R-id}: {backlog item title}"`
|
|
51
|
+
- `milestone.origin: {R-id}`
|
|
52
|
+
- `current.tier: standard`, `current.status: researching`
|
|
53
|
+
- `progress.last_update: {ISO date}`
|
|
54
|
+
3. Append to `.forge/state/index.yml` `milestones:`:
|
|
55
|
+
```yaml
|
|
56
|
+
- id: m-{R-id}
|
|
57
|
+
name: "Promoted from {R-id}: {title}"
|
|
58
|
+
status: active
|
|
59
|
+
last_updated: "{ISO date}"
|
|
60
|
+
```
|
|
61
|
+
4. Append to `.forge/roadmap.yml` — one milestone entry + one phase (`refactor-{R-id}`, `requirements_source: refactor-backlog.yml#{R-id}`, `dependencies: []`).
|
|
62
|
+
5. Update `.forge/refactor-backlog.yml` item: `status: in_progress`, add `promoted_to: m-{R-id}`.
|
|
63
|
+
6. Confirm: *"Promoted {R-id} → milestone m-{R-id}. State + roadmap created. Routing to researching."*
|
|
64
|
+
|
|
65
|
+
```text
|
|
66
|
+
backlog pickup → effort: standard
|
|
67
|
+
├─ write milestone-{m-R-id}.yml (origin: {R-id})
|
|
68
|
+
├─ append index.yml + roadmap.yml
|
|
69
|
+
├─ flip backlog item (in_progress + promoted_to)
|
|
70
|
+
└─ fall through → Standard tier routing
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Downstream skills (researching, discussing, planning, executing, verifying, reviewing) see a normal milestone — no special branching.
|
|
41
74
|
|
|
42
75
|
Check `desire_paths` 3+ occurrences:
|
|
43
76
|
- *"Recurring: [{description}] ({N}x). Fix via [suggestion]?"*
|
|
@@ -57,15 +57,41 @@ If missing, create from `.forge/templates/requirements.yml`:
|
|
|
57
57
|
|
|
58
58
|
Never write to top-level `.forge/requirements.yml` -- that path is deprecated.
|
|
59
59
|
|
|
60
|
-
## Step 5: Create Roadmap
|
|
60
|
+
## Step 5: Create or Update Roadmap
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
`.forge/roadmap.yml` is **multi-milestone by design** -- see `.forge/templates/roadmap.yml`. Top-level `milestones:` lists each milestone with its phase numbers; top-level `phases:` lists every phase. Phase IDs are scoped per-milestone via the dir naming `m{milestone_id}-{phase_num}-{name}/`, so phase `id: 1` can exist in m50 and m51 without collision.
|
|
63
|
+
|
|
64
|
+
**Never overwrite existing roadmap content.** Read first, then route on three cases:
|
|
65
|
+
|
|
66
|
+
### Case A: `roadmap.yml` missing (Full only)
|
|
67
|
+
|
|
68
|
+
Create from `.forge/templates/roadmap.yml`:
|
|
63
69
|
1. Group by delivery boundaries
|
|
64
70
|
2. Inter-group dependencies
|
|
65
71
|
3. Phases (coherent, verifiable)
|
|
66
72
|
4. Every FR -> one phase, no orphans
|
|
67
73
|
5. Waves: independent=1, dependent=2+
|
|
68
74
|
|
|
75
|
+
### Case B: `roadmap.yml` exists, current milestone already in it
|
|
76
|
+
|
|
77
|
+
Verify the milestone entry under `milestones:` and its phases under `phases:` are present and consistent with `requirements/m{N}.yml`. Update phase entries in place if requirements changed. Do not touch other milestones.
|
|
78
|
+
|
|
79
|
+
### Case C: `roadmap.yml` exists, current milestone NOT in it (append)
|
|
80
|
+
|
|
81
|
+
This is the common case when starting a new milestone alongside an existing one. Do not fork the file, do not create per-milestone roadmap files, do not overwrite.
|
|
82
|
+
|
|
83
|
+
1. Append a new entry under `roadmap.milestones:`:
|
|
84
|
+
```yaml
|
|
85
|
+
- id: {N}
|
|
86
|
+
name: "{milestone name from state/milestone-{N}.yml}"
|
|
87
|
+
phases: [{list of phase ids you are about to add}]
|
|
88
|
+
```
|
|
89
|
+
2. Append each new phase under `roadmap.phases:` with IDs scoped to this milestone (start at `1`, ignore IDs used by other milestones -- dir naming prevents collision).
|
|
90
|
+
3. Recompute `coverage_verified` against the union of all active milestones' `requirements/m{N}.yml` files. Every FR-ID in the active milestone must map to exactly one phase in that milestone.
|
|
91
|
+
4. Update `waves:` only with the new milestone's phase wave assignments. Leave other milestones' wave entries alone.
|
|
92
|
+
|
|
93
|
+
If a sibling milestone (e.g. m50) has state + requirements but is missing from `roadmap.yml`, that's a pre-existing gap -- flag to user, don't silently backfill.
|
|
94
|
+
|
|
69
95
|
## Step 6: Decompose Tasks
|
|
70
96
|
|
|
71
97
|
Per phase (or feature, Standard tier):
|
|
@@ -304,16 +304,28 @@ Report = audit trail.
|
|
|
304
304
|
## Backlog Lifecycle
|
|
305
305
|
|
|
306
306
|
```
|
|
307
|
-
pending → in_progress →
|
|
308
|
-
pending →
|
|
307
|
+
pending → in_progress → resolved
|
|
308
|
+
pending → wontfix (during triage or later)
|
|
309
309
|
```
|
|
310
310
|
|
|
311
|
-
`quick` -> `quick-tasking`. `standard` ->
|
|
311
|
+
`quick` -> `quick-tasking`. `standard` -> promoted to milestone via `forge` Step 1.2.
|
|
312
312
|
|
|
313
|
-
`forge` surfaces -> user selects -> route by effort -> `status:
|
|
313
|
+
`forge` surfaces -> user selects -> route by effort -> on completion, `status: resolved` + date.
|
|
314
|
+
|
|
315
|
+
Legacy items may use `done`/`dismissed` — both still readable; new transitions use `resolved`/`wontfix`.
|
|
316
|
+
|
|
317
|
+
## Promoted Milestone Completion Hook
|
|
318
|
+
|
|
319
|
+
If the milestone being completed has `milestone.origin: {R-id}` set (promoted from refactor-backlog), flip the originating item before exit:
|
|
320
|
+
|
|
321
|
+
1. Read `milestone.origin` from `milestone-{id}.yml`. If null → skip (fresh milestone, no hook).
|
|
322
|
+
2. Open `.forge/refactor-backlog.yml`. Find item with matching `id`.
|
|
323
|
+
3. Update item: `status: resolved`, set `completed: "<ISO 8601 date>"`. Keep `promoted_to: {milestone-id}` intact for audit trail.
|
|
324
|
+
4. Log in summary: *"Backlog item {R-id} → resolved (promoted milestone {id} complete)."*
|
|
314
325
|
|
|
315
326
|
## Phase Handoff
|
|
316
327
|
|
|
317
328
|
1. Confirm report + backlog
|
|
318
|
-
2.
|
|
319
|
-
3.
|
|
329
|
+
2. **Run promoted-milestone completion hook** (above) if `milestone.origin` set
|
|
330
|
+
3. Set `current.status: complete` and `current.completed_at: "<ISO 8601 timestamp>"`
|
|
331
|
+
4. *"Milestone [{name}] complete. Report: `.forge/audits/milestone-{id}-health-report.md`. {N} backlog items. `/forge` or backlog."*
|
|
@@ -89,6 +89,8 @@ grep -h "^\s*- id: NFR-" .forge/requirements/*.yml | sort | uniq -d
|
|
|
89
89
|
|
|
90
90
|
If duplicates appear: keep the older milestone's ID, renumber the newer one to the next free integer across all files. Update any references in `.forge/phases/m{N}-*/plan-*.md` that cite the renumbered IDs.
|
|
91
91
|
|
|
92
|
+
**Pragmatic out for projects mid-stream.** If you are migrating a project where multiple milestones were authored under the old pre-0.10.0 assumption that IDs were file-scoped, retroactively renumbering can be hours of mechanical edits across already-shipped plan files. Acceptable alternative: grandfather the existing duplicates as-is, enforce global uniqueness only for new milestones from this point forward, and record the carve-out in `.forge/context.md` under Locked Decisions. The framework's downstream tooling (refactor backlog, plan-file cross-references) will tolerate the grandfathered duplicates as long as no new collisions are introduced.
|
|
93
|
+
|
|
92
94
|
### 6. Update references in state files
|
|
93
95
|
|
|
94
96
|
State files may cite the old paths in `decisions`, `blockers`, or `quick_tasks_history`:
|
package/template/CLAUDE.md
CHANGED
|
@@ -125,7 +125,7 @@ State lives in `.forge/`:
|
|
|
125
125
|
- `project.yml` — Vision, stack, design system, verification, constraints (<5KB)
|
|
126
126
|
- `constitution.md` — Active architectural gates
|
|
127
127
|
- `design-system.md` — Component mapping table
|
|
128
|
-
- `requirements/m{N}.yml` — Per-milestone structured requirements with `[NEEDS CLARIFICATION]` markers. FR-IDs are globally unique across
|
|
128
|
+
- `requirements/m{N}.yml` — Per-milestone structured requirements with `[NEEDS CLARIFICATION]` markers. **FR-IDs, DEF-IDs, and NFR-IDs are globally unique across all milestone files** — `FR-001` may exist in exactly one `m{N}.yml`. Before adding a new ID, scan `.forge/requirements/*.yml` for the highest in-use number and continue the sequence. On collision (e.g. during a migration), keep the older milestone's ID and renumber the newer. Concurrent milestones each own their file — no cross-stream contention on file writes, but ID space is shared.
|
|
129
129
|
- `roadmap.yml` — Phases, milestones, dependencies
|
|
130
130
|
- `state/index.yml` — Global: active milestones, desire_paths, metrics
|
|
131
131
|
- `state/milestone-{id}.yml` — Per-milestone cursor: position, progress, decisions, blockers
|