opencode-thrum-pro 0.1.12 → 0.1.14

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 (26) hide show
  1. package/assets/commands/thrum-compact-extended.md +5 -0
  2. package/assets/commands/thrum-compact.md +5 -0
  3. package/assets/skills/coordinator-assessing-agent-completion/SKILL.md +17 -20
  4. package/assets/skills/coordinator-deploying-a-node/SKILL.md +2 -2
  5. package/assets/skills/coordinator-hotpath-merge-gate/SKILL.md +11 -2
  6. package/assets/skills/coordinator-merging-code/SKILL.md +79 -5
  7. package/assets/skills/coordinator-philosophy-merge-gate/SKILL.md +2 -2
  8. package/assets/skills/coordinator-rolling-out-to-nodes/SKILL.md +2 -2
  9. package/assets/skills/diagnosing-fleet-and-daemon/SKILL.md +1 -1
  10. package/assets/skills/implementer-receiving-dispatch/SKILL.md +1 -1
  11. package/assets/skills/orchestrate/SKILL.md +1 -1
  12. package/assets/skills/persistent-watcher-archetype/SKILL.md +24 -8
  13. package/assets/skills/persistent-watcher-archetype/resources/roster-watch.sh +3 -3
  14. package/assets/skills/project-setup/SKILL.md +7 -12
  15. package/assets/skills/project-setup/resources/implementation-agent.md +2 -2
  16. package/assets/skills/researcher-maintaining-memory/SKILL.md +1 -1
  17. package/assets/skills/thrum/resources/CLI_REFERENCE.md +1 -1
  18. package/assets/skills/thrum/resources/LISTENER_PATTERN.md +2 -2
  19. package/assets/skills/using-monitors/SKILL.md +156 -18
  20. package/assets/skills/using-tmux-ssh/SKILL.md +121 -0
  21. package/assets/skills/using-tmux-ssh/resources/tmux-ssh +1158 -0
  22. package/assets/skills/verify-against-plan/SKILL.md +1 -1
  23. package/dist/installer.js +3 -5
  24. package/package.json +1 -1
  25. package/assets/skills/coordinator-context-monitoring/SKILL.md +0 -685
  26. package/assets/skills/coordinator-post-restart-sweep/SKILL.md +0 -135
@@ -226,6 +226,11 @@ if [ "$SNAPSHOT_OK" = 1 ] && [ "$SESSION_OK" = 1 ]; then
226
226
  # all, so this is caught synchronously, not inferred later from silence.
227
227
  thrum tmux send "$AGENT" "/compact"
228
228
  SEND_RC=$?
229
+ # Exit 0 may print "ACCEPTED (non-turn command)": the runtime acknowledged the
230
+ # command without starting a model turn (for example compaction began). That is
231
+ # SUCCESS - continue to the next step exactly as for a plain exit 0.
232
+ # Exit 4 UNCONFIRMED means no acknowledgement was seen: inspect the pane before
233
+ # doing anything else.
229
234
  # Exit 3 = HELD, exit 4 = VERDICT UNKNOWN (thrum tmux send --help). In both
230
235
  # the "/compact" text is ALREADY TYPED into this pane and Enter was withheld
231
236
  # or unconfirmed. NEVER fall through to the raw retry below: it would append a
@@ -223,6 +223,11 @@ if [ "$SNAPSHOT_OK" = 1 ] && [ "$SESSION_OK" = 1 ]; then
223
223
  # turn regardless, so the delay costs nothing.
224
224
  thrum tmux send "$SESSION" "/compact"
225
225
  SEND_RC=$?
226
+ # Exit 0 may print "ACCEPTED (non-turn command)": the runtime acknowledged the
227
+ # command without starting a model turn (for example compaction began). That is
228
+ # SUCCESS - continue to the next step exactly as for a plain exit 0.
229
+ # Exit 4 UNCONFIRMED means no acknowledgement was seen: inspect the pane before
230
+ # doing anything else.
226
231
  # Exit 3 = HELD (Enter withheld), 4 = VERDICT UNKNOWN: "/compact" is already
227
232
  # typed in the pane. Do NOT retype it (that yields "/compact/compact"); report
228
233
  # and stop so a human/coordinator can inspect the pane.
@@ -159,7 +159,7 @@ across background sub-agents that examine each worktree read-only and RETURN a v
159
159
  they never reap. Per worktree each reports: sleeping-agent marker present?; branch
