opencode-thrum-pro 0.1.5 → 0.1.6

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 (67) hide show
  1. package/assets/commands/thrum-_compact-runtime-commands.md +61 -0
  2. package/assets/commands/thrum-_snapshot-protocol.md +17 -6
  3. package/assets/commands/thrum-_stamp-protocol.md +9 -2
  4. package/assets/commands/thrum-compact-extended.md +352 -0
  5. package/assets/commands/thrum-compact.md +300 -0
  6. package/assets/commands/thrum-inbox.md +1 -1
  7. package/assets/commands/thrum-restart-extended.md +84 -11
  8. package/assets/commands/thrum-restart.md +105 -13
  9. package/assets/commands/thrum-send.md +4 -1
  10. package/assets/commands/thrum-sleep-extended.md +67 -46
  11. package/assets/commands/thrum-sleep.md +67 -58
  12. package/assets/skills/adversarial-critique/SKILL.md +5 -8
  13. package/assets/skills/brainstorm-steward/SKILL.md +65 -11
  14. package/assets/skills/brainstormer-staying-current/SKILL.md +1 -4
  15. package/assets/skills/choosing-subagent-models/SKILL.md +14 -0
  16. package/assets/skills/conversation-only-context/SKILL.md +11 -11
  17. package/assets/skills/conversation-only-context/resources/driver-subagent-pattern.md +1 -1
  18. package/assets/skills/conversation-only-context/resources/remote-environment-scenarios.md +1 -1
  19. package/assets/skills/coordinator-assessing-agent-completion/SKILL.md +98 -6
  20. package/assets/skills/coordinator-context-monitoring/SKILL.md +29 -19
  21. package/assets/skills/coordinator-deploying-a-node/SKILL.md +124 -0
  22. package/assets/skills/coordinator-dispatching-work/SKILL.md +24 -11
  23. package/assets/skills/coordinator-hotpath-merge-gate/SKILL.md +62 -20
  24. package/assets/skills/coordinator-managing-state-and-lifecycle/SKILL.md +6 -6
  25. package/assets/skills/coordinator-merging-code/SKILL.md +25 -11
  26. package/assets/skills/coordinator-philosophy-merge-gate/SKILL.md +28 -7
  27. package/assets/skills/coordinator-plan-reconcile-gate/SKILL.md +3 -3
  28. package/assets/skills/coordinator-rolling-out-to-nodes/SKILL.md +92 -0
  29. package/assets/skills/coordinator-running-autonomous-feature-development/SKILL.md +3 -3
  30. package/assets/skills/coordinator-running-brainstorm-cycles/SKILL.md +21 -20
  31. package/assets/skills/coordinator-running-review-cycles/SKILL.md +15 -4
  32. package/assets/skills/diagnosing-fleet-and-daemon/SKILL.md +0 -2
  33. package/assets/skills/efficient-multi-agent-research/SKILL.md +3 -3
  34. package/assets/skills/implementer-orchestrating-execution/SKILL.md +11 -14
  35. package/assets/skills/orchestrate/SKILL.md +47 -35
  36. package/assets/skills/persistent-watcher-archetype/SKILL.md +172 -25
  37. package/assets/skills/persistent-watcher-archetype/resources/capture_archive.py +618 -0
  38. package/assets/skills/persistent-watcher-archetype/resources/jev_watcher_filter.py +837 -0
  39. package/assets/skills/persistent-watcher-archetype/resources/roster-watch.sh +1140 -0
  40. package/assets/skills/persistent-watcher-archetype/resources/roster-watch_test.sh +291 -0
  41. package/assets/skills/persistent-watcher-archetype/resources/thrum-capture-fallback.sh +2 -2
  42. package/assets/skills/persistent-watcher-archetype/resources/thrum-watch-pane-capture.sh +20 -8
  43. package/assets/skills/prime-agent/SKILL.md +10 -0
  44. package/assets/skills/project-setup/SKILL.md +22 -16
  45. package/assets/skills/project-setup/resources/implementation-agent.md +56 -35
  46. package/assets/skills/researcher-investigating/SKILL.md +2 -5
  47. package/assets/skills/thrum/SKILL.md +14 -7
  48. package/assets/skills/thrum/resources/ANTI_PATTERNS.md +16 -18
  49. package/assets/skills/thrum/resources/CLI_REFERENCE.md +17 -11
  50. package/assets/skills/thrum/resources/LISTENER_PATTERN.md +9 -3
  51. package/assets/skills/thrum/resources/MESSAGING.md +18 -11
  52. package/assets/skills/thrum/resources/WORKTREES.md +1 -1
  53. package/assets/skills/thrum-memory/SKILL.md +1 -1
  54. package/assets/skills/trace-spec-to-plan/resources/sweep-agent-prompt.md +1 -1
  55. package/assets/skills/update-queue/SKILL.md +6 -8
  56. package/assets/skills/using-the-dashboard/SKILL.md +30 -0
  57. package/assets/skills/using-the-queue/SKILL.md +76 -5
  58. package/assets/skills/using-thrum-state/SKILL.md +83 -0
  59. package/assets/skills/verify-against-plan/SKILL.md +120 -5
  60. package/assets/skills/watcher-archetype/SKILL.md +18 -0
  61. package/assets/skills/writing-durable-markdown/SKILL.md +5 -0
  62. package/dist/installer.js +4 -4
  63. package/dist/permission-fixture.integration.test.js +4 -4
  64. package/package.json +1 -1
  65. package/assets/skills/coordinator-deploying-the-fleet/SKILL.md +0 -396
  66. package/dist/allowlist-sync.test.d.ts +0 -1
  67. package/dist/allowlist-sync.test.js +0 -44
