Make the risk grade fail safe, and gate CI on absence
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

The mechanism behind RISK-F-0003 was sharper than the finding described.
is_high_risk was risk == "high", but risk was never absent at the model layer:
RouteEntry.risk carried a dataclass default of "standard". An omitted grade was
not unhandled, it was actively resolved to the permissive value — fail-open by
construction, which is why nothing ever warned.

The default is now "ungraded" and is_high_risk returns true for anything outside
an explicit low-risk vocabulary (standard / low / accepted). An omitted grade and
an unrecognised grade from a newer catalog both resolve to high, so the boundary
fails safe in both directions rather than reading an unknown value as permission.

test_every_repo_catalog_lane_is_explicitly_graded is the CI gate that stops an
ungraded lane being committed, per ADR-0007: absence is not a grade.

"accepted" is in the low-risk vocabulary deliberately, ready for the
maturity-derived default — an experimental-context lane may be explicitly
accepted, which is a graded decision rather than an omission.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
tegwick 2026-08-20 01:13:35 +02:00
parent ac85259c20
commit d0d4f9d8fc
4 changed files with 110 additions and 5 deletions

View file

@ -219,7 +219,7 @@ policy covers these paths (T06).
```task
id: WARDEN-WP-0032-T06
status: wait
status: progress
priority: medium
state_hub_task_id: "8c082416-0ff9-45dc-8cbd-e9ca7913a6ef"
```
@ -235,6 +235,31 @@ Feed back to `ZONE-WP-0001-T03` whether ops-warden can supply the join it needs
today no lane references a workload or an environment, so the `M0``M3` ladder
has nothing to attach to from this side.
**Enforcement half done 2026-08-20.** It did not need the zone model: `ADR-0007`
already decided absence is a defect, which is enough to make the code fail safe
and to gate CI.
The real mechanism turned out to be sharper than `RISK-F-0003` described.
`is_high_risk` was `risk == "high"`, but `risk` was **not** absent at the model
layer — `RouteEntry.risk` carried a dataclass default of `"standard"`. So an
omitted grade was not unhandled; it was actively resolved to the permissive
value. Fail-open by construction, which is why nothing warned.
Now: the default is `"ungraded"`, and `is_high_risk` returns true for anything
not in an explicit low-risk vocabulary (`standard` / `low` / `accepted`). An
omitted grade **and** a grade from a newer catalog both resolve to high, so the
boundary fails safe in both directions. `is_graded` exposes the distinction, and
`test_every_repo_catalog_lane_is_explicitly_graded` is the CI gate that stops an
ungraded lane being committed. Four regression tests cover it.
`accepted` is in the low-risk vocabulary deliberately, ready for the
maturity-derived default: an experimental-context lane may be explicitly
accepted, which is a graded decision rather than an omission.
**Still open on this task:** whether the maturity-derived default replaces the
`ungraded` sentinel entirely (waits on `ZONE-WP-0001-T03`), and verifying
OpenBao's `agent-high-risk-boundary` policy covers these paths.
## Related
- `zone-engine` `ZONE-WP-0001` — the model, and where this work is led from