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.commuteandpersonaltrip purpose values require an engine vocabulary extension before they can be evaluated deterministically. Until that extension lands, claims carrying either value will havetrip_purpose_stated: not_returnedin 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.