One-Roof Clone Axis/Topic — 04 Axis Assignment Coverage (Obj C, PASS, 5 fail-closed)
04 — Objective C: Axis Assignment Coverage
Verdict: PASS — committed (integrated active state). SQL: sql/C_axis_assignment_coverage_clone_COMMIT.sql. 16/16 checks PASS including 5 fail-closed negatives.
What was committed — the integrated two-axis state
The topic axis was activated and persisted, and topic owners seeded in the parallel axis_object_ownership table, producing the project's first integrated multi-axis coverage state:
| axis | status | required | gap | reading |
|---|---|---|---|---|
| responsibility | active | 210 | 0 | production-equivalent; reads existing v_object_effective_owner |
| topic | active | 6 | 2 | honest residual (designed-in for detection) |
| total | 216 | 2 |
The 5 topic required cells (after adding a stale tasks assignment) are owned for 4 and intentionally left uncovered for 1 (modules), and a 6th cell appears from the quarantine test — yielding the residual 2.
Confidence / zone (proven)
Every topic assignment carries confidence, match_score (kept separate — never collapsed), zone, provenance, and assigned_kind. The committed object→topic picture:
| object | topic | zone | confidence | kind | quality_flag |
|---|---|---|---|---|---|
| agents | ai-ops | candidate | 0.92 | human | ok |
| governance_registry | registry-kg | candidate | 0.85 | agent | ok |
| workflows | workflow | candidate | 0.96 | human | ok |
| modules | workflow | candidate | 0.55 | agent | low_confidence |
| tasks | ai-ops | candidate | 0.80 | agent | stale (assigned 60d ago, rule staleness 30d) |
| iu_staging_record | ai-ops | quarantine | null | agent | quarantine (null provenance) |
Detection (all four required signals proven)
v_axis_assignment_quality computes a single quality_flag per active assignment from the coverage rule:
- low_confidence —
modules(0.55 < 0.70 threshold). - stale —
tasks(assigned_at older thanstaleness_days). - quarantine / missing_provenance —
iu_staging_record(null provenance forced to quarantine). - missing assignment —
v_axis_missing_assignmentlists inventory objects with no topic assignment (29 after this run's assignments) — bounded by inventory. - missing owner —
v_axis_coverage_gapfor topic (modules+ the quarantine cell).
Invalid assignment — fail-closed (5 negatives, all rejected)
Each was attempted in a savepoint-isolated subtransaction and must error:
| # | attempt | rejected by | SQLSTATE |
|---|---|---|---|
| N1 | assignment with NULL provenance, zone≠quarantine | chk_provenance_or_quarantine |
23514 (check) |
| N2 | assignment to a non-existent axis value | FK → axis_value |
23503 (fk) |
| N3 | duplicate active assignment (same object/axis/value) | uq_axis_assignment_active |
23505 (unique) |
| N4 | owner referencing a non-existent value | FK → axis_value |
23503 (fk) |
| N5 | duplicate accountable owner for one cell | uq_axis_obj_accountable |
23505 (unique) |
Positive control: a NULL-provenance assignment is allowed only when zone='quarantine' — proving the provenance-or-quarantine invariant is a gate, not a blanket ban. That quarantine cell then correctly counts as an uncovered required cell (it still needs an owner), bumping the topic gap as expected.
Significance
This is the first time the project has run two governed axes at once with honest, differentiated coverage: responsibility fully covered (the proven model), topic partially covered with every quality signal — low confidence, stale, quarantine, missing owner, missing assignment — surfaced rather than hidden. The fail-closed negatives show the substrate cannot be driven into an invalid state.