forge-orkes 0.30.0 → 0.32.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 +94 -118
- package/package.json +1 -1
- package/template/.claude/skills/chief-of-staff/SKILL.md +238 -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 +21 -198
- package/template/.forge/FORGE.md +57 -23
- package/template/.forge/migrations/0.10.0-per-milestone-requirements.md +10 -6
- package/template/.forge/migrations/0.17.0-cross-layer-contracts.md +7 -7
- package/template/.forge/migrations/0.19.0-worktree-safe-state.md +9 -4
- package/template/.forge/migrations/0.20.0-nested-phase-layout.md +8 -4
- package/template/.forge/migrations/0.22.0-backlog-compaction.md +12 -8
- package/template/.forge/migrations/0.28.0-worktree-root.md +5 -5
- package/template/.forge/migrations/0.29.0-shared-state-taxonomy.md +7 -2
- package/template/.forge/migrations/0.32.0-chief-streams.md +159 -0
- package/template/.forge/releases.yml +85 -15
- package/template/.forge/templates/context.md +4 -0
- package/template/.forge/templates/migration-guide.md +111 -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
|
@@ -112,215 +112,38 @@ Unchanged: {N} files
|
|
|
112
112
|
|
|
113
113
|
The `Migrated:` line appears only when a legacy marker/`# Forge` section was extracted this run; `Restored:` only when a missing import line was re-appended. A steady-state upgrade lists `CLAUDE.md` under Unchanged.
|
|
114
114
|
|
|
115
|
-
## Step 7: Post-Upgrade Migration Checks
|
|
115
|
+
## Step 7: Post-Upgrade Migration Checks (data-driven)
|
|
116
116
|
|
|
117
|
-
After sync completes, detect legacy file layouts
|
|
117
|
+
After sync completes, detect legacy file layouts the new framework version no longer writes but may still read in compatibility mode. This is **data-driven** — it loops over the migration guides synced in Step 4 and runs each guide's `## Detection` block. There are **no per-version blocks here**: a new guide that ships in the template (with a conformant Detection block — see `.forge/templates/migration-guide.md`) is auto-covered on the next upgrade with no edit to this skill.
|
|
118
118
|
|
|
119
|
-
|
|
119
|
+
For each guide that signals it applies, surface a migration prompt — **never auto-migrate**.
|
|
120
120
|
|
|
121
|
-
|
|
121
|
+
### The loop
|
|
122
122
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
123
|
+
1. **`installed`** = the project's `.claude/settings.json` `forge.version`, **captured at the START of this upgrade run, BEFORE Step 5 stamps the new version**. If absent/unknown, treat `installed` as `0.0.0` (all guides in range). Do **not** read the *source template's* `settings.json` literal — it carries a placeholder the installer stamps at write time, not the real version.
|
|
124
|
+
2. **`source`** = `{source}/packages/create-forge/package.json` `version`. This is the authoritative new version. (Again: never the template `settings.json` literal.)
|
|
125
|
+
3. Glob the just-synced guides: `.forge/migrations/{v}-*.md`. Parse `{v}` (the leading `MAJOR.MINOR.PATCH`) from each filename. Select guides where **`installed < v <= source`** (semver compare on dotted numerics).
|
|
126
|
+
4. For each selected guide, ascending by version: run its `## Detection` fenced bash block from the project root (via the Bash tool, under `bash`).
|
|
127
|
+
- stdout contains **`MIGRATE`** → the migration applies; surface the prompt (below). The text after `MIGRATE —` is the reason; show it.
|
|
128
|
+
- prints nothing / no `MIGRATE` → **no-op**; report `{v}: no action` and move on.
|
|
129
|
+
- the block errors → report `{v}: detection error (skipped)`; do **not** abort the loop.
|
|
127
130
|
|
|
128
|
-
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
If either command returns matches, surface:
|
|
132
|
-
|
|
133
|
-
```
|
|
134
|
-
Pre-0.10.0 requirements layout detected
|
|
135
|
-
───────────────────────────────────────
|
|
136
|
-
Found: {list of legacy paths}
|
|
137
|
-
|
|
138
|
-
Forge 0.10.0 uses per-milestone files at .forge/requirements/m{N}.yml.
|
|
139
|
-
A migration guide is available at: .forge/migrations/0.10.0-per-milestone-requirements.md
|
|
140
|
-
(installed alongside Forge; canonical copy at
|
|
141
|
-
https://github.com/Attuned-Media/forge/blob/main/docs/migrations/0.10.0-per-milestone-requirements.md)
|
|
142
|
-
|
|
143
|
-
Run the migration now? (yes/no/show guide)
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
- **yes** → invoke `quick-tasking` skill, hand it the migration guide as the task definition
|
|
147
|
-
- **show guide** → read and display the file, then re-ask
|
|
148
|
-
- **no** → note in upgrade report. Skills will continue reading the legacy path as deprecated; new writes still go to the new path, causing split-brain state. Recommend running migration before next planning cycle.
|
|
149
|
-
|
|
150
|
-
### Pre-0.17.0 missing `layers:` field
|
|
151
|
-
|
|
152
|
-
Run from project root:
|
|
153
|
-
|
|
154
|
-
```bash
|
|
155
|
-
grep -q '^layers:' .forge/project.yml || echo "no layers field"
|
|
156
|
-
ls .forge/contracts/index.yml 2>/dev/null
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
If `project.yml` has no `layers:` key AND `.forge/contracts/index.yml` is absent, surface:
|
|
160
|
-
|
|
161
|
-
```
|
|
162
|
-
Cross-layer contracts: project.yml predates the `layers:` field (Forge 0.17.0)
|
|
163
|
-
─────────────────────────────────────────────────────────────────────────────
|
|
164
|
-
Forge 0.17.0 added cross-layer contract detection (planning Step 6.1), which
|
|
165
|
-
reads `layers:` from .forge/project.yml. Without it, planning falls back to a
|
|
166
|
-
coarse top-level-directory heuristic.
|
|
167
|
-
|
|
168
|
-
A migration guide is available at: .forge/migrations/0.17.0-cross-layer-contracts.md
|
|
169
|
-
|
|
170
|
-
Add the layers field now? (yes/no/show guide)
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
- **yes** → invoke `quick-tasking` skill, hand it the migration guide as the task definition (identify layers, write `layers:` to project.yml, seed `.forge/contracts/index.yml` for multi-layer projects)
|
|
174
|
-
- **show guide** → read and display the file, then re-ask
|
|
175
|
-
- **no** → note in upgrade report. Planning still works on the fallback heuristic; cross-layer detection is just imprecise until `layers:` is declared. A single-layer project can set `layers: []` to opt out and clear the notice.
|
|
176
|
-
|
|
177
|
-
`upgrading` never edits `.forge/project.yml` directly — this is the only path that adds the field, via `quick-tasking`.
|
|
178
|
-
|
|
179
|
-
### Pre-0.19.0 legacy `state/index.yml`
|
|
180
|
-
|
|
181
|
-
Run from project root:
|
|
182
|
-
|
|
183
|
-
```bash
|
|
184
|
-
grep -qE '^[[:space:]]*(desire_paths|metrics|current_status):' .forge/state/index.yml && echo "legacy index"
|
|
185
|
-
wc -c .forge/state/index.yml # slim registry is a few hundred bytes; KBs = narrative drifted in
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
If `state/index.yml` carries `desire_paths:`/`metrics:`/embedded narrative or is large, surface:
|
|
189
|
-
|
|
190
|
-
```
|
|
191
|
-
Worktree-safe state: state/index.yml predates the derived registry (Forge 0.19.0)
|
|
192
|
-
─────────────────────────────────────────────────────────────────────────────────
|
|
193
|
-
Forge 0.19.0 makes index.yml a derived registry (regenerated by rollup), moves
|
|
194
|
-
desire_paths to append-only files, and commits .forge/ at every phase handoff.
|
|
195
|
-
A legacy index.yml conflicts across git worktrees.
|
|
196
|
-
|
|
197
|
-
A migration guide is available at: .forge/migrations/0.19.0-worktree-safe-state.md
|
|
198
|
-
|
|
199
|
-
Migrate now? (yes/no/show guide)
|
|
200
|
-
```
|
|
131
|
+
### The prompt (uniform across guides)
|
|
201
132
|
|
|
202
|
-
|
|
203
|
-
- **show guide** → read and display the file, then re-ask
|
|
204
|
-
- **no** → note in upgrade report. Skills still run against a legacy index.yml; it just won't gain worktree conflict-safety until migrated.
|
|
205
|
-
|
|
206
|
-
`upgrading` never edits `.forge/state/` directly — migration runs via `quick-tasking`.
|
|
207
|
-
|
|
208
|
-
### Pre-0.20.0 flat phase dirs
|
|
209
|
-
|
|
210
|
-
Run from project root:
|
|
211
|
-
|
|
212
|
-
```bash
|
|
213
|
-
ls .forge/phases/ | grep -E '^m[0-9]+-[0-9]+-' && echo "flat layout"
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
If any dir matching `m{id}-{phase}-{name}` sits directly under `.forge/phases/`, surface:
|
|
133
|
+
For each applying guide:
|
|
217
134
|
|
|
218
135
|
```
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
m{id}-{phase}-{name}/ → milestone-{id}/{phase}-{name}/
|
|
223
|
-
This keeps `ls .forge/phases/` scoped per-milestone instead of dumping every
|
|
224
|
-
phase across all milestones into context. Phase numbers are preserved verbatim
|
|
225
|
-
(nothing is renumbered); the state cursor stays valid.
|
|
226
|
-
|
|
227
|
-
{N} flat phase dir(s) detected.
|
|
228
|
-
A migration guide is available at: .forge/migrations/0.20.0-nested-phase-layout.md
|
|
229
|
-
(canonical: https://github.com/Attuned-Media/forge/blob/main/docs/migrations/0.20.0-nested-phase-layout.md)
|
|
136
|
+
{v} migration available — {reason from the MIGRATE line, or the guide title}
|
|
137
|
+
Guide: .forge/migrations/{v}-{slug}.md
|
|
138
|
+
(canonical: https://github.com/Attuned-Media/forge/blob/main/docs/migrations/{v}-{slug}.md)
|
|
230
139
|
|
|
231
140
|
Migrate now? (yes/no/show guide)
|
|
232
141
|
```
|
|
233
142
|
|
|
234
|
-
- **yes** → invoke `quick-tasking` skill,
|
|
235
|
-
- **show guide** → read and display the file, then re-ask
|
|
236
|
-
- **no** → note in upgrade report.
|
|
237
|
-
|
|
238
|
-
`upgrading` never moves phase dirs directly — migration runs via `quick-tasking`.
|
|
239
|
-
|
|
240
|
-
### Pre-0.22.0 unbounded refactor-backlog
|
|
241
|
-
|
|
242
|
-
Run from project root (backlog present only):
|
|
243
|
-
|
|
244
|
-
```bash
|
|
245
|
-
F=.forge/refactor-backlog.yml
|
|
246
|
-
[ -f "$F" ] || exit 0
|
|
247
|
-
kb=$(( $(wc -c < "$F") / 1024 ))
|
|
248
|
-
terminal=$(grep -cE 'status:[[:space:]]*(done|dismissed|completed|complete|closed|wont_fix|stale)' "$F")
|
|
249
|
-
noncanon=$(grep -oE 'status:[[:space:]]*[A-Za-z_]+' "$F" \
|
|
250
|
-
| grep -vE 'status:[[:space:]]*(pending|in_progress|done|dismissed|deferred)$' | wc -l)
|
|
251
|
-
# bloat if: kb > 150 OR terminal > 0 OR noncanon > 0
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
Surface the prompt when `kb > 150` OR `terminal > 0` OR `noncanon > 0`, printing the three detected numbers:
|
|
255
|
-
|
|
256
|
-
```
|
|
257
|
-
Refactor-backlog compaction available (Forge 0.22.0)
|
|
258
|
-
────────────────────────────────────────────────────
|
|
259
|
-
Pre-0.22.0 the refactor backlog was append-only — resolved items were never
|
|
260
|
-
pruned and statuses drifted (completed/complete/closed/wont_fix/stale + junk).
|
|
261
|
-
0.22.0 archives terminal items to .forge/refactor-backlog-archive.yml and
|
|
262
|
-
enforces the canonical vocab (pending|in_progress|done|dismissed|deferred).
|
|
263
|
-
|
|
264
|
-
Detected: {kb} KB · {terminal} terminal item(s) · {noncanon} non-canonical status(es).
|
|
265
|
-
A migration guide is available at: .forge/migrations/0.22.0-backlog-compaction.md
|
|
266
|
-
(canonical: https://github.com/Attuned-Media/forge/blob/main/docs/migrations/0.22.0-backlog-compaction.md)
|
|
267
|
-
|
|
268
|
-
Migrate now? (yes/no/show guide)
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
- **yes** → invoke `quick-tasking` skill, hand it the migration guide as the task definition (snapshot item count, normalize statuses, split actionable/terminal/triage, archive terminal items to `.forge/refactor-backlog-archive.yml`, rewrite the working file, verify item-count conservation before committing).
|
|
272
|
-
- **show guide** → read and display the file, then re-ask
|
|
273
|
-
- **no** → note in upgrade report. The backlog keeps growing and statuses stay drifted until migrated; reviewing/quick-tasking will compact on their next write regardless, but a bloated file lingers until then. Recommend running before the next review cycle.
|
|
274
|
-
|
|
275
|
-
No-op guarantee: detection exits clean (no prompt) when the backlog is absent, under the gate, has zero terminal items, and all statuses are canonical. (Pending-item count is **not** a trigger — a busy-but-clean backlog is left alone.)
|
|
276
|
-
|
|
277
|
-
`upgrading` never edits the backlog directly — migration runs via `quick-tasking`.
|
|
278
|
-
|
|
279
|
-
### Pre-0.28.0 fully-ignored `.claude/`
|
|
280
|
-
|
|
281
|
-
Run from project root:
|
|
282
|
-
|
|
283
|
-
```bash
|
|
284
|
-
F=.gitignore
|
|
285
|
-
[ -f "$F" ] || exit 0
|
|
286
|
-
# bare ".claude/" or ".claude" rule (no negation lines un-ignoring product files)
|
|
287
|
-
if grep -qE '^[[:space:]]*\.claude/?[[:space:]]*$' "$F" \
|
|
288
|
-
&& ! grep -qE '^![[:space:]]*\.claude/(skills|agents|hooks|settings\.json)' "$F"; then
|
|
289
|
-
echo "broad-ignore"
|
|
290
|
-
fi
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
If the script prints `broad-ignore`, surface:
|
|
294
|
-
|
|
295
|
-
```
|
|
296
|
-
.claude/ fully ignored — Forge worktrees + hooks silently break (Forge 0.28.0)
|
|
297
|
-
─────────────────────────────────────────────────────────────────────────────
|
|
298
|
-
Your .gitignore ignores all of `.claude/` without a carve-out. That means:
|
|
299
|
-
• git worktrees (Forge or the app's) have no `.claude/skills/`, so `/forge`
|
|
300
|
-
is missing — typing `/forge` in a worktree prints "Unknown command".
|
|
301
|
-
• M10 worktrees come up with no hooks (forge-claim-check, branch-guard,
|
|
302
|
-
session-id) — coordination + ADR-008 protection are silently disabled.
|
|
303
|
-
|
|
304
|
-
These are PRODUCT files, not per-machine config. The fix is a narrow
|
|
305
|
-
carve-out: track skills/agents/hooks/settings.json; keep settings.local.json,
|
|
306
|
-
projects/, worktrees/ ignored.
|
|
307
|
-
|
|
308
|
-
A migration guide is available at: .forge/migrations/0.28.0-worktree-root.md
|
|
309
|
-
(canonical: https://github.com/Attuned-Media/forge/blob/main/docs/migrations/0.28.0-worktree-root.md)
|
|
310
|
-
|
|
311
|
-
Apply the carve-out now? (yes/no/show guide)
|
|
312
|
-
```
|
|
313
|
-
|
|
314
|
-
- **yes** → invoke `quick-tasking` skill with the migration guide as the task (edit `.gitignore` in place, `git rm -r --cached .claude/` to clear the ignore-cache, stage `.gitignore` + the four product trees, commit `chore(forge): track .claude/ product files`). The skill MUST confirm with the user before staging anything outside the four product trees.
|
|
315
|
-
- **show guide** → read and display the file, then re-ask
|
|
316
|
-
- **no** → note in upgrade report. The framework keeps working in the main checkout but worktree-mode sessions (M10 / Claude Desktop folder-open) will be missing `/forge` and Forge hooks until migrated.
|
|
317
|
-
|
|
318
|
-
This is a Forge-product-tracking concern, not a state migration — `upgrading` never edits user `.gitignore` directly. Migration runs via `quick-tasking`.
|
|
143
|
+
- **yes** → invoke the `quick-tasking` skill, handing it the guide path as the task definition. `upgrading` never edits user state / project files / `.gitignore` directly — every migration runs via `quick-tasking`, and any lossy step (e.g. narrative extraction, staging files) is confirmed with the user first.
|
|
144
|
+
- **show guide** → read and display the guide file, then re-ask.
|
|
145
|
+
- **no** → note in the upgrade report. The new skills compose new-shape paths on write while legacy files persist on disk (split-brain) until migrated; recommend running it before the next planning/review cycle.
|
|
319
146
|
|
|
320
|
-
###
|
|
147
|
+
### Why there is no bookkeeping
|
|
321
148
|
|
|
322
|
-
|
|
323
|
-
1. Detection command(s)
|
|
324
|
-
2. Single-line description of the drift
|
|
325
|
-
3. Pointer to `.forge/migrations/{version}-{slug}.md` (installed copy; canonical at `docs/migrations/...` in the Forge source repo)
|
|
326
|
-
4. Three-way prompt (yes/no/show guide)
|
|
149
|
+
Recording "crossed" guides is implicit in the range. Once Step 5 stamps `forge.version` to `source`, a later run's range `(new installed, source]` excludes every guide already crossed — so nothing re-detects, with **no ledger or marker file**. The range also closes the install-run blind spot: detection keys off the guides **freshly synced this run** (Step 4) plus the **pre-stamp installed version**, so the run that installs new detection behavior uses the new guides, not this skill's own pre-sync prose.
|
package/template/.forge/FORGE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Forge
|
|
2
2
|
|
|
3
|
-
Lean meta-prompting framework
|
|
3
|
+
Lean meta-prompting framework. Context engineering + constitutional governance on agent-native primitives.
|
|
4
4
|
|
|
5
5
|
## Critical: No Native Plan Mode
|
|
6
6
|
|
|
@@ -11,7 +11,7 @@ All phases: **invoke via `Skill` tool**, never native behavior. `planning` → `
|
|
|
11
11
|
## Core Principles
|
|
12
12
|
|
|
13
13
|
1. **Lean default, powerful when needed.** Quick → skip ceremony. Complex → full governance.
|
|
14
|
-
2. **
|
|
14
|
+
2. **Adapter-native.** Use each platform's built-ins through adapters. Avoid custom runtime unless the substrate truly needs it.
|
|
15
15
|
3. **Context is sacred.** Size-gate artifacts, lazy-load skills, fresh agents for isolated work.
|
|
16
16
|
4. **Decisions are contracts.** Lock before building. Honor or flag — never silently override.
|
|
17
17
|
5. **Verify goals, not tasks.** "Does it work?" > "Did we finish checklist?"
|
|
@@ -19,6 +19,24 @@ All phases: **invoke via `Skill` tool**, never native behavior. `planning` → `
|
|
|
19
19
|
7. **Pave desire paths.** Repeated deviations/corrections = signal → evolve framework.
|
|
20
20
|
8. **Disconfirm before commit.** Before locking a diagnosis, a solution, or a foundational choice, run the cheap pass that could break it. A conclusion reached without an attempt to refute it is a hypothesis, not a finding. Enforced at the three commit points: `debugging` (Confirmation Gate), `discussing`/`architecting` (option-space framing), `architecting` (Platform & Goal Validation).
|
|
21
21
|
|
|
22
|
+
## Core Protocol And Adapters
|
|
23
|
+
|
|
24
|
+
**Core protocol** lives in `.forge/`: project/constitution state, milestones, requirements, roadmap, context, streams, work packages, plans, verification, audits, and state ownership rules. The core protocol describes durable behavior, not one platform's tool names.
|
|
25
|
+
|
|
26
|
+
**Platform adapters** translate the protocol into a runtime. Each platform adapter maps core behavior to its tools: Claude Code skills/hooks, Codex/AGENTS behavior, manual multi-session handoffs, or future agent surfaces. Adapter mechanics stay in adapter files and skills; they should not become core requirements.
|
|
27
|
+
|
|
28
|
+
## Project Streams
|
|
29
|
+
|
|
30
|
+
Forge has three runtime coordination layers: Project, Stream, and Work Package.
|
|
31
|
+
|
|
32
|
+
| Layer | Purpose | Default Context |
|
|
33
|
+
|---|---|---|
|
|
34
|
+
| **Project** | Repo-wide traffic map: active streams, ownership, risks, merge order | `.forge/streams/active.yml` |
|
|
35
|
+
| **Stream** | One active line of work: goal, branch/worktree, state, blockers, next action | `.forge/streams/{stream}.yml` + `brief.md` |
|
|
36
|
+
| **Work Package** | Delegated bounded task inside a stream | `.forge/streams/{stream}/packages/{id}.yml` |
|
|
37
|
+
|
|
38
|
+
Use ordinary Quick/Standard/Full tiers inside a stream. Use Project Chief / Chief of Staff when coordinating multiple active streams or pivoting without dropping context. Workers never coordinate laterally; they report to the stream or project chief. M10 worktrees remain an optional backend for isolation/merge discipline, not the primary UX.
|
|
39
|
+
|
|
22
40
|
## Workflow Tiers
|
|
23
41
|
|
|
24
42
|
Auto-detects complexity. Override: "Use Quick/Standard/Full tier."
|
|
@@ -60,7 +78,7 @@ Auto-detects complexity. Override: "Use Quick/Standard/Full tier."
|
|
|
60
78
|
| Systematic debugging | `debugging` | When stuck |
|
|
61
79
|
| Upgrade Forge files | `upgrading` | On-demand |
|
|
62
80
|
| Cross-session memory | `beads-integration` | When Beads installed |
|
|
63
|
-
| Multi-agent
|
|
81
|
+
| Multi-agent backend (experimental) | `orchestrating` | Optional, usually selected by Chief/Streams |
|
|
64
82
|
|
|
65
83
|
> Experimental skills require opt-in install — see `packages/create-forge/experimental/m10/README.md`.
|
|
66
84
|
|
|
@@ -73,7 +91,25 @@ Auto-detects complexity. Override: "Use Quick/Standard/Full tier."
|
|
|
73
91
|
| `requirements/m{N}.yml` | 50 KB/file | Prevents scope creep |
|
|
74
92
|
| `plan.md` | 30 KB | Keeps executor context <50% |
|
|
75
93
|
| `constitution.md` | 10 KB | Gates must be scannable |
|
|
94
|
+
| `context.md` | 12 KB | Active decisions only; history archives to `context-archive.md` |
|
|
76
95
|
| `refactor-backlog.yml` | 150 KB | Working backlog stays scannable; terminal items archive to `refactor-backlog-archive.yml` (advisory — flags, never blocks) |
|
|
96
|
+
| `streams/active.yml` | 20 KB | Project Chief traffic map must stay cheap to load |
|
|
97
|
+
| `streams/{stream}.yml` | 15 KB | Stream state stays resumable without becoming history |
|
|
98
|
+
| `streams/{stream}/brief.md` | 8 KB | Stream context packet must fit into active session context |
|
|
99
|
+
| `streams/{stream}/packages/{id}.yml` | 10 KB | Delegated work contract stays bounded |
|
|
100
|
+
|
|
101
|
+
### Accumulating Artifacts
|
|
102
|
+
|
|
103
|
+
Every new accumulating artifact needs: owner, size gate, archive/compaction rule,
|
|
104
|
+
`derived` vs source-of-truth status, and migration behavior. Defaults:
|
|
105
|
+
|
|
106
|
+
- `roadmap.yml`, `requirements/*.yml`, `releases.yml` are source-of-truth; load
|
|
107
|
+
scoped slices, not whole history.
|
|
108
|
+
- `phases/`, `audits/`, `research/`, `archive/`, and `context-archive.md` are
|
|
109
|
+
historical; load only by milestone/stream/package/version.
|
|
110
|
+
- Runtime/generated files (`.mcp-server/*.db*`, logs, spike DBs) are excluded
|
|
111
|
+
from framework context and packages unless debugging them.
|
|
112
|
+
- Template copies sync mechanically; do not treat them as separate concepts.
|
|
77
113
|
|
|
78
114
|
### Fresh Agent Pattern
|
|
79
115
|
Task touches 20+ files or complex subsystem → spawn fresh executor with isolated context. Prevents context rot.
|
|
@@ -82,7 +118,9 @@ Task touches 20+ files or complex subsystem → spawn fresh executor with isolat
|
|
|
82
118
|
Each phase writes outputs to `.forge/` before completing. At phase boundaries, recommend `/clear`. Next phase loads from disk. Advisory — skip for short phases under 40% context.
|
|
83
119
|
|
|
84
120
|
### Lazy Loading
|
|
85
|
-
Skills load only when invoked.
|
|
121
|
+
Skills load only when invoked. Active context is `.forge/context.md`; consult
|
|
122
|
+
`.forge/context-archive.md` only when older decisions matter. Skill details stay
|
|
123
|
+
on demand. Base context ~300 lines.
|
|
86
124
|
|
|
87
125
|
## Model Routing
|
|
88
126
|
|
|
@@ -136,7 +174,12 @@ State lives in `.forge/`:
|
|
|
136
174
|
- `state/index.yml` — DERIVED registry rolled up from milestone files (id, name, status, last_updated). Never hand-edited; never written by worktree agents.
|
|
137
175
|
- `state/milestone-{id}.yml` — Per-milestone cursor (single source of truth): position, progress, decisions, blockers. One owner at a time.
|
|
138
176
|
- `state/desire-paths/` — Append-only framework-usage observations, one file per observation. Occurrence counts derived by globbing (no mutable counter). Each carries `scope: project | framework` (set at capture; absent ⇒ project). **`forge` boot is the single review owner**: at 3+ occurrences it surfaces a concrete fix from the co-located suggestion table, persists declines to `declined/` (no re-nag), and for `scope: framework` signals routes them upstream — a portable block to `upstream/` plus a `gh issue` offer against `forge.upstream_repo`. This closes Principle 7's capture→act loop; `verifying` captures but no longer surfaces. See [ADR-012](../docs/decisions/ADR-012-upstream-desire-path-feedback-channel.md).
|
|
139
|
-
- `context.md` —
|
|
177
|
+
- `context.md` — Active locked decisions + deferred ideas (target <=12KB)
|
|
178
|
+
- `context-archive.md` — Historical locked decisions; load only when relevant
|
|
179
|
+
- `streams/active.yml` — Compact Project Chief traffic map: active stream summaries only.
|
|
180
|
+
- `streams/{stream}.yml` — Per-stream state: lifecycle, ownership, shared surfaces, blockers, merge readiness.
|
|
181
|
+
- `streams/{stream}/brief.md` — Human-readable stream context packet loaded when resuming that stream.
|
|
182
|
+
- `streams/{stream}/packages/{id}.yml` — Work package contract for delegated workers or manual sessions.
|
|
140
183
|
- `research/milestone-{id}.md` — Research findings snapshot (dated, immutable)
|
|
141
184
|
- `phases/milestone-{id}/{phase}-{name}/plan-{NN}.md` — Task plans with must_haves frontmatter (`{id}`=milestone, `{phase}`=phase# preserved verbatim, `{name}`=kebab, `{NN}`=seq)
|
|
142
185
|
- `refactor-backlog.yml` — Refactoring catalog (actionable items only), worked via quick-tasking. Canonical status vocab: `pending | in_progress | done | dismissed | deferred`. Terminal items auto-archive on the next reviewing/quick-tasking write (compaction-on-write).
|
|
@@ -162,31 +205,22 @@ State-sync commits are separate from per-task code commits (which stay atomic du
|
|
|
162
205
|
|
|
163
206
|
### State Ownership (multi-worktree safety)
|
|
164
207
|
|
|
165
|
-
`.forge/` is
|
|
166
|
-
|
|
167
|
-
**Every `.forge/` artifact falls into one of five sharing classes.** The class determines the write rule across worktrees:
|
|
208
|
+
`.forge/` is code-like: it branches with the repo, syncs via git, and commits
|
|
209
|
+
with the work it describes. Every artifact has a sharing class:
|
|
168
210
|
|
|
169
211
|
| Class | Files | Write rule |
|
|
170
212
|
|---|---|---|
|
|
171
213
|
| **Single-owner mutable** | `state/milestone-{id}.yml`, `phases/milestone-{id}/`, `research/milestone-{id}.md` | Exactly one writer at a time — the worktree (or main session) currently driving that milestone. **Other worktrees never touch it**, not even to read-then-write — they pull from main if they need it. |
|
|
172
214
|
| **Derived** | `state/index.yml` | Never hand-edited. Regenerated by Rollup 1.0 from `milestone-*.yml`. Only the main/orchestrator session runs rollup. |
|
|
173
215
|
| **Append-only shared** | `releases.yml` (version reservations), `state/desire-paths/*` (one file per observation) | Many writers OK; structure prevents collision. `releases.yml` uses the Version Reservation Protocol (append + commit + push before depending on the slot); desire-paths use distinct filenames so two writers never touch the same file. |
|
|
174
|
-
| **Shared mutable** | `context.md`, `refactor-backlog.yml`, `requirements/m{N}.yml` (ID space `FR-`/`DEF-`/`NFR-` is globally shared even though each milestone owns its file) |
|
|
216
|
+
| **Shared mutable** | `context.md`, `refactor-backlog.yml`, `requirements/m{N}.yml` (ID space `FR-`/`DEF-`/`NFR-` is globally shared even though each milestone owns its file) | Write only to your milestone/stream block. Within a block, append-only; strike through instead of rewriting. |
|
|
175
217
|
| **Stable shared** | `project.yml`, `constitution.md`, `design-system.md`, `roadmap.yml`, `FORGE.md` | Rarely changes after init. Canonical on main. Worktrees lag and pull on rebase. No special protocol — git handles it because the conflict surface is tiny. |
|
|
176
218
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
-
|
|
182
|
-
|
|
183
|
-
**Why not global `.forge/`?** A common instinct is "make `.forge/` shared so context propagates automatically." It breaks four load-bearing invariants:
|
|
184
|
-
1. **Decisions are contracts** — they're versioned with the code they govern; severing them from branches breaks the contract.
|
|
185
|
-
2. **State survives machine loss** — the multi-laptop pull-from-any-clone story depends on `.forge/` being in git.
|
|
186
|
-
3. **History time-travel** — `git checkout` an old commit and you see the plan/decisions as they were; global state makes that impossible.
|
|
187
|
-
4. **Git is the concurrency detector** — without it, two sessions writing the same field becomes silent last-write-wins.
|
|
188
|
-
|
|
189
|
-
Per-worktree `.forge/` with a sharing taxonomy is the model. See [ADR-011](../docs/decisions/ADR-011-shared-state-taxonomy.md) for the longer version.
|
|
219
|
+
Cross-tree edits land on the current branch and are invisible to other worktrees
|
|
220
|
+
until they pull/rebase. `forge` surfaces live worktrees at boot; `discussing`
|
|
221
|
+
and `reviewing` warn before touching shared-mutable blocks; optional
|
|
222
|
+
`forge.worktree_rebase_check` detects stale shared files inside worktrees. See
|
|
223
|
+
[ADR-011](../docs/decisions/ADR-011-shared-state-taxonomy.md) for rationale.
|
|
190
224
|
|
|
191
225
|
### State Ownership rules (quick reference)
|
|
192
226
|
|
|
@@ -194,7 +228,7 @@ Per-worktree `.forge/` with a sharing taxonomy is the model. See [ADR-011](../do
|
|
|
194
228
|
- Worktree / parallel agents write **only** their own milestone file and **append** desire-path files. They **never** write `index.yml`.
|
|
195
229
|
- `index.yml` is **regenerated by rollup** (read every `milestone-*.yml` → rewrite the registry) by the main/orchestrator session — on `forge` resume and at `orchestrating` teardown. The rollup is deterministic + idempotent, so it **is** the reconcile step — never a hand-merge.
|
|
196
230
|
- For shared-mutable files: write only your milestone's block; within a block, append-only (strike through, don't rewrite).
|
|
197
|
-
- Same-milestone parallel work
|
|
231
|
+
- Same-milestone parallel work needs Chief/Streams contracts; M10 file claims are optional defense-in-depth.
|
|
198
232
|
|
|
199
233
|
### Version Reservation Protocol
|
|
200
234
|
|
|
@@ -15,16 +15,20 @@ The pre-0.10.0 spec had a single top-level `.forge/requirements.yml` "refreshed
|
|
|
15
15
|
|
|
16
16
|
## Detection
|
|
17
17
|
|
|
18
|
-
Run from project root.
|
|
18
|
+
Run from project root. Prints `MIGRATE` on stdout if a legacy requirements layout is present; silent + exit 0 when already on the per-milestone layout (the data-driven `upgrading` loop keys off the `MIGRATE` sentinel).
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
|
-
|
|
22
|
-
ls .forge/requirements.yml 2>/dev/null # legacy single file
|
|
23
|
-
ls .forge/requirements-m*.yml 2>/dev/null # suffixed top-level
|
|
24
|
-
find .forge/phases -name "requirements.yml" 2>/dev/null # per-phase files
|
|
21
|
+
legacy=$(
|
|
22
|
+
ls .forge/requirements.yml 2>/dev/null # legacy single file
|
|
23
|
+
ls .forge/requirements-m*.yml 2>/dev/null # suffixed top-level
|
|
24
|
+
find .forge/phases -name "requirements.yml" 2>/dev/null # per-phase files
|
|
25
|
+
)
|
|
26
|
+
if [ -n "$legacy" ]; then
|
|
27
|
+
echo "MIGRATE — legacy requirements layout: $(echo "$legacy" | tr '\n' ' ')"
|
|
28
|
+
fi
|
|
25
29
|
```
|
|
26
30
|
|
|
27
|
-
If `.forge/requirements/` already exists as a directory and the legacy paths above are absent, migration is complete —
|
|
31
|
+
If `.forge/requirements/` already exists as a directory and the legacy paths above are absent, migration is complete — the block prints nothing and exits 0.
|
|
28
32
|
|
|
29
33
|
## Migration steps
|
|
30
34
|
|
|
@@ -17,17 +17,17 @@ Adding `layers:` once makes the detection deterministic. A single-layer project
|
|
|
17
17
|
|
|
18
18
|
## Detection
|
|
19
19
|
|
|
20
|
-
Run from project root.
|
|
20
|
+
Run from project root. Prints `MIGRATE` if `project.yml` predates the `layers:` field and no contract index has been seeded; silent + exit 0 once `layers:` is declared (the data-driven `upgrading` loop keys off the `MIGRATE` sentinel).
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
|
-
|
|
24
|
-
grep -q '^layers:' .forge/project.yml
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
if [ -f .forge/project.yml ] \
|
|
24
|
+
&& ! grep -q '^layers:' .forge/project.yml \
|
|
25
|
+
&& [ ! -f .forge/contracts/index.yml ]; then
|
|
26
|
+
echo "MIGRATE — project.yml has no layers: field"
|
|
27
|
+
fi
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
If `project.yml` already contains a `layers:` key (any value, including `[]`), migration is complete —
|
|
30
|
+
If `project.yml` already contains a `layers:` key (any value, including `[]`), or a `.forge/contracts/index.yml` exists (layers were declared at init), migration is complete — the block prints nothing and exits 0.
|
|
31
31
|
|
|
32
32
|
## Migration steps
|
|
33
33
|
|
|
@@ -19,14 +19,19 @@ Two problems this release fixes:
|
|
|
19
19
|
|
|
20
20
|
## Detection
|
|
21
21
|
|
|
22
|
+
Run from project root. Prints `MIGRATE` if `state/index.yml` is a legacy file — still carrying the metrics/desire-paths/narrative blocks, or grown to KBs; silent + exit 0 once it is the slim derived registry (the data-driven `upgrading` loop keys off the `MIGRATE` sentinel).
|
|
23
|
+
|
|
22
24
|
```bash
|
|
23
|
-
|
|
24
|
-
|
|
25
|
+
F=.forge/state/index.yml
|
|
26
|
+
[ -f "$F" ] || exit 0
|
|
25
27
|
# Anchored so the file's own explanatory comments don't false-positive:
|
|
26
|
-
grep -
|
|
28
|
+
if grep -qE '^[[:space:]]*(desire_paths|metrics|current_status):' "$F" \
|
|
29
|
+
|| [ "$(wc -c < "$F")" -gt 4096 ]; then
|
|
30
|
+
echo "MIGRATE — legacy state/index.yml ($(wc -c < "$F") bytes)"
|
|
31
|
+
fi
|
|
27
32
|
```
|
|
28
33
|
|
|
29
|
-
|
|
34
|
+
A slim derived registry is a few hundred bytes and carries none of those keys → the block prints nothing and exits 0. The installer (`npx forge-orkes upgrade`) runs the same check after sync.
|
|
30
35
|
|
|
31
36
|
## Migration steps
|
|
32
37
|
|
|
@@ -55,14 +55,18 @@ Now `ls .forge/phases/milestone-9/` shows only milestone 9's phases.
|
|
|
55
55
|
## Detection
|
|
56
56
|
|
|
57
57
|
A flat (un-migrated) layout has directories matching `m{id}-{phase}-{name}`
|
|
58
|
-
**directly** under `.forge/phases
|
|
58
|
+
**directly** under `.forge/phases/`. Run from project root — prints `MIGRATE`
|
|
59
|
+
if any flat phase dir is present; silent + exit 0 when already nested (the
|
|
60
|
+
data-driven `upgrading` loop keys off the `MIGRATE` sentinel):
|
|
59
61
|
|
|
60
62
|
```bash
|
|
61
|
-
ls .forge/phases/ | grep -
|
|
63
|
+
if ls .forge/phases/ 2>/dev/null | grep -qE '^m[0-9]+-[0-9]+-'; then
|
|
64
|
+
echo "MIGRATE — flat phase layout under .forge/phases/"
|
|
65
|
+
fi
|
|
62
66
|
```
|
|
63
67
|
|
|
64
|
-
Already-nested projects have only `milestone-{id}/` dirs at that level
|
|
65
|
-
|
|
68
|
+
Already-nested projects have only `milestone-{id}/` dirs at that level → the
|
|
69
|
+
block prints nothing and exits 0.
|
|
66
70
|
|
|
67
71
|
## Defensive parse
|
|
68
72
|
|
|
@@ -59,23 +59,27 @@ triage."* Silently dropping or guessing is forbidden.
|
|
|
59
59
|
## Detection
|
|
60
60
|
|
|
61
61
|
Bloat/drift exists if the file is over the 150 KB size gate, OR any terminal
|
|
62
|
-
item is present, OR any non-canonical status appears
|
|
62
|
+
item is present, OR any non-canonical status appears. Run from project root —
|
|
63
|
+
prints `MIGRATE` when bloat is detected; silent + exit 0 when the backlog is
|
|
64
|
+
absent or clean (the data-driven `upgrading` loop keys off the `MIGRATE`
|
|
65
|
+
sentinel):
|
|
63
66
|
|
|
64
67
|
```bash
|
|
65
68
|
F=.forge/refactor-backlog.yml
|
|
66
|
-
[ -f "$F" ] ||
|
|
69
|
+
[ -f "$F" ] || exit 0
|
|
67
70
|
kb=$(( $(wc -c < "$F") / 1024 ))
|
|
68
71
|
terminal=$(grep -cE 'status:[[:space:]]*(done|dismissed|completed|complete|closed|wont_fix|stale)' "$F")
|
|
69
72
|
noncanon=$(grep -oE 'status:[[:space:]]*[A-Za-z_]+' "$F" \
|
|
70
73
|
| grep -vE 'status:[[:space:]]*(pending|in_progress|done|dismissed|deferred)$' | wc -l)
|
|
71
|
-
|
|
72
|
-
|
|
74
|
+
if [ "$kb" -gt 150 ] || [ "$terminal" -gt 0 ] || [ "$noncanon" -gt 0 ]; then
|
|
75
|
+
echo "MIGRATE — backlog bloat: size=${kb}KB terminal=$terminal noncanon=$noncanon"
|
|
76
|
+
fi
|
|
73
77
|
```
|
|
74
78
|
|
|
75
|
-
A clean backlog (under the gate, zero terminal, all-canonical) prints
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
+
A clean backlog (under the gate, zero terminal, all-canonical) prints nothing
|
|
80
|
+
and exits 0 → **no-op**. The detector keys off bloat that compaction actually
|
|
81
|
+
fixes, **not** the count of pending items — a busy-but-clean backlog is left
|
|
82
|
+
alone.
|
|
79
83
|
|
|
80
84
|
## ⚠️ Environment gotcha (read before scripting)
|
|
81
85
|
|
|
@@ -27,14 +27,14 @@ git worktree add ${wt_root}/${anchor} main
|
|
|
27
27
|
|
|
28
28
|
The resolved absolute path is recorded in `lifecycle.worktree_path` and read verbatim by teardown + crash-recovery — so the config knob is forward-looking, not retroactive.
|
|
29
29
|
|
|
30
|
-
###
|
|
30
|
+
### Inventory (informational — not a migration trigger)
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
33
|
# Are any of your active milestones pointing at the old shared dir?
|
|
34
34
|
grep -rE '^\s*worktree_path:.*forge-worktrees' .forge/state/ 2>/dev/null | head
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
Matches = pre-0.28.0 worktrees still in flight. **Leave them alone** — they keep working off their recorded path. Only **new** worktrees pick up the new default.
|
|
37
|
+
Matches = pre-0.28.0 worktrees still in flight. **Leave them alone** — they keep working off their recorded path. Only **new** worktrees pick up the new default. This is informational: it does **not** trigger a migration (the actionable trigger for this guide is the `.gitignore` carve-out — see `## Detection` below).
|
|
38
38
|
|
|
39
39
|
### Migration
|
|
40
40
|
|
|
@@ -86,16 +86,16 @@ Forge installs into `.claude/` (skills, agents, hooks, `settings.json`). Many Cl
|
|
|
86
86
|
|
|
87
87
|
The fix: track product files, keep per-machine/scratch files ignored.
|
|
88
88
|
|
|
89
|
-
|
|
89
|
+
## Detection
|
|
90
90
|
|
|
91
|
-
`upgrading` runs this automatically; you can run it by hand too:
|
|
91
|
+
This is the guide's single migration trigger — the `.gitignore` carve-out. (Part 1's worktree-path inventory above is informational only.) `upgrading` runs this automatically; you can run it by hand too. Prints `MIGRATE` when `.claude/` is broadly ignored with no product-file carve-out; silent + exit 0 otherwise (the data-driven `upgrading` loop keys off the `MIGRATE` sentinel):
|
|
92
92
|
|
|
93
93
|
```bash
|
|
94
94
|
F=.gitignore
|
|
95
95
|
[ -f "$F" ] || exit 0
|
|
96
96
|
if grep -qE '^[[:space:]]*\.claude/?[[:space:]]*$' "$F" \
|
|
97
97
|
&& ! grep -qE '^![[:space:]]*\.claude/(skills|agents|hooks|settings\.json)' "$F"; then
|
|
98
|
-
echo "
|
|
98
|
+
echo "MIGRATE — .claude/ broadly ignored with no product-file carve-out"
|
|
99
99
|
fi
|
|
100
100
|
```
|
|
101
101
|
|
|
@@ -50,9 +50,14 @@ The taxonomy is descriptive: every existing decision in `context.md` already fit
|
|
|
50
50
|
|
|
51
51
|
If a past edit broke the rule (decision rewritten in place), don't go back and reconstruct strike-throughs — the history is in git. Just follow the rule going forward.
|
|
52
52
|
|
|
53
|
-
## Detection
|
|
53
|
+
## Detection
|
|
54
54
|
|
|
55
|
-
There's nothing to detect on disk
|
|
55
|
+
Intentional no-op. There's nothing to detect on disk — the 0.29.0 changes are in skills and `FORGE.md`, so upgrading the framework files is the whole migration. The block below is the uniform-contract placeholder: it prints no `MIGRATE` sentinel and exits 0, so the data-driven `upgrading` loop correctly treats this in-range guide as "no action".
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# 0.29.0 is documentation + skill-behavior only — nothing on disk to migrate.
|
|
59
|
+
exit 0
|
|
60
|
+
```
|
|
56
61
|
|
|
57
62
|
## Validation
|
|
58
63
|
|