forge-orkes 0.74.0 → 0.77.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.
@@ -0,0 +1,120 @@
1
+ # Migration Guide: State rollup made mechanical (Forge 0.77.0)
2
+
3
+ Applies to projects upgrading to 0.77.0 or later. State Rollup 1.0 and the
4
+ Stream Rollup (ADR-015 addendum) — previously advisory skill prose that an
5
+ agent had to remember to run at boot — are now an executable,
6
+ `.claude/hooks/forge-state-rollup.sh`, invoked mechanically by a `SessionStart`
7
+ hook. A boot session can no longer skip the render and fall back to reading a
8
+ stale `.forge/state/index.yml` / `.forge/streams/active.yml` cache, or
9
+ hand-reconstruct the registries from memory — the exact failure mode filed as
10
+ issue #22.
11
+
12
+ `/upgrading` ships the new hook file (`.claude/hooks/forge-state-rollup.sh`)
13
+ like any other framework file. It does **not** wire the `SessionStart`
14
+ registration, because `.claude/settings.json` is a **user-owned file** —
15
+ upgrades never overwrite it (FORGE.md → State Ownership, "Stable shared"
16
+ class notes settings.json is gitignored-carve-out territory, propagated only
17
+ via explicit installer steps, never blanket overwrite). Without this
18
+ migration's one manual step, the hook ships but is never invoked: the
19
+ executable exists, nothing mechanically triggers it.
20
+
21
+ Projects that ran `initializing` fresh on 0.77.0+ (or already carry the
22
+ `SessionStart` block from an earlier partial adoption) need nothing further.
23
+
24
+ ## Prerequisites
25
+
26
+ 1. On the new version's framework files (`npx forge-orkes upgrade`, or the
27
+ `upgrading` skill) — so `.claude/hooks/forge-state-rollup.sh` and
28
+ `.claude/hooks/forge-release-fold.sh` are present and executable.
29
+ 2. Working tree clean or changes committed — this migration edits
30
+ `.claude/settings.json`, a tracked file.
31
+
32
+ ## Detection
33
+
34
+ Keyed on **the executable existing (or the version already at/above 0.77.0)
35
+ while the SessionStart wiring is absent** — the shipped-but-unwired gap. Uses
36
+ `jq` to inspect `.claude/settings.json`'s `hooks.SessionStart` array for an
37
+ entry referencing `forge-state-rollup`; degrades to a plain-text grep if `jq`
38
+ is not installed. Silent in a non-Forge / non-git tree, silent once the hook
39
+ is wired:
40
+
41
+ ```bash
42
+ git rev-parse --is-inside-work-tree >/dev/null 2>&1 || exit 0
43
+ [ -x .claude/hooks/forge-state-rollup.sh ] || exit 0
44
+
45
+ settings=".claude/settings.json"
46
+ [ -f "$settings" ] || {
47
+ echo "MIGRATE — forge-state-rollup.sh is present but $settings does not exist; add it with the SessionStart hook below"
48
+ exit 0
49
+ }
50
+
51
+ if command -v jq >/dev/null 2>&1; then
52
+ wired="$(jq -r '
53
+ (.hooks.SessionStart // []) as $entries
54
+ | [$entries[].hooks[]?.command // "" | select(contains("forge-state-rollup"))]
55
+ | length > 0
56
+ ' "$settings" 2>/dev/null)"
57
+ if [ "$wired" != "true" ]; then
58
+ echo "MIGRATE — $settings has no SessionStart hook referencing forge-state-rollup.sh; the executable shipped but nothing mechanically triggers it"
59
+ fi
60
+ else
61
+ if ! grep -q "forge-state-rollup" "$settings" 2>/dev/null; then
62
+ echo "MIGRATE — $settings has no reference to forge-state-rollup.sh (jq unavailable, ran plain-text check); add the SessionStart hook below"
63
+ fi
64
+ fi
65
+ ```
66
+
67
+ ## Migration steps
68
+
69
+ ### 1. Add the SessionStart hook block
70
+
71
+ Open `.claude/settings.json` and add (or merge into) a `hooks.SessionStart`
72
+ array entry:
73
+
74
+ ```json
75
+ {
76
+ "hooks": {
77
+ "SessionStart": [
78
+ {
79
+ "matcher": "startup|resume|clear",
80
+ "hooks": [
81
+ {
82
+ "type": "command",
83
+ "command": "[ -x \"$CLAUDE_PROJECT_DIR/.claude/hooks/forge-state-rollup.sh\" ] && \"$CLAUDE_PROJECT_DIR/.claude/hooks/forge-state-rollup.sh\" || true"
84
+ }
85
+ ]
86
+ }
87
+ ]
88
+ }
89
+ }
90
+ ```
91
+
92
+ If `hooks.SessionStart` already has other entries (e.g. from a project-local
93
+ customization), append this object to the existing array rather than
94
+ replacing it. If `hooks` exists but has no `SessionStart` key yet, add the key
95
+ alongside the existing `PreToolUse`/`PostToolUse` blocks.
96
+
97
+ The `[ -x ... ] && ... || true` guard means the hook is a no-op — never a
98
+ boot failure — on any checkout where the script is absent or not executable
99
+ (SessionStart hooks are non-blocking; `forge-state-rollup.sh` itself also
100
+ always exits 0).
101
+
102
+ ### 2. Commit the settings change
103
+
104
+ ```bash
105
+ git add .claude/settings.json
106
+ git commit -m "chore(forge): wire forge-state-rollup SessionStart hook (0.77.0)"
107
+ ```
108
+
109
+ ## Validation
110
+
111
+ - Start a new session, or run `/clear` — the boot summary line should include
112
+ `[forge-state-rollup] rendered index.yml (…) …` (plus an `active.yml` clause
113
+ if `.forge/streams/` exists), confirming the hook actually ran.
114
+ - `jq '.hooks.SessionStart' .claude/settings.json` prints a non-null array
115
+ containing the `forge-state-rollup` command, not `null`.
116
+ - Re-running the Detection block above now prints nothing (exits silently) —
117
+ the gap is closed.
118
+ - `.forge/state/index.yml` and `.forge/streams/active.yml` (if applicable)
119
+ exist on disk and are fresh — their mtimes update on every boot, since the
120
+ hook re-renders unconditionally.
@@ -99,6 +99,20 @@ verification:
99
99
  # # only — the private key lives host-side, in the deploy Environment).
