forge-orkes 0.77.0 → 0.80.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.
Files changed (41) hide show
  1. package/bin/create-forge.js +27 -0
  2. package/experimental/m10/README.md +4 -4
  3. package/experimental/m10/install.sh +10 -9
  4. package/experimental/m10/source/hooks/protect-primary-checkout.sh +149 -0
  5. package/package.json +1 -1
  6. package/template/.claude/hooks/forge-context-migrate.sh +297 -0
  7. package/template/.claude/hooks/forge-size-gate.sh +175 -0
  8. package/template/.claude/hooks/forge-state-rollup.sh +135 -2
  9. package/template/.claude/hooks/protect-primary-checkout.sh +149 -0
  10. package/template/.claude/hooks/skill-gate-tiers.txt +6 -0
  11. package/template/.claude/hooks/tests/forge-context-migrate.test.sh +166 -0
  12. package/template/.claude/hooks/tests/forge-size-gate.test.sh +132 -0
  13. package/template/.claude/hooks/tests/protect-primary-checkout.test.sh +147 -0
  14. package/template/.claude/settings.json +14 -1
  15. package/template/.claude/skills/discussing/SKILL.md +30 -31
  16. package/template/.claude/skills/executing/SKILL.md +3 -3
  17. package/template/.claude/skills/forge/SKILL.md +112 -170
  18. package/template/.claude/skills/forge/references/manual-fallback-procedures.md +54 -0
  19. package/template/.claude/skills/initializing/SKILL.md +20 -1
  20. package/template/.claude/skills/planning/SKILL.md +11 -9
  21. package/template/.claude/skills/researching/SKILL.md +2 -0
  22. package/template/.claude/skills/reviewing/SKILL.md +17 -0
  23. package/template/.claude/skills/upgrading/SKILL.md +22 -2
  24. package/template/.claude/skills/verifying/SKILL.md +2 -2
  25. package/template/.forge/FORGE.md +81 -90
  26. package/template/.forge/bin/new-worktree.sh +61 -0
  27. package/template/.forge/bin/tests/new-worktree.test.sh +70 -0
  28. package/template/.forge/checks/forge-jarvis-awareness.sh +46 -2
  29. package/template/.forge/checks/forge-jarvis-relay.sh +64 -16
  30. package/template/.forge/checks/tests/forge-jarvis-awareness.test.sh +58 -0
  31. package/template/.forge/checks/tests/forge-jarvis-relay.test.sh +50 -0
  32. package/template/.forge/git-hooks/pre-commit +57 -0
  33. package/template/.forge/git-hooks/tests/pre-commit.test.sh +97 -0
  34. package/template/.forge/migrations/0.78.0-weld-primary-checkout.md +66 -0
  35. package/template/.forge/migrations/0.80.0-context-md-sharding.md +158 -0
  36. package/template/.forge/migrations/0.80.0-size-gate-wiring.md +145 -0
  37. package/template/.forge/templates/constitution.md +1 -1
  38. package/template/.forge/templates/context-milestone.md +30 -0
  39. package/template/.forge/templates/slice-runner/config.yml +7 -1
  40. package/template/.forge/templates/state/desire-path.yml +3 -0
  41. package/experimental/m10/source/hooks/forge-branch-guard.sh +0 -61
@@ -18,55 +18,54 @@ Structured conversation: approach, trade-offs, decisions. Clarity, not artifacts
18
18
  ## Boundaries
19
19
 
20
20
  - No plans or code
21
- - Writes `context.md` progressively (after each confirmed decision, not just at handoff)
21
+ - Writes `context/{id}.md` progressively (after each confirmed decision, not just at handoff) — `context-log.md` instead in advisory mode (no milestone yet)
22
22
  - No phase/plan required
23
23
  - Entered via a worktree already, for new work (R10, `forge/SKILL.md` Step 3) — if this skill is somehow invoked directly on the main checkout for new work, enter one now before writing anything.
24
24
 
25
25
  ## Progressive Persistence
26
26
 
27
27
  > **HARD GATE — NOT A GUIDELINE. NO EXCEPTIONS.**
28
- > Write to `.forge/context.md` after EVERY confirmed decision, before asking the next question.
28
+ > Write to `.forge/context/{id}.md` after EVERY confirmed decision, before asking the next question ({id} = the milestone this discussion is scoped to).
29
29
  > If you reach convergence without having written each decision individually — you already violated this rule.
