refactor(skills)!: rename every skill to kvb-<category>-<name>
All 38 first-party skills move to kvb-<category>-<name> with the categories think, create, code, ci, git, check, org and skills; kvb-cleanup and kvb-help are the only uncategorized names. tests/test_naming.py pins the schema, the Agent Skills name rules and the README organigram. enable-plugins.js repoints hook commands of renamed skills in settings.local.json so a stale script path cannot block tools. BREAKING CHANGE: the old skill names and slash commands (/commit-next, /dream, /autotune, ...) are gone; use their kvb- successors listed in the README organigram. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
64403cefca
commit
624baccfc4
59 files changed
+504
-312
No files matched your search
@@ -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-<category>-<name>` 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 (`<repo>/.agents/skills` and `<repo>/.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.
|
||||
|
||||
|
||||
+30
-12
@@ -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}`);
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
---
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
@@ -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 <ref>` or `/advocate <a>..<b>`: that commit or range.
|
||||
- `/advocate` alone: the index if it is non-empty, else `HEAD`.
|
||||
- `/kvb-check-legal <ref>` or `/kvb-check-legal <a>..<b>`: 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
|
||||
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
---
|
||||
|
||||
@@ -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
|
||||
File renamed without changes.
@@ -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 <target> or when the
|
||||
new failures as they appear. Trigger on /kvb-ci-observe <target> 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 <run>`. 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 <run>`. 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.
|
||||
@@ -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 <run>`
|
||||
For a GitHub Actions run, the kvb-ci-artifacts skill's `ci_failures.py <run>`
|
||||
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
|
||||
@@ -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.
|
||||
@@ -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:<path>`) 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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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 <symbol> --path <path>`) for a change
|
||||
- **Search every branch** (the kvb-git-merge-fix skill's `find_fix.py -S <symbol> --path <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/<slug>`, 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.
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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-<repo>`, 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,
|
||||
@@ -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.
|
||||
---
|
||||
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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 <description> or when the
|
||||
into the current branch. Trigger on /kvb-git-merge-fix <description> 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 <base>..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
|
||||
File renamed without changes.
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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 |
|
||||
@@ -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/<slug> "
|
||||
"--work '<one line>'. Exit 3 or 4 means another agent holds it; read the "
|
||||
"democracy skill.",
|
||||
"kvb-org-organize skill.",
|
||||
file=sys.stderr,
|
||||
)
|
||||
return 2
|
||||
@@ -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,
|
||||
)
|
||||
@@ -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.
|
||||
@@ -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"},
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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/<name>/SKILL.md` there (or in the current
|
||||
project for project-specific behavior), then mirror the skill directory
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
@@ -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.
|
||||
---
|
||||
|
||||
@@ -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,
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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.
|
||||
---
|
||||
|
||||
@@ -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,
|
||||
@@ -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(
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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):
|
||||
|
||||
+59
-16
@@ -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__":
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
"""Pin every first-party skill name to kvb-<category>-<name> 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()
|
||||
@@ -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",
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -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<shortcut>[^`]+)`\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(
|
||||
|
||||
@@ -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())
|
||||
|
||||
+2
-2
@@ -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}
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user