e044a2de0d
---ci--- project: acdl phase: 6 milestone: v1.1 status: plan-as-execute persona: lead-developer tasks: [T-6.1, T-6.2, T-6.3, T-6.4] ---/ci--- Archive the v1.0 demo under demo/ (D-037) and reorient the repo to the real platform. Wave 1 of the Phase 06 plan. - T-6.1: git mv modules/, scripts/, evidence-ui/, contracts/, contracts-repo/, .gitea/ -> demo/; mv ACDL_DEMO.md + runner-data/ -> demo/ - T-6.2: scaffold new v1.1 top-level dirs (platform/, schemas/, adapters/, terraform/, modules-ir/) with .gitkeep - T-6.3: create top-level scripts/verify_phase06.sh (v1.1 verify scripts live at top-level, NOT demo/scripts/ which holds the v1.0 demo verify scripts) - T-6.4: rewrite README.md to reflect the real platform (vision + architecture links, new layout, status v1.1 active); add runner-data/ to .gitignore All moves via git mv (history preserved). Repo root now contains only README.md, demo/, docs/, .ciagent/, and the new empty v1.1 dirs.
55 lines
1.7 KiB
Python
Executable File
55 lines
1.7 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""confidence_signal.py — REQ-08 / D-024
|
|
|
|
Reads a contract.yaml, invokes policy_checker.py as a subprocess, and emits
|
|
a deterministic JSON confidence score.
|
|
|
|
policy pass -> {"score": 0.90, "reason": "POLICY_PASS"}
|
|
policy fail -> {"score": 0.40, "reason": "<violation code>"}
|
|
|
|
Exit 0 ALWAYS (per D-024): the pipeline decides the gate, not this script's
|
|
exit code.
|
|
|
|
Input: argv[1] = path to a contract.yaml file.
|
|
"""
|
|
import json
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
|
|
|
|
def main() -> int:
|
|
if len(sys.argv) < 2:
|
|
print("usage: confidence_signal.py <contract.yaml>", file=sys.stderr)
|
|
return 1
|
|
|
|
contract_path = sys.argv[1]
|
|
|
|
# Resolve policy_checker.py relative to this script so it works regardless
|
|
# of cwd. Use python3 + script path (not ./) per the contract.
|
|
here = os.path.dirname(os.path.abspath(__file__))
|
|
policy_checker = os.path.join(here, "policy_checker.py")
|
|
|
|
proc = subprocess.run(
|
|
["python3", policy_checker, contract_path],
|
|
capture_output=True,
|
|
text=True,
|
|
)
|
|
|
|
if proc.returncode == 0:
|
|
score = "0.90"
|
|
# POLICY_PASS is the expected stdout; strip any trailing whitespace.
|
|
reason = proc.stdout.strip() or "POLICY_PASS"
|
|
else:
|
|
score = "0.40"
|
|
# The violation code (e.g. "POLICY_VIOLATION:PUBLIC_INGRESS") is on stdout.
|
|
reason = proc.stdout.strip() or "POLICY_VIOLATION:UNKNOWN"
|
|
|
|
# Emit with literal score (two-decimal form per the contract) and a quoted
|
|
# reason. Constructed manually so json.dumps does not collapse 0.90 -> 0.9.
|
|
print('{"score": ' + score + ', "reason": ' + json.dumps(reason) + '}')
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main()) |