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.
- package/bin/create-forge.js +20 -1
- package/package.json +1 -1
- package/template/.claude/skills/chief-of-staff/SKILL.md +281 -0
- package/template/.claude/skills/discussing/SKILL.md +2 -0
- package/template/.claude/skills/forge/SKILL.md +31 -4
- package/template/.claude/skills/planning/SKILL.md +9 -0
- package/template/.claude/skills/upgrading/SKILL.md +30 -2
- package/template/.forge/FORGE.md +72 -23
- package/template/.forge/migrations/0.32.0-chief-streams.md +159 -0
- package/template/.forge/migrations/0.32.1-chief-front-door.md +64 -0
- package/template/.forge/migrations/0.33.0-worktree-convention-base.md +94 -0
- package/template/.forge/releases.yml +95 -15
- package/template/.forge/templates/context.md +4 -0
- package/template/.forge/templates/migration-guide.md +33 -0
- package/template/.forge/templates/streams/active.yml +34 -0
- package/template/.forge/templates/streams/brief.md +47 -0
- package/template/.forge/templates/streams/stream.yml +56 -0
- package/template/.forge/templates/streams/work-package.yml +70 -0
package/bin/create-forge.js
CHANGED
|
@@ -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
|
@@ -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
|
|
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`
|
|
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
|
|
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
|
-
**
|
|
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 →
|
|
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
|
- ...
|