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.
- package/assets/commands/thrum-compact-extended.md +36 -21
- package/assets/commands/thrum-compact.md +19 -18
- package/assets/commands/thrum-restart-extended.md +1 -5
- package/assets/commands/thrum-restart.md +2 -2
- package/assets/commands/thrum-sleep-extended.md +1 -5
- package/assets/commands/thrum-sleep.md +1 -5
- package/assets/commands/thrum-update-project.md +1 -1
- package/assets/skills/brainstorm-queue-aware/SKILL.md +1 -1
- package/assets/skills/brainstorm-steward/SKILL.md +3 -3
- package/assets/skills/choosing-subagent-models/SKILL.md +183 -74
- package/assets/skills/closing-findings-while-warm/SKILL.md +1 -2
- package/assets/skills/configure-roles/SKILL.md +2 -2
- package/assets/skills/coordinator-assessing-agent-completion/SKILL.md +11 -10
- package/assets/skills/coordinator-branch-split-on-block/SKILL.md +1 -2
- package/assets/skills/coordinator-context-monitoring/SKILL.md +11 -12
- package/assets/skills/coordinator-deploying-a-node/SKILL.md +3 -1
- package/assets/skills/coordinator-dispatching-work/SKILL.md +5 -4
- package/assets/skills/coordinator-hotpath-merge-gate/SKILL.md +9 -7
- package/assets/skills/coordinator-interacting-with-the-owner/SKILL.md +1 -2
- package/assets/skills/coordinator-maintaining-memory/SKILL.md +1 -1
- package/assets/skills/coordinator-managing-state-and-lifecycle/SKILL.md +10 -3
- package/assets/skills/coordinator-merging-code/SKILL.md +21 -14
- package/assets/skills/coordinator-philosophy-merge-gate/SKILL.md +4 -5
- package/assets/skills/coordinator-plan-reconcile-gate/SKILL.md +1 -2
- package/assets/skills/coordinator-rolling-out-to-nodes/SKILL.md +1 -0
- package/assets/skills/coordinator-running-brainstorm-cycles/SKILL.md +4 -5
- package/assets/skills/coordinator-running-review-cycles/SKILL.md +1 -2
- package/assets/{commands/thrum-_deviations-protocol.md → skills/deviations-protocol/SKILL.md} +6 -12
- package/assets/skills/efficient-multi-agent-research/SKILL.md +2 -2
- package/assets/skills/generator-idempotency-protocol/SKILL.md +9 -0
- package/assets/skills/implementer-maintaining-memory/SKILL.md +3 -4
- package/assets/skills/implementer-orchestrating-execution/SKILL.md +1 -2
- package/assets/skills/implementer-receiving-dispatch/SKILL.md +15 -17
- package/assets/skills/implementer-receiving-review-feedback/SKILL.md +3 -4
- package/assets/skills/implementer-status-and-handoff/SKILL.md +1 -14
- package/assets/skills/implementer-tdd-and-quality/SKILL.md +2 -2
- package/assets/skills/memory-audit-recover/SKILL.md +7 -5
- package/assets/skills/memory-curate/SKILL.md +3 -3
- package/assets/skills/memory-maintenance/SKILL.md +2 -0
- package/assets/skills/memory-write-discipline/SKILL.md +1 -1
- package/assets/skills/orchestrate/SKILL.md +34 -5
- package/assets/skills/persistent-watcher-archetype/SKILL.md +2 -2
- package/assets/skills/persistent-watcher-archetype/resources/jev_watcher_filter.py +5 -5
- package/assets/skills/persistent-watcher-archetype/resources/roster-watch.sh +5 -5
- package/assets/skills/persistent-watcher-archetype/resources/roster-watch_test.sh +2 -2
- package/assets/skills/persistent-watcher-archetype/resources/thrum-capture-fallback.sh +1 -1
- package/assets/skills/persistent-watcher-archetype/resources/thrum-watch-pane-capture.sh +3 -3
- package/assets/skills/prime-agent/SKILL.md +1 -1
- package/assets/skills/project-hotpath-gate/SKILL.md +1 -2
- package/assets/skills/project-philosophy/SKILL.md +2 -3
- package/assets/skills/project-rules-protocol/SKILL.md +12 -0
- package/assets/skills/project-setup/SKILL.md +9 -10
- package/assets/skills/project-setup/resources/implementation-agent.md +1 -2
- package/assets/skills/researcher-answering-queries/SKILL.md +1 -2
- package/assets/skills/researcher-investigating/SKILL.md +6 -8
- package/assets/skills/researcher-maintaining-memory/SKILL.md +3 -1
- package/assets/{commands/thrum-_snapshot-protocol.md → skills/snapshot-protocol/SKILL.md} +10 -15
- package/assets/{commands/thrum-_stamp-protocol.md → skills/stamp-protocol/SKILL.md} +5 -6
- package/assets/skills/thrum/SKILL.md +9 -4
- package/assets/skills/thrum/resources/CLI_REFERENCE.md +32 -27
- package/assets/skills/thrum-memory/SKILL.md +1 -1
- package/assets/skills/using-monitors/SKILL.md +198 -0
- package/assets/skills/using-the-queue/SKILL.md +2 -3
- package/assets/skills/using-thrum-state/SKILL.md +3 -3
- package/assets/skills/verify-against-plan/SKILL.md +2 -2
- package/dist/hooks/block-sync-cd.js +1 -1
- package/dist/hooks/block-sync-cd.test.js +1 -1
- package/dist/installer-assets.test.d.ts +1 -0
- package/dist/installer-assets.test.js +41 -0
- package/package.json +1 -1
- package/assets/commands/thrum-_compact-runtime-commands.md +0 -61
- package/assets/commands/thrum-_generator-idempotency-protocol.md +0 -15
- package/assets/commands/thrum-_project-rules-protocol.md +0 -18
- 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
|
|
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
|
-
##
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
|
48
|
-
|
|
|
49
|
-
| **
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
- **`
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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
|
|
70
|
-
|
|
71
|
-
|
|
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
|
-
**
|
|
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
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
the agent definition, the Workflow opts, or
|
|
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
|
|
106
|
-
|
|
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
|
|
110
|
-
EFFORT
|
|
111
|
-
|
|
112
|
-
|
|
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
|
|
118
|
-
|
|
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
|
-
|
|
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
|
-
|
|
123
|
-
|
|
124
|
-
|
|
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
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
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,
|
|
137
|
-
`effort` wherever the mechanism exposes it.
|
|
138
|
-
INHERITS THE PARENT'S MODEL — so an
|
|
139
|
-
|
|
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
|
-
|
|
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
|
|
166
|
-
|
|
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
|
|
179
|
-
over one
|
|
180
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
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
|
-
|
|
204
|
-
|
|
205
|
-
|
|
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
|
|
306
|
-
|
|
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
|
-
|
|
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
|
|
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 (
|
|
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
|
|
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
|
|
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`
|
|
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` (
|
|
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
|
|
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
|
|
242
|
-
(`
|
|
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()`
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|