feat(P03): confidence_signal.py (T-3.6)
---ci--- phase: 3 milestone: v1.0 status: execute persona: backend-engineer task: T-3.6 requirements: covered: [REQ-08] ---/ci--- Wave 2, task T-3.6. Confidence signal: 0.90 on policy pass, 0.40 on violation; exit 0 always (D-024).
This commit is contained in:
Executable
+53
@@ -0,0 +1,53 @@
|
||||
#!/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"
|
||||
|
||||
print(json.dumps({"score": score, "reason": reason}))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user