@@ -30,12 +30,16 @@ to sleep until the operator wakes it later. Same termination semantics as
30
30
  ```bash
31
31
  # Resolve identity + your worktree (needed before reading the partial).
32
32
  # $REPO must be YOUR worktree — the directory `thrum prime` reads the restart
33
- # snapshot back from. Resolve it from the daemon's authoritative identity, NOT
34
- # `git rev-parse` (which keys off the current shell CWD and would write to the
35
- # wrong .thrum/restart/ if a bash step left your worktree). Fall back to git
36
- # only if whoami can't answer.
37
- REPO=$(thrum whoami --field worktree 2>/dev/null)
38
- [ -n "$REPO" ] || REPO=$(git rev-parse --show-toplevel) || { echo "ERROR: cannot resolve your worktree"; exit 1; }
33
+ # snapshot back from. Resolve it ONLY via the daemon's authoritative,
34
+ # peercred-resolved identity (`thrum agent worktree --authoritative`) — NEVER
35
+ # via `thrum whoami --field worktree` or `git rev-parse --show-toplevel`
36
+ # (both cwd-resolved). A cwd-derived pattern could silently
37
+ # resolve to a DIFFERENT agent's worktree, or the main repo. There is NO git
38
+ # fallback — if the daemon can't answer, refuse and stop rather than guess.
39
+ REPO=$(
40
+ thrum agent worktree --authoritative 2>/dev/null
41
+ ) || { echo "ERROR: cannot authoritatively resolve your worktree via the daemon. Refusing to fall back to cwd/git-toplevel — that would risk silently saving this snapshot to the wrong repo. Check daemon connectivity and retry."; exit 1; }
42
+ [ -n "$REPO" ] || { echo "ERROR: thrum agent worktree --authoritative returned empty"; exit 1; }
39
43
  AGENT=$(thrum whoami --field agent_id) || { echo "ERROR: agent not registered"; exit 1; }
40
44
  [ -n "$AGENT" ] || { echo "ERROR: empty agent_id"; exit 1; }
41
45
  mkdir -p "${REPO}/.thrum/restart"
@@ -76,44 +80,43 @@ Per Step 3 of the partial, use the Write tool to save your composed continuation
76
80
  to `${REPO}/.thrum/restart/${AGENT}.md`. On next boot, `thrum prime`
77
81
  auto-injects this file — same mechanism as restart wake.
78
82
 
79
- ### 4. Back up important files to your durable agents folder (survives worktree teardown)
83
+ ### 4. Back up OTHER important artifacts to your durable agents folder (survives worktree teardown)
80
84
 
81
- **Your worktree may be torn down while you sleep — and if it is, YOUR SNAPSHOT
82
- GOES WITH IT unless you do this step.**
85
+ **Your restart snapshot itself no longer needs this step.** Step 6
86
+ (`thrum agent sleep`) now relocates `<worktree>/.thrum/restart/<agent-id>.md`
87
+ to the canonical `<main-repo>/.thrum/agents/<agent-id>/sessions/<ts>-restart.md`
88
+ synchronously, BEFORE it kills your pane — that is the fix for the bug this
89
+ step used to exist to work around (the snapshot previously was archived only
90
+ at your NEXT WAKE, so a worktree reap between sleep and wake destroyed it
91
+ permanently with no warning).
83
92
 
84
93
  🔴 **READ THIS CAREFULLY.** A worktree's `.thrum/` is a REAL LOCAL DIRECTORY. The
85
94
  `redirect` inside it is just a plain text FILE containing a path — a pointer
86
95
  thrum's code consults. The filesystem redirects nothing. Your worktree keeps its
87
96
  own local `agents/`, `context/`, `identities/`, and `restart/`.
88
97
 
89
- **THE ACTUAL MECHANISM:** your snapshot at `<worktree>/.thrum/restart/<agent-id>.md`
90
- is **worktree-local**. It is copied into the main repo **only when you WAKE** —
91
- `thrum prime` reads it from the worktree and archives it to
92
- `<main-repo>/.thrum/agents/<agent-id>/sessions/`. **Then and only then.** So a
93
- teardown that happens BEFORE your wake destroys the snapshot, permanently, and
94
- nothing warns you. This matters more for an extended snapshot: you are parking
95
- wire contracts, a capability matrix, and design rationale that are expensive to
96
- reconstruct and exist nowhere else.
97
-
98
- **Leave the snapshot where it is** — `thrum prime` reads it from the worktree on
99
- wake, so that path is correct and required. **Additionally**, copy anything you
100
- need to survive teardown to the MAIN REPO PATH, resolved explicitly:
98
+ **What THIS step is still for:** anything OTHER than the restart snapshot that
99
+ you need to survive a worktree teardown while parked — reports / findings you
100
+ authored, important uncommitted artifacts, and anything your resume plan
101
+ references. This matters more for an extended snapshot: you are parking wire
102
+ contracts, a capability matrix, and design rationale that are expensive to
103
+ reconstruct and exist nowhere else — but that content lives IN the snapshot
104
+ itself, which Step 6 already relocates; use this step for anything ELSE.
105
+ Copy those to the MAIN REPO PATH, resolved explicitly:
101
106
 
102
107
  ```bash
103
108
  # Resolve the main repo's .thrum from the redirect FILE (do not assume a path).
