forge-orkes 0.33.0 → 0.34.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forge-orkes",
3
- "version": "0.33.0",
3
+ "version": "0.34.0",
4
4
  "description": "Set up the Forge meta-prompting framework for Claude Code in your project",
5
5
  "bin": {
6
6
  "create-forge": "./bin/create-forge.js"
@@ -28,8 +28,8 @@ git worktree list --porcelain 2>/dev/null \
28
28
  ```
29
29
 
30
30
  **If `in_main_checkout: true`** AND any Forge worktrees are reported:
31
- - Surface them at the top of the boot output, one line each: *"m{id} is live in worktree `{path}` on branch `{branch}`. Edits to its milestone state belong there; shared-doc edits here (`context.md`, `refactor-backlog.yml`) won't be visible to it until it rebases or pulls."*
32
- - This is informational `forge` continues to Rollup + selection. The operator now knows. (See FORGE.md State Ownership for the full taxonomy.)
31
+ - Surface them at the top of the boot output, one line each: *"m{id} is live in worktree `{path}` on branch `{branch}`. Its milestone state is **owned there** — selecting it from main triggers the Live-Worktree Ownership Gate (1.1a). Shared-doc edits here (`context.md`, `refactor-backlog.yml`) won't be visible to it until it rebases or pulls."*
32
+ - Surfacing continues to Rollup + selection — but it is **no longer purely informational**. Enforcement is deferred to **1.1a**, which fires only for the *selected* milestone (booting from main to work an unrelated milestone stays free). Record which worktrees were reported here so 1.1a can match the selection against them. (See FORGE.md State Ownership for the full taxonomy.)
33
33
 
34
34
  **If `in_main_checkout: false`** (this session is itself a worktree) AND `forge.worktree_rebase_check: true` in `.forge/project.yml` (default `false` — opt-in):
35
35
  - Diff `.forge/` between this worktree's `HEAD` and `origin/main` (or `main` if no remote), restricted to the **shared-mutable** + **stable-shared** files per the FORGE.md taxonomy (`context.md`, `refactor-backlog.yml`, `project.yml`, `constitution.md`, `design-system.md`, `roadmap.yml`, `requirements/m{N}.yml`).
@@ -74,7 +74,7 @@ Check state files:
74
74
  4. **Multiple (no arg, no anchor):** Show active + not_started milestones with status + `last_updated`. Default most recent. After main list, show **Deferred:** section (id, name, frozen status `was: {current.status}`, defer date, reason). *"{N} active. Most recent: [{name}] ({current.status}, {date}). This one, or switch?"*
75
75
  5. **One:** Auto-select. *"Resuming: [{name}] -- {current.status}, {percent}%"*
76
76
  6. **None active:** If deferred exist, mention them: *"No active milestones. {N} deferred — 'resume milestone {id}' to reactivate."* Else → init or create.
77
- 7. Load `milestone-{id}.yml`
77
+ 7. Load `milestone-{id}.yml`, then run the **Live-Worktree Ownership Gate (1.1a)** — it can block routing before any milestone-owned write.
78
78
  8. **Route on `current.status`, NOT `{percent}`.** Complete only at `complete`. 100% phases ≠ done -- verifying + reviewing must run.
79
79
  9. Report + **immediately route** (Step 3). Show: `current.status`, phase labels (Executed/Verified/Pending/In progress -- **never "Complete" for unverified**), `{percent}`. **No menus.** Position → action → invoke.
80
80
 
@@ -89,6 +89,35 @@ Beads enabled (`forge.beads_integration: true`) → `bd prime`. Optional.
89
89
 
90
90
  Read `.forge/context.md`. **Needs Resolution** unchecked → warn: *"{N} unresolved discrepancies."* Quick proceeds; Standard/Full blocked at planning.
91
91
 
92
+ ### 1.1a Live-Worktree Ownership Gate (enforced)
93
+
94
+ Single-owner-mutable state must be written by exactly one checkout. When this session is on **main** and the **selected** milestone has a **live worktree**, writing its state from here forks the cursor — main records one `current.status`, the worktree another, and a later resume anchored to the worktree silently contradicts main's claim. FORGE.md State Ownership forbids this; this gate is where the entrypoint **enforces** it, before routing to any skill that writes milestone-owned files. (See FORGE.md → State Ownership.)
95
+
96
+ **Trigger.** `in_main_checkout: true` (from the Step 1 preflight) **AND** the selected milestone has a live worktree — any of:
97
+ - the preflight's `git worktree list` reported a `forge/m-{id}-*` / `forge/{id}` branch for this milestone; or
98
+ - `milestone-{id}.yml` `lifecycle.worktree_mode` is `active` or `degraded` and a `lifecycle.worktree_path` is recorded; or
99
+ - `.forge/streams/active.yml` shows a stream for this milestone with a `runtime.worktree`.
100
+
101
+ Resolve the worktree path from the recorded `lifecycle.worktree_path` / `runtime.worktree`, or — if absent — from the base **Worktree Convention** (FORGE.md).
102
+
103
+ **When it does NOT trigger** (no-op — continue to routing): no live worktree for the selected milestone; or this session **is** the owning worktree (`in_main_checkout: false` and the branch anchors to this milestone); or the milestone has a recorded, still-current `lifecycle.ownership_override` (see option 4).
104
+
105
+ **When it triggers — STOP. Do not route** to `planning`, `executing`, `verifying`, `reviewing`, `quick-tasking` against this milestone, and do not write any of:
106
+ - `.forge/state/milestone-{id}.yml`
107
+ - `.forge/phases/milestone-{id}/`
108
+ - `.forge/research/milestone-{id}.md`
109
+
110
+ Present the four resolutions and wait for an explicit choice:
111
+
112
+ 1. **Enter the worktree** *(recommended)* — print the exact command (`cd {worktree_path}` then `/forge`); re-running there anchors to this milestone and writes land in the owner. This session does nothing further to the milestone.
113
+ 2. **Sync, then continue in the worktree** — bring main's commits in (`git -C {worktree_path} rebase main`, or merge), then work from the worktree. Use when main has changes the worktree needs first.
114
+ 3. **Retire the worktree** — only if it is dead/superseded. Close the stream, `git worktree remove {worktree_path}`, and clear `lifecycle.worktree_*` on the milestone — which ends its ownership so main may write. **Confirm before removing; never auto-remove a worktree.**
115
+ 4. **Recorded override** — deliberately write from main anyway. Write `lifecycle.ownership_override: {at: {ISO}, from: main, reason: "{operator's reason}"}` into `milestone-{id}.yml`, echo it in the boot line, and carry it into the next `reviewing` report. This is the **only** way past the block and it is **never silent**. (An override is scoped to this milestone; clear it once the worktree is retired or synced.)
116
+
117
+ **Shared project docs** (`context.md`, `refactor-backlog.yml`, `project.yml`, `constitution.md`, `roadmap.yml`, `requirements/m{N}.yml`) stay writable from main even when the gate is up — but warn they won't be visible to the live worktree until it pulls/rebases (same note as the preflight).
118
+
119
+ An agent must never present "override" as a peer default. Lead with option 1; reach for 4 only on the operator's explicit instruction with a reason.
120
+
92
121
  ### 1.2 Backlog + Desire Paths
93
122
 
94
123
  Check `.forge/refactor-backlog.yml`:
@@ -232,14 +232,18 @@ with the work it describes. Every artifact has a sharing class:
232
232
  | **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. |
233
233
 
234
234
  Cross-tree edits land on the current branch and are invisible to other worktrees
235
- until they pull/rebase. `forge` surfaces live worktrees at boot; `discussing`
236
- and `reviewing` warn before touching shared-mutable blocks; optional
237
- `forge.worktree_rebase_check` detects stale shared files inside worktrees. See
235
+ until they pull/rebase. `forge` surfaces live worktrees at boot **and enforces
236
+ the Live-Worktree Ownership Gate** (forge SKILL 1.1a): when invoked from main for
237
+ a milestone that has a live worktree, milestone-owned writes are **blocked**
238
+ until the operator enters the worktree, syncs it, retires it, or records an
239
+ explicit `lifecycle.ownership_override`. `discussing` and `reviewing` warn before
240
+ touching shared-mutable blocks; optional `forge.worktree_rebase_check` detects
241
+ stale shared files inside worktrees. See
238
242
  [ADR-011](../docs/decisions/ADR-011-shared-state-taxonomy.md) for rationale.
239
243
 
240
244
  ### State Ownership rules (quick reference)
241
245
 
242
- - `state/milestone-{id}.yml` is the **single source of truth**; exactly one agent owns it at a time. **Other worktrees never write it** — promoted from advice to explicit rule, because catching yourself before the first wrong edit is the part the framework can help with.
246
+ - `state/milestone-{id}.yml` is the **single source of truth**; exactly one agent owns it at a time. **Other worktrees never write it** — and from a main checkout this is **enforced**, not just advised: the Live-Worktree Ownership Gate (forge SKILL 1.1a) blocks milestone-owned writes from main while a live worktree owns the milestone, with a recorded `lifecycle.ownership_override` as the only (never-silent) bypass.
243
247
  - Worktree / parallel agents write **only** their own milestone file and **append** desire-path files. They **never** write `index.yml`.
244
248
  - `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.
245
249
  - For shared-mutable files: write only your milestone's block; within a block, append-only (strike through, don't rewrite).
