Files
claude-plugin-inference-arb…/tests/classify.test.sh
Oleks 105e9f5bae Phase 7 acceptance: two FR-5.4/S3 fidelity fixes found by running the real pipeline
S1-S3 and S5-S8 pass; S4 is prepared but deliberately unfiled pending user
sign-off (tasks.md 7.4 stays unchecked).

Two bugs surfaced by running the composed pipeline against real data rather
than synthetic fixtures, both in load-bearing places:

audit-snapshot: cost_per_invocation folded to 0 when a candidate had zero
invocations in a window, so a step that simply did not run reported -100% and
direction() called it `shrunk`. That is the quiet-window artefact FR-5.4 exists
to prevent, one level up from absolute tokens, and it contradicted direction()'s
own docstring. It is now None, metric_delta marks the pair `unmeasured`,
direction returns a new `unmeasured` status, and the pages render "not run".

tests/calibration/mask-worktree-audit.py: recomputed script_loc from scripts
alone, silently dropping all 1051 LOC of worktree-discipline's hooks. Masking
one 272-LOC script appeared to remove 1323, taking script_coverage 0.353 -> 0.083
instead of 0.297, which let S3 pass partly on an artefact of the mask. The mask
now matches build_aggregate. S3 still flags the known cut `high` /
llm-over-script-digest on the corrected, harder input.

Both fixes carry regression tests; suite is 156 assertions, exit 0.
2026-07-29 18:15:47 +03:00

134 lines
5.8 KiB
Bash
Executable File

#!/usr/bin/env bash
# bin/boundary-classify: rubric §6 confidence table + the FR-4.2 filing gate.
# Synthetic cases with hand-computable expectations, then the two calibration
# gates from tasks.md 4.4.
set -euo pipefail
cd "$(dirname "${BASH_SOURCE[0]}")"
BIN=../bin/boundary-classify
tmp=$(mktemp -d)
trap 'rm -rf "$tmp"' EXIT
fail=0
# field <json-file> <candidate-index> <key>
field() {
python3 -c "import json,sys;print(json.load(open(sys.argv[1]))['candidates'][int(sys.argv[2])][sys.argv[3]])" "$@"
}
summary() {
python3 -c "import json,sys;print(json.load(open(sys.argv[1]))['summary'][sys.argv[2]])" "$@"
}
check() {
local what=$1 got=$2 want=$3
if [ "$got" = "$want" ]; then
echo " ok $what = $want"
else
echo " FAIL $what = $got (want $want)" >&2
fail=1
fi
}
# A complete, high-confidence position-3 candidate with a measured 10% share.
mk() {
cat >"$tmp/in.json" <<EOF
{
"target": "synthetic",
"audited_spend_weighted_tokens": 1000000,
"candidates": [{
"candidate_id": "syn/skill/step",
"skill": "syn:skill",
"position": ${1:-\"llm-over-script-digest\"},
"determinism_tests": {"T1": true, "T2": ${2:-true}, "T3": true, "T4": ${3:-true}, "T5": true},
"falsifiability": {
"signature": "f(x: int) -> str",
"examples": ["1 -> a", "2 -> b", "EDGE: 0 -> z"],
"edge_case_index": 2,
"overrule_case": ${4:-\"a human would say no when the tree is live\"}
},
"escalation_path": ${5:-\"unclassifiable rows escalate\"},
"digest_schema": "one typed row per item",
"measurement": {"offload_value": ${6:-100000}, "invocations": 12, "attributed_turns": 200}
}]
}
EOF
$BIN "$tmp/in.json" >"$tmp/out.json"
}
echo "== complete position-3 candidate, measured 10% share -> high / file =="
mk
check "confidence" "$(field "$tmp/out.json" 0 boundary_confidence)" "high"
check "verdict" "$(field "$tmp/out.json" 0 verdict)" "file"
check "share" "$(field "$tmp/out.json" 0 share_of_audited_spend)" "0.1"
check "strength" "$(field "$tmp/out.json" 0 measurement_strength)" "measured"
echo "== FR-4.2 hard gate: no overrule case -> boundary question, never filed =="
mk '"llm-over-script-digest"' true true null
check "confidence" "$(field "$tmp/out.json" 0 boundary_confidence)" "medium"
check "verdict" "$(field "$tmp/out.json" 0 verdict)" "boundary-question"
echo "== T4 fails -> low (rubric §6 bottom row) =="
mk '"llm-over-script-digest"' true false
check "confidence" "$(field "$tmp/out.json" 0 boundary_confidence)" "low"
echo "== T2 fails -> low =="
mk '"llm-over-script-digest"' false true
check "confidence" "$(field "$tmp/out.json" 0 boundary_confidence)" "low"
echo "== no escalation path -> medium (positioning question P3) =="
mk '"llm-over-script-digest"' true true '"human overrules on live trees"' null
check "confidence" "$(field "$tmp/out.json" 0 boundary_confidence)" "medium"
echo "== position 4 -> no-offload, a finding rather than a question =="
mk '"pure-inference"'
check "verdict" "$(field "$tmp/out.json" 0 verdict)" "no-offload"
echo "== measured but 0.5% of spend -> below the 2% filing threshold =="
mk '"llm-over-script-digest"' true true '"human overrules"' '"escalates"' 5000
check "confidence" "$(field "$tmp/out.json" 0 boundary_confidence)" "high"
check "verdict" "$(field "$tmp/out.json" 0 verdict)" "boundary-question"
echo "== position 2 without a staleness plan -> medium =="
mk '"script-with-compiled-judgment"'
check "confidence" "$(field "$tmp/out.json" 0 boundary_confidence)" "medium"
echo "== CALIBRATION GATE 1 (tasks.md 4.4): token-budget -> zero high-confidence =="
$BIN calibration/token-budget.judgments.json >"$tmp/tb.json"
check "high_confidence" "$(summary "$tmp/tb.json" high_confidence)" "0"
check "to_file" "$(summary "$tmp/tb.json" to_file)" "0"
check "conclusion" "$(summary "$tmp/tb.json" conclusion)" "nothing to offload here"
echo "== CALIBRATION GATE 2 (tasks.md 4.4): masked worktree-discipline -> known cut is high =="
$BIN calibration/worktree-discipline-masked.judgments.json >"$tmp/wd.json"
check "high_confidence" "$(summary "$tmp/wd.json" high_confidence)" "1"
check "top candidate" "$(field "$tmp/wd.json" 0 candidate_id)" \
"worktree-discipline/sweep-worktrees/worktree-safety-classification"
check "position" "$(field "$tmp/wd.json" 0 position)" "llm-over-script-digest"
check "confidence" "$(field "$tmp/wd.json" 0 boundary_confidence)" "high"
check "drift is its own category" "$(summary "$tmp/wd.json" drift_notes)" "1"
echo "== the mask actually removes the script (S3 setup is real) =="
if [ ! -f ../../worktree-discipline/.claude-plugin/plugin.json ]; then
echo " skip (no sibling worktree-discipline checkout)"
exit "$fail"
fi
../bin/plugin-inventory ../../worktree-discipline --json |
python3 calibration/mask-worktree-audit.py >"$tmp/masked.json"
check "worktree-audit absent" \
"$(python3 -c "import json;d=json.load(open('$tmp/masked.json'));print(any('worktree-audit' in s['file'] for s in d['scripts']))")" \
"False"
check "its command block is gone too" \
"$(python3 -c "import json;d=json.load(open('$tmp/masked.json'));print(len(d['_mask']['removed_command_blocks']))")" \
"1"
# The mask must recompute script_loc the same way build_aggregate does, hooks
# included; recomputing from scripts alone deletes every hook and makes the
# masked plugin look far more script-starved than it is, which would let S3
# pass on an artefact of the mask instead of on the missing script.
check "script_loc still counts hooks" \
"$(python3 -c "import json;d=json.load(open('$tmp/masked.json'));print(d['aggregate']['script_loc'] == sum(s['loc'] for s in d['scripts']) + sum(h['loc'] for h in d['hooks']))")" \
"True"
check "only worktree-audit's LOC was removed" \
"$(python3 -c "import json;d=json.load(open('$tmp/masked.json'));m=d['_mask'];print(m['script_loc_before'] - m['script_loc_after'] < 500)")" \
"True"
exit "$fail"