30
30
 
31
- > **Advisory mode (no milestone yet):** Storage still exists. Use `### M? — {topic} (drafting)` heading. Do NOT wait for milestone creation in Step A to start writing. First decision → create heading → append. Same protocol as milestone-bound discussions.
31
+ > **Advisory mode (no milestone yet):** Storage still exists — write to `.forge/context-log.md` instead (there is no `{id}` to shard by yet). Use `### M? — {topic} (drafting)` heading. Do NOT wait for milestone creation in Step A to start writing. First decision → create heading → append. Once Step A creates the milestone, migrate that drafting block from `context-log.md` into the new `.forge/context/{id}.md`.
32
32
 
33
33
  After each user response that confirms a decision:
34
34
 
35
35
  1. **STOP** — do not continue the discussion
36
- 2. **Write to disk** — append to `.forge/context.md` (create from template if missing)
37
- - **Path is always `.forge/context.md`** — never `.forge/phases/*/context.md`, never inline memory
36
+ 2. **Write to disk** — append to `.forge/context/{id}.md` (create from `.forge/templates/context-milestone.md` if missing); `.forge/context-log.md` instead in advisory mode
37
+ - **Path is always `.forge/context/{id}.md`** (or `.forge/context-log.md` pre-milestone) — never `.forge/phases/*/context.md`, never inline memory, and never the rendered `.forge/context.md` index (derived — read for orientation, never write to it)
38
38
  3. **THEN** continue to the next question
39
39
 
40
40
  Never accumulate decisions in working memory. Never batch writes to convergence.
41
41
 
42
- **Common failure mode:** Agent says "decisions live in conversation; planning writes context.md." This is WRONG. Discussing writes context.md. Planning reads it.
42
+ **Common failure mode:** Agent says "decisions live in conversation; planning writes context.md." This is WRONG. Discussing writes context/{id}.md. Planning reads it.
43
43
 
44
44
  ### Write Protocol
45
45
 
46
- `context.md` is **shared mutable** state per FORGE.md State Ownership writes follow two structural rules:
47
- - **Scope to your milestone's block.** Different milestone blocks git merges cleanly across worktrees.
48
- - **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.
49
- - **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.
46
+ `context/{id}.md` is **single-owner mutable, per milestone** (ADR-033) sharding by milestone means different milestones already write different files, so the old shared-file merge-safety rules collapse to one:
47
+ - **Append-only within your file.** When superseding an older decision, *strike through* (`~~old decision~~`) and append the new line below — never rewrite in place. Reading the history of a decision stays possible by inspection.
48
+ - **Keep active context active.** Write current/open decisions to `.forge/context/{id}.md`. Do not rehydrate old milestone blocks from `.forge/context-archive.md` unless the user is amending that historical decision.
50
49
 
51
50
  **On first decision of the session:**
52
- - Check if `.forge/context.md` exists. If not → create it from `.forge/templates/context.md`
53
- - Add a milestone heading inside `## Locked Decisions`: `### M{id} — {name} (drafting)` (use "M?" if no milestone yet)
51
+ - Check if `.forge/context/{id}.md` exists. If not → create it from `.forge/templates/context-milestone.md`
52
+ - Heading: `### M{id} — {name} (drafting)` (use "M?" and write to `.forge/context-log.md` instead if no milestone yet — see Advisory mode above)
54
53
  - If the needed historical decision is archived, cite the archive in the new active decision instead of copying the whole block back.
