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 <noreply@anthropic.com>
This commit is contained in:
Kevin Veen-BirkenbachandClaude Opus 5.5 committed 2026-11-04 17:07:24 +01:00
1 parent 27559dabc4
commit 6fa0311704
31 files changed
+126 -102

No files matched your search

+1 -1
View File
@@ -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 <sender> "relaxed: <what still runs>"`. Waking up is the
`kvb-agent-wakeup` skill.
+3 -2
View File
@@ -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: <handover path>`, 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
<sender> --wake` (its next wave waits on it), and end the turn. Offices
stay claimed and register rows unchanged.
## While asleep
+3 -3
View File
@@ -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 <sender>
Reply to a sunrise message through the radio, not a wake:
`${CLAUDE_SKILL_DIR}/../kvb-org-radio/scripts/radio.py post --to <sender>
"awake: <what resumes>"`.
+6 -6
View File
@@ -28,9 +28,9 @@ a new commit starts from zero.
the operator.
3. **Status**: `gate.py status --repo <root>`. `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 <root> --target <t> [--target ...] --log-dir /tmp/<slug> [--fail-regex <re> ...]
queue.py hold --kind <kind> --task <register task> -- gate.py run --repo <root> --target <t> [--target ...] --log-dir /tmp/<slug> [--fail-regex <re> ...]
```
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 <slug>, 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 <slug>, 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
+2 -2
View File
@@ -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
"<target>: <job> <failing line> -> <verdict>"`. Fold each newly fixed
failure into the baseline.
4. **Reschedule** by what you wait on: an active run that changes every few
+4 -3
View File
@@ -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 <run>` 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 '<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
+9 -4
View File
@@ -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 <kind>
--task <register task> -- <command>`, 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
"<text>"` (`--to <name>` per peer), then remove the sidetree.
+7 -7
View File
@@ -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 <chair>
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 <chair>
"<plan>"`.
## 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
<peer> --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 <peer>` tells each
skipped or failed item with its reason. `radio.py post --to <peer>` tells each
answering peer which removed items lay near its own.
+1 -1
View File
@@ -5,6 +5,6 @@ Cleanup by <own session name>. These unregistered items look like yours:
<item, size per line>
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.
```
+5 -2
View File
@@ -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 <kind>
--task <register task> -- make <target>`, which waits for the rule-based
grant and releases on exit.
Run the selected targets in the operator's order, one `make <target>` per
command so a failure is attributable. No `-k`, no reordering, no faster
+2 -2
View File
@@ -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.
+1 -1
View File
@@ -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
`<step> from <before> to under <after>`, 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 <holder>
(`${CLAUDE_SKILL_DIR}/../kvb-org-radio/scripts/radio.py post --to <holder>
"<text>"`), take the next cluster, never build a second optimization. A claim
ends with its release or the operator's reassignment.
+2 -2
View File
@@ -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
+3 -2
View File
@@ -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 "<finding>" --to
<name>`; `SendMessage` only when the peer must act or answer.
`${CLAUDE_SKILL_DIR}/../kvb-org-radio/scripts/radio.py post "<finding>" --to
<name>`; `radio.py send direct --to <name> --wake` only when the peer must act
or answer.
+1 -1
View File
@@ -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 "<text>"`, not
`${CLAUDE_SKILL_DIR}/../kvb-org-radio/scripts/radio.py post "<text>"`, not
as messages; then release the claim.
## Rules
+5 -5
View File
@@ -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 <n> --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
+2 -2
View File
@@ -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.
+4 -4
View File
@@ -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 <name> --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.
+6 -4
View File
@@ -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 <session> --wake` per printed session, since each must act, first
line:
"Operator ran kvb-org-evening in <name>: 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
+3 -2
View File
@@ -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.
+6 -4
View File
@@ -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
"<text>"`: "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.
+6 -5
View File
@@ -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 '<line>' --repo <worktree>` 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 <name> --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 <name>`: commit,
5. **Report** to the same peers through `radio.py post --to <name>`: 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.
+9 -7
View File
@@ -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 <office>`, 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 <office>`, 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
<name> --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 <office> --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.
+4 -4
View File
@@ -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 "<text>"`,
not as messages.
one `${CLAUDE_SKILL_DIR}/../kvb-org-radio/scripts/radio.py post "<text>"`,
not as wakes.
## Rules
+4 -3
View File
@@ -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.
+5 -5
View File
@@ -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 "<text>"`,
never into a message.
`${CLAUDE_SKILL_DIR}/../kvb-org-radio/scripts/radio.py post "<text>"`,
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
+2 -2
View File
@@ -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 "<text>"`,
not as messages. Drop each removed item from the `kvb-org-rasci` register
`${CLAUDE_SKILL_DIR}/../kvb-org-radio/scripts/radio.py post "<text>"`,
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
+10 -8
View File
@@ -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 <name>: 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 <name> --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 <name>: 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
+1 -1
View File
@@ -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.
+7 -5
View File
@@ -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.
+2 -2
View File
@@ -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.