The defect
tools/check_release_plane.py (landing in #373, for #370) catches release: assignments buried in the fields: extension bag, where rivet's query surface is blind to them. It works, and it is structurally general — but the field it checks is a hardcoded module-level constant:
The same defect exists right now on status:, and nothing catches it.
Measured evidence
While migrating #371 I reconciled 303 raw status: text matches against rivet's 276 reported errors. The 27-item gap is entirely two blind spots:
|
count |
why rivet misses it |
safety/stpa/architecture.yaml |
6 |
status: nested inside fields:, invisible to the query surface |
safety/requirements.yaml |
21 |
file is under no path in rivet.yaml's sources: — never loaded at all |
The six are ARCH-026, ARCH-027, ARCH-028, ARCH-030, ARCH-031, ARCH-032. Each carries fields.status: planned at 6-space indent, sibling of rationale: and source-files:, and has no artifact-plane status at all. That is precisely #370's shape, one field over.
They are not errors today only because rivet cannot see them. They also did not appear in #371's 276, which is why #371 left them in place and named them rather than silently absorbing them.
Proposed fix
Generalise FIELD to a list — ("release", "status") — and iterate. The parser, the block-scalar handling, the fail-closed behaviour and the fixtures are already field-agnostic; only the constant and the report strings assume a single name.
This was deliberately not done inside #371/#374: that branch is stacked on #368, and touching #373's tool there would have stacked it three-deep and broken the "vocabulary only, no tooling change" scope posted on #371.
Second, separable problem
safety/requirements.yaml holds 21 off-vocabulary statuses and rivet never loads it. A plane-checker will not help — the file is outside the store entirely. Either add it to sources: (and then fix what surfaces), or delete it if it is genuinely dead. It should not keep sitting there looking like tracked traceability while being tracked by nothing.
Ordering
Blocked on both #373 and #374 merging.
The defect
tools/check_release_plane.py(landing in #373, for #370) catchesrelease:assignments buried in thefields:extension bag, where rivet's query surface is blind to them. It works, and it is structurally general — but the field it checks is a hardcoded module-level constant:The same defect exists right now on
status:, and nothing catches it.Measured evidence
While migrating #371 I reconciled 303 raw
status:text matches against rivet's 276 reported errors. The 27-item gap is entirely two blind spots:safety/stpa/architecture.yamlstatus:nested insidefields:, invisible to the query surfacesafety/requirements.yamlrivet.yaml'ssources:— never loaded at allThe six are
ARCH-026,ARCH-027,ARCH-028,ARCH-030,ARCH-031,ARCH-032. Each carriesfields.status: plannedat 6-space indent, sibling ofrationale:andsource-files:, and has no artifact-planestatusat all. That is precisely #370's shape, one field over.They are not errors today only because rivet cannot see them. They also did not appear in #371's 276, which is why #371 left them in place and named them rather than silently absorbing them.
Proposed fix
Generalise
FIELDto a list —("release", "status")— and iterate. The parser, the block-scalar handling, the fail-closed behaviour and the fixtures are already field-agnostic; only the constant and the report strings assume a single name.This was deliberately not done inside #371/#374: that branch is stacked on #368, and touching #373's tool there would have stacked it three-deep and broken the "vocabulary only, no tooling change" scope posted on #371.
Second, separable problem
safety/requirements.yamlholds 21 off-vocabulary statuses and rivet never loads it. A plane-checker will not help — the file is outside the store entirely. Either add it tosources:(and then fix what surfaces), or delete it if it is genuinely dead. It should not keep sitting there looking like tracked traceability while being tracked by nothing.Ordering
Blocked on both #373 and #374 merging.