opencode-thrum-pro 0.1.5 → 0.1.7
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 +367 -0
- package/assets/commands/thrum-compact.md +301 -0
- package/assets/commands/thrum-inbox.md +1 -1
- package/assets/commands/thrum-restart-extended.md +85 -16
- package/assets/commands/thrum-restart.md +106 -14
- package/assets/commands/thrum-send.md +4 -1
- package/assets/commands/thrum-sleep-extended.md +68 -51
- package/assets/commands/thrum-sleep.md +68 -63
- package/assets/commands/thrum-update-project.md +1 -1
- package/assets/skills/adversarial-critique/SKILL.md +5 -8
- package/assets/skills/brainstorm-steward/SKILL.md +65 -11
- package/assets/skills/brainstormer-staying-current/SKILL.md +1 -4
- package/assets/skills/choosing-subagent-models/SKILL.md +200 -70
- package/assets/skills/closing-findings-while-warm/SKILL.md +1 -2
- package/assets/skills/configure-roles/SKILL.md +2 -2
- package/assets/skills/conversation-only-context/SKILL.md +11 -11
- package/assets/skills/conversation-only-context/resources/driver-subagent-pattern.md +1 -1
- package/assets/skills/conversation-only-context/resources/remote-environment-scenarios.md +1 -1
- package/assets/skills/coordinator-assessing-agent-completion/SKILL.md +98 -6
- package/assets/skills/coordinator-branch-split-on-block/SKILL.md +1 -2
- package/assets/skills/coordinator-context-monitoring/SKILL.md +29 -19
- package/assets/skills/coordinator-deploying-a-node/SKILL.md +124 -0
- package/assets/skills/coordinator-dispatching-work/SKILL.md +26 -14
- package/assets/skills/coordinator-hotpath-merge-gate/SKILL.md +65 -21
- 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 +7 -8
- package/assets/skills/coordinator-merging-code/SKILL.md +43 -22
- package/assets/skills/coordinator-philosophy-merge-gate/SKILL.md +29 -9
- package/assets/skills/coordinator-plan-reconcile-gate/SKILL.md +4 -5
- package/assets/skills/coordinator-rolling-out-to-nodes/SKILL.md +92 -0
- package/assets/skills/coordinator-running-autonomous-feature-development/SKILL.md +3 -3
- package/assets/skills/coordinator-running-brainstorm-cycles/SKILL.md +25 -25
- package/assets/skills/coordinator-running-review-cycles/SKILL.md +16 -6
- package/assets/{commands/thrum-_deviations-protocol.md → skills/deviations-protocol/SKILL.md} +6 -12
- package/assets/skills/diagnosing-fleet-and-daemon/SKILL.md +0 -2
- package/assets/skills/efficient-multi-agent-research/SKILL.md +3 -3
- 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 +12 -16
- 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-curate/SKILL.md +1 -1
- package/assets/skills/memory-write-discipline/SKILL.md +1 -1
- package/assets/skills/orchestrate/SKILL.md +77 -36
- package/assets/skills/persistent-watcher-archetype/SKILL.md +172 -25
- package/assets/skills/persistent-watcher-archetype/resources/capture_archive.py +618 -0
- package/assets/skills/persistent-watcher-archetype/resources/jev_watcher_filter.py +837 -0
- package/assets/skills/persistent-watcher-archetype/resources/roster-watch.sh +1140 -0
- package/assets/skills/persistent-watcher-archetype/resources/roster-watch_test.sh +291 -0
- package/assets/skills/persistent-watcher-archetype/resources/thrum-capture-fallback.sh +2 -2
- package/assets/skills/persistent-watcher-archetype/resources/thrum-watch-pane-capture.sh +20 -8
- package/assets/skills/prime-agent/SKILL.md +10 -0
- package/assets/skills/project-hotpath-gate/SKILL.md +1 -2
- package/assets/skills/project-philosophy/SKILL.md +1 -2
- package/assets/skills/project-rules-protocol/SKILL.md +12 -0
- package/assets/skills/project-setup/SKILL.md +27 -22
- package/assets/skills/project-setup/resources/implementation-agent.md +55 -35
- package/assets/skills/researcher-answering-queries/SKILL.md +1 -2
- package/assets/skills/researcher-investigating/SKILL.md +8 -13
- package/assets/skills/researcher-maintaining-memory/SKILL.md +1 -1
- package/assets/{commands/thrum-_snapshot-protocol.md → skills/snapshot-protocol/SKILL.md} +27 -21
- package/assets/{commands/thrum-_stamp-protocol.md → skills/stamp-protocol/SKILL.md} +14 -8
- package/assets/skills/thrum/SKILL.md +14 -7
- package/assets/skills/thrum/resources/ANTI_PATTERNS.md +16 -18
- package/assets/skills/thrum/resources/CLI_REFERENCE.md +17 -11
- package/assets/skills/thrum/resources/LISTENER_PATTERN.md +9 -3
- package/assets/skills/thrum/resources/MESSAGING.md +18 -11
- package/assets/skills/thrum/resources/WORKTREES.md +1 -1
- package/assets/skills/thrum-memory/SKILL.md +1 -1
- package/assets/skills/trace-spec-to-plan/resources/sweep-agent-prompt.md +1 -1
- package/assets/skills/update-queue/SKILL.md +6 -8
- package/assets/skills/using-the-dashboard/SKILL.md +30 -0
- package/assets/skills/using-the-queue/SKILL.md +76 -5
- package/assets/skills/using-thrum-state/SKILL.md +85 -2
- package/assets/skills/verify-against-plan/SKILL.md +122 -7
- package/assets/skills/watcher-archetype/SKILL.md +18 -0
- package/assets/skills/writing-durable-markdown/SKILL.md +5 -0
- package/dist/installer-assets.test.js +41 -0
- package/dist/installer.js +4 -4
- package/dist/permission-fixture.integration.test.js +4 -4
- package/package.json +1 -1
- 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
- package/assets/skills/coordinator-deploying-the-fleet/SKILL.md +0 -396
- package/dist/allowlist-sync.test.js +0 -44
- /package/dist/{allowlist-sync.test.d.ts → installer-assets.test.d.ts} +0 -0
|
@@ -26,40 +26,51 @@ What's forbidden is a script that bypasses this skill and fires
|
|
|
26
26
|
`thrum tmux restart --force` unconditionally (that violates
|
|
27
27
|
`feedback_restart_discipline` — burn the runway, don't restart on schedule).
|
|
28
28
|
|
|
29
|
-
## Coordinator self-restart — ALWAYS
|
|
29
|
+
## Coordinator self-restart — ALWAYS the EXTENDED form, compact-extended FIRST
|
|
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
|
|
33
|
+
applies and it is absolute — but D5 (owner-ruled)
|
|
34
|
+
REVERSES which command that is:
|
|
34
35
|
|
|
35
|
-
> **The coordinator ALWAYS
|
|
36
|
-
>
|
|
36
|
+
> **The coordinator ALWAYS uses the EXTENDED snapshot grade for itself — never
|
|
37
|
+
> the standard/compact form. Which command carries that grade is
|
|
38
|
+
> runtime-directed: `/thrum:compact-extended` on any runtime with a verified
|
|
39
|
+
> compact-equivalent skill (D6, the default), `/thrum:restart-extended` ONLY
|
|
40
|
+
> as the fallback on a runtime without one (today: muse, copilot).**
|
|
41
|
+
|
|
42
|
+
This is a REVERSAL of the prior absolute rule ("ALWAYS restart-extended, NEVER
|
|
43
|
+
compact") — that rule is retired, not merely relaxed. Do not restore it.
|
|
37
44
|
|
|
38
45
|
Rationale: the coordinator is the nerve center. Its handoff must carry the full
|
|
39
46
|
16-section snapshot (wire contracts, capability matrix, cycle history, open
|
|
40
47
|
L-questions, anticipated Q&A, design rationale) so the next session resumes
|
|
41
|
-
steady-state coordination without re-deriving fleet state
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
steady-state coordination without re-deriving fleet state — that requirement
|
|
49
|
+
is UNCHANGED and is what "EXTENDED" governs; only the compact-vs-restart choice
|
|
50
|
+
changed. Compacting (rather than restarting) additionally keeps the SAME
|
|
51
|
+
process/session alive — sub-agents, background loops, and cron schedules the
|
|
52
|
+
coordinator owns survive the compaction, where a restart would drop them.
|
|
53
|
+
There is no ctx-band at which the coordinator downgrades to the standard/
|
|
54
|
+
compact-grade snapshot — the tier ladder below governs OTHER agents, not this.
|
|
46
55
|
|
|
47
|
-
Practical trigger points for coordinator self-restart:
|
|
56
|
+
Practical trigger points for coordinator self-restart/compact:
|
|
48
57
|
|
|
49
58
|
- A warn-tier context nudge fires on the coordinator's own pane (e.g. 70%+).
|
|
50
59
|
- The coordinator hits a clean checkpoint and elects a fresh session.
|
|
51
60
|
- Rate-limit / stuck-state recovery on the coordinator itself.
|
|
52
61
|
|
|
53
|
-
In every one of these
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
62
|
+
In every one of these: run `/thrum:compact-extended` if the coordinator's
|
|
63
|
+
runtime has a compact equivalent (the default); `/thrum:restart-extended` only
|
|
64
|
+
if it does not. (The role-rule `coord-always-restart-extended` — `Coordinator
|
|
65
|
+
ALWAYS uses /thrum:restart-extended` — is RETIRED as of D5; see
|
|
66
|
+
`thrum memory` for its retirement record. This skill is the always-loaded home
|
|
67
|
+
so the CURRENT rule survives even when memory isn't consulted.)
|
|
57
68
|
|
|
58
69
|
Note the distinction from Steps 3–5 below: those steps drive `/thrum:restart`
|
|
59
70
|
(Step 4) and `/thrum:restart-extended` (Step 5) into
|
|
60
71
|
**implementer/brainstormer** panes per their ctx tier — that tiering is correct
|
|
61
72
|
for worker agents. The carve-out here is ONLY about the coordinator's own
|
|
62
|
-
restart, which is unconditionally the extended
|
|
73
|
+
restart/compact, which is unconditionally the extended grade, compact-first.
|
|
63
74
|
|
|
64
75
|
## How the scheduled sweep works (v0.10.6+ — thrum monitor)
|
|
65
76
|
|
|
@@ -274,10 +285,7 @@ brick.
|
|
|
274
285
|
|
|
275
286
|
## Subagent model selection
|
|
276
287
|
|
|
277
|
-
> **Model tiers:** pass an explicit `model:` on every dispatch
|
|
278
|
-
> (low effort) mechanical, `sonnet` (medium effort) judgment, Opus only on
|
|
279
|
-
> operator-ask or a skill step that names it. See the
|
|
280
|
-
> `choosing-subagent-models` skill for the full policy.
|
|
288
|
+
> **Model tiers:** pass an explicit `model:` on every dispatch; choose model and effort per the `choosing-subagent-models` skill (read `runtime.role_models` at the moment of use). Never let a sub-agent inherit your own model.
|
|
281
289
|
|
|
282
290
|
## Step 1 — Run the sweep
|
|
283
291
|
|
|
@@ -464,6 +472,8 @@ by typing the restart command directly into their input field:
|
|
|
464
472
|
thrum tmux send <tmux_session_name> '/thrum:restart'
|
|
465
473
|
```
|
|
466
474
|
|
|
475
|
+
If it exits 3 (Enter WITHHELD, text already typed) or 4 (verdict unknown), do NOT retype it: `thrum tmux capture` the pane and submit with `thrum tmux send <tmux_session_name> --keys Enter` only if no dialog is showing.
|
|
476
|
+
|
|
467
477
|
(Find the tmux session name in sweep output — it's typically the worktree
|
|
468
478
|
basename, e.g. `myepic-impl`, NOT the agent_id.)
|
|
469
479
|
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: coordinator-deploying-a-node
|
|
3
|
+
description: "Use when deploying a build to a single node, migrating or not — deploying a build, schema-migrating deploy, pro-bundle install plus service restart on a node, roll out a build to a node, ship to a node, single-node canary. Loads the deploy runbook — verifying the artifact actually CONTAINS the fix, install-before-restart ordering, verify-by-effect, and preventing store corruption on migration."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Coordinator: Deploying a Build to a Single Node — migrating or not
|
|
7
|
+
|
|
8
|
+
> This runbook covers EVERY deploy to a single node, migrating or not. Most sections apply to every deploy; only migration-weight and store-corruption specifics are bump-only.
|
|
9
|
+
|
|
10
|
+
## 0. Pull-current first (ff-only)
|
|
11
|
+
|
|
12
|
+
The absolute first action before anything else: fetch the control-plane repository and fast-forward to the orchestrator's pin.
|
|
13
|
+
|
|
14
|
+
- Read the project's deployment adapter inside `.thrum/config.json` (`fleet.deployment`; reference at the deployment-adapter reference) to obtain `preflight.pull_command` and `preflight.pin_command`.
|
|
15
|
+
- Run `preflight.pull_command` (must be ff-only; if not fast-forwardable, STOP and surface — never blind-merge in the shared tree).
|
|
16
|
+
- Verify the delivered artifact actually CONTAINS the fix at the pinned SHA (adapter `artifact.commit_file` sidecar).
|
|
17
|
+
|
|
18
|
+
This ensures the node's coordinator reasons from a checkout that is actually current before evaluating backup, install, or migration.
|
|
19
|
+
|
|
20
|
+
> Example — Thrum project: pull via `git fetch origin && git merge --ff-only origin/<branch>` before any backup or install.
|
|
21
|
+
|
|
22
|
+
## 1. Who executes — resolve the node's local coordinator (via adapter identity)
|
|
23
|
+
|
|
24
|
+
The node's own coordinator drives the deploy locally on its own host. Never drive a node's build/install/restart from another host.
|
|
25
|
+
|
|
26
|
+
- Resolve WHO via `topology.identity_resolution` (adapter `fleet.deployment.thrum.topology.identity_resolution` or `fleet.deployment.products.<id>.topology`) — a `daemon_id` join plus hostname and absence of `.thrum/redirect`, never by agent name or worktree name.
|
|
27
|
+
- When connected-repo daemons share a host, respect the adapter-defined restart order within that host.
|
|
28
|
+
|
|
29
|
+
If the target node has no working coordinator, state why explicitly before using any fallback.
|
|
30
|
+
|
|
31
|
+
## 2. Back up before touching anything (via adapter backup command + sizing formula)
|
|
32
|
+
|
|
33
|
+
- Run the project's backup command (`fleet.deployment.thrum.backup.command` or `fleet.deployment.products.<id>.backup.command`) and verify per `backup.verify`.
|
|
34
|
+
- Size BEFORE you run it on a bloated node: apply the adapter's `backup.sizing_formula` (`free_at_completion = free_now - zip(stale current/) + size(stale current/) - size(live lane)`) — the stale `current/` is removed before the fresh export, so peak is not double-count. Retention runs last and does not bound the peak.
|
|
35
|
+
- On failure, roll back via `backup.restore_command`; never delete the store.
|
|
36
|
+
|
|
37
|
+
> Example — Thrum project: backup via `thrum backup`, sized per the formula above, verified with `sqlite3 ?mode=ro&immutable=1` read.
|
|
38
|
+
|
|
39
|
+
## 3. Storage access — through the engine or control-plane CLI, never file-bypass
|
|
40
|
+
|
|
41
|
+
Access the state store only through the engine or the control-plane CLI in read-only mode. Never bypass the storage engine's file ownership.
|
|
42
|
+
|
|
43
|
+
- Via: `storage_access.via` (e.g., CLI or `?mode=ro`).
|
|
44
|
+
- Forbidden: `storage_access.forbidden` (e.g., hand-copy of live `-wal`/`-shm`, concurrent `.backup` on live store).
|
|
45
|
+
- A bare read-write open can fire a checkpoint that truncates the write log out from under live readers → sustained corruption. Always use `?mode=ro` where applicable.
|
|
46
|
+
|
|
47
|
+
If the project has no WAL/SHM, this section is N/A — skip and note.
|
|
48
|
+
|
|
49
|
+
## 4. Never wrap service start/restart in a blind timeout
|
|
50
|
+
|
|
51
|
+
Run the project's service restart command (`fleet.deployment.thrum.service.restart_command` or product equivalent) without a blind timeout wrapper. A timeout that kills a migrating restart mid-migration manufactures a half-migrated store.
|
|
52
|
+
|
|
53
|
+
- Adapter flag `service.never_timeout` is true.
|
|
54
|
+
- 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.
|
|
55
|
+
|
|
56
|
+
> Example — Thrum project: restart via `thrum daemon restart`, never wrapped in `timeout`; mac path via `scripts/mac-daemon-restart-via-cron.sh`.
|
|
57
|
+
|
|
58
|
+
## 5. Install from the delivered artifact (never rebuild on the node)
|
|
59
|
+
|
|
60
|
+
Install from the identical bundle the orchestrator built, delivered to `artifact.distribution.drop_path`.
|
|
61
|
+
|
|
62
|
+
- Verify BEFORE unpack that the delivered bundle's version/checksum/commit sidecar equals the orchestrator's pin (adapter `artifact.checksum`, `artifact.version_file`, `artifact.commit_file`).
|
|
63
|
+
- Run `install.command` (from adapter). The node does not compile, sign, or rebuild — it installs.
|
|
64
|
+
- Collect BEFORE readings (current version, state counters, checkpoint counts, health probes) before the install.
|
|
65
|
+
|
|
66
|
+
> Example — Thrum project: install from the adapter's `artifact.distribution.drop_path` via the adapter's `install.command`.
|
|
67
|
+
|
|
68
|
+
## 6. Measure from the running process, never the checkout
|
|
69
|
+
|
|
70
|
+
Read version/state from the running service, not from the filesystem checkout.
|
|
71
|
+
|
|
72
|
+
- Verify via `install.verify_by_effect` probes: version equals pin, NEW PID, service status reports pin, sidecar equals pin.
|
|
73
|
+
- Do not trust installer exit 0 alone.
|
|
74
|
+
|
|
75
|
+
## 7. Migrate via service restart — verify by effect
|
|
76
|
+
|
|
77
|
+
Migration is performed by restarting the service after install; the service's own boot migration does the schema/data move.
|
|
78
|
+
|
|
79
|
+
- Calibrate weight via `migration.weight_calibration` (heavy bulk-export vs light add-column) — do not assume a fixed duration.
|
|
80
|
+
- Known signatures that require a cold-restart recovery: `migration.sigbus_signatures` (e.g., WAL-index recover signatures) and `migration.on_sigbus`.
|
|
81
|
+
- Observe that the restarted service reports the new version/state and that health probes have converged (adapter `health.probes`, `health.convergence_wait`).
|
|
82
|
+
|
|
83
|
+
## 8. Verify post-migration (liveness, health probes, checkpoint counts, agent liveness)
|
|
84
|
+
|
|
85
|
+
Run adapter `health.probes` and compare BEFORE/AFTER:
|
|
86
|
+
|
|
87
|
+
- Service alive and reporting pin.
|
|
88
|
+
- State counters converged per `health.convergence_wait` (mechanism-derived, e.g., `3m`).
|
|
89
|
+
- Crash log empty, expected agents live.
|
|
90
|
+
|
|
91
|
+
For tandem daemons that share a host or depend on each other, verify the coordinated set per adapter.
|
|
92
|
+
|
|
93
|
+
## 8a. Re-render configuration/templates if the build changes them
|
|
94
|
+
|
|
95
|
+
If the build carries template or role changes, re-render between install and restart:
|
|
96
|
+
|
|
97
|
+
- Commands: `templates.refresh_command` and `templates.deploy_command`.
|
|
98
|
+
- Order: `templates.order` (`refresh→deploy` between `install.sh` and daemon restart).
|
|
99
|
+
- Verify by effect (render output, then service restart).
|
|
100
|
+
|
|
101
|
+
> Example — Thrum project: `thrum roles refresh` then `thrum roles deploy` between install and restart.
|
|
102
|
+
|
|
103
|
+
## 8b. Plugin/skill refresh if the deploy carries skill changes
|
|
104
|
+
|
|
105
|
+
If the bundle carries skill/plugin changes, refresh the plugin cache:
|
|
106
|
+
|
|
107
|
+
- Refresh driver: `plugin.refresh` (version bump required — cache keyed by version).
|
|
108
|
+
- Manifests: `plugin.manifests` (all skill-carrying manifests bumped in the same commit as the new skills).
|
|
109
|
+
|
|
110
|
+
Do not hand-edit generated marketplace manifests.
|
|
111
|
+
|
|
112
|
+
## 8c. Reconcile registry/phase after restart
|
|
113
|
+
|
|
114
|
+
Re-verify the daemon registry and agent phases after restart (adapter `health.probes` includes phase reconciliation). Confirm the pinned version is durable across a clean cold-boot probe where applicable.
|
|
115
|
+
|
|
116
|
+
## Red flags — STOP
|
|
117
|
+
|
|
118
|
+
- Pull not ff-only.
|
|
119
|
+
- Backup skipped or undersized.
|
|
120
|
+
- Storage accessed via forbidden path (`storage_access.forbidden`).
|
|
121
|
+
- Restart wrapped in a blind timeout or killed with `SIGQUIT`/`SIGUSR1` in a fatal window (`migration.signal_rules`).
|
|
122
|
+
- Install rebuilt locally instead of from the delivered artifact.
|
|
123
|
+
- Post-migration health not verified by observed effect.
|
|
124
|
+
- Template re-render skipped when the build changed templates (`templates.order` violated).
|
|
@@ -65,10 +65,7 @@ optimization.
|
|
|
65
65
|
|
|
66
66
|
## Subagent model selection
|
|
67
67
|
|
|
68
|
-
> **Model tiers:** pass an explicit `model:` on every dispatch
|
|
69
|
-
> (low effort) mechanical, `sonnet` (medium effort) judgment, Opus only on
|
|
70
|
-
> operator-ask or a skill step that names it. See the
|
|
71
|
-
> `choosing-subagent-models` skill for the full policy.
|
|
68
|
+
> **Model tiers:** pass an explicit `model:` on every dispatch; choose model and effort per the `choosing-subagent-models` skill (read `runtime.role_models` at the moment of use). Never let a sub-agent inherit your own model.
|
|
72
69
|
|
|
73
70
|
## Check the target's queue before you dispatch (R3)
|
|
74
71
|
|
|
@@ -162,13 +159,30 @@ re-dispatch overhead.
|
|
|
162
159
|
3. Acceptance criteria as bullets
|
|
163
160
|
4. The worktree path the work happens in
|
|
164
161
|
5. An explicit reminder to pass `model:` on any sub-agents the implementer
|
|
165
|
-
spawns (
|
|
162
|
+
spawns (model and effort per `choosing-subagent-models`)
|
|
166
163
|
6. Spec/plan paths to read before starting
|
|
167
164
|
7. **Adjacent candidate beads** from the adjacency pass above, labeled as
|
|
168
165
|
CANDIDATES with their validity explicitly unverified — plus the instruction to
|
|
169
166
|
check them against the merged-forward tip and either fold them in or return
|
|
170
167
|
them as completed
|
|
171
168
|
|
|
169
|
+
## Anti-pattern-removal epics must ship a ratchet lens
|
|
170
|
+
|
|
171
|
+
**Why:** during a prior owner-bypass remediation, judgment
|
|
172
|
+
review alone let 11 new instances of the exact anti-pattern being removed
|
|
173
|
+
land through the merge gate mid-sprint, because no mechanical check enforced
|
|
174
|
+
a monotonic budget across diffs.
|
|
175
|
+
|
|
176
|
+
**How to apply:** When dispatching an epic whose purpose is removing an
|
|
177
|
+
existing anti-pattern (not just fixing one instance of it), the acceptance
|
|
178
|
+
criteria MUST include a mechanical ratchet lens (see
|
|
179
|
+
`coordinator-hotpath-merge-gate` § "Invariant-ratchet lenses") wired into
|
|
180
|
+
`.thrum/hotpath-gate.json` as `always_run` before the epic is considered
|
|
181
|
+
closeable — not as a follow-up. A judgment-only acceptance ("reviewer
|
|
182
|
+
confirms the count went down") is insufficient; the count must be enforced
|
|
183
|
+
by a standing mechanical budget the gate itself checks on every subsequent
|
|
184
|
+
merge.
|
|
185
|
+
|
|
172
186
|
## Execution invariants — carry these in every implementation dispatch
|
|
173
187
|
|
|
174
188
|
**Why:** A plan is a snapshot; trunk moves and reality drifts from it. Sprints
|
|
@@ -208,17 +222,16 @@ with a different name — do not rename in place.
|
|
|
208
222
|
|
|
209
223
|
## Propagate model-selection discipline downward
|
|
210
224
|
|
|
211
|
-
**Why:** Sub-agents inherit the parent model by default. A coordinator
|
|
212
|
-
that spawns an unspecified sub-agent gets
|
|
213
|
-
|
|
225
|
+
**Why:** Sub-agents inherit the parent model by default. A coordinator whose own tier is
|
|
226
|
+
costly that spawns an unspecified sub-agent gets costly work for tasks that need
|
|
227
|
+
a cheap tier. The same trap repeats inside an implementer's worktree: if the
|
|
214
228
|
implementer doesn't propagate the discipline, their own sub-agents silently
|
|
215
229
|
inherit too. Cost compounds across a session.
|
|
216
230
|
|
|
217
231
|
**How to apply:** Every dispatch prompt should include the model-selection rule
|
|
218
232
|
explicitly: "When you spawn your own sub-agents, pass explicit `model:` —
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
only when justified. Default to sonnet over opus." Audit the dispatch prompt before sending.
|
|
233
|
+
choose model and effort per the `choosing-subagent-models` skill (read
|
|
234
|
+
`runtime.role_models` at the moment of use); never inherit your own model." Audit the dispatch prompt before sending.
|
|
222
235
|
|
|
223
236
|
## The impl-prompt review stamp satisfies pre-dispatch review
|
|
224
237
|
|
|
@@ -294,14 +307,13 @@ EOF
|
|
|
294
307
|
### Step 3: Your role during execution
|
|
295
308
|
|
|
296
309
|
- You receive the orchestrator's merge report when all epics complete.
|
|
297
|
-
- Run your merge-approval gate (see
|
|
310
|
+
- Run your merge-approval gate (see the merge approval rules in your preamble).
|
|
298
311
|
- Monitor the orchestrator's status updates; escalate to the operator only for
|
|
299
312
|
genuine judgment calls (architectural pivot, scope change, budget concern).
|
|
300
313
|
|
|
301
314
|
## Project-specific rules (already loaded)
|
|
302
315
|
|
|
303
|
-
|
|
304
|
-
`claude-plugin/commands/_project-rules-protocol.md`
|
|
316
|
+
Load the /thrum:project-rules-protocol skill and follow it.
|
|
305
317
|
|
|
306
318
|
If you accumulate a new rule mid-session (the user corrects you), capture it via
|
|
307
319
|
the `coordinator-maintaining-memory` skill — it references the
|
|
@@ -117,23 +117,37 @@ rediscovering these the hard way:
|
|
|
117
117
|
carrying dupes instead of the real content.
|
|
118
118
|
6. Run full-package `-race`, not targeted `-run` — a targeted race run misses
|
|
119
119
|
cross-test races.
|
|
120
|
-
7.
|
|
120
|
+
7. **`internal/daemon/rpc` must NEVER be run monolithically at gate time, in
|
|
121
|
+
either lane** — a bare package-level `go test [-race] ./internal/daemon/rpc`
|
|
122
|
+
starves and hits the configured `-timeout` wall in both the race and
|
|
123
|
+
non-race lane. The gate's OUTPUT must show the sharded runner actually
|
|
124
|
+
executed for RPC (`race-shard` / `package-shard --mode norace`, or
|
|
125
|
+
`scripts/test-run.sh race|norace ./internal/daemon/rpc`, or `make gate`
|
|
126
|
+
which shards both lanes automatically) — not just that some RPC test ran.
|
|
127
|
+
A bound-timeout with ZERO test failures is a FALSE RED, not a finding:
|
|
128
|
+
distinguish it from a genuine hang/deadlock via
|
|
129
|
+
`go run ./cmd/testgate classify-timeout --log <file> --shard-config <file>
|
|
130
|
+
--shard <name>` (fails closed — only BOUND-TIMEOUT exits 0; HANG and
|
|
131
|
+
UNCLASSIFIED both exit nonzero) before reporting it as a regression.
|
|
132
|
+
If a gate's own command line invokes the bare package path for RPC, that is a gate defect, not a passing lane.
|
|
133
|
+
A HANG or UNCLASSIFIED verdict from `classify-timeout` requires human review.
|
|
134
|
+
8. Build+test the MERGED-tree result as a SEPARATE condition — neither gate
|
|
121
135
|
currently runs a build of the actual post-merge tree; a clean pre-merge
|
|
122
136
|
build/test does not prove the merged result compiles or passes.
|
|
123
|
-
|
|
124
|
-
`--force` as the default (see item
|
|
137
|
+
9. Use `rm -r`, NEVER `rm -rf`; use plain `git worktree remove` to drop a worktree, never
|
|
138
|
+
`--force` as the default (see item 13 below). A broad `ask` rule on `rm -rf *` outranks any narrow `/tmp` allow,
|
|
125
139
|
so `rm -rf` raises a human permission prompt EVERY time regardless of path —
|
|
126
140
|
it stalls gate sub-agents mid-run waiting on a keystroke. `rm -r` runs free. Do NOT widen the ask rule
|
|
127
141
|
to work around this; that entry is the only deletion protection on the box.
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
142
|
+
10. Check the discriminator before picking a scratch path, don't assume from
|
|
143
|
+
the platform: `[ -L /tmp ]`. macOS (symlink) — create throwaway worktrees
|
|
144
|
+
under `/private/tmp`; a worktree under `/tmp` false-FAILs worktree-ancestor
|
|
145
|
+
tests via the symlink, producing a confident wrong gate result. Linux (real
|
|
146
|
+
dir) — `/tmp` is correct; `/private/tmp` may not exist there and must not
|
|
147
|
+
be created.
|
|
148
|
+
11. Your report reaches the coordinator ONLY as your final returned text.
|
|
135
149
|
Side-channel output is discarded. Put the whole verdict in the return value.
|
|
136
|
-
|
|
150
|
+
12. **NEVER run `git stash`, `git checkout`, `git reset`, or any working-tree
|
|
137
151
|
mutation in the SHARED repo.** Do read-only inspection there (`git show
|
|
138
152
|
<sha>:<path>`, `git log`, `git diff`) and do every build/test in a throwaway
|
|
139
153
|
detached worktree. `git stash` is a SINGLE SHARED STACK across every
|
|
@@ -142,12 +156,12 @@ rediscovering these the hard way:
|
|
|
142
156
|
hold uncommitted `State.md` they are actively re-authoring.
|
|
143
157
|
If you believe you must mutate the shared tree, STOP and report instead —
|
|
144
158
|
that is always a finding, never a step.
|
|
145
|
-
|
|
159
|
+
13. **TEAR DOWN YOUR THROWAWAY WORKTREE WHEN THE GATE ENDS — after two checks,
|
|
146
160
|
in this order.** A required final step, not cleanup etiquette. Each
|
|
147
161
|
abandoned worktree pins its HEAD commit against `gc` and adds a
|
|
148
162
|
`.git/worktrees` admin entry, so the object store grows monotonically.
|
|
149
163
|
Before removing:
|
|
150
|
-
(a) `git -C <wt> status --porcelain` — if NON-EMPTY, **STOP and report it
|
|
164
|
+
(a) `git -C <wt> status --porcelain --untracked-files=all --ignored -- .thrum` — if NON-EMPTY, **STOP and report it
|
|
151
165
|
instead of removing.** Uncommitted work in a throwaway worktree exists
|
|
152
166
|
NOWHERE else; this is the category that actually loses work.
|
|
153
167
|
(b) `git branch -a --contains $(git -C <wt> rev-parse HEAD)` — if EMPTY,
|
|
@@ -155,7 +169,7 @@ rediscovering these the hard way:
|
|
|
155
169
|
it. Usually fine (a gate merge is reproducible by redoing it) but say so
|
|
156
170
|
in your report rather than doing it silently.
|
|
157
171
|
Then `git worktree remove <wt>` — **plain, no `--force`.** Its rc=128 refusal backstops
|
|
158
|
-
ONLY untracked/modified content (see rule
|
|
172
|
+
ONLY untracked/modified content (see rule 9 on `rm -r`) — it does NOT cover gitignored
|
|
159
173
|
content, which git removes silently with no refusal; a clean rc=0 is not proof nothing of
|
|
160
174
|
value was in there (see coordinator-assessing-agent-completion's reap procedure). `--force`
|
|
161
175
|
is a justified override only, never the default (see coordinator-merging-code §7a).
|
|
@@ -169,6 +183,21 @@ config entry (see `lens_scope_semantics` in the config), which still runs on
|
|
|
169
183
|
every diff regardless of trigger directories. If the config has no
|
|
170
184
|
`trigger_directories`, fail with guidance to run `project-hotpath-gate`.
|
|
171
185
|
|
|
186
|
+
## Invariant-ratchet lenses
|
|
187
|
+
|
|
188
|
+
A lens may declare `mandatory_test_command` (see `census_classification_coverage`
|
|
189
|
+
and `write_owner_bypass_ratchet` in `.thrum/hotpath-gate.json`) instead of
|
|
190
|
+
(or alongside) a pattern-match `question`/`required_evidence` pair. When
|
|
191
|
+
present, PASS/FAIL is the command's own exit code — never a judgment call
|
|
192
|
+
from reading the diff. This is the shape for any invariant that already has
|
|
193
|
+
a mechanical detector: wire the detector as an `always_run` lens with a
|
|
194
|
+
monotonic budget (a count that may only decrease, or an explicit
|
|
195
|
+
waiver-tagged exception), so a diff cannot silently re-widen the invariant
|
|
196
|
+
in the same change that appears to narrow it. `write_owner_bypass_ratchet`
|
|
197
|
+
is the reference instance: it fails a merge that bumps a
|
|
198
|
+
ceiling/aggregate in the ledger file without a `RATCHET-WAIVER:` tag, even
|
|
199
|
+
when the ledger-equality test alone would pass.
|
|
200
|
+
|
|
172
201
|
## Delta re-gate continuity — walk the whole branch, read the whole function
|
|
173
202
|
|
|
174
203
|
**Why:** A commit introducing a lock can be an ancestor of a delta-re-gate's
|
|
@@ -432,7 +461,7 @@ hoc test target nothing routes to. A merge that adds a `state.NewState(...)`
|
|
|
432
461
|
call site in an `internal/daemon/rpc/*_test.go` file (test-fixture setup, not a
|
|
433
462
|
handler) can leave it unclassified and desync the frozen census snapshot with
|
|
434
463
|
no gate catching it — trunk went RED post-merge on 573mo v87 for exactly this
|
|
435
|
-
reason
|
|
464
|
+
reason.
|
|
436
465
|
|
|
437
466
|
**Relationship to Lenses 1–10:** every other lens in this file is an
|
|
438
467
|
LLM-judgment pattern check — grep a pattern, read the surrounding code, apply
|
|
@@ -476,7 +505,7 @@ diff on `TestCensusRegeneration`'s brittleness with zero added
|
|
|
476
505
|
defect-prevention (`ClassificationCoverage` alone already catches the defect
|
|
477
506
|
this lens exists for). `TestCensusRegeneration`'s own staleness is tracked
|
|
478
507
|
separately (nd2j1/P1 owns the classification data; the brittle count-snapshot
|
|
479
|
-
assertion itself is
|
|
508
|
+
assertion itself is a distinct open question — "make advisory or drop the
|
|
480
509
|
raw-count assertion"), not by this lens.
|
|
481
510
|
|
|
482
511
|
**Severity:** Trigger fires and `mandatory_test_command` was not run before
|
|
@@ -520,10 +549,24 @@ otherwise leave them.
|
|
|
520
549
|
|
|
521
550
|
## If it fails
|
|
522
551
|
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
552
|
+
For a genuine hot-path/perf defect, a production-behaviour change, or a design
|
|
553
|
+
judgment call: send it back as a normal review finding — same channel as
|
|
554
|
+
dual-review output, folded into the same numbered list if dual review is still
|
|
555
|
+
open, or as its own short reply if dual review already passed. Cite the
|
|
556
|
+
offending function/file, which lens it failed, and the config value that
|
|
557
|
+
triggered the finding.
|
|
558
|
+
|
|
559
|
+
For mechanical bookkeeping only (census/shard regen via the tool, line-number
|
|
560
|
+
or key refreshes, ledger totals/ceilings where the arithmetic is derivable, a
|
|
561
|
+
per-entry waiver or citation comment recording a classification already
|
|
562
|
+
established elsewhere (never a new safety judgment of your own), a nosec
|
|
563
|
+
baseline hash for an already-reviewed pattern, comment wording, stale test
|
|
564
|
+
expectations that merely follow a landed change): fix it yourself as a
|
|
565
|
+
`GATE-AUTHORED` commit on your
|
|
566
|
+
`gate/` branch, re-run ONLY the lens(es) the fix affects, and report
|
|
567
|
+
`CLEAN-WITH-GATE-FIXES` listing each fix instead of bouncing it to the owner.
|
|
568
|
+
When unsure which bucket a finding falls in, ask the coordinator with the exact
|
|
569
|
+
diff — don't bounce reflexively.
|
|
527
570
|
|
|
528
571
|
## Efficacy tracking (v1 acceptance requirement)
|
|
529
572
|
|
|
@@ -563,6 +606,7 @@ rows.
|
|
|
563
606
|
| `FALSE_POSITIVE` | Gate flagged something correct — record which lens and why |
|
|
564
607
|
| `SLIPPED` | A wedge occurred AFTER merge that the gate did not catch |
|
|
565
608
|
| `SKIPPED_WITH_EVIDENCE` | Gate deliberately skipped (no trigger dirs), evidence cited |
|
|
609
|
+
| `CLEAN-WITH-GATE-FIXES` | Gate found only mechanical bookkeeping gaps, fixed them itself as a GATE-AUTHORED commit, re-ran only the affected checks, merge proceeded |
|
|
566
610
|
|
|
567
611
|
**Retrospective reclassification:** When triaging a new wedge or incident, grep
|
|
568
612
|
`dev-docs/hotpath-gate-efficacy.md` for the merged branch/date. If the gate
|
|
@@ -591,4 +635,4 @@ gaps and lens improvements for the next version.
|
|
|
591
635
|
first gate run, appended after each run)
|
|
592
636
|
|
|
593
637
|
<!-- THRUM-GATE: stage=skill next=review -->
|
|
594
|
-
<!-- THRUM-REVIEW: stage=skill verdict=Ready:Yes cycle=2
|
|
638
|
+
<!-- THRUM-REVIEW: stage=skill verdict=Ready:Yes cycle=2 -->
|
|
@@ -162,8 +162,7 @@ bd update thrum-abc --notes "$notes"
|
|
|
162
162
|
|
|
163
163
|
## Project-specific rules (already loaded)
|
|
164
164
|
|
|
165
|
-
|
|
166
|
-
`claude-plugin/commands/_project-rules-protocol.md`
|
|
165
|
+
Load the /thrum:project-rules-protocol skill and follow it.
|
|
167
166
|
|
|
168
167
|
If you accumulate a new rule mid-session (the user corrects you), capture it
|
|
169
168
|
via the `coordinator-maintaining-memory` skill — it references the
|
|
@@ -40,7 +40,7 @@ thrum memory create --kind agent_rule --scope role \
|
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
`--short`/`--full` carry real prose — compose via heredoc or file, never
|
|
43
|
-
double-quoted inline; see
|
|
43
|
+
double-quoted inline; see the heredoc-or-file rule in your role preamble.
|
|
44
44
|
|
|
45
45
|
Body shape uniform across all role-rule writes — see `memory-write-discipline`.
|
|
46
46
|
|
|
@@ -57,8 +57,11 @@ created from origin, unpushed commits can be lost or inaccessible.
|
|
|
57
57
|
|
|
58
58
|
**How to apply:** Session close protocol — push the coordination branch every
|
|
59
59
|
session end. **Read the branch name, never recall it:**
|
|
60
|
-
`
|
|
61
|
-
|
|
60
|
+
`CONFIG=.thrum/config.json; [ -f .thrum/redirect ] && CONFIG="$(cat .thrum/redirect)/config.json"; jq -r '.orchestration.merge_target' "$CONFIG"`
|
|
61
|
+
(a worktree's `.thrum/` holds only a `redirect` file pointing at the main
|
|
62
|
+
repo's `.thrum` dir, so reading `.thrum/config.json` directly there returns
|
|
63
|
+
empty) — or your project's CLAUDE.md § Branching Strategy. Push every
|
|
64
|
+
`feature/*` and `fix/*` branch too.
|
|
62
65
|
A docs/site branch pushes only when the site is ready to deploy; `main` and
|
|
63
66
|
`release/*` go through the release flow.
|
|
64
67
|
|
|
@@ -77,10 +80,7 @@ batch — the visual tree exposes inversion immediately. For bulk epic creation
|
|
|
77
80
|
(many tasks at once), spawn parallel sub-agents to issue the `bd create` calls;
|
|
78
81
|
bd is fully concurrent-safe.
|
|
79
82
|
|
|
80
|
-
> **Model tiers:** pass an explicit `model:` on every dispatch
|
|
81
|
-
> (low effort) mechanical, `sonnet` (medium effort) judgment, Opus only on
|
|
82
|
-
> operator-ask or a skill step that names it. See the
|
|
83
|
-
> `choosing-subagent-models` skill for the full policy.
|
|
83
|
+
> **Model tiers:** pass an explicit `model:` on every dispatch; choose model and effort per the `choosing-subagent-models` skill (read `runtime.role_models` at the moment of use). Never let a sub-agent inherit your own model.
|
|
84
84
|
|
|
85
85
|
## Use `bd close --suggest-next` to surface unblocked work
|
|
86
86
|
|
|
@@ -184,8 +184,7 @@ orchestrators to for the implementers **they** launched.
|
|
|
184
184
|
|
|
185
185
|
## Project-specific rules (already loaded)
|
|
186
186
|
|
|
187
|
-
|
|
188
|
-
`claude-plugin/commands/_project-rules-protocol.md`
|
|
187
|
+
Load the /thrum:project-rules-protocol skill and follow it.
|
|
189
188
|
|
|
190
189
|
If you accumulate a new rule mid-session (the user corrects you), capture it via
|
|
191
190
|
the `coordinator-maintaining-memory` skill — it references the
|