diff --git a/README.md b/README.md index 1d64801..a07ab90 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,69 @@ Every skill is pinned in `skills-lock.json` for reproducible installs. First-party skills live under `skills/` and are layered on top of the locked ones at install time. Compatible with Claude Code, Codex, Gemini CLI, Cursor, Copilot, Windsurf, Cline, and other agents. +## Naming 🏷️ + +Every first-party skill is named `kvb--` with one of these categories: `think`, `create`, `code`, `ci`, `git`, `check`, `org`, `skills`. Only `kvb-cleanup` and `kvb-help` stand without a category. Names use `a-z`, `0-9` and single hyphens, at most 64 characters, and equal their directory name. `tests/test_naming.py` enforces all of it, including that the organigram below lists every skill under its category. + +## Organigram 🏛️ + +Every first-party skill under its category. + +```mermaid +flowchart LR + kvb((kvb)) + kvb --> think[think] + kvb --> create[create] + kvb --> code[code] + kvb --> ci[ci] + kvb --> git[git] + kvb --> check[check] + kvb --> org[org] + kvb --> skills[skills] + kvb --> none[no category] + think --> think_listen[kvb-think-listen] + think --> think_explain[kvb-think-explain] + think --> think_dialectic[kvb-think-dialectic] + think --> think_criticize[kvb-think-criticize] + create --> create_plan[kvb-create-plan] + create --> create_feature[kvb-create-feature] + code --> code_scope_guard[kvb-code-scope-guard] + code --> code_no_defaults[kvb-code-no-defaults] + code --> code_no_comments[kvb-code-no-comments] + code --> code_refactor[kvb-code-refactor] + code --> code_test[kvb-code-test] + code --> code_tune[kvb-code-tune] + ci --> ci_triage[kvb-ci-triage] + ci --> ci_artifacts[kvb-ci-artifacts] + ci --> ci_observe[kvb-ci-observe] + git --> git_commit_next[kvb-git-commit-next] + git --> git_commit_no_verify[kvb-git-commit-no-verify] + git --> git_merge_fix[kvb-git-merge-fix] + git --> git_branch_gc[kvb-git-branch-gc] + git --> git_changelog[kvb-git-changelog] + check --> check_legal[kvb-check-legal] + check --> check_security[kvb-check-security] + check --> check_principles[kvb-check-principles] + check --> check_confidence[kvb-check-confidence] + check --> check_break_risk[kvb-check-break-risk] + org --> org_organize[kvb-org-organize] + org --> org_split[kvb-org-split] + org --> org_coordinate[kvb-org-coordinate] + org --> org_perform[kvb-org-perform] + org --> org_matrix[kvb-org-matrix] + org --> org_robot[kvb-org-robot] + skills --> skills_dream[kvb-skills-dream] + skills --> skills_tune[kvb-skills-tune] + skills --> skills_auto[kvb-skills-auto] + skills --> skills_essence[kvb-skills-essence] + skills --> skills_shortcuts[kvb-skills-shortcuts] + none --> cleanup[kvb-cleanup] + none --> help[kvb-help] +``` + ## Skill map 🗺️ -How the first-party skills work together. A solid arrow means the skill invokes or relies on the other one; a dotted arrow means it fires automatically. Every skill that reports a result closes with the `confidence` block; those arrows are left out. The locked third-party skills (caveman, ponytail, archify) are not drawn. +How the first-party skills work together. A solid arrow means the skill invokes or relies on the other one; a dotted arrow means it fires automatically. Every skill that reports a result closes with the `kvb-check-confidence` block; those arrows are left out. The locked third-party skills (caveman, ponytail, archify) are not drawn. ```mermaid flowchart LR @@ -21,59 +81,61 @@ flowchart LR code_task([code task]) spawn([subagent spawn]) end - subgraph commit [Commit] - commit_next[commit-next] - commit_no_verify[commit-no-verify] - comments_clean[comments-clean] - advocate[advocate] - confidence[confidence] - break_risk[break-risk] - explain[explain] + subgraph cat_think [think] + active_listening[kvb-think-listen] + explain[kvb-think-explain] + dialectic[kvb-think-dialectic] + criticize[kvb-think-criticize] end - subgraph coordination [Coordination] - democracy[democracy] - coordinate[coordinate] - funnel[funnel] - cleanup[cleanup] - branch_gc[branch-gc] - subagent_model[subagent-model] + subgraph cat_create [create] + plan[kvb-create-plan] + auto_feature[kvb-create-feature] end - subgraph ci [CI] - observe[observe] - triage[triage] - ci_artifacts[ci-artifacts] - tune[tune] - merge_fix[merge-fix] + subgraph cat_code [code] + scope_guard[kvb-code-scope-guard] + no_defaults[kvb-code-no-defaults] + refactor[kvb-code-refactor] + test[kvb-code-test] + tune[kvb-code-tune] + comments_clean[kvb-code-no-comments] end - subgraph reasoning [Reasoning] - active_listening[active-listening] - dialectic[dialectic] - criticize[criticize] - sceptic[sceptic] - auto_feature[auto-feature] + subgraph cat_ci [ci] + triage[kvb-ci-triage] + ci_artifacts[kvb-ci-artifacts] + observe[kvb-ci-observe] end - subgraph autonomy [Autonomy] - plan[plan] - robot[robot] + subgraph cat_git [git] + commit_next[kvb-git-commit-next] + commit_no_verify[kvb-git-commit-no-verify] + merge_fix[kvb-git-merge-fix] + branch_gc[kvb-git-branch-gc] + changelog[kvb-git-changelog] end - subgraph self_improvement [Self-improvement] - dream[dream] - autotune[autotune] - autoskill[autoskill] - essence[essence] - shortcuts[shortcuts] + subgraph cat_check [check] + advocate[kvb-check-legal] + medusa[kvb-check-security] + sceptic[kvb-check-principles] + confidence[kvb-check-confidence] + break_risk[kvb-check-break-risk] end - subgraph quality [Quality] - test[test] - refactor[refactor] - no_defaults[no-defaults] - scope_guard[scope-guard] + subgraph cat_org [org] + democracy[kvb-org-organize] + funnel[kvb-org-split] + coordinate[kvb-org-coordinate] + subagent_model[kvb-org-perform] + status_matrix[kvb-org-matrix] + robot[kvb-org-robot] end - subgraph standalone [Standalone] - changelog[changelog] - help_skills[help-skills] - status_matrix[status-matrix] - medusa[medusa] + subgraph cat_skills [skills] + dream[kvb-skills-dream] + autotune[kvb-skills-tune] + autoskill[kvb-skills-auto] + essence[kvb-skills-essence] + shortcuts[kvb-skills-shortcuts] + end + subgraph cat_none [no category] + cleanup[kvb-cleanup] + help_skills[kvb-help] end commit_req -.-> commit_next @@ -163,7 +225,7 @@ Copy the skills into a specific project (`/.agents/skills` and `/.cl make project TARGET=/path/to/repo ``` -Both commands also patch the target's `.claude/settings.local.json` — the machine-local, untracked file, so a project's reviewed `.claude/settings.json` is never rewritten by an install: the caveman and ponytail plugins are enabled so their modes auto-activate on session start, and two reminder hooks are registered — `autotune` points you at `/autotune` at most once an hour, `dream` points you at `/dream` at most once every twelve hours per repository (stamped in that repository's git dir). A PreToolUse gate from the `democracy` skill blocks edits to files in a git worktree until the session holds a claim (`skills/democracy/scripts/council.py`), and its resource watch (`skills/democracy/scripts/watch.py`) measures disk, Docker and caches, cleans up low-risk data and blocks new heavy jobs before the disk runs out; it stays inactive until `~/.config/agents-council/config.json` exists. Two hooks of the `subagent-model` skill (`skills/subagent-model/scripts/log.py`) log every Agent spawn with its task class, model and effort, and store the quality feedback a sandboxed session prints, in `~/.local/state/agents-council/subagent-model.jsonl`. Existing settings are preserved. +Both commands also patch the target's `.claude/settings.local.json` — the machine-local, untracked file, so a project's reviewed `.claude/settings.json` is never rewritten by an install: the caveman and ponytail plugins are enabled so their modes auto-activate on session start, and two reminder hooks are registered — `kvb-skills-tune` points you at `/kvb-skills-tune` at most once an hour, `kvb-skills-dream` points you at `/kvb-skills-dream` at most once every twelve hours per repository (stamped in that repository's git dir). A PreToolUse gate from the `kvb-org-organize` skill blocks edits to files in a git worktree until the session holds a claim (`skills/kvb-org-organize/scripts/council.py`), and its resource watch (`skills/kvb-org-organize/scripts/watch.py`) measures disk, Docker and caches, cleans up low-risk data and blocks new heavy jobs before the disk runs out; it stays inactive until `~/.config/agents-council/config.json` exists. Two hooks of the `kvb-org-perform` skill (`skills/kvb-org-perform/scripts/log.py`) log every Agent spawn with its task class, model and effort, and store the quality feedback a sandboxed session prints, in `~/.local/state/agents-council/subagent-model.jsonl`. Existing settings are preserved. Restart your agent afterwards so it loads the new skills. diff --git a/scripts/enable-plugins.js b/scripts/enable-plugins.js index 93e3189..1a2d8b4 100644 --- a/scripts/enable-plugins.js +++ b/scripts/enable-plugins.js @@ -1,8 +1,8 @@ #!/usr/bin/env node // Enable the caveman and ponytail plugins in a Claude Code settings.json so -// their SessionStart hooks auto-activate both modes, register the autotune -// and dream reminder hooks, the democracy claim gate, the resource watch and the subagent-model log. Merges non-destructively: existing marketplaces, -// plugins and hooks are preserved, unparseable files are left untouched. +// their SessionStart hooks auto-activate both modes, register the kvb-skills-tune +// and kvb-skills-dream reminder hooks, the kvb-org-organize claim gate, the resource watch and the kvb-org-perform log. Merges non-destructively: existing marketplaces, +// plugins and hooks are preserved, hooks of renamed skills are repointed, unparseable files are left untouched. "use strict"; const fs = require("fs"); @@ -19,7 +19,14 @@ const MARKETPLACES = { ponytail: { source: { source: "github", repo: "DietrichGebert/ponytail" } }, }; const PLUGINS = { "caveman@caveman": true, "ponytail@ponytail": true }; -const REMINDERS = ["autotune", "dream"]; +const REMINDERS = ["kvb-skills-tune", "kvb-skills-dream"]; +const RENAMED = { + "autotune/hooks/reminder.sh": "kvb-skills-tune/hooks/reminder.sh", + "dream/hooks/reminder.sh": "kvb-skills-dream/hooks/reminder.sh", + "democracy/scripts/council.py": "kvb-org-organize/scripts/council.py", + "democracy/scripts/watch.py": "kvb-org-organize/scripts/watch.py", + "subagent-model/scripts/log.py": "kvb-org-perform/scripts/log.py", +}; let data = {}; if (fs.existsSync(settingsPath)) { @@ -41,6 +48,17 @@ for (const [name, entry] of Object.entries(MARKETPLACES)) { data.enabledPlugins = Object.assign(data.enabledPlugins || {}, PLUGINS); data.hooks = data.hooks || {}; +for (const entries of Object.values(data.hooks)) { + if (!Array.isArray(entries)) continue; + for (const entry of entries) { + for (const hook of entry.hooks || []) { + if (typeof hook.command !== "string") continue; + for (const [from, to] of Object.entries(RENAMED)) { + hook.command = hook.command.replace(`/skills/${from}`, `/skills/${to}`); + } + } + } +} data.hooks.UserPromptSubmit = data.hooks.UserPromptSubmit || []; const alreadyRegistered = JSON.stringify(data.hooks.UserPromptSubmit); for (const skill of REMINDERS) { @@ -52,8 +70,8 @@ for (const skill of REMINDERS) { } data.hooks.PreToolUse = data.hooks.PreToolUse || []; -if (!JSON.stringify(data.hooks.PreToolUse).includes("democracy/scripts/council.py")) { - const council = path.join(path.dirname(settingsPath), "skills", "democracy", "scripts", "council.py"); +if (!JSON.stringify(data.hooks.PreToolUse).includes("kvb-org-organize/scripts/council.py")) { + const council = path.join(path.dirname(settingsPath), "skills", "kvb-org-organize", "scripts", "council.py"); data.hooks.PreToolUse.push({ matcher: "Edit|Write|MultiEdit|NotebookEdit", hooks: [{ type: "command", command: `python3 ${JSON.stringify(council)} gate` }], @@ -61,11 +79,11 @@ if (!JSON.stringify(data.hooks.PreToolUse).includes("democracy/scripts/council.p } const SCRIPT_HOOKS = [ - ["democracy/scripts/watch.py", "UserPromptSubmit", null, "watch"], - ["democracy/scripts/watch.py", "PostToolUse", "Bash", "watch"], - ["democracy/scripts/watch.py", "PreToolUse", "Bash", "block"], - ["subagent-model/scripts/log.py", "PreToolUse", "Agent|Task", "spawn"], - ["subagent-model/scripts/log.py", "PostToolUse", "Bash", "persist"], + ["kvb-org-organize/scripts/watch.py", "UserPromptSubmit", null, "watch"], + ["kvb-org-organize/scripts/watch.py", "PostToolUse", "Bash", "watch"], + ["kvb-org-organize/scripts/watch.py", "PreToolUse", "Bash", "block"], + ["kvb-org-perform/scripts/log.py", "PreToolUse", "Agent|Task", "spawn"], + ["kvb-org-perform/scripts/log.py", "PostToolUse", "Bash", "persist"], ]; for (const [script, event, matcher, sub] of SCRIPT_HOOKS) { data.hooks[event] = data.hooks[event] || []; @@ -79,4 +97,4 @@ for (const [script, event, matcher, sub] of SCRIPT_HOOKS) { } fs.writeFileSync(settingsPath, JSON.stringify(data, null, 2) + "\n"); -console.log(`skills: enabled caveman + ponytail plugins, the ${REMINDERS.join(" + ")} reminders, the democracy claim gate, the resource watch and the subagent-model log in ${settingsPath}`); +console.log(`skills: enabled caveman + ponytail plugins, the ${REMINDERS.join(" + ")} reminders, the kvb-org-organize claim gate, the resource watch and the kvb-org-perform log in ${settingsPath}`); diff --git a/skills/coordinate/SKILL.md b/skills/coordinate/SKILL.md deleted file mode 100644 index 2f12116..0000000 --- a/skills/coordinate/SKILL.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -name: coordinate -description: > - Coordinate a failure or fix with the agents on related branches through - merges: claim, ask, report. Trigger on /coordinate and when a fix touches - code other branches share. ---- - -Run the `democracy` skill's **Lineage** and **Peer protocol** sections for the -failure or fix at hand. They hold the whole procedure; this skill only keeps -`/coordinate` working. diff --git a/skills/break-risk/SKILL.md b/skills/kvb-check-break-risk/SKILL.md similarity index 96% rename from skills/break-risk/SKILL.md rename to skills/kvb-check-break-risk/SKILL.md index fc34bf2..5a19989 100644 --- a/skills/break-risk/SKILL.md +++ b/skills/kvb-check-break-risk/SKILL.md @@ -1,8 +1,8 @@ --- -name: break-risk +name: kvb-check-break-risk description: > Derive the break-risk percentage from measurement, not feel. Called by - `confidence` on every report; also when the operator asks "what could this + `kvb-check-confidence` on every report; also when the operator asks "what could this break?" or names a break-risk threshold. --- diff --git a/skills/break-risk/reference.md b/skills/kvb-check-break-risk/reference.md similarity index 98% rename from skills/break-risk/reference.md rename to skills/kvb-check-break-risk/reference.md index 514d945..90bbbc4 100644 --- a/skills/break-risk/reference.md +++ b/skills/kvb-check-break-risk/reference.md @@ -1,6 +1,6 @@ # Break risk: the method in detail -Each step of the `break-risk` skill, with the trap it defeats. +Each step of the `kvb-check-break-risk` skill, with the trap it defeats. ## The consumer question, first and always diff --git a/skills/confidence/SKILL.md b/skills/kvb-check-confidence/SKILL.md similarity index 79% rename from skills/confidence/SKILL.md rename to skills/kvb-check-confidence/SKILL.md index 5018bcc..b495d1f 100644 --- a/skills/confidence/SKILL.md +++ b/skills/kvb-check-confidence/SKILL.md @@ -1,5 +1,5 @@ --- -name: confidence +name: kvb-check-confidence description: > Report calibrated fix confidence and break risk unprompted whenever you stage changes, declare a fix or bundle ready, or summarize work the operator @@ -9,12 +9,12 @@ description: > Every stage summary, fix report, or ready-to-commit bundle ends with a confidence block. -Invoke the `break-risk` skill every time, before writing the block; this skill +Invoke the `kvb-check-break-risk` skill every time, before writing the block; this skill reports the number it derives and never estimates one itself. 1. **Fix confidence** (percent): probability the change does what it claims. **Break risk** (percent): probability it breaks anything else, - derived via the `break-risk` skill. Two separate numbers, never one + derived via the `kvb-check-break-risk` skill. Two separate numbers, never one blended figure. 2. **Evidence**: the strongest proof lines only — what was executed, reproduced, enumerated, or read from authoritative source. Distinguish @@ -33,8 +33,8 @@ Calibration rules: (test, reproduction, live probe) justifies more. A threshold the operator named ("95% confidence, break risk ≤5%") is a gate on -the work, handled as the `break-risk` skill's last section says, for both +the work, handled as the `kvb-check-break-risk` skill's last section says, for both numbers. -Objective: the `autotune` skill's **Objective** section. Two figures with their residuals replace a +Objective: the `kvb-skills-tune` skill's **Objective** section. Two figures with their residuals replace a hedging paragraph and save the operator a verification round trip. diff --git a/skills/advocate/SKILL.md b/skills/kvb-check-legal/SKILL.md similarity index 88% rename from skills/advocate/SKILL.md rename to skills/kvb-check-legal/SKILL.md index ad16352..b4ddf05 100644 --- a/skills/advocate/SKILL.md +++ b/skills/kvb-check-legal/SKILL.md @@ -1,24 +1,24 @@ --- -name: advocate +name: kvb-check-legal description: > Check a commit for legal soundness: licence compatibility of added code and dependencies, attribution, copied snippets, GDPR, trademarks. Run - AUTOMATICALLY before every commit the operator requests; also on /advocate + AUTOMATICALLY before every commit the operator requests; also on /kvb-check-legal [ref|range], "rechtlich prüfen", "lizenz prüfen". --- The stance is the project's counsel: find what would make the change unlawful to distribute before it is distributed. This is not legal advice but a reading of the licence texts, with German and EU law where jurisdiction matters; every -report says so in one line. Leaked secrets belong to `medusa`, engineering -principles to `sceptic`. +report says so in one line. Leaked secrets belong to `kvb-check-security`, engineering +principles to `kvb-check-principles`. ## Target - Before a commit: the staging index (`git diff --cached`, plus every added or changed file in full where origin or licence is in question). -- `/advocate ` or `/advocate ..`: that commit or range. -- `/advocate` alone: the index if it is non-empty, else `HEAD`. +- `/kvb-check-legal ` or `/kvb-check-legal ..`: that commit or range. +- `/kvb-check-legal` alone: the index if it is non-empty, else `HEAD`. ## Fast exit @@ -56,7 +56,7 @@ attribution, copied snippets, data protection, trademarks). ## Blockers stop the commit -Harden every blocker with the `dialectic` skill before reporting it. The +Harden every blocker with the `kvb-think-dialectic` skill before reporting it. The antithesis tries: the code is trivial or the operator's own; the dependency is build- or test-only and never distributed; an exception applies (linking or Classpath exception, dual licensing, a licence grant in the issue or commit @@ -75,7 +75,7 @@ the operator's language). Then one table, blockers first: `Evidence` is `proven` (licence text, metadata, or file read; cite path:line or the registry URL) or `derived` (inferred). Close with the verdict (commit -stops or proceeds) and the `confidence` skill's numbers. +stops or proceeds) and the `kvb-check-confidence` skill's numbers. ## Rules diff --git a/skills/advocate/checks.md b/skills/kvb-check-legal/checks.md similarity index 96% rename from skills/advocate/checks.md rename to skills/kvb-check-legal/checks.md index 84c2929..12f2f9a 100644 --- a/skills/advocate/checks.md +++ b/skills/kvb-check-legal/checks.md @@ -1,6 +1,6 @@ # Advocate: the checks -Apply each check to a target the `advocate` skill found in scope. +Apply each check to a target the `kvb-check-legal` skill found in scope. 1. **Inbound code** - every file or block of foreign origin carries a licence that the project licence can absorb in the direction of distribution. GPL diff --git a/skills/sceptic/SKILL.md b/skills/kvb-check-principles/SKILL.md similarity index 87% rename from skills/sceptic/SKILL.md rename to skills/kvb-check-principles/SKILL.md index 2af38d6..53041af 100644 --- a/skills/sceptic/SKILL.md +++ b/skills/kvb-check-principles/SKILL.md @@ -1,15 +1,15 @@ --- -name: sceptic +name: kvb-check-principles description: > Analyse a repository, path or diff with a hostile eye for violated principles: SPOT, DRY, KISS, SRP, security at trust boundaries. Trigger on - /sceptic, "sei skeptisch", "kritische analyse", "review the architecture", + /kvb-check-principles, "sei skeptisch", "kritische analyse", "review the architecture", or "what is wrong with the code". --- The stance is adversarial: the code is guilty until its structure proves otherwise. This skill hunts violated principles, not bugs (`code-review`), -not bloat (`ponytail-audit`), not leaked secrets (`medusa`). Read-only — +not bloat (`ponytail-audit`), not leaked secrets (`kvb-check-security`). Read-only — report the findings, change nothing unless the operator asks afterwards. ## Scope @@ -44,7 +44,7 @@ Apply each independently; a finding belongs to exactly one: findings only. 6. **Silent defaults** — a fallback that substitutes a guess for a value the caller failed to supply, turning a misconfiguration into wrong behaviour - instead of a loud failure. See the `no-defaults` skill. + instead of a loud failure. See the `kvb-code-no-defaults` skill. ## Method @@ -55,7 +55,7 @@ Apply each independently; a finding belongs to exactly one: which value drifts, which caller breaks, which input reaches which sink. A finding whose worst case is "feels wrong" gets deleted, not softened. - **Attack your own finding.** For anything consequential or expensive to - fix, run it through the `dialectic` skill before reporting it — the + fix, run it through the `kvb-think-dialectic` skill before reporting it — the strongest counter-argument is usually "these two are not the same knowledge" or "this boundary is already checked upstream". - **Respect intent.** A deliberate marker (`ponytail:`, a documented @@ -69,7 +69,7 @@ One ranked table, worst blast radius first: | Severity | Principle | Location | What is wrong | Smallest fix | Then three closing lines at most: what the scope excluded, which findings -survived `dialectic` versus which are still derived-only, and the single +survived `kvb-think-dialectic` versus which are still derived-only, and the single finding to fix first. No per-finding paragraphs — the operator asks when a row needs unpacking. @@ -78,7 +78,7 @@ row needs unpacking. - Never report formatting, naming taste, or missing comments; a linter owns those and the operator did not ask. - Distinguish proven (grepped, read, reproduced) from derived (reasoned - statically) per finding, and close with the `confidence` skill's numbers + statically) per finding, and close with the `kvb-check-confidence` skill's numbers for the audit as a whole. - No silent caps: if you ranked and cut, say how many findings were dropped and by what rule. diff --git a/skills/medusa/SKILL.md b/skills/kvb-check-security/SKILL.md similarity index 96% rename from skills/medusa/SKILL.md rename to skills/kvb-check-security/SKILL.md index 83d4b94..17793e1 100644 --- a/skills/medusa/SKILL.md +++ b/skills/kvb-check-security/SKILL.md @@ -1,9 +1,9 @@ --- -name: medusa +name: kvb-check-security description: > Run the MEDUSA security scanner (medusa-security, PyPI) on a repository, working tree or secret stores. Use for security scans, vetting a repo before - cloning, leaked-secret detection in chat or shell history, or /medusa. + cloning, leaked-secret detection in chat or shell history, or /kvb-check-security. Defensive only. --- diff --git a/skills/ci-artifacts/SKILL.md b/skills/kvb-ci-artifacts/SKILL.md similarity index 99% rename from skills/ci-artifacts/SKILL.md rename to skills/kvb-ci-artifacts/SKILL.md index f280425..51edf9d 100644 --- a/skills/ci-artifacts/SKILL.md +++ b/skills/kvb-ci-artifacts/SKILL.md @@ -1,5 +1,5 @@ --- -name: ci-artifacts +name: kvb-ci-artifacts description: > Get the evidence out of a CI run: failed job logs (also mid-run) clustered by error line, and the artifacts that hold the cause. Trigger whenever a CI diff --git a/skills/ci-artifacts/scripts/ci_failures.py b/skills/kvb-ci-artifacts/scripts/ci_failures.py similarity index 100% rename from skills/ci-artifacts/scripts/ci_failures.py rename to skills/kvb-ci-artifacts/scripts/ci_failures.py diff --git a/skills/observe/SKILL.md b/skills/kvb-ci-observe/SKILL.md similarity index 83% rename from skills/observe/SKILL.md rename to skills/kvb-ci-observe/SKILL.md index 4d0aef1..3f2184a 100644 --- a/skills/observe/SKILL.md +++ b/skills/kvb-ci-observe/SKILL.md @@ -1,8 +1,8 @@ --- -name: observe +name: kvb-ci-observe description: > Watch a named target (CI run, pipeline, build, log) on a cadence and triage - new failures as they appear. Trigger on /observe or when the + new failures as they appear. Trigger on /kvb-ci-observe or when the operator asks to keep monitoring and fix regressions. --- @@ -23,18 +23,18 @@ baseline, so a stale baseline re-triages solved failures. Drive this with `/loop` in dynamic mode (no fixed interval unless the operator gave one): after each observation, schedule the next wake-up yourself and pass -the same `/observe` prompt back so the next firing repeats the watch. +the same `/kvb-ci-observe` prompt back so the next firing repeats the watch. 1. **Poll the target.** Pull its current state (job list, check conclusions, the - log's tail); for a GitHub Actions run, the ci-artifacts skill's - `ci_failures.py `. Enumerate the failures exactly as the `triage` skill's step 1 + log's tail); for a GitHub Actions run, the kvb-ci-artifacts skill's + `ci_failures.py `. Enumerate the failures exactly as the `kvb-ci-triage` skill's step 1 does: failure, cancelled, timed-out; a downstream aggregate that fails only because an upstream did is not its own failure. 2. **Diff against the baseline.** A failure is *new* only if it is not in the baseline and was not already triaged this session. If nothing is new, log one short line ("still green" / "N known failures, no change") and reschedule. -3. **Triage each new failure.** Invoke the `triage` skill on the new set only — - which applies `dialectic` per failing job to a ~99% root cause and a real +3. **Triage each new failure.** Invoke the `kvb-ci-triage` skill on the new set only — + which applies `kvb-think-dialectic` per failing job to a ~99% root cause and a real fix. Never mask (no retry-until-pass, no disabled check, no soft-skip). Fold each newly fixed failure into the baseline so it is not re-triaged. 4. **Reschedule.** Pick the next delay from what you are waiting on: an active @@ -50,7 +50,7 @@ the same `/observe` prompt back so the next firing repeats the watch. notification instead of polling for it; reserve the timed wake-up for external state the harness cannot see (a remote CI run, a deploy queue). - Executed evidence beats reasoning: read the actual failing log line and the - artifact, not the job title — triage and dialectic carry this through. + artifact, not the job title — kvb-ci-triage and kvb-think-dialectic carry this through. - One baseline, updated in place: dedup every observation against all failures seen so far, or a flaky-then-fixed failure reappears every cycle and the watch never converges. diff --git a/skills/triage/SKILL.md b/skills/kvb-ci-triage/SKILL.md similarity index 90% rename from skills/triage/SKILL.md rename to skills/kvb-ci-triage/SKILL.md index 5f803d2..7debe12 100644 --- a/skills/triage/SKILL.md +++ b/skills/kvb-ci-triage/SKILL.md @@ -1,5 +1,5 @@ --- -name: triage +name: kvb-ci-triage description: > Triage a failing CI run, pipeline or job set to a verified root cause and a real fix, one cluster per worktree. Trigger when a build, test or deploy @@ -12,7 +12,7 @@ root cause is proven. ## Procedure -For a GitHub Actions run, the ci-artifacts skill's `ci_failures.py ` +For a GitHub Actions run, the kvb-ci-artifacts skill's `ci_failures.py ` does the mechanics of steps 0 to 2 in one call: distance to HEAD, the failed jobs' logs, and a first clustering. The judgement in those steps stays yours. @@ -37,11 +37,11 @@ jobs' logs, and a first clustering. The judgement in those steps stays yours. actual failing line, not by job name. Jobs whose messages differ in anything but the interpolated identifiers (host, app, port, path) belong in separate clusters. -3. **Coordinate every cluster.** Run the `democracy` skill's Lineage and Peer +3. **Coordinate every cluster.** Run the `kvb-org-organize` skill's Lineage and Peer protocol for each cluster before fixing it: claim it, ask the lineage whether someone already fixes it, and take their fix or keep yours. Keep investigating while you wait for answers. -4. **Download artifacts per cluster.** Use the `ci-artifacts` skill for the +4. **Download artifacts per cluster.** Use the `kvb-ci-artifacts` skill for the mechanics — it covers per-job logs while a run is still in progress, which bundle to pull, and the grep hygiene that keeps a false positive from becoming a root cause. For each cluster, fetch every artifact of @@ -53,7 +53,7 @@ jobs' logs, and a first clustering. The judgement in those steps stays yours. log looks conclusive, because a log that explains the symptom rarely explains the cause. 5. **One funnel per cluster.** Hand every cluster you claimed in step 3 to the - `funnel` skill: one agent per cluster, working in its own worktree on its own + `kvb-org-split` skill: one agent per cluster, working in its own worktree on its own branch created from the exact current HEAD, with that cluster as its only concern, the artifact paths of step 4 in its brief and a time cap for its interim report. @@ -61,7 +61,7 @@ jobs' logs, and a first clustering. The judgement in those steps stays yours. another cluster's work or under a running gate or deploy. Run clusters in parallel only when their fixes touch different files and the machine has room. A split cluster (step 7) gets a funnel of its own. -6. **Dialectic per cluster.** For EACH cluster, invoke the `dialectic` skill: +6. **Dialectic per cluster.** For EACH cluster, invoke the `kvb-think-dialectic` skill: form a thesis about the root cause from evidence (the job log, its artifacts, the code at the run's commit, git history), attack it with independent skeptics, and iterate to a ~99% thesis. @@ -71,18 +71,18 @@ jobs' logs, and a first clustering. The judgement in those steps stays yours. is actually green, not just past the first error. 8. **Fix at the root, through the funnel.** Apply the real fix for each proven root cause in the cluster's sidetree, with a test and a negative control as - the `funnel` skill demands. The fix enters the main line only at the funnel's + the `kvb-org-split` skill demands. The fix enters the main line only at the funnel's bar (at least 90 % fix confidence, under 5 % break risk) 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, every proposal, and - every abandoned attempt to the same agents through the `democracy` Peer protocol, + every abandoned attempt to the same agents through the `kvb-org-organize` Peer protocol, then remove the sidetree. 9. **Tune what ran out of time.** Only for a cluster whose jobs died on their time budget (timed out, or cancelled by the runner's limit), or when the - operator asks: hand the job log that ran furthest to the `tune` skill. Its + operator asks: hand the job log that ran furthest to the `kvb-code-tune` skill. Its candidates run through funnels of their own, separate from the cluster's fix sidetree, and never delay or block the fix. 10. **Follow the run.** While the run is still in progress, re-check it diff --git a/skills/cleanup/SKILL.md b/skills/kvb-cleanup/SKILL.md similarity index 95% rename from skills/cleanup/SKILL.md rename to skills/kvb-cleanup/SKILL.md index 8e7f6dc..bf7134b 100644 --- a/skills/cleanup/SKILL.md +++ b/skills/kvb-cleanup/SKILL.md @@ -1,9 +1,9 @@ --- -name: cleanup +name: kvb-cleanup description: > Free disk space agents filled: ask peer sessions what they still need, inventory /tmp, Docker and agent dirs, and delete only what the operator - picks. Trigger on /cleanup, "aufräumen", "bereinigen", "platte voll", "no + picks. Trigger on /kvb-cleanup, "aufräumen", "bereinigen", "platte voll", "no space left on device". --- @@ -12,10 +12,10 @@ its owner, its size, and its risk. ## Step 0: the resource chair -Shared resources belong to the resource chair of the `democracy` skill. If +Shared resources belong to the resource chair of the `kvb-org-organize` skill. If another session holds the chair, send it the cleanup request and stop, unless the operator ordered the cleanup in this session; then tell the chair before -step 1, so its grants and queue stay consistent. The `democracy` resource +step 1, so its grants and queue stay consistent. The `kvb-org-organize` resource watch already runs the configured low-risk cleanup at its stop threshold; this skill covers everything that needs the operator's pick. @@ -59,7 +59,7 @@ Read-only, in parallel, sizes included: - **Other agent dirs**: package and tool caches (pip, npm, pre-commit, act, gh, buildx), worktrees with `git status --short` and whether their branch is merged or pushed, Ansible and build temp dirs. With `pkgmgr` installed, - merged branches and worktrees go to the `branch-gc` skill instead. + merged branches and worktrees go to the `kvb-git-branch-gc` skill instead. - **Live use**: open handles (`fuser`, `lsof`) and running processes by name only (`ps -o pid,etime,comm`). Never print full command lines or environments: process arguments carry credentials. A sandboxed agent often @@ -152,7 +152,7 @@ ticked items. Revise repeats call 1; nothing is deleted before `Execute`. free space: not for a priority slot, not at a disk stop. Free idle items, ask the operator for an exception, or wait; an owner's own disk guard only alerts the chair, and only the operator can order a running job down. - A hung job is not freed through cleanup: the `democracy` skill's hang rule + A hung job is not freed through cleanup: the `kvb-org-organize` skill's hang rule lets only its owner end it. - Idle running stacks go down through the project's teardown target, never by removing their containers or volumes underneath them. diff --git a/skills/comments-clean/SKILL.md b/skills/kvb-code-no-comments/SKILL.md similarity index 93% rename from skills/comments-clean/SKILL.md rename to skills/kvb-code-no-comments/SKILL.md index 5d41c8d..f7124a3 100644 --- a/skills/comments-clean/SKILL.md +++ b/skills/kvb-code-no-comments/SKILL.md @@ -1,10 +1,10 @@ --- -name: comments-clean +name: kvb-code-no-comments description: > Purge explanatory comments from staged and unstaged changes. Run AUTOMATICALLY before every commit or stage request (commit, commit no-verify, stage next, socon, sobu, socobu, "commite ..."); also on - /comments-clean or comment complaints. + /kvb-code-no-comments or comment complaints. --- When the operator asks to commit or stage, run this audit first and only @@ -32,7 +32,7 @@ added lines only) and delete every explanatory comment: both the lint and the language parser can pass over code that no longer executes. Diff against the pre-edit revision (`git show HEAD:`) and confirm that only comment lines left. -5. Do not stage in order to run a check (the `commit-next` skill's step 4 +5. Do not stage in order to run a check (the `kvb-git-commit-next` skill's step 4 says why). Re-stage after the audit exactly the files that were staged before it. 6. Penalty: if this audit finds anything you wrote yourself, admit it in diff --git a/skills/no-defaults/SKILL.md b/skills/kvb-code-no-defaults/SKILL.md similarity index 99% rename from skills/no-defaults/SKILL.md rename to skills/kvb-code-no-defaults/SKILL.md index 10a39c4..f4f2c41 100644 --- a/skills/no-defaults/SKILL.md +++ b/skills/kvb-code-no-defaults/SKILL.md @@ -1,5 +1,5 @@ --- -name: no-defaults +name: kvb-code-no-defaults description: > Forbid default values for parameters, settings and environment lookups; demand explicit values and fail loudly. Apply AUTOMATICALLY on every task diff --git a/skills/refactor/SKILL.md b/skills/kvb-code-refactor/SKILL.md similarity index 96% rename from skills/refactor/SKILL.md rename to skills/kvb-code-refactor/SKILL.md index 31bdb64..2f9e307 100644 --- a/skills/refactor/SKILL.md +++ b/skills/kvb-code-refactor/SKILL.md @@ -1,8 +1,8 @@ --- -name: refactor +name: kvb-code-refactor description: > Refactor every uncommitted file (staged, unstaged, untracked) up to the - project's standards without changing behaviour. Trigger on /refactor or when + project's standards without changing behaviour. Trigger on /kvb-code-refactor or when the operator asks to clean up, tidy or polish the current changes. --- @@ -80,7 +80,7 @@ Concretely: returning early; replace magic values with a named constant at its use site. - **Errors**: never widen a caught exception, never swallow one, never remove a validation or a security check to make the code shorter. -- **Comments**: invoke the `comments-clean` skill rather than reimplementing its +- **Comments**: invoke the `kvb-code-no-comments` skill rather than reimplementing its rules here. Do not reformat regions you have no substantive fix for - cosmetic churn buries diff --git a/skills/scope-guard/SKILL.md b/skills/kvb-code-scope-guard/SKILL.md similarity index 98% rename from skills/scope-guard/SKILL.md rename to skills/kvb-code-scope-guard/SKILL.md index 794ee90..4c6a355 100644 --- a/skills/scope-guard/SKILL.md +++ b/skills/kvb-code-scope-guard/SKILL.md @@ -1,5 +1,5 @@ --- -name: scope-guard +name: kvb-code-scope-guard description: > Deliver exactly what was asked and nothing more. Trigger on every task that creates files, commands or commits, on unreviewed autonomous runs, on diff --git a/skills/test/SKILL.md b/skills/kvb-code-test/SKILL.md similarity index 91% rename from skills/test/SKILL.md rename to skills/kvb-code-test/SKILL.md index b29572d..296d01d 100644 --- a/skills/test/SKILL.md +++ b/skills/kvb-code-test/SKILL.md @@ -1,8 +1,8 @@ --- -name: test +name: kvb-code-test description: > Discover the Makefile's test targets, let the operator pick, run and report; - fix mode loops until green. Trigger on /test, /test --fix, or when the + fix mode loops until green. Trigger on /kvb-code-test, /kvb-code-test --fix, or when the operator asks to run the tests, make them pass, or get the suite green. --- @@ -73,7 +73,7 @@ quoted verbatim. Never paraphrase a failure. Then one line with the exact command to reproduce the failure alone. Do not fix what failed unless the operator asks - report first. A request to -make the tests pass, fix them, or get the suite green (`/test --fix`) switches +make the tests pass, fix them, or get the suite green (`/kvb-code-test --fix`) switches to fix mode. ## Fix mode @@ -87,8 +87,8 @@ after three simultaneous changes proves nothing about which one mattered. - **Run** the failing target alone, the fastest command that reproduces the failure. Widen back to the full selection only when that target is green. - **Diagnose** from the actual error output before touching a file. Apply the - `triage` skill to reach a verified root cause; for a cause still unclear - after one look, apply `dialectic` rather than guessing twice. Say in one line + `kvb-ci-triage` skill to reach a verified root cause; for a cause still unclear + after one look, apply `kvb-think-dialectic` rather than guessing twice. Say in one line which side is wrong: - **Code**: the test states the intended behaviour. Fix the code. - **Test**: it encodes an outdated or incorrect expectation. Fix it only with @@ -98,7 +98,7 @@ after three simultaneous changes proves nothing about which one mattered. unbuilt artefact. Fix the environment or report it; do not patch code around it. - **Fix** with the smallest change that addresses the root cause, in the - project's idioms and under the `no-defaults` and `comments-clean` rules. + project's idioms and under the `kvb-code-no-defaults` and `kvb-code-no-comments` rules. Forbidden without explicit operator approval: deleting, skipping, `xfail`-ing or commenting out a failing test; loosening an assertion to what the code produces; swallowing the exception the test surfaces; retries, sleeps or @@ -126,5 +126,5 @@ Emit one line per iteration: target, failure, hypothesis, change. The final report gives per iteration what failed, the root cause, the fix and the result; the final state of every selected target with the verbatim output of anything still failing; everything deliberately not done; and the command -reproducing the final state. State confidence per the `confidence` skill. Do +reproducing the final state. State confidence per the `kvb-check-confidence` skill. Do not commit unless the operator asked for a commit. diff --git a/skills/tune/SKILL.md b/skills/kvb-code-tune/SKILL.md similarity index 93% rename from skills/tune/SKILL.md rename to skills/kvb-code-tune/SKILL.md index b315820..a995c8d 100644 --- a/skills/tune/SKILL.md +++ b/skills/kvb-code-tune/SKILL.md @@ -1,8 +1,8 @@ --- -name: tune +name: kvb-code-tune description: > Find and apply performance optimizations (CI, deploy, build, gate, hot - paths) without reducing logic, coverage or correctness. Trigger on /tune, + paths) without reducing logic, coverage or correctness. Trigger on /kvb-code-tune, when a job dies on its time budget, when a pipeline or deploy grows slower, or asked where time goes. --- @@ -14,7 +14,7 @@ correctness counts as a speed-up.** ## Once per session: listen first -The first time this skill runs in a session, invoke the `active-listening` +The first time this skill runs in a session, invoke the `kvb-think-listen` skill before measuring anything, and ask three questions through the host's structured question mechanism. Offer each as a checklist (multi-select) with suggestions, and allow free text: @@ -31,13 +31,14 @@ suggestions, and allow free text: 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 `funnel` skill's 90 % confidence and + change; the merge bar (default: the `kvb-org-split` skill's 90 % confidence and under 5 % break risk); a time cap per delegated agent (default 60 minutes). Keep the answers for the rest of the session and do not ask again. Work only inside them; a candidate outside them becomes a proposal. -When another skill (triage, observe) or an autonomous run invoked tune, skip +When another skill (kvb-ci-triage, kvb-ci-observe) or an autonomous run invoked +this skill, skip the questions: examine the handed-over log, apply the defaults above, and ask only when an operator-only fact blocks. @@ -92,7 +93,7 @@ Discard a before/after pair, not just its noise, when: ## Before you optimize -- **Search every branch** (the merge-fix skill's `find_fix.py -S --path `) for a change +- **Search every branch** (the kvb-git-merge-fix skill's `find_fix.py -S --path `) for a change that already removes or reshapes the step. A fix on a sibling branch can make the whole candidate worth zero. - A step that is long by design (a backup and restore drill, an end-to-end @@ -106,10 +107,10 @@ Discard a before/after pair, not just its noise, when: A cost cluster is one place the time goes: one step, one hot path, one repeated call, named by its log line and its number. Before investigating or -implementing a cluster, run the `democracy` skill's Peer protocol for it with +implementing a cluster, run the `kvb-org-organize` skill's Peer protocol for it with every agent session on this machine, not only the branch lineage. -- **The first to identify a cluster works it.** "First" is the `democracy` +- **The first to identify a cluster works it.** "First" is the `kvb-org-organize` claim `cluster/`, whose `--work` names the cluster's log line and number; between machines, the earliest announcement by message time. A claim without a measurement does not count. @@ -180,14 +181,14 @@ lighter one or the standard library: ## Delegating an optimization -Hand every optimization to an agent through the `funnel` skill: one sidetree +Hand every optimization to an agent through the `kvb-org-split` skill: one sidetree per candidate, branched from an exact commit, with a time cap and "measure first, report the time split before implementing". The agent probes live systems read-only and never starts gates or deploys. A broad brief without a cap can run for hours without a word; at its cap, collect the agent's interim findings and let it run on. -Before merging, run independent skeptics through the `dialectic` skill. The +Before merging, run independent skeptics through the `kvb-think-dialectic` skill. The antithesis must try to show that the candidate removes coverage, hides a failure, or only moves the cost somewhere the measurement does not look. @@ -197,7 +198,7 @@ failure, or only moves the cost somewhere the measurement does not look. 2. Coordinate the cluster with the other agents; work it only when you identified it first, otherwise hand over your findings and take the next. Then form one candidate for it, after the branch search and the floor check. -3. Harden it with the `dialectic` skill. +3. Harden it with the `kvb-think-dialectic` skill. 4. Funnel it through a sidetree; merge what reaches the bar, submit the rest as proposals. Re-measure from the same source under the same conditions and report a before and an after number. diff --git a/skills/auto-feature/SKILL.md b/skills/kvb-create-feature/SKILL.md similarity index 90% rename from skills/auto-feature/SKILL.md rename to skills/kvb-create-feature/SKILL.md index cb02d5c..a3922c5 100644 --- a/skills/auto-feature/SKILL.md +++ b/skills/kvb-create-feature/SKILL.md @@ -1,9 +1,9 @@ --- -name: auto-feature +name: kvb-create-feature description: > - Derive missing work (sceptic pass for structural flaws, usability pass for + Derive missing work (principles pass for structural flaws, usability pass for missing features) and write requirement documents after single-select - confirmation. Trigger on /auto-feature, "was fehlt noch", "welche features + confirmation. Trigger on /kvb-create-feature, "was fehlt noch", "welche features brauchen wir", or when the operator asks what to build next. --- @@ -19,9 +19,9 @@ surface. Read the project's existing requirement documents first — their location, filename convention, and section structure are the template, and an already-written requirement is not a finding. -## Step 2: the sceptic pass +## Step 2: the principles pass -Invoke the `sceptic` skill on the target. Its findings become requirement +Invoke the `kvb-check-principles` skill on the target. Its findings become requirement candidates by severity: a violated SPOT, SRP, or trust boundary is work the product needs whether or not a user ever notices. Carry each finding's `file:line` evidence forward — a requirement without it is a guess. @@ -55,7 +55,7 @@ Merge both lists, drop duplicates where a structural finding and a usability gap describe the same defect, and rank by blocked users first, blast radius second. -Then apply `active-listening`: answer everything you can from the code, the +Then apply `kvb-think-listen`: answer everything you can from the code, the docs, and the git history yourself, and put only the genuinely open decisions to the operator with `AskUserQuestion`, `multiSelect: false`, so every question renders as radio buttons. At most four questions per call, each @@ -94,5 +94,5 @@ Show the drafted document and ask for a final `Write it` / `Revise it` / not written. - Record the rejected alternatives inside the document; the next reader needs to know what was already considered and dismissed. -- Close with the `confidence` skill's numbers for the analysis: how sure the +- Close with the `kvb-check-confidence` skill's numbers for the analysis: how sure the gaps are real, and what the passes did not cover. diff --git a/skills/plan/SKILL.md b/skills/kvb-create-plan/SKILL.md similarity index 87% rename from skills/plan/SKILL.md rename to skills/kvb-create-plan/SKILL.md index 31e0919..8db26d3 100644 --- a/skills/plan/SKILL.md +++ b/skills/kvb-create-plan/SKILL.md @@ -1,8 +1,8 @@ --- -name: plan +name: kvb-create-plan description: > - Turn a request into an objective-oriented plan and hand it to the robot - skill. Trigger on /plan or when the operator asks for a plan, breakdown or + Turn a request into an objective-oriented plan and hand it to the kvb-org-robot + skill. Trigger on /kvb-create-plan or when the operator asks for a plan, breakdown or strategy before work starts. --- @@ -12,7 +12,7 @@ verified, and an unverifiable plan cannot be handed to a robot. ## Procedure -1. **Interview first.** Open every plan with the `active-listening` skill: ask +1. **Interview first.** Open every plan with the `kvb-think-listen` skill: ask until scope, constraints, success criteria, and the operator-only facts are all pinned, then reflect the understanding back. This is the only point in the run where questions are allowed, so leave nothing open here. @@ -28,7 +28,7 @@ verified, and an unverifiable plan cannot be handed to a robot. the items that are independent, so they can run in parallel. 5. **Resolve the open decisions now.** Any root cause, design choice, or trade-off the plan rests on gets settled before execution, escalating to the - `dialectic` skill where being wrong is expensive. The robot does not ask, so + `kvb-think-dialectic` skill where being wrong is expensive. The robot does not ask, so an unresolved decision becomes a guess at runtime. 6. **Record the plan as a todo list.** Write the sub-objectives into the harness's own todo tracking, one entry per item, phrased as the outcome. Keep @@ -42,8 +42,8 @@ verified, and an unverifiable plan cannot be handed to a robot. read the diff, run the linters, the unit tests, and whatever dry-run or syntax check the project offers. This step ends only when the whole plan exists on disk, with no sub-objective left unwritten. -9. **Then iterate under `robot`.** With the static implementation complete, - invoke the `robot` skill with the objective as its goal for the dynamic part: +9. **Then iterate under `kvb-org-robot`.** With the static implementation complete, + invoke the `kvb-org-robot` skill with the objective as its goal for the dynamic part: run, deploy, observe, fix, repeat until every verification passes. It drives the loop without check-ins, verifies each outcome instead of assuming it, and reports the items that fall outside its clearance for the operator to run. diff --git a/skills/branch-gc/SKILL.md b/skills/kvb-git-branch-gc/SKILL.md similarity index 96% rename from skills/branch-gc/SKILL.md rename to skills/kvb-git-branch-gc/SKILL.md index 9478eb1..6c288f1 100644 --- a/skills/branch-gc/SKILL.md +++ b/skills/kvb-git-branch-gc/SKILL.md @@ -1,9 +1,9 @@ --- -name: branch-gc +name: kvb-git-branch-gc description: > Remove merged branches and worktrees with `pkgmgr branch gc`: dry run, operator picks from the plan, then apply; unmerged items only one by one. - Trigger on /branch-gc, "branches aufräumen", "worktrees aufräumen", + Trigger on /kvb-git-branch-gc, "branches aufräumen", "worktrees aufräumen", "garbage collect". --- @@ -14,7 +14,7 @@ and nothing is removed before the operator's pick in this run. ## Step 0: claim and chair 1. Claim `work/branch-gc-`, or `work/branch-gc-all` for every - repository, through the `democracy` skill. + repository, through the `kvb-org-organize` skill. 2. The apply takes stacks down and ends with a host-wide `docker image prune -f` and `docker builder prune -f`, which reach every session's images and build cache. When another session holds the chair, diff --git a/skills/changelog/SKILL.md b/skills/kvb-git-changelog/SKILL.md similarity index 98% rename from skills/changelog/SKILL.md rename to skills/kvb-git-changelog/SKILL.md index 6f6b833..7996e65 100644 --- a/skills/changelog/SKILL.md +++ b/skills/kvb-git-changelog/SKILL.md @@ -1,9 +1,9 @@ --- -name: changelog +name: kvb-git-changelog description: > Write the release message since the last release for `pkgmgr release`; prints it only, never edits CHANGELOG.md, tags or releases. Trigger on - /changelog, "release message", "changelog entry", before cutting a release, + /kvb-git-changelog, "release message", "changelog entry", before cutting a release, or on pkgmgr's markdown-lint rejection. --- diff --git a/skills/commit-next/SKILL.md b/skills/kvb-git-commit-next/SKILL.md similarity index 75% rename from skills/commit-next/SKILL.md rename to skills/kvb-git-commit-next/SKILL.md index 208b9fe..8f66fb4 100644 --- a/skills/commit-next/SKILL.md +++ b/skills/kvb-git-commit-next/SKILL.md @@ -1,24 +1,24 @@ --- -name: commit-next +name: kvb-git-commit-next description: > Check every branch for the staged fix, commit the staged bundle with - --no-verify, then stage and brief the next bundle. Trigger on /commit-next + --no-verify, then stage and brief the next bundle. Trigger on /kvb-git-commit-next or when the operator asks to commit and stage the next bundle in one step. --- 1. `git fetch --all --prune --tags`, then hunt the staged fix across every - ref with the merge-fix skill's `find_fix.py` (by `--grep`, by `-S`, by + ref with the kvb-git-merge-fix skill's `find_fix.py` (by `--grep`, by `-S`, by `--path`). Describe the staged bundle in one line first so a wrong search intent is visible. Only the search runs here — never cherry-pick or merge, and never touch the staging index or the tree. -2. A similar fix on another branch is a stop: run the dialectic skill on the +2. A similar fix on another branch is a stop: run the kvb-think-dialectic skill on the two candidates (staged version as thesis, foreign commit as antithesis) until one survives, then present sha, branch, both diffs, the verdict and the recommended move (keep staged / take theirs / combine). Wait for the operator's decision; do not commit. 3. Nothing similar found, or the operator picked the staged version: run the - commit-no-verify skill on the currently staged changes (comments-clean - audit and advocate check first, then `git commit --no-verify`, exact + kvb-git-commit-no-verify skill on the currently staged changes (kvb-code-no-comments + audit and kvb-check-legal check first, then `git commit --no-verify`, exact staging index only). 4. Group the remaining uncommitted changes into logical bundles (one concern per bundle: same failure class, same mechanism, or same role) @@ -29,8 +29,8 @@ description: > NEW file needs `git add` to become visible. Path-scope every `git add` to the bundle — `git add -A` sweeps up the operator's own edits and their local config. -5. For the newly staged bundle run the explain skill (what the changes do +5. For the newly staged bundle run the kvb-think-explain skill (what the changes do and how the pieces interact, file:line-anchored) followed by the - confidence skill (fix confidence, break risk, evidence, residuals). + kvb-check-confidence skill (fix confidence, break risk, evidence, residuals). 6. Close with what remains unstaged and wait for the operator's commit decision; never auto-commit the newly staged bundle. diff --git a/skills/commit-no-verify/SKILL.md b/skills/kvb-git-commit-no-verify/SKILL.md similarity index 71% rename from skills/commit-no-verify/SKILL.md rename to skills/kvb-git-commit-no-verify/SKILL.md index 3e85448..c4af29d 100644 --- a/skills/commit-no-verify/SKILL.md +++ b/skills/kvb-git-commit-no-verify/SKILL.md @@ -1,12 +1,12 @@ --- -name: commit-no-verify +name: kvb-git-commit-no-verify description: > - Commit the staged changes with --no-verify. Trigger on /commit-no-verify or + Commit the staged changes with --no-verify. Trigger on /kvb-git-commit-no-verify or any request for a no-verify commit; invoking it IS the per-commit authorization --no-verify requires, never carried over to later commits. --- -1. Run the comments-clean audit over the staged and unstaged changes first, +1. Run the kvb-code-no-comments audit over the staged and unstaged changes first, then the advocate check over the staging index. An advocate blocker stops here. 2. Commit exactly the staging index with `git commit --no-verify` and a diff --git a/skills/merge-fix/SKILL.md b/skills/kvb-git-merge-fix/SKILL.md similarity index 91% rename from skills/merge-fix/SKILL.md rename to skills/kvb-git-merge-fix/SKILL.md index ec8e3e9..5b30945 100644 --- a/skills/merge-fix/SKILL.md +++ b/skills/kvb-git-merge-fix/SKILL.md @@ -1,12 +1,12 @@ --- -name: merge-fix +name: kvb-git-merge-fix description: > Hunt down the commits on any branch that carry a described fix and merge it - into the current branch. Trigger on /merge-fix or when the + into the current branch. Trigger on /kvb-git-merge-fix or when the operator asks to bring over a fix from another branch. --- -The free text after `/merge-fix` is the fix description, exactly like `/loop` +The free text after `/kvb-git-merge-fix` is the fix description, exactly like `/loop` takes its prompt. Everything after the skill name is the search intent; there is no other input. If it is missing, ask for it and stop. @@ -67,7 +67,7 @@ and its diff plainly is the described fix. ## 7. Report Show `git log --oneline ..HEAD` and the resulting diffstat, then apply the -confidence skill: what came over, what did not, what still has to be verified. +kvb-check-confidence skill: what came over, what did not, what still has to be verified. Run the project's test or quality gate only when the operator asks for it. ## Rules diff --git a/skills/merge-fix/scripts/find_fix.py b/skills/kvb-git-merge-fix/scripts/find_fix.py similarity index 100% rename from skills/merge-fix/scripts/find_fix.py rename to skills/kvb-git-merge-fix/scripts/find_fix.py diff --git a/skills/help-skills/SKILL.md b/skills/kvb-help/SKILL.md similarity index 83% rename from skills/help-skills/SKILL.md rename to skills/kvb-help/SKILL.md index e036506..442c8ee 100644 --- a/skills/help-skills/SKILL.md +++ b/skills/kvb-help/SKILL.md @@ -1,7 +1,7 @@ --- -name: help-skills +name: kvb-help description: > - List and explain every skill in the session. Trigger on /help-skills, + List and explain every skill in the session. Trigger on /kvb-help, "welche skills gibt es", "skill übersicht", or when the operator asks what skills exist or what one does. --- @@ -17,8 +17,8 @@ Produce a one-shot overview of every skill the session can invoke: — compress the description, do not paste it. 3. When the operator names a specific skill or topic, explain only the matching skills in more depth: what they do, when they fire on their - own, and how they compose (e.g. commit-next → commit-no-verify → - comments-clean). + own, and how they compose (e.g. kvb-git-commit-next → kvb-git-commit-no-verify → + kvb-code-no-comments). 4. End with the activation hint: project installers or `make install` in the skills repository refresh the live copies; a restart loads renamed or new skills. diff --git a/skills/kvb-org-coordinate/SKILL.md b/skills/kvb-org-coordinate/SKILL.md new file mode 100644 index 0000000..9219ca4 --- /dev/null +++ b/skills/kvb-org-coordinate/SKILL.md @@ -0,0 +1,11 @@ +--- +name: kvb-org-coordinate +description: > + Coordinate a failure or fix with the agents on related branches through + merges: claim, ask, report. Trigger on /kvb-org-coordinate and when a fix touches + code other branches share. +--- + +Run the `kvb-org-organize` skill's **Lineage** and **Peer protocol** sections for the +failure or fix at hand. They hold the whole procedure; this skill only keeps +`/kvb-org-coordinate` working. diff --git a/skills/status-matrix/SKILL.md b/skills/kvb-org-matrix/SKILL.md similarity index 95% rename from skills/status-matrix/SKILL.md rename to skills/kvb-org-matrix/SKILL.md index a1fb80d..9947a7a 100644 --- a/skills/status-matrix/SKILL.md +++ b/skills/kvb-org-matrix/SKILL.md @@ -1,8 +1,8 @@ --- -name: status-matrix +name: kvb-org-matrix description: > Print one matrix of everything in flight: tasks, workflows, background jobs, - with confidence and break risk per item. Trigger on /status-matrix, + with confidence and break risk per item. Trigger on /kvb-org-matrix, "status", "übersicht", "wo stehen wir", or what is done, left or running. --- @@ -35,7 +35,7 @@ One table, most-blocking first, one row per item: - **State**: `open`, `running`, `blocked`, `done`. `done` means verified — a passing run, a green check, a reproduction that now succeeds. Work that merely looks finished is `open`. -- **Conf.** and **Break risk**: two separate percentages per the `confidence` +- **Conf.** and **Break risk**: two separate percentages per the `kvb-check-confidence` skill — probability the item does what it claims, and probability it breaks something else. Only for rows that changed something; `—` for pure observation rows. diff --git a/skills/democracy/SKILL.md b/skills/kvb-org-organize/SKILL.md similarity index 94% rename from skills/democracy/SKILL.md rename to skills/kvb-org-organize/SKILL.md index cc8006b..78062b7 100644 --- a/skills/democracy/SKILL.md +++ b/skills/kvb-org-organize/SKILL.md @@ -1,10 +1,10 @@ --- -name: democracy +name: kvb-org-organize description: > Keep parallel agents from duplicating work: the first to claim it owns it; line representatives and a resource chair coordinate. Run AUTOMATICALLY before work another agent might also do (failure, cluster, feature, gate, - deploy, cleanup), and on /democracy. + deploy, cleanup), and on /kvb-org-organize. --- Two agents doing the same work waste the second run and then collide in the @@ -23,8 +23,8 @@ operator at any time. (security, GUI, identity, i18n), repository, branch line, host, cloud account. An agent belongs to one line per dimension. - **Organiser of a work cluster**: the first agent that starts a cluster - cutting across lines (a failure cluster from `triage`, a cost cluster from - `tune`, a feature touching several domains). It works the strand end to end + cutting across lines (a failure cluster from `kvb-ci-triage`, a cost cluster from + `kvb-code-tune`, a feature touching several domains). It works the strand end to end and informs the representative of every line the strand touches before it changes that line's files. - **Chair**: the earliest-elected president still running. It chairs the @@ -82,7 +82,7 @@ records the result. free capacity. The chair neither asks nor orders its owner to stop, take down or kill it, not for an operator-prioritised slot and not for a projected disk stop. It grants nothing new, frees idle items through the - `cleanup` flow, asks the operator for an exception, or waits. An owner's + `kvb-cleanup` flow, asks the operator for an exception, or waits. An owner's own disk guard only alerts the chair and takes nothing down; only the operator can order a running job down. The one exception is a hang: an agent may end its own job, a stuck step inside it, or a process its own @@ -141,10 +141,10 @@ plans to it. ## Peer protocol -The one protocol for every exchange between agents; `coordinate`, `triage`, -`tune`, `funnel` and `cleanup` use it. +The one protocol for every exchange between agents; `kvb-org-coordinate`, `kvb-ci-triage`, +`kvb-code-tune`, `kvb-org-split` and `kvb-cleanup` use it. -1. **Look**: `council.py list` and the refs (the merge-fix skill's +1. **Look**: `council.py list` and the refs (the kvb-git-merge-fix skill's `find_fix.py`). A claim or a committed fix answers the question without a message. 2. **Claim** the office (Election). @@ -195,7 +195,7 @@ For a failure or a fix that other branches share through merges: ## Output -On /democracy, one table of the current offices from `council.py list`, stale +On /kvb-org-organize, one table of the current offices from `council.py list`, stale claims marked: | Office | Holder | Since | Work | Grants or queue | diff --git a/skills/democracy/scripts/council.py b/skills/kvb-org-organize/scripts/council.py similarity index 95% rename from skills/democracy/scripts/council.py rename to skills/kvb-org-organize/scripts/council.py index 1495639..11dd8a7 100755 --- a/skills/democracy/scripts/council.py +++ b/skills/kvb-org-organize/scripts/council.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -"""Claim, release and list democracy offices in the shared council directory. +"""Claim, release and list kvb-org-organize offices in the shared council directory. Environment: AGENTS_COUNCIL_ROOT: council directory shared by every agent on the host; @@ -122,7 +122,7 @@ def cmd_takeover(args: argparse.Namespace) -> int: print(json.dumps(claim) if claim else f"{args.office}: claim in progress") return 3 # Two successors racing between this check and the rename can both win; - # democracy names exactly one successor per office to keep that window closed. + # kvb-org-organize names exactly one successor per office to keep that window closed. if path.exists(): tomb = path.with_name(f"{path.name}.stale-{os.getpid()}-{time.time_ns()}") try: @@ -186,10 +186,10 @@ def cmd_gate(_: argparse.Namespace) -> int: return 0 script = Path(__file__).resolve() print( - "democracy: this session holds no claim, so it may not edit files in a git " + "kvb-org-organize: this session holds no claim, so it may not edit files in a git " f"worktree. Claim the work first: python3 {script} claim work/ " "--work ''. Exit 3 or 4 means another agent holds it; read the " - "democracy skill.", + "kvb-org-organize skill.", file=sys.stderr, ) return 2 diff --git a/skills/democracy/scripts/watch.py b/skills/kvb-org-organize/scripts/watch.py similarity index 98% rename from skills/democracy/scripts/watch.py rename to skills/kvb-org-organize/scripts/watch.py index e62243d..72a1e69 100755 --- a/skills/democracy/scripts/watch.py +++ b/skills/kvb-org-organize/scripts/watch.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -"""Watch disk, Docker and caches for the democracy resource chair. +"""Watch disk, Docker and caches for the kvb-org-organize resource chair. Usage: watch.py watch hook (UserPromptSubmit, PostToolUse): measure at most once @@ -226,7 +226,7 @@ def cmd_block(cfg: dict) -> int: return 0 if any(re.search(p, command) for p in cfg["heavy_commands"]): print( - f"democracy: resource stage is {stage}; new heavy jobs are blocked until " + f"kvb-org-organize: resource stage is {stage}; new heavy jobs are blocked until " "the disk recovers. Teardown commands still run. Ask the resource chair.", file=sys.stderr, ) diff --git a/skills/subagent-model/SKILL.md b/skills/kvb-org-perform/SKILL.md similarity index 97% rename from skills/subagent-model/SKILL.md rename to skills/kvb-org-perform/SKILL.md index c18df3e..679b8f5 100644 --- a/skills/subagent-model/SKILL.md +++ b/skills/kvb-org-perform/SKILL.md @@ -1,5 +1,5 @@ --- -name: subagent-model +name: kvb-org-perform description: > Pick `model` and `effort` per subagent from a fixed table: cheaper only on a clear match at 90 % that the result equals the default's; log spawns and @@ -66,7 +66,7 @@ Inside a sandbox that cannot write it, the script prints the line as runs and the share with the same result: completed, not redone, no failing test, no follow-up. A row is added, or a cheaper setting extended to a class, only when the report shows at least 90 % over at least 20 rated runs, and only -after the operator confirms it (for example through `/autotune`). A row whose +after the operator confirms it (for example through `/kvb-skills-tune`). A row whose rate falls below 90 % over 20 rated runs goes back to the default. `sonnet` enters the table only this way, and a trial run on a setting the table does not hold needs the operator's order. diff --git a/skills/subagent-model/scripts/log.py b/skills/kvb-org-perform/scripts/log.py similarity index 99% rename from skills/subagent-model/scripts/log.py rename to skills/kvb-org-perform/scripts/log.py index 1dbb405..f84d702 100755 --- a/skills/subagent-model/scripts/log.py +++ b/skills/kvb-org-perform/scripts/log.py @@ -39,7 +39,7 @@ LOG = Path( ) TASK_CLASS = re.compile(r"^task-class:\s*(\S+)", re.MULTILINE) PENDING = "pending: " -SCRIPT = "subagent-model/scripts/log.py" +SCRIPT = "kvb-org-perform/scripts/log.py" CONTROL = re.compile(r"^[();<>|&]+$") KEYS = { "feedback": {"kind", "time", "session", "description", "completed", "tests", "redo"}, diff --git a/skills/robot/SKILL.md b/skills/kvb-org-robot/SKILL.md similarity index 90% rename from skills/robot/SKILL.md rename to skills/kvb-org-robot/SKILL.md index 941df72..86b2f08 100644 --- a/skills/robot/SKILL.md +++ b/skills/kvb-org-robot/SKILL.md @@ -1,5 +1,5 @@ --- -name: robot +name: kvb-org-robot description: > Work fully autonomously to a goal: no check-ins, no stopping before the goal, only commands already cleared. Trigger when the operator wants hands-off, @@ -11,7 +11,7 @@ Operate as an autonomous robot: given a goal, reach it without hand-holding. ## Contract - **No questions once the goal is clear.** Clarify only genuinely-blocking - unknowns up front (via the `active-listening` skill), then proceed without + unknowns up front (via the `kvb-think-listen` skill), then proceed without further check-ins. Pick the cleanest option and continue; never pause to confirm a choice you can make yourself. - **Never stop before the goal.** Do not end the run, hand back, or declare done @@ -31,7 +31,7 @@ Operate as an autonomous robot: given a goal, reach it without hand-holding. ## Rules -- Escalate an uncertain root cause or design decision to the `dialectic` skill +- Escalate an uncertain root cause or design decision to the `kvb-think-dialectic` skill 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. diff --git a/skills/funnel/SKILL.md b/skills/kvb-org-split/SKILL.md similarity index 91% rename from skills/funnel/SKILL.md rename to skills/kvb-org-split/SKILL.md index 279e9e4..204df10 100644 --- a/skills/funnel/SKILL.md +++ b/skills/kvb-org-split/SKILL.md @@ -1,9 +1,9 @@ --- -name: funnel +name: kvb-org-split description: > Keep agent work in its own git worktree until it reaches 90% fix confidence and under 5% break risk; below that bar it becomes a proposal. Trigger when - delegating work to agents, when agents work in parallel, or on /funnel. + delegating work to agents, when agents work in parallel, or on /kvb-org-split. --- # Funnel @@ -14,18 +14,18 @@ in a sidetree until it does, or leaves as a proposal. ## The bar - **Fix confidence of at least 90 %** and **break risk under 5 %**, both - reported by the `confidence` skill, the break risk derived through the - `break-risk` skill. + reported by the `kvb-check-confidence` skill, the break risk derived through the + `kvb-check-break-risk` skill. - The operator may set a different bar. Never lower it to make a change fit. ## The stages -1. **Brief.** One concern per agent, on the model the `subagent-model` skill +1. **Brief.** One concern per agent, on the model the `kvb-org-perform` skill picks. Name the goal, the exact base commit, the scope that may change, the evidence expected back, a time cap (default 60 minutes) at which it reports its interim state, and what the agent must not do: no pushes, no gates or deploys - unless the resource chair of the `democracy` skill granted them, read-only + unless the resource chair of the `kvb-org-organize` skill granted them, read-only probes on shared live systems. 2. **Sidetree.** The agent works in its own worktree on its own branch, created from the exact base commit, so its edits never land under a running @@ -36,7 +36,7 @@ in a sidetree until it does, or leaves as a proposal. Numbers come from the same source before and after. 4. **Self-assessment.** The agent reports fix confidence and break risk with their residuals and commits on its branch. -5. **Independent review.** Before anything is merged, run the `dialectic` skill +5. **Independent review.** Before anything is merged, run the `kvb-think-dialectic` skill with skeptics who did not write the change. A hole they find returns the change to stage 3. 6. **Merge.** At or above the bar, merge the sidetree branch into the main line @@ -66,7 +66,7 @@ and verify each step instead of assuming it: 5. **Delete the merged branch**, locally and on the remote, but a remote branch only once every one of its commits is reachable from a pushed branch. 6. **Release what it held**: slots (reported to the resource chair), port or - subnet reservations, locks, its `democracy` claims and every claim + subnet reservations, locks, its `kvb-org-organize` claims and every claim announced to other agents. 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/autoskill/SKILL.md b/skills/kvb-skills-auto/SKILL.md similarity index 85% rename from skills/autoskill/SKILL.md rename to skills/kvb-skills-auto/SKILL.md index 919bc07..f0ca3b3 100644 --- a/skills/autoskill/SKILL.md +++ b/skills/kvb-skills-auto/SKILL.md @@ -1,5 +1,5 @@ --- -name: autoskill +name: kvb-skills-auto description: > Turn operator repetition into a skill. Trigger when the operator gives the same instruction, correction or prompt pattern about the third time in a @@ -7,7 +7,7 @@ description: > reusable. --- -Its objective is the `autotune` skill's **Objective** section: a skill is worth +Its objective is the `kvb-skills-tune` skill's **Objective** section: a skill is worth creating only when it cuts tokens or time and raises quality; judge every candidate against its three axes and rules. @@ -20,9 +20,9 @@ vary), do the following: a skill name suggestion, the trigger phrasing, and what the skill would do. Ask whether to create it. 3. On approval, write the skill: - - a conversation shortcut or expansion: add it to the `shortcuts` skill + - a conversation shortcut or expansion: add it to the `kvb-skills-shortcuts` skill table instead of creating a new skill. - - anything else: persist it exactly as the `autotune` skill's + - anything else: persist it exactly as the `kvb-skills-tune` skill's **Persistence** section specifies — locate the operator's skills repository, write `skills//SKILL.md` there (or in the current project for project-specific behavior), then mirror the skill directory diff --git a/skills/dream/SKILL.md b/skills/kvb-skills-dream/SKILL.md similarity index 92% rename from skills/dream/SKILL.md rename to skills/kvb-skills-dream/SKILL.md index a41a3ea..08153cc 100644 --- a/skills/dream/SKILL.md +++ b/skills/kvb-skills-dream/SKILL.md @@ -1,9 +1,9 @@ --- -name: dream +name: kvb-skills-dream description: > Consolidate the last 24 hours of work in this repository: what held, what broke, which hypotheses follow, into memory and improvement proposals. - Trigger on /dream or when the operator asks to reflect on or learn from + Trigger on /kvb-skills-dream or when the operator asks to reflect on or learn from recent work. --- @@ -24,13 +24,13 @@ A class of error counts as closed only when something structural prevents it — a test, a lint rule, a CI check, a hook, a written rule in the agent instructions, or a skill. "Be more careful next time" closes nothing. Report the confidence the next run can now hold on each closed class, calibrated as the -`confidence` skill requires, and name what is still open. +`kvb-check-confidence` skill requires, and name what is still open. ## Scope Everything is read from the repository the skill runs in (`git rev-parse --show-toplevel`); never mix in another project's history or memory. The default -window is the last 24 hours — the operator may widen it (`/dream 7d`). State the +window is the last 24 hours — the operator may widen it (`/kvb-skills-dream 7d`). State the repository and the window in one line before you start. Run only when the operator asks. The 12-hour reminder hook @@ -77,7 +77,7 @@ that nothing could disprove is not a hypothesis — cut it. ## Step 4: dialectic -Put every surviving hypothesis through the `dialectic` skill: thesis, +Put every surviving hypothesis through the `kvb-think-dialectic` skill: thesis, independent skeptics, synthesis, iterated to ~99%. What survives becomes a finding. What gets refuted is recorded as discarded **with the refutation**, so the next dream does not re-derive it. @@ -106,10 +106,10 @@ as radio buttons: the improvement, the evidence behind it, and the options `Apply now`, `Record as a task`, `Skip`. Ranked by evidence, one question per improvement. No repository file changes before an answer comes back. -## Step 7: autotune, then autoskill +## Step 7: kvb-skills-tune, then kvb-skills-auto -With the dialectic done and memory written, run `autotune` — hand it this run's -findings as its evidence so it does not re-collect them — and then `autoskill` +With the dialectic done and memory written, run `kvb-skills-tune` — hand it this run's +findings as its evidence so it does not re-collect them — and then `kvb-skills-auto` for the operator corrections the window revealed. Both keep their own confirmation steps; the dream never writes a skill on their behalf. diff --git a/skills/dream/hooks/reminder.sh b/skills/kvb-skills-dream/hooks/reminder.sh similarity index 68% rename from skills/dream/hooks/reminder.sh rename to skills/kvb-skills-dream/hooks/reminder.sh index 58c318a..5ba8de0 100755 --- a/skills/dream/hooks/reminder.sh +++ b/skills/kvb-skills-dream/hooks/reminder.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -# UserPromptSubmit hook: emit the dream hint at most once per interval and per +# UserPromptSubmit hook: emit the kvb-skills-dream hint at most once per interval and per # repository. The stamp lives in the repository's git dir, so every repository # keeps its own cadence; outside a git repository the hook stays silent. # Stdout lands in the agent's context, which is why the payload tells the agent -# to show the hint and keep going instead of running dream by itself. +# to show the hint and keep going instead of running kvb-skills-dream by itself. set -euo pipefail interval="${DREAM_INTERVAL_SECONDS:-43200}" @@ -31,10 +31,11 @@ printf '%s\n' "${now}" >"${stamp}" cat <<'HINT' DREAM HINT: over twelve hours since the last hint for this repository. Show the operator this notice verbatim as a short block, then continue with their -request. Do NOT run dream, do not start replaying the history, do not ask -questions about it. +request. Do NOT run kvb-skills-dream, do not start replaying the history, do +not ask questions about it. - 💤 /dream - consolidate the last 24h in this repository: what held, what - broke, which hypotheses follow, into memory and improvement proposals. + 💤 /kvb-skills-dream - consolidate the last 24h in this repository: what + held, what broke, which hypotheses follow, into memory and improvement + proposals. Runs only when you trigger it. HINT diff --git a/skills/essence/SKILL.md b/skills/kvb-skills-essence/SKILL.md similarity index 97% rename from skills/essence/SKILL.md rename to skills/kvb-skills-essence/SKILL.md index 39e6c67..a05379b 100644 --- a/skills/essence/SKILL.md +++ b/skills/kvb-skills-essence/SKILL.md @@ -1,8 +1,8 @@ --- -name: essence +name: kvb-skills-essence description: > Compact skills and memory to their essence after a health pass that finds - dead weight. Trigger on /essence or when skills or MEMORY.md grow too long, + dead weight. Trigger on /kvb-skills-essence or when skills or MEMORY.md grow too long, duplicate, or eat too much context. --- diff --git a/skills/shortcuts/SKILL.md b/skills/kvb-skills-shortcuts/SKILL.md similarity index 97% rename from skills/shortcuts/SKILL.md rename to skills/kvb-skills-shortcuts/SKILL.md index fe123e3..5a4bfca 100644 --- a/skills/shortcuts/SKILL.md +++ b/skills/kvb-skills-shortcuts/SKILL.md @@ -1,5 +1,5 @@ --- -name: shortcuts +name: kvb-skills-shortcuts description: > Operator conversation shortcuts. Trigger when the message is exactly one of these tokens, optionally with arguments: sobu, soco, socobu, socon, sona, diff --git a/skills/autotune/SKILL.md b/skills/kvb-skills-tune/SKILL.md similarity index 90% rename from skills/autotune/SKILL.md rename to skills/kvb-skills-tune/SKILL.md index 13db397..550ac9d 100644 --- a/skills/autotune/SKILL.md +++ b/skills/kvb-skills-tune/SKILL.md @@ -1,9 +1,9 @@ --- -name: autotune +name: kvb-skills-tune description: > Generate new skills or optimize existing ones (fewer tokens, fewer errors, persistent learnings), each proposal confirmed by single-select question. - Trigger ONLY on an explicit request: /autotune, "autotune", "tune the + Trigger ONLY on an explicit request: /kvb-skills-tune, "autotune", "tune the skills"; never on your own initiative. --- @@ -13,8 +13,8 @@ skill it writes or rewrites lands in the operator's skills repository. ## Objective -The shared objective of the self-improving skills (autotune, autoskill, -confidence): every skill, rule, or report the agent produces about its own +The shared objective of the self-improving skills (kvb-skills-tune, +kvb-skills-auto, kvb-check-confidence): every skill, rule, or report the agent produces about its own working is judged on three axes at once. A proposal that cannot name the axis it moves is not an optimization, it is a preference. @@ -43,7 +43,7 @@ it moves is not an optimization, it is a preference. ## Trigger discipline -- Run **only** when the operator asks: `/autotune`, "autotune", "tune the +- Run **only** when the operator asks: `/kvb-skills-tune`, "autotune", "tune the skills", or an equivalent instruction. - The 60-minute reminder hook is a hint for the operator, not a trigger. When it fires, print the hint and continue the operator's actual request. @@ -75,14 +75,14 @@ option, and never write a file before the answers are in. Ask in this order, at most four questions per call: -1. **Scope** - "What should autotune do this run?" Options: `Create a new +1. **Scope** - "What should kvb-skills-tune do this run?" Options: `Create a new skill`, `Optimize an existing skill`, `Both`, plus the ranked findings if more than one candidate exists. 2. **Target** - which finding becomes a skill, or which existing skill gets optimized. One option per candidate, each with its measured cost in the description. -3. **Shape** - for a new skill: `Standalone skill`, `Row in the shortcuts - skill`, `Extend an existing skill`, `Memory entry instead of a skill`. +3. **Shape** - for a new skill: `Standalone skill`, `Row in the + kvb-skills-shortcuts skill`, `Extend an existing skill`, `Memory entry instead of a skill`. For an optimization: `Tighten wording only`, `Change the trigger`, `Add rules`, `Split into two skills`, `Merge into another skill`. 4. **Placement** - `Operator skills repository (portable)` or @@ -130,7 +130,7 @@ reverse — remove the mirrors too, or the old name keeps firing. - Optimizing an existing skill means the file gets shorter or sharper, not longer. Delete rules the agent already follows, merge duplicated ones, and cut every sentence that does not change an action. Route that compaction - through the `essence` skill instead of trimming by hand: it runs a health + through the `kvb-skills-essence` skill instead of trimming by hand: it runs a health pass for dead pointers and rules duplicated across skills before cutting anything, ranks by what loads in every session, and shows the diff before it writes. It asks for its own scope — answer with the skill being optimized. @@ -140,7 +140,7 @@ reverse — remove the mirrors too, or the old name keeps firing. ## Rules - One skill per run unless the operator picked `Both`; a broad rewrite of the - whole collection is not what autotune is for. + whole collection is not what kvb-skills-tune is for. - Never write a skill for one-off work, for secrets, or for behaviour an existing skill already covers - propose extending that skill instead. - The **Objective** section decides what counts as an improvement: at least diff --git a/skills/autotune/hooks/reminder.sh b/skills/kvb-skills-tune/hooks/reminder.sh similarity index 70% rename from skills/autotune/hooks/reminder.sh rename to skills/kvb-skills-tune/hooks/reminder.sh index 5585763..dfbfae9 100755 --- a/skills/autotune/hooks/reminder.sh +++ b/skills/kvb-skills-tune/hooks/reminder.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash -# UserPromptSubmit hook: emit the autotune hint at most once per interval. +# UserPromptSubmit hook: emit the kvb-skills-tune hint at most once per interval. # Stdout lands in the agent's context, which is why the payload tells the agent -# to show the hint and keep going instead of running autotune by itself. +# to show the hint and keep going instead of running kvb-skills-tune by itself. set -euo pipefail interval="${AUTOTUNE_INTERVAL_SECONDS:-3600}" @@ -24,9 +24,9 @@ printf '%s\n' "${now}" >"${stamp}" cat <<'HINT' AUTOTUNE HINT: over an hour since the last hint. Show the operator this notice verbatim as a short block, then continue with their request. Do NOT run -autotune, do not propose skills, do not ask questions about it. +kvb-skills-tune, do not propose skills, do not ask questions about it. - 💡 /autotune - generate a new skill or optimize an existing one + 💡 /kvb-skills-tune - generate a new skill or optimize an existing one (fewer tokens, fewer errors, more focus, learnings that persist). Runs only when you trigger it. HINT diff --git a/skills/criticize/SKILL.md b/skills/kvb-think-criticize/SKILL.md similarity index 89% rename from skills/criticize/SKILL.md rename to skills/kvb-think-criticize/SKILL.md index 747e750..78c81a1 100644 --- a/skills/criticize/SKILL.md +++ b/skills/kvb-think-criticize/SKILL.md @@ -1,21 +1,21 @@ --- -name: criticize +name: kvb-think-criticize description: > Give constructive criticism of a problem, plan, design, decision, text or code from diverse aspects, each point hardened by dialectic. Trigger on - /criticize, "kritisiere", "kritisch betrachten", "konstruktive Kritik", "was + /kvb-think-criticize, "kritisiere", "kritisch betrachten", "konstruktive Kritik", "was haeltst du davon", or requests for honest feedback. --- The stance is critical but constructive: the goal is a better result, not a verdict on its author. This skill judges any artifact from many angles; it is -not limited to code (`sceptic` hunts violated engineering principles in code, +not limited to code (`kvb-check-principles` hunts violated engineering principles in code, `code-review` hunts bugs). Read-only: report the critique, change nothing unless the operator asks afterwards. ## Before you start: listen -Invoke the `active-listening` skill. Pin down what is being criticized, what it +Invoke the `kvb-think-listen` skill. Pin down what is being criticized, what it is meant to achieve, for whom, and under which constraints. Derive what you can from the artifact and its surroundings first; ask only what only the operator knows. A critique against the wrong goal is noise. @@ -53,7 +53,7 @@ Sweep every aspect that applies, and name the ones you skipped and why: ## Harden every point with dialectic -Run each candidate critique through the `dialectic` skill before reporting it: +Run each candidate critique through the `kvb-think-dialectic` skill before reporting it: - **Thesis**: the critique point with its evidence. - **Antithesis**: independent defenders argue that the artifact is right as it @@ -76,7 +76,7 @@ One line of scope, then the steelman. Then: `Evidence` is `proven` (read, run, reproduced, cited) or `derived` (reasoned). Close with at most three lines: how many candidate points dialectic dropped and -why, the single change that helps most, and the `confidence` skill's numbers for +why, the single change that helps most, and the `kvb-check-confidence` skill's numbers for the critique as a whole. ## Rules diff --git a/skills/dialectic/SKILL.md b/skills/kvb-think-dialectic/SKILL.md similarity index 86% rename from skills/dialectic/SKILL.md rename to skills/kvb-think-dialectic/SKILL.md index 7374134..f23d711 100644 --- a/skills/dialectic/SKILL.md +++ b/skills/kvb-think-dialectic/SKILL.md @@ -1,5 +1,5 @@ --- -name: dialectic +name: kvb-think-dialectic description: > Reach a defensible conclusion by thesis, independent skeptic antithesis and synthesis, iterated to ~99% confidence. Trigger for any consequential root @@ -12,13 +12,13 @@ answer; drive the loop until a thesis survives every attack at ~99% confidence. ## Before you start: listen -Invoke the `active-listening` skill first. Do not begin the dialectic until you +Invoke the `kvb-think-listen` skill first. Do not begin the dialectic until you have gathered every requirement, constraint, and success criterion the task needs. A dialectic run on the wrong question wastes the whole loop. Return to -`active-listening` mid-loop whenever an objection turns on a fact only the +`kvb-think-listen` mid-loop whenever an objection turns on a fact only the operator holds. -When another skill or an autonomous run (robot, observe, a loop) invoked this +When another skill or an autonomous run (kvb-org-robot, kvb-ci-observe, a loop) invoked this skill, derive the requirements from the task and the evidence instead of asking; ask only when an operator-only fact blocks the conclusion. @@ -30,7 +30,7 @@ asking; ask only when an operator-only fact blocks the conclusion. make or CLI helpers the project exposes); CI logs and artifacts; tests; docs. Cite `file:line` and command output — never a bare assertion. 2. **Antithesis.** Spawn MULTIPLE independent skeptics (parallel subagents or a - workflow, on the default model as the `subagent-model` skill requires) + workflow, on the default model as the `kvb-org-perform` skill requires) whose only job is to REFUTE the thesis. Each re-inspects the sources itself and defaults to "refuted" on any concrete hole. Give diverse skeptics diverse lenses: correctness, an alternate mechanism, does-it- @@ -41,7 +41,7 @@ asking; ask only when an operator-only fact blocks the conclusion. 4. **Iterate.** Repeat thesis → antithesis → synthesis until a full skeptic round finds no new hole and the thesis holds at ~99%. If confidence stalls below 99%, name the exact residual and the evidence that would close it, then - go get that evidence (more inspection, or `active-listening` for an + go get that evidence (more inspection, or `kvb-think-listen` for an operator-only fact) and loop again. ## Rules diff --git a/skills/explain/SKILL.md b/skills/kvb-think-explain/SKILL.md similarity index 96% rename from skills/explain/SKILL.md rename to skills/kvb-think-explain/SKILL.md index 45350ad..3b74256 100644 --- a/skills/explain/SKILL.md +++ b/skills/kvb-think-explain/SKILL.md @@ -1,8 +1,8 @@ --- -name: explain +name: kvb-think-explain description: > Explain code and its interactions. Trigger when the operator asks what code - does, how a mechanism works, why components interact, or invokes /explain on + does, how a mechanism works, why components interact, or invokes /kvb-think-explain on a file, function, role or module. --- diff --git a/skills/active-listening/SKILL.md b/skills/kvb-think-listen/SKILL.md similarity index 98% rename from skills/active-listening/SKILL.md rename to skills/kvb-think-listen/SKILL.md index 53d7651..5d4efe8 100644 --- a/skills/active-listening/SKILL.md +++ b/skills/kvb-think-listen/SKILL.md @@ -1,5 +1,5 @@ --- -name: active-listening +name: kvb-think-listen description: > Ask focused questions until every requirement is pinned down, then reflect the task back. Trigger at the start of any task with unclear scope, diff --git a/tests/test_autotune.py b/tests/test_autotune.py index 15a7d3f..4b70e65 100644 --- a/tests/test_autotune.py +++ b/tests/test_autotune.py @@ -1,4 +1,4 @@ -"""Validate the autotune reminder hook and its settings registration.""" +"""Validate the kvb-skills-tune reminder hook and its settings registration.""" from __future__ import annotations @@ -10,8 +10,8 @@ import unittest from pathlib import Path REPO_ROOT = Path(__file__).resolve().parents[1] -SKILL = REPO_ROOT / "skills" / "autotune" / "SKILL.md" -HOOK = REPO_ROOT / "skills" / "autotune" / "hooks" / "reminder.sh" +SKILL = REPO_ROOT / "skills" / "kvb-skills-tune" / "SKILL.md" +HOOK = REPO_ROOT / "skills" / "kvb-skills-tune" / "hooks" / "reminder.sh" PATCHER = REPO_ROOT / "scripts" / "enable-plugins.js" @@ -33,7 +33,7 @@ def _run_hook(stamp: Path, interval: str = "3600") -> subprocess.CompletedProces class TestAutotuneSkill(unittest.TestCase): def test_skill_is_trigger_only(self): text = SKILL.read_text(encoding="utf-8") - self.assertIn("name: autotune", text) + self.assertIn("name: kvb-skills-tune", text) self.assertIn("multiSelect: false", text) @@ -51,7 +51,7 @@ class TestSkillPersistence(unittest.TestCase): self.assertIn(target, text) def test_autoskill_routes_to_the_same_persistence(self): - text = (REPO_ROOT / "skills" / "autoskill" / "SKILL.md").read_text( + text = (REPO_ROOT / "skills" / "kvb-skills-auto" / "SKILL.md").read_text( encoding="utf-8" ) for target in ("Persistence", "~/.claude/skills/", "~/.agents/skills/"): @@ -66,7 +66,7 @@ class TestAutotuneHook(unittest.TestCase): def test_first_run_hints_and_stamps(self): result = _run_hook(self.stamp) - self.assertIn("/autotune", result.stdout) + self.assertIn("/kvb-skills-tune", result.stdout) self.assertTrue(self.stamp.is_file()) def test_second_run_is_silent_within_interval(self): @@ -75,12 +75,12 @@ class TestAutotuneHook(unittest.TestCase): def test_hint_returns_after_the_interval(self): _run_hook(self.stamp) - self.assertIn("/autotune", _run_hook(self.stamp, interval="0").stdout) + self.assertIn("/kvb-skills-tune", _run_hook(self.stamp, interval="0").stdout) def test_corrupt_stamp_does_not_crash(self): self.stamp.parent.mkdir(parents=True, exist_ok=True) self.stamp.write_text("not-a-timestamp\n", encoding="utf-8") - self.assertIn("/autotune", _run_hook(self.stamp).stdout) + self.assertIn("/kvb-skills-tune", _run_hook(self.stamp).stdout) @unittest.skipUnless(shutil.which("node"), "node not installed") @@ -100,7 +100,7 @@ class TestSettingsRegistration(unittest.TestCase): self._patch() data = self._patch() entries = json.dumps(data["hooks"]["UserPromptSubmit"]) - self.assertEqual(entries.count("autotune/hooks/reminder.sh"), 1) + self.assertEqual(entries.count("kvb-skills-tune/hooks/reminder.sh"), 1) def test_existing_hooks_preserved(self): self.settings.write_text( diff --git a/tests/test_ci_tools.py b/tests/test_ci_tools.py index 35890e7..3a48da7 100644 --- a/tests/test_ci_tools.py +++ b/tests/test_ci_tools.py @@ -11,8 +11,8 @@ import unittest from pathlib import Path REPO_ROOT = Path(__file__).resolve().parents[1] -CI_FAILURES = REPO_ROOT / "skills" / "ci-artifacts" / "scripts" / "ci_failures.py" -FIND_FIX = REPO_ROOT / "skills" / "merge-fix" / "scripts" / "find_fix.py" +CI_FAILURES = REPO_ROOT / "skills" / "kvb-ci-artifacts" / "scripts" / "ci_failures.py" +FIND_FIX = REPO_ROOT / "skills" / "kvb-git-merge-fix" / "scripts" / "find_fix.py" def _load(path: Path): @@ -55,7 +55,7 @@ class TestCiFailures(unittest.TestCase): "Ran 41 tests in 1.0s\n" "OK\n" "UP017 [*] Use `datetime.UTC` alias\n" - " --> skills/democracy/scripts/council.py:92:40\n" + " --> skills/kvb-org-organize/scripts/council.py:92:40\n" "Found 1 error.\n" "make: *** [Makefile:15: test] Error 1\n" "##[error]Process completed with exit code 2.\n" diff --git a/tests/test_council.py b/tests/test_council.py index 260feb4..7205155 100644 --- a/tests/test_council.py +++ b/tests/test_council.py @@ -1,4 +1,4 @@ -"""Exercise the democracy council script: election, staleness, release, gate.""" +"""Exercise the kvb-org-organize council script: election, staleness, release, gate.""" from __future__ import annotations @@ -10,7 +10,7 @@ import unittest from pathlib import Path REPO_ROOT = Path(__file__).resolve().parents[1] -COUNCIL = REPO_ROOT / "skills" / "democracy" / "scripts" / "council.py" +COUNCIL = REPO_ROOT / "skills" / "kvb-org-organize" / "scripts" / "council.py" class TestCouncil(unittest.TestCase): diff --git a/tests/test_dream.py b/tests/test_dream.py index 87ee609..7504d91 100644 --- a/tests/test_dream.py +++ b/tests/test_dream.py @@ -10,8 +10,8 @@ import unittest from pathlib import Path REPO_ROOT = Path(__file__).resolve().parents[1] -SKILL = REPO_ROOT / "skills" / "dream" / "SKILL.md" -HOOK = REPO_ROOT / "skills" / "dream" / "hooks" / "reminder.sh" +SKILL = REPO_ROOT / "skills" / "kvb-skills-dream" / "SKILL.md" +HOOK = REPO_ROOT / "skills" / "kvb-skills-dream" / "hooks" / "reminder.sh" PATCHER = REPO_ROOT / "scripts" / "enable-plugins.js" @@ -38,7 +38,7 @@ def _run_hook( class TestDreamSkill(unittest.TestCase): def test_skill_is_trigger_only(self): text = SKILL.read_text(encoding="utf-8") - self.assertIn("name: dream", text) + self.assertIn("name: kvb-skills-dream", text) self.assertIn("multiSelect: false", text) @@ -51,7 +51,7 @@ class TestDreamHook(unittest.TestCase): def test_first_run_hints_and_stamps(self): result = _run_hook(self.cwd, self.stamp) - self.assertIn("/dream", result.stdout) + self.assertIn("/kvb-skills-dream", result.stdout) self.assertTrue(self.stamp.is_file()) def test_second_run_is_silent_within_interval(self): @@ -60,12 +60,12 @@ class TestDreamHook(unittest.TestCase): def test_hint_returns_after_the_interval(self): _run_hook(self.cwd, self.stamp) - self.assertIn("/dream", _run_hook(self.cwd, self.stamp, interval="0").stdout) + self.assertIn("/kvb-skills-dream", _run_hook(self.cwd, self.stamp, interval="0").stdout) def test_corrupt_stamp_does_not_crash(self): self.stamp.parent.mkdir(parents=True, exist_ok=True) self.stamp.write_text("not-a-timestamp\n", encoding="utf-8") - self.assertIn("/dream", _run_hook(self.cwd, self.stamp).stdout) + self.assertIn("/kvb-skills-dream", _run_hook(self.cwd, self.stamp).stdout) def test_outside_a_repository_it_stays_silent(self): self.assertEqual(_run_hook(self.cwd).stdout, "") @@ -78,7 +78,7 @@ class TestDreamHook(unittest.TestCase): subprocess.run( ["git", "init", "-q", str(repo)], check=True, capture_output=True ) - self.assertIn("/dream", _run_hook(repo).stdout) + self.assertIn("/kvb-skills-dream", _run_hook(repo).stdout) self.assertTrue((repo / ".git" / ".dream-stamp").is_file()) self.assertEqual(_run_hook(repo).stdout, "") @@ -103,7 +103,7 @@ class TestDreamHook(unittest.TestCase): subprocess.run( ["git", *args], check=True, capture_output=True, env=env, cwd=str(repo) ) - self.assertIn("/dream", _run_hook(repo).stdout) + self.assertIn("/kvb-skills-dream", _run_hook(repo).stdout) self.assertEqual(_run_hook(tree).stdout, "") @@ -124,16 +124,59 @@ class TestSettingsRegistration(unittest.TestCase): self._patch() data = self._patch() entries = json.dumps(data["hooks"]["UserPromptSubmit"]) - self.assertEqual(entries.count("dream/hooks/reminder.sh"), 1) - self.assertEqual(entries.count("autotune/hooks/reminder.sh"), 1) + self.assertEqual(entries.count("kvb-skills-dream/hooks/reminder.sh"), 1) + self.assertEqual(entries.count("kvb-skills-tune/hooks/reminder.sh"), 1) gate = json.dumps(data["hooks"]["PreToolUse"]) - self.assertEqual(gate.count("democracy/scripts/council.py"), 1) - self.assertEqual(gate.count("democracy/scripts/watch.py"), 1) - self.assertEqual(entries.count("democracy/scripts/watch.py"), 1) + self.assertEqual(gate.count("kvb-org-organize/scripts/council.py"), 1) + self.assertEqual(gate.count("kvb-org-organize/scripts/watch.py"), 1) + self.assertEqual(entries.count("kvb-org-organize/scripts/watch.py"), 1) post = json.dumps(data["hooks"]["PostToolUse"]) - self.assertEqual(post.count("democracy/scripts/watch.py"), 1) - self.assertEqual(gate.count("subagent-model/scripts/log.py"), 1) - self.assertEqual(post.count("subagent-model/scripts/log.py"), 1) + self.assertEqual(post.count("kvb-org-organize/scripts/watch.py"), 1) + self.assertEqual(gate.count("kvb-org-perform/scripts/log.py"), 1) + self.assertEqual(post.count("kvb-org-perform/scripts/log.py"), 1) + + def test_hooks_of_renamed_skills_are_repointed(self): + base = Path(self.tmp.name) / "skills" + + def hook(command): + return {"hooks": [{"type": "command", "command": command}]} + + self.settings.write_text( + json.dumps( + { + "hooks": { + "UserPromptSubmit": [ + hook(f'bash "{base}/autotune/hooks/reminder.sh"'), + hook(f'bash "{base}/dream/hooks/reminder.sh"'), + hook(f'python3 "{base}/democracy/scripts/watch.py" watch'), + hook("echo keep"), + ], + "PreToolUse": [ + hook(f'python3 "{base}/democracy/scripts/council.py" gate'), + hook(f'python3 "{base}/democracy/scripts/watch.py" block'), + hook(f'python3 "{base}/subagent-model/scripts/log.py" spawn'), + ], + "PostToolUse": [ + hook(f'python3 "{base}/democracy/scripts/watch.py" watch'), + hook(f'python3 "{base}/subagent-model/scripts/log.py" persist'), + ], + } + } + ), + encoding="utf-8", + ) + data = self._patch() + text = json.dumps(data["hooks"]) + for old in ("/autotune/", "/dream/", "/democracy/", "/subagent-model/"): + self.assertNotIn(f"skills{old}", text) + self.assertIn("echo keep", text) + entries = json.dumps(data["hooks"]["UserPromptSubmit"]) + self.assertEqual(entries.count("kvb-skills-dream/hooks/reminder.sh"), 1) + self.assertEqual(entries.count("kvb-skills-tune/hooks/reminder.sh"), 1) + self.assertEqual(entries.count("kvb-org-organize/scripts/watch.py"), 1) + gate = json.dumps(data["hooks"]["PreToolUse"]) + self.assertEqual(gate.count("kvb-org-organize/scripts/council.py"), 1) + self.assertEqual(gate.count("kvb-org-perform/scripts/log.py"), 1) if __name__ == "__main__": diff --git a/tests/test_naming.py b/tests/test_naming.py new file mode 100644 index 0000000..f8a5d4c --- /dev/null +++ b/tests/test_naming.py @@ -0,0 +1,67 @@ +"""Pin every first-party skill name to kvb-- and the Agent Skills name rules.""" + +from __future__ import annotations + +import re +import unittest +from pathlib import Path + +REPO_ROOT = Path(__file__).resolve().parents[1] +SKILLS = REPO_ROOT / "skills" +README = REPO_ROOT / "README.md" +CATEGORIES = ("think", "create", "code", "ci", "git", "check", "org", "skills") +UNCATEGORIZED = frozenset({"kvb-cleanup", "kvb-help"}) +SPEC = re.compile(r"^[a-z0-9]+(-[a-z0-9]+)*$") +SCHEMA = re.compile(rf"^kvb-(?:{'|'.join(CATEGORIES)})-[a-z0-9]+(?:-[a-z0-9]+)*$") +NAME_LINE = re.compile(r"^name:\s*(\S+)\s*$", re.MULTILINE) +ORGANIGRAM_EDGE = re.compile(r"^\s*(\w+) --> \w+\[(kvb-[a-z0-9-]+)\]\s*$", re.MULTILINE) + + +class TestSkillNames(unittest.TestCase): + def setUp(self): + self.names = sorted(p.name for p in SKILLS.iterdir() if p.is_dir()) + + def test_name_field_matches_the_directory(self): + for name in self.names: + with self.subTest(skill=name): + text = (SKILLS / name / "SKILL.md").read_text(encoding="utf-8") + match = NAME_LINE.search(text) + self.assertIsNotNone(match, "SKILL.md has no name: line") + self.assertEqual(match.group(1), name) + + def test_names_follow_the_agent_skills_rules(self): + for name in self.names: + with self.subTest(skill=name): + self.assertRegex(name, SPEC) + self.assertLessEqual(len(name), 64) + self.assertNotRegex(name, "anthropic|claude") + + def test_names_use_a_listed_category(self): + for name in self.names: + if name in UNCATEGORIZED: + continue + with self.subTest(skill=name): + self.assertRegex(name, SCHEMA) + + def test_every_category_and_exception_is_in_use(self): + for category in CATEGORIES: + with self.subTest(category=category): + self.assertTrue( + any(n.startswith(f"kvb-{category}-") for n in self.names), + f"category {category} has no skill", + ) + self.assertLessEqual(UNCATEGORIZED, set(self.names)) + + def test_readme_organigram_places_every_skill_under_its_category(self): + text = README.read_text(encoding="utf-8") + section = text.split("## Organigram", 1)[1].split("\n## ", 1)[0] + edges = ORGANIGRAM_EDGE.findall(section) + self.assertEqual(sorted(name for _, name in edges), self.names) + for parent, name in edges: + with self.subTest(skill=name): + expected = "none" if name in UNCATEGORIZED else name.split("-")[1] + self.assertEqual(parent, expected) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_optimize.py b/tests/test_optimize.py index 8dbc33f..64f4030 100644 --- a/tests/test_optimize.py +++ b/tests/test_optimize.py @@ -1,4 +1,4 @@ -"""The self-improving skills must share the objective held by autotune.""" +"""The self-improving skills must share the objective held by kvb-skills-tune.""" from __future__ import annotations @@ -7,12 +7,12 @@ from pathlib import Path REPO_ROOT = Path(__file__).resolve().parents[1] SKILLS = REPO_ROOT / "skills" -ROUTERS = ("autoskill", "confidence") +ROUTERS = ("kvb-skills-auto", "kvb-check-confidence") class TestOptimizeObjective(unittest.TestCase): def test_autotune_names_the_three_axes(self): - text = (SKILLS / "autotune" / "SKILL.md").read_text(encoding="utf-8") + text = (SKILLS / "kvb-skills-tune" / "SKILL.md").read_text(encoding="utf-8") self.assertIn("## Objective", text) for axis in ("**Tokens**", "**Time**", "**Quality**"): self.assertIn(axis, text) @@ -21,9 +21,9 @@ class TestOptimizeObjective(unittest.TestCase): for skill in ROUTERS: text = (SKILLS / skill / "SKILL.md").read_text(encoding="utf-8") self.assertIn( - "`autotune` skill's **Objective**", + "`kvb-skills-tune` skill's **Objective**", text, - f"{skill} does not route to the autotune objective", + f"{skill} does not route to the kvb-skills-tune objective", ) diff --git a/tests/test_shortcuts.py b/tests/test_shortcuts.py index 8864aa6..0c2295a 100644 --- a/tests/test_shortcuts.py +++ b/tests/test_shortcuts.py @@ -1,4 +1,4 @@ -"""Validate the shortcuts skill table: rows present, sorted, ``soc``-prefixed, +"""Validate the kvb-skills-shortcuts skill table: rows present, sorted, ``soc``-prefixed, no two adjacent consonants.""" from __future__ import annotations @@ -8,7 +8,7 @@ import unittest from pathlib import Path REPO_ROOT = Path(__file__).resolve().parents[1] -SKILL = REPO_ROOT / "skills" / "shortcuts" / "SKILL.md" +SKILL = REPO_ROOT / "skills" / "kvb-skills-shortcuts" / "SKILL.md" ROW_RE = re.compile(r"^\|\s*`(?P[^`]+)`\s*\|") VOWELS = frozenset("aeiou") @@ -37,7 +37,7 @@ class TestShortcuts(unittest.TestCase): ] def test_shortcuts_present(self): - self.assertTrue(self.shortcuts, "no shortcut rows found in shortcuts skill") + self.assertTrue(self.shortcuts, "no shortcut rows found in kvb-skills-shortcuts skill") def test_shortcuts_sorted_ascending(self): self.assertEqual( diff --git a/tests/test_subagent_model.py b/tests/test_subagent_model.py index bc5e856..db9f8a5 100644 --- a/tests/test_subagent_model.py +++ b/tests/test_subagent_model.py @@ -1,4 +1,4 @@ -"""Exercise the subagent-model log: spawn hook, feedback, sandbox persist, report.""" +"""Exercise the kvb-org-perform log: spawn hook, feedback, sandbox persist, report.""" from __future__ import annotations @@ -10,7 +10,7 @@ import unittest from pathlib import Path REPO_ROOT = Path(__file__).resolve().parents[1] -LOG_PY = REPO_ROOT / "skills" / "subagent-model" / "scripts" / "log.py" +LOG_PY = REPO_ROOT / "skills" / "kvb-org-perform" / "scripts" / "log.py" class TestSubagentModelLog(unittest.TestCase): @@ -66,13 +66,13 @@ class TestSubagentModelLog(unittest.TestCase): def test_sandboxed_feedback_is_printed_and_stored_by_the_persist_hook(self): stdout = self._pending_feedback() - self._persist("python3 /x/skills/subagent-model/scripts/log.py feedback --description 'd'", stdout) + self._persist("python3 /x/skills/kvb-org-perform/scripts/log.py feedback --description 'd'", stdout) self.assertEqual(self._lines()[0]["kind"], "feedback") def test_persist_rejects_pending_lines_it_did_not_get_from_a_bare_log_call(self): stdout = self._pending_feedback() line = json.loads(stdout[len("pending: "):]) - call = "/x/skills/subagent-model/scripts/log.py feedback --description d" + call = "/x/skills/kvb-org-perform/scripts/log.py feedback --description d" for command, output, session in ( ("cat ci.log", stdout, "s1"), (f"{call}; cat ci.log", stdout, "s1"), @@ -82,7 +82,7 @@ class TestSubagentModelLog(unittest.TestCase): (call, stdout + stdout, "s1"), (call, "pending: " + json.dumps({**line, "extra": 1}), "s1"), (call, "pending: " + json.dumps({**line, "completed": "yes"}), "s1"), - ("/x/skills/subagent-model/scripts/log.py followup --description d", stdout, "s1"), + ("/x/skills/kvb-org-perform/scripts/log.py followup --description d", stdout, "s1"), ): self._persist(command, output, session) self.assertFalse(self.log.exists()) diff --git a/tests/test_watch.py b/tests/test_watch.py index 1cacc33..a063054 100644 --- a/tests/test_watch.py +++ b/tests/test_watch.py @@ -1,4 +1,4 @@ -"""Exercise the democracy resource watch: stages, projection, block, admit, alerts, caches.""" +"""Exercise the kvb-org-organize resource watch: stages, projection, block, admit, alerts, caches.""" from __future__ import annotations @@ -13,7 +13,7 @@ import unittest from pathlib import Path REPO_ROOT = Path(__file__).resolve().parents[1] -WATCH = REPO_ROOT / "skills" / "democracy" / "scripts" / "watch.py" +WATCH = REPO_ROOT / "skills" / "kvb-org-organize" / "scripts" / "watch.py" LIMITS = {"warn": 40, "stop": 15, "critical": 12}