forge-orkes 0.31.0 → 0.33.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.
@@ -37,6 +37,16 @@ const FRAMEWORK_OWNED_DIRS = ['.claude/agents', '.claude/skills'];
37
37
  // Experimental / opt-in skills installed separately (e.g. from experimental/m10).
38
38
  // They are NOT in the shipped base template, so the framework-owned auto-clean
39
39
  // would otherwise delete them on upgrade. Preserve them instead.
40
+ //
41
+ // The npm tarball ships only bin/ + template/ — NOT experimental/ — so this route
42
+ // cannot diff or re-sync an experimental skill against its source. Preserving
43
+ // blindly is what silently froze them pre-0.33.0 (issue #5): a base migration that
44
+ // changed experimental-skill behavior became a no-op. The structural fix lives
45
+ // elsewhere — (a) the clone-based `upgrading` skill (Step 3b) offers a real
46
+ // re-sync against experimental/*/source, and (b) load-bearing conventions are
47
+ // promoted to base (FORGE.md) so they no longer depend on the frozen skill. Here
48
+ // we can only PRESERVE + flag, so the report below tells the user staleness was
49
+ // not checked and how to refresh.
40
50
  const EXPERIMENTAL_SKILL_PATHS = ['.claude/skills/orchestrating'];
41
51
 