160
160
  containment (ancestor of trunk / pushed / UNMERGED-with-commit-list); only-copy authored
161
161
  content (docs/plans/specs, undelivered reports, restart snapshots), ignoring regenerable
162
- dirt (`scripts/thrum-*.sh`, `.thrum/redirect`, `runtime_config.json`). Fence them READ-ONLY
162
+ dirt (`thrum-*.sh` helper scripts, `.thrum/redirect`, `runtime_config.json`). Fence them READ-ONLY
163
163
  (no checkout/reset/stash/clean/rebase/commit/push, no `worktree remove`, no `agent delete`,
164
164
  no `rm`). You consolidate and decide.
165
165
 
@@ -251,28 +251,25 @@ Once you've classified an agent as idle, its `gopls` process (if any) is a
251
251
  second, independent reclaim candidate — an idle agent's gopls is dead weight
252
252
  sitting in RAM.
253
253
 
254
- `scripts/reap-idle-gopls.sh` matches each running `gopls` process to its
255
- owning agent (ppid chain → tmux pane_pid → `thrum team --json` session) and
256
- uses `tmux_state` as a cheap first-pass filter — anything not idle by that
257
- signal is skipped outright. That filter is bounded, not authoritative: it
258
- does not replace this skill's own idle/finished judgment, which still comes
259
- from the transcript per the rules above. Run the script alongside the scan
260
- above, apply the same transcript-based gate to whatever it surfaces, and
261
- fold the result into a single combined table: idle agent · gopls PID ·
262
- RSS-MB.
254
+ Match each running `gopls` process to its owning agent (ppid chain → tmux
255
+ pane_pid → `thrum team --json` session) and use `tmux_state` as a cheap
256
+ first-pass filter — anything not idle by that signal is skipped outright. That
257
+ filter is bounded, not authoritative: it does not replace this skill's own
258
+ idle/finished judgment, which still comes from the transcript per the rules
259
+ above. Do this alongside the scan above, apply the same transcript-based gate to
260
+ whatever it surfaces, and fold the result into a single combined table: idle
261
+ agent · gopls PID · RSS-MB.
263
262
 
264
263
  - Killing an idle agent's gopls is a no-op — it respawns on the agent's next
265
264
  LSP request. Never destructive to the agent itself.
266
- - **NEVER kill a pool or active-worker gopls.** The script excludes by ROLE
267
- (orchestrator, gate, coordinator, brainstormer, researcher — the roles
268
- that are never reap targets) plus the non-idle-state skip above, plus one
269
- named exception for a role-uncovered pool agent. It also runs a canary
270
- self-check before printing anything: if it can't prove the exclusion still
271
- resolves correctly, it aborts loudly instead of printing a kill-list.
272
- Do not override or bypass any of this.
273
- - Same framing as the rest of this skill: the script **produces information,
274
- you decide**. It is read-only and dry-run — it prints a kill-list, it never
275
- kills anything.
265
+ - **NEVER kill a pool or active-worker gopls.** Exclude by ROLE (orchestrator,
266
+ gate, coordinator, brainstormer, researcher — the roles that are never reap
267
+ targets) plus the non-idle-state skip above. Before building any kill-list,
268
+ prove the exclusion still resolves correctly; if you cannot, abort rather than
269
+ print one. Do not override or bypass any of this.
270
+ - Same framing as the rest of this skill: this step **produces information, you
271
+ decide**. It is read-only — it yields a candidate list, it never kills
272
+ anything.
276
273
 
277
274
  ## 🔴 Footguns — never do these (each measured, each cost real time or state)
278
275
 
@@ -48,14 +48,14 @@ 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
- 🔴 **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.
51
+ 🔴 **On macOS, use `service.mac_restart_command`, not `service.restart_command`.** (Example — Thrum adapter: `service.mac_restart_command` preserves Local Network (TCC) permission.) 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. After a mac restart, verify the peers on the LAN reconnect, not just the version.
52
52
 
53
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.
54
54
 
55
55
  - Adapter flag `service.never_timeout` is true.
56
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.
57
57
 
58
- > Example — Thrum project: restart via `thrum daemon restart`, never wrapped in `timeout`; mac path via `scripts/mac-daemon-restart-via-cron.sh`.
58
+ > Example — Thrum adapter: use the configured `service.mac_restart_command` on macOS; use `service.restart_command` otherwise. Never wrap either in `timeout`.
59
59
 
