opencode-thrum-pro 0.1.6 → 0.1.8

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 (74) hide show
  1. package/assets/commands/thrum-compact-extended.md +36 -21
  2. package/assets/commands/thrum-compact.md +19 -18
  3. package/assets/commands/thrum-restart-extended.md +1 -5
  4. package/assets/commands/thrum-restart.md +2 -2
  5. package/assets/commands/thrum-sleep-extended.md +1 -5
  6. package/assets/commands/thrum-sleep.md +1 -5
  7. package/assets/commands/thrum-update-project.md +1 -1
  8. package/assets/skills/brainstorm-queue-aware/SKILL.md +1 -1
  9. package/assets/skills/brainstorm-steward/SKILL.md +3 -3
  10. package/assets/skills/choosing-subagent-models/SKILL.md +183 -74
  11. package/assets/skills/closing-findings-while-warm/SKILL.md +1 -2
  12. package/assets/skills/configure-roles/SKILL.md +2 -2
  13. package/assets/skills/coordinator-assessing-agent-completion/SKILL.md +11 -10
  14. package/assets/skills/coordinator-branch-split-on-block/SKILL.md +1 -2
  15. package/assets/skills/coordinator-context-monitoring/SKILL.md +11 -12
  16. package/assets/skills/coordinator-deploying-a-node/SKILL.md +3 -1
  17. package/assets/skills/coordinator-dispatching-work/SKILL.md +5 -4
  18. package/assets/skills/coordinator-hotpath-merge-gate/SKILL.md +9 -7
  19. package/assets/skills/coordinator-interacting-with-the-owner/SKILL.md +1 -2
  20. package/assets/skills/coordinator-maintaining-memory/SKILL.md +1 -1
  21. package/assets/skills/coordinator-managing-state-and-lifecycle/SKILL.md +10 -3
  22. package/assets/skills/coordinator-merging-code/SKILL.md +21 -14
  23. package/assets/skills/coordinator-philosophy-merge-gate/SKILL.md +4 -5
  24. package/assets/skills/coordinator-plan-reconcile-gate/SKILL.md +1 -2
  25. package/assets/skills/coordinator-rolling-out-to-nodes/SKILL.md +1 -0
  26. package/assets/skills/coordinator-running-brainstorm-cycles/SKILL.md +4 -5
  27. package/assets/skills/coordinator-running-review-cycles/SKILL.md +1 -2
  28. package/assets/{commands/thrum-_deviations-protocol.md → skills/deviations-protocol/SKILL.md} +6 -12
  29. package/assets/skills/efficient-multi-agent-research/SKILL.md +2 -2
  30. package/assets/skills/generator-idempotency-protocol/SKILL.md +9 -0
  31. package/assets/skills/implementer-maintaining-memory/SKILL.md +3 -4
  32. package/assets/skills/implementer-orchestrating-execution/SKILL.md +1 -2
  33. package/assets/skills/implementer-receiving-dispatch/SKILL.md +15 -17
  34. package/assets/skills/implementer-receiving-review-feedback/SKILL.md +3 -4
  35. package/assets/skills/implementer-status-and-handoff/SKILL.md +1 -14
  36. package/assets/skills/implementer-tdd-and-quality/SKILL.md +2 -2
  37. package/assets/skills/memory-audit-recover/SKILL.md +7 -5
  38. package/assets/skills/memory-curate/SKILL.md +3 -3
  39. package/assets/skills/memory-maintenance/SKILL.md +2 -0
  40. package/assets/skills/memory-write-discipline/SKILL.md +1 -1
  41. package/assets/skills/orchestrate/SKILL.md +34 -5
  42. package/assets/skills/persistent-watcher-archetype/SKILL.md +2 -2
  43. package/assets/skills/persistent-watcher-archetype/resources/jev_watcher_filter.py +5 -5
  44. package/assets/skills/persistent-watcher-archetype/resources/roster-watch.sh +5 -5
  45. package/assets/skills/persistent-watcher-archetype/resources/roster-watch_test.sh +2 -2
  46. package/assets/skills/persistent-watcher-archetype/resources/thrum-capture-fallback.sh +1 -1
  47. package/assets/skills/persistent-watcher-archetype/resources/thrum-watch-pane-capture.sh +3 -3
  48. package/assets/skills/prime-agent/SKILL.md +1 -1
  49. package/assets/skills/project-hotpath-gate/SKILL.md +1 -2
  50. package/assets/skills/project-philosophy/SKILL.md +2 -3
  51. package/assets/skills/project-rules-protocol/SKILL.md +12 -0
  52. package/assets/skills/project-setup/SKILL.md +9 -10
  53. package/assets/skills/project-setup/resources/implementation-agent.md +1 -2
  54. package/assets/skills/researcher-answering-queries/SKILL.md +1 -2
  55. package/assets/skills/researcher-investigating/SKILL.md +6 -8
  56. package/assets/skills/researcher-maintaining-memory/SKILL.md +3 -1
  57. package/assets/{commands/thrum-_snapshot-protocol.md → skills/snapshot-protocol/SKILL.md} +10 -15
  58. package/assets/{commands/thrum-_stamp-protocol.md → skills/stamp-protocol/SKILL.md} +5 -6
  59. package/assets/skills/thrum/SKILL.md +9 -4
  60. package/assets/skills/thrum/resources/CLI_REFERENCE.md +32 -27
  61. package/assets/skills/thrum-memory/SKILL.md +1 -1
  62. package/assets/skills/using-monitors/SKILL.md +198 -0
  63. package/assets/skills/using-the-queue/SKILL.md +2 -3
  64. package/assets/skills/using-thrum-state/SKILL.md +3 -3
  65. package/assets/skills/verify-against-plan/SKILL.md +2 -2
  66. package/dist/hooks/block-sync-cd.js +1 -1
  67. package/dist/hooks/block-sync-cd.test.js +1 -1
  68. package/dist/installer-assets.test.d.ts +1 -0
  69. package/dist/installer-assets.test.js +41 -0
  70. package/package.json +1 -1
  71. package/assets/commands/thrum-_compact-runtime-commands.md +0 -61
  72. package/assets/commands/thrum-_generator-idempotency-protocol.md +0 -15
  73. package/assets/commands/thrum-_project-rules-protocol.md +0 -18
  74. package/assets/commands/thrum-_verify-before-write-protocol.md +0 -27
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: choosing-subagent-models
3
- description: "Use when about to launch, spawn, or dispatch a subagent, sub-agent, or parallel agent - including the Agent/Task tool, an Explore agent, fanning out research, or any time you choose a model for a subagent. ALSO fires on every REVIEW dispatch - dispatching a reviewer, a code review, a code-quality review, a spec-compliance review, a dual review, a verify-against-plan or verify-against-source pass, or a merge-gate sub-agent. Reviewer dispatch is the HIGHEST-STAKES judgment-tier spawn and is the one most often done from memory. Enforces the role-based model tiering (opus-low orchestrators, sonnet-medium implementers and reviewers, sonnet-low sub-agents) and cheap parallel fan-out."
3
+ description: "Use when about to launch, spawn, or dispatch a subagent, sub-agent, or parallel agent - including the Agent/Task tool, an Explore agent, fanning out research, or any time you choose a model for a subagent. ALSO fires on every REVIEW dispatch - dispatching a reviewer, a code review, a code-quality review, a spec-compliance review, a dual review, a verify-against-plan or verify-against-source pass, or a merge-gate sub-agent. Reviewer dispatch is the HIGHEST-STAKES judgment-tier spawn and is the one most often done from memory. Enforces role-based model TIERING (mechanical, judgment, orchestration) resolved to a concrete model+effort for whichever runtime you are actually running under, and cheap parallel fan-out."
4
4
  ---