104
- MAIN_THRUM=$(cat "${REPO}/.thrum/redirect" 2>/dev/null) || MAIN_THRUM="${REPO}/.thrum"
109
+ MAIN_THRUM=$(
110
+ cat "${REPO}/.thrum/redirect" 2>/dev/null
111
+ ) || MAIN_THRUM="${REPO}/.thrum"
105
112
  mkdir -p "${MAIN_THRUM}/agents/${AGENT}"
106
- cp "${REPO}/.thrum/restart/${AGENT}.md" "${MAIN_THRUM}/agents/${AGENT}/last-sleep-snapshot.md"
107
- # ...and any other artifact you need on wake.
108
- ls -la "${MAIN_THRUM}/agents/${AGENT}/last-sleep-snapshot.md" # VERIFY IT LANDED
113
+ cp <artifact> "${MAIN_THRUM}/agents/${AGENT}/<name>"
114
+ ls -la "${MAIN_THRUM}/agents/${AGENT}/<name>" # VERIFY IT LANDED
109
115
  ```
110
116
 
111
- Copy there: reports / findings you authored, important uncommitted artifacts, and
112
- anything your resume plan references.
113
-
114
- **VERIFY THE COPY EXISTS AT THE MAIN PATH before ending your session.** Do not
115
- trust `cp`'s exit code — list the destination file. This step is your ONLY
116
- recoverability guarantee against teardown-while-asleep; the redirect is not one.
117
+ If you have nothing beyond the restart snapshot to preserve, this step is a
118
+ no-op — proceed to Step 5. Do not trust `cp`'s exit code for anything you do
119
+ copy — list the destination file to confirm it landed.
117
120
 
118
121
  ### 5. Mark agent operational status idle
119
122
 
@@ -121,29 +124,47 @@ recoverability guarantee against teardown-while-asleep; the redirect is not one.
121
124
  thrum agent set-status idle
122
125
  ```
123
126
 
124
- `idle` is the signal that this agent has parked. NO new "sleeping" state was
125
- added — `idle` covers both "no active work" and "parked for operator wake."
127
+ `idle` is the operational/presence-status signal, separate from the durable
128
+ `agents.phase` field. Step 6 (`thrum agent sleep`) is what transitions phase
129
+ to `sleeping` — a real, distinct phase, not folded into `idle`. This step
130
+ only covers the lighter-weight status field.
126
131
 
127
132
  If `thrum agent set-status` returns an error, continue to Step 6 — the snapshot
128
133
  on disk is the load-bearing artifact.
129
134
 
130
- ### 6. End session cleanly
131
-
132
- ```bash
133
- thrum session end
134
- ```
135
-
136
- This emits `agent.session.end` cleanly so the dead-agent sweeper does NOT treat
137
- the disconnect as a crash.
138
-
139
- ### 7. Kill own tmux session
135
+ ### 6. Sleep the agent (relocate snapshot, teardown, phase transition)
140
136
 
141
137
  ```bash
142
- thrum tmux kill "$SESSION"
138
+ thrum agent sleep --agent "$AGENT"
143
139
  ```
144
140
 
145
- Tmux pane terminates → runtime process exits → no further activity until
146
- operator wakes the agent.
141
+ This calls the daemon's `agent.sleep` RPC (CLI alias `park`), which runs the
142
+ full park ceremony in the correct order: it relocates your snapshot from the
143
+ worktree-local `.thrum/restart/` into the canonical
144
+ `agents/<id>/sessions/` directory, *then* kills your own tmux session, *then*
145
+ writes the `agent.phase.transition {to: "sleeping"}` event. This is the fix
146
+ for the bug a raw `thrum session end` + `thrum tmux kill` sequence had: it
147
+ killed the pane before the snapshot was ever relocated (permanent data-loss
148
+ risk if the worktree was reaped first) and left the roster row reading
149
+ `active` after the pane was already gone — a "ghost-active" agent.
150
+
151
+ **Critical: the daemon kills YOUR OWN pane mid-call, as part of this same
152
+ RPC's teardown stage.** A successful self-park is therefore observed, from
153
+ inside this pane, as the CLI call's transport dying — connection reset, EOF,
154
+ or broken pipe — NOT a clean JSON response; the pane is gone before a
155
+ response can reach it. **Do not retry** `thrum agent sleep` on transport
156
+ loss after dispatch, and **do not treat transport loss as a failure.** It is
157
+ the expected signal that self-park succeeded. A real failure (a gate,
158
+ relocation, or teardown error) is signaled by the RPC returning an explicit
159
+ error message BEFORE the pane dies — that is the only failure signal
160
+ observable from inside this pane. If independent confirmation is needed, it
161
+ must come from a DIFFERENT caller (this pane will be gone) checking
162
+ `thrum agent list` / `thrum team list` afterward.
163
+
164
+ **Do not fall back to a raw `tmux kill-session`.** A raw kill bypasses
165
+ `agent.sleep`'s relocate-before-kill ordering and daemon bookkeeping
166
+ entirely — reintroducing the exact data-loss and ghost-active bug this
167
+ ceremony exists to close.
147
168
 
148
169
  ## How wake works
149
170
 
