Skip to content

The four status vocabulary

What it is

Every fact that reaches a rules tool arrives in an envelope with a status. There are four statuses and no fifth. A rule may act on two of them, must treat one as the vendor's own claim, and must resolve the last to indeterminate. Any other literal raises unknown_fact_status .

Status Meaning Who may produce it What a rule may do
stated A value was returned for the field Carrier, vendor, native extractor Act on the value
not_stated The document was read and the fact is not there; a verified absence Carrier, vendor, native extractor Act on the absence
not_extractable The reader attempted the field and could not resolve it (a garbled table, scan quality); the vendor's own claim Vendor or native extractor only Treat as open; never synthesise on the vendor's behalf
not_returned The spec expected the field and nothing was said about it; nobody looked The normalizer, on an omitted key Nothing; resolves to indeterminate

Two statuses a carrier may send

A carrier sending structured claim data uses only stated and not_stated. An omitted field is not_returned and resolves indeterminate. This is written into the carrier format and its schema enum, and the receipt returned before a run lists what the payload stated, what it marked not stated, and what it left out .

The distinction has teeth. A sample payload once sent not_stated for seven facts that the reference brief listed as not supplied (among them waiver of subrogation, employment relationship and the five fleet negligence facts). Sent that way, the waiver gate clears, the independent contractor defense excludes and fleet negligence excludes instead of staying open, and the brief cannot match its target. The fields had to be omitted. A converter that emits not_stated from a not_returned seed field is a converter defect.

not_stated means reviewed and absent. A vocabulary of present, absent and unknown is rejected at the normalizer, and no unknown enum value exists anywhere on the path.

Why the two absences are never merged

not_returned ("not supplied") and not_stated ("not stated, verified absence") are different facts. They are never merged, mapped to each other, or rendered with the same words .

The reason is what a rule does with each. not_stated is a fact a rule may act on: a stated absence on a defense trigger is a verified absence and the defense does not fire. not_returned means nobody looked, which no rule may act on. If any consumer reads non-stated as absent, a field nobody answered becomes a confirmed negative, and a theory fails to fire for a reason that is never reported. That is why the screener needed a code-level check rather than an assumption, and why every consumer that branches on status is traced for what it does with an unrecognised value.

The same line runs into the brief. A render once printed not_returned as "Not stated". That is a meaning error, not a wording one, and it is on the list of mistakes not to repeat.

Why not_extractable is not synthesised

When a vendor omits a field, the normalizer could have written not_extractable. It does not, because not_extractable is the vendor's own claim about a field it tried to read, and writing it on their behalf puts words in their mouth. Defaulting an absent key to not_stated would be worse: the harness would be asserting a fact about a document nobody read.

A fifth distinction sits inside not_stated. An absence can be verified (a vendor citation confirming a searched paragraph) or conventional (a vendor's empty-string convention). The normalizer carries this as basis: "vendor_convention" rather than folding it into the status, so a rule acting on an absence can see whether the absence was verified. basis is an audit annotation. It must never adjust a confidence score, because a score adjustment is invisible in the output and compounds silently .

One accessor

One accessor, _fact_status, reads status. Nothing bypasses it. The single accessor was the first gap fix in the subrogation build, with the rule that non-stated never confirms, and it is the enforcement point for the closed enum .

The envelope stays on every field, on every path. Bare values on the vendor path while the native path carried status would reintroduce the divergence the normalizer exists to close, and a bare empty string is not self-describing where an empty envelope is.

Indeterminate resolution

A tool reading not_returned resolves the rule that needed it to indeterminate, and the indeterminate names the fields it needed. This is the same behaviour the detector has for a missing fact: a fired trigger whose resolution depends on something unread is open, and only that kind of unknown changes a verdict. A fact searched for and not found is simply not fired.

Could-not-evaluate and considered-and-rejected must never render the same. A Property subrogation section reporting no referral when a vocabulary mismatch meant no theory could ever confirm is the same defect as the detector's not fired against indeterminate, arriving in the output layer.

Where the vocabulary came from

The four statuses were fixed at the vendor boundary. When extraction moved to an external IDP, the normalizer had to walk the spec's field list rather than the vendor's output keys, and a field the spec expected with no key in the vendor JSON needed a name. Four rulings settled it: absent is not_returned, the envelope stays on every field, basis distinguishes conventional from verified absence, and provenance records the vendor, vendor model, normalizer version and spec versions with field counts across the four statuses .

Negative controls were required because every available fixture was a positive case. A normalizer that collapsed not_stated, not_extractable and not_returned into one value would have passed every fixture. The guard that matters is a test in which three inputs must produce exactly three distinct statuses at once.

The Martinez finding

The first measurement of what a vendor did not answer came from the Martinez worked example: 119 stated, 77 not_stated, 0 not_extractable, 16 not_returned against EXTRACT-CORE v1 and the AUTO spec v2. Whether the 16 are a schema gap, a vendor gap or fields no Auto document would carry is not yet established. The count is a completeness measurement now and a procurement metric later, tracked with the spec version beside it, because a rising count after a spec change means the spec grew rather than the vendor got worse.

Completeness is a property that must be measured, never assumed. The detector's Phase A once reported success on a response missing a third of the facts it asked for, because nothing compared the requested list to the returned list.

Status words in a brief

A status word in a brief comes only from a ledger template. The inputs considered section renders each field as Stated with its value and speaker, Not stated, or Not supplied, and the renderer assertion that status words appear only via ledger templates is one of the twelve the page must pass .

Open items

  • The 16 not_returned fields on Martinez are unclassified.
  • vendor_model read "unknown" in the smoke test, which makes two runs incomparable.
  • The harness falls back to a flat copy when the database is unavailable; it should fail closed with the reason.
  • An addendum stating that not_stated means reviewed and absent, with no unknown value, goes to the carrier only after engine verification returns.