5
5
 
6
6
  # Choosing Subagent Models
@@ -11,16 +11,33 @@ description: "Use when about to launch, spawn, or dispatch a subagent, sub-agent
11
11
  (e.g. `/tmp/<task>.md`); its reply to you is only a summary. Put this
12
12
  in the prompt.**
13
13
 
14
- ## Pin every spawn. The floor depends on the agent's ROLE.
15
-
16
- Every subagent you spawn MUST pass an explicit `model:` (plus effort where the
17
- runtime supports it). Omitting it runs the subagent on YOUR model (Opus) — the
18
- single biggest avoidable cost leak in agent work.
19
-
20
- **Haiku is banned entirely.** There is no
21
- mechanical-task carve-out anymore — lint runs, grep-and-collect, file maps,
22
- config edits, and all other "simple" work now dispatch at sonnet-low, not Haiku.
23
- Never select Haiku on own judgment — use sonnet-low instead.
14
+ ## Pick a TIER by role/task, then resolve it for YOUR runtime. Pin every spawn.
15
+
16
+ Model selection here is two steps, always in this order:
17
+
18
+ 1. **Pick the semantic tier** by the spawned agent's role/task — one of three,
19
+ named identically everywhere in the fleet (Go constants, role templates,
20
+ this doc): **`mechanical`** (rote/find-replace/grep-and-collect/lint/file-maps —
21
+ the cheapest tier), **`judgment`** (the default tier for implementers,
22
+ reviewers, verifiers, researchers — real analysis, not busywork), and
23
+ **`orchestration`** (orchestrator/coordinator tier — never spawned for a
24
+ sub-agent, only ever the operator's own agent or a skill that explicitly
25
+ names it for one step).
26
+ 2. **Resolve that tier to a concrete `model:` + `effort:` for the runtime you
27
+ are actually running under** — via that runtime's own preset
28
+ (`RuntimePreset.TierModels`) or operator config (`runtime.role_models`);
29
+ see "Where the tier-model mapping lives" below. Never assume Claude's
30
+ model names (`sonnet`, `opus`, `haiku`) apply —
31
+ a Codex or OpenCode agent reading this same file has no such models, and
32
+ passing one either errors or silently falls back to the runtime's own
33
+ default (see "Never let an unresolved pin fall through" below).
34
+
35
+ Every subagent you spawn MUST pass an explicit, resolved `model:` (plus effort
36
+ where the runtime supports it). Omitting it runs the subagent on YOUR model —
37
+ the single biggest avoidable cost leak in agent work.
38
+
39
+ Haiku 5.5 is eligible for summarization and mechanical work.
40
+ Read the effective model and effort at use from `runtime.role_models`.
24
41
 
25
42
  ### Read the tiers at the moment of use
26
43
 
@@ -39,36 +56,45 @@ from `runtime.role_models` for the target role, per this skill.
39
56
  ### Agent tiers
40
57
 
41
58
  Effort tier governs whether an agent does the hard thing or the expedient thing.
