job4: SPEC-08 oracle-sandbox

New T7 block in lib/tests/run-reconcile.sh (+6 assertions, 20→26):
a throwaway git repo under mktemp with a LOCAL BARE origin drives the
3 previously-unexercised oracles live: tree_clean (dirty→rc≠0, clean→
rc0), pushed (pushed to origin FIRST so origin/main exists — else
rev-list is vacuously empty — then rc0 when synced, rc≠0 once 1 ahead),
msg_committed (rc0 for a present commit message, rc≠0 for an absent
one). Closes J4-12 (DEGRADED, prerequisite of SPEC-09/10): these 3
oracles backed report-only /reconcile output with zero test coverage —
a silent inversion would mis-report open-work state.

Mutation (lean scratch copy — only lib/reconcile.sh + lib/tests/
run-reconcile.sh + its fixtures + .claude/memory/decisions.md, not the
whole repo/.git, per the /tmp-exhaustion lesson from SPEC-01/02/04):
inverted tree_clean's rc (`-z` → `-n` on the porcelain-status check;
the report's literal "--quiet → negated" wording doesn't match this
function's actual `[ -z ... ]` shape, so applied the equivalent
semantic inversion). RED: both T7a assertions fail (dirty reads as
clean and vice versa); T7b/T7c stay green, confirming the mutation is
localized. (T6a/b/c red in the lean copy too, expected — no real git
history / skills dir there — unrelated to the mutation.)
GREEN: real repo unmutated, 26/26 passed (T7 included).
This commit is contained in:
Bastien Chanot
2026-07-06 19:12:48 +02:00
parent c8e91e8924
commit 12c0d1d9fd
+23
View File
@@ -75,5 +75,28 @@ if reconcile_oracle_sha_exists "$REPO" "be1dcef"; then ok "T6b sha_exists(b
dk="$REPO/../skills/darwin-skill"
if reconcile_oracle_path_present "$dk"; then ok "T6c path_present(darwin-skill) via fs"; else no "T6c path absent"; fi
echo; echo "=== T7 oracle-sandbox — tree_clean/pushed/msg_committed driven live (not by name) ==="
OWORK="$(mktemp -d)"
bare="$OWORK/origin.git"; git init -q --bare "$bare"
orepo="$OWORK/repo"; git init -q "$orepo"
git -C "$orepo" config user.email t@t; git -C "$orepo" config user.name t
git -C "$orepo" remote add origin "$bare"
echo base > "$orepo/base.txt"; git -C "$orepo" add base.txt; git -C "$orepo" commit -q -m "base commit"
git -C "$orepo" branch -M main
git -C "$orepo" push -q origin main # populates origin/main BEFORE the pushed-oracle checks (else vacuous rc0)
echo dirty >> "$orepo/base.txt"
if reconcile_oracle_tree_clean "$orepo"; then no "T7a tree_clean should be dirty"; else ok "T7a tree_clean rc≠0 with a dirty file"; fi
git -C "$orepo" checkout -q -- base.txt
if reconcile_oracle_tree_clean "$orepo"; then ok "T7a tree_clean rc0 after restoring clean"; else no "T7a tree_clean should be clean"; fi
if reconcile_oracle_pushed "$orepo" main; then ok "T7b pushed rc0 when synced"; else no "T7b pushed should be rc0 (synced)"; fi
echo more >> "$orepo/base.txt"; git -C "$orepo" add base.txt; git -C "$orepo" commit -q -m "ahead commit"
if reconcile_oracle_pushed "$orepo" main; then no "T7b pushed should be rc≠0 (1 ahead)"; else ok "T7b pushed rc≠0 when 1 ahead of origin"; fi
if reconcile_oracle_msg_committed "$orepo" "ahead commit"; then ok "T7c msg_committed rc0 for a present message"; else no "T7c msg_committed should find 'ahead commit'"; fi
if reconcile_oracle_msg_committed "$orepo" "nonexistent-message-xyz"; then no "T7c msg_committed should be rc≠0 for an absent message"; else ok "T7c msg_committed rc≠0 for an absent message"; fi
rm -rf "$OWORK"
echo; echo "================ $pass GREEN / $fail RED ================"
[ "$fail" -eq 0 ] && exit 0 || exit 1