Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Evaluate a repo agent harness (AGENTS.md, rules, skills, skill refs) for broken paths/commands, redundant instructions, and usefulness using a stack-agnostic dual-judge protocol with planted traps. HIGH PRIORITY questionnaires at top: Q1 optional docs, Q2 B/C budget before Track A (certainty/tokens). A always runs after Q2; B/C opt-in. ADRs/RFCs excluded from T2. Mixed apply uses 11-mixed-apply.md (KEEP/CUT). Use when the user says harness eval, harness-eval, harness debug, audit AGENTS.md, audi
.claude/skills/tech-leads-club-harness-eval/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-09 | ✗→✓ | ▲ Improved | 130% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 68% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 146% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 326% | 0% |
| case-14 | ✗→✓ | ▲ Improved | 194% | 0% |
Run a full, stack-agnostic harness evaluation and stop at reports. Do not auto-edit AGENTS.md or skills unless the user explicitly asks after reviewing Ship/Slim.
Stop and ask before continuing. Do not skip these gates. Do not silently include optional docs or spawn B/C judges.
Order after inventory: Q1 (if needed) → Q2 → then Track A (A always runs) → B/C only if approved.
When optional-docs-candidates.md lists optional types, ask before Q2 / Track A:
markdownInventory found cited project docs outside the agent skill trees. - **Always in scope:** skill-tree files (`.agents/skills`, `.cursor/skills`, `.claude/skills`) - **Always excluded:** ADRs / RFCs / decision-record trees (never scored as T2) - **Optional (default: omit):** see types/paths in `optional-docs-candidates.md` Include any optional doc types or paths in this run? Reply with: `none` (default), type ids (e.g. `docs`), and/or specific paths.
Re-run inventory with --include-doc-type / --include-doc only after the user answers. If no optional types, skip Q1.
Ask before Track A so the user sets spend up front. Track A always runs next (deterministic, ~0 model tokens). B/C run only if approved.
markdownChoose eval scope for this run (before Track A). | Track | Question | Certainty | Token consumption | |-------|----------|-----------|-------------------| | **A — Correctness** | Cited path/command exists? | **Highest** — script only, no LLM. Prefers false negatives over false BROKEN. | **~0 model tokens** (always runs next) | | **B — Redundancy** | Would an agent rediscover this cheaply without the harness? | **Medium** — dual LLM + plants; Ship only if trap PASS and both agree. Disagree → Hold. Less model-sensitive than C. | **High** — 2 judges × every claim (~N in this inventory). Each may spot-check the repo. | | **C — Usefulness** | Does this surface change behavior vs theory/demo/overlap? | **Lowest / most subjective** — dual LLM + plants + fan-in; **model-sensitive**. Slim/Mixed need gates; prefer second-model check before large deletes. | **Highest** — 2 judges × every surface (whole files; often dominates the run). | Notes: Ship (B) ≠ Slim (C). Rediscoverable ≠ useless. A always runs; B/C are optional. Reply with one of: `A only`, `B`, `C`, or `B+C`.
Fill claim count from claims.md when known; surface count ≈ T0+T1+T2 markdown after extract (or say “after surfaces_extract” if not run yet).
A only: run Track A; present 04; stop (no B/C judges).B: Track A, then Steps 4–6.C: Track A, then Steps 7–10 (C does not need B).B+C: Track A, then Steps 4–11.If the user already requested B/C/full eval in the triggering message, treat as approval — still show the Q2 table once so costs are visible.
This skill is self-contained. Protocol, scripts, and judge prompts live under this skill directory (the folder that contains this SKILL.md). Resolve SKILL_DIR as that directory — never assume another install path.
04 / 07 / 10 reports).python3 "$SKILL_DIR/scripts/<name>.py" ....Run outputs (not protocol) go to the target repo at .harness-eval/runs/<run-id>/.
bin/*)..agents/skills, .cursor/skills, .claude/skills). ADRs / RFCs (decision-record trees) are always excluded from T2 surfaces. Other cited project docs are optional — default omit; ask via Q1 at the top of this skill, then re-run with --include-doc-type / --include-doc.SPEC_FOLDER, {x}, [feature]) are never BROKEN. Never normalize paths with str.lstrip('./').trap-key.json). Ship only if trap gate PASS and dual REDUNDANT with Judge2 cost ≤ 1.08-usefulness-j1.md or usefulness-trap-key.json. Slim only if trap PASS, dual SLIM/ROUTING-ONLY, and fan-in PASS (no other harness surface hard-loads the path as SoT — merge enforces this on the full skill tree, not just --seed). Usefulness is model-sensitive — record model: <id> in both score files; prefer same model within a run; re-judge on a second model before large Slim deletes.*-fast models.python3 "$SKILL_DIR/scripts/slim_fanin.py" --path <P> reports citers) unless those consumers are updated in the same change.See app/... / lib/... / test/... — that swaps SoT for a code-tree pointer. Judge evidence paths stay in score tables only; if the behavior-changing contract must survive, keep a short in-skill rule or snippet.11-mixed-apply.md with per-ID KEEP (from Keep-core columns) and CUT (from Slim columns). Apply agents must follow that file only — do not re-judge, redesign, or invent a different pattern than KEEP. Empty Keep-core/Slim cells → skip that path (Hold).Set SKILL_DIR to the directory containing this SKILL.md. Verify:
$SKILL_DIR/references/PROTOCOL.md$SKILL_DIR/scripts/inventory_extract.py$SKILL_DIR/scripts/track_a_correctness.py$SKILL_DIR/scripts/merge_agreement.py$SKILL_DIR/scripts/surfaces_extract.py$SKILL_DIR/scripts/merge_usefulness.py$SKILL_DIR/scripts/slim_fanin.py$SKILL_DIR/scripts/doc_scope.pyIf missing, the skill install is broken — stop.
From the target repo root:
bashRUN_ID=$(date -u +%Y-%m-%d)-full python3 "$SKILL_DIR/scripts/inventory_extract.py" --root . --run-id "$RUN_ID" # Optional scope: AGENTS.md + one-hop related skills only # python3 "$SKILL_DIR/scripts/inventory_extract.py" --root . --run-id "$RUN_ID" --seed AGENTS.md
Expected under .harness-eval/runs/$RUN_ID/: inventory.json, claims.jsonl, claims.md, trap-key.json, optional-docs-candidates.md (+ .json).
Read optional-docs-candidates.md. If optional types exist, run Q1 from User questionnaires. Re-run inventory only after approval:
bashpython3 "$SKILL_DIR/scripts/inventory_extract.py" --root . --run-id "$RUN_ID" \ --include-doc-type docs # and/or --include-doc path
Run Q2 from User questionnaires before Track A. Record the answer (A only / B / C / B+C). Do not start Steps 4+ unless B and/or C were approved.
bashpython3 "$SKILL_DIR/scripts/track_a_correctness.py" --root . --run-id "$RUN_ID"
Expected: 04-correctness.md (includes term definitions at top). Spot-check that .agents/... cites resolve (not agents/...).
Summarize Track A (broken count + notable clusters). If Q2 was A only, stop. Otherwise continue to the approved B and/or C steps.
Read references/judge-prompts.md (Track B Judge1). Spawn an independent subagent with an allowlisted model. Point it at .harness-eval/runs/$RUN_ID/claims.md. It writes 05-redundancy-j1.md (include model: <id>).
Judge1 may read inventory.json. Must not read trap-key.json.
Read references/judge-prompts.md (Track B Judge2). Spawn a second subagent. Writes 06-blind-scores.md.
Forbidden for Judge2: trap-key.json, 05-redundancy-j1.md, 07-agreement.md, prior agreement reports.
Prefer Steps 4 and 5 in parallel.
bashpython3 "$SKILL_DIR/scripts/merge_agreement.py" --run-dir .harness-eval/runs/$RUN_ID
Expected: 07-agreement.md (Ship/Review/Hold + What these words mean). On trap FAIL: fix plants per PROTOCOL, rescore P00x, re-merge — do not Ship.
bashpython3 "$SKILL_DIR/scripts/surfaces_extract.py" --root . --run-id "$RUN_ID"
Expected: surfaces.md, surfaces.json, usefulness-trap-key.json.
Read references/judge-prompts.md (Usefulness Judge1). Spawn subagent with allowlisted model (record same id in header). Writes 08-usefulness-j1.md.
Must not read usefulness-trap-key.json.
Read Usefulness Judge2 prompt. Prefer same model as Step 8 for agreement stability. Writes 09-usefulness-j2.md.
Forbidden: usefulness-trap-key.json, 08-usefulness-j1.md, 10-usefulness-agreement.md, and using Track B 05/06/07 to decide usefulness classes.
Prefer Steps 8 and 9 in parallel.
bashpython3 "$SKILL_DIR/scripts/merge_usefulness.py" --run-dir .harness-eval/runs/$RUN_ID
Expected: 10-usefulness-agreement.md (Slim/Keep-core/Mixed/Hold + What these words mean), 11-mixed-apply.md (KEEP/CUT per Mixed ID), plus slim-fanin.json. On trap FAIL: do not Slim. Surfaces with slim-fanin-blocked are Hold — not Slim apply candidates.
Summarize from the agreement reports (each starts with term definitions):
04-correctness.md07-agreement.md10-usefulness-agreement.md11-mixed-apply.md when Mixed count > 0 (the only Mixed apply path)Stop unless the user asks to apply Ship/Slim/Mixed. When applying:
11-mixed-apply.md and execute KEEP/CUT per ID only (rule 12). Never re-judge from the Mixed path list alone. Never add code-tree path pointers as substitutes for cut demos (rule 11).User says: "run harness eval on this repo"
Actions: inventory → Q1 if needed → Q2 (B/C budget table) → Track A → if approved, Steps 4–11. Parallel B judges, then C judges. Present agreements (terms are in the files).
User says: "run Track C usefulness on the last harness-eval run"
Actions: Steps 7–11 on that RUN_ID (inventory must already exist).
User says: "setup harness" / "init harness" → harness setup (not this skill). User says: "specify feature" → tlc-spec-driven.
Cause: KEEP/KEEP-CORE plants were deck duplicates, or blind judge mis-family. Solution: use skill’s fixed plant templates; rescore plants; re-merge.
.agents/...Cause: bad path normalization. Solution: skill script must use normalize_cite (strip ./ only). Re-run Track A from $SKILL_DIR/scripts/.
Cause: missing/allowlisted model or *-fast blocked. Solution: re-spawn with an allowlisted non-fast model.
Expected: usefulness is model-sensitive. Re-run C1+C2 on a second model; intersection of Slim bands is the safe delete set.
Cause: apply agent re-judged from the Mixed path list instead of following KEEP/CUT. Solution: apply only via 11-mixed-apply.md; if that file is missing, re-run merge_usefulness.py; if Keep-core/Slim cells are vague, re-score those IDs before apply.
references/ missing from inventoryCause: path normalize used lstrip("./") and turned .agents/… into agents/…. Solution: doc_scope.normalize_rel must strip only a ./ prefix (same rule as Track A).
Cause: old inventory treated all one-hop docs/** as T2. Solution: v1.7+ excludes decision-record trees; only user-approved optional doc types (never ADR/RFC) can enter T2.
Cause: content OVERLAP/Slim without fan-in — older runs, or apply skipped the gate. Solution: restore the checklist body; re-merge with merge_usefulness.py (fan-in scans full skill trees). Confirm with slim_fanin.py --path <P>.
Cause: incomplete skill folder. Solution: restore $SKILL_DIR/scripts/ and references/.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-08 | pass→pass | 11,310 | 6,035 | -47% | 1 | 1 | 0% | 1,960 | 5,272 | +169% | 0 | 0 | — |
case-09 | fail→pass | 12,873 | 5,984 | -54% | 1 | 1 | 0% | 2,239 | 5,155 | +130% | 0 | 0 | — |
case-01 | fail→fail | 23,322 | 10,286 | -56% | 1 | 1 | 0% | 3,605 | 4,715 | +31% | 0 | 0 | — |
case-02 | fail→fail | 21,114 | 5,367 | -75% | 1 | 1 | 0% | 4,043 | 4,550 | +13% | 0 | 0 | — |
case-03 | fail→fail | 2,044 | 6,769 | +231% | 1 | 1 | 0% | 371 | 4,584 | +1136% | 0 | 0 | — |
case-04 | fail→fail | 24,597 | 6,572 | -73% | 1 | 1 | 0% | 5,182 | 4,784 | -8% | 0 | 0 | — |
case-05 | fail→pass | 19,868 | 11,130 | -44% | 1 | 1 | 0% | 3,632 | 6,085 | +68% | 0 | 0 | — |
case-06 | pass→fail | 6,931 | 13,500 | +95% | 1 | 1 | 0% | 1,159 | 5,159 | +345% | 0 | 0 | — |
case-07 | pass→pass | 16,210 | 9,048 | -44% | 1 | 1 | 0% | 2,550 | 5,550 | +118% | 0 | 0 | — |
case-10 | pass→pass | 9,098 | 4,568 | -50% | 1 | 1 | 0% | 1,578 | 4,955 | +214% | 0 | 0 | — |
case-11 | fail→pass | 13,695 | 8,538 | -38% | 1 | 1 | 0% | 2,284 | 5,623 | +146% | 0 | 0 | — |
case-12 | pass→pass | 7,860 | 4,742 | -40% | 1 | 1 | 0% | 1,264 | 4,997 | +295% | 0 | 0 | — |
case-13 | fail→pass | 7,870 | 5,984 | -24% | 1 | 1 | 0% | 1,240 | 5,281 | +326% | 0 | 0 | — |
case-14 | fail→pass | 11,728 | 5,371 | -54% | 1 | 1 | 0% | 1,766 | 5,195 | +194% | 0 | 0 | — |
case-15 | fail→pass | 9,198 | 3,255 | -65% | 1 | 1 | 0% | 1,492 | 4,710 | +216% | 0 | 0 | — |
case-16 | fail→fail | 10,235 | 3,964 | -61% | 1 | 1 | 0% | 1,476 | 4,784 | +224% | 0 | 0 | — |
case-17 | pass→pass | 5,946 | 5,283 | -11% | 1 | 1 | 0% | 903 | 5,084 | +463% | 0 | 0 | — |
case-18 | fail→pass | 13,198 | 2,688 | -80% | 1 | 1 | 0% | 2,039 | 4,607 | +126% | 0 | 0 | — |
case-19 | fail→pass | 14,318 | 5,416 | -62% | 1 | 1 | 0% | 2,417 | 5,221 | +116% | 0 | 0 | — |
case-20 | fail→fail | 10,695 | 5,891 | -45% | 1 | 1 | 0% | 1,542 | 5,112 | +232% | 0 | 0 | — |
case-21 | fail→pass | 13,819 | 8,273 | -40% | 1 | 1 | 0% | 1,765 | 5,566 | +215% | 0 | 0 | — |
case-22 | pass→pass | 14,282 | 3,915 | -73% | 1 | 1 | 0% | 1,863 | 4,795 | +157% | 0 | 0 | — |
case-23 | fail→fail | 7,226 | 3,301 | -54% | 1 | 1 | 0% | 978 | 4,827 | +394% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted, and 19 counted toward the lift figure. The other 4 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +35 percentage points is the difference between those two pass rates over the 19 comparable cases. 2 cases got worse with the skill loaded, and they are included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.