@@ -34,12 +34,16 @@ should bring you back in-place, use `/thrum:restart` instead.
34
34
  ```bash
35
35
  # Resolve identity + your worktree (needed before reading the partial).
36
36
  # $REPO must be YOUR worktree — the directory `thrum prime` reads the restart
37
- # snapshot back from. Resolve it from the daemon's authoritative identity, NOT
38
- # `git rev-parse` (which keys off the current shell CWD and would write to the
39
- # wrong .thrum/restart/ if a bash step left your worktree). Fall back to git
40
- # only if whoami can't answer.
41
- REPO=$(thrum whoami --field worktree 2>/dev/null)
42
- [ -n "$REPO" ] || REPO=$(git rev-parse --show-toplevel) || { echo "ERROR: cannot resolve your worktree"; exit 1; }
37
+ # snapshot back from. Resolve it ONLY via the daemon's authoritative,
38
+ # peercred-resolved identity (`thrum agent worktree --authoritative`) — NEVER
39
+ # via `thrum whoami --field worktree` or `git rev-parse --show-toplevel`
40
+ # (both cwd-resolved). A cwd-derived pattern could silently
41
+ # resolve to a DIFFERENT agent's worktree, or the main repo. There is NO git
42
+ # fallback — if the daemon can't answer, refuse and stop rather than guess.
43
+ REPO=$(
44
+ thrum agent worktree --authoritative 2>/dev/null
45
+ ) || { echo "ERROR: cannot authoritatively resolve your worktree via the daemon. Refusing to fall back to cwd/git-toplevel — that would risk silently saving this snapshot to the wrong repo. Check daemon connectivity and retry."; exit 1; }
46
+ [ -n "$REPO" ] || { echo "ERROR: thrum agent worktree --authoritative returned empty"; exit 1; }
43
47
  AGENT=$(thrum whoami --field agent_id) || { echo "ERROR: agent not registered"; exit 1; }
44
48
  [ -n "$AGENT" ] || { echo "ERROR: empty agent_id"; exit 1; }
45
49
  mkdir -p "${REPO}/.thrum/restart"
@@ -80,42 +84,39 @@ Per Step 3 of the partial, use the Write tool to save your composed continuation
80
84
  to `${REPO}/.thrum/restart/${AGENT}.md`. On next boot, `thrum prime`
81
85
  auto-injects this file — same mechanism as restart wake.
82
86
 
83
- ### 4. Back up important files to your durable agents folder (survives worktree teardown)
87
+ ### 4. Back up OTHER important artifacts to your durable agents folder (survives worktree teardown)
84
88
 
85
- **Your worktree may be torn down while you sleep — and if it is, YOUR SNAPSHOT
86
- GOES WITH IT unless you do this step.**
89
+ **Your restart snapshot itself no longer needs this step.** Step 6
90
+ (`thrum agent sleep`) now relocates `<worktree>/.thrum/restart/<agent-id>.md`
91
+ to the canonical `<main-repo>/.thrum/agents/<agent-id>/sessions/<ts>-restart.md`
92
+ synchronously, BEFORE it kills your pane — that is the fix for the bug this
93
+ step used to exist to work around (the snapshot previously was archived only
94
+ at your NEXT WAKE, so a worktree reap between sleep and wake destroyed it
95
+ permanently with no warning).
87
96
 
88
97
  🔴 **READ THIS CAREFULLY.** A worktree's `.thrum/` is a REAL LOCAL DIRECTORY. The
89
98
  `redirect` inside it is just a plain text FILE containing a path — a pointer
90
99
  thrum's code consults. The filesystem redirects nothing. Your worktree keeps its
91
100
  own local `agents/`, `context/`, `identities/`, and `restart/`.
92
101
 
93
- **THE ACTUAL MECHANISM:** your snapshot at `<worktree>/.thrum/restart/<agent-id>.md`
94
- is **worktree-local**. It is copied into the main repo **only when you WAKE** —
95
- `thrum prime` reads it from the worktree and archives it to
96
- `<main-repo>/.thrum/agents/<agent-id>/sessions/`. **Then and only then.** So a
97
- teardown that happens BEFORE your wake destroys the snapshot, permanently, and
98
- nothing warns you.
99
-
100
- **Leave the snapshot where it is** — `thrum prime` reads it from the worktree on
101
- wake, so that path is correct and required. **Additionally**, copy anything you
102
- need to survive teardown to the MAIN REPO PATH, resolved explicitly:
102
+ **What THIS step is still for:** anything OTHER than the restart snapshot that
103
+ you need to survive a worktree teardown while parked — reports / findings you
104
+ authored, important uncommitted artifacts, and anything your resume plan
105
+ references. Copy those to the MAIN REPO PATH, resolved explicitly:
103
106
 
104
107
  ```bash
105
108
  # Resolve the main repo's .thrum from the redirect FILE (do not assume a path).
106
- MAIN_THRUM=$(cat "${REPO}/.thrum/redirect" 2>/dev/null) || MAIN_THRUM="${REPO}/.thrum"
109
+ MAIN_THRUM=$(
110
+ cat "${REPO}/.thrum/redirect" 2>/dev/null
111
+ ) || MAIN_THRUM="${REPO}/.thrum"
107
112
  mkdir -p "${MAIN_THRUM}/agents/${AGENT}"
108
- cp "${REPO}/.thrum/restart/${AGENT}.md" "${MAIN_THRUM}/agents/${AGENT}/last-sleep-snapshot.md"
109
- # ...and any other artifact you need on wake.
110
- ls -la "${MAIN_THRUM}/agents/${AGENT}/last-sleep-snapshot.md" # VERIFY IT LANDED
113
+ cp <artifact> "${MAIN_THRUM}/agents/${AGENT}/<name>"
114
+ ls -la "${MAIN_THRUM}/agents/${AGENT}/<name>" # VERIFY IT LANDED
111
115
  ```
112
116
 
113
- Copy there: reports / findings you authored, important uncommitted artifacts, and
114
- anything your resume plan references.
115
-
116
- **VERIFY THE COPY EXISTS AT THE MAIN PATH before ending your session.** Do not
117
- trust `cp`'s exit code — list the destination file. This step is your ONLY
118
- recoverability guarantee against teardown-while-asleep; the redirect is not one.
117
+ If you have nothing beyond the restart snapshot to preserve, this step is a
118
+ no-op — proceed to Step 5. Do not trust `cp`'s exit code for anything you do
119
+ copy — list the destination file to confirm it landed.
119
120
 
120
121
  ### 5. Mark agent operational status idle
121
122
 
@@ -123,41 +124,48 @@ recoverability guarantee against teardown-while-asleep; the redirect is not one.
123
124
  thrum agent set-status idle
124
125
  ```
