179 lines
8.3 KiB
Bash
Executable File
179 lines
8.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# bin/filing-plan: output path A — the marker-based idempotency contract
|
|
# (FR-6.3), template rendering (FR-6.1), and repo-less degradation (FR-6.4).
|
|
#
|
|
# The load-bearing case is "run 1 files, run 2 comments". It is proved here the
|
|
# only way that means anything: run 1's ACTUAL rendered body is fed back as the
|
|
# tracker's state for run 2. Nothing is asserted about the marker by hand.
|
|
#
|
|
# tests/fixtures/gitea-issues.json is copied verbatim from real Gitea API
|
|
# responses (probe issue kotkan/claude-plugin-inference-arbitrage#9, since
|
|
# closed), so the shape this parses is the shape the API returns.
|
|
set -euo pipefail
|
|
cd "$(dirname "${BASH_SOURCE[0]}")/.."
|
|
|
|
BIN=bin/filing-plan
|
|
JUD=tests/fixtures/filing-judgments.json
|
|
tmp=$(mktemp -d)
|
|
trap 'rm -rf "$tmp"' EXIT
|
|
fail=0
|
|
|
|
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
|
|
}
|
|
# q <file> <python-expr over `d`>
|
|
q() { python3 -c "import json,sys;d=json.load(open(sys.argv[1]));print($2)" "$1"; }
|
|
|
|
bin/boundary-classify "$JUD" >"$tmp/cls.json"
|
|
|
|
plan() { # plan <existing.json> <out.json> [extra args...]
|
|
local existing=$1 out=$2
|
|
shift 2
|
|
$BIN plan --classified "$tmp/cls.json" --judgments "$JUD" \
|
|
--target-repo oleks/claude-plugin-fixture --existing "$existing" \
|
|
--audit-page Audits/fixture-plugin/2026-07-29 \
|
|
--window "2026-07-22 -> 2026-07-29" --run-date 2026-07-29 "$@" >"$out"
|
|
}
|
|
|
|
echo "== the fixture's two candidates grade as expected (guards the rest) =="
|
|
check "A verdict" "$(q "$tmp/cls.json" "d['candidates'][0]['verdict']")" "file"
|
|
check "B verdict" "$(q "$tmp/cls.json" "d['candidates'][1]['verdict']")" "no-offload"
|
|
|
|
echo "== RUN 1: empty tracker -> files, with the marker as line 1 =="
|
|
echo '[]' >"$tmp/empty.json"
|
|
plan "$tmp/empty.json" "$tmp/plan1.json"
|
|
check "to_file" "$(q "$tmp/plan1.json" "d['summary']['to_file']")" "1"
|
|
check "to_comment" "$(q "$tmp/plan1.json" "d['summary']['to_comment']")" "0"
|
|
check "action" "$(q "$tmp/plan1.json" "d['actions'][0]['action']")" "file"
|
|
check "marker is line 1" \
|
|
"$(q "$tmp/plan1.json" "d['actions'][0]['body'].splitlines()[0]")" \
|
|
"<!-- ia-candidate: fixture-plugin/skill-a/label-derivation -->"
|
|
check "token-offload label required" \
|
|
"$(q "$tmp/plan1.json" "d['actions'][0]['required_labels']")" "['token-offload']"
|
|
check "non-file verdict skipped" "$(q "$tmp/plan1.json" "d['actions'][1]['action']")" "skip"
|
|
|
|
echo "== the body carries every element of the FR-6 contract =="
|
|
body=$(q "$tmp/plan1.json" "d['actions'][0]['body']")
|
|
for needle in \
|
|
"**Measured cost.**" "**Evidence strength.**" "**Boundary position.**" \
|
|
"Determinism tests: T1 ✓ T2 ✓ T3 ✓ T4 ✓ T5 ✓" \
|
|
"**Proposed signature.**" "derive_labels(" "**Examples.**" \
|
|
"**When a human would overrule this.**" "**Escalation path.**" \
|
|
"**What crosses the boundary.**" \
|
|
"Audits/fixture-plugin/2026-07-29" "Rubric v1.0.0"; do
|
|
if grep -qF -- "$needle" <<<"$body"; then
|
|
echo " ok body contains: $needle"
|
|
else
|
|
echo " FAIL body missing: $needle" >&2
|
|
fail=1
|
|
fi
|
|
done
|
|
check "measurement is quoted, not invented" \
|
|
"$(grep -cF 'Recurring sequence observed 17x' <<<"$body")" "1"
|
|
check "3 examples incl. the edge case" "$(grep -c '^- ' <<<"$body")" "3"
|
|
|
|
echo "== RUN 2 (FR-6.3, S5): run 1's own body is now on the tracker -> comment =="
|
|
python3 - "$tmp/plan1.json" "$tmp/tracker.json" <<'PY'
|
|
import json, sys
|
|
plan = json.load(open(sys.argv[1]))
|
|
filed = next(a for a in plan["actions"] if a["action"] == "file")
|
|
json.dump([{"number": 41, "state": "open", "title": filed["proposed_title"],
|
|
"body": filed["body"], "comments": []}], open(sys.argv[2], "w"))
|
|
PY
|
|
plan "$tmp/tracker.json" "$tmp/plan2.json" --status grown
|
|
check "files nothing on re-run" "$(q "$tmp/plan2.json" "d['summary']['to_file']")" "0"
|
|
check "comments instead" "$(q "$tmp/plan2.json" "d['summary']['to_comment']")" "1"
|
|
check "on the right issue" \
|
|
"$(q "$tmp/plan2.json" "d['actions'][0]['issue']")" "oleks/claude-plugin-fixture#41"
|
|
check "comment re-carries the marker" \
|
|
"$(q "$tmp/plan2.json" "d['actions'][0]['body'].splitlines()[0]")" \
|
|
"<!-- ia-candidate: fixture-plugin/skill-a/label-derivation -->"
|
|
check "comment reports the diff status" \
|
|
"$(q "$tmp/plan2.json" "'Status: grown' in d['actions'][0]['body']")" "True"
|
|
|
|
echo "== RUN 3: the comment from run 2 is the only marker left (body rewritten) =="
|
|
python3 - "$tmp/plan2.json" "$tmp/tracker3.json" <<'PY'
|
|
import json, sys
|
|
plan = json.load(open(sys.argv[1]))
|
|
c = next(a for a in plan["actions"] if a["action"] == "comment")
|
|
json.dump([{"number": 41, "state": "closed", "title": "a human retitled this",
|
|
"body": "and rewrote the body, dropping the marker",
|
|
"comments": [{"body": c["body"]}]}], open(sys.argv[2], "w"))
|
|
PY
|
|
plan "$tmp/tracker3.json" "$tmp/plan3.json"
|
|
check "still no duplicate" "$(q "$tmp/plan3.json" "d['summary']['to_file']")" "0"
|
|
check "found via the comment" "$(q "$tmp/plan3.json" "d['actions'][0]['action']")" "comment"
|
|
check "closed state surfaced for issuer" \
|
|
"$(q "$tmp/plan3.json" "d['actions'][0]['issue_state']")" "closed"
|
|
|
|
echo "== real Gitea API shapes parse, and a DIFFERENT id does not false-match =="
|
|
plan tests/fixtures/gitea-issues.json "$tmp/plan4.json"
|
|
check "unrelated markers -> files" "$(q "$tmp/plan4.json" "d['summary']['to_file']")" "1"
|
|
check "searched the fixture" "$(q "$tmp/plan4.json" "d['summary']['searched_issues']")" "1"
|
|
|
|
echo "== a marker on two issues warns and takes the lowest number =="
|
|
python3 - "$tmp/plan1.json" "$tmp/dupes.json" <<'PY'
|
|
import json, sys
|
|
filed = next(a for a in json.load(open(sys.argv[1]))["actions"] if a["action"] == "file")
|
|
json.dump([{"number": 77, "state": "open", "title": "later dupe", "body": filed["body"], "comments": []},
|
|
{"number": 41, "state": "open", "title": "original", "body": filed["body"], "comments": []}],
|
|
open(sys.argv[2], "w"))
|
|
PY
|
|
plan "$tmp/dupes.json" "$tmp/plan5.json"
|
|
check "lowest issue wins" "$(q "$tmp/plan5.json" "d['actions'][0]['issue_number']")" "41"
|
|
check "warns a human" "$(q "$tmp/plan5.json" "len(d['warnings'])")" "1"
|
|
|
|
echo "== --existing is mandatory: a skipped search must never mean 'file it all' =="
|
|
if $BIN plan --classified "$tmp/cls.json" --judgments "$JUD" \
|
|
--target-repo oleks/claude-plugin-fixture --audit-page A --window w \
|
|
--run-date 2026-07-29 >/dev/null 2>&1; then
|
|
echo " FAIL plan ran without --existing" >&2
|
|
fail=1
|
|
else
|
|
echo " ok refuses to plan without a search result"
|
|
fi
|
|
|
|
echo "== FR-6.4: a target with no writable repo degrades to summary-only =="
|
|
# Real, not synthetic: third-party/baoyu-design is a vendored plugin whose only
|
|
# remote is github.com, i.e. nothing this environment can file to.
|
|
THIRD=../third-party/baoyu-design
|
|
if [ -d "$THIRD" ]; then
|
|
bin/plugin-inventory "$THIRD" --json >"$tmp/tp-inv.json"
|
|
check "inventory still resolves it" "$(q "$tmp/tp-inv.json" "d['plugin']['name']")" "baoyu-design"
|
|
$BIN queries --classified "$tmp/cls.json" --judgments "$JUD" \
|
|
--target-path "$THIRD" --workspace /nonexistent >"$tmp/tp-q.json"
|
|
check "filing" "$(q "$tmp/tp-q.json" "d['filing']")" "unavailable"
|
|
check "reason names the remote" \
|
|
"$(q "$tmp/tp-q.json" "'github.com' in d['filing_unavailable_reason']")" "True"
|
|
check "no queries emitted" "$(q "$tmp/tp-q.json" "'queries' in d")" "False"
|
|
|
|
$BIN plan --classified "$tmp/cls.json" --judgments "$JUD" \
|
|
--target-path "$THIRD" --workspace /nonexistent --existing "$tmp/empty.json" \
|
|
--audit-page A --window w --run-date 2026-07-29 >"$tmp/tp-plan.json"
|
|
check "nothing filed" "$(q "$tmp/tp-plan.json" "d['summary']['to_file']")" "0"
|
|
check "candidate marked unavailable" \
|
|
"$(q "$tmp/tp-plan.json" "d['actions'][0]['filing']")" "unavailable"
|
|
else
|
|
echo " skip (no third-party/baoyu-design checkout)"
|
|
fi
|
|
|
|
echo "== a writable target resolves through its own checkout's remote =="
|
|
if [ -d ../worktree-discipline/.git ]; then
|
|
$BIN queries --classified "$tmp/cls.json" --judgments "$JUD" \
|
|
--target-path ../worktree-discipline >"$tmp/wd-q.json"
|
|
check "repo" "$(q "$tmp/wd-q.json" "d['repo']")" "kotkan/claude-plugin-worktree-discipline"
|
|
check "filing" "$(q "$tmp/wd-q.json" "d['filing']")" "available"
|
|
check "label scan is the authoritative query" \
|
|
"$(q "$tmp/wd-q.json" "d['queries']['label_scan']['labels']")" "['token-offload']"
|
|
else
|
|
echo " skip (no sibling worktree-discipline checkout)"
|
|
fi
|
|
|
|
exit "$fail"
|