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.
- package/assets/commands/thrum-compact-extended.md +5 -0
- package/assets/commands/thrum-compact.md +5 -0
- package/assets/skills/coordinator-assessing-agent-completion/SKILL.md +17 -20
- package/assets/skills/coordinator-deploying-a-node/SKILL.md +2 -2
- package/assets/skills/coordinator-hotpath-merge-gate/SKILL.md +11 -2
- package/assets/skills/coordinator-merging-code/SKILL.md +79 -5
- package/assets/skills/coordinator-philosophy-merge-gate/SKILL.md +2 -2
- package/assets/skills/coordinator-rolling-out-to-nodes/SKILL.md +2 -2
- package/assets/skills/diagnosing-fleet-and-daemon/SKILL.md +1 -1
- package/assets/skills/implementer-receiving-dispatch/SKILL.md +1 -1
- package/assets/skills/orchestrate/SKILL.md +1 -1
- package/assets/skills/persistent-watcher-archetype/SKILL.md +24 -8
- package/assets/skills/persistent-watcher-archetype/resources/roster-watch.sh +3 -3
- package/assets/skills/project-setup/SKILL.md +7 -12
- package/assets/skills/project-setup/resources/implementation-agent.md +2 -2
- package/assets/skills/researcher-maintaining-memory/SKILL.md +1 -1
- package/assets/skills/thrum/resources/CLI_REFERENCE.md +1 -1
- package/assets/skills/thrum/resources/LISTENER_PATTERN.md +2 -2
- package/assets/skills/using-monitors/SKILL.md +156 -18
- package/assets/skills/using-tmux-ssh/SKILL.md +121 -0
- package/assets/skills/using-tmux-ssh/resources/tmux-ssh +1158 -0
- package/assets/skills/verify-against-plan/SKILL.md +1 -1
- package/dist/installer.js +3 -5
- package/package.json +1 -1
- package/assets/skills/coordinator-context-monitoring/SKILL.md +0 -685
- 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 (`
|
|
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
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
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.**
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
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,
|
|
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
|
|
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
|
-
|
|
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>` (
|
|
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
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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,
|
|
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 `
|
|
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
|
|
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
|
|
30
|
-
capture of its status bar — **never from a figure it claims
|
|
31
|
-
itself** (a message, a memory-footer line, anywhere).
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
108
|
-
#
|
|
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/
|
|
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. `
|
|
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
|
|
645
|
-
|
|
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
|
-
|
|
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
|
-
|
|
898
|
-
--
|
|
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. `
|
|
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
|
|
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
|
|
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
|
|
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:
|
|
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:
|
|
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
|
|