Merge feature/kvb-org-swarm-unify into master

This commit is contained in:
Kevin Veen-Birkenbach committed 2026-11-11 08:45:47 +00:00
commit 275745ba1d
16 files changed
+118 -22

No files matched your search

+10 -2
View File
@@ -74,7 +74,8 @@ flowchart LR
check --> check_ansible[kvb-check-ansible]
check --> check_score[kvb-check-score]
org --> org_organize[kvb-org-organize]
org --> org_split[kvb-org-split]
org --> org_swarm[kvb-org-swarm]
org --> org_unify[kvb-org-unify]
org --> org_coordinate[kvb-org-coordinate]
org --> org_perform[kvb-org-perform]
org --> org_matrix[kvb-org-matrix]
@@ -188,7 +189,8 @@ flowchart LR
end
subgraph cat_org [org]
democracy[kvb-org-organize]
funnel[kvb-org-split]
funnel[kvb-org-swarm]
unify[kvb-org-unify]
coordinate[kvb-org-coordinate]
subagent_model[kvb-org-perform]
status_matrix[kvb-org-matrix]
@@ -297,6 +299,12 @@ flowchart LR
democracy --> merge_fix
democracy -. claim and release .-> rasci
funnel --> rasci
unify --> funnel
unify --> rasci
unify --> gate
unify --> branch_gc
unify --> cleanup
unify --> radio
status_matrix --> rasci
cleanup --> artefacts
artefacts --> rasci
+1 -1
View File
@@ -67,7 +67,7 @@ commit starts from zero.
only while a host process under it lives; a `docker compose exec` deploy
runs on in its container unguarded.
- 90/5 is allowed only on `gate: green` for the exact head: in
`kvb-check-score`, the `90/5` label and the `kvb-org-split` bar.
`kvb-check-score`, the `90/5` label and the `kvb-org-swarm` bar.
- Never edit `kvb-gate.json` by hand.
## Output
+1 -1
View File
@@ -35,7 +35,7 @@ steps 0 to 2; the judgement stays yours.
member's only when the first leaves part of the cluster unexplained. Pull
them even when the log looks conclusive: it only names the artifact; the
assertion, server-side exception and state dumps are inside.
5. **One funnel per cluster** via the `kvb-org-split` skill: one agent per
5. **One funnel per cluster** via the `kvb-org-swarm` skill: one agent per
claimed cluster, its own worktree and branch from the exact current HEAD,
that cluster its only concern, worked as `funnel.md` next to this file
says (dialectic, shared vs hidden causes, root fix); read it before
+2 -2
View File
@@ -14,7 +14,7 @@ skill's Rules apply here too.
the first, keep going until the job is actually green, not just past the
first error.
3. **Fix at the root**: apply the real fix for each proven root cause in the
sidetree, with a test and a negative control as the `kvb-org-split` skill
sidetree, with a test and a negative control as the `kvb-org-swarm` skill
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
@@ -23,7 +23,7 @@ skill's Rules apply here too.
`${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 %,
at the funnel's bar (the `kvb-org-swarm` skill's: fix confidence ≥ 90 %,
break risk ≤ 5 %, cost and time ≤ 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
+1 -1
View File
@@ -15,7 +15,7 @@ with the questions of `listen.md` next to this file. Keep the answers for the
session, never ask again, work only inside them; a candidate outside them
becomes a proposal. Invoked by another skill (kvb-ci-triage, kvb-ci-observe)
or an autonomous run: no questions; examine the handed-over log with the
defaults (10 s floor per run, the `kvb-org-split` skill's 90/5 bar as merge
defaults (10 s floor per run, the `kvb-org-swarm` skill's 90/5 bar as merge
bar, 60 minutes per delegated agent), ask only when an operator-only fact
blocks.
+1 -1
View File
@@ -28,7 +28,7 @@ Levers that usually pay:
## Delegating it
Hand every optimization to an agent through the `kvb-org-split` skill: one
Hand every optimization to an agent through the `kvb-org-swarm` skill: one
sidetree per candidate, branched from an exact commit, with a time cap and
"measure first, report the time split before implementing". One agent per
candidate, never more; the brief names the step, its log line and number, the
+1 -1
View File
@@ -15,7 +15,7 @@ checklist (multi-select) with suggestions, free text allowed:
3. **Which limits apply to optimizations.** Suggestions: the scope that may
be changed (files, roles, services); whether new dependencies, toolchains
or languages may be introduced; whether infrastructure or CI configuration
may change; the merge bar (default: the `kvb-org-split` skill's bar of fix
may change; the merge bar (default: the `kvb-org-swarm` skill's bar of fix
confidence ≥ 90 %, break risk ≤ 5 %, cost and time ≤ 100 %, over
100 % only after asking the operator, naming the cause); a time cap per
delegated agent (default 60 minutes).
+1 -1
View File
@@ -34,7 +34,7 @@ hotfix.py void --repo <worktree> --target <t> [--target ...]
## Before every deploy, merge or gate
1. `sync`: fetches, merges `origin/<default>`, then every branch up the funnel
chain the `kvb-org-split` skill records as `base` (open rows of this
chain the `kvb-org-swarm` skill records as `base` (open rows of this
repository), each with `--no-verify --no-edit`. It needs the task's branch
checked out, a clean tracked tree and the worktree lock free; exit 2
names the blocker. Exit 4: a merge conflicted and was aborted;
+3 -3
View File
@@ -23,7 +23,7 @@ request, so a red one blocks nothing else.
created once: `gh label create "in analysis" --color FBCA04 --description
"An agent analyses this issue"`, `gh label create "in progress" --color
1D76DB --description "An agent works on a fix"`.
4. **Solve** each with the `kvb-org-split` skill: claim `work/issue-<n>`,
4. **Solve** each with the `kvb-org-swarm` skill: claim `work/issue-<n>`,
enter it in the `kvb-org-rasci` register (objective: the issue fixed; key
results: a test that failed before and passes after, the pull request
open), branch `fix/<scope>/<n>` from the default branch in its own
@@ -40,10 +40,10 @@ request, so a red one blocks nothing else.
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
`radio.py post`. Below the split bar the proposal becomes a draft pull
`radio.py post`. Below the swarm 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
as `kvb-org-swarm` describes; the branch stays until the merge. An issue
dropped or handed on loses its label and gets a comment saying why.
## Output
+1 -1
View File
@@ -23,7 +23,7 @@ confirms it.
evidence, the score block, and one `Closes #<n>` line per issue the
branch fixes, each verified as the `kvb-git-issue-close` skill does.
5. **Confirm** with one `AskUserQuestion`: title (Conventional Commits),
base, state and labels. The state follows the bar of the `kvb-org-split`
base, state and labels. The state follows the bar of the `kvb-org-swarm`
skill (fix confidence ≥ 90 %, break risk ≤ 5 %, cost and time
≤ 100 %): ready at or above it, a draft with the residuals in the body
below it. A cost or time over 100 % goes into this question with
+1 -1
View File
@@ -11,7 +11,7 @@ holds:
- **`hotfix`**: the pull request targets the default branch and fixes a
failure on it, a red default-branch run or an issue that reproduces there;
name the run or issue.
- **`90/5`**: the pull request meets the bar of the `kvb-org-split` skill (fix
- **`90/5`**: the pull request meets the bar of the `kvb-org-swarm` skill (fix
confidence ≥ 90 %, break risk ≤ 5 %, cost and time ≤ 100 %; over
100 %, ask the operator first, naming the cause), from the
`kvb-check-score` block in its body or freshly assessed, and only when
+2 -2
View File
@@ -1,7 +1,7 @@
# Coordinating a failure or fix with peers
`kvb-org-coordinate`, `kvb-ci-triage`, `kvb-code-tune`, `kvb-org-split` and
`kvb-cleanup` follow these steps.
`kvb-org-coordinate`, `kvb-ci-triage`, `kvb-code-tune`, `kvb-org-swarm`,
`kvb-org-unify` and `kvb-cleanup` follow these steps.
1. **Look**: `council.py list`, the `kvb-org-rasci` register, the radio,
`hotfix.py match --line '<line>' --repo <worktree>` of the `kvb-git-hotfix`
@@ -1,11 +1,11 @@
---
name: kvb-org-split
name: kvb-org-swarm
description: >
Keep agent work in its own worktree until it meets the 90/5 bar
(kvb-check-score), else a proposal. Trigger when delegating or parallelizing.
---
# Funnel
# Swarm
The main line only receives changes that have earned it. Everything else stays
in a sidetree until it does, or leaves as a proposal.
@@ -52,9 +52,8 @@ in a sidetree until it does, or leaves as a proposal.
5. **Independent review.** Before any merge, run the `kvb-think-dialectic`
skill with skeptics who did not write the change, briefed the same way
(exact diff and claim, capped answer). A hole returns the change to stage 3.
6. **Merge.** At or above the bar, merge the sidetree branch by the
repository's commit rules, then re-verify on the main line with the
project's gate.
6. **Merge.** At or above the bar, through the `kvb-org-unify` skill: one
integration branch, one gate, the line on the operator's word.
7. **Tear down.** Read `teardown.md` next to this file before tearing down a
merged, proposed or abandoned sidetree.
File renamed without changes.
File renamed without changes.
+89
View File
@@ -0,0 +1,89 @@
---
name: kvb-org-unify
description: >
Unify a swarm's branches into one integration branch, gate it once, land it
on the operator's word, then clear worktrees, branches and leftovers.
Trigger on "unify", "swarm zusammenführen" or after a kvb-org-swarm round.
---
The `kvb-org-swarm` skill splits a goal into sidetrees; this skill brings them
home in one pass. Invoking it clears the merges into `unify/<goal>`; the line
receives nothing, and nothing is removed, without the operator's word in this
run. Never push: that stays with the operator (`kvb-git-push`).
## Step 0: claim
Claim `work/unify-<goal>` through the `kvb-org-organize` skill and enter it in
the `kvb-org-rasci` register: objective "every swarm branch of `<goal>` at the
bar on `<line>`", key results gate green, landed, cleaned up, overview posted.
`<line>` is the line the operator names, else the default branch.
## Step 1: collect
The register is the swarm's record (stage 2 of `kvb-org-swarm` sets `--branch`
and `--base`):
```bash
jq -r --arg base "<line>" 'to_entries[] | select(.value.base == $base and .value.branch) | [.key, .value.branch, .value.workdir // "-", .value.status] | @tsv' "${AGENTS_COUNCIL_ROOT:-/tmp/agents-council}/rasci.json"
```
Per branch: `git log --oneline <line>..<branch>` (empty: already merged, go
to step 5), `git status --porcelain` in its worktree, its latest
`kvb-check-score` block and its independent review (`kvb-org-swarm` stage 5).
A branch is **ready** only at the bar, clean, reviewed and with its owner's
claim released or the owner's yes by `radio.py post`; everything else is a
proposal with its reason: below the bar (the score), unreviewed, dirty, owner
busy.
## Step 2: integrate
A worktree in a released directory on `unify/<goal>` from `<line>`. Merge the
ready branches, highest register priority first, with
`git merge --no-ff --no-verify <branch>`. A conflict: `git merge --abort`, and
the branch becomes a proposal naming the conflicting files.
## Step 3: gate
The project's full gate on `unify/<goal>` through `queue.py hold`
(`kvb-check-gate`), and `security.py` over `<line>..unify/<goal>`
(`kvb-check-security`), logs under `/tmp`. Red: find the merge that broke it
(`git bisect start --first-parent`), rebuild the branch without it, which
becomes a proposal naming the failing test, and gate again.
## Step 4: land
Show the `kvb-check-score` commit table of `<line>..unify/<goal>` and every
proposal. On the operator's word: `git merge --ff-only unify/<goal>` in the
line's checkout; when the line moved meanwhile, merge it into `unify/<goal>`
and gate again first. The push goes to the operator as a `kvb-org-operator`
row.
## Step 5: clean up
Per merged branch and for `unify/<goal>`, the teardown of `kvb-org-swarm`
(`teardown.md`: jobs, stacks, container-owned files, worktree, register). A
proposal keeps its branch and loses worktree, stacks and temporary files. Then
the dry runs of `kvb-git-branch-gc` (`--merged-into <line>`) and the
inventory of `kvb-cleanup` for the swarm's logs, scratch and Docker leftovers,
merged into one table (area, item, size, owner, risk, what breaks if wrong)
and one `AskUserQuestion` pick; each skill removes only the picked items, by
its own execute rules. What the sandbox blocks becomes a `kvb-org-operator`
row.
## Step 6: report
Post the overview to the operator, not merged first:
`${CLAUDE_SKILL_DIR}/../kvb-org-radio/scripts/radio.py post --to Operator
"unify <goal>: <m> of <n> merged; NOT merged: <branch> (<reason>, closes with
<step>), ..."`. Set the register task `done`, or `stopped` while a key result
is open.
## Output
First line, when any branch stayed out: **⚠️ <k> of <n> swarm branches NOT
merged**. Then one table, not merged rows first:
| Branch | Task | Score | Verdict | Reason / what closes the gap |
Verdict: **⚠️ NOT MERGED** (proposal), ✅ merged, 🧹 removed. Below it the
cleanup result per area and the operator rows handed over.