import json import pathlib import tempfile import unittest from wbv2_business_status import business_progress class BusinessStatusTests(unittest.TestCase): def setUp(self): self.directory = tempfile.TemporaryDirectory() self.addCleanup(self.directory.cleanup) self.root = pathlib.Path(self.directory.name) self.write("tests/golden/WBV2/web-product-backlog.json", {"tasks": [ {"id": "READY", "commands": ["one"]}, {"id": "MISSING", "commands": ["two"]}, ]}) def write(self, path, value): target = self.root / path target.parent.mkdir(parents=True, exist_ok=True) target.write_text(json.dumps(value)) def test_heartbeat_cannot_advance_verified_business_time(self): self.write("receipt.json", {"status": "verified", "verifiedAt": "2026-09-09T03:00:00+00:00"}) state = {"verification": {"validJobs": ["READY"]}, "jobs": {"READY": {"receipt": "receipt.json"}}, "heartbeatAt": "2026-09-09T03:10:00+00:00"} first = business_progress(self.root, state) state["heartbeatAt"] = "2026-09-10T03:10:00+00:00" self.assertEqual(first, business_progress(self.root, state)) self.assertEqual(first["lastVerifiedAt"], "2026-09-09T03:00:00+00:00") self.assertEqual(first["state"], "waiting_for_implementation") def test_stale_evidence_is_not_progress(self): self.write("receipt.json", {"status": "verified", "verifiedAt": "2026-09-09T03:00:00+00:00"}) result = business_progress(self.root, {"verification": {"staleJobs": ["READY"]}, "jobs": {"READY": {"receipt": "receipt.json"}}}) self.assertIsNone(result["lastVerifiedAt"]) self.assertEqual(result["readyForValidation"], ["READY"]) self.assertEqual(result["validWorkflows"], 0) def test_blocked_job_does_not_hide_an_independent_runnable_job(self): self.write("tests/golden/WBV2/autopilot/local-task-assignments.json", { "assignments": [{"job": "READY", "state": "ready"}]}) result = business_progress(self.root, {"jobs": {"MISSING": { "state": "blocked", "reason": "native test failed"}}}) self.assertEqual(result["state"], "ready_for_validation") self.assertEqual(result["readyForValidation"], ["READY"]) self.assertEqual(result["validationFailures"][0]["job"], "MISSING") def test_missing_recipe_reports_action_and_not_completion(self): self.write("tests/golden/WBV2/autopilot/preparation/MISSING.json", { "commands": ["two"], "sourceUnits": [{"id": "web-command:two"}], "candidateTests": ["web/tests/e2e/two.spec.ts"], "nextActions": ["Validate two and bind its native result"], "businessBlocker": {"category": "workflow_contract_missing", "contractPath": "my-tools/local-workflows/MISSING.json"}}) result = business_progress(self.root, {}) self.assertEqual(result["nextImplementationTasks"][0]["job"], "MISSING") self.assertEqual(result["needsImplementation"], 2) self.assertEqual(result["validWorkflows"], 0) def test_behavior_pending_is_not_ready_despite_an_old_ready_assignment(self): self.write("tests/golden/WBV2/autopilot/local-task-assignments.json", { "assignments": [{"job": "MISSING", "state": "ready"}]}) result = business_progress(self.root, {"jobs": {"MISSING": { "state": "behavior_pending", "reason": "compilation-only"}}}) self.assertNotIn("MISSING", result["readyForValidation"]) pending = next(item for item in result["nextImplementationTasks"] if item["job"] == "MISSING") self.assertEqual(pending["category"], "behavior_contract_missing") self.assertEqual(result["validationFailures"], []) def test_external_receipt_cannot_supply_progress(self): result = business_progress(self.root, {"verification": {"validJobs": ["READY"]}, "jobs": {"READY": {"receipt": "../foreign.json"}}}) self.assertIsNone(result["lastVerifiedAt"]) def test_native_failure_exposes_the_current_attempt_repair_action(self): run = "tests/golden/WBV2/autopilot/runs/MISSING-attempt" self.write(f"{run}/cases/native-business-diagnostic.json", { "schemaVersion": 1, "job": "MISSING", "status": "FAIL", "findings": [{"assertion": "evaluated_value", "sourceUnit": "web-command:two", "symbol": "native_two", "message": "evaluated value differed"}], "reproduce": {"argv": ["node", "my-tools/diagnostic.mjs"], "cwd": "."}, }) state = {"jobs": {"MISSING": {"state": "blocked", "runDirectory": run}}} failure = business_progress(self.root, state)["validationFailures"][0] self.assertEqual(failure["repairActions"][0]["sourceUnit"], "web-command:two") self.assertEqual(failure["reproduce"]["argv"][0], "node") self.assertEqual(business_progress(self.root, state)["validWorkflows"], 0) def test_other_job_or_success_diagnostics_do_not_create_repair_actions(self): run = "tests/golden/WBV2/autopilot/runs/MISSING-attempt" state = {"jobs": {"MISSING": {"state": "blocked", "runDirectory": run}}} for job, status in [("READY", "FAIL"), ("MISSING", "PASS")]: self.write(f"{run}/cases/native-business-diagnostic.json", { "schemaVersion": 1, "job": job, "status": status, "findings": [{"message": "old"}]}) failure = business_progress(self.root, state)["validationFailures"][0] self.assertNotIn("repairActions", failure) if __name__ == "__main__": unittest.main()