#!/usr/bin/env python3 """Compile-time artifact registry invariants and no runtime auto-admission.""" import importlib.util import os import sys ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) COMPILER = os.path.join(ROOT, ".claude", "hooks", "compile_artifact_registry.py") spec = importlib.util.spec_from_file_location("artifact_registry_compiler", COMPILER) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) sys.path.insert(0, os.path.join(ROOT, ".claude", "hooks")) import artifact_contract as AC # noqa: E402 passed = failed = 0 def check(name, condition): global passed, failed if condition: passed += 1 print(f" PASS {name}") else: failed += 1 print(f" FAIL {name}") document, errors = module.compile_registry() registry = (document or {}).get("artifact-registry", {}) check("registry compiles without invariant errors", errors == []) check("runtime registry covers the controlled vocabulary", registry.get("artifact-kind-count") >= 180) check("all compiled producer roles are concrete", all( role in module._roles() for definition in (registry.get("artifact-kinds") or {}).values() for role in definition.get("producer-roles") or [] )) check("every reviewer capability is declared", all( definition.get("reviewer-capability") in module._load(module.WORKFLOW_PATH)["workflow-contracts"]["role-capabilities"] for definition in (registry.get("artifact-kinds") or {}).values() )) check("core aggregate bindings are compiled into the runtime registry", registry["artifact-kinds"]["grounding-package"]["method-binding"]["role-methods"] ["STR-ANALYST"]["checkpoint-step-id"] == "diverge-options" and registry["artifact-kinds"]["executive-decision-packet"]["method-binding"] ["role-methods"]["EXEC-CEO"]["checkpoint-step-id"] == "converge-decision") check("venture bootstrap bindings support standard-tier submissions", registry["artifact-kinds"]["opportunity-cluster"]["method-binding"]["mode"] == "stage-synthesis" and registry["artifact-kinds"]["venture-validation"]["method-binding"]["mode"] == "stage-synthesis" and registry["artifact-kinds"]["venture-validation"]["producer-roles"] == ["EXEC-CEO"] and registry["artifact-kinds"]["venture-decision"]["method-binding"] ["role-methods"]["EXEC-CEO"]["checkpoint-step-id"] == "converge-decision") broken_binding = { "producer-roles": ["STR-ANALYST"], "required-payload-fields": ["options"], "method-binding": {"mode": "aggregate", "role-methods": {"STR-ANALYST": { "method-id": "strategy-analysis", "checkpoint-step-id": "diverge-options", "embedded-outputs": {"option-set": ["options"]}, }}}, } binding_errors = module._binding_errors( "broken-grounding", broken_binding, module._methods()) check("aggregate binding cannot omit earlier craft outputs", any("grounding-evidence" in error for error in binding_errors) and any("analysis-synthesis" in error for error in binding_errors)) original = module._methods try: module._methods = lambda: { "ENG-BE": {"methods": [{"method-id": "typo", "output-artifacts": ["api-contarct"]}]} } _document, typo_errors = module.compile_registry() check("method typo cannot auto-create a legal artifact kind", any("not explicitly admitted" in error and "api-contarct" in error for error in typo_errors)) finally: module._methods = original check("generated registry has no drift", module.main(["--check"]) == 0) standard_minimal = {"tier": "standard", "artifact-kind": "executive-decision-packet", "payload": {"recommendation": "A"}} light_minimal = {"tier": "light", "artifact-kind": "executive-decision-packet", "payload": {"recommendation": "A"}} check("standard decision packet rejects recommendation-only payload", any("selected-option-id" in error for error in AC._semantic_errors( standard_minimal, "executive-decision-packet"))) check("light decision packet keeps proportional minimal contract", AC._semantic_errors(light_minimal, "executive-decision-packet") == []) _gates = [ "problem-intensity", "competition-alternatives", "willingness-to-pay", "revenue-unit-economics", "tech-feasibility-moat", "operability", "distribution", "founder-fit", "kill-criteria", ] _option = { "id": "V1", "customer": "developer", "painful-job": "understand mechanisms", "current-alternative": "docs", "wedge": "guided lab", "monetization": "unknown", "expected-price": "unknown", "reachable-customers": "unknown", "rough-revenue-ceiling": "unknown", "acquisition-channel": "unknown", "build-cost": "one flagship", "operation-cost": "unknown", "founder-fit": "conditional", "defensibility": "learning design", "kill-criteria": ["no learning outcome"], "unresolved-assumptions": ["demand"], "validation-results": [ {"option-id": "V1", "gate": gate, "verdict": "unknown", "evidence": [], "dissent": []} for gate in _gates ], } _validation_payload = { "source-artifact-refs": [ {"artifact-id": "OC1", "artifact-sha256": "a" * 64}, {"artifact-id": "OC2", "artifact-sha256": "b" * 64}, ], "hypotheses": ["demand"], "experiments": ["user test"], "evidence": ["existing product"], "option-evaluations": [_option, {**_option, "id": "V2", "validation-results": [ {**result, "option-id": "V2"} for result in _option["validation-results"] ]}], "kill-criteria": ["no learning outcome"], "recommendation": "V1", } check("venture validation requires exactly one result for each of the 9 gates", AC._semantic_errors({"tier": "standard", "payload": _validation_payload}, "venture-validation") == []) _duplicate_gate_payload = {**_validation_payload, "option-evaluations": [ {**_option, "validation-results": [*_option["validation-results"][:-1], _option["validation-results"][0]]}, _validation_payload["option-evaluations"][1], ]} _duplicate_errors = AC._semantic_errors( {"tier": "standard", "payload": _duplicate_gate_payload}, "venture-validation") check("venture validation rejects duplicated gate standing in for a missing gate", any("9-gate 누락" in error for error in _duplicate_errors) and any("gate 중복" in error for error in _duplicate_errors)) compiled_kinds = AC.load_contract()["artifact-kinds"] check("core gates use specialized reviewers", compiled_kinds["overall-design"]["reviewer-capability"] == "architecture-auditor" and compiled_kinds["threat-model"]["reviewer-capability"] == "security-auditor" and compiled_kinds["api-contract"]["reviewer-capability"] == "technical-accuracy-auditor") print(f"\n{passed} passed, {failed} failed") raise SystemExit(1 if failed else 0)