opencode-thrum-pro 0.1.6 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/commands/thrum-compact-extended.md +36 -21
- package/assets/commands/thrum-compact.md +19 -18
- package/assets/commands/thrum-restart-extended.md +1 -5
- package/assets/commands/thrum-restart.md +2 -2
- package/assets/commands/thrum-sleep-extended.md +1 -5
- package/assets/commands/thrum-sleep.md +1 -5
- package/assets/commands/thrum-update-project.md +1 -1
- package/assets/skills/brainstorm-queue-aware/SKILL.md +1 -1
- package/assets/skills/brainstorm-steward/SKILL.md +3 -3
- package/assets/skills/choosing-subagent-models/SKILL.md +183 -74
- package/assets/skills/closing-findings-while-warm/SKILL.md +1 -2
- package/assets/skills/configure-roles/SKILL.md +2 -2
- package/assets/skills/coordinator-assessing-agent-completion/SKILL.md +11 -10
- package/assets/skills/coordinator-branch-split-on-block/SKILL.md +1 -2
- package/assets/skills/coordinator-context-monitoring/SKILL.md +11 -12
- package/assets/skills/coordinator-deploying-a-node/SKILL.md +3 -1
- package/assets/skills/coordinator-dispatching-work/SKILL.md +5 -4
- package/assets/skills/coordinator-hotpath-merge-gate/SKILL.md +9 -7
- package/assets/skills/coordinator-interacting-with-the-owner/SKILL.md +1 -2
- package/assets/skills/coordinator-maintaining-memory/SKILL.md +1 -1
- package/assets/skills/coordinator-managing-state-and-lifecycle/SKILL.md +10 -3
- package/assets/skills/coordinator-merging-code/SKILL.md +21 -14
- package/assets/skills/coordinator-philosophy-merge-gate/SKILL.md +4 -5
- package/assets/skills/coordinator-plan-reconcile-gate/SKILL.md +1 -2
- package/assets/skills/coordinator-rolling-out-to-nodes/SKILL.md +1 -0
- package/assets/skills/coordinator-running-brainstorm-cycles/SKILL.md +4 -5
- package/assets/skills/coordinator-running-review-cycles/SKILL.md +1 -2
- package/assets/{commands/thrum-_deviations-protocol.md → skills/deviations-protocol/SKILL.md} +6 -12
- package/assets/skills/efficient-multi-agent-research/SKILL.md +2 -2
- package/assets/skills/generator-idempotency-protocol/SKILL.md +9 -0
- package/assets/skills/implementer-maintaining-memory/SKILL.md +3 -4
- package/assets/skills/implementer-orchestrating-execution/SKILL.md +1 -2
- package/assets/skills/implementer-receiving-dispatch/SKILL.md +15 -17
- package/assets/skills/implementer-receiving-review-feedback/SKILL.md +3 -4
- package/assets/skills/implementer-status-and-handoff/SKILL.md +1 -14
- package/assets/skills/implementer-tdd-and-quality/SKILL.md +2 -2
- package/assets/skills/memory-audit-recover/SKILL.md +7 -5
- package/assets/skills/memory-curate/SKILL.md +3 -3
- package/assets/skills/memory-maintenance/SKILL.md +2 -0
- package/assets/skills/memory-write-discipline/SKILL.md +1 -1
- package/assets/skills/orchestrate/SKILL.md +34 -5
- package/assets/skills/persistent-watcher-archetype/SKILL.md +2 -2
- package/assets/skills/persistent-watcher-archetype/resources/jev_watcher_filter.py +5 -5
- package/assets/skills/persistent-watcher-archetype/resources/roster-watch.sh +5 -5
- package/assets/skills/persistent-watcher-archetype/resources/roster-watch_test.sh +2 -2
- package/assets/skills/persistent-watcher-archetype/resources/thrum-capture-fallback.sh +1 -1
- package/assets/skills/persistent-watcher-archetype/resources/thrum-watch-pane-capture.sh +3 -3
- package/assets/skills/prime-agent/SKILL.md +1 -1
- package/assets/skills/project-hotpath-gate/SKILL.md +1 -2
- package/assets/skills/project-philosophy/SKILL.md +2 -3
- package/assets/skills/project-rules-protocol/SKILL.md +12 -0
- package/assets/skills/project-setup/SKILL.md +9 -10
- package/assets/skills/project-setup/resources/implementation-agent.md +1 -2
- package/assets/skills/researcher-answering-queries/SKILL.md +1 -2
- package/assets/skills/researcher-investigating/SKILL.md +6 -8
- package/assets/skills/researcher-maintaining-memory/SKILL.md +3 -1
- package/assets/{commands/thrum-_snapshot-protocol.md → skills/snapshot-protocol/SKILL.md} +10 -15
- package/assets/{commands/thrum-_stamp-protocol.md → skills/stamp-protocol/SKILL.md} +5 -6
- package/assets/skills/thrum/SKILL.md +9 -4
- package/assets/skills/thrum/resources/CLI_REFERENCE.md +32 -27
- package/assets/skills/thrum-memory/SKILL.md +1 -1
- package/assets/skills/using-monitors/SKILL.md +198 -0
- package/assets/skills/using-the-queue/SKILL.md +2 -3
- package/assets/skills/using-thrum-state/SKILL.md +3 -3
- package/assets/skills/verify-against-plan/SKILL.md +2 -2
- package/dist/hooks/block-sync-cd.js +1 -1
- package/dist/hooks/block-sync-cd.test.js +1 -1
- package/dist/installer-assets.test.d.ts +1 -0
- package/dist/installer-assets.test.js +41 -0
- package/package.json +1 -1
- package/assets/commands/thrum-_compact-runtime-commands.md +0 -61
- package/assets/commands/thrum-_generator-idempotency-protocol.md +0 -15
- package/assets/commands/thrum-_project-rules-protocol.md +0 -18
- package/assets/commands/thrum-_verify-before-write-protocol.md +0 -27
|
@@ -189,8 +189,10 @@ thrum worktree create <name>
|
|
|
189
189
|
thrum tmux create <name> --cwd <worktree-path> \
|
|
190
190
|
--name <agent_name> --role implementer --module <module> \
|
|
191
191
|
--mode ephemeral --identity ephemeral \
|
|
192
|
-
--model <from runtime.role_models, per choosing-subagent-models>
|
|
193
|
-
|
|
192
|
+
--model <from runtime.role_models, per choosing-subagent-models> \
|
|
193
|
+
--effort <from runtime.role_models, per choosing-subagent-models>
|
|
194
|
+
thrum tmux launch <name> --runtime <runtime> --model <from runtime.role_models, per choosing-subagent-models> \
|
|
195
|
+
--effort <from runtime.role_models, per choosing-subagent-models>
|
|
194
196
|
```
|
|
195
197
|
|
|
196
198
|
> **Implementer lifecycle:** All implementers are ephemeral+stateless (no agent
|
|
@@ -233,7 +235,7 @@ That prints the runtime's own footer line, e.g. `Model: <resolved model>`. **Rea
|
|
|
233
235
|
intended tier from `.thrum/config.json` → `runtime.role_models`, not from memory.**
|
|
234
236
|
If the footer shows a different tier (see the BLOCKED note under Step 2 — the model ban
|
|
235
237
|
list lives in `choosing-subagent-models`), the pin failed silently — re-pin with
|
|
236
|
-
`thrum tmux create ... --model <from runtime.role_models, per choosing-subagent-models>` (or
|
|
238
|
+
`thrum tmux create ... --model <from runtime.role_models, per choosing-subagent-models> --effort <from runtime.role_models, per choosing-subagent-models>` (or
|
|
237
239
|
`thrum agent runtime-config set <agent_name> --model <from runtime.role_models, per choosing-subagent-models>`) and relaunch BEFORE
|
|
238
240
|
assigning work. **Do not dispatch an unpinned implementer** — the daemon's
|
|
239
241
|
role-default backstop (`jq -r '.runtime.role_models' .thrum/config.json`) is a
|
|
@@ -504,7 +506,7 @@ done
|
|
|
504
506
|
|
|
505
507
|
**C. If conflicts arise:**
|
|
506
508
|
Reading the conflicted files directly is permitted (merge-conflict carve-out
|
|
507
|
-
in Scope
|
|
509
|
+
in the Scope section of your preamble). Analyze the conflict using your plan/intent context to
|
|
508
510
|
determine the correct resolution. Then spawn a targeted edit sub-agent:
|
|
509
511
|
|
|
510
512
|
```text
|
|
@@ -651,7 +653,7 @@ thrum worktree teardown <name>
|
|
|
651
653
|
```
|
|
652
654
|
|
|
653
655
|
> After set-phase=retired, `thrum team` and the active UI views no longer show
|
|
654
|
-
> this agent (sidebar, pickers, badge, kbd-nav). It remains in the Retired tab.
|
|
656
|
+
> this agent (sidebar, pickers, badge, kbd-nav). It remains in the Retired tab (teardown retires, it does not delete the row).
|
|
655
657
|
> Its messages + runtime transcript persist for audit. `thrum agent delete` is
|
|
656
658
|
> operator-only (gated to the coordinator) and is NOT an orchestrator tool —
|
|
657
659
|
> `set-phase retired` is the orchestrator's retirement command for both normal
|
|
@@ -805,3 +807,30 @@ EOF
|
|
|
805
807
|
```
|
|
806
808
|
|
|
807
809
|
Do not proceed without approval when autonomy is `per_epic`.
|
|
810
|
+
|
|
811
|
+
### Tier-swap: replace an underperforming implementer in the same worktree
|
|
812
|
+
|
|
813
|
+
Use when the first review shows multiple BLOCKING findings, systematic misunderstanding of the task, or an agent clearly going long. The swap reuses the SAME worktree: retire the underperforming agent and relaunch a fresh one under a NEW name in place. Never `thrum agent delete` (operator-only, gated to the coordinator; orchestrators are refused). The swapped-out agent is retired with `set-phase retired`; its registry row, messages and transcript are retained.
|
|
814
|
+
|
|
815
|
+
Step 1: kill the old agent's tmux session first, so its pid is dead. A live-pid identity file is preserved and not quarantined; a dead pid lets the new create quarantine it.
|
|
816
|
+
thrum tmux kill <same_worktree_name>
|
|
817
|
+
Step 2: retire the old agent. It keeps the registry row (Retired tab). `set-phase` is not operator-gated. Retiring does not free the identity; Step 4's create does.
|
|
818
|
+
thrum agent set-phase retired --agent <underperforming_agent_name>
|
|
819
|
+
Step 3: verify the worktree is intact (WIP code preserved).
|
|
820
|
+
ls <worktree-path>
|
|
821
|
+
Step 4: launch a fresh ephemeral identity under a NEW name in the SAME worktree, pinned on both create and launch from `runtime.role_models` (per `choosing-subagent-models`). `--intent` carries the orient-from-WIP one-liner.
|
|
822
|
+
thrum tmux create <same_worktree_name> --cwd <worktree-path> --name <new_agent_name> --role implementer --module <module> --mode ephemeral --identity ephemeral --model <per runtime.role_models> --effort <per runtime.role_models> --intent "tier-swap: orient in the worktree (WIP + first-review findings) and continue"
|
|
823
|
+
thrum tmux launch <same_worktree_name> --runtime claude --model <per runtime.role_models> --effort <per runtime.role_models>
|
|
824
|
+
Step 5: deliver the WIP pointer and first-review findings (a cold handoff: the code plus the findings).
|
|
825
|
+
thrum send --to @<new_agent_name> --stdin <<'EOF'
|
|
826
|
+
Tier-swap pickup: <WIP summary + first-review findings>
|
|
827
|
+
EOF
|
|
828
|
+
|
|
829
|
+
The pickup prompt (Step 5) must include:
|
|
830
|
+
You are picking up in-progress work from a prior agent that was replaced.
|
|
831
|
+
Context:
|
|
832
|
+
- Worktree: <path> — contains partial implementation, review it with git diff
|
|
833
|
+
- Task: <epic-id> / <task description>
|
|
834
|
+
- First-review findings from the prior pass:
|
|
835
|
+
<paste the consolidated finding list here>
|
|
836
|
+
- Your goal: address all BLOCKING findings + complete the remaining task scope.
|
|
@@ -131,7 +131,7 @@ The procedure, every time, no shortcuts:
|
|
|
131
131
|
another peer's panes read-only regardless of capability.
|
|
132
132
|
|
|
133
133
|
**Worked example** — the standard two-variant Claude Code tool-confirmation
|
|
134
|
-
modal (
|
|
134
|
+
modal (the daemon's permission patterns, pattern `tool_confirmation`,
|
|
135
135
|
dialect `claude-tui`), captured verbatim:
|
|
136
136
|
|
|
137
137
|
```
|
|
@@ -149,7 +149,7 @@ dialect `claude-tui`), captured verbatim:
|
|
|
149
149
|
allow-rule beyond this one command; the modal judgment rubric above is a
|
|
150
150
|
per-command judgment, not a license to mint blanket permissions. This is
|
|
151
151
|
pinned by `ApproveKey: "1", // Yes (once) — NEVER "2"` in
|
|
152
|
-
|
|
152
|
+
the daemon's permission patterns and tested by
|
|
153
153
|
`TestApproveKeyNeverForeverAllow`.
|
|
154
154
|
|
|
155
155
|
## Your own restart (auto-restart-at-ctx-threshold)
|
|
@@ -45,8 +45,8 @@ NOTIFY_CLASSES = VALID_CLASSES - {"ordinary"}
|
|
|
45
45
|
REDACTION_TOKEN = "[REDACTED_SECRET]"
|
|
46
46
|
LOCAL_PATH_REDACTION_TOKEN = "[REDACTED_LOCAL_PATH]"
|
|
47
47
|
SECRET_PATTERNS: tuple[tuple[str, re.Pattern[str]], ...] = (
|
|
48
|
-
("private_key_block", re.compile(r"-----BEGIN [
|
|
49
|
-
("env_secret_assignment", re.compile(r"(?im)^\s*(?:export\s+)?[
|
|
48
|
+
("private_key_block", re.compile(r"-----BEGIN [0-9A-Z ]*PRIVATE KEY-----.*?-----END [0-9A-Z ]*PRIVATE KEY-----", re.S)),
|
|
49
|
+
("env_secret_assignment", re.compile(r"(?im)^\s*(?:export\s+)?[0-9A-Z_]*(?:API[_-]?KEY|TOKEN|SECRET|PASSWORD|PRIVATE[_-]?KEY|AUTH[_-]?KEY)[0-9A-Z_]*\s*=\s*([^\s#]+)")),
|
|
50
50
|
("bearer_token", re.compile(r"(?i)\bBearer\s+[A-Za-z0-9._~+/=-]{16,}")),
|
|
51
51
|
("openai_key", re.compile(r"\bsk-[A-Za-z0-9_-]{20,}\b")),
|
|
52
52
|
("thrum_key", re.compile(r"\btskey-[A-Za-z0-9_-]{16,}\b")),
|
|
@@ -318,7 +318,7 @@ def prompt_payload(state: dict[str, Any], provider: str = TYPESAFE_PROVIDER) ->
|
|
|
318
318
|
},
|
|
319
319
|
}
|
|
320
320
|
if provider == OPENROUTER_PROVIDER:
|
|
321
|
-
payload["user"] = "
|
|
321
|
+
payload["user"] = "roster-watch-filter"
|
|
322
322
|
return payload
|
|
323
323
|
|
|
324
324
|
|
|
@@ -462,8 +462,8 @@ def classify_remote(state: dict[str, Any], provider: str, api_key: str, timeout:
|
|
|
462
462
|
}
|
|
463
463
|
if provider == OPENROUTER_PROVIDER:
|
|
464
464
|
headers.update({
|
|
465
|
-
"HTTP-Referer": "https://github.com/
|
|
466
|
-
"X-Title": "
|
|
465
|
+
"HTTP-Referer": "https://github.com/leonletto/thrum-pro.git",
|
|
466
|
+
"X-Title": "roster-watch-filter",
|
|
467
467
|
})
|
|
468
468
|
last_error = None
|
|
469
469
|
last_category = None
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
# GHOST-TIP DETECTION: Claude Code's TUI renders an unaccepted inline
|
|
33
33
|
# autocomplete suggestion in the input box using the literal SGR
|
|
34
34
|
# "dim/faint" escape code (ESC[2m ... ESC[0m) — confirmed by direct byte
|
|
35
|
-
# inspection (
|
|
35
|
+
# inspection (a reconciler agent's "Stop the sweep loop
|
|
36
36
|
# for now" tip). Real typed/submitted text never carries that code. `thrum
|
|
37
37
|
# tmux capture` returns plain text with all styling stripped, so a script
|
|
38
38
|
# parsing ONLY that output cannot tell a live ghost-tip apart from real
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
#
|
|
51
51
|
# REDIRECT FIX (the actual bug this reconciliation targets):
|
|
52
52
|
# `watch_params.json` lives under the SHARED, redirect-resolved `agents/`
|
|
53
|
-
# tree (
|
|
53
|
+
# tree (the AgentDir path helper: "the agents/ tree is shared,
|
|
54
54
|
# not per-worktree"), not under this script's own worktree. Both source
|
|
55
55
|
# scripts read it as if it were always reachable via a hardcoded/relative
|
|
56
56
|
# main-repo path (`cd /Users/you/dev/thrum` +
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
# feature worktree. `resolve_watch_params()` below replaces that implicit
|
|
61
61
|
# assumption with the same explicit `.thrum/redirect`-following idiom
|
|
62
62
|
# already used by `scripts/heartbeat-lib.sh:225-232` and
|
|
63
|
-
#
|
|
63
|
+
# the check-inbox hook script.
|
|
64
64
|
#
|
|
65
65
|
# PORTABILITY FIX: both source scripts also hardcoded a single operator's
|
|
66
66
|
# absolute paths (`cd /Users/you/dev/thrum`,
|
|
@@ -105,7 +105,7 @@ set -uo pipefail
|
|
|
105
105
|
# ---------------------------------------------------------------------------
|
|
106
106
|
# Args: worktree_root. Prints the redirect-resolved absolute .thrum/ dir.
|
|
107
107
|
# Matches the idiom already used by scripts/heartbeat-lib.sh's
|
|
108
|
-
# hb_sessions_dir() and
|
|
108
|
+
# hb_sessions_dir() 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/.
|
|
@@ -648,7 +648,7 @@ except: print(0)
|
|
|
648
648
|
# entry resolves to a real agent_id via `thrum team --offline --json`, and
|
|
649
649
|
# log ROSTER-CHECK OK/FAIL. Cheap and valuable regardless of execution
|
|
650
650
|
# model (catches the exact "bare `<box>`-as-hostname" class of stale-
|
|
651
|
-
# roster-entry bug watcher-primary hit
|
|
651
|
+
# roster-entry bug watcher-primary hit). Runs AFTER
|
|
652
652
|
# the dynamic roster is loaded from watch_params.json, not against a
|
|
653
653
|
# hardcoded array.
|
|
654
654
|
# ---------------------------------------------------------------------------
|
|
@@ -69,8 +69,8 @@ AGENT="watcher_primary"
|
|
|
69
69
|
# Scenario 1 (MANDATORY, cmain-required regression guard): a worktree that
|
|
70
70
|
# redirects to a main-repo tree. The "roster-editing agent's Edit-tool write"
|
|
71
71
|
# lands in the REDIRECT TARGET (main-repo) copy -- that's the physically
|
|
72
|
-
# correct, shared, redirect-resolved location per
|
|
73
|
-
#
|
|
72
|
+
# correct, shared, redirect-resolved location per the AgentDir path helper
|
|
73
|
+
# ("the agents/ tree is shared, not per-worktree"), and it's what
|
|
74
74
|
# resolve_watch_params must read. A worktree-LOCAL copy at the naive,
|
|
75
75
|
# unresolved path is a decoy: it's what a broken script (SCRIPT_DIR-relative,
|
|
76
76
|
# no redirect-follow) would read instead, and it must be ignored.
|
|
@@ -94,7 +94,7 @@ run_ssh() {
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
# ssh-add retry: if the SSH hop itself fails at the connection layer (not a
|
|
97
|
-
#
|
|
97
|
+
# CLI-level error), the caller's identities may need re-adding to the
|
|
98
98
|
# keychain-backed ssh-agent. No default keys ship here -- this is a
|
|
99
99
|
# generic plugin script, and baking in one operator's specific key
|
|
100
100
|
# filenames would be wrong for every other fleet/operator that copies it.
|
|
@@ -74,7 +74,7 @@ AGENT_NAME="$(basename -- "${SCRIPT_DIR}")"
|
|
|
74
74
|
REPO_ROOT="$(cd -- "${SCRIPT_DIR}/../../.." >/dev/null 2>&1 && pwd)"
|
|
75
75
|
# Resolve watch_params.json through .thrum/redirect. The
|
|
76
76
|
# agents/ tree is the SHARED, redirect-resolved (main-repo) tree, not
|
|
77
|
-
# per-worktree (see
|
|
77
|
+
# per-worktree (see the AgentDir path helper) -- reading it
|
|
78
78
|
# straight off SCRIPT_DIR (this copy's own worktree-local location) reads
|
|
79
79
|
# the wrong, stale file whenever this script is deployed into a feature
|
|
80
80
|
# worktree that redirects: a roster-editing agent's Edit-tool write lands
|
|
@@ -185,7 +185,7 @@ log "roster: ${ROSTER[*]}"
|
|
|
185
185
|
#
|
|
186
186
|
# NOTE ON THE TWO-STEP TOPOLOGY LOOKUP: `thrum state list --kind topology
|
|
187
187
|
# --json`'s CLI output does NOT include each entry's `.value` (verified
|
|
188
|
-
# against
|
|
188
|
+
# against the CLI's stateListEntry struct, which has no Value
|
|
189
189
|
# field, and confirmed live -- `state list --json` returns only
|
|
190
190
|
# kind/scope/method/as_of/established_by). Only `state get`/`state show`
|
|
191
191
|
# emit the full entry including `.value`. So topology resolution is
|
|
@@ -338,7 +338,7 @@ for agent in "${ROSTER[@]}"; do
|
|
|
338
338
|
STATUS="clean"
|
|
339
339
|
MATCH_NAME=""
|
|
340
340
|
|
|
341
|
-
# thrum detect exit-code contract
|
|
341
|
+
# thrum detect exit-code contract:
|
|
342
342
|
# exit 0 + matched entry name on stdout -> match
|
|
343
343
|
# exit 1, silent -> no match
|
|
344
344
|
# `if VAR=$(...); then` is exempt from `set -e` semantics for this
|
|
@@ -88,7 +88,7 @@ context on a healthy daemon — no turn spent reading a file or running a skill.
|
|
|
88
88
|
This skill is the correct choice here only as a **fallback**, when that
|
|
89
89
|
auto-injection didn't fire or failed (e.g. the hook's "auto-injection failed"
|
|
90
90
|
notice, daemon unreachable). In that fallback case: read the snapshot first,
|
|
91
|
-
then run this skill. See
|
|
91
|
+
then run this skill. See `/thrum:compact`'s "How resume
|
|
92
92
|
works" section.
|
|
93
93
|
|
|
94
94
|
## After Step 2
|
|
@@ -23,8 +23,7 @@ later ones.
|
|
|
23
23
|
3. **Re-run-evolved** (config present, project has drifted) — compute a
|
|
24
24
|
sectional diff, present for approval, write only on confirmation.
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
`claude-plugin/commands/_generator-idempotency-protocol.md`
|
|
26
|
+
Load the /thrum:generator-idempotency-protocol skill and follow it.
|
|
28
27
|
|
|
29
28
|
> **Note: human-in-the-loop required.** This skill uses interactive prompts for
|
|
30
29
|
> first-run incident-prose seeding and re-run-evolved diff approval. It cannot
|
|
@@ -29,8 +29,7 @@ later ones.
|
|
|
29
29
|
3. **Re-run-evolved** (doc present, project has drifted) — compute a sectional
|
|
30
30
|
diff, present via `AskUserQuestion`, write only on confirmation.
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
`claude-plugin/commands/_generator-idempotency-protocol.md`
|
|
32
|
+
Load the /thrum:generator-idempotency-protocol skill and follow it.
|
|
34
33
|
|
|
35
34
|
> **Note: human-in-the-loop required.** This skill uses `AskUserQuestion` for
|
|
36
35
|
> first-run project-specific prompts, re-run-evolved diff approval, and
|
|
@@ -232,7 +231,7 @@ undetected or unprovided. Fill in:
|
|
|
232
231
|
|
|
233
232
|
### Step 6a: MANDATORY — wire the project's security/threat model into the Decision Framework
|
|
234
233
|
|
|
235
|
-
If the project has a written threat model (search
|
|
234
|
+
If the project has a written threat model (search the project's security-model directory,
|
|
236
235
|
`docs/security*.md`, `SECURITY.md`), the rendered philosophy MUST carry a
|
|
237
236
|
Decision Framework row pointing at it — and that row MUST NOT be keyed on the
|
|
238
237
|
word "attacker".
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: project-rules-protocol
|
|
3
|
+
description: "Use when loading project-specific rules - shared rule skill for role skills."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# Project-Specific Rules Protocol
|
|
8
|
+
Project-local rules of kind `agent_rule` at `--scope role` were loaded at
|
|
9
|
+
session start by your preamble (see the memory rules in your role preamble).
|
|
10
|
+
If a project-local rule conflicts with a universal rule above, the
|
|
11
|
+
project-local rule wins; surface the conflict in your reply so the user can
|
|
12
|
+
decide whether to graduate or remove the override.
|
|
@@ -50,7 +50,7 @@ describes the artifact in front of you. Parse the binding keys from the
|
|
|
50
50
|
**highest-cycle** (last-appended) `stage=plan` line — stamps are only ever
|
|
51
51
|
appended, never reordered, so `tail -1` is the binding verdict; never `sort`
|
|
52
52
|
(a `cycle=10` line must beat `cycle=9`, which a lexical sort inverts) — then
|
|
53
|
-
re-derive the current values per `
|
|
53
|
+
re-derive the current values per `stamp-protocol.md` § "Review-object
|
|
54
54
|
binding" and compare:
|
|
55
55
|
|
|
56
56
|
```bash
|
|
@@ -95,7 +95,7 @@ Notes on the check:
|
|
|
95
95
|
marker. Surface any `THRUM-DEFER` lines still present in the doc as part
|
|
96
96
|
of the override audit.
|
|
97
97
|
- **The Deviations block has no override.** Its absence always fails the
|
|
98
|
-
gate — see
|
|
98
|
+
gate — see the /thrum:deviations-protocol skill ("empty must
|
|
99
99
|
be WRITTEN, not omitted").
|
|
100
100
|
- **`verify=` has no silent-omission path.** A stamp missing `verify=`
|
|
101
101
|
entirely FAILS this third check exactly like a missing stamp fails the
|
|
@@ -117,7 +117,7 @@ Notes on the check:
|
|
|
117
117
|
silent-omission path** — a stamp missing `plan_obj`/`src_lock` entirely
|
|
118
118
|
fails exactly like a missing `verify=` field (fourth check above). The
|
|
119
119
|
remedy is the same shape as the `verify=` remedy: re-run the plan review so
|
|
120
|
-
the stamp is emitted with live binding keys (`
|
|
120
|
+
the stamp is emitted with live binding keys (`stamp-protocol.md` § "Review-
|
|
121
121
|
object binding"), or a coordinator adds an explicit `verdict=OVERRIDE`
|
|
122
122
|
(with `reason=`) to the `stage=plan` line — the SAME auditable escape used
|
|
123
123
|
for the first check, not a new mechanism. There is no `PREDATES` value for
|
|
@@ -260,8 +260,8 @@ components, data flow, and interfaces.
|
|
|
260
260
|
|
|
261
261
|
### 🔴 Phase 1a — MANDATORY security-frame check (do this BEFORE decomposing)
|
|
262
262
|
|
|
263
|
-
**Read the project's threat model** (
|
|
264
|
-
|
|
263
|
+
**Read the project's threat model** (its security-model document, or
|
|
264
|
+
`docs/security*.md` / `SECURITY.md`) **whenever the plan
|
|
265
265
|
contains ANY of the following — and note that NONE of them need name an
|
|
266
266
|
attacker:**
|
|
267
267
|
|
|
@@ -476,8 +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 role preamble
|
|
480
|
-
🔴 PROSE INTO A COMMAND rule. `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. `scripts/bd-shared` delivers `--body-file` (and
|
|
481
480
|
`--stdin`) content: it reads the file on your box and pipes those bytes to bd,
|
|
482
481
|
and an empty or blank body is refused loudly; only `-f`/`--file` and `--graph`
|
|
483
482
|
(bulk-plan files) are refused there. Scratch files go in `/private/tmp` on macOS,
|
|
@@ -870,11 +869,11 @@ architecture notes specific to this feature:
|
|
|
870
869
|
|
|
871
870
|
> ⚠️ Verify base before acting: `git diff <sha>..origin/<merge_target> -- <files cited>` -- non-empty ⇒ cited code moved. (Resolve `<merge_target>` through its remote-tracking ref, never a bare local branch name — a local branch of the same name can be stale or absent.)
|
|
872
871
|
|
|
873
|
-
<!-- Derive stamp per
|
|
872
|
+
<!-- Derive stamp per the /thrum:stamp-protocol skill. -->
|
|
874
873
|
|
|
875
874
|
## Deviations from Source
|
|
876
875
|
|
|
877
|
-
<!-- Derive per
|
|
876
|
+
<!-- Derive per the /thrum:deviations-protocol skill — diff
|
|
878
877
|
against the plan/spec, never recall from memory. Required even when
|
|
879
878
|
empty. -->
|
|
880
879
|
|
|
@@ -959,7 +958,7 @@ prompt file:
|
|
|
959
958
|
```
|
|
960
959
|
|
|
961
960
|
2. **After the post-setup prompt review terminates `Ready:Yes`**, compute
|
|
962
|
-
`prompt_obj`/`plan_lock` per `
|
|
961
|
+
`prompt_obj`/`plan_lock` per `stamp-protocol.md` § "Review-object binding"
|
|
963
962
|
(strip-then-hash the prompt against itself for `prompt_obj`; plain-hash the
|
|
964
963
|
LOCKED plan for `plan_lock`), then append the verdict stamp:
|
|
965
964
|
|
|
@@ -439,8 +439,7 @@ bd list --type=epic | grep -i refactor
|
|
|
439
439
|
If no refactoring epic exists, create one:
|
|
440
440
|
|
|
441
441
|
`--description` is multi-line prose — never double-quoted inline. Write it to a
|
|
442
|
-
scratch file and pass `--body-file <file>`; see your role preamble
|
|
443
|
-
INTO A COMMAND rule. `scripts/bd-shared` delivers `--body-file` (and `--stdin`)
|
|
442
|
+
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`)
|
|
444
443
|
content: it reads the file on YOUR box and pipes those bytes to bd, and an empty
|
|
445
444
|
or blank body is refused loudly. Only `-f`/`--file` and `--graph` (bulk-plan
|
|
446
445
|
files) are refused there. Scratch files go in `/private/tmp` on macOS, where
|
|
@@ -75,8 +75,7 @@ where inlining is genuinely cheaper than the round-trip.
|
|
|
75
75
|
|
|
76
76
|
## Project-specific rules (already loaded)
|
|
77
77
|
|
|
78
|
-
|
|
79
|
-
`claude-plugin/commands/_project-rules-protocol.md`
|
|
78
|
+
Load the /thrum:project-rules-protocol skill and follow it.
|
|
80
79
|
|
|
81
80
|
If you accumulate a new rule mid-session (the user corrects you), capture it via
|
|
82
81
|
the `researcher-maintaining-memory` skill — it references the
|
|
@@ -74,8 +74,8 @@ sessions and re-readable by other agents.
|
|
|
74
74
|
|
|
75
75
|
**How to apply:** After reporting to the requester, write the finding as a
|
|
76
76
|
`research_note` memory with cited file:line refs and a verification footer. Tag
|
|
77
|
-
with
|
|
78
|
-
`thrum memory search --tag
|
|
77
|
+
it with `--tag <slug>` so other agents can find it later via
|
|
78
|
+
`thrum memory search --tag <slug>`:
|
|
79
79
|
|
|
80
80
|
```bash
|
|
81
81
|
cat > /tmp/research-note-body.md <<EOF
|
|
@@ -85,19 +85,18 @@ Verified: $(date +%Y-%m-%d) @ $(git rev-parse HEAD)
|
|
|
85
85
|
EOF
|
|
86
86
|
thrum memory create --kind research_note --scope role \
|
|
87
87
|
--title "<finding prose, ~80 char soft limit>" \
|
|
88
|
-
--tag
|
|
88
|
+
--tag <slug> \
|
|
89
89
|
--oneline "<one-line summary>" \
|
|
90
90
|
--full "@/tmp/research-note-body.md"
|
|
91
91
|
```
|
|
92
92
|
|
|
93
93
|
`--full` here is multi-line prose — compose via heredoc or a captured
|
|
94
|
-
variable, never double-quoted inline like this; see your role preamble
|
|
95
|
-
PROSE INTO A COMMAND rule.
|
|
94
|
+
variable, never double-quoted inline like this; see the heredoc-or-file rule in your role preamble.
|
|
96
95
|
|
|
97
96
|
Then add one line to `.thrum/context/research.md` under Tracked Topics (note: `thrum queue` now supersedes free-text Open Questions tracking):
|
|
98
97
|
|
|
99
98
|
```markdown
|
|
100
|
-
-
|
|
99
|
+
- `<slug>` — <one-line description, ≤ 80 chars>
|
|
101
100
|
```
|
|
102
101
|
|
|
103
102
|
The full index format and staleness-check protocol live in
|
|
@@ -121,8 +120,7 @@ gaps — you surface them, the implementer ships them.
|
|
|
121
120
|
|
|
122
121
|
## Project-specific rules (already loaded)
|
|
123
122
|
|
|
124
|
-
|
|
125
|
-
`claude-plugin/commands/_project-rules-protocol.md`
|
|
123
|
+
Load the /thrum:project-rules-protocol skill and follow it.
|
|
126
124
|
|
|
127
125
|
If you accumulate a new rule mid-session (the user corrects you), capture it via
|
|
128
126
|
the `researcher-maintaining-memory` skill — it references the
|
|
@@ -94,6 +94,8 @@ EOF
|
|
|
94
94
|
thrum memory edit <id> --full "@/tmp/memory-verify-body.md"
|
|
95
95
|
```
|
|
96
96
|
|
|
97
|
+
Re-verifying with `memory edit` needs a license.
|
|
98
|
+
|
|
97
99
|
## Staleness check via git diff
|
|
98
100
|
|
|
99
101
|
For research notes that cite specific files, structural staleness review filters
|
|
@@ -158,7 +160,7 @@ thrum memory create --kind agent_rule --scope role \
|
|
|
158
160
|
```
|
|
159
161
|
|
|
160
162
|
`--short`/`--full` carry real prose — compose via heredoc or file, never
|
|
161
|
-
double-quoted inline; see
|
|
163
|
+
double-quoted inline; see the heredoc-or-file rule in your role preamble.
|
|
162
164
|
|
|
163
165
|
This is the SAME pattern as coordinator/implementer role-rule writes — see
|
|
164
166
|
`memory-write-discipline` for the canonical shape.
|
|
@@ -1,20 +1,15 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
Not user-invocable directly.
|
|
2
|
+
name: snapshot-protocol
|
|
3
|
+
description: "Use when composing a restart snapshot or continuation - snapshot structure, worktree resolution, write rules."
|
|
5
4
|
---
|
|
6
5
|
|
|
7
|
-
# Snapshot Composition Protocol (shared partial)
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
added or dropped. Note: plain `/thrum:restart` does NOT consume this partial; it
|
|
13
|
-
carries its own inline snapshot template.
|
|
7
|
+
# Snapshot Composition Protocol
|
|
8
|
+
Note: plain `/thrum:restart` carries its own inline snapshot template rather
|
|
9
|
+
than consuming this skill.
|
|
14
10
|
|
|
15
|
-
This is the canonical source-of-truth for snapshot composition discipline.
|
|
16
|
-
|
|
17
|
-
variant-specific terminal action. Do NOT invoke this file directly; it has no
|
|
11
|
+
This is the canonical source-of-truth for snapshot composition discipline.
|
|
12
|
+
Invoke this skill to compose a snapshot, then take the variant-specific
|
|
18
13
|
terminal action.
|
|
19
14
|
|
|
20
15
|
## Step 1 — Resolve identity and your worktree
|
|
@@ -71,14 +66,14 @@ shapes everything else you write below it.
|
|
|
71
66
|
|
|
72
67
|
**Stamp your snapshot with the base it was authored against.**
|
|
73
68
|
Derive and emit the **Authored-against** stamp per
|
|
74
|
-
|
|
69
|
+
the /thrum:stamp-protocol skill and place it at the very top of your
|
|
75
70
|
§1 section (that protocol computes the SHA and merge_target for you — never
|
|
76
71
|
hand-type them). This is what lets `thrum prime` diff your snapshot at the next
|
|
77
72
|
wake and flag which cited files have MOVED; an unstamped snapshot reads as
|
|
78
73
|
"current", indistinguishable from one that never drifted.
|
|
79
74
|
|
|
80
75
|
Any commit your snapshot names as its own stamped SHA must also be readable
|
|
81
|
-
under `
|
|
76
|
+
under `stamp-protocol.md`'s "Read-time provenance re-derivation" section
|
|
82
77
|
(SHA-resolves, then merge-status) — link to that section rather than restating
|
|
83
78
|
its checks here.
|
|
84
79
|
|
|
@@ -114,7 +109,7 @@ session's conversation context. Refer to the previous session in third person.
|
|
|
114
109
|
|
|
115
110
|
### Choose your structure
|
|
116
111
|
|
|
117
|
-
The variant skill that invoked this
|
|
112
|
+
The variant skill that invoked this skill tells you which structure to use:
|
|
118
113
|
|
|
119
114
|
- **`/thrum:sleep`** → use the STANDARD 11-section structure below.
|
|
120
115
|
- **`/thrum:restart-extended` and `/thrum:sleep-extended`** → use the EXTENDED
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
commands, and never-type rule. Not user-invocable directly.
|
|
2
|
+
name: stamp-protocol
|
|
3
|
+
description: "Use when stamping a plan, prompt, or snapshot - Authored-against format, derivation commands, never-type rule."
|
|
5
4
|
---
|
|
6
5
|
|
|
7
|
-
# Authored-against Stamp Protocol (shared partial)
|
|
8
6
|
|
|
7
|
+
# Authored-Against Stamp Protocol
|
|
9
8
|
This is the canonical source-of-truth for the Authored-against stamp: its format,
|
|
10
9
|
derivation commands, and the never-type rule. Consuming files point here instead of
|
|
11
|
-
restating the recipe. Do
|
|
12
|
-
(To find what currently points here: `grep -rn "
|
|
10
|
+
restating the recipe. Do not run this as a command; it has no terminal action — other skills and commands load it by name.
|
|
11
|
+
(To find what currently points here: `grep -rn "thrum:stamp-protocol" claude-plugin/commands/ claude-plugin/skills/`
|
|
13
12
|
— a hand-listed consumer roster in this file would rot the moment a new emitter or
|
|
14
13
|
reader is added, so none is kept here.)
|
|
15
14
|
|
|
@@ -86,14 +86,19 @@ thrum tmux launch <session> [--runtime <r>] Start runtime in session (REQUIRED
|
|
|
86
86
|
### Monitor Jobs
|
|
87
87
|
|
|
88
88
|
```bash
|
|
89
|
-
thrum monitor
|
|
90
|
-
thrum monitor list
|
|
91
|
-
thrum monitor show <name> Show job details
|
|
89
|
+
thrum monitor start --name <n> --match <re> --to @agent [--schedule "<cron>"] [--notify-on-success] -- <cmd> [args...]
|
|
90
|
+
thrum monitor list [--all] List monitor jobs (running; --all adds stopped)
|
|
91
|
+
thrum monitor show <name> Show job details
|
|
92
|
+
thrum monitor logs <name> Recent matched lines
|
|
93
|
+
thrum monitor update <name> Change match, schedule, target or debounce in place
|
|
92
94
|
thrum monitor stop <name> Stop a monitor job
|
|
93
|
-
thrum monitor
|
|
95
|
+
thrum monitor delete <name> Remove a job and free its name
|
|
94
96
|
thrum monitor restart <name> Restart a stopped job
|
|
95
97
|
```
|
|
96
98
|
|
|
99
|
+
Reminders, periodic script checks and delivery verification: see the
|
|
100
|
+
`using-monitors` skill.
|
|
101
|
+
|
|
97
102
|
### Daemon & Sync
|
|
98
103
|
|
|
99
104
|
```bash
|