76 lines
2.3 KiB
Python
76 lines
2.3 KiB
Python
|
|
"""V4 arm-readiness reporter — DARK, read-only, non-colliding.
|
||
|
|
|
||
|
|
Aggregates V4 gate outcomes into a typed report answering: "is V4 ready
|
||
|
|
to ARM the live canary?" Does NOT run gates — CONSUMES their results
|
||
|
|
(passed in) and applies fail-closed readiness logic.
|
||
|
|
|
||
|
|
Spec: prod/docs/VIOLET_PASS_MM1_V4_READINESS_REPORTER.md
|
||
|
|
"""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from .domain import StrictModel, typed
|
||
|
|
|
||
|
|
__all__ = ["V4ReadinessReport", "assess_v4_readiness"]
|
||
|
|
|
||
|
|
|
||
|
|
class V4ReadinessReport(StrictModel):
|
||
|
|
"""Typed V4 readiness report — all six gates must pass for ready_to_arm."""
|
||
|
|
|
||
|
|
creds_ok: bool
|
||
|
|
canary_passed: bool
|
||
|
|
arming_gate_present: bool
|
||
|
|
conviction_bit_identical: bool
|
||
|
|
selection_parity_ok: bool
|
||
|
|
feed_live: bool
|
||
|
|
reasons: list[str]
|
||
|
|
|
||
|
|
@property
|
||
|
|
def ready_to_arm(self) -> bool:
|
||
|
|
return all((
|
||
|
|
self.creds_ok,
|
||
|
|
self.canary_passed,
|
||
|
|
self.arming_gate_present,
|
||
|
|
self.conviction_bit_identical,
|
||
|
|
self.selection_parity_ok,
|
||
|
|
self.feed_live,
|
||
|
|
))
|
||
|
|
|
||
|
|
|
||
|
|
@typed
|
||
|
|
def assess_v4_readiness(
|
||
|
|
*,
|
||
|
|
creds_ok: bool,
|
||
|
|
canary_passed: bool,
|
||
|
|
arming_gate_present: bool,
|
||
|
|
conviction_bit_identical: bool,
|
||
|
|
selection_parity_ok: bool,
|
||
|
|
feed_live: bool,
|
||
|
|
) -> V4ReadinessReport:
|
||
|
|
"""Build a V4ReadinessReport from gate outcomes. Fail-closed: any False
|
||
|
|
means ready_to_arm is False. No partial-arm."""
|
||
|
|
|
||
|
|
reasons: list[str] = []
|
||
|
|
if not creds_ok:
|
||
|
|
reasons.append("creds_ok: PASS2.1 not satisfied")
|
||
|
|
if not canary_passed:
|
||
|
|
reasons.append("canary_passed: PASS2.3 canary not round-tripped flat")
|
||
|
|
if not arming_gate_present:
|
||
|
|
reasons.append("arming_gate_present: PASS2.2 not satisfied")
|
||
|
|
if not conviction_bit_identical:
|
||
|
|
reasons.append("conviction_bit_identical: PASS2.5 fidelity mismatch")
|
||
|
|
if not selection_parity_ok:
|
||
|
|
reasons.append("selection_parity_ok: PASS2.7/3.1 parity mismatch")
|
||
|
|
if not feed_live:
|
||
|
|
reasons.append("feed_live: PASS2.6 HZ feed stale or deaf")
|
||
|
|
|
||
|
|
return V4ReadinessReport(
|
||
|
|
creds_ok=creds_ok,
|
||
|
|
canary_passed=canary_passed,
|
||
|
|
arming_gate_present=arming_gate_present,
|
||
|
|
conviction_bit_identical=conviction_bit_identical,
|
||
|
|
selection_parity_ok=selection_parity_ok,
|
||
|
|
feed_live=feed_live,
|
||
|
|
reasons=reasons,
|
||
|
|
)
|