42
- These are the tiers now:
43
-
44
- | Role | Model / Effort |
45
- | ---------------------------- | ------------------- |
46
- | **Orchestrator** | **`opus` / low** |
47
- | **Implementer** | **`sonnet` / medium** |
48
- | **Verifier / reviewer** | **`sonnet` / medium** |
49
- | **Sub-agent** (investigation, grep, mechanical) | **`sonnet` / low** |
50
-
51
- - **`model: "sonnet"` @ low effort — sub-agents ONLY.** Investigation,
52
- grep-and-collect, file maps, lint runs, mechanical tasks. This is the floor for
53
- a *sub-agent*, NOT for an implementer or a reviewer.
54
- - **`model: "sonnet"` @ MEDIUM effort — implementers, verifiers, reviewers.**
55
- Not low. A reviewer on low effort is a rubber stamp with extra steps, and
56
- rubber-stamped reviews are how a merge gate that ran zero tests survived six
57
- sessions.
58
- - **`model: "opus"` @ low — orchestrators.** Not selectable for sub-agents —
59
- set by the operator on the agent's runtime-config.
60
- - **`model: "opus"` — NOT your call.** Allowed only when (a) the operator
61
- explicitly asked for a deep review or prose review in this task, or (b) a
62
- skill you are running prescribes Opus for the specific step you are currently
63
- executing — NOT for every spawn under that skill. "This research is hard /
64
- important" is NOT a justification — hard investigation is exactly what Sonnet
65
- is for.
59
+ These are the three tiers, with their Claude-runtime resolution shown as a
60
+ worked example — **if you are running under a different runtime, resolve the
61
+ same tier from your own runtime's preset (`RuntimePreset.TierModels`) or
62
+ `runtime.role_models`, not from the Claude column:**
63
+
64
+ | Role | Tier | Resolved for Claude (example) |
65
+ | ---------------------------- | ------------- | ------------------- |
66
+ | **Orchestrator / coordinator** | `orchestration` | **`opus` / low** |
67
+ | **Implementer** | `judgment` | **`sonnet` / medium** |
68
+ | **Verifier / reviewer** | `judgment` | **`sonnet` / medium** |
69
+ | **Sub-agent** (investigation, grep, mechanical) | `mechanical` | **`sonnet` / low** |
70
+
71
+ - **`mechanical` tier (sub-agents ONLY)** — investigation, grep-and-collect,
72
+ file maps, lint runs, mechanical tasks. Read the effective model and effort
73
+ at use from `runtime.role_models`. For other runtimes, use their own
74
+ mechanical-tier value (`RuntimePreset.TierModels`), not a Claude name.
75
+ The mechanical tier is for sub-agents only, never for an implementer or a reviewer.
76
+ - **`judgment` tier (implementers, verifiers, reviewers)** — resolves to
77
+ `sonnet` @ MEDIUM effort on Claude. Not low. A reviewer on low effort is a
78
+ rubber stamp with extra steps, and rubber-stamped reviews are how a merge
79
+ gate that ran zero tests survived six sessions.
80
+ - **`orchestration` tier (orchestrators/coordinators)** — resolves to `opus` @
81
+ low on Claude. Not selectable for sub-agents — set by the operator on the
82
+ agent's runtime-config.
83
+ - **`orchestration` tier is NOT your call to spawn.** Allowed only when (a) the
84
+ operator explicitly asked for a deep review or prose review in this task, or
85
+ (b) a skill you are running prescribes the orchestration tier for the
86
+ specific step you are currently executing — NOT for every spawn under that
87
+ skill. "This research is hard / important" is NOT a justification — hard
88
+ investigation is exactly what the `judgment` tier is for.
66
89
 
67
90
  ## Worked examples — LITERAL ARGUMENTS, AND EFFORT IS TOOL-DEPENDENT
68
91
 
69
- **Pin `model` on every spawn. Pass `effort` wherever the mechanism exposes it.**
70
- Syntax per mechanism — re-check the schema in front of you rather than restating
71
- from memory, because it can change:
92
+ **Pin `model` on every spawn, using the value your runtime's own preset
93
+ (`RuntimePreset.TierModels`) or `runtime.role_models` resolves the tier to.**
94
+ **Pass
95
+ `effort` wherever the mechanism exposes it** — some mechanisms don't. Syntax per
96
+ mechanism — re-check the schema in front of you rather than restating from
97
+ memory, because it can change:
72
98
 
73
99
  | Mechanism | `model` | `effort` |
74
100
  |---|---|---|
@@ -76,8 +102,14 @@ from memory, because it can change:
76
102
  | **Workflow `agent()`** (opts: label, phase, schema, model, effort, isolation, agentType) | ✅ settable | ✅ settable |
77
103
  | **Agent DEFINITION** (`.claude/agents/*.md` / plugin `agents/*.md` frontmatter) | ✅ | ✅ — sets the default for that agent type |
78
104
  | **`thrum tmux create` / `launch`** | ✅ `--model` | ✅ `--effort` — pass on BOTH |
105
+ | **Other runtimes' own spawn mechanism** | ✅ settable | runtime-dependent — check its own schema |
79
106
 
80
- **Agent tool — `model` only. It takes no `effort` argument.**
107
+ **Below is ONE fully concrete example — what a `judgment`-tier spawn looks
108
+ like once resolved for Claude's own Agent tool (which takes no `effort`
109
+ argument).** It is Claude-specific syntax with a Claude-specific model string;
110
+ if you are running under a different runtime, use that runtime's own spawn
111
+ mechanism and its own resolved model+effort from `RuntimePreset.TierModels` /
112
+ `runtime.role_models` instead of copying this literal string.
81
113
 
82
114
  ```python
83
115
  Agent(subagent_type="general-purpose", model="sonnet",
@@ -85,12 +117,14 @@ Agent(subagent_type="general-purpose", model="sonnet",
85
117
  prompt="...")
86
118
  ```
87
119
 
88
- **The tier philosophy still governs even where the Agent tool cannot express it:**
89
- sonnet-low for investigation and mechanical work, sonnet-medium for reviewers,
90
- verifiers and implementers. Where effort is not settable, carry the intent through
91
- the agent definition, the Workflow opts, or the tmux launch flags.
120
+ **The tier philosophy still governs even where a mechanism cannot express
121
+ `effort`:** the `model` value alone still must be the tier's resolved value for
122
+ YOUR runtime — never a bare Claude name assumed universal. Where effort is not
123
+ settable, carry the intent through the agent definition, the Workflow opts, or
124
+ the tmux launch flags instead.
92
125
 
