init: llm-wiki-haness 하네스 설계
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
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()
|
||||
Reference in New Issue
Block a user