@@ -0,0 +1,66 @@
1
+ # Migration Guide: Live-Worktree Ownership Gate (Forge 0.34.0)
2
+
3
+ Applies to every project, but it is **framework-behavior only — nothing on disk
4
+ to migrate**. The change lives entirely in framework-owned files that
5
+ `upgrading` overwrites for you (`forge/SKILL.md`, `FORGE.md`). This guide exists
6
+ so the change is recorded and discoverable; its Detection is an intentional no-op
7
+ (issue [#7](https://github.com/Attuned-Media/forge/issues/7)).
8
+
9
+ ## What changed
10
+
11
+ `forge` boot already surfaced live Forge worktrees, but the warning was
12
+ **informational** — a session on `main` could still write single-owner-mutable
13
+ milestone state while a worktree owned that milestone, forking the cursor (main
14
+ says `reviewing`, the worktree says `planning`, a later resume contradicts the
15
+ earlier claim).
16
+
17
+ 0.34.0 promotes that warning to an **enforced gate** (forge SKILL **1.1a**):
18
+
19
+ - **Trigger** — invoked from `main` AND the selected milestone has a live
20
+ worktree (recorded `lifecycle.worktree_path` / `lifecycle.worktree_mode`,
21
+ a `forge/m-{id}-*` branch in `git worktree list`, or a stream `runtime.worktree`).
22
+ - **Effect** — milestone-owned writes are blocked
23
+ (`state/milestone-{id}.yml`, `phases/milestone-{id}/`, `research/milestone-{id}.md`)
24
+ and routing stops until the operator picks one resolution: **enter** the
25
+ worktree, **sync** it, **retire** it, or record an explicit
26
+ `lifecycle.ownership_override: {at, from: main, reason}` — the only,
27
+ never-silent bypass.
28
+ - Shared project docs (`context.md`, `refactor-backlog.yml`, `project.yml`, …)
29
+ stay writable from `main`, with the existing "not visible to the worktree
30
+ until it pulls/rebases" warning.
31
+
32
+ `FORGE.md` State Ownership is updated from advice to enforcement to match.
33
+
34
+ ## Prerequisites
35
+
36
+ 1. On the new version's framework files (`npx forge-orkes upgrade`, or the
37
+ `upgrading` skill).
38
+
39
+ ## Detection
40
+
41
+ No on-disk migration — the new behavior ships in framework-owned files that the
42
+ upgrade already overwrote. The `lifecycle.ownership_override` field is written
43
+ lazily, only when an operator records an override; absent means "no override,"
44
+ which is the correct default. Intentional no-op:
45
+
46
+ ```bash
47
+ # Skill-behavior change only — enforcement lives in forge/SKILL.md + FORGE.md,
48
+ # both framework-owned and synced by the upgrade. Nothing on disk to migrate.
49
+ exit 0
50
+ ```
51
+
52
+ ## Migration steps
53
+
54
+ None. After the upgrade, the next `/forge` invoked from `main` against a
55
+ milestone with a live worktree will enforce the gate automatically.
56
+
57
+ ## Validation
58
+
59
+ - `grep -c '1.1a Live-Worktree Ownership Gate' .claude/skills/forge/SKILL.md`
60
+ returns 1.
61
+ - From a `main` checkout with a live `forge/m-*` worktree, run `/forge` and
62
+ select that milestone — Forge blocks milestone-owned writes and offers the
63
+ enter / sync / retire / recorded-override choices instead of routing straight
64
+ into planning/executing/verifying/reviewing.
65
+ - From the owning worktree (or for a milestone with no live worktree), `/forge`
66
+ routes normally — the gate is a no-op.
@@ -97,6 +97,11 @@ releases:
97
97
  bump: minor
98
98
  reserved_at: "2026-06-21"
99
99
  summary: "Worktree convention promoted to base + experimental-skill drift fix + Chief registry drift check (issues #4/#5/#6). (1) FORGE.md gains a base 'Worktree Convention' (path/anchor/branch + orchestration.worktree_root resolution + lifecycle.worktree_path authority) so Chief/Streams has a fallback when a worktree was created outside orchestrating, and the convention stays upgrade-synced regardless of the experimental skill. (2) upgrading no longer blanket-skips installed experimental skills — it diffs them against experimental/*/source and offers a preview/confirm re-sync (warn at minimum), closing the silent-freeze where base migrations (e.g. 0.28.0 worktree-root) became no-ops against a frozen orchestrating skill. (3) migration-guide template gains an authoring guard: guides whose behavior lives in an experimental skill must detect the skill's content, not just the version stamp. (4) chief-of-staff gains an advisory Registry Drift Check (Show + Sync) reconciling state/index.yml active milestones against streams/active.yml."
100
+ - milestone: 16
101
+ version: "0.34.0"
102
+ bump: minor
103
+ reserved_at: "2026-06-21"
104
+ summary: "Live-Worktree Ownership Gate (issue #7). forge boot's worktree surfacing was advisory, so a session on main could write single-owner-mutable milestone state (milestone-{id}.yml, phases/, research/) while a live worktree owned the milestone — forking the cursor (main 'reviewing' vs worktree 'planning'). forge SKILL gains an enforced gate (1.1a): when invoked from main and the selected milestone has a live worktree, milestone-owned writes are blocked and routing stops until the operator enters the worktree, syncs it, retires it, or records an explicit lifecycle.ownership_override (the only, never-silent bypass). Shared project docs stay writable from main with a not-visible-until-sync warning. FORGE.md State Ownership promoted from advice to enforcement. Also folds in dev/template skill drift cleanup: forge/discussing/planning dev .claude/skills copies were behind the template (chief-streams + context-archive content) — brought to parity."
100
105
 
101
106
  # Note on the 15 / 0.24.0 ordering: reserved as max(0.23.0)+minor. origin/main was
102
107
  # already at 0.23.0 when this shipped (M10/M12/M13/M14 all merged), so 0.24.0 is a