55
- - **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.
54
+ - **Cross-tree liveness check (informational).** If editing an existing `context/{id}.md` 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/{id}.md`, this is a heads-up, not a block.
56
55
 
57
56
  **On each confirmed decision:**
58
57
  - Append under the milestone heading: `- **[Topic]**: [Decision]. Reason: [Why]`
59
58
 
60
- **On superseding a prior decision (in your own milestone's block):**
59
+ **On superseding a prior decision:**
61
60
  - Find the original line. Wrap it in `~~ ~~` (markdown strikethrough). DO NOT delete it.
62
61
  - Append the new decision on a new line below it: `- **[Topic]**: [Decision]. Reason: [Why]. Supersedes ~~prior on {date}~~.`
63
- - Why: shared-mutable append-only rule (FORGE.md State Ownership). Decisions stay readable as history; concurrent writes from another worktree on a different bullet can't conflict with this one.
62
+ - Why: append-only rule. Decisions stay readable as history; concurrent writes from another worktree touching this same milestone's file on a different bullet can't conflict with this one.
64
63
 
65
64
  **On deferred ideas** (user says "not now" / "later" / "skip"):
66
- - Append to `## Deferred Ideas` immediately: `- [Idea] — Deferred because: [reason]`
65
+ - Append to this milestone's `## Deferred` heading in `.forge/context/{id}.md` immediately: `- [Idea] — Deferred because: [reason]`. Genuinely cross-cutting (not owned by this milestone) → `.forge/context/_shared.md`'s `## Deferred Ideas` heading instead — never guess a milestone onto a cross-cutting idea.
67
66
 
68
67
  **On discretion areas** (left to agent judgment):
69
- - Append to `## Discretion Areas` immediately
68
+ - Append to this milestone's `## Discretion` heading in `.forge/context/{id}.md` immediately. Cross-cutting → `.forge/context/_shared.md`'s `## Discretion Areas` heading instead.
70
69
 
71
70
  **At Phase Handoff:**
72
71
  - Rename `(drafting)` → `(locked {date})` — decisions are already written, just finalize the heading
@@ -113,11 +112,11 @@ If fresh (after `/clear`):
113
112
  ```
114
113
  Read: .forge/state/milestone-{id}.yml → current position, progress (skip if no milestone — advisory mode)
115
114
  Read: .forge/project.yml → tech stack, project description
116
- Read: .forge/context.md → existing locked decisions (if exists)
115
+ Read: .forge/context/{id}.md → this milestone's existing locked decisions (if exists)
117
116
  Read: .forge/constitution.md → active gates (if exists)
118
117
  ```
119
118
 
120
- **Advisory mode (no milestone):** Skip milestone state load. Progressive persistence still applies — writes go to `.forge/context.md` under `### M? — {topic} (drafting)` heading from the first decision. Milestone gets created in Step A only if scope warrants it.
119
+ **Advisory mode (no milestone):** Skip milestone state load. Progressive persistence still applies — writes go to `.forge/context-log.md` under `### M? — {topic} (drafting)` heading from the first decision. Milestone gets created in Step A only if scope warrants it.
121
120
 
122
121
  Check `.forge/phases/` for research. If inline-only: *"Summarize findings, or re-scan?"*
123
122
 
@@ -145,7 +144,7 @@ Brief context paragraph from research.
145
144
 
146
145
  Surface 3-5 decisions that matter.
147
146
 
148
- **After each user response:** write confirmed decisions to `context.md` immediately (see Progressive Persistence).
147
+ **After each user response:** write confirmed decisions to `context/{id}.md` immediately (see Progressive Persistence).
149
148
 
150
149
  ### Step 2: Facilitate, Don't Dictate
151
150
 
@@ -176,17 +175,17 @@ AskUserQuestion:
176
175
 
177
176
  Open-ended via prose: *"Tried before?" / "Must-haves or must-nots?"* 1-2 at a time.
178
177
 
179
- **After each user response:** write confirmed decisions/constraints to `context.md` immediately.
178
+ **After each user response:** write confirmed decisions/constraints to `context/{id}.md` immediately.
180
179
 
181
180
  ### Step 4: Functionality Distillation
182
181
 
183
182
  Apply Functionality Distillation (above), grounded in research findings.
184
183
 
185
- **After each user response:** write confirmed behavioral decisions to `context.md` immediately.
184
+ **After each user response:** write confirmed behavioral decisions to `context/{id}.md` immediately.
186
185
 
187
186
  ### Step 5: Pre-Convergence Audit
188
187
 
189
- **Before summarizing, read `.forge/context.md` and verify all confirmed decisions are present.**
188
+ **Before summarizing, read `.forge/context/{id}.md` (or `.forge/context-log.md` in advisory mode) and verify all confirmed decisions are present.**
190
189
 
191
190
  If any decision from the conversation is missing from the file → write it now. Do not proceed to the summary until the file matches the conversation. This is a hard gate.
192
191
 