42
52
  function isExperimentalSkillPath(displayPath) {
@@ -623,8 +633,17 @@ async function upgrade() {
623
633
  if (results.preserved.length > 0) {
624
634
  console.log(` Preserved (${results.preserved.length}):`);
625
635
  for (const f of results.preserved) {
626
- console.log(` ${f} (kept — opt-in experimental skill)`);
636
+ console.log(` ${f} (kept — opt-in experimental skill; staleness not checked by npm)`);
627
637
  }
638
+ console.log(
639
+ ` ↳ The npm upgrade does not ship experimental sources, so it cannot`
640
+ );
641
+ console.log(
642
+ ` re-sync these. To refresh against a Forge clone, run the \`upgrading\``
643
+ );
644
+ console.log(
645
+ ` skill (offers a re-sync), or re-run \`experimental/<pkg>/install.sh\`.`
646
+ );
628
647
  console.log();
629
648
  }
630
649
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forge-orkes",
3
- "version": "0.31.0",
3
+ "version": "0.33.0",
4
4
  "description": "Set up the Forge meta-prompting framework for Claude Code in your project",
5
5
  "bin": {
6
6
  "create-forge": "./bin/create-forge.js"
@@ -0,0 +1,281 @@
1
+ ---
2
+ name: chief-of-staff
3
+ description: "Coordinate multiple active Forge streams. Use for explicit stream intents, mid-flow pivots, delegated work, cross-stream conflict checks, and merge ordering."
4
+ ---
5
+
6
+ # Chief Of Staff
7
+
8
+ Project-level traffic control for concurrent Forge work. The Chief owns the
9
+ project stream registry, stream lifecycle, conflict checks, context switching,
10
+ delegation, merge order, and closeout.
11
+
12
+ Use this skill when the user explicitly asks about streams, Chief of Staff, or
13
+ parallel application work. Do not route ordinary single-feature work here by
14
+ default. Inside each stream, continue to use Forge's Quick, Standard, and Full
15
+ tiers for actual execution.
16
+
17
+ ## Operating Model
18
+
19
+ Forge has three coordination layers:
20
+
21
+ | Layer | Owner | Purpose | Default context |
22
+ |-------|-------|---------|-----------------|
23
+ | Project | Project Chief | Active streams, conflicts, pivots, merge order | `.forge/streams/active.yml` |
24
+ | Stream | Stream Chief or lead session | One coherent line of application work | `.forge/streams/{stream}.yml` + `brief.md` |
25
+ | Work Package | Worker session | Delegated bounded task | `.forge/streams/{stream}/packages/{id}.yml` |
26
+
27
+ Workers never coordinate laterally. A worker reports to its stream chief or the
28
+ Project Chief. Scope expansion, shared-surface edits, and cross-stream conflict
29
+ questions return to the Chief before work continues.
30
+
31
+ ## Stream States
32
+
33
+ - `draft` - described but not ready for active work
34
+ - `active` - currently being driven in this session
35
+ - `paused` - safe to resume later; context snapshot is current
36
+ - `delegated` - worker session or external session is carrying the stream
37
+ - `blocked` - cannot proceed until a dependency, decision, or conflict clears
38
+ - `ready` - implementation is ready for merge or verification
39
+ - `merged` - stream work has landed in the integration branch
40
+ - `closed` - final outcome recorded; no active coordination remains
41
+
42
+ ## Context Loading
43
+
44
+ 1. Read `.forge/streams/active.yml` first.
45
+ 2. If missing, create it from `.forge/templates/streams/active.yml`.
46
+ 3. Load only the selected stream's `.forge/streams/{stream}.yml`.
47
+ 4. Load the selected stream's `brief.md` when the user needs status, handoff,
48
+ conflict context, or resume context.
49
+ 5. Load work packages only when delegating, checking worker status, or closing
50
+ a stream.
51
+
52
+ Keep summaries in the registry short. Deep history belongs in stream briefs,
53
+ packages, plans, verification reports, commits, and archived artifacts.
54
+
55
+ ## Supported Intents
56
+
57
+ | Intent | Examples | Action |
58
+ |--------|----------|--------|
59
+ | Show | "show streams", "active streams", "what is running?" | Run Registry Drift Check, then summarize registry without loading all deep history |
60
+ | Start | "start stream X", "new stream for billing" | Snapshot current stream, create stream files, register stream |
61
+ | Pause | "pause stream X" | Update brief, mark paused, keep next action explicit |
62
+ | Resume | "resume stream X" | Load stream context, set active, surface blockers and ownership |
63
+ | Delegate | "delegate stream X", "farm this out" | Create or update a work package and handoff prompt |
64
+ | Adopt M10 | "adopt existing M10 worktrees", "migrate active orchestrating sessions" | Wrap live M10 worktrees as streams without teardown |
65
+ | Sync | "sync streams" | Run Registry Drift Check, then refresh registry summaries from active stream briefs |
66
+ | Detect Conflicts | "detect conflicts", "check stream conflicts" | Compare ownership and dependencies |
67
+ | Merge Safe | "merge safe?", "what can land?" | Identify ready streams with no blocking conflicts |
68
+ | Close | "close stream X" | Record final status, archive/mark closed, clear active pointer if needed |
69
+
70
+ ## Registry Drift Check
71
+
72
+ Forge keeps two registries that both describe "what work is active," with no
73
+ automatic reconciliation: `.forge/state/index.yml` (milestones, owned by the
74
+ `forge` skill) and `.forge/streams/active.yml` (streams, owned by the Chief).
75
+ `/forge` and `/chief-of-staff` can therefore present different pictures of the
76
+ project. Run this check at the **start of the Show and Sync intents** so the
77
+ divergence is surfaced instead of silently left to the operator.
78
+
79
+ This is **advisory — it never blocks, never auto-creates a milestone, and never
80
+ auto-writes a stream.** It reports, and offers.
81
+
82
+ 1. Read active milestones from `.forge/state/index.yml` (those with
83
+ `status: active`). If the file is absent, skip the check silently — a
84
+ streams-only project has nothing to reconcile.
85
+ - Note: invoking `/chief-of-staff` directly bypasses `forge`'s boot preflight,
86
+ so `index.yml` may be stale (it is regenerated by `forge`'s Rollup, not by
87
+ the Chief). Read it as-is; do not run Rollup from the Chief. If it looks
88
+ stale, say so and suggest a `/forge` pass.
89
+ 2. Read the stream registry from `.forge/streams/active.yml`.
90
+ 3. Map each active milestone to a stream by id, trying these forms in order:
91
+ `m-{id}`, `milestone-{id}`, bare `{id}`, and any stream whose
92
+ `context.milestone` points at `.forge/state/milestone-{id}.yml`.
93
+ 4. Report each mismatch:
94
+ - **Active milestone with no stream** → offer to add it as a `paused` stream
95
+ (do not create it automatically). Quick-fix milestones legitimately may not
96
+ warrant a stream — let the operator decide.
97
+ - **Stream pointing at a `deferred`, `complete`, or absent milestone** → the
98
+ stream's status should follow its milestone; offer to update it (pause a
99
+ stream whose milestone deferred, close one whose milestone completed).
100
+ - **Stream with no milestone counterpart** → informational only. Quick-fix
101
+ streams are valid; never auto-create a milestone for them.
102
+ 5. If everything maps cleanly, say so in one line (`registries aligned`) and
103
+ continue to the intent.
104
+
105
+ Keep the output compact — a few lines under a `Registry drift:` header, then
106
+ proceed with the requested Show/Sync.
107
+
108
+ ## Start Stream Flow
109
+
110
+ 1. Read the registry.
111
+ 2. If another stream is active, snapshot its current state:
112
+ - update `.forge/streams/{stream}/brief.md`
113
+ - set `next_action`
114
+ - mark it `paused`, `delegated`, or leave `active` only if work continues
115
+ 3. Create a stable stream id from the goal, such as `billing-webhooks`.
116
+ 4. Create:
117
+ - `.forge/streams/{id}.yml` from `.forge/templates/streams/stream.yml`
118
+ - `.forge/streams/{id}/brief.md` from `.forge/templates/streams/brief.md`
119
+ - `.forge/streams/{id}/packages/`
120
+ 5. Add a compact entry to `.forge/streams/active.yml`.
121
+ 6. Declare ownership:
122
+ - `owned_surfaces` for files or areas the stream may edit
123
+ - `shared_surfaces` for contracts, APIs, schemas, or docs touched with care
124
+ - `read_only_surfaces` for context only
125
+ - `forbidden_surfaces` for explicit exclusions
126
+ 7. If ownership is uncertain, start read-only and ask for a narrower boundary.
127
+ 8. Run conflict detection before making edits.
128
+
129
+ ## Adopt Existing M10 Worktrees Flow
130
+
131
+ Use this when a repo already has `orchestrating` / M10 worktrees running and the
132
+ user asks to move to Chief/Streams. Do not teardown, merge, rebase, or remove
133
+ worktrees as part of adoption. Adoption only creates stream metadata around
134
+ existing M10 state.
135
+
136
+ 1. Read or create `.forge/streams/active.yml`.
137
+ 2. Discover live M10 worktrees from both sources:
138
+ - `git worktree list --porcelain` branches matching `refs/heads/forge/m-*`
139
+ - `.forge/state/milestone-*.yml` with
140
+ `lifecycle.worktree_mode: active` or `degraded`
141
+ 3. For each discovered worktree, read its milestone state when available:
142
+ - milestone id and name
143
+ - `current.status`, `current.phase`, `current.phase_name`
144
+ - `lifecycle.worktree_path`
145
+ - `lifecycle.worktree_branch`
146
+ - `lifecycle.worktree_anchor`
147
+ - `lifecycle.session_id`
148
+ - `lifecycle.claim_session_id`
149
+ - blockers or refused/degraded reason
150
+ 4. Create a stable stream id. Prefer a slug from milestone id + name, for
151
+ example `m16-chief-streams`. If only the branch is known, derive from the
152
+ branch suffix.
153
+ 5. For each adopted stream, create if missing:
154
+ - `.forge/streams/{id}.yml`
155
+ - `.forge/streams/{id}/brief.md`
156
+ - `.forge/streams/{id}/packages/`
157
+ 6. Populate the stream file:
158
+ - `stream.id`, `goal`, `status`, `tier`
159
+ - `runtime.branch` from `lifecycle.worktree_branch`
160
+ - `runtime.worktree` from `lifecycle.worktree_path`. **If no path was
161
+ recorded** (a manual `git worktree add`, or pre-convention state), resolve
162
+ it from the base **Worktree Convention** in `FORGE.md` —
163
+ `{orchestration.worktree_root or ../<repo>-worktrees}/{anchor}` — rather
164
+ than assuming the experimental `orchestrating` skill's internal default.
165
+ Confirm the resolved path with `git worktree list` before recording it.
166
+ - `runtime.worker_sessions` with the M10 session / claim ids
167
+ - `ownership.owned_surfaces`, `shared_surfaces`, and `read_only_surfaces`
168
+ as empty lists if unknown
169
+ - `blockers` from milestone blockers or degraded/refused notes
170
+ - `context.milestone` pointing at `.forge/state/milestone-{id}.yml`
171
+ 7. Populate the stream brief with:
172
+ - current milestone/phase/status
173
+ - worktree path and branch
174
+ - known blockers
175
+ - unknown ownership surfaces marked as needing declaration
176
+ - next action from milestone state or "declare ownership and sync"
177
+ 8. Add or update the compact entry in `.forge/streams/active.yml`.
178
+ 9. Run conflict detection. Missing ownership is a conflict until clarified, but
179
+ it does not block adoption.
180
+ 10. Ask before changing `.forge/project.yml`:
181
+ - If the user confirms Chief should be the front door, set
182
+ `orchestration.auto: false`.
183
+ - If not confirmed, leave legacy M10 auto-routing unchanged.
184
+
185
+ Adoption is idempotent. If a stream already references the same worktree branch
186
+ or path, update its summary and brief instead of creating a duplicate stream.
187
+
188
+ ## Pause And Resume Flow
189
+
190
+ Pause:
191
+ 1. Update the stream brief with current state, decisions, blockers, and next
192
+ action.
193
+ 2. Set registry status to `paused`, unless work was handed to another session
194
+ and should be `delegated`.
195
+ 3. Clear `current_stream` only if no stream remains active in this session.
196
+
197
+ Resume:
198
+ 1. Load registry, stream file, and brief.
199
+ 2. Surface status, blockers, owned surfaces, shared surfaces, and next action.
200
+ 3. Set the stream to `active`.
201
+ 4. Run conflict detection before continuing.
202
+
203
+ ## Delegate Flow
204
+
205
+ 1. Confirm the stream has a clear goal and ownership boundary.
206
+ 2. Copy `.forge/templates/streams/work-package.yml` to
207
+ `.forge/streams/{stream}/packages/{id}.yml`.
208
+ 3. Include goal, owned/read-only/forbidden surfaces, deliverables, verification
209
+ commands, stop conditions, and reporting target.
210
+ 4. Mark the stream `delegated` if the worker owns the next action.
211
+ 5. Tell the worker to report back to the Chief, not to other workers.
212
+ 6. If the worker finds conflicts, missing contracts, blocked verification, or
213
+ scope expansion, they stop and report back before editing outside package
214
+ scope.
215
+
216
+ If the work-package template is not present yet, create the smallest package
217
+ shape that preserves goal, surfaces, deliverables, stop conditions, and next
218
+ reporting step. Phase 25 upgrades this to the full schema.
219
+
220
+ Delegation prompt must name the package path and the reporting target:
221
+
222
+ ```text
223
+ Work from `.forge/streams/{stream}/packages/{id}.yml`.
224
+ Edit only `scope.owns`.
225
+ Read `scope.may_read` for context.
226
+ Do not touch `scope.must_not_touch`.
227
+ Report conflicts, missing contracts, blocked verification, or scope expansion
228
+ back to the Chief. Do not coordinate directly with other workers.
229
+ ```
230
+
231
+ ## Detect Conflicts
232
+
233
+ Compare all `active`, `delegated`, and `ready` streams:
234
+
235
+ - overlapping `owned_surfaces` means serialize, split, or block one stream
236
+ - `owned_surfaces` overlapping another stream's `shared_surfaces` requires a
237
+ reservation, contract, or explicit merge order
238
+ - overlapping `shared_surfaces` requires a named contract owner
239
+ - overlapping `read_only_surfaces` is safe
240
+ - missing ownership is a conflict until clarified
241
+
242
+ Record conflicts in both the registry and the affected stream files. Do not let
243
+ workers resolve cross-stream conflicts directly.
244
+
245
+ ## Merge Safe Flow
246
+
247
+ Use "merge safe" to identify streams that can land:
248
+
249
+ 1. Candidate stream status must be `ready`.
250
+ 2. No blockers may be open.
251
+ 3. Owned surfaces must not overlap another active or ready stream.
252
+ 4. Shared surfaces must have a contract owner and documented validation.
253
+ 5. Verification commands or manual validation must be listed.
254
+ 6. Merge order must be explicit when more than one stream is ready.
255
+
256
+ If any condition fails, mark the stream blocked or keep it ready with a named
257
+ reason it cannot merge yet.
258
+
259
+ ## Close Flow
260
+
261
+ 1. Confirm final status: merged, intentionally abandoned, superseded, or split.
262
+ 2. Record final outcome in the stream brief.
263
+ 3. Update registry status to `closed`.
264
+ 4. Clear `current_stream` if this was the active stream.
265
+ 5. Keep closed stream history available until a later archive/compaction pass.
266
+
267
+ ## Output Shape
268
+
269
+ Keep Chief responses short and operational:
270
+
271
+ ```text
272
+ Streams:
273
+ - billing-webhooks — active — owns api/billing, shared db/schema — next: verify webhook retries
274
+ - settings-ui — paused — owns app/settings — next: resume form validation
275
+
276
+ Conflicts:
277
+ - billing-webhooks and reporting-export both touch db/schema. Contract owner needed before either merges.
278
+
279
+ Next:
280
+ - Continue billing-webhooks, or start a new stream with read-only ownership until boundaries are declared.
281
+ ```
@@ -45,10 +45,12 @@ Never accumulate decisions in working memory. Never batch writes to convergence.
45
45
  `context.md` is **shared mutable** state per FORGE.md State Ownership — writes follow two structural rules:
46
46
  - **Scope to your milestone's block.** Different milestone blocks → git merges cleanly across worktrees.
47
47
  - **Append-only within a block.** When superseding an older decision, *strike through* (`~~old decision~~`) and append the new line below — never rewrite in place. Same-line concurrent edits become impossible by construction; reading the history of a decision becomes possible by inspection.
48
+ - **Keep active context active.** Write current/open decisions to `.forge/context.md`. Do not rehydrate old milestone blocks from `.forge/context-archive.md` unless the user is amending that historical decision.
48
49
 
49
50
  **On first decision of the session:**
50
51
  - Check if `.forge/context.md` exists. If not → create it from `.forge/templates/context.md`
51
52
  - Add a milestone heading inside `## Locked Decisions`: `### M{id} — {name} (drafting)` (use "M?" if no milestone yet)
53
+ - If the needed historical decision is archived, cite the archive in the new active decision instead of copying the whole block back.
52
54
  - **Cross-tree liveness check (informational).** If editing an existing block for milestone `{id}`, run `git worktree list --porcelain | awk '/^branch / && $2 ~ /refs\/heads\/forge\/m-'"$id"'(-|$)/ {print}'`. Any hit means m{id} is **live in another worktree** — surface one line: *"m{id} is live in worktree at `{path}`. Edits land cleanly on main but won't be visible to that worktree until it rebases or pulls."* Proceed with the write — main is often the canonical author of `context.md`, this is a heads-up, not a block.
53
55
 
54
56
  **On each confirmed decision:**
@@ -163,7 +163,12 @@ No `project.yml` + Standard/Full → **Step 2A**. State exists → **Step 2B**.
163
163
 
164
164
  ## Step 1.5: Lifecycle Operations
165
165
 
166
- Before tier detection, check if user request matches lifecycle patterns:
166
+ Before tier detection, check if user request matches stream or lifecycle patterns:
167
+ - "show streams" / "active streams" / "what streams are active" / "stream status" → **Show Streams**
168
+ - "start stream {name}" / "new stream {name}" / "create stream {name}" / "pivot to {work}" → **Start Stream**
169
+ - "pause stream {id}" / "resume stream {id}" / "delegate stream {id}" / "sync streams" → **Manage Streams**
170
+ - "detect conflicts" / "check stream conflicts" / "merge safe" / "close stream {id}" → **Manage Streams**
171
+ - "Chief of Staff" / "Project Chief" / "use streams" / "parallel workstreams" → **Chief**
167
172
  - "defer milestone {id}" / "defer {id}" / "pause milestone {id}" → **Defer**
168
173
  - "resume milestone {id}" / "undefer {id}" / "reactivate milestone {id}" → **Resume**
169
174
  - "delete milestone {id}" / "archive milestone {id}" / "remove milestone {id}" → **Delete** (see below)
@@ -171,6 +176,22 @@ Before tier detection, check if user request matches lifecycle patterns:
171
176
 
172
177
  No match → fall through to Step 2B (tier detection).
173
178
 
179
+ ### Chief / Stream Operations
180
+
181
+ 1. Invoke `Skill(chief-of-staff)` directly.
182
+ 2. Do not enter tier detection. The Chief is project-level traffic control, not
183
+ a replacement for Forge's Quick, Standard, or Full tiers.
184
+ 3. Use Chief only for explicit stream intents, concurrent application work,
185
+ mid-flow pivots, delegated work, conflict detection, merge ordering, or
186
+ closing streams.
187
+ 4. Ordinary single-stream feature work still follows normal tier detection.
188
+ Once inside a stream, the stream uses Quick/Standard/Full for execution.
189
+
190
+ Examples:
191
+ - "show streams" → `Skill(chief-of-staff)` summarizes `.forge/streams/active.yml`
192
+ - "start stream settings cleanup" → `Skill(chief-of-staff)` snapshots current stream, creates a new stream, and checks conflicts
193
+ - "merge safe?" → `Skill(chief-of-staff)` lists ready streams that can land without blocking conflicts
194
+
174
195
  ### Show Deferred
175
196
 
176
197
  1. Invoke `Skill(deferred)` directly.
@@ -262,13 +283,17 @@ Tier + state → invoke via `Skill` tool. All phases use `Skill()`.
262
283
 
263
284
  **CRITICAL: NEVER `EnterPlanMode`.** "Planning" = `Skill(planning)`. Native plan mode writes wrong format, bypasses gates + state.
264
285
 
265
- **Experimental — M10 orchestration (auto-routes when installed).** Installing M10 *is* the consent: `forge` then auto-routes Standard/Full work through `orchestrating` **before** `executing` — no separate invocation to remember. Route through `Skill(orchestrating)` first when **all** hold:
286
+ **Experimental — M10 orchestration backend.** Chief/Streams is the preferred
287
+ user-facing orchestration model. M10 remains an optional backend for streams
288
+ that need worktree isolation, merge-queue discipline, or experimental file
289
+ claims. Route through `Skill(orchestrating)` first when **all** hold:
290
+ - **Selected:** Project Chief chooses M10 for a stream, user explicitly asks for multi-agent/worktree mode, or legacy `orchestration.auto` is enabled.
266
291
  - **Installed:** `.claude/skills/orchestrating/` present + `forge-orchestrator` in `.mcp.json` + `.claude/hooks/forge-claim-check.sh` present.
267
- - **Not opted out:** `orchestration.auto` in `project.yml` ≠ `false` (absent = on; install = consent per ADR-001).
292
+ - **Not opted out:** `orchestration.auto` in `project.yml` ≠ `false` for legacy auto-routing; explicit Project Chief selection can still use M10 when installed.
268
293
  - **Tier is Standard or Full.** Quick never auto-orchestrates (a worktree per typo is the wrong trade).
269
294
  - **Not already in a session:** active milestone has no `lifecycle.worktree_mode: active|degraded` (don't re-bootstrap inside a live session).
270
295
 
271
- `orchestrating` bootstrap stays the safety net — incompatible repo → it refuses, writes `worktree_mode: refused`, and `forge` continues single-agent. Absent install → standard routing. Manual `Skill(orchestrating)` still works for explicit control; set `orchestration.auto: false` in `project.yml` to opt back out.
296
+ `orchestrating` bootstrap stays the safety net — incompatible repo → it refuses, writes `worktree_mode: refused`, and `forge` continues single-agent. Absent install → standard routing. Manual `Skill(orchestrating)` still works for explicit backend control; set `orchestration.auto: false` in `project.yml` to opt out of legacy auto-routing.
272
297
 
273
298
  ### Auto-Routing (Always Deterministic)
274
299
 
@@ -307,6 +332,7 @@ Where `{source}` = `skills.{name}` | `models.default` | `parent session`. Suppre
307
332
  | discussing | sonnet | Conversation |
308
333
  | testing | sonnet | Code gen (author) + audit judgment (analyst) — matches executing/reviewing. M9: author-mode refuses e2e without `e2e:true` + `validated:true`. |
309
334
  | deferred | haiku | Read + format only |
335
+ | chief-of-staff | sonnet | Cross-stream coordination and conflict judgment |
310
336
 
311
337
  | `current.status` | Route To |
312
338
  |-------------------|----------|
@@ -322,6 +348,7 @@ Where `{source}` = `skills.{name}` | `models.default` | `parent session`. Suppre
322
348
  | `deferred` | Milestone frozen. *"Resume milestone {id}" to reactivate.* |
323
349
  | `quick-tasking` | `Skill(quick-tasking)` |
324
350
  | (keyword: `deferred` / "show deferred") | `Skill(deferred)` — read-only aggregator |
351
+ | (keyword: `show streams` / `start stream` / `merge safe` / `Chief of Staff`) | `Skill(chief-of-staff)` — project stream coordination |
325
352
 
326
353
  ### Status Advancement Check
327
354
 
@@ -32,6 +32,11 @@ If you find yourself writing a plan that only touches `src/models/`, `src/db/`,
32
32
  Read `.forge/context.md` **Needs Resolution**. If unchecked `- [ ]` items:
33
33
  *"{N} items need input: [list]. For each: lock, defer, fix, or drop?"*
34
34
 
35
+ Load `.forge/context.md` as the active decision set. Consult
36
+ `.forge/context-archive.md` only when the current milestone, stream, or
37
+ requirement cites an older milestone decision (for example M9 e2e policy or M14
38
+ backlog lifecycle). Do not load archived decision blocks wholesale.
39
+
35
40
  | Choice | Action |
36
41
  |--------|--------|
37
42
  | Lock | Record in Locked Decisions |
@@ -61,6 +66,10 @@ If missing, create `.forge/context.md` from template:
61
66
 
62
67
  Must complete BEFORE plans. Plans reference context.md.
63
68
 
69
+ If a plan depends on an archived decision, cite the archive section in the plan
70
+ or active context summary; do not copy the historical block back into
71
+ `.forge/context.md`.
72
+
64
73
  ## Step 4: Structure Requirements
65
74
 
66
75
  Resolve current milestone ID from `.forge/state/index.yml` (active milestone) or invocation context. Target file: `.forge/requirements/m{N}.yml`.
@@ -43,7 +43,7 @@ Read the source version (`{source}/packages/create-forge/package.json` `version`
43
43
 
44
44
  **Never touch** user-generated files: `.forge/project.yml`, `.forge/state/`, `.forge/constitution.md`, `.forge/context.md`, `.forge/requirements/`, `.forge/roadmap.yml`, `.forge/design-system.md`, `.forge/refactor-backlog.yml`.
45
45
 
46
- **Preserve experimental skills.** Opt-in skills installed separately (e.g. `.claude/skills/orchestrating/` from `experimental/m10/`) are not in the base template. Never flag them as "removed from template" or delete them leave them untouched.
46
+ **Experimental skills — re-sync, don't blanket-skip.** Opt-in skills installed separately (e.g. `.claude/skills/orchestrating/` from `experimental/m10/`) are not in the base template, so they never appear in the Step 3 base sync. Earlier guidance was to leave them *untouched* — but that silently froze them at install-time content, so a base-template migration that changes behavior living only in an experimental skill became a no-op (the version stamp advanced and the migration doc shipped, yet the behavior never landed — e.g. the 0.28.0 repo-scoped worktree root). Step 3b now gives experimental skills their own **detect-and-offer-re-sync** pass against their `experimental/*/source/` origin. Never auto-overwrite and never flag them "removed from template" but never leave staleness invisible either.
47
47
 
48
48
  ## Step 3: Sync Framework-Owned Files
49
49
 
@@ -53,7 +53,31 @@ For each framework-owned file in the source template:
53
53
  2. Different → overwrite local, report **updated**
54
54
  3. Same → report **unchanged**
55
55
  4. Source has new file → copy, report **added**
56
- 5. Local has file not in source → report **removed from template** (don't delete -- let user decide)
56
+ 5. Local has file not in source → it may be an **experimental** skill — defer the verdict to Step 3b, which distinguishes "experimental, has a known source" from "genuinely removed from template." Only skills with no experimental source are reported **removed from template** (don't delete -- let user decide).
57
+
58
+ ## Step 3b: Re-sync Experimental Skills (detect + offer, never blanket-skip)
59
+
60
+ Experimental skills are installed from `{source}/packages/create-forge/experimental/<pkg>/source/skills/<name>/`, not the base template — so Step 3 never sees them. Without this pass they freeze at install-time content forever (issue #5). This pass makes staleness **visible and one-click-fixable** while staying non-destructive.
61
+
62
+ For each skill dir present in the project's `.claude/skills/` but **absent from the base template**:
63
+
64
+ 1. Search the source for a matching experimental origin: `{source}/packages/create-forge/experimental/*/source/skills/<name>/`.
65
+ 2. **No match** → genuinely local / removed-from-template. Report **removed from template** (don't delete) as before. Done.
66
+ 3. **Match found** → it is an experimental skill with a known upstream. Diff each markdown file in the installed dir against the source dir (`SKILL.md` and any siblings, e.g. `bootstrap-checks.md`):
67
+ - **All identical** → report `{name}: experimental, unchanged`.
68
+ - **Differs** → report `{name}: experimental, STALE (pinned at install; source has changes)` and **offer** a re-sync with the same preview/confirm UX as base skills:
69
+
70
+ ```
71
+ {name} is an experimental skill (from experimental/{pkg}/) pinned at install time.
72
+ The release ships newer content. Files that differ: {list}.
73
+ Re-sync from experimental/{pkg}/source? (yes / show diff / no)
74
+ ```
75
+
76
+ - **yes** → overwrite the installed skill's markdown files from source; report **updated (experimental)**.
77
+ - **show diff** → display the diff(s), then re-ask.
78
+ - **no** → leave untouched; note in the report that it stays pinned.
79
+
80
+ **Default is non-destructive** — never overwrite an experimental skill without an explicit `yes`. **Scope:** this pass re-syncs the skill's **markdown** (the behavior-bearing prose). It does **not** touch the experimental package's hooks, MCP server, or `settings.json`/`.mcp.json` wiring — those are owned by the package's own installer. When a re-sync lands, add one line: *"Hooks / MCP server for {pkg} are not re-synced here — re-run `experimental/{pkg}/install.sh` if the release changed them."*
57
81
 
58
82
  ## Step 4: Sync Template-Only Files
59
83
 
@@ -97,6 +121,10 @@ Added: {N} files
97
121
  - .claude/skills/new-skill/SKILL.md
98
122
  - ...
99
123
 
124
+ Experimental skills: {N}
125
+ - orchestrating (from experimental/m10) — updated [or: unchanged / STALE, declined]
126
+ - ...
127
+
100
128
  Removed from template: {N} files
101
129
  - .claude/agents/old-agent.md (still in your project)
102
130
  - ...