60
60
  ## 5. Install from the delivered artifact (never rebuild on the node)
61
61
 
@@ -122,12 +122,13 @@ rediscovering these the hard way:
122
122
  starves and hits the configured `-timeout` wall in both the race and
123
123
  non-race lane. The gate's OUTPUT must show the sharded runner actually
124
124
  executed for RPC (`race-shard` / `package-shard --mode norace`, or
125
- `scripts/test-run.sh race|norace ./internal/daemon/rpc`, or `make gate`
125
+ the project's sharded test runner (race or norace lane) on `./internal/daemon/rpc`, or `make gate`
126
126
  which shards both lanes automatically) — not just that some RPC test ran.
127
127
  A bound-timeout with ZERO test failures is a FALSE RED, not a finding:
128
128
  distinguish it from a genuine hang/deadlock via
129
129
  `go run ./cmd/testgate classify-timeout --log <file> --shard-config <file>
130
- --shard <name>` (fails closed — only BOUND-TIMEOUT exits 0; HANG and
130
+ --shard <name> --pkg-dir <package dir>` (shard configs are hash-placed, so
131
+ `--pkg-dir` is required) (fails closed — only BOUND-TIMEOUT exits 0; HANG and
131
132
  UNCLASSIFIED both exit nonzero) before reporting it as a regression.
132
133
  If a gate's own command line invokes the bare package path for RPC, that is a gate defect, not a passing lane.
133
134
  A HANG or UNCLASSIFIED verdict from `classify-timeout` requires human review.
@@ -200,6 +201,14 @@ when the ledger-equality test alone would pass.
200
201
 
201
202
  ## Delta re-gate continuity — walk the whole branch, read the whole function
202
203
 
204
+ **When a delta re-gate exists at all:** only after a gate found a failing test
205
+ or a blocking finding that the change itself causes, and the author pushed a
206
+ fix for it. Then the gate reruns only the lanes that were red plus the packages
207
+ the fix touches. A delta re-gate is NEVER asked for because trunk moved, because
208
+ the branch merged trunk, because a generated file was regenerated, or because a
209
+ minor finding was fixed: a green run lands as it is (coordinator-merging-code,
210
+ "LAND ON GREEN").
211
+
203
212
  **Why:** A commit introducing a lock can be an ancestor of a delta-re-gate's
204
213
  base and never appear in any walked diff, even when a later commit edits the
205
214
  gating condition on that call. Root cause: the gate is delta-scoped. The diff
@@ -26,6 +26,78 @@ authority for this branch in practice (check with your team, or your
26
26
  project's own operational convention); if that is not you, route the merge
27
27
  to them the same as if the map had named them explicitly.
28
28
 
29
+ ## LAND ON GREEN — read this before anything else in this skill
30
+
31
+ **If a green gate run comes in, that is enough. Land it in the same turn.**
32
+ Sending a green change back costs hours on every landing and delays all
33
+ development. Nothing below in this skill overrides this section; where another
34
+ line seems to, this section wins.
35
+
36
+ 1. **Green run + clean merge against trunk = merge now**, in the turn the
37
+ verdict, or the request to land, arrives.
38
+ 2. **Trunk moving never invalidates a green run.** The gate takes trunk once for
39
+ its landing tree. Do not ask for a merge-forward, a fast-forward, a rebase or
40
+ a re-run because trunk has moved since.
41
+ 3. **No "delta gates".** A merge-forward followed by a second gate of the new
42
+ tip is the same send-back loop under another name. So is a "validation run",
43
+ a "confirmation run", a "re-pin", a "re-admit" or a "fresh full gate" of a
44
+ change that already has a green run. Do not ask for any of them.
45
+ 4. **Minor findings do not reopen a gate.** If a small commit on the branch
46
+ already fixes them, land the tip and name that commit in the merge message.
47
+ If they are not fixed, land and route the fix as a follow-up.
48
+ 5. **Generated-file conflicts are the gate's to regenerate**, as a
49
+ gate-authored commit on the landing ref, with no race re-run and no trip
50
+ back to the implementer.
51
+ 6. **No post-landing verification gate.** The next gate's landing tree contains
52
+ the landing and covers it.
53
+ 7. **Do not hold a ready change behind another landing** unless the two
54
+ actually conflict when merged.
55
+ 8. **A chain of branches built on top of each other lands as ONE merge.** They
56
+ build on each other; gate the top of the chain once (it contains the rest)
57
+ and merge it once. Do not gate or merge the links separately, and do not ask
58
+ for four merges when the chain has four links.
59
+ 9. **A request to land gets a merge or a named blocking finding**, with the
60
+ failing test name or the file and line. Never a status report, and never a
61
+ place in a queue.
62
+
63
+ ### What the per-landing gate runs (owner ruling, 2026-10-11) — no race on every landing
64
+
65
+ **A full race is NOT run for every landing.** Landings go in on a non-race
66
+ gate, and trunk is raced in batches. **Nothing gets to deploy without a race.**
67
+
68
+ The per-landing gate:
69
+
70
+ 1. Landing tree on trunk, taken once.
71
+ 2. Build and vet (default and darwin).
72
+ 3. The NON-RACE lane (the project test runner's `norace` lane, one concrete package per
73
+ call) for the packages the diff touches. The non-race lane runs every test;
74
+ the race lane runs the same tests with the detector on.
75
+ 4. The structural checks (shard configs, census coverage, the guard tests the
76
+ change names); the gate regenerates generated files itself.
77
+ 5. Only where the change is itself a concurrency change — it adds or changes a
78
+ lock, a channel, a goroutine, a context-cancellation path, or a fence
79
+ against a concurrent actor — also the change's OWN focused race selectors
80
+ (the tests it adds), not the whole package under race.
81
+ 6. An explicit verdict with the landing ref. Green lands the same turn.
82
+
83
+ The batch race:
84
+
85
+ - After every FIVE landings, dispatch ONE full race of trunk
86
+ (the project test runner's `race all`) to one gate.
87
+ - A failure is attributed to a landing by test name and stack trace and fixed
88
+ as a follow-up. Landings are not unwound, and other landings do not wait.
89
+ - **A bundle is built only from a trunk commit that has a green full race.**
90
+ If the last batch race is older than trunk's tip, race the tip first.
91
+
92
+ A non-race run may take a pool slot above the cap (lower load); a race run
93
+ uses a normal slot.
94
+
95
+ The only things that stop a landing: a failing test that the change itself
96
+ causes, named; a blocking review finding, with file and line; a hand-written
97
+ merge conflict (the implementer resolves that one conflict, and only the
98
+ conflicting part is checked again); or no gate run at all, in which case the
99
+ change goes on a gate as that gate's next job, not back to its author.
100
+
29
101
  > 🔴 **THE ONE THING MOST OFTEN GOT WRONG: YOU DO NOT RUN THE GATES. YOU DISPATCH
30
102
  > THEM TO THE GATE RUNNER.** See §3. A coordinator that walks the lenses inline
31
103
  > burns the one resource it cannot replace and leaves **no auditable verdict** —
@@ -49,10 +121,12 @@ agent and either one finding or an explicit zero, per axis. **An absent report a
49
121
  a clean report are different things**, and silence defaults to the reading you
50
122
  want. If an axis goes silent twice, re-route it rather than re-spawning.
51
123
 
52
- **A verdict attaches to an OBJECT.** If the branch takes a new commit after review
53
- — including a merge-forward — the prior verdicts do not transfer. **Re-dispatch the
54
- axes on the delta.** A fix produced in response to a finding is exactly where the
55
- next defect lives.
124
+ **A review verdict attaches to the change it read.** If the branch takes a new
125
+ commit that changes behaviour after review, a reviewer reads that commit before
126
+ it lands. A merge of trunk into the branch, a regenerated generated file, or a
127
+ commit that only fixes a minor finding the gate already named is NOT a new
128
+ object: the prior review and the green gate run stand, and nothing is
129
+ re-dispatched for it (see "LAND ON GREEN" above).
56
130
 
57
131
  **Consolidate into ONE numbered list** across all severities before anything goes
58
132
  back to the implementer. Never send partial findings; they fix batch 1 and miss
@@ -170,7 +244,7 @@ executed half is **scoped to the change**:
170
244
 
171
245
  - Build the merged tree (`go build ./...`).
172
246
  - 🔴 **RULING:** the full sharded race suite —
173
- `scripts/test-run.sh race all` (~15-20 min) — on the **merged tree**, every
247
+ the project's sharded race test runner over all packages (~15-20 min) — on the **merged tree**, every
174
248
  Pass-3 verdict. This replaces the prior "changed packages only (+ rpc shard
175
249
  sweep)" race scoping below the ruling; a targeted `-run` is still never
176
250
  acceptable (a targeted run misses cross-test races). Never on primary (the
@@ -93,10 +93,10 @@ dispatch time — hand this list verbatim:
93
93
  **Exception: `internal/daemon/rpc` must NEVER be run monolithically** — a
94
94
  bare `go test [-race] ./internal/daemon/rpc` cannot finish inside any
95
95
  gate-length timeout. Run it through the sharded runner (`race-shard`,
96
- `scripts/test-run.sh race ./internal/daemon/rpc`, or `make gate`) and confirm
96
+ the project's sharded race test runner on `./internal/daemon/rpc`, or `make gate`) and confirm
97
97
  the gate's output shows it executed. A bound-timeout with ZERO test failures
98
98
  is a false red: classify it with `go run ./cmd/testgate classify-timeout
99
- --log <file> --shard-config <file> --shard <name>` (only BOUND-TIMEOUT exits
99
+ --log <file> --shard-config <file> --shard <name> --pkg-dir <package dir>` (only BOUND-TIMEOUT exits
100
100
  0) before reporting a regression. See item 7 of `coordinator-hotpath-merge-gate`.
101
101
  7. Build+test the MERGED-tree result as a SEPARATE condition — neither gate
102
102
  currently runs a build of the actual post-merge tree; a clean pre-merge
@@ -62,7 +62,7 @@ Build once per artifact on its `artifact.build_host` via `artifact.build_command
62
62
  ## 5. The staged order — canary, waves, prepare-and-hold, promotion gate
63
63
 
64
64
  > 🔴 **If any node fails during the rollout — canary or any wave — STOP THE ROLLOUT.** Do not roll, restart, or recommend
65
- > restarting any further node (including the build host / primary) until the failure is root-caused and fixed or the
65
+ > restarting any further node (including the build host) until the failure is root-caused and fixed or the
66
66
  > owner explicitly decides to continue. A node that went down and was recovered by hand is a FAILURE, not a green.
67
67
 
68
68
  - **Canary first, alone.** One node (adapter `topology.canary`) rolls first. Its health must be observed green before any wave proceeds.
@@ -94,4 +94,4 @@ The node's local runbook is `coordinator-deploying-a-node` — reference that sk
94
94
  - If `fleet.deployment.thrum.products` exists (vestigial), STOP — products live only at `fleet.deployment.products`.
95
95
  - If a node reports success by exit code alone without observed-effect verification, treat as not-verified.
96
96
  - Never wrap a service restart in a blind timeout on the node (see node skill `service.never_timeout` and `migration.signal_rules`).
97
- - 🔴 A **macOS** node (including the build host / primary) restarted with the plain `service.restart_command` instead of `service.mac_restart_command` (Thrum: `scripts/mac-daemon-restart-via-cron.sh`). The daemon loses its Local Network permission and its LAN peers go dark while it looks healthy. Put the mac command in every macOS node's dispatch, and use it yourself when you roll the build host last.
97
+ - 🔴 A **macOS** node restarted with the plain `service.restart_command` instead of `service.mac_restart_command` (Example — Thrum adapter: `service.mac_restart_command`). The daemon loses its Local Network permission and its LAN peers go dark while it looks healthy. Put the mac command in every macOS node's dispatch, and use it yourself when you roll the build host last.
@@ -249,5 +249,5 @@ name the wrong path or wrong query explicitly, so the next reader recognises
249
249
  their own mistake rather than just reading the right answer; and if a claim is
250
250
  about runtime behaviour, say how it was measured.
251
251
 
252
- > *Dev-fleet only: after editing, run `scripts/sync-skills.sh` so every runtime
252
+ > *Dev-fleet only: after editing, regenerate the runtime plugin mirrors so every runtime
253
253
  > plugin picks it up.*
@@ -62,7 +62,7 @@ EOF
62
62
  ```
63
63
 
64
64
  If the coordinator asks you to file the bead, write the description to a scratch
65
- file and pass `--body-file <file>` to `scripts/bd-shared` (and
65
+ file and pass `--body-file <file>` to the project's shared `bd` wrapper (and
66
66
  `comments add <id> -f <file>` for comments).
67
67
 
68
68
  Then continue with the assigned work. Do not implement the refactoring.
@@ -778,7 +778,7 @@ and report a confident verdict about it.
778
778
  - **Require the reviewer to report back the SHA it actually scanned.** If the
779
779
  SHA it reports is not the SHA you pinned, the verdict is VOID — re-dispatch.
780
780
  Do not accept a verdict that cannot name its own base.
781
- - Cite `origin/<branch>` (e.g. `git show origin/thrum-agents:path/to/file.go`),
781
+ - Cite `origin/<branch>` (e.g. `git show origin/<base>:path/to/file.go`),
782
782
  never a working copy, when reasoning about tip state. A stale local clone
783
783
  produces confident, wrong impeachments — and sub-agents reading that same
784
784
  stale clone will "corroborate" it. That is echo, not corroboration.
@@ -26,12 +26,28 @@ every agent in your `roster`:
26
26
  unreachable) is escalated to your `parent` every cycle until a coordinator
