"""Tests for the completion-enforcement loop: on_no_result fallbacks, proof-of-result followups, the NACK acted-variant, and the auditor funnel.""" import importlib.util import json import sys import types import unittest from pathlib import Path REPO_ROOT = Path(__file__).resolve().parent.parent def _load(mod_name, rel_path): spec = importlib.util.spec_from_file_location(mod_name, REPO_ROOT / rel_path) mod = importlib.util.module_from_spec(spec) spec.loader.exec_module(mod) return mod sw = _load("sweeper_completion", "bin/followup-sweeper.py") harv = _load("harvester_completion", "bin/response-harvester.py") aud = _load("completion_audit_mod", "bin/completion-audit.py") grav = _load("gravity_completion", "bin/gravity.py") class DeriveJobName(unittest.TestCase): def test_valid(self): self.assertEqual( sw.derive_job_name("autonomy-pulse-646-20261006-060000-ed9a26af"), "autonomy-pulse-646", ) def test_invalid_shapes(self): for bad in (None, "", "nonsense", "job-2026-1-abc", "nonexistent-job-20261006-060000-ed9a26af"): self.assertIsNone(sw.derive_job_name(bad), bad) class LoadJobFallback(unittest.TestCase): def test_seeded_pulse_jobs(self): for name in ("autonomy-pulse-646", "autonomy-pulse-pip", "autonomy-pulse-opm"): spec, err = sw.load_job_fallback(name) self.assertIsNone(err, name) self.assertIsNotNone(spec, name) self.assertEqual(spec["op"], "swarm.spawn") self.assertEqual(spec["args"]["count"], 2) def test_absent_is_none(self): spec, err = sw.load_job_fallback("646-daily-checkin") self.assertIsNone(spec) self.assertIsNone(err) class RunNoResultFallback(unittest.TestCase): def test_unresolvable_rec(self): out = sw.run_no_result_fallback({"dm_id": "x"}) self.assertFalse(out["ran"]) self.assertFalse(out["configured"]) def test_job_without_spec(self): out = sw.run_no_result_fallback( {"dm_id": "x", "job_id": "646-daily-checkin-20261006-090000-abcdef12", "recipient": "646"}) self.assertFalse(out["ran"]) self.assertFalse(out["configured"]) def test_dry_run_marks_configured(self): out = sw.run_no_result_fallback( {"dm_id": "x", "job_id": "autonomy-pulse-646-20261006-060000-ed9a26af", "recipient": "646"}, dry_run=True) self.assertTrue(out["configured"]) self.assertFalse(out["ran"]) def test_op_path_uses_validated_build(self): calls = {} class FakeOpError(Exception): pass def fake_validate(args): calls["validated"] = dict(args) return {"echo": "yes"} def fake_build(clean): calls["built"] = clean return ["/bin/echo", "fallback-ok"] fake_mod = types.SimpleNamespace( OPS={"probe.op": {"validate": fake_validate, "build": fake_build, "timeout": 10}}) orig_exec, orig_load, orig_derive = ( sw._load_exec_ops, sw.load_job_fallback, sw.derive_job_name) sw._load_exec_ops = lambda: fake_mod sw.load_job_fallback = lambda name: ( ({"op": "probe.op", "args": {"a": 1}}, None)) sw.derive_job_name = lambda jid: "autonomy-pulse-646" try: out = sw.run_no_result_fallback( {"dm_id": "x", "job_id": "whatever", "recipient": "646"}) finally: sw._load_exec_ops, sw.load_job_fallback, sw.derive_job_name = ( orig_exec, orig_load, orig_derive) self.assertTrue(out["ran"], out) self.assertEqual(out["mode"], "op") self.assertEqual(calls["validated"], {"a": 1}) self.assertEqual(calls["built"], {"echo": "yes"}) self.assertIn("fallback-ok", out["detail"]) def test_unknown_op_is_outcome_not_raise(self): orig_exec, orig_load, orig_derive = ( sw._load_exec_ops, sw.load_job_fallback, sw.derive_job_name) sw._load_exec_ops = lambda: types.SimpleNamespace(OPS={}) sw.load_job_fallback = lambda name: ({"op": "nope.nope"}, None) sw.derive_job_name = lambda jid: "autonomy-pulse-646" try: out = sw.run_no_result_fallback( {"dm_id": "x", "job_id": "whatever", "recipient": "646"}) finally: sw._load_exec_ops, sw.load_job_fallback, sw.derive_job_name = ( orig_exec, orig_load, orig_derive) self.assertTrue(out["configured"]) self.assertFalse(out["ran"]) self.assertIn("unknown op", out["detail"]) class FallbackDue(unittest.TestCase): def test_fresh_record_due(self): self.assertTrue(sw.fallback_due({"dm_id": "x"})) def test_ran_never_due(self): self.assertFalse(sw.fallback_due( {"fallback": {"ran": True, "ts": "2026-10-06T00:00:00+00:00"}})) def test_failed_recent_not_due(self): from datetime import datetime, timezone, timedelta ts = (datetime.now(timezone.utc) - timedelta(minutes=5)).isoformat() self.assertFalse(sw.fallback_due( {"fallback": {"ran": False, "ts": ts}})) def test_failed_old_due(self): self.assertTrue(sw.fallback_due( {"fallback": {"ran": False, "ts": "2026-10-05T00:00:00+00:00"}})) class GravityFallback(unittest.TestCase): def test_dry_run_configured(self): rec = {"dm_id": "x", "job_id": "autonomy-pulse-646-20261006-060000-ed9a26af", "recipient": "646"} out = grav.maybe_run_terminal_fallback( rec, "2026-10-06T08:00:00+00:00", dry_run=True) self.assertIsNotNone(out) self.assertFalse(out["ran"]) self.assertNotIn("fallback", rec) def test_no_spec_returns_none(self): rec = {"dm_id": "x", "job_id": "646-daily-checkin-20261006-090000-abcdef12", "recipient": "646"} self.assertIsNone(grav.maybe_run_terminal_fallback( rec, "2026-10-06T08:00:00+00:00", dry_run=True)) def test_already_ran_returns_none(self): rec = {"dm_id": "x", "job_id": "autonomy-pulse-646-20261006-060000-ed9a26af", "recipient": "646", "fallback": {"ran": True, "ts": "2026-10-06T07:00:00+00:00"}} self.assertIsNone(grav.maybe_run_terminal_fallback( rec, "2026-10-06T08:00:00+00:00", dry_run=True)) class GravityEntry(unittest.TestCase): def test_no_args_prints_help(self): import io from contextlib import redirect_stdout buf = io.StringIO() with redirect_stdout(buf): rc = grav.main([]) self.assertEqual(rc, 2) self.assertIn("remediate", buf.getvalue()) def test_remediate_dry_run_returns_json(self): import io from contextlib import redirect_stdout buf = io.StringIO() with redirect_stdout(buf): rc = grav.main(["--remediate", "--dry-run"]) self.assertEqual(rc, 0) data = json.loads(buf.getvalue()) self.assertTrue(data["ok"]) self.assertTrue(data["dry_run"]) class ResultEvidence(unittest.TestCase): def test_positives(self): for text in ( "done, swarm sw-20261006-060000-ab12 reported 2/2", "wrote /tmp/out.json with 40 rows", "timer id: pulse-15m restarted", "thread 1dfb3199-2f99-446c-83e3-848ae2da0a12 swept", "3/3 slots complete", ): self.assertTrue(harv.result_has_evidence(text), text) def test_negatives(self): for text in ("OK all good", "done, nothing to report", "", None): self.assertFalse(harv.result_has_evidence(text), repr(text)) class ProofRequest(unittest.TestCase): def _patch(self, tmp_path): orig = (harv.NUDGE_TRACKER_FILE, harv.JOB_LOG, harv.execute_agent_tool, getattr(harv, "PROOF_REQUESTS_ENABLED", False)) harv.NUDGE_TRACKER_FILE = tmp_path / "tracker.json" harv.JOB_LOG = tmp_path / "job-log.jsonl" harv.PROOF_REQUESTS_ENABLED = True calls = [] harv.execute_agent_tool = lambda a, op, args: ( calls.append((a, op, args)), (True, "scheduled"))[1] return orig, calls def test_bare_result_schedules_proof(self): import tempfile with tempfile.TemporaryDirectory() as td: orig, calls = self._patch(Path(td)) try: ok = harv.maybe_request_proof( "646", "1dfb3199-2f99-446c-83e3-848ae2da0a12", "job-1", "OK all good") finally: (harv.NUDGE_TRACKER_FILE, harv.JOB_LOG, harv.execute_agent_tool, harv.PROOF_REQUESTS_ENABLED) = orig self.assertTrue(ok) self.assertEqual(calls[0][1], "followup.create") self.assertEqual(calls[0][2]["in_m"], 30) self.assertIn("PROOF", calls[0][2]["prompt"]) def test_evidence_skips(self): ok = harv.maybe_request_proof( "646", "1dfb3199-2f99-446c-83e3-848ae2da0a12", "job-1", "done, swarm sw-20261006-060000-ab12") self.assertFalse(ok) def test_bad_thread_and_dry_run_skip(self): self.assertFalse(harv.maybe_request_proof( "646", "main", "job-1", "OK")) self.assertFalse(harv.maybe_request_proof( "646", "1dfb3199-2f99-446c-83e3-848ae2da0a12", "job-1", "OK", dry_run=True)) def test_one_shot_per_job(self): import tempfile with tempfile.TemporaryDirectory() as td: orig, calls = self._patch(Path(td)) try: kw = dict(agent="646", thread_id="1dfb3199-2f99-446c-83e3-848ae2da0a12", job_id="job-9", result_text="OK") self.assertTrue(harv.maybe_request_proof(**kw)) self.assertFalse(harv.maybe_request_proof(**kw)) finally: (harv.NUDGE_TRACKER_FILE, harv.JOB_LOG, harv.execute_agent_tool, harv.PROOF_REQUESTS_ENABLED) = orig self.assertEqual(len(calls), 1) class NackActedVariant(unittest.TestCase): def test_acted_variant_text(self): import tempfile sent = [] fake = types.ModuleType("muse_hybrid") fake.send_message = lambda a, m, thread_id=None, wait=0: sent.append(m) with tempfile.TemporaryDirectory() as td: tp = Path(td) (tp / "followups.json").write_text(json.dumps({ "m1": {"status": "pending", "thread_uuid": "1dfb3199-2f99-446c-83e3-848ae2da0a12", "job_id": "job-7", "recipient": "646"}})) orig = (harv.NUDGE_TRACKER_FILE, harv.FOLLOWUPS_FILE, sys.modules.get("muse_hybrid")) harv.NUDGE_TRACKER_FILE = tp / "tracker.json" harv.FOLLOWUPS_FILE = tp / "followups.json" sys.modules["muse_hybrid"] = fake try: harv.maybe_nudge_untagged_sidechat( "646", "1dfb3199-2f99-446c-83e3-848ae2da0a12", "646 tasks", "mid-1", "some prose", acted=True) finally: (harv.NUDGE_TRACKER_FILE, harv.FOLLOWUPS_FILE, old_mod) = orig if old_mod is None: sys.modules.pop("muse_hybrid", None) else: sys.modules["muse_hybrid"] = old_mod self.assertEqual(len(sent), 1) self.assertIn("Action received", sent[0]) self.assertIn("[RESULT job-7]", sent[0]) self.assertNotIn("STRICT ENFORCEMENT", sent[0]) class AuditorFunnel(unittest.TestCase): def _events(self): base = "2026-10-06T07:00:00+00:00" return [ {"ts": base, "type": "job_sent", "job_id": "work-finder-20261006-070000-aaaaaaaa"}, {"ts": base, "type": "job_dispatched", "job_id": "work-finder-20261006-070000-aaaaaaaa"}, {"ts": base, "type": "tool_exec", "op": "swarm.spawn", "success": True}, {"ts": base, "type": "job_result", "job_id": "work-finder-20261006-070000-aaaaaaaa", "success": True}, {"ts": base, "type": "job_sent", "job_id": "pulse-20261006-070000-bbbbbbbb"}, {"ts": base, "type": "job_failed", "job_id": "pulse-20261006-070000-bbbbbbbb"}, ] def test_funnel_counts(self): from datetime import datetime, timezone fam, tools = aud.compute_funnel( self._events(), datetime(2026, 10, 6, 6, 0, tzinfo=timezone.utc)) self.assertEqual(fam["work-finder"]["sent"], 1) self.assertEqual(fam["work-finder"]["results"], 1) self.assertEqual(fam["pulse"]["failed"], 1) self.assertEqual(tools["tools"]["total"], 1) self.assertEqual(tools["tools"]["ok"], 1) def test_family_of(self): self.assertEqual(aud.family_of("a-b-20261006-070000-aaaaaaaa"), "a-b") self.assertEqual(aud.family_of("weird"), "weird") def test_digest_verdicts(self): healthy = {"ts": "2026-10-06T07:00:00+00:00", "window_h": 6, "totals": {"sent": 4, "dispatched": 4, "results": 4, "ok": 4}, "tools": {"tools": {"total": 3, "ok": 3}, "tool_errs": {}}, "families": {}, "silent_families": [], "swarms": {}, "stale_running": [], "followups": {"pending": 1}, "degraded": False, "reasons": []} out = aud.render_digest(healthy) self.assertIn("HEALTHY", out) self.assertIn("4 sent", out) bad = dict(healthy, degraded=True, reasons=["1 silent families: x"], silent_families=["x"]) self.assertIn("DEGRADED", aud.render_digest(bad)) def test_should_post_policy(self): import tempfile with tempfile.TemporaryDirectory() as td: orig = aud.STATE_FILE aud.STATE_FILE = Path(td) / "state.json" try: self.assertTrue(aud.should_post({"degraded": True})[0]) ok, why = aud.should_post({"degraded": False}) self.assertTrue(ok) self.assertEqual(why, "heartbeat") finally: aud.STATE_FILE = orig if __name__ == "__main__": unittest.main()