93
- An agent definition can also carry a default:
126
+ An agent definition can also carry a default (Claude example — resolve to
127
+ your own runtime's `mechanical`-tier value if you are not Claude):
94
128
 
95
129
  ```yaml
96
130
  # claude-plugin/agents/message-listener.md
@@ -99,53 +133,87 @@ model: sonnet
99
133
  effort: low
100
134
  ```
101
135
 
102
- **Workflow `agent()` — effort IS a literal argument. Pass it.**
136
+ **Workflow `agent()` — effort IS a literal argument. Pass it, resolved for
137
+ your runtime's tier:**
103
138
 
104
139
  ```javascript
105
- agent(prompt, { model: "sonnet", effort: "medium" }) // reviewer / implementer
106
- agent(prompt, { model: "sonnet", effort: "low" }) // mechanical sub-agent
140
+ agent(prompt, { model, effort }) // `model`/`effort` = your runtime's resolution
141
+ // of the `judgment` tier (reviewer/implementer)
142
+ // or the `mechanical` tier (sub-agent) —
143
+ // resolve via RuntimePreset.TierModels /
144
+ // runtime.role_models for the literal values
107
145
  ```
108
146
 
109
- **THE DIRECTIVE, imperative and not a comment: REVIEWERS RUN SONNET AT MEDIUM
110
- EFFORT.** Pass `effort: "medium"` literally under Workflow, in the agent
111
- definition, or on `thrum tmux create`/`launch`. Never dispatch a reviewer "from
112
- memory".
147
+ **THE DIRECTIVE, imperative and not a comment: REVIEWERS RUN THE `judgment`
148
+ TIER, WHICH IS MEDIUM EFFORT ON EVERY RUNTIME THAT HAS AN EFFORT KNOB.** Pass
149
+ the resolved effort literally under Workflow, in the agent definition, or on
150
+ `thrum tmux create`/`launch` (the Agent tool takes no `effort`, so `model`
151
+ alone must still be the `judgment`-tier value there). Never dispatch a
152
+ reviewer "from memory", and never dispatch one at the mechanical tier.
113
153
 
114
154
  **AND VERIFY, DO NOT ASSERT:** any claim about what a tool does or does not expose
115
155
  must be checked against the schema in front of you.
116
156
 
117
- Never select Opus or Haiku on own judgment — use Sonnet, at the floor of
118
- sonnet-low.
157
+ Never select the `orchestration` tier on your own judgment — use the
158
+ `judgment` tier's configured value from `runtime.role_models`.
159
+
160
+ ## Where the tier-model mapping lives
161
+
162
+ **Do not copy a tier's model string from this doc — read it at the moment of
163
+ use.** The three semantic tiers (`mechanical` / `judgment` / `orchestration`)
164
+ are the same across every runtime; only the concrete model+effort differs per
165
+ runtime, and that mapping lives in exactly two places:
166
+
167
+ - **The runtime's own preset** (the `TierModels` field of the runtime preset
168
+ schema) — the machine-checked, per-runtime tier→model
169
+ table. A runtime with no entry for a tier has no fleet-configured value for
170
+ it and resolves to nothing rather than inheriting another runtime's model.
171
+ - **`runtime.role_models` in `.thrum/config.json`** — operator configuration
172
+ for this project, which always outranks the preset's tier table.
119
173
 
120
- ## Fleet model-tiering by runtime/role
174
+ **If you are running under Claude**, use the Agent tiers table above
175
+ (orchestrator/implementer/reviewer/sub-agent → orchestration/judgment/
176
+ judgment/mechanical), plus brainstormer → `orchestration` and brainstormer's
177
+ own subagents → `mechanical` (except reviewers, which are always `judgment`).
121
178
 
122
- Different runtimes and roles pin different tiers. Claude tiers are canonical —
123
- see the Agent tiers table above (orchestrator/implementer/reviewer/sub-agent),
124
- plus brainstormer → opus-medium and brainstormer's own subagents → sonnet-low
125
- (except reviewers → sonnet-medium). Other runtimes:
179
+ **If you are running under a different runtime, read your own tier's value
180
+ from the two sources above** — never assume Claude's model names apply, and
181
+ never hard-code a model string you saw once in a doc or a prior session.
126
182
 
127
- | Runtime | Role | Model / effort |
128
- | ------------ | ---------------------------- | --------------------------------------------------- |
129
- | OpenCode | default | GLM-5.2 (fine as-is) |
130
- | Codex | orchestrator / reviewer | gpt-5.5-medium |
131
- | Codex | implementer | gpt-5.5-low |
132
- | Cursor-agent | default | composer-2.5 (fine as-is) |
183
+ A runtime/role pair with no fleet-configured tier value has no override —
184
+ resolve it to that runtime's own configured default, and pass it explicitly
185
+ (never leave it unset — see "Never let an unresolved pin fall through"
186
+ below).
133
187
 
134
188
  ## Pin every spawn explicitly — the floor depends on the ROLE, not the depth
135
189
 
136
- Every orchestrator MUST pass an explicit `model:` on EVERY subagent it spawns, and
137
- `effort` wherever the mechanism exposes it. An unspecified subagent SILENTLY
138
- INHERITS THE PARENT'S MODEL — so an Opus orchestrator that forgets the pin just
139
- spent Opus tokens on a grep.
190
+ Every orchestrator MUST pass an explicit `model:` on EVERY subagent it spawns,
191
+ resolved for its own runtime, and `effort` wherever the mechanism exposes it.
192
+ An unspecified subagent SILENTLY INHERITS THE PARENT'S MODEL — so an
193
+ orchestration-tier orchestrator that forgets the pin just spent its
194
+ (expensive) tier's tokens on a grep.
140
195
 
