feat(check): score fix, break, efficiency and speed in one block
🧪 Test / 🧪 Lock + lint (push) Waiting to run

kvb-check-efficiency measures a change against its base: tokens.py counts skill text tokens and listing words, measure.py runs one command in a base worktree and the working tree (one run per side, the mean of five over 100, an estimate marked ~ when other processes load the CPU). kvb-check-speed reads wall time from the same run and is not relevant for skills. kvb-check-score prints fix, break, efficiency, speed and the product score with emojis plus a gate line: below 90/5 it reports, over 100 it requires asking the operator before the commit.

Every skill that reported confidence and break risk now shows the score block; the 90/5 bar adds efficiency and speed at most 100. Commit blocks and the commit call's approval prompt name worktree, branch, diff stat and the score values, also for merges. 24 descriptions were shortened to keep the skill listing within its budget.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kevin Veen-BirkenbachandClaude Opus 5.5 committed 2026-11-04 17:07:24 +01:00
1 parent 6fa0311704
commit 0343a2f3ce
46 files changed
+1145 -118

No files matched your search

+118
View File
@@ -0,0 +1,118 @@
#!/usr/bin/env python3
"""Fold fix confidence, break risk, efficiency and speed into one score line and one gate line.
Args:
--fix: fix confidence in percent, 0 to 100.
--break: break risk in percent, 0 to 100.
--efficiency: efficiency in percent above 0; `-` when not measured or not
relevant, `new` when the change has no base. Both count as 100 in the score.
--speed: speed in percent above 0, `-` or `new` as for --efficiency.
Output:
Line 1: `🎯 fix <f> % · 💥 break <b> % · 🌱 efficiency <e> % · ⚡ speed <s> % · 🏆 score <n>`,
`–` in place of `<x> %` for `-`, `new` for `new`. Score is
fix * (100 - break) / 100 * 100 / efficiency * 100 / speed, capped to 0..100, rounded half up.
Line 2: the gate verdict, `✅ gate: ...`, `⛔ gate: ...` or `⚠️ gate: ...`.
Exit codes:
0 gate passed, 1 fix under 90 or break over 5, 2 usage error,
3 efficiency or speed over 100 or new: ask the operator before the commit.
"""
from __future__ import annotations
import argparse
import math
import sys
FIX_MIN = 90
BREAK_MAX = 5
COST_MAX = 100
DASH = "-"
NEW = "new"
def percent(text: str) -> float:
try:
value = float(text)
except ValueError:
raise argparse.ArgumentTypeError(f"{text!r} is not a number") from None
if not 0 <= value <= 100:
raise argparse.ArgumentTypeError(f"{text!r} is outside 0..100")
return value
def cost(text: str) -> float | str:
if text in (DASH, NEW):
return text
try:
value = float(text)
except ValueError:
raise argparse.ArgumentTypeError(f"{text!r} is neither a number, {DASH!r} nor {NEW!r}") from None
if not math.isfinite(value) or value <= 0:
raise argparse.ArgumentTypeError(f"{text!r} must be a positive number")
return value
def number(value: float) -> str:
return f"{value:g}"
def shown(value: float | str) -> str:
if value == DASH:
return "–"
if value == NEW:
return NEW
return f"{number(value)} %"
def factor(value: float | str) -> float:
return 100 / value if isinstance(value, float) else 1.0
def score(fix: float, risk: float, efficiency: float | str, speed: float | str) -> int:
raw = fix * (100 - risk) / 100 * factor(efficiency) * factor(speed)
return math.floor(min(max(raw, 0.0), 100.0) + 0.5)
def over(name: str, value: float | str) -> str | None:
if value == NEW:
return f"{name} {NEW}"
if isinstance(value, float) and value > COST_MAX:
return f"{name} {number(value)} % > {COST_MAX}"
return None
def gate(fix: float, risk: float, efficiency: float | str, speed: float | str) -> tuple[str, int]:
failed = []
if fix < FIX_MIN:
failed.append(f"fix {number(fix)} % < {FIX_MIN}")
if risk > BREAK_MAX:
failed.append(f"break {number(risk)} % > {BREAK_MAX}")
if failed:
return f"⛔ gate: {', '.join(failed)}", 1
costly = [text for text in (over("efficiency", efficiency), over("speed", speed)) if text]
if costly:
return f"⚠️ gate: {', '.join(costly)}: ask the operator before the commit", 3
return f"✅ gate: {FIX_MIN}/{BREAK_MAX}, efficiency and speed <= {COST_MAX}", 0
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
parser.add_argument("--fix", type=percent, required=True)
parser.add_argument("--break", dest="risk", type=percent, required=True)
parser.add_argument("--efficiency", type=cost, required=True)
parser.add_argument("--speed", type=cost, required=True)
args = parser.parse_args()
total = score(args.fix, args.risk, args.efficiency, args.speed)
print(
f"🎯 fix {number(args.fix)} % · 💥 break {number(args.risk)} % · "
f"🌱 efficiency {shown(args.efficiency)} · ⚡ speed {shown(args.speed)} · 🏆 score {total}"
)
verdict, code = gate(args.fix, args.risk, args.efficiency, args.speed)
print(verdict)
return code
if __name__ == "__main__":
sys.exit(main())