CoverageAnalyzerGKR
What it is¶
CoverageAnalyzerGKR is one engine with a coverage_spec per line of business. It answers whether the policy responds to the loss: policy validity on the trigger date, insured status per party, grants, exclusions with their carve-outs, endorsements, terms, and a verdict with duties for the liability lines. It also publishes concerns for the authority gate. It replaced the separate Property and GL coverage tools, filled the Auto gap that had left the gate's coverage verification dimension permanently indeterminate, and added a WC coverage step ahead of compensability .
The engine is LOB-agnostic. Its docstring still describes Property as a Phase 2 migration and GL and WC as later phases; that text records a sequencing plan and reads as a limitation, and is flagged for correction.
Spec content¶
Each coverage_spec carries the same shape. Exclusions are chunks with structured triggers and carve-outs. Endorsements are read only from the policy schedule. Form provisions are records, so a carrier's manuscript form supersedes ISO by overlay rather than by code. State overlays come only from the jurisdiction resolver. Homeowner and commercial vacancy provisions are separate records. Additional insured status established by certificate alone is unverified .
No LLM runs inside the analyzer. An exclusion whose application is interpretive returns indeterminate with a coverage-counsel item rather than a guess.
Policy source is the posture¶
Every run records policy_source as one of policy_system, declarations_document or fnol_stated. The verdict inherits the weakest source: fnol_stated means provisional, and the authority gate reads provisional as not verified. The provisional flag has to travel to the next tool, or the fail-open simply moves one hop downstream. The worked example is an adapter block that carried policy status and driver fields to the gate but omitted verification_status, so the gate saw an active policy and a simple file with no way to know it rested on dates stated over the phone.
Two consequences follow. Endorsement presence is knowable only at policy_system or declarations_document. Duty to indemnify is yes only at policy_system with every exclusion resolved; it is never affirmed at first notice.
There are no defaults for missing policy facts. The Property tool's HO-3 default and its ratio-filled limits were retired.
Two kinds of unknown¶
Only one kind of unknown is a coverage question. An absent claim fact leaves the exclusion's trigger indeterminate: a search that came back empty, which does not change the verdict. A fired trigger whose carve-out depends on an unverified policy is open, and that does change the verdict. Reservation of rights fires only in the second case, and an ROR verdict names its grounds with the fact and the span. Status partial is scoped to indeterminate grants, triggered-open exclusions and an indeterminate verdict. Drawing this line turned ten identical reservation-of-rights verdicts into ten covered verdicts on the Auto review. It is the same line SensitiveIndicatorDetectorGKR draws between not_fired and indeterminate.
Answered per head¶
Coverage is answered per coverage head, not per file. A grant needs both limbs: the loss fact and the part on the schedule. The verdict aggregates by head using a trigger_would_fire flag, so a triggered head with no responding part yields partially_covered with a concern rather than covered. A party whose role is other_driver is not_an_insured by rule, not unknown. Absence of an exclusion endorsement is never the presence of a coverage endorsement.
Exclusions are still evaluated at file level and must aggregate by coverage part the way grants now do; Property inherits this and should carry it from the start. A head whose loss fact is true and whose part presence is unknown needs its own verification item naming the head.
The boundary with compensability¶
Coverage never evaluates arising out of employment, course of employment or WC defenses. Compensability never verifies the policy, the employer match, the state listing or the class, and never sets authority. Coverage runs before compensability in the WC recipe, but compensability runs regardless of the coverage verdict, because an injury can be compensable with no policy responding and the claim then runs to the uninsured employers fund. Coverage is recorded as context that gates the recommendation, never the analysis. See .
The empty catalogue¶
Absence of a catalogue is not absence of the thing catalogued. A coverage verdict of covered was reached with zero exclusions evaluated because the coverage loader returned an empty list and the engine read that as no exclusions applying; the run reported success rather than a missing-governed-input error, so a verdict was computed with nothing checked. This was one of three false affirmatives found in a single readiness audit, and one of two certain to fire on every Property claim. The rule now is that an empty exclusion catalogue is a missing governed input and the run fails closed with a named reason. The same shape appeared in the subrogation screener silently dropping a chunk id that does not resolve, where a mistyped id and a claim with no recovery produced identical output.
The related finding is that truthful governance extends to stubs. An empty overlay_rejected list asserts that carrier records were considered; a state_overlays_applied list inferred from resolved sections claims work that was not done. A field that names a control is a claim that the control ran. The overlay stub was replaced by real resolution with a tighten-only check; the overlay rejection path is untested and needs carrier fixtures.
Fail closed is a property of the path¶
The three-valued grammar inside the evaluator was correct from the start. The defect sat one layer inside: the facts dict assembled for it collapsed absent to false through derived convenience flags, and endorsement presence was fabricated from an unread policy. Every non-negotiable was checkable at the boundary and passed. Check where the facts come from, not only what the engine does with them. A broken read and a fail-closed refusal look identical from the output and have opposite remedies; the Auto build reported schema drift against EXTRACT-CORE as correct fail-closed behaviour for a full review round. An indeterminate is only trustworthy once you can name the path that was read.
Some errors are visible only to a domain reader: the business-use carve-out inversion, an invented ISO exclusion, rescission modelled as an exclusion rather than a concern, indemnity affirmed at first notice, and covered returned when the injury head had no responding part. Curation review is a separate gate from code review.
Regression and status¶
Auto was cleared engineering complete and shadow-ready on 2026-09-07 after three review rounds, with COVERAGE-AUTO-PLATFORM-v1 active on a recorded twelve-case matrix keyed on policy_source, the same fact pattern run at every source . Scenario seeds borrowed from the subrogation taxonomy were only a smoke test; the matrix on the axis the design turns on is the gate. Both carry-forwards from the review closed on spec v2 at 12/12. A spec seeded active with a null regression block occurred here for the third time across liability, authority and coverage, so seed approved and promote on a recorded run is the standing rule.
Sequencing was Auto first, Property second, GL third, WC fourth. In the Trace Contract Program lineup coverage is step 3, ahead of liability, because the payment gate and the authority gate need it and it carries the most curation . On the carrier-structured path the analyzer must report not_run with a reason rather than error when it has no configured input.
Open items¶
Exclusions aggregate at file level, not per part. Seed-time field validation should extend to the spec's own applies_when expressions across both namespaces (extractor-published facts and analyzer-derived keys). The overlay rejection path has no carrier fixtures. The gate's coverage dimension must read coverage_result verification_status and concerns rather than the flat adapter block. The docstring sequencing text is stale.