@@ -213,7 +212,7 @@ options:
213
212
  ```
214
213
  Read: .forge/phases/milestone-{id}/{phase}-{name}/plan-{NN}.md → the plan
215
214
  Read: .forge/requirements/m{N}.yml → source requirements (current milestone)
216
- Read: .forge/context.md → locked decisions
215
+ Read: .forge/context/{id}.md → this milestone's locked decisions
217
216
  Read: .forge/constitution.md → active gates
218
217
  ```
219
218
 
@@ -315,9 +314,9 @@ If no milestone exists (advisory discussion — forge routed here without tier/m
315
314
  - `current.tier` = detected tier
316
315
  - `current.status` = `planning` (Standard) / `architecting` (Full) / `not_started` (Quick)
317
316
  - `current.last_updated` = now
318
- - `decisions[]` = locked decisions from `context.md`
317
+ - `decisions[]` = locked decisions from the `context-log.md` drafting block
319
318
  - Regenerate `.forge/state/index.yml` via the `forge` **Rollup** (read all `milestone-*.yml` → rewrite registry). Do not hand-add the entry. (Create `index.yml` from `.forge/templates/state/index.yml` first if missing.)
320
- 4. **Update `context.md`** scope decisions under `### M{id} — {name} (locked {date})`
319
+ 4. **Migrate the drafting block** — move the `### M? — {topic} (drafting)` block from `.forge/context-log.md` into `.forge/context/{id}.md` (create from `.forge/templates/context-milestone.md` if missing), renaming the heading to `### M{id} — {name} (drafting)`
321
320
  5. **Quick tier?** → *"Scope is Quick. `/clear` then `/forge {id}` for quick-tasking."* End.
322
321
  6. Proceed to Step B with new milestone.
323
322
 
@@ -326,17 +325,17 @@ If milestone exists → skip to Step B.
326
325
  ### Step B: Standard Handoff
327
326
 
328
327
  > **HARD GATE — VERIFY BEFORE HANDOFF.**
329
- > Read `.forge/context.md` now. Count decisions under the active milestone heading. Compare against decisions confirmed in this conversation.
328
+ > Read `.forge/context/{id}.md` now. Count decisions under `## Locked Decisions`. Compare against decisions confirmed in this conversation.
330
329
  > - **If counts match** → proceed to handoff steps below.
331
330
  > - **If file is missing, heading absent, or decisions undercount** → progressive persistence failed. STOP. Do NOT recommend `/clear`. Write the missing decisions now from conversation memory, then re-verify. Only then proceed.
332
331
  > - **Never claim "state written" without having just read the file.** The recommendation `/clear` is destructive to working memory — earn it.
333
332
 
334
- 1. **Promote decisions in `context.md`** -- Rename milestone heading from `(drafting)` → `(locked {date})`. Decisions already written progressively — just finalize:
333
+ 1. **Promote decisions in `context/{id}.md`** -- Rename milestone heading from `(drafting)` → `(locked {date})`. Decisions already written progressively — just finalize:
335
334
  - Verify all confirmed decisions present under `## Locked Decisions`
336
335
  - Verify deferred items under `## Deferred Ideas`
337
336
  - Verify discretion areas under `## Discretion Areas`
338
- - Add any unresolved items to `## Needs Resolution`
339
- - If `context.md` already exists (post-planning discussion), update relevant sections + log amendments
337
+ - Add any unresolved items to `.forge/context-log.md`'s `## Needs Resolution`
338
+ - If `context/{id}.md` already exists (post-planning discussion), update relevant sections + log amendments in `context-log.md`'s `## Amendment Log`
340
339
  2. **Update state** -- `current.status` = `planning` (`architecting` for Full) in milestone yml
341
340
  3. **State-sync commit** (State Commit Protocol): `git -C {worktree_path} add .forge/` then `git -C {worktree_path} commit -m "chore(forge): sync state after discussing — m{N} {name}"` (worktree form — recorded `lifecycle.worktree_path` is authoritative over cwd; see FORGE.md State Commit Protocol. Scoped; never `git add .`).
342
- 4. **Recommend clear:** *"State synced and verified ({N} decisions in context.md). `/clear` then `/forge` for {planning/architecting}."*
341
+ 4. **Recommend clear:** *"State synced and verified ({N} decisions in context/{id}.md). `/clear` then `/forge` for {planning/architecting}."*
@@ -127,7 +127,7 @@ For each task in the plan:
127
127
 
128
128
  1. **Read** task XML (name, files, action, verify, done)
129
129
  2. **Mark in-progress** — `TaskUpdate` to `in_progress`
130
- 3. **Check** context.md — honor locked decisions exactly
130
+ 3. **Check** context/{id}.md — honor locked decisions exactly
131
131
  4. **Implement** per action instructions
132
132
  5. **Verify** using the verify step
133
133
  6. **Confirm** done criteria met
@@ -317,7 +317,7 @@ Once a task's verification bookkeeping settles (3-Strike result known, declared-
317
317
  | Task carries a `complexity` tag whose resolved model **differs from the live session model** (COST, M24) | Spawn a fresh executor on that resolved model — even under 40% context (real routing). |
318
318
  | Task carries a `complexity` tag but resolves to the **live session model** (e.g. no `models:` block) | Spawn changes nothing — treat the tag as a context signal only: spawn **iff** a row above fires. Otherwise run inline. |
319
319
 
320
- **Spawn via Agent tool** with: relevant plan details, specific files, locked decisions from context.md, clear success criteria. **Resolve the model PER TASK**, not once per skill run: `models.by_complexity.{task.complexity}` → `models.skills.executing` → `models.default` → parent (complexity overrides skill — FORGE.md → Model Routing). **Then compare the resolved model to the live session model** (the model this session is actually running on): differ → spawn (mandatory routing); equal → the tag is a context signal, not a routing obligation. Display per spawn: *"Spawning executor with model: {model} (from {source})"*
320
+ **Spawn via Agent tool** with: relevant plan details, specific files, locked decisions from context/{id}.md, clear success criteria. **Resolve the model PER TASK**, not once per skill run: `models.by_complexity.{task.complexity}` → `models.skills.executing` → `models.default` → parent (complexity overrides skill — FORGE.md → Model Routing). **Then compare the resolved model to the live session model** (the model this session is actually running on): differ → spawn (mandatory routing); equal → the tag is a context signal, not a routing obligation. Display per spawn: *"Spawning executor with model: {model} (from {source})"*
321
321
 
322
322
  **Why the tag gates the spawn (predicate A — the spawn must change the model).** Routing only *does* something when a task's resolved model differs from the **live session model**; a same-model spawn is pure briefing overhead — m-30 burned ~315k subagent tokens spawning tasks that resolved straight back to the parent model for zero routing benefit. So the mandatory spawn fires only when resolving actually swaps the model (which requires a `models:` block whose resolution lands on a different tier than the one this session runs on). With **no `models:` block** every resolved model equals the parent == the live session model, so tagged tasks run inline unless a context trigger (20+ files / deep subsystem / >40%) independently calls for a fresh agent. The tag still marks work "worth routing," and an inline task genuinely cannot be re-routed — but that leak only matters when a different model was actually available, which is exactly the resolved-≠-live case the gate keeps mandatory. (A full parent-as-orchestrator model — spawn everything, parent never implements — remains a deferred follow-up, justified by M24 outcome-log evidence, not implemented here.)
323
323
 
@@ -360,7 +360,7 @@ Append **one file per observation** to `.forge/state/desire-paths/` — copy `.f
360
360
  - **User corrections**: Repeated correction matching a prior one → `type: user_correction`
361
361
  - **Agent struggles**: Multiple attempts or user guidance needed → `type: agent_struggle`
362
362
 
363
- **Set `scope` at capture** (see ADR-012): `framework` when the fix this signal implies targets Forge's own skills/templates (a skill's check, a plan/tier heuristic, a template); `project` when it targets user-owned files (`constitution.md`, `design-system.md`, `context.md`, project setup). Record `suggestion_target` when you know the file/skill it touches. `scope: framework` is what later lets `forge` review route the signal upstream instead of trapping it in this project.
363
+ **Set `scope` at capture** (see ADR-012): `framework` when the fix this signal implies targets Forge's own skills/templates (a skill's check, a plan/tier heuristic, a template); `project` when it targets user-owned files (`constitution.md`, `design-system.md`, `context/{id}.md`, project setup). Record `suggestion_target` when you know the file/skill it touches. `scope: framework` is what later lets `forge` review route the signal upstream instead of trapping it in this project.
364
364
 
365
365
  ## Cross-Layer Seam Check
366
366