Skip to content

Carrier-structured v1.0 adapter


title: Carrier-Structured v1.0 Adapter description: How the AXA v1.0 carrier-structured payload is validated, mapped to canonical shape, and submitted to the pipeline: including damage mapping, party conversion, subro_facts restructuring, and trip-purpose translation. kind: authored status: current source_date: 2026-10-02 tags: [carrier_structured, v1.0, idp_normalizer, adapt_carrier_structured_v1, V1IntegrityError, AXA, AUTO, PROPERTY]


What it is

The carrier-structured v1.0 adapter is the entry path for pre-structured claim payloads submitted by carriers that have already performed their own FNOL data capture. Rather than running FNOLExtractorGKR against raw documents, the pipeline accepts a JSON payload in AXA's v1.0 schema, validates it against the published schema and a pinned SHA-256, and maps its fields to the canonical envelope that all downstream GKR tools expect. The adapter function is adapt_carrier_structured_v1(payload) in idp_normalizer.py. It is auto-invoked by CarrierStructuredNormalizer.normalize() when header.format_version == "1.0" is detected in the submitted payload: no caller flag is needed beyond --idp carrier_structured.

The Schema Gate

Before any field mapping occurs, the payload is validated against the pinned schema file:

  • Schema path: 53-ADJUST360-FNOL/docs/axa/carrier_structured.subro.v1.0.schema.json
  • Pinned SHA-256: 33b87db3ea821f656abe636d6442ddba64d5f251a2002ec7f1b76569b87f4183

Both checks must pass. A schema validation failure raises V1IntegrityError (a subclass of ValueError) and the harness exits with code 2. The --in flag is used in place of --manifest on the carrier_structured track; the harness validates the file against the schema immediately on load, before any pipeline step executes.

Running a v1.0 Claim

python adjust360_harness.py \
  --idp carrier_structured \
  --in payload.json \
  --lob auto \
  --state TX \
  --reference-date 2025-07-22 \
  --mode subro \
  --brief /tmp/brief.pdf

--reference-date is required on the carrier_structured track. Because no document is parsed, the pipeline has no source from which to derive date_of_loss automatically; the reference date anchors all SOL and deadline calculations.

Field Mapping

Damages

The v1.0 damages[] array uses a (head, kind) tuple to identify each damage item. The adapter maps these to canonical fields as follows:

v1.0 head v1.0 kind Canonical field
PD estimate repair_estimate_stated
rental coverage_terms rental_stated
rental incurred Not mapped: listed on receipt as outside canonical scope
BI reserve medical_reserve_stated
structure estimate structure_estimate_stated
contents estimate contents_estimate_stated
ALE estimate ale_estimate_stated

The (rental, incurred) combination has no canonical key in the current engine vocabulary. The adapter lists it in the receipt's out-of-scope section rather than discarding it silently, so the carrier can see that it was received but not evaluated.

Parties

The adapter converts v1.0 party records via _v1_party_to_canonical. The v1.0 format carries name as a string envelope: {status, value}: whereas the canonical shape expects a bare string. The conversion unwraps the envelope and carries identity_status and insurer_name forward as status envelopes unchanged. The roles[] array is a plain array in both formats and passes through directly.

v1.0 field shape Canonical field shape
name: {status, value} name: "<value string>"
roles: [...] roles: [...] (unchanged)
identity_status: {status, value} identity_status: {status, value} (passed through)
insurer_name: {status, value} insurer_name: {status, value} (passed through)

subro_facts

The v1.0 payload carries some subro_facts fields flat at the top level that the canonical engine expects nested into named groups. The adapter restructures these via _restructure_v1_auto_subro_facts using the mapping table _V1_SUBRO_FLAT_TO_GROUP:

Flat v1.0 field Canonical group
assignment_stated scope_of_employment
deviation_personal_purpose_stated scope_of_employment
route_deviation_described scope_of_employment
owner_knowledge_stated entrustment_evidence
driver_condition_observed entrustment_evidence
license_status_stated entrustment_evidence
prior_incidents_referenced fleet_operations
hours_driven_stated fleet_operations
fatigue_described fleet_operations
pre_trip_condition_stated fleet_operations
prior_repair_referenced fleet_operations

Groups that are already present in the v1.0 payload are merged with the flat fields belonging to the same group: the adapter does not overwrite group-level data that the carrier supplied directly.

trip_purpose_stated

The v1.0 schema carries a trip_purpose_stated field with three possible values. The canonical engine handles one of them natively; the other two require special handling (TC-03a-F3 ruling):

v1.0 value Canonical handling
employer_business Translated to delivery_for_employer: the canonical engine evaluates this deterministically
commute Passed as a finding; trip_purpose_stated set to not_returned; original value preserved in receipt/thesis as a routine verification item
personal Same treatment as commute: passed as finding, status not_returned, original value preserved

The commute and personal values cannot be evaluated deterministically because the engine vocabulary does not yet include them. The receipt and thesis carry a routine verification item for claims where either value appears. The engine vocabulary must be extended before these can be resolved without a manual step.

Exit Code 2 and V1IntegrityError

V1IntegrityError is a subclass of ValueError raised by the adapter when either the schema validation or the SHA-256 check fails. The harness maps this to exit code 2, which is distinct from general pipeline errors (non-zero other). This allows callers and CI scripts to handle schema contract violations as a specific, actionable failure class rather than conflating them with runtime errors.

When a payload fails with exit code 2, the error message identifies whether the failure was a schema violation (with the failing field path) or a SHA-256 mismatch. A SHA-256 mismatch indicates that the payload was built against a different version of the schema than the one pinned in the harness: the carrier must resubmit using the pinned schema.

Unidentified Owner: T15 Ruling

An unidentified party (identity_status.value == "unknown") is never assigned the vehicle_owner role during party conversion. This is a deliberate constraint from the T15 ruling (2026-10-01): vehicle ownership cannot be attributed to an unknown person. If the adapter were to assign the owner role to an unknown party, the engine could treat the owner-driver relationship as established: and from there infer entrustment or deviation: when in fact the identity of the owner is not known. The unknown party receives a placeholder record with identity_status preserved, but no ownership inference is drawn from it. Any downstream tool that queries for the vehicle owner will find no confirmed owner record for the claim rather than a falsely attributed one.

Open Items

  • (rental, incurred) has no canonical key. It is receipted as out-of-scope. A canonical key must be defined before rental incurred amounts can be evaluated in the subro thesis.
  • commute and personal trip purpose values require an engine vocabulary extension before they can be evaluated deterministically. Until that extension lands, claims carrying either value will have trip_purpose_stated: not_returned in the thesis and a verification item in the receipt.
  • PROPERTY v1.0 damage mapping covers the structure/contents/ALE fields listed above; the PROPERTY subro_facts restructuring follows the same group pattern as AUTO but with property-specific field names: the full PROPERTY group map is not yet documented on this page.