141
196
  **The floor is set by what the agent DOES, not by how deep it sits** — see the
142
197
  Agent tiers table above. This applies recursively: an implementer spawning its
143
198
  own helpers pins them by THEIR role, not by copying its own tier down.
144
199
 
145
200
  The check before every spawn: what is this agent's ROLE? Reviewer or implementer?
146
- sonnet-medium. Pure investigation or mechanical work? sonnet-low. Never leave it
201
+ `judgment` tier. Pure investigation or mechanical work? `mechanical` tier. Then
202
+ resolve that tier to your runtime's concrete model+effort. Never leave it
147
203
  unspecified.
148
204
 
205
+ ### Never let an unresolved pin fall through
206
+
207
+ **An unsupported or unrecognized model name must never block delegation, and
208
+ must never cause silent inheritance of the parent's model.** If your
209
+ runtime's preset has no `TierModels` entry for this tier, or a resolved name
210
+ is rejected by the runtime you're spawning under, do NOT skip the pin and do
211
+ NOT let the spawn go unpinned so it falls back to inheriting the caller's
212
+ model — fall back explicitly to the runtime's own configured default for the
213
+ matching tier and pass THAT, so every spawn is always pinned to some resolved
214
+ model+effort. An unset `model:` is a bug at every layer of this stack, not
215
+ just under Claude.
216
+
149
217
  ## Paste the constraint block into the child prompt — the pin is not enough
150
218
 
151
219
  **A model pin is an ARGUMENT and travels by itself. A behavioural constraint is
@@ -162,8 +230,10 @@ that stops at depth 1 is absent where the work happens.
162
230
  tool's own guidance suggests it. It trips a permission modal, and A FROZEN
163
231
  PANE EMITS NOTHING, so nobody can tell you are blocked. If you must background
164
232
  work, wait for the completion notification.
165
- - Every sub-agent YOU spawn gets an explicit `model:` — sonnet (low mechanical,
166
- medium judgment). HAIKU IS BANNED. Opus is never yours.
233
+ - Every sub-agent YOU spawn gets an explicit `model:`, resolved for your
234
+ runtime's tier — `mechanical` (rote/find-replace) or `judgment` (real
235
+ analysis). Read the effective model and effort from `runtime.role_models` at
236
+ use. The `orchestration` tier is never yours to spawn.
167
237
  - READ-ONLY git outside your own worktree. NEVER `checkout`/`reset`/`restore`/
168
238
  `stash`/`clean` in ANY directory — `stash` is one shared stack across all
169
239
  worktrees and the shared tree holds live agents' uncommitted state.
@@ -175,15 +245,22 @@ signal this condition produces.
175
245
 
176
246
  ### Cheap subagents → fan out, don't pile up
177
247
 
178
- Because sonnet-low subagents are cheap, prefer MANY small parallel subagents
179
- over one subagent handed a pile of tasks. When a research or investigation task
180
- has independent parts, partition it and dispatch the parts in parallel (use the
248
+ Because Haiku 5.5 supports summarization and mechanical sub-agent work, prefer
249
+ MANY small parallel subagents over one agent handed a pile of tasks. Read the
250
+ effective model and effort from `runtime.role_models` at dispatch. When research or
251
+ investigation has independent parts, partition them in parallel (use the
181
252
  `efficient-multi-agent-research` skill) — smaller scopes are cheaper, run
182
253
  concurrently (faster), and keep each subagent's context tight. One subagent
183
254
  given ten tasks is the anti-pattern.
184
255
 
185
256
  ## ⚠️ The pin-verification command LIES — do not trust it
186
257
 
258
+ **This section's examples are Claude-specific** (`thrum tmux capture`'s footer
259
+ format, and the historical Sonnet/Opus incident it documents) because that is
260
+ where this defect was measured — but the underlying rule generalizes: verify
261
+ a pin by reading the runtime's own RESOLVED status output, never a stored
262
+ "configured" value, whichever runtime you're on.
263
+
187
264
  `thrum agent runtime-config get <agent>` reports the **configured** value, not the
188
265
  **resolved** one.
189
266
 
@@ -264,3 +341,35 @@ launch **by construction**.
264
341
  An implementer pinned to sonnet, with an implementer role-default of sonnet, comes up
265
342
  correct whether or not the pin landed — so "pin sonnet, confirm sonnet" passes whether
266
343
  or not the fix works.
344
+
345
+ ## Paste blocks for child prompts
346
+
347
+ Paste these verbatim into a child prompt when the work involves the named activity.
348
+
349
+ --- SUB-AGENT HYGIENE ---
350
+ - No kill -0, Monitor or until-loop polling.
351
+ - No pgrep -f.
352
+ - Kill only by a captured PID number.
353
+ - Use rm -r, never rm -rf; a variable path uses "${d:?}".
354
+ - No 2>/dev/null on destructive commands.
355
+ - Bounded timeouts on everything.
356
+ - Remove only the worktree you created in this task, by its recorded path, never with --force.
357
+ - Never demonstrate an unguarded destructive idiom, even on a literal path.
358
+ --- END SUB-AGENT HYGIENE ---
359
+
360
+ --- TESTS ---
361
+ - To prove a selector resolves, use `go test <pkg> -list '<selector>'` plus a `-list '^TestNoSuchThingAtAll$'` negative control that must list zero tests. Never `-run '<sel>' -list '.*'`.
362
+ - `bd list -l` is --label; use `-n` for a limit.
363
+ - A timeout with 0 FAIL is neither red nor green: classify it as a bound failure, read the panic's "running tests:" line, and re-run wider.
364
+ --- END TESTS ---
365
+
366
+ --- WORKTREE TEARDOWN & SALVAGE ---
367
+ - Before any teardown, enumerate with both flags: `git -C <wt> status --porcelain --untracked-files=all --ignored -- .thrum`.
368
+ - Salvage anything found to a durable path (not /tmp), one subdirectory per worktree, filenames path-flattened.
369
+ - Never glob `.thrum/context/*.md`; salvage the exact agent-name file only, and assert no `project_state.md` landed in any salvage output.
370
+ - Verify salvage by name set first, then `cmp` each file, with a negative control proving `cmp` detects a difference.
371
+ - Kill the tmux session first (`thrum tmux kill <session>`), verify it is gone, then plain `git worktree remove`, never `--force`.
372
+ - Afterwards verify by effect: gone from `git worktree list` and from disk, and every remaining live pane's cwd still resolves (`tmux list-panes -a -F '#{pane_current_path}'`, then `git rev-parse --show-toplevel` per pane).
373
+ - Build the in-use protection set from live pane cwds, not from a name or registry list.
374
+ - Report the removal count and the registry delta separately.
375
+ --- END WORKTREE TEARDOWN & SALVAGE ---
@@ -94,8 +94,7 @@ tool that can prove it, not by trusting the sentence that claims it.
94
94
 
95
95
  ## Project-specific rules (already loaded)
96
96
 
97
- Read the shared partial at the absolute path:
98
- `claude-plugin/commands/_project-rules-protocol.md`
97
+ Load the /thrum:project-rules-protocol skill and follow it.
99
98
 
100
99
  If you accumulate a new rule mid-session (the user corrects you), capture it
101
100
  via the `implementer-maintaining-memory` skill (or `coordinator-maintaining-
@@ -155,7 +155,7 @@ For each role:
155
155
  - If beads detected: include `bd` commands in Task Tracking section
156
156
  - If MCP servers detected: add to Efficiency section
157
157
  - If specific skills detected: reference them
158
- - If worktree restrictions: adjust Scope Boundaries
158
+ - If worktree restrictions: adjust the Scope section
159
159
 
160
160
  3. Write to `.thrum/role_templates/{role}.md`. Keep per-agent template tokens
161
161
  (`{{.AgentName}}`, `{{.Module}}`, `{{.WorktreePath}}`,
@@ -226,4 +226,4 @@ rendered files from saved answers without asking any questions.
226
226
  | Thrum MCP server | Add MCP tool references, CLI fallback for sub-agents |
227
227
  | Claude plugin skills | List installed skills with usage guidance |
228
228
  | Context7 MCP | Add library docs guidance to Efficiency section |
229
- | Multiple worktrees | Add worktree scope rules to Scope Boundaries |
229
+ | Multiple worktrees | Add worktree scope rules to the Scope section |
@@ -176,11 +176,10 @@ salvaged files distinct names and land the salvage somewhere durable (the main r
176
176
 
177
177
  ## 🔴 The reap is worktree-removal-only — and TEST every step on ONE item first
178
178
 
179
- **`thrum agent delete --force` is REFUSED by the CAS guard on a stale agent with an empty
180
- `agent_pid_start_time`** (*"expected-state premise is required … refusing rather than treating
181
- an empty/never-read premise as a match"*). `--force` does NOT bypass it; the guard is
182
- correct. So the reap that actually frees load is worktree removal — but salvage BEFORE you remove,
183
- then remove PLAIN (no `--force`):
179
+ **`thrum agent delete` refuses an agent whose linked worktree still exists** (and any agent
180
+ with a live pid/tmux process, and coordinators); `--force` does NOT bypass these guards. So
181
+ the reap that frees load is worktree removal first — salvage BEFORE you remove, then remove
182
+ PLAIN (no `--force`), then `thrum agent delete`:
184
183
 
185
184
  1. Enumerate untracked+ignored `.thrum` content — BOTH flags, one flag alone misses a class:
186
185
  `git status --untracked-files=all --ignored -- .thrum`
@@ -200,9 +199,10 @@ then remove PLAIN (no `--force`):
200
199
  mistake it for protecting the ignored-file class. (Not a pipe — a pipe returns the last
201
200
  command's rc, not `git`'s.)
202
201
 
203
- The delete (`thrum agent delete`) best-effort-fails and leaves a **benign orphan DB row**,
204
- which you LEAVE (filtered at query per the fleet ruling; never `agent cleanup --force` to
205
- tidy them).
202
+ Then REAP the agent row with `thrum agent delete <agent>` once the worktree is gone and no
203
+ process is live: orphan rows must be reaped, not left. Never use `thrum agent cleanup
204
+ --force` (it can flag live fleet agents). A refused reap on a dead, worktree-less agent is a
205
+ bug: report it, do not route around it.
206
206
 
207
207
  ⚠️ **After a large reap you may see a `DeadAgentSweeper` skip alert + elevated write-RPC
208
208
  latency — do NOT assume the reap caused it.** This box carries a standing single-writer
@@ -302,8 +302,9 @@ RSS-MB.
302
302
  list AND disk), not just the exit code.
303
303
  - **Rank candidates by last-message CONTENT, not elapsed time** — your own
304
304
  broadcasts reset every recipient's idle clock.
305
- - **`--force` on agent-delete does NOT bypass the CAS guard** on a stale agent — the
306
- reap that frees load is worktree removal, not the delete.
305
+ - **`--force` on agent-delete does NOT bypass its guards** — the worktree must go first
306
+ (teardown with salvage or plain `git worktree remove`), then `thrum agent delete` reaps
307
+ the row.
307
308
  - **Reap order is `thrum tmux kill <session>` FIRST, THEN `git worktree remove`** —
308
309
  removing the worktree alone leaves the agent's tmux session alive with a
309
310
  now-deleted cwd, which the fleet flags as recurring "cwd drift" and whose runtime
@@ -159,8 +159,7 @@ asserted after the fact).
159
159
 
160
160
  ## Project-specific rules (already loaded)
161
161
 
162
- Read the shared partial at the absolute path:
163
- `claude-plugin/commands/_project-rules-protocol.md`
162
+ Load the /thrum:project-rules-protocol skill and follow it.
164
163
 
165
164
  If you accumulate a new rule mid-session about branch-splitting, capture it
166
165
  via the `coordinator-maintaining-memory` skill — it references the
@@ -30,13 +30,13 @@ What's forbidden is a script that bypasses this skill and fires
30
30
 
31
31
  This skill's tier ladder (Steps 3–5) governs how the coordinator restarts
32
32
  **other** agents. When the **coordinator restarts ITSELF**, a different rule
33
- applies and it is absolute — but D5 (owner-ruled)
33
+ applies and it is absolute — but the current ruling
34
34
  REVERSES which command that is:
35
35
 
36
36
  > **The coordinator ALWAYS uses the EXTENDED snapshot grade for itself — never
37
37
  > the standard/compact form. Which command carries that grade is
38
38
  > runtime-directed: `/thrum:compact-extended` on any runtime with a verified
39
- > compact-equivalent skill (D6, the default), `/thrum:restart-extended` ONLY
39
+ > compact-equivalent skill (the default), `/thrum:restart-extended` ONLY
40
40
  > as the fallback on a runtime without one (today: muse, copilot).**
41
41
 
42
42
  This is a REVERSAL of the prior absolute rule ("ALWAYS restart-extended, NEVER
@@ -62,7 +62,7 @@ Practical trigger points for coordinator self-restart/compact:
62
62
  In every one of these: run `/thrum:compact-extended` if the coordinator's
63
63
  runtime has a compact equivalent (the default); `/thrum:restart-extended` only
64
64
  if it does not. (The role-rule `coord-always-restart-extended` — `Coordinator
65
- ALWAYS uses /thrum:restart-extended` — is RETIRED as of D5; see
65
+ ALWAYS uses /thrum:restart-extended` — is RETIRED; see
66
66
  `thrum memory` for its retirement record. This skill is the always-loaded home
67
67
  so the CURRENT rule survives even when memory isn't consulted.)
68
68
 
@@ -163,7 +163,7 @@ is a single monitor for all lenses in v1, not one per lens.
163
163
  | `idle_mid_task` | ON | L2 — 30-min idle-with-open-task detection (bead cross-ref). RECOMMEND `/thrum:sleep-extended`; a no-task variant REPORTs `idle-no-task` at lower priority. |
164
164
  | `snapshot_awaiting_restart` | ON | L3 — pane text + fresh-snapshot two-signal heuristic. RECOMMEND `thrum tmux restart <agent>` (never autonomous). |
165
165
  | `blocked_on_human_modal` | ON | L4 — detects spend-limit/permission/consent modal prompts. DETECTION ONLY, never auto-answers; routes into the L5 ledger. |
166
- | `pending_human_ledger` | ON | L5 — flat JSONL ledger of items awaiting a human. EXEMPT from D5 backoff — surfaces every tick. `hb_ledger_resolve` (the resolution path) is defined but has zero call sites — nothing marks an entry resolved, so the ledger is append-only-forever, not "until resolved." |
166
+ | `pending_human_ledger` | ON | L5 — flat JSONL ledger of items awaiting a human. EXEMPT from progressive backoff — surfaces every tick. `hb_ledger_resolve` (the resolution path) is defined but has zero call sites — nothing marks an entry resolved, so the ledger is append-only-forever, not "until resolved." |
167
167
  | `waiting_on_coord` | ON | L9 — 21-rule pattern match (folded in from the standalone waiting-on-coord sweep) + warm-hold exemption. RECOMMEND coordinator answer. |
168
168
 
169
169
  ### Default-OFF lenses (E8, flag-gated — NOT YET IMPLEMENTED as of E7)
@@ -183,8 +183,7 @@ produce no output until enabled.
183
183
  ## Configuration
184
184
 
185
185
  The heartbeat system is configured under the `heartbeat` key in
186
- `.thrum/config.json` (Go type: `HeartbeatConfig` in
187
- `internal/config/heartbeat.go`). Example:
186
+ `.thrum/config.json` (Go type: `HeartbeatConfig`). Example:
188
187
 
189
188
  ```json
190
189
  {
@@ -222,10 +221,10 @@ The heartbeat system is configured under the `heartbeat` key in
222
221
  | -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
223
222
  | `cadence_minutes_day` | Daytime cadence target (default 30 min). The underlying monitor runs `@every 30m` and self-gates so only busy-fleet daytime ticks fire. |
224
223
  | `cadence_minutes_overnight` | Overnight cadence target (default 60 min). The monitor fires every other `@every 30m` tick overnight (effective 60-min rate). |
225
- | `busy_only_daytime` | When `true`, daytime ticks are skipped unless any agent has `agent_status=working` (D3 busy-signal gate). |
224
+ | `busy_only_daytime` | When `true`, daytime ticks are skipped unless any agent has `agent_status=working` (busy-signal gate). |
226
225
  | `busy_signal` | Algorithm for "is the fleet busy?" Default `working_or_activity_30m`: any agent working OR activity in the last 30 min. |
227
226
  | `overnight_window.tz` | **MUST be an explicit IANA timezone** (e.g. `"America/New_York"`). If unset, the sweep warns and falls back to always-daytime-rate rather than silently guessing. |
228
- | `backoff.start_after` | Number of consecutive unchanged detections of the same problem before D5 progressive backoff begins. |
227
+ | `backoff.start_after` | Number of consecutive unchanged detections of the same problem before progressive backoff begins. |
229
228
  | `backoff.multiplier` | Each backoff step multiplies the surface interval by this factor (default 2×). |
230
229
  | `backoff.floor_every` | The surface interval is capped at this many ticks — the problem is never fully silenced (always surfaces at least once per `floor_every` ticks). |
231
230
  | `lenses.<name>.enabled` | Enable/disable a lens individually. |
@@ -238,8 +237,8 @@ The heartbeat system is configured under the `heartbeat` key in
238
237
  `.thrum/config.json`** to configure the heartbeat. Two gotchas make this
239
238
  non-obvious; both bite silently.
240
239
 
241
- **1. All-or-nothing merge (the sharp footgun).** The loader
242
- (`internal/config/daemon.go`, `LoadThrumConfig`) applies
240
+ **1. All-or-nothing merge (the sharp footgun).** The config
241
+ loader (`LoadThrumConfig`) applies
243
242
  `DefaultHeartbeatConfig()` **only when the stanza is effectively absent**
244
243
  (`schema_version == 0` AND zero lenses):
245
244
 
@@ -254,7 +253,7 @@ There is **no field-level deep merge.** The moment you write a stanza with
254
253
  `cadence_minutes_day: 0`, `enabled: false`, and **all 12 lenses disabled**. So
255
254
  "I'll just set the timezone" with a three-line stanza silently turns the whole
256
255
  sweep off. **Always write the COMPLETE stanza** — copy
257
- `DefaultHeartbeatConfig()` (`internal/config/heartbeat.go`) in full, then change
256
+ `DefaultHeartbeatConfig()` in full, then change
258
257
  only what you need.
259
258
 
260
259
  **2. `overnight_window.tz` MUST be an explicit IANA zone.** Default is `""` (the
@@ -332,7 +331,7 @@ repeals fix-while-warm.
332
331
  restart is **under one turn** once context is meaningfully above the re-prime
333
332
  floor.
334
333
  - **Orchestrators re-prime far cheaper than coordinators, and it is structural:**
335
- `internal/cli/prime_filter.go` gives ONLY `role=="coordinator"` the full
334
+ the prime output filter gives ONLY `role=="coordinator"` the full
336
335
  project-state passthrough. Measured orchestrator re-prime ≈ 30k tokens.
337
336
  - Coordinators keep the ladder below for a stated reason — larger re-entry cost,
338
337
  plus decision-dense context a snapshot cannot faithfully reconstruct.
@@ -48,7 +48,9 @@ If the project has no WAL/SHM, this section is N/A — skip and note.
48
48
 
49
49
  ## 4. Never wrap service start/restart in a blind timeout
50
50
 
51
- Run the project's service restart command (`fleet.deployment.thrum.service.restart_command` or product equivalent) without a blind timeout wrapper. A timeout that kills a migrating restart mid-migration manufactures a half-migrated store.
51
+ 🔴 **On macOS, the restart command is NOT `service.restart_command` — it is `service.mac_restart_command`** (Thrum: `scripts/mac-daemon-restart-via-cron.sh`, run from inside the repo). A daemon restarted from a terminal or agent pane gets its Local Network (TCC) permission attributed to that terminal and is silently denied LAN peer dials (`no route to host`): peers go dark while the node itself looks healthy, and `PPID 1` does NOT prove it was re-parented correctly. Check the node's OS before choosing the command; this has been forgotten on primary repeatedly. After a mac restart, verify the peers on the LAN reconnect, not just the version.
52
+
53
+ Run the project's service restart command (`fleet.deployment.thrum.service.restart_command`, or `service.mac_restart_command` on macOS, or product equivalent) without a blind timeout wrapper. A timeout that kills a migrating restart mid-migration manufactures a half-migrated store.
52
54
 
53
55
  - Adapter flag `service.never_timeout` is true.
54
56
  - Signal-window rules are adapter data: `migration.signal_rules` (`SIGQUIT` fatal-always, `SIGUSR1` fatal-before-socket). Respect them — do not send fatal signals in the forbidden window.
@@ -26,7 +26,9 @@ send. See `coordinator-managing-state-and-lifecycle` § "Destroy an agent before
26
26
  tearing down its worktree" for the canonical sequence (`thrum tmux kill` BEFORE
27
27
  `thrum worktree teardown`). The dispatching skill mentions it here so you find
28
28
  the cross-reference when planning a wave recycle, not just when reading the
29
- lifecycle skill end-to-end.
29
+ lifecycle skill end-to-end. Teardown does not delete the agent row: it stays
30
+ retired until a separate `thrum agent delete <agent>` (after the worktree is
31
+ gone) or the sweeper reaps it.
30
32
 
31
33
  ## Never spawn sub-agents into worktrees where Thrum agents are running
32
34
 
@@ -307,14 +309,13 @@ EOF
307
309
  ### Step 3: Your role during execution
308
310
 
309
311
  - You receive the orchestrator's merge report when all epics complete.
310
- - Run your merge-approval gate (see Merge Approval Gate in your preamble).
312
+ - Run your merge-approval gate (see the merge approval rules in your preamble).
311
313
  - Monitor the orchestrator's status updates; escalate to the operator only for
312
314
  genuine judgment calls (architectural pivot, scope change, budget concern).
313
315
 
314
316
  ## Project-specific rules (already loaded)
315
317
 
316
- Read the shared partial at the absolute path:
317
- `claude-plugin/commands/_project-rules-protocol.md`
318
+ Load the /thrum:project-rules-protocol skill and follow it.
318
319
 
319
320
  If you accumulate a new rule mid-session (the user corrects you), capture it via
320
321
  the `coordinator-maintaining-memory` skill — it references the