#!/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 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 [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]")" \ "" 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]")" \ "" 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"