from __future__ import annotations import json from pathlib import Path import subprocess import sys import unittest ROOT = Path(__file__).resolve().parents[2] RUNTIME = ROOT / "harness/runtime" sys.path.insert(0, str(RUNTIME)) import workflow_dispatch # noqa: E402 class WorkflowDispatchTest(unittest.TestCase): def test_all_manifest_workflows_resolve(self) -> None: result = workflow_dispatch.check_all(ROOT) self.assertEqual(result["status"], "PASS") self.assertEqual(result["workflow_count"], 24) self.assertEqual(result["findings"], []) def test_agentic_workflow_emits_review_and_output_plan(self) -> None: result = workflow_dispatch.build_plan(ROOT, "branch-spec") self.assertEqual(result["status"], "PLANNED") self.assertEqual(result["execution"]["kind"], "orchestrated") self.assertEqual(result["dispatch"]["semantic_review"], "dispatch") self.assertEqual(result["output_contract"]["mode"], "decision-risk-summary") self.assertEqual(result["phase"], "baseline") self.assertEqual(result["mandatory_gates"]["typed_contract"], "required") def test_final_resolution_reacts_to_findings_and_claims(self) -> None: result = workflow_dispatch.build_plan( ROOT, "branch-spec", phase="final", finding_count=6, claims_present=True, public_claims_present=True, risk="high", ) self.assertEqual(result["phase"], "final") self.assertEqual(result["mandatory_gates"]["proof_manifest"], "required") self.assertEqual(result["dispatch"]["adversarial_review"], "dispatch") def test_baseline_rejects_post_work_context(self) -> None: with self.assertRaises(workflow_dispatch.DispatchError): workflow_dispatch.build_plan(ROOT, "branch-spec", finding_count=1) def test_deterministic_execute_binds_apply_to_dry_run_hash(self) -> None: plan = workflow_dispatch.build_plan(ROOT, "branch-from-project") digest = "a" * 64 calls: list[list[str]] = [] def runner(argv, **_kwargs): calls.append(list(argv)) status = "DRY_RUN" if "--dry-run" in argv else "APPLIED" stdout = json.dumps({ "schema_version": "branch-from-project-result/v1", "status": status, "plan_sha256": digest, }) return subprocess.CompletedProcess(argv, 0, stdout, "") result, exit_code = workflow_dispatch.execute_deterministic( ROOT, plan, ["demo", "WI-DEMO-001"], runner=runner, ) self.assertEqual(exit_code, 0) self.assertEqual(result["status"], "APPLIED") self.assertEqual(len(calls), 2) self.assertIn("--dry-run", calls[0]) self.assertEqual(calls[1][-2:], ["--expected-plan-sha256", digest]) def test_required_review_blocks_deterministic_execution(self) -> None: plan = workflow_dispatch.build_plan(ROOT, "branch-from-project", risk="high") result, exit_code = workflow_dispatch.execute_deterministic( ROOT, plan, ["demo", "WI-DEMO-001"], runner=lambda *_args, **_kwargs: self.fail("runner must not execute"), ) self.assertEqual(exit_code, 1) self.assertEqual(result["status"], "REVIEW_REQUIRED") def test_invalid_child_schema_is_environment_error(self) -> None: plan = workflow_dispatch.build_plan(ROOT, "branch-from-project") def runner(argv, **_kwargs): return subprocess.CompletedProcess(argv, 0, '{"schema_version":"wrong"}', "") with self.assertRaises(workflow_dispatch.DispatchError): workflow_dispatch.execute_deterministic(ROOT, plan, ["demo", "WI-DEMO-001"], runner=runner) def test_child_exit_envelope_preserves_quality_and_environment_failures(self) -> None: plan = workflow_dispatch.build_plan(ROOT, "branch-from-project") def result(code: int, status: str): def runner(argv, **_kwargs): return subprocess.CompletedProcess( argv, code, json.dumps({ "schema_version": "branch-from-project-result/v1", "status": status, }), "", ) return runner quality, quality_code = workflow_dispatch.execute_deterministic( ROOT, plan, ["demo", "WI-DEMO-001"], runner=result(1, "FAIL"), ) environment, environment_code = workflow_dispatch.execute_deterministic( ROOT, plan, ["demo", "WI-DEMO-001"], runner=result(2, "ERROR"), ) self.assertEqual((quality["status"], quality_code), ("FAIL", 1)) self.assertEqual((environment["status"], environment_code), ("ERROR", 2)) def test_successful_apply_must_echo_dry_run_plan_hash(self) -> None: plan = workflow_dispatch.build_plan(ROOT, "branch-from-project") calls = 0 def runner(argv, **_kwargs): nonlocal calls calls += 1 document = { "schema_version": "branch-from-project-result/v1", "status": "DRY_RUN" if calls == 1 else "APPLIED", "plan_sha256": ("a" if calls == 1 else "b") * 64, } return subprocess.CompletedProcess(argv, 0, json.dumps(document), "") with self.assertRaises(workflow_dispatch.DispatchError): workflow_dispatch.execute_deterministic( ROOT, plan, ["demo", "WI-DEMO-001"], runner=runner, ) if __name__ == "__main__": unittest.main()