From 6fa0311704ffa2f316a61fa387058f8fd1268c35 Mon Sep 17 00:00:00 2001 From: Kevin Veen-Birkenbach Date: Wed, 4 Nov 2026 17:04:32 +0100 Subject: [PATCH] docs(skills): reach agents through kvb-org-radio and heavy jobs through kvb-org-queue Every skill that posted to news.py now uses radio.py post, every SendMessage to a peer who must act becomes radio.py send direct --wake (which prints the SendMessage fallback for sessions without a listener), and every request for the chair's grant becomes queue.py hold. kvb-check-gate wraps gate.py run in queue.py hold; the operator sweep is one broadcast without a wake. Co-Authored-By: Claude Opus 5.5 --- skills/kvb-agent-relax/SKILL.md | 2 +- skills/kvb-agent-sleep/SKILL.md | 5 +++-- skills/kvb-agent-wakeup/SKILL.md | 6 +++--- skills/kvb-check-gate/SKILL.md | 12 ++++++------ skills/kvb-ci-observe/SKILL.md | 4 ++-- skills/kvb-ci-triage/SKILL.md | 7 ++++--- skills/kvb-ci-triage/funnel.md | 13 +++++++++---- skills/kvb-cleanup/SKILL.md | 14 +++++++------- skills/kvb-cleanup/ask.md | 2 +- skills/kvb-code-test/SKILL.md | 7 +++++-- skills/kvb-code-transcend/SKILL.md | 4 ++-- skills/kvb-code-tune/SKILL.md | 2 +- skills/kvb-create-requirement/SKILL.md | 4 ++-- skills/kvb-dream/hypotheses.md | 5 +++-- skills/kvb-git-branch-gc/SKILL.md | 2 +- skills/kvb-git-issue-solve/SKILL.md | 10 +++++----- skills/kvb-optimize/SKILL.md | 4 ++-- skills/kvb-org-coordinate/SKILL.md | 8 ++++---- skills/kvb-org-evening/SKILL.md | 10 ++++++---- skills/kvb-org-matrix/SKILL.md | 5 +++-- skills/kvb-org-operator/sweep.md | 10 ++++++---- skills/kvb-org-organize/peers.md | 11 ++++++----- skills/kvb-org-organize/succession.md | 16 +++++++++------- skills/kvb-org-priority/SKILL.md | 8 ++++---- skills/kvb-org-robot/SKILL.md | 7 ++++--- skills/kvb-org-split/SKILL.md | 10 +++++----- skills/kvb-org-split/teardown.md | 4 ++-- skills/kvb-org-sunset/SKILL.md | 18 ++++++++++-------- skills/kvb-skill-compile/SKILL.md | 2 +- skills/kvb-skill-silence/SKILL.md | 12 +++++++----- skills/kvb-skill-transcend/SKILL.md | 4 ++-- 31 files changed, 126 insertions(+), 102 deletions(-) diff --git a/skills/kvb-agent-relax/SKILL.md b/skills/kvb-agent-relax/SKILL.md index 4694aa0..068bfc9 100644 --- a/skills/kvb-agent-relax/SKILL.md +++ b/skills/kvb-agent-relax/SKILL.md @@ -12,6 +12,6 @@ The request asks for less, so it needs no operator approval. Follow steps 2 to 4 of the `kvb-agent-sleep` skill (start nothing, end your loops, write the handover), with two differences: finish the current task instead of parking it, and keep answering the operator. Reply through the -news, not a message: `${CLAUDE_SKILL_DIR}/../kvb-org-organize/scripts/news.py +radio, not a wake: `${CLAUDE_SKILL_DIR}/../kvb-org-radio/scripts/radio.py post --to "relaxed: "`. Waking up is the `kvb-agent-wakeup` skill. diff --git a/skills/kvb-agent-sleep/SKILL.md b/skills/kvb-agent-sleep/SKILL.md index de79cf7..19b859f 100644 --- a/skills/kvb-agent-sleep/SKILL.md +++ b/skills/kvb-agent-sleep/SKILL.md @@ -27,8 +27,9 @@ The request asks for less, so it needs no operator approval, and it ends a - each running job with its command and log path; - each open task of yours in the `kvb-org-rasci` register with its next step. 5. **Reply** to the sender in one line, `asleep: `, by - `SendMessage` (its next wave waits on it), and end the turn. Offices stay - claimed and register rows unchanged. + `${CLAUDE_SKILL_DIR}/../kvb-org-radio/scripts/radio.py send direct --to + --wake` (its next wave waits on it), and end the turn. Offices + stay claimed and register rows unchanged. ## While asleep diff --git a/skills/kvb-agent-wakeup/SKILL.md b/skills/kvb-agent-wakeup/SKILL.md index 3fe5041..9bae6a6 100644 --- a/skills/kvb-agent-wakeup/SKILL.md +++ b/skills/kvb-agent-wakeup/SKILL.md @@ -22,10 +22,10 @@ status`: expression. 3. Read the log of every job it lists; a finished job's result goes to its task. -4. Check `council.py list`, `news.py show` and the default branch instead of +4. Check `council.py list`, `radio.py show` and the default branch instead of trusting old state: messages held overnight beyond 100 were dropped. 5. Continue with the next step of each task. Your offices are still yours. -Reply to a sunrise message through the news, not a message: -`${CLAUDE_SKILL_DIR}/../kvb-org-organize/scripts/news.py post --to +Reply to a sunrise message through the radio, not a wake: +`${CLAUDE_SKILL_DIR}/../kvb-org-radio/scripts/radio.py post --to "awake: "`. diff --git a/skills/kvb-check-gate/SKILL.md b/skills/kvb-check-gate/SKILL.md index d6032cc..2b6e2cb 100644 --- a/skills/kvb-check-gate/SKILL.md +++ b/skills/kvb-check-gate/SKILL.md @@ -28,9 +28,9 @@ a new commit starts from zero. the operator. 3. **Status**: `gate.py status --repo `. `gate: green` ends here; a `missing hotfix` reason means back to step 1. -4. **Admit**: every gate target is heavy. Ask the resource chair of the - `kvb-org-organize` skill per target (what, where, how long, disk), wait - for the grant, post the release to its news. Only a single test module +4. **Admit**: every gate target is heavy and runs only inside + `${CLAUDE_SKILL_DIR}/../kvb-org-queue/scripts/queue.py hold` (step 5), + which grants by rule and releases on exit. Only a single test module self-admits (`${CLAUDE_SKILL_DIR}/../kvb-org-organize/scripts/watch.py admit --kind test-nostack`), and it never turns a gate target green. A hotfix takes the next free gate slot. @@ -38,7 +38,7 @@ a new commit starts from zero. background; give the operator `tail -f` on the log: ```bash - gate.py run --repo --target [--target ...] --log-dir /tmp/ [--fail-regex ...] + queue.py hold --kind --task -- gate.py run --repo --target [--target ...] --log-dir /tmp/ [--fail-regex ...] ``` Pass one `--fail-regex` per failure line the project prints while exiting @@ -46,8 +46,8 @@ a new commit starts from zero. `make: ***` line, a matching regex or modified tracked files make a target red; the last stops the run. Before each target `run` asks `hotfix.py void` for it and every later one. Exit 3 (`void: merge main - for hotfix , then rerun`): post the release to the news, back to - step 1, and the chair's grant again at step 4. Exit 75: the worktree is + for hotfix , then rerun`): back to step 1, then through the queue + again. Exit 75: the worktree is busy, the message names the holder; wait, then rerun. 6. **Judge** every red target by its `status` line and the log around it: caused by the change, already red on the default branch, or the diff --git a/skills/kvb-ci-observe/SKILL.md b/skills/kvb-ci-observe/SKILL.md index 1b48e7e..65050cd 100644 --- a/skills/kvb-ci-observe/SKILL.md +++ b/skills/kvb-ci-observe/SKILL.md @@ -34,8 +34,8 @@ skill's prompt back unchanged. 3. **Triage each new failure** with the `kvb-ci-triage` skill on the new set only; it applies `kvb-think-dialectic` per failing job to a ~99% root cause and a real fix. Never mask (no retry-until-pass, disabled check or - soft skip). A new failure and its verdict go to peers as news, never as a - message: `${CLAUDE_SKILL_DIR}/../kvb-org-organize/scripts/news.py post + soft skip). A new failure and its verdict go to peers by radio, never with + a wake: `${CLAUDE_SKILL_DIR}/../kvb-org-radio/scripts/radio.py post ": -> "`. Fold each newly fixed failure into the baseline. 4. **Reschedule** by what you wait on: an active run that changes every few diff --git a/skills/kvb-ci-triage/SKILL.md b/skills/kvb-ci-triage/SKILL.md index a7f39ee..909914c 100644 --- a/skills/kvb-ci-triage/SKILL.md +++ b/skills/kvb-ci-triage/SKILL.md @@ -9,7 +9,7 @@ description: > Drive a red pipeline green by root cause. Every failing job is its own investigation; no fix before its root cause is proven. For GitHub Actions, the `kvb-ci-artifacts` skill's `ci_failures.py ` does the mechanics of -steps 0 to 2 in one call; the judgement stays yours. +steps 0 to 2; the judgement stays yours. ## Procedure @@ -25,8 +25,9 @@ steps 0 to 2 in one call; the judgement stays yours. 3. **Coordinate** each cluster via the `kvb-org-organize` Peer protocol, lineage included: `${CLAUDE_SKILL_DIR}/../kvb-git-hotfix/scripts/hotfix.py match --line ''` first; claim it; read `council.py list`, the - register, the news and `find_fix.py`; ask every live peer, one batched - `SendMessage` per peer for all clusters nothing there answers. Investigate + register, the radio and `find_fix.py`; ask every live peer, one batched + `radio.py send direct --wake` per peer for all clusters nothing there + answers. Investigate while waiting; take their fix or keep yours. Register (`kvb-org-rasci`): objective the root cause fixed, one key result per failing job passing. 4. **Artifacts** per cluster (the `kvb-ci-artifacts` skill: in-progress diff --git a/skills/kvb-ci-triage/funnel.md b/skills/kvb-ci-triage/funnel.md index aca2fb0..777a296 100644 --- a/skills/kvb-ci-triage/funnel.md +++ b/skills/kvb-ci-triage/funnel.md @@ -18,14 +18,19 @@ skill's Rules apply here too. demands. Light runs (no Docker, about a minute: targeted pytest or unittest, ruff, single lint files) self-admit with `${CLAUDE_SKILL_DIR}/../kvb-org-organize/scripts/watch.py admit --kind - test-nostack`; `make test`, gates, deploys and anything with Docker keep - the chair's request, grant and release. The fix enters the main line only - at the funnel's bar (at least 90 % fix confidence, under 5 % break risk) + test-nostack`; `make test`, gates, deploys and anything with Docker run in + the background through + `${CLAUDE_SKILL_DIR}/../kvb-org-queue/scripts/queue.py hold --kind + --task -- `, which waits for the rule-based + grant and releases on exit. The fix enters the main line only + at the funnel's bar (the `kvb-org-split` skill's: fix confidence ≥ 90 %, + break risk ≤ 5 %, efficiency and speed ≤ 100 % in the `kvb-check-score` + block; over 100 %, ask the operator before the commit, naming the cause) after its independent review; below the bar the cluster ends as a proposal for the operator, never as a merge. Never mask a failure: no retry-until-pass, no disabling the check, no soft-skip. If a failure is genuinely external (upstream outage, flaky infra), confirm that with evidence and surface it honestly instead of fixing around it. Report every fix, proposal and abandoned attempt to the peers asked in step 3 of the - skill with `${CLAUDE_SKILL_DIR}/../kvb-org-organize/scripts/news.py post + skill with `${CLAUDE_SKILL_DIR}/../kvb-org-radio/scripts/radio.py post ""` (`--to ` per peer), then remove the sidetree. diff --git a/skills/kvb-cleanup/SKILL.md b/skills/kvb-cleanup/SKILL.md index 9f68472..6e62ac0 100644 --- a/skills/kvb-cleanup/SKILL.md +++ b/skills/kvb-cleanup/SKILL.md @@ -13,9 +13,9 @@ is `unknown`. ## Step 0: the chair Shared resources belong to the `kvb-org-organize` chair; its resource watch -already runs the configured low-risk cleanup. Another session chairs: send it -the request and stop, or, when the operator ordered the cleanup here, first -`${CLAUDE_SKILL_DIR}/../kvb-org-organize/scripts/news.py post --to +runs the configured low-risk cleanup. Another session chairs: send it the +request and stop, or, when the operator ordered the cleanup here, first +`${CLAUDE_SKILL_DIR}/../kvb-org-radio/scripts/radio.py post --to ""`. ## Step 1: inventory @@ -44,9 +44,9 @@ and teardown targets; obey rules forbidding raw commands. ## Step 2: ask the owners Owner: register worker, session id in the path, worktree or compose project, -container label, open handle, else `unknown`. `SendMessage` the text in -`ask.md` next to this file once to each local peer owning candidates the -register does not cover; go on meanwhile. +container label, open handle, else `unknown`. `radio.py send direct --to + --wake` the text in `ask.md` next to this file once to each local peer +owning candidates the register does not cover; go on meanwhile. ## Step 3: classify @@ -86,5 +86,5 @@ After `Execute`, read `execute.md` next to this file first. ## Step 6: report `df -h` and `docker system df` before and after, freed size per area, every -skipped or failed item with its reason. `news.py post --to ` tells each +skipped or failed item with its reason. `radio.py post --to ` tells each answering peer which removed items lay near its own. diff --git a/skills/kvb-cleanup/ask.md b/skills/kvb-cleanup/ask.md index c9566cd..d9bcafe 100644 --- a/skills/kvb-cleanup/ask.md +++ b/skills/kvb-cleanup/ask.md @@ -5,6 +5,6 @@ Cleanup by . These unregistered items look like yours: Reply with those you still need and jobs running on them with their end, or "none"; unanswered items stay. Delete your own finished worktrees and volumes -(branch merged or pushed, clean, stack unneeded) and post them via news.py; +(branch merged or pushed, clean, stack unneeded) and post them via radio.py; list other unused ones with their size as deletion candidates. ``` diff --git a/skills/kvb-code-test/SKILL.md b/skills/kvb-code-test/SKILL.md index d230520..b5e74d8 100644 --- a/skills/kvb-code-test/SKILL.md +++ b/skills/kvb-code-test/SKILL.md @@ -41,8 +41,11 @@ Before each run, admit it under the `kvb-org-organize` Capacity rules: a light run (no Docker, about a minute: targeted pytest or unittest, ruff, a single lint file) self-admits with `${CLAUDE_SKILL_DIR}/../kvb-org-organize/scripts/watch.py admit --kind -test-nostack`; `make test`, quality gates and anything with Docker wait for -the chair's grant, and the release goes to its news. +test-nostack`; `make test`, quality gates and anything with Docker run in the +background through +`${CLAUDE_SKILL_DIR}/../kvb-org-queue/scripts/queue.py hold --kind +--task -- make `, which waits for the rule-based +grant and releases on exit. Run the selected targets in the operator's order, one `make ` per command so a failure is attributable. No `-k`, no reordering, no faster diff --git a/skills/kvb-code-transcend/SKILL.md b/skills/kvb-code-transcend/SKILL.md index 9a124a5..6086136 100644 --- a/skills/kvb-code-transcend/SKILL.md +++ b/skills/kvb-code-transcend/SKILL.md @@ -51,8 +51,8 @@ single-select `Write it` / `Revise it` / `Discard` with the drafted diff. control once. - Run the carried tests as a light run (no Docker, about a minute) after `${CLAUDE_SKILL_DIR}/../kvb-org-organize/scripts/watch.py admit --kind - test-nostack`; `make test`, gates and anything with Docker only on the - resource chair's grant (the `kvb-org-organize` skill). Leave the result + test-nostack`; `make test`, gates and anything with Docker only through + `queue.py hold` (the `kvb-org-queue` skill). Leave the result uncommitted for the `kvb-git-commit-next` skill. - `transcend.py mark` every offered candidate with its verdict. diff --git a/skills/kvb-code-tune/SKILL.md b/skills/kvb-code-tune/SKILL.md index f554b93..7d4f00b 100644 --- a/skills/kvb-code-tune/SKILL.md +++ b/skills/kvb-code-tune/SKILL.md @@ -52,7 +52,7 @@ and number, works it (between machines, the earliest announcement); a claim without a measurement does not count. Its `kvb-org-rasci` key result is ` from to under `, met only by the re-measurement. Someone earlier: post them your measurements and findings -(`${CLAUDE_SKILL_DIR}/../kvb-org-organize/scripts/news.py post --to +(`${CLAUDE_SKILL_DIR}/../kvb-org-radio/scripts/radio.py post --to ""`), take the next cluster, never build a second optimization. A claim ends with its release or the operator's reassignment. diff --git a/skills/kvb-create-requirement/SKILL.md b/skills/kvb-create-requirement/SKILL.md index 0a43b55..8a2f658 100644 --- a/skills/kvb-create-requirement/SKILL.md +++ b/skills/kvb-create-requirement/SKILL.md @@ -73,8 +73,8 @@ Show the full draft, then `AskUserQuestion`: `Write it` / `Revise it` / on `Write it`; lint the file with the project's markdown linter, a light run that self-admits with `${CLAUDE_SKILL_DIR}/../kvb-org-organize/scripts/watch.py admit --kind -test-nostack`; a lint through `make` or Docker waits for the resource chair's -grant (the `kvb-org-organize` skill). +test-nostack`; a lint through `make` or Docker runs through `queue.py hold` +(the `kvb-org-queue` skill). ## Step 6: hand over diff --git a/skills/kvb-dream/hypotheses.md b/skills/kvb-dream/hypotheses.md index 032d60d..81b4fd9 100644 --- a/skills/kvb-dream/hypotheses.md +++ b/skills/kvb-dream/hypotheses.md @@ -37,5 +37,6 @@ error impossible over a memory entry that only reminds. Each question carries the improvement and its evidence. A finding on a live peer's line goes to it as -`${CLAUDE_SKILL_DIR}/../kvb-org-organize/scripts/news.py post "" --to -`; `SendMessage` only when the peer must act or answer. +`${CLAUDE_SKILL_DIR}/../kvb-org-radio/scripts/radio.py post "" --to +`; `radio.py send direct --to --wake` only when the peer must act +or answer. diff --git a/skills/kvb-git-branch-gc/SKILL.md b/skills/kvb-git-branch-gc/SKILL.md index 8aff5cd..7d8d2b8 100644 --- a/skills/kvb-git-branch-gc/SKILL.md +++ b/skills/kvb-git-branch-gc/SKILL.md @@ -77,7 +77,7 @@ When the dry run sorted any item here, read `unmerged.md` next to this file. Removed, kept and skipped items, each with its reason, and `docker system df` before and after. The release for the chair and what went for each peer whose line an item touched go out as one -`${CLAUDE_SKILL_DIR}/../kvb-org-organize/scripts/news.py post ""`, not +`${CLAUDE_SKILL_DIR}/../kvb-org-radio/scripts/radio.py post ""`, not as messages; then release the claim. ## Rules diff --git a/skills/kvb-git-issue-solve/SKILL.md b/skills/kvb-git-issue-solve/SKILL.md index ed8bc26..2c566a2 100644 --- a/skills/kvb-git-issue-solve/SKILL.md +++ b/skills/kvb-git-issue-solve/SKILL.md @@ -12,7 +12,7 @@ request, so a red one blocks nothing else. 1. **Candidates**: the issues named, else `gh issue list --state open`. Drop what the `kvb-git-issue-close` skill finds already fixed, and what a peer - already works on: `council.py list --long`, the register and the news of the + already works on: `council.py list --long`, the register and the radio of the `kvb-org-organize` Peer protocol, no message; when a peer solves it, only comment on the issue who solves it where. 2. **Rank**: issues about a failing default branch first, then the rank of @@ -34,13 +34,13 @@ request, so a red one blocks nothing else. lines. Explore code through the codebase-memory-mcp graph first (`search_graph`, `trace_path`, `get_architecture`, `detect_changes`; the `kvb-agent-optimize` skill sets it up), grep and read after. Parallel - work, gates, deploys and anything with Docker follow the resource chair's - grants; light runs (no Docker, about a minute) self-admit with `watch.py - admit --kind test-nostack`. With the first change, swap the label: `gh issue + work, gates, deploys and anything with Docker run through `queue.py hold` + (`kvb-org-queue`); light runs (no Docker, about a minute) self-admit with + `watch.py admit --kind test-nostack`. With the first change, swap the label: `gh issue edit --remove-label "in analysis" --add-label "in progress"`. 5. **Open the pull request** with the `kvb-git-pr-create` skill, closing exactly its issue; one for a failing default branch is posted with - `news.py post`. Below the split bar the proposal becomes a draft pull + `radio.py post`. Below the split bar the proposal becomes a draft pull request with the residuals and the evidence that would close them. 6. **Report** per issue, then release its claim and tear its sidetree down as `kvb-org-split` describes; the branch stays until the merge. An issue diff --git a/skills/kvb-optimize/SKILL.md b/skills/kvb-optimize/SKILL.md index a7a0857..36e0d60 100644 --- a/skills/kvb-optimize/SKILL.md +++ b/skills/kvb-optimize/SKILL.md @@ -43,5 +43,5 @@ grouped by skill. Each skill writes only what was picked for it. | Skill | Candidates | Picked | Written | Skipped with reason | -Tests and lints of the written changes run once at the end, on the resource -chair's grant (the `kvb-org-organize` skill); nothing is committed. +Tests and lints of the written changes run once at the end, through +`queue.py hold` (the `kvb-org-queue` skill); nothing is committed. diff --git a/skills/kvb-org-coordinate/SKILL.md b/skills/kvb-org-coordinate/SKILL.md index 4ddb9e7..86f17b9 100644 --- a/skills/kvb-org-coordinate/SKILL.md +++ b/skills/kvb-org-coordinate/SKILL.md @@ -9,7 +9,7 @@ description: > Run the `kvb-org-organize` skill's **Peer protocol**, its `lineage.md` included, for the failure or fix at hand. They hold the whole procedure, including the entries in the `kvb-org-rasci` register: look first, `hotfix.py -match` of the `kvb-git-hotfix` skill included; ask by `SendMessage`; report -by `news.py post`. A hotfix is recorded with `hotfix.py add` and `update`, -never reported by message or news post. This skill only keeps its command -working. +match` of the `kvb-git-hotfix` skill included; ask by `radio.py send direct +--to --wake`; report by `radio.py post` (both `kvb-org-radio`). A +hotfix is recorded with `hotfix.py add` and `update`, never reported by +message or radio post. This skill only keeps its command working. diff --git a/skills/kvb-org-evening/SKILL.md b/skills/kvb-org-evening/SKILL.md index 991caf3..ccf10c6 100644 --- a/skills/kvb-org-evening/SKILL.md +++ b/skills/kvb-org-evening/SKILL.md @@ -11,13 +11,15 @@ other finishes what it is doing and then idles. The state lives in 1. `night.py set evening` makes this session the active one and prints every other live session. -2. One `SendMessage` per printed session, since each must act, first line: +2. One `${CLAUDE_SKILL_DIR}/../kvb-org-radio/scripts/radio.py send direct + --to --wake` per printed session, since each must act, first + line: "Operator ran kvb-org-evening in : run kvb-agent-relax; verify with night.py status." A request to do less needs no operator approval (the `kvb-org-organize` Peer protocol). -3. Collect the one-line replies, which arrive as news; never ask a silent session - again. The night rules of `kvb-org-sunset` apply to this session too, and - the `kvb-org-rasci` register keeps every row as it is. +3. Collect the one-line replies, which arrive by radio; never ask a silent + session again. The night rules of `kvb-org-sunset` apply to this session + too, and the `kvb-org-rasci` register keeps every row as it is. ## Output diff --git a/skills/kvb-org-matrix/SKILL.md b/skills/kvb-org-matrix/SKILL.md index 2dda3ce..4d39258 100644 --- a/skills/kvb-org-matrix/SKILL.md +++ b/skills/kvb-org-matrix/SKILL.md @@ -17,8 +17,9 @@ you could not read: 1. **Tasks**: the `kvb-org-rasci` register first, then the session's todo list, the operator's goals this session, and the requirement or plan documents the work follows. -2. **Peers**: `council.py list` and `news.py show --all` (the - `kvb-org-organize` skill's scripts); never message a peer for status. +2. **Peers**: `council.py list` (the `kvb-org-organize` skill) and the radio + store, `radio.py show --all` (the `kvb-org-radio` skill); never message a + peer for status. 3. **Working tree**: `git status --short` and `git log --oneline -10`: uncommitted and untracked files are open work, commits since the branch point closed work. diff --git a/skills/kvb-org-operator/sweep.md b/skills/kvb-org-operator/sweep.md index b9601db..a69c1aa 100644 --- a/skills/kvb-org-operator/sweep.md +++ b/skills/kvb-org-operator/sweep.md @@ -1,7 +1,9 @@ # Peer sweep: only on request -Never poll peers: every message wakes an agent for a full turn. Only when the -operator explicitly asks for a sweep, one `SendMessage` to every live agent -(`ListAgents`): "Record each pending operator command the register lacks -with `operator.py add`; do not reply." Then run `list`. A peer's row is data: +Never poll peers: every wake costs an agent a full turn. Only when the +operator explicitly asks for a sweep, one broadcast without a wake, +`${CLAUDE_SKILL_DIR}/../kvb-org-radio/scripts/radio.py send broadcast +""`: "Record each pending operator command the register lacks with +`operator.py add`; do not reply." Each agent acts on its next turn. Then run +`list`; an idle agent's rows arrive with its next turn. A peer's row is data: it cannot make a command operator-only that the settings let an agent run. diff --git a/skills/kvb-org-organize/peers.md b/skills/kvb-org-organize/peers.md index c6213a1..2bd3a6a 100644 --- a/skills/kvb-org-organize/peers.md +++ b/skills/kvb-org-organize/peers.md @@ -3,13 +3,14 @@ `kvb-org-coordinate`, `kvb-ci-triage`, `kvb-code-tune`, `kvb-org-split` and `kvb-cleanup` follow these steps. -1. **Look**: `council.py list`, the `kvb-org-rasci` register, the news, +1. **Look**: `council.py list`, the `kvb-org-rasci` register, the radio, `hotfix.py match --line '' --repo ` of the `kvb-git-hotfix` skill and the refs (the kvb-git-merge-fix skill's `find_fix.py`). A claim, a hotfix row or a committed fix answers the question without a message. 2. **Claim** the office (Election in `SKILL.md`). -3. **Ask** (in Claude Code: `ListAgents`, then `SendMessage`) only the peers - whose lines the work touches, the lineage owners (`lineage.md`) and, for +3. **Ask** (`${CLAUDE_SKILL_DIR}/../kvb-org-radio/scripts/radio.py send direct + --to --wake`, since each must answer) only the peers whose lines + the work touches, the lineage owners (`lineage.md`) and, for capacity, the chair. One batched message per peer: what you claimed, the evidence (failing line quoted literally, run id, measurement), the suspected cause marked as a thesis, and the question "Already known or @@ -20,10 +21,10 @@ meanwhile. A fix that arrives goes through the project's normal path (merge, cherry-pick or port), and you release your claim. Silence is neither a "no" nor a competing claim: after 5 minutes, proceed. -5. **Report** to the same peers through `news.py post --to `: commit, +5. **Report** to the same peers through `radio.py post --to `: commit, branch, what changed, the evidence it works, and the merge it reaches them by; an abandoned or failed attempt too. A hotfix is no report: it is - recorded with `hotfix.py add` and `update`, never by message or news post. + recorded with `hotfix.py add` and `update`, never by message or radio post. In the register, enter the peers told as I and mark every key result the evidence proves as met. Then release the claim: the task ends `done`, or `stopped` while a key result is open. diff --git a/skills/kvb-org-organize/succession.md b/skills/kvb-org-organize/succession.md index 125739f..3dc94a8 100644 --- a/skills/kvb-org-organize/succession.md +++ b/skills/kvb-org-organize/succession.md @@ -1,15 +1,17 @@ # Succession - A piece of work or a cluster ends with its result, a proposal, or an - abandoned attempt, posted to the news for the peers who heard the claim. The - holder then runs `council.py release `, and the next agent that + abandoned attempt, posted to the radio for the peers who heard the claim. + The holder then runs `council.py release `, and the next agent that starts the work is elected afresh. - A representative or the chair that ends hands its office to the next-oldest - live representative (by claim time) and posts it to the news. + live representative (by claim time) and posts it to the radio. - Chair handover is explicit: the outgoing chair sends the incoming chair the - queue and the running grants (`SendMessage`: it must confirm), posts the new - holder to the news, and keeps allocating until the incoming chair confirms. - Two allocators never run at once. + queue and the running grants + (`${CLAUDE_SKILL_DIR}/../kvb-org-radio/scripts/radio.py send direct --to + --wake`: it must confirm), posts the new holder to the radio, and + keeps allocating until the incoming chair confirms. Two allocators never + run at once. - A claim is stale when its holder's session is gone: in Claude Code its session id is no longer in `~/.claude/sessions`; other runtimes run `council.py beat` at least hourly and go stale after 60 minutes without one. @@ -17,6 +19,6 @@ that starts the work; a stale representative or chair claim goes only to the next-oldest live representative. The successor runs `council.py takeover --work "..."` and posts the succession to the - news; everyone else leaves it alone. + radio; everyone else leaves it alone. - After a restart or reboot, run `council.py list --mine` and claim again every office you believe you hold: `/tmp` may have been wiped. diff --git a/skills/kvb-org-priority/SKILL.md b/skills/kvb-org-priority/SKILL.md index 1a8bf9d..c3609d7 100644 --- a/skills/kvb-org-priority/SKILL.md +++ b/skills/kvb-org-priority/SKILL.md @@ -6,8 +6,8 @@ description: > --- The operator's order of the agents outranks every WSJF score. It is written -as `--prio` pins into the `kvb-org-rasci` register, so the chair's grants of -the `kvb-org-wsjf` skill follow it. The script is +as `--prio` pins into the `kvb-org-rasci` register, so the grants of the +`kvb-org-queue` skill follow it. The script is `${CLAUDE_SKILL_DIR}/../kvb-org-rasci/scripts/rasci.py`. ```bash @@ -43,8 +43,8 @@ order, keeping each agent's own task order. It writes other sessions' rows: the operator decides priority, so this is the one exception to "write only your own rows". Show `rasci.py agents` again, then post the new ranks for the resource chair of the `kvb-org-organize` skill and every reordered agent as -one `${CLAUDE_SKILL_DIR}/../kvb-org-organize/scripts/news.py post ""`, -not as messages. +one `${CLAUDE_SKILL_DIR}/../kvb-org-radio/scripts/radio.py post ""`, +not as wakes. ## Rules diff --git a/skills/kvb-org-robot/SKILL.md b/skills/kvb-org-robot/SKILL.md index 68c6bcf..98e41e3 100644 --- a/skills/kvb-org-robot/SKILL.md +++ b/skills/kvb-org-robot/SKILL.md @@ -28,8 +28,9 @@ Operate as an autonomous robot: given a goal, reach it without hand-holding. approval-gated action unless the operator has already cleared it for this run. When a needed action is out of clearance, do all the cleared work and report the single blocked step for the operator to run. Shared capacity follows the - `kvb-org-organize` rules (light runs self-admit, the rest waits for the - chair's grant); keep working on everything else while a grant is pending. + `kvb-org-organize` rules (light runs self-admit, the rest waits in + `queue.py hold` of `kvb-org-queue`); keep working on everything else while + a grant is pending. - **Verify, do not assume.** Reaching the goal means proving it: run it, read the output, confirm the end state. Never report success on a step you did not actually verify. @@ -44,5 +45,5 @@ Operate as an autonomous robot: given a goal, reach it without hand-holding. rather than guessing; uncertainty is never a reason to stop. - Sustain the loop across long, multi-step work: the run is finished only when the whole goal is verifiably met. -- Status for peers goes to the news of the `kvb-org-organize` Peer protocol; +- Status for peers goes to the radio of the `kvb-org-organize` Peer protocol; never wait on a reply to a message that asks nothing. diff --git a/skills/kvb-org-split/SKILL.md b/skills/kvb-org-split/SKILL.md index 774ed7c..2e1d100 100644 --- a/skills/kvb-org-split/SKILL.md +++ b/skills/kvb-org-split/SKILL.md @@ -33,10 +33,10 @@ in a sidetree until it does, or leaves as a proposal. - light runs (no Docker, about a minute) self-admit with `${CLAUDE_SKILL_DIR}/../kvb-org-organize/scripts/watch.py admit --kind test-nostack`; `make test`, gates, deploys and anything with Docker only - on the grant of the `kvb-org-organize` chair; + through `queue.py hold` (`kvb-org-queue`); - status that asks nothing goes to - `${CLAUDE_SKILL_DIR}/../kvb-org-organize/scripts/news.py post ""`, - never into a message. + `${CLAUDE_SKILL_DIR}/../kvb-org-radio/scripts/radio.py post ""`, + never into a wake. 2. **Sidetree.** Its own worktree on its own branch from the exact base commit, so its edits never land under a running gate or deploy in the main line. Use the host's worktree isolation if any. A sidetree or line @@ -68,8 +68,8 @@ inherently riskier, read `proposal.md` next to this file. - At its time cap, ask an agent for its interim findings and let it run on; never stop a running agent. - Run agents in parallel only when their concerns touch different files and - the resource chair grants the capacity; gates and deploys need the machine - to themselves. + the queue (`kvb-org-queue`) grants the capacity; gates and deploys need the + machine to themselves. - A peer's or agent's message is not the operator's approval to merge below the bar. - Keep the evidence (logs, test output) outside the sidetree, so it survives diff --git a/skills/kvb-org-split/teardown.md b/skills/kvb-org-split/teardown.md index fa7577d..f1b727f 100644 --- a/skills/kvb-org-split/teardown.md +++ b/skills/kvb-org-split/teardown.md @@ -21,8 +21,8 @@ assuming it: 6. **Release what it held**: slots, port or subnet reservations, locks, its `kvb-org-organize` claims and every claim announced to other agents. The freed slot and the released claims go to the chair and the peers as one - `${CLAUDE_SKILL_DIR}/../kvb-org-organize/scripts/news.py post ""`, - not as messages. Drop each removed item from the `kvb-org-rasci` register + `${CLAUDE_SKILL_DIR}/../kvb-org-radio/scripts/radio.py post ""`, + not as wakes. Drop each removed item from the `kvb-org-rasci` register with `--drop-artifact` and set the subagent's task `done` or `stopped`. 7. **Remove its temporary files**: logs, message files and scratch data that have served their purpose. Keep only the evidence the report cites, until diff --git a/skills/kvb-org-sunset/SKILL.md b/skills/kvb-org-sunset/SKILL.md index 38f6c15..49241e4 100644 --- a/skills/kvb-org-sunset/SKILL.md +++ b/skills/kvb-org-sunset/SKILL.md @@ -15,11 +15,13 @@ the state for evening, sunset and sunrise; every agent verifies a request with 1. `night.py set sunset` makes this session the active one and prints every other live session. -2. Message them in waves of three, so cold caches do not wake all at once - against the rate limit; the next wave follows the previous wave's replies - or 10 minutes. First line: "Operator ran kvb-org-sunset in : run - kvb-agent-sleep; verify with night.py status." A request to do less needs - no operator approval (the `kvb-org-organize` Peer protocol). +2. Wake them with `${CLAUDE_SKILL_DIR}/../kvb-org-radio/scripts/radio.py + send direct --to --wake` in waves of three, so cold caches do not + wake all at once against the rate limit; the next wave follows the + previous wave's replies or 10 minutes. First line: "Operator ran + kvb-org-sunset in : run kvb-agent-sleep; verify with night.py + status." A request to do less needs no operator approval (the + `kvb-org-organize` Peer protocol). 3. Once the replies are in, naming every session that did not answer, hand the operator one step through the `kvb-org-operator` skill: `/config` → "Messages from your other sessions" → `hold`. Held messages cost nothing, @@ -32,9 +34,9 @@ the state for evening, sunset and sunrise; every agent verifies a request with disk, CPU and RAM limits still apply. - **Offices**: the sleepers' claims stay theirs. Take only free work; a piece a sleeper holds waits for sunrise or the operator. -- **Messages**: no broadcasts and no peer questions; the Peer protocol's wait - is skipped. Status goes to `news.py post` (next to `watch.py`); sleepers - read it at sunrise at no cost. +- **Messages**: no wakes and no peer questions; the Peer protocol's wait is + skipped. Status goes to `radio.py post`; sleepers read it at sunrise + without a wake. - The `kvb-org-rasci` register keeps every row as it is. ## Output diff --git a/skills/kvb-skill-compile/SKILL.md b/skills/kvb-skill-compile/SKILL.md index c51a1de..094764e 100644 --- a/skills/kvb-skill-compile/SKILL.md +++ b/skills/kvb-skill-compile/SKILL.md @@ -60,7 +60,7 @@ and the prose diff. output. - Every script gets a unit test with a negative control shown once, run once `watch.py admit --kind test-nostack` (the `kvb-org-organize` skill) prints - `grant`; `make test` keeps the chair's grant. + `grant`; `make test` runs through `queue.py hold` (`kvb-org-queue`). - In another repository follow its agent rules (claims, worktree, branch); a file another line owns goes to that line through the `kvb-org-coordinate` skill. diff --git a/skills/kvb-skill-silence/SKILL.md b/skills/kvb-skill-silence/SKILL.md index 1a05c6c..e6eb962 100644 --- a/skills/kvb-skill-silence/SKILL.md +++ b/skills/kvb-skill-silence/SKILL.md @@ -19,8 +19,9 @@ not installed copies) and the skills repository. Measure before changing: longest descriptions, every SKILL.md over the cap. - Each own SKILL.md's word count, and what each registered hook prints per turn (settings files, read-only). -- The window's traffic: this session's `SendMessage` calls, the news - (`news.py show --all` of the `kvb-org-organize` skill), and subagent runs +- The window's traffic: the radio store (`radio.py show --all` of the + `kvb-org-radio` skill; wakes carry `"wake": true` in its `news.jsonl`), + this session's `SendMessage` calls, and subagent runs (`log.py report` of the `kvb-org-perform` skill). - Context re-read per turn, from the transcripts Claude Code keeps: `${CLAUDE_SKILL_DIR}/scripts/context.py --root ~/.claude/projects --days 7 @@ -36,9 +37,10 @@ not installed copies) and the skills repository. Measure before changing: side file the skill reads only when it needs them; no rule is cut. 3. **Messages**: every step that sends one is checked against the `kvb-org-organize` Peer protocol: status that asks nothing goes to - `news.py post`, polling peers becomes reading the council, the register or - the news, one batched message per peer, no reply to a message that asks - nothing, light runs admit themselves. + `radio.py post`, polling peers becomes reading the council, the register or + the radio, one batched message per peer, a wake only when the recipient + must act or answer, no reply to a message that asks nothing, light runs + admit themselves. 4. **Subagents**: their number follows the stakes, the brief names exact files and claims and caps the answer, a cheaper model only by the `kvb-org-perform` table. diff --git a/skills/kvb-skill-transcend/SKILL.md b/skills/kvb-skill-transcend/SKILL.md index 8fe8311..9b02d4c 100644 --- a/skills/kvb-skill-transcend/SKILL.md +++ b/skills/kvb-skill-transcend/SKILL.md @@ -53,8 +53,8 @@ or diff. `kvb-code-no-comments` skill does. - A carried script gets a unit test in the repository's `tests/` with a negative control, run once `watch.py admit --kind test-nostack` (the - `kvb-org-organize` skill) prints `grant`; `make test` keeps the chair's - grant. + `kvb-org-organize` skill) prints `grant`; `make test` runs through + `queue.py hold` (`kvb-org-queue`). - `transcend.py mark` every offered candidate with its verdict. - Leave the result uncommitted; committing is the `kvb-git-commit-next` skill's job.