100
100
  # # Empty ⇒ git config gpg.ssh.allowedSignersFile.
101
101
 
102
+ # orchestration: # OPTIONAL — worktree behavior (M10 / streams). Absent → defaults.
103
+ # worktree_root: "" # Where Forge worktrees live. Default ../<repo-basename>-worktrees.
104
+ # # Relative → resolves against repo root; absolute / ~ honored verbatim.
105
+ # worktree_hydrate: [] # OPTIONAL list of superproject-relative paths — required-but-gitignored
106
+ # # artifacts copied into a fresh worktree so it can build and reach its
107
+ # # tools (a clean worktree checks out TRACKED files only). Guarded
108
+ # # source-exists && dest-absent: never overwrites, never git-adds, so a
109
+ # # secret-bearing file stays gitignored/untracked in both trees and never
110
+ # # enters git history (.mcp.json the canonical case). Applied by
111
+ # # orchestrating at creation AND asserted in executing's Workspace
112
+ # # Prerequisites → worktrees of ANY origin covered. Omit → no propagation.
113
+ # # e.g. [".mcp.json", ".env.local"]. Dependency install stays with the
114
+ # # executing/verifying preflight, not this key.
115
+
102
116
  success_criteria: # How do we know we're done?
103
117
  - "" # e.g., "User can create and edit posts"
104
118
  - "" # e.g., "All tests pass with >80% coverage"