Search Brigade

Search Brigade pages and docs.

[ COMPARISON ]

Keep an agent skill's score honest after you edit it

How do you keep an agent skill's score honest when the skill changes

Updated July 14, 2026 · Escoffier Labs

Short answer: Brigade’s outcome ledger stamps every record with a SHA-256 content_fingerprint of the artifact at capture time. outcome rank and outcome explain default to a score that drops proven-stale records (fingerprinted against a different revision) while keeping lifetime counts visible, so an edited skill re-earns its score instead of inheriting credit for text that no longer exists. Static or self-graded skill scores have no concept of “this text changed”. They keep counting old signal against new content until someone manually resets it.

The problem

A skill collects passes and failures over weeks. Then you edit it: fix a bad instruction, add a step, rewrite the whole thing. A static score does not know the difference. It keeps averaging in signal earned by the old text, so a skill that was rewritten yesterday can outrank one that has been solid and unchanged for a month, on the strength of evidence that no longer describes what ships. Self-graded scores have the same blind spot one layer up: the model that wrote the skill also grades whether it worked, so there is no independent signal to invalidate in the first place.

The path

brigade work verify run --target . --command "pytest -q" --capture <skill-id>   # verify, then capture in one step
brigade outcome rank --target .                    # drops stale-fingerprint records by default
brigade outcome explain <skill-id> --target .       # shows lifetime vs. current-fingerprint signal
brigade outcome reconcile --apply --target .        # ratchet scores the current-fingerprint cohort only

outcome capture and outcome record stamp each new record with the SHA-256 of the artifact’s content: the installed copy first, the registry master as fallback. A skill bundle’s fingerprint covers every file in the bundle (path plus content hash, skipping .DS_Store and the skill.json sidecar), so editing a bundled helper invalidates signal the same way editing SKILL.md does. A memory card’s fingerprint folds in the transitive closure of the cards it [[links]], so editing a linked card invalidates every card that reaches it. Pre-fingerprint records are grandfathered in, so a never-edited artifact’s score and rank output stay byte-identical until you actually edit something.

The promotion ratchet uses the same idea for the decision that matters most: outcome reconcile and outcome fork score the current-fingerprint cohort, so an edited skill has to re-earn install_min_helped against the text that now ships, not coast on signal for a version that’s gone. Thresholds, cooldown, and the forward-only ratchet are unchanged, only the score fed into them narrows.

Comparison

Static / self-graded skill scoringBrigade outcome ledger
Detects an edited skillno, score keeps averaging old and new text togetheryes, content_fingerprint drops stale records automatically
Who grades the signaloften the model that wrote the skillverify exit codes and other model-unauthored signals
Scopes by runtime contextno, one score for every harness/modelyes, outcome rank --by-capability shrinks toward the pooled rate for thin per-context evidence
Weights recent evidenceno, or only via a manual resetyes, outcome rank --recency (45-day half-life by default)
Promotion decisionusually a manual callratchet scores the current-fingerprint cohort automatically
Backward compatible with old recordsn/ayes, pre-fingerprint records are grandfathered, byte-identical until an edit happens

outcome rank --by-capability resolves a capability fingerprint over {harness, model_family, python, platform} from a runtime-context manifest (Brigade version, interpreter major.minor, platform, best-effort harness and model) captured on each record, and shrinks a thin current-context cohort toward the pooled rate with (helped + kappa*pooled_rate)/(total + kappa), kappa=4.0. It sorts by the shrunk estimate, then on-capability sample size, then the pooled rate, so “what worked under my current context” wins ties over raw volume. outcome explain shows the per-capability breakdown behind that number.

outcome rank --recency layers a half-life on top: a signal’s weight halves every 45 days by default (--recency-half-life DAYS to change it), so credit earned under an environment you’ve since drifted away from fades without rewriting the append-only log. It applies to the pooled score by default and composes with --by-capability. Both flags are off by default, so nothing changes until you ask for it. The promotion ratchet never uses recency, only the fingerprint-scoped cohort.

When static scoring is fine

If a skill never changes after you write it, or you have exactly one harness and one model and never plan to add another, a static or manually-tracked score costs less to run and gets you most of the way there. Fingerprinting and capability shrinkage earn their keep once skills get edited regularly or you run more than one agent harness against the same skill set, which is the common case once a team is past the first few weeks.

Questions

Does this rewrite old outcome records? No. The ledger stays append-only and hash-chained. Fingerprinting adds fields to new records and changes what rank/explain read, it does not touch history.

What happens to records from before fingerprinting existed? They’re grandfathered into the current score, so a never-edited skill’s rank output is byte-identical to before. They only start getting excluded once the artifact is actually edited.

Does capability-aware ranking need me to declare my harness or model? No. The manifest is captured automatically, best-effort, tagged with its source, on every outcome capture / outcome record call.

Can I still see lifetime totals alongside the current-fingerprint score? Yes. outcome rank and outcome explain keep lifetime counts visible alongside the current-fingerprint score and the stale/legacy record counts.

Quickstart and outcome loop docs.

Try Brigade

One reviewed source for the memory, tools, and MCP your AI coding agents share, merged into each tool's native config with a review gate and a receipt for every change. Local files, no daemon, no lock-in.

Quickstart · GitHub · All comparisons