diff --git a/README.md b/README.md index 403774d..8f31644 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/skills/kvb-check-gate/SKILL.md b/skills/kvb-check-gate/SKILL.md index 069a354..e0bb6ae 100644 --- a/skills/kvb-check-gate/SKILL.md +++ b/skills/kvb-check-gate/SKILL.md @@ -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 diff --git a/skills/kvb-ci-triage/SKILL.md b/skills/kvb-ci-triage/SKILL.md index 91a6574..002c2cc 100644 --- a/skills/kvb-ci-triage/SKILL.md +++ b/skills/kvb-ci-triage/SKILL.md @@ -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 diff --git a/skills/kvb-ci-triage/funnel.md b/skills/kvb-ci-triage/funnel.md index 6789e62..9ba07c0 100644 --- a/skills/kvb-ci-triage/funnel.md +++ b/skills/kvb-ci-triage/funnel.md @@ -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 --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 %, + 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 diff --git a/skills/kvb-code-tune/SKILL.md b/skills/kvb-code-tune/SKILL.md index 43bc690..bc957eb 100644 --- a/skills/kvb-code-tune/SKILL.md +++ b/skills/kvb-code-tune/SKILL.md @@ -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. diff --git a/skills/kvb-code-tune/candidate.md b/skills/kvb-code-tune/candidate.md index 247d31a..89f5cfd 100644 --- a/skills/kvb-code-tune/candidate.md +++ b/skills/kvb-code-tune/candidate.md @@ -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 diff --git a/skills/kvb-code-tune/listen.md b/skills/kvb-code-tune/listen.md index 3ff4788..54ceb99 100644 --- a/skills/kvb-code-tune/listen.md +++ b/skills/kvb-code-tune/listen.md @@ -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). diff --git a/skills/kvb-git-hotfix/SKILL.md b/skills/kvb-git-hotfix/SKILL.md index 526c7b6..7507d99 100644 --- a/skills/kvb-git-hotfix/SKILL.md +++ b/skills/kvb-git-hotfix/SKILL.md @@ -34,7 +34,7 @@ hotfix.py void --repo --target [--target ...] ## Before every deploy, merge or gate 1. `sync`: fetches, merges `origin/`, 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; diff --git a/skills/kvb-git-issue-solve/SKILL.md b/skills/kvb-git-issue-solve/SKILL.md index 280267a..500bc4c 100644 --- a/skills/kvb-git-issue-solve/SKILL.md +++ b/skills/kvb-git-issue-solve/SKILL.md @@ -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-`, +4. **Solve** each with the `kvb-org-swarm` skill: claim `work/issue-`, 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//` from the default branch in its own @@ -40,10 +40,10 @@ request, so a red one blocks nothing else. 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 - `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 diff --git a/skills/kvb-git-pr-create/SKILL.md b/skills/kvb-git-pr-create/SKILL.md index 3050021..595f903 100644 --- a/skills/kvb-git-pr-create/SKILL.md +++ b/skills/kvb-git-pr-create/SKILL.md @@ -23,7 +23,7 @@ confirms it. evidence, the score block, and one `Closes #` 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 diff --git a/skills/kvb-git-pr-label/SKILL.md b/skills/kvb-git-pr-label/SKILL.md index bf7f7cd..00a6a3c 100644 --- a/skills/kvb-git-pr-label/SKILL.md +++ b/skills/kvb-git-pr-label/SKILL.md @@ -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 diff --git a/skills/kvb-org-organize/peers.md b/skills/kvb-org-organize/peers.md index ca5e654..44c051a 100644 --- a/skills/kvb-org-organize/peers.md +++ b/skills/kvb-org-organize/peers.md @@ -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 '' --repo ` of the `kvb-git-hotfix` diff --git a/skills/kvb-org-split/SKILL.md b/skills/kvb-org-swarm/SKILL.md similarity index 95% rename from skills/kvb-org-split/SKILL.md rename to skills/kvb-org-swarm/SKILL.md index 47d5531..3f1aa68 100644 --- a/skills/kvb-org-split/SKILL.md +++ b/skills/kvb-org-swarm/SKILL.md @@ -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. diff --git a/skills/kvb-org-split/proposal.md b/skills/kvb-org-swarm/proposal.md similarity index 100% rename from skills/kvb-org-split/proposal.md rename to skills/kvb-org-swarm/proposal.md diff --git a/skills/kvb-org-split/teardown.md b/skills/kvb-org-swarm/teardown.md similarity index 100% rename from skills/kvb-org-split/teardown.md rename to skills/kvb-org-swarm/teardown.md diff --git a/skills/kvb-org-unify/SKILL.md b/skills/kvb-org-unify/SKILL.md new file mode 100644 index 0000000..0f24038 --- /dev/null +++ b/skills/kvb-org-unify/SKILL.md @@ -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/`; 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-` through the `kvb-org-organize` skill and enter it in +the `kvb-org-rasci` register: objective "every swarm branch of `` at the +bar on ``", key results gate green, landed, cleaned up, overview posted. +`` 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 "" '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 ..` (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/` from ``. Merge the +ready branches, highest register priority first, with +`git merge --no-ff --no-verify `. 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/` through `queue.py hold` +(`kvb-check-gate`), and `security.py` over `..unify/` +(`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 `..unify/` and every +proposal. On the operator's word: `git merge --ff-only unify/` in the +line's checkout; when the line moved meanwhile, merge it into `unify/` +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/`, 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 `) 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 : of merged; NOT merged: (, closes with +), ..."`. Set the register task `done`, or `stopped` while a key result +is open. + +## Output + +First line, when any branch stayed out: **⚠️ of 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.