125
126
 
126
- `idle` is the signal that this agent has parked. NO new "sleeping" state was
127
- added — `idle` covers both "no active work" and "parked for operator wake."
127
+ `idle` is the operational/presence-status signal, separate from the durable
128
+ `agents.phase` field. Step 6 (`thrum agent sleep`) is what transitions phase
129
+ to `sleeping` — a real, distinct phase, not folded into `idle`. This step
130
+ only covers the lighter-weight status field.
128
131
 
129
132
  If `thrum agent set-status` returns an error (e.g. rate-limited), continue to
130
133
  Step 6 — the snapshot on disk is the load-bearing artifact, not the status
131
134
  field. The operator can set status post-wake.
132
135
 
133
- ### 6. End session cleanly
136
+ ### 6. Sleep the agent (relocate snapshot, teardown, phase transition)
134
137
 
135
138
  ```bash
136
- thrum session end
139
+ thrum agent sleep --agent "$AGENT"
137
140
  ```
138
141
 
139
- This emits an `agent.session.end` event cleanly so the dead-agent sweeper does
140
- NOT later treat the disconnect as a crash. If `thrum session end` fails,
141
- continue to Step 7.
142
-
143
- ### 7. Kill own tmux session
144
-
145
- ```bash
146
- thrum tmux kill "$SESSION"
147
- ```
148
-
149
- Tmux pane terminates → runtime process exits → no further activity until
150
- operator wakes the agent via `thrum tmux create <session-name>`.
151
-
152
- **If Step 7 fails with "anonymous caller cannot invoke":** `thrum session end`
153
- (Step 6) severs the daemon binding, so `thrum tmux kill` may be rejected if the
154
- daemon hasn't yet processed the CallerWorktree self-kill path. Use the raw tmux
155
- fallback — the lifecycle safeguards (snapshot, status idle, session end) were
156
- already discharged by Steps 1-6, so nothing is lost:
157
-
158
- ```bash
159
- tmux kill-session -t "$SESSION"
160
- ```
142
+ This calls the daemon's `agent.sleep` RPC (CLI alias `park`), which runs the
143
+ full park ceremony in the correct order: it relocates your snapshot from the
144
+ worktree-local `.thrum/restart/` into the canonical
145
+ `agents/<id>/sessions/` directory, *then* kills your own tmux session, *then*
146
+ writes the `agent.phase.transition {to: "sleeping"}` event. This is the fix
147
+ for the bug a raw `thrum session end` + `thrum tmux kill` sequence had: it
148
+ killed the pane before the snapshot was ever relocated (permanent data-loss
149
+ risk if the worktree was reaped first) and left the roster row reading
150
+ `active` after the pane was already gone — a "ghost-active" agent.
151
+
152
+ **Critical: the daemon kills YOUR OWN pane mid-call, as part of this same
153
+ RPC's teardown stage.** A successful self-park is therefore observed, from
154
+ inside this pane, as the CLI call's transport dying — connection reset, EOF,
155
+ or broken pipe — NOT a clean JSON response; the pane is gone before a
156
+ response can reach it. **Do not retry** `thrum agent sleep` on transport
157
+ loss after dispatch, and **do not treat transport loss as a failure.** It is
158
+ the expected signal that self-park succeeded. A real failure (a gate,
159
+ relocation, or teardown error) is signaled by the RPC returning an explicit
160
+ error message BEFORE the pane dies — that is the only failure signal
161
+ observable from inside this pane. If independent confirmation is needed, it
162
+ must come from a DIFFERENT caller (this pane will be gone) checking
163
+ `thrum agent list` / `thrum team list` afterward.
164
+
165
+ **Do not fall back to a raw `tmux kill-session`.** A raw kill bypasses
166
+ `agent.sleep`'s relocate-before-kill ordering and daemon bookkeeping
167
+ entirely — reintroducing the exact data-loss and ghost-active bug this
168
+ ceremony exists to close.
161
169
 
162
170
  ## How wake works
163
171
 
@@ -207,6 +215,7 @@ resumable via Claude Code's native session-continuation mechanism.
207
215
 
208
216
  ## Programmatic use (operator shutdown scripts)
209
217
 
210
- The underlying mechanic — write snapshot + set status idle + session end + tmux
211
- kill — can be invoked from an operator's shutdown script directly via the bash
212
- commands above (without going through the skill).
218
+ The underlying mechanic — write snapshot + set status idle + `thrum agent sleep`
219
+ (relocate + teardown + phase transition) — can be invoked from an operator's
220
+ shutdown script directly via the bash commands above (without going through
221
+ the skill).
@@ -54,14 +54,11 @@ Pre-assembled context is the difference between a real debate and a shallow one.
54
54
 
55
55
  ## The three rounds
56
56
 
57
- > **Model tiers:** pass an explicit `model:` on every dispatch — `sonnet`
58
- > (low effort) mechanical, `sonnet` (medium effort) judgment, Opus only on
59
- > operator-ask or a skill step that names it. See the
60
- > `choosing-subagent-models` skill for the full policy.
57
+ > **Model tiers:** pass an explicit `model:` on every dispatch; choose model and effort per the `choosing-subagent-models` skill (read `runtime.role_models` at the moment of use). Never let a sub-agent inherit your own model.
61
58
 
62
59
  Dispatch one sub-agent per option, in parallel (single message, multiple Agent
63
- tool calls). `model: "sonnet"` for all dispatches — quality matches Opus on
64
- structured critique at a fraction of the cost.
60
+ tool calls). `model: <per choosing-subagent-models>` for all dispatches — a cheaper tier
61
+ matches a costly one on structured critique at a fraction of the cost.
65
62
 
66
63
  ### Round 1 — opening positions
67
64
 
@@ -221,9 +218,9 @@ the working plan/context in an actionable shape:
221
218
 
222
219
  ## Model and cost
223
220
 
224
- Sonnet for all dispatches. See `~/.claude/CLAUDE.md § Sub-Agent Model Selection`
221
+ Model per `choosing-subagent-models` for all dispatches. See `~/.claude/CLAUDE.md § Sub-Agent Model Selection`
225
222
  — the project-wide rule that every `Agent` dispatch must pass `model` explicitly
226
- (never inherit parent Opus by default). Roughly ~100k tokens for 2 options,
223
+ (never inherit your own model by default). Roughly ~100k tokens for 2 options,
227
224
  ~150k for 3 options. This is an investment that buys a reviewer-ready decision
228
225
  an implementer can execute in a fresh session without re-hashing the design.
229
226
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: brainstorm-steward
3
- description: "Use when running as the Brainstorm Steward — a persistent watcher on the coordinator's home box that manages a roster of remote brainstormers, multiplexes their NEED questions into one pane queue for the owner, routes ANSWERs back, and delegates launch and dual-review/project-setup to coordinators. Never decides content."
3
+ description: "Use when running as the Brainstorm Steward — a persistent watcher on the coordinator's home box that manages a roster of remote brainstormers, multiplexes their NEED questions into one pane queue for the owner, routes ANSWERs back, and delegates launch and dual-review approval to coordinators (the brainstormer runs its own project-setup after approval). Never decides content."
4
4
  ---
5
5
 
6
6
  # Brainstorm Steward
@@ -10,8 +10,9 @@ set of remote brainstormer agents rather than implementers or coordinators.
10
10
  Your job is to keep the owner from having to hold N brainstorm threads open
11
11
  at once: you multiplex every brainstormer's pending question into a single
12
12
  queue in your own pane, relay the owner's answer back to the right
13
- brainstormer, and hand off the mechanical parts (launch, review, project
14
- setup) to coordinators. **You never decide content.** You route.
13
+ brainstormer, and hand off the mechanical parts (launch, dual-review
14
+ approval) to coordinators. The brainstormer then runs its own project
15
+ setup. **You never decide content.** You route.
15
16
 
16
17
  ## You are a persistent watcher
17
18
 
@@ -27,9 +28,29 @@ to that coordinator). Everything below is additive — the brainstorm-specific
27
28
  duties layered on top of that base.
28
29
 
29
30
  Your roster is entirely remote (other boxes), so the base skill's remote
30
- modal-unblock note applies to every roster member by default — use
31
- `thrum tmux send` (peer-routed, works fleet-wide); the local-only
32
- tmux-key primitive it replaces is retired.
31
+ modal-unblock note applies to every roster member by default — cross-peer
32
+ send-keys is refused by design, so you cannot `thrum tmux send` into a
33
+ roster member's pane yourself; route the unblock to that box's local
34
+ coordinator instead.
35
+
36
+ ## Available skills (situational — you MUST invoke when triggered)
37
+
38
+ These skills deepen role discipline for specific situations. They do NOT
39
+ auto-load — when a trigger condition below applies, you MUST invoke the
40
+ matching skill via the Skill tool BEFORE taking action.
41
+
42
+ - `agent-messaging-protocol` — forwarding or relaying information between
43
+ parties, routing an owner answer, carrying a decision or request through an
44
+ intermediary, summarizing another author's message, or adding
45
+ interpretation to someone else's words
46
+ - `brainstormer-staying-current` — the safe way to merge forward: a
47
+ long-lived worktree may be behind its configured merge target, before
48
+ review or handoff, or when asked to merge-forward and leave the worktree
49
+ clean
50
+ - `conversation-only-context` — at the START of any long-lived session, when
51
+ told you'll have a long conversation or get a lot done, when context is
52
+ climbing, when several investigations are in flight, or before reading code
53
+ or a multi-file doc set to investigate
33
54
 
34
55
  ## Roster = brainstormers
35
56
 
@@ -77,7 +98,7 @@ thread:
77
98
  that skill's "Driving your cycle" section for the setup-copy step and the
78
99
  exact `thrum monitor start` registration — **`--notify-on-success` is
79
100
  mandatory there too**, for the identical reason: a `--schedule`d job
80
- delivers nothing on `--match` alone (thrum-ruz1z §5c).
101
+ delivers nothing on `--match` alone.
81
102
 
82
103
  ## The queue (your pane console)
83
104
 
@@ -98,6 +119,23 @@ convention doc) via `thrum reply <need-message-id> --stdin` addressed to the
98
119
  original NEED message, in the owner's own words. Once relayed, drop the item
99
120
  from your queue and surface the next.
100
121
 
122
+ ## Dashboard board (rehearsal-only today — see gate below)
123
+
124
+ <!-- DASHBOARD-SHIP-GATE: the paragraph below is AWARENESS-safe now, but the
125
+ USE-mandate (publish the NEED queue as a dashboard board) activates only
126
+ when the web UI Dashboard tab (E3) AND the answer round-trip (E4) are
127
+ actually DEPLOYED, not merely landed on trunk — per `using-the-dashboard`'s
128
+ honesty table, publishing today is still a no-op for the human on any box
129
+ running a pre-E3/pre-E4 binary. Re-check that table before flipping this
130
+ to a mandate. -->
131
+ Your pane console above is the mechanism today. `using-the-dashboard`
132
+ documents an owner-facing board surface for the SAME NEED-multiplexing this
133
+ skill already does — invoke it (with `coordinator-dashboard-human-loop`,
134
+ since a steward is launched coordinator-shaped and inherits that skill too)
135
+ to check what is actually usable before treating a board as a second channel
136
+ for your queue. Until the honesty table's E3+E4 rows read DEPLOYED, keep
137
+ routing owner Q&A through the pane console, not a board.
138
+
101
139
  ## Idle nudge
102
140
 
103
141
  If items sit in the queue past a threshold (default keyed off your
@@ -128,11 +166,15 @@ while brainstormers run on other boxes. To start a new brainstorm on topic X:
128
166
  ## Finish handoff
129
167
 
130
168
  When a brainstormer reports its design locked and ready to move forward,
131
- **message a coordinator** to run the dual-review → project-setup flow —
132
- you do not run either of those yourself; the brainstormer's own
169
+ **message a coordinator to APPROVE it**: the coordinator runs its dual
170
+ review and approves or returns findings. The brainstormer's own
133
171
  NEED/ANSWER-driven design-lock process is not a substitute for that
134
- coordinator-run review. Once the handoff is confirmed and the brainstormer
135
- is torn down, drop it from your roster.
172
+ coordinator-run review. **On approval, the brainstormer runs its own
173
+ project-setup.** Never ask the coordinator to run project-setup for a
174
+ brainstormer, and do not run either step yourself. Phrase the handoff as
175
+ "approve, then the brainstormer runs project-setup." Once project-setup has
176
+ produced its beads and the brainstormer is torn down, drop it from your
177
+ roster.
136
178
 
137
179
  ## Context economy (load-bearing)
138
180
 
@@ -153,6 +195,18 @@ your entire durable resume state (watcher/parent/model/roster/cadence);
153
195
  nothing else needs to survive a restart, because nothing else is
154
196
  authoritative.
155
197
 
198
+ ## Persist state + queue before compacting
199
+
200
+ Before running `/thrum:compact` or `/thrum:compact-extended`, first persist
201
+ your load-bearing context to the durable store — it survives compaction;
202
+ your conversation context does not. Update your personal state
203
+ (`thrum state set --kind personal_state ...` — see the `using-thrum-state`
204
+ skill) and your committed work (`thrum queue` — see the `using-the-queue`
205
+ skill) BEFORE composing your snapshot. This is distinct from the restart
206
+ recovery above (compaction keeps your daemon binding and live session
207
+ intact, unlike a restart) but the same durable stores are what a
208
+ post-compact render reads back.
209
+
156
210
  ## Keep the pipeline flowing (stalled-handoff detection)
157
211
 
158
212
  Beyond the owner-facing queue, track when a roster brainstormer is
@@ -21,10 +21,7 @@ Locate the canonical config from the current worktree:
21
21
 
22
22
  ```bash
23
23
  CONFIG=.thrum/config.json
24
- if [ ! -f "$CONFIG" ]; then
25
- COMMON_DIR=$(git rev-parse --path-format=absolute --git-common-dir)
26
- CONFIG="${COMMON_DIR%/.git}/.thrum/config.json"
27
- fi
24
+ [ -f .thrum/redirect ] && CONFIG="$(cat .thrum/redirect)/config.json"
28
25
  test -f "$CONFIG"
29
26
  TARGET=$(jq -er '.orchestration.merge_target | select(type == "string" and length > 0)' "$CONFIG")
30
27
  MERGE_KING=$(jq -r --arg target "$TARGET" '.orchestration.merge_kings[$target] // "unset"' "$CONFIG")
@@ -22,6 +22,20 @@ mechanical-task carve-out anymore — lint runs, grep-and-collect, file maps,
22
22
  config edits, and all other "simple" work now dispatch at sonnet-low, not Haiku.
23
23
  Never select Haiku on own judgment — use sonnet-low instead.
24
24
 
25
+ ### Read the tiers at the moment of use
26
+
27
+ **Role templates and launch examples do not name models or effort levels; this
28
+ skill and the live config do.** Read the tier when you are about to spawn or
29
+ launch, never from memory or from a copied example:
30
+
31
+ ```bash
32
+ jq -r '.runtime.role_models' .thrum/config.json
33
+ ```
34
+
35
+ Launching with `--role` and no `--model` resolves the role default
36
+ automatically. A `--model` / `--effort` flag in a launch command takes its value
37
+ from `runtime.role_models` for the target role, per this skill.
38
+
25
39
  ### Agent tiers
26
40
 
27
41
  Effort tier governs whether an agent does the hard thing or the expedient thing.
@@ -62,7 +62,7 @@ Workflow `agent()` opts, agent-definition frontmatter, `thrum tmux launch
62
62
  ```python
63
63
  Agent(subagent_type="general-purpose",
64
64
  name="<prefix>_<slug>",
65
- model="sonnet",
65
+ model="<per choosing-subagent-models>",
66
66
  description="<3-5 words>",
67
67
  prompt="""<task>
68
68
 
@@ -92,14 +92,14 @@ to fire-and-forget monitors, not to a named agent you re-message.
92
92
 
93
93
  | Subagent role | Name prefix | Model / effort (effort only where exposed) | Result file |
94
94
  |---|---|---|---|
95
- | Investigation, grep, doc summary, mechanical | `<topic>` (e.g. `vmdocs`) | `sonnet` / low | `<scratch>/<name>.md` |
96
- | Root-cause | `<bead>_rc` | `sonnet` / low | `<scratch>/<bead>-rc.md` |
97
- | Verifier, reviewer, design-verify | `<bead>_verify` | `sonnet` / medium | `<scratch>/<bead>-verify.md` |
98
- | Implementer | `impl_<slug>` | `sonnet` / medium | `<scratch>/<slug>-impl.md` |
99
- | VM driver | `vmdriver_<slug>` | `sonnet` / medium | `<scratch>/<slug>-vm.md` |
100
- | Prose or deep review | any | `opus` — **only when the operator asks** | as above |
95
+ | Investigation, grep, doc summary, mechanical | `<topic>` (e.g. `vmdocs`) | per `choosing-subagent-models` | `<scratch>/<name>.md` |
96
+ | Root-cause | `<bead>_rc` | per `choosing-subagent-models` | `<scratch>/<bead>-rc.md` |
97
+ | Verifier, reviewer, design-verify | `<bead>_verify` | per `choosing-subagent-models` | `<scratch>/<bead>-verify.md` |
98
+ | Implementer | `impl_<slug>` | per `choosing-subagent-models` | `<scratch>/<slug>-impl.md` |
99
+ | VM driver | `vmdriver_<slug>` | per `choosing-subagent-models` | `<scratch>/<slug>-vm.md` |
100
+ | Prose or deep review | any | per `choosing-subagent-models` — **only when the operator asks** | as above |
101
101
 
102
- Haiku is banned. Opus is never yours to grant onward.
102
+ The model ban list lives in `choosing-subagent-models`. A costly tier is never yours to grant onward.
103
103
 
104
104
  ### CONSTRAINTS block — paste verbatim into every dispatch
105
105
 
@@ -111,8 +111,8 @@ Haiku is banned. Opus is never yours to grant onward.
111
111
  tool's own guidance suggests it. It trips a permission modal, and A FROZEN
112
112
  PANE EMITS NOTHING, so nobody can tell you are blocked. If you must background
113
113
  work, wait for the completion notification.
114
- - Every sub-agent YOU spawn gets an explicit `model:` — sonnet (low mechanical,
115
- medium judgment). HAIKU IS BANNED. Opus is never yours.
114
+ - Every sub-agent YOU spawn gets an explicit `model:` chosen per `choosing-subagent-models`
115
+ (read `runtime.role_models`). The model ban list lives there. A costly tier is never yours.
116
116
  - READ-ONLY git outside your own worktree. NEVER `checkout`/`reset`/`restore`/
117
117
  `stash`/`clean` in ANY directory — `stash` is one shared stack across all
118
118
  worktrees and the shared tree holds live agents' uncommitted state.
@@ -186,7 +186,7 @@ Restart on a number read from the pane footer, never on a felt sense.
186
186
  - The parent reading code or docs "to just check quickly" — message the subagent that already read them and ask for the one field.
187
187
  - One subagent handed ten tasks — partition it and dispatch the parts in parallel.
188
188
  - A spawn with no `name:` — it cannot be re-messaged. Name every spawn.
189
- - A spawn with no `model:` — it silently inherits Opus. Pin `model:` on every spawn, and `effort` wherever the mechanism takes it.
189
+ - A spawn with no `model:` — it silently inherits your own model. Pin `model:` on every spawn, and `effort` wherever the mechanism takes it.
190
190
  - Holding a design-gating answer behind the rest of the pass while an implementer builds on the old premise — that one goes immediately; the rest ships as one consolidated message.
191
191
  - Acting on the resume plan alone and skipping the middle of the prime — the falsified premise sits in the part you skipped.
192
192
  - Trusting an older "not started" message over a newer "already running" one — verify, do not recall; that cuts both directions.
@@ -21,7 +21,7 @@ findings, and its troubleshooting state across rounds.
21
21
 
22
22
  Do this:
23
23
 
24
- 1. `Agent(name: "vmdriver_<slug>", model: "sonnet", prompt: <round-1 GO>)`.
24
+ 1. `Agent(name: "vmdriver_<slug>", model: <per choosing-subagent-models>, prompt: <round-1 GO>)`.
25
25
  2. Wait for its report.
26
26
  3. `SendMessage(to: "vmdriver_<slug>", message: <round-2 GO>)`.
27
27
 
@@ -10,7 +10,7 @@ sanctions for reaching it.
10
10
 
11
11
  You want a multi-hour load or soak run and a verdict, not a log.
12
12
 
13
- 1. Spawn `vmdriver_<slug>` with `model: "sonnet"`. The GO names the run, the
13
+ 1. Spawn `vmdriver_<slug>` with `model: <per choosing-subagent-models>`. The GO names the run, the
14
14
  revision under test, and the exact metrics to report.
15
15
  2. The driver opens a persistent session with `<your-ssh-wrapper> <remote-host>`,
16
16
  starts the run detached, and writes the exit code to its own file.