27
27
  or human removes it from your roster — never dropped, never silently
28
28
  given up on (see Escalation).
29
- 2. **Watch its context% and warn.** Read its ctx% from YOUR OWN tmux
30
- capture of its status bar — **never from a figure it claims about
31
- itself** (a message, a memory-footer line, anywhere). If it's getting
32
- close to the end and hasn't restarted, warn it. This is the exact
33
- mechanism — a watcher that trusts the target's self-report would catch
34
- none of them.
29
+ 2. **Watch context, warn, and compact only when exhausted.** Read ctx% from
30
+ YOUR OWN tmux capture of its status bar — **never from a figure it claims
31
+ about itself** (a message, a memory-footer line, anywhere). Reuse your
32
+ configured `restart_ctx_pct` as the target warning threshold (default
33
+ 50%); this does not change its separate use for your own self-restart.
34
+ At that threshold, warn the target if it has not restarted. Do not compact
35
+ at the threshold alone. Compact only when a fresh pane capture shows the
36
+ target is out of context AND two consecutive fresh checks show it at rest,
37
+ using the idle criteria in "Declared-intent reminders" below. Never
38
+ interrupt an active turn.
39
+
40
+ Get the target runtime from that member's `runtime` field in
41
+ `thrum team --json`; do not guess. Send its verified compact command (`/compact` for Claude,
42
+ Codex, and OpenCode; `/summarize` for Cursor; no command for runtimes
43
+ without a verified equivalent) with one `thrum tmux send <session>
44
+ "<command>"` call. That call settles and withholds Enter if a dialog
45
+ appears; never send a separate Enter. Exit 3 (Enter withheld) or 4
46
+ (verdict unknown) requires a fresh capture before any retry. If a
47
+ cross-peer send fails (for example, `can_send_keys` is unavailable),
48
+ escalate to your `parent` instead of retrying or switching transports.
49
+ Never resend while the command is queued or already visible in the pane.
50
+ After sending, report one line to your `parent`.
35
51
  3. **All of it is judgment.** Read pane, judge (unblock / warn-on-ctx /
36
52
  escalate), act or escalate. Every cycle, every roster member.
37
53
  4. **Catch declared-but-unexecuted intent.** If a roster member's last
@@ -60,7 +76,7 @@ every agent in your `roster`:
60
76
 
61
77
  ### Approving or dismissing a modal: keys only, never text
62
78
 
63
- > 🔴 **NEVER answer a modal with a text payload — not even a single
79
+ > 🔴 **For modal handling, NEVER answer with a text payload — not even a single
64
80
  > character, and never a bare positional argument to `thrum tmux send`.**
65
81
  > Plain text TYPES INTO the agent's input box; it does not act as a
66
82
  > keypress. If the modal isn't actually showing, or focus differs from what
@@ -438,7 +454,7 @@ problem rather than a clean tick.
438
454
 
439
455
  ## Relationship to the deterministic context-monitoring sweep
440
456
 
441
- You are NOT a replacement for `scripts/error-and-context-agent-sweep.sh`
457
+ You are NOT a replacement for the fleet's deterministic context-monitoring sweep
442
458
  (the `context-monitoring` `thrum monitor` job, `@every 30m`,
443
459
  self-gated to ~30-60min effective) — the two COEXIST. The sweep stays the fleet-wide, always-on,
444
460
  zero-incremental-cost tripwire covering every agent, including ones with no
@@ -59,7 +59,7 @@
59
59
  # worktree-local copy) the moment this script or its cwd ever moves to a
60
60
  # feature worktree. `resolve_watch_params()` below replaces that implicit
61
61
  # assumption with the same explicit `.thrum/redirect`-following idiom
62
- # already used by `scripts/heartbeat-lib.sh:225-232` and
62
+ # already used by the heartbeat library and
63
63
  # the check-inbox hook script.
64
64
  #
65
65
  # PORTABILITY FIX: both source scripts also hardcoded a single operator's
@@ -104,8 +104,8 @@ set -uo pipefail
104
104
  # both of which were independently reimplementing this same body).
105
105
  # ---------------------------------------------------------------------------
106
106
  # Args: worktree_root. Prints the redirect-resolved absolute .thrum/ dir.
107
- # Matches the idiom already used by scripts/heartbeat-lib.sh's
108
- # hb_sessions_dir() and the check-inbox hook script's SPOOL_THRUM
107
+ # Matches the idiom already used by the heartbeat library's
108
+ # session-dir helper and the check-inbox hook script's SPOOL_THRUM
109
109
  # resolution: no redirect file present (main repo) -> use the local .thrum/
110
110
  # as-is; redirect file present (feature worktree) -> follow it to the main
111
111
  # repo's .thrum/.
@@ -241,7 +241,7 @@ configuration from day one.
241
241
  ## Inputs
242
242
 
243
243
  Primary input: **plan file path** (output of writing-plans, e.g.
244
- `dev-docs/plans/2026-02-21-feature-plan.md`). The plan references the design doc
244
+ `dev-docs/plans/YYYY-MM-DD-feature-plan.md`). The plan references the design doc
245
245
  — both are read in Phase 1.
246
246
 
247
247
  Also needed from CLAUDE.md or conversation context:
@@ -476,7 +476,7 @@ template's "Logging Refactoring Opportunities" section.
476
476
  If not found, create one:
477
477
 
478
478
  `--description` is multi-line prose — never double-quoted inline. Use
479
- `--body-file` to pass the content from a file instead; see the heredoc-or-file rule in your role preamble. `scripts/bd-shared` delivers `--body-file` (and
479
+ `--body-file` to pass the content from a file instead; see the heredoc-or-file rule in your role preamble. The project's shared `bd` wrapper delivers `--body-file` (and
480
480
  `--stdin`) content: it reads the file on your box and pipes those bytes to bd,
481
481
  and an empty or blank body is refused loudly; only `-f`/`--file` and `--graph`
482
482
  (bulk-plan files) are refused there. Scratch files go in `/private/tmp` on macOS,
@@ -641,8 +641,8 @@ cat .thrum/redirect # should point to <project-root>/.thrum
641
641
  cat .beads/redirect # should point to <project-root>/.beads
642
642
 
643
643
  # If redirects are missing or wrong, fix them:
644
- # (from project root)
645
- ./scripts/setup-worktree-thrum.sh <worktree-path>
644
+ # (from the worktree; non-destructive and idempotent)
645
+ thrum worktree adopt
646
646
 
647
647
  # Verify beads sees shared database
648
648
  bd where # Should show <project-root>/.beads
@@ -673,14 +673,9 @@ thrum worktree create <worktree-name> --branch <branch-name> \
673
673
  thrum worktree setup <worktree-name> --branch <branch-name> \
674
674
  --name <agent-name> --role implementer
675
675
 
676
- # Alternative: shell script (does the same thing; the SCRIPT keeps its own
677
- # <worktree-path> <branch> --identity interface — distinct from the CLI above)
678
- ./scripts/setup-worktree-thrum.sh \
679
- <worktree-path> <branch-name> \
680
- --identity <agent-name> --role implementer
681
676
  ```
682
677
 
683
- All three handle: branch creation, worktree creation, thrum redirect, beads
678
+ Both handle: branch creation, worktree creation, thrum redirect, beads
684
679
  redirect, and `thrum quickstart` registration.
685
680
 
686
681
  #### For current worktree (small fixes)
@@ -894,8 +889,8 @@ Worktree ready at `{{WORKTREE_PATH}}` on branch `{{BRANCH_NAME}}`. Agent
894
889
 
895
890
  <!-- If worktree needs to be created by the implementation agent: -->
896
891
 
897
- ./scripts/setup-worktree-thrum.sh {{WORKTREE_PATH}} {{BRANCH_NAME}} \
898
- --identity {{AGENT_NAME}} --role implementer
892
+ thrum worktree create <worktree-name> --branch {{BRANCH_NAME}} \
893
+ --name {{AGENT_NAME}} --role implementer
899
894
 
900
895
  ---
901
896
 
@@ -438,7 +438,7 @@ bd list --type=epic | grep -i refactor
438
438
  If no refactoring epic exists, create one:
439
439
 
440
440
  `--description` is multi-line prose — never double-quoted inline. Write it to a
441
- scratch file and pass `--body-file <file>`; see the heredoc-or-file rule in your role preamble. `scripts/bd-shared` delivers `--body-file` (and `--stdin`)
441
+ scratch file and pass `--body-file <file>`; see the heredoc-or-file rule in your role preamble. The project's shared `bd` wrapper delivers `--body-file` (and `--stdin`)
442
442
  content: it reads the file on YOUR box and pipes those bytes to bd, and an empty
443
443
  or blank body is refused loudly. Only `-f`/`--file` and `--graph` (bulk-plan
444
444
  files) are refused there. Scratch files go in `/private/tmp` on macOS, where
@@ -563,7 +563,7 @@ EOF
563
563
  # NOTE: delivers only to agent(s) matching @implementer — see the mention-delivery
564
564
  # note under "Handling Blockers" above for the full rule.
565
565
  thrum send --mention @implementer --stdin <<'EOF'
566
- Heads up: I'm modifying internal/daemon/rpc.go which may overlap with your work
566
+ Heads up: I'm modifying <shared-file> which may overlap with your work
567
567
  EOF
568
568
 
569
569
  # Update your intent when switching tasks
@@ -52,7 +52,7 @@ findings yet. Each line ≤120 chars; cite a file area or epic if relevant.
52
52
  Example:
53
53
 
54
54
  ```text
55
- - Is the embedding adapter wired post-<epic>? (check internal/memory/embed/adapter_ollama.go)
55
+ - Is the embedding adapter wired post-<epic>? (check the embedding adapter source)
56
56
  - thrum-abc monitor reliability follow-up still has 4 child bugs open
57
57
  - Open: does --scope role on memory.create auto-infer the role, or does it require explicit value?
58
58
  ```
@@ -1051,7 +1051,7 @@ thrum memory migrate-from-bd --rollback --confirm-rollback "DELETE 53"
1051
1051
 
1052
1052
  # Explicit manifest, hard purge:
1053
1053
  thrum memory migrate-from-bd --rollback \
1054
- --manifest dev-docs/migrations/2026-05-26T1500Z-bd-to-thrum-migration-manifest.json \
1054
+ --manifest <migration-manifest.json> \
1055
1055
  --hard --confirm-rollback "DELETE 53"
1056
1056
  ```
1057
1057
 
@@ -25,7 +25,7 @@ prevents duplicate listeners — spawning when one is already running is safe.
25
25
  Task(
26
26
  subagent_type="message-listener",
27
27
  model="<per choosing-subagent-models>", # cheapest tier
28
- prompt="Listen for Thrum messages.\nSTEP_1: /path/to/repo/scripts/thrum-startup.sh --listener-heartbeat\nSTEP_2: thrum wait --timeout 8m --after -15s --agent-name <agent_id>"
28
+ prompt="Listen for Thrum messages.\nSTEP_1: thrum-startup --listener-heartbeat\nSTEP_2: thrum wait --timeout 8m --after -15s --agent-name <agent_id>"
29
29
  )
30
30
  ```
31
31
 
@@ -59,7 +59,7 @@ Automatically respawn the listener if it dies or is lost after compaction.
59
59
  ```text
60
60
  CronCreate(
61
61
  cron="*/30 * * * *",
62
- prompt="Check the listener PID file at .thrum/var/<agent_id>-listener.pid.\nIf the file does not exist, or if kill -0 <pid> fails (process not running),\nspawn a new listener:\n\nAgent(subagent_type=\"message-listener\", model=\"<per choosing-subagent-models>\", prompt=\"Listen for Thrum messages.\\nSTEP_1: /path/to/repo/scripts/thrum-startup.sh --listener-heartbeat\\nSTEP_2: thrum wait --timeout 8m --after -15s --agent-name <agent_id>\")"
62
+ prompt="Check the listener PID file at .thrum/var/<agent_id>-listener.pid.\nIf the file does not exist, or if kill -0 <pid> fails (process not running),\nspawn a new listener:\n\nAgent(subagent_type=\"message-listener\", model=\"<per choosing-subagent-models>\", prompt=\"Listen for Thrum messages.\\nSTEP_1: thrum-startup --listener-heartbeat\\nSTEP_2: thrum wait --timeout 8m --after -15s --agent-name <agent_id>\")"
63
63
  )
64
64
  ```
65
65