Extract the Documents (Block 3a)¶
The claim form is the one document that arrives as a structured form, so it is read into fields with IXP. The policy and the assessor report are prose: they stay documents, and the Agents read them directly. This block proves the reading before anything downstream binds to it.
Nothing is created here. The shared IXP project already exists, published and pinned, and the provided Extract Claim Data automation is wired to it. Your job is to adopt it and prove it. The extraction is provided infrastructure, like the generator and the retrieval processes: bind these, never rebuild them.
The prompt¶
# Reuse — Claim Form IXP extraction
The claim form (FNOL) is the one document that arrives as a **structured form**, so it is read into fields with IXP. The other two — the policy and the assessor's report — are prose and stay documents; the agents read them directly (`PDD.md` §5.6).
**The IXP project already exists.** `CONFIG.md` names the shared one, published and tagged `live`, and the provided `Extract Claim Data (IXP)` automation is already wired to it — `contracts/provided-processes.md` says what it takes and what it returns. Nothing is created in this block. Point your design's extraction step at that automation and prove the reading before anything downstream binds to it.
- **Run two generated claims through it and read a payload beside its form.** Check that the key set does not vary and the damage inventory repeats per row. Every one of the six field groups present (`Claim`, `ClaimClaimant`, `ClaimProperty`, `ClaimIncident`, `ClaimDamageInventory`, `ClaimClaimTotals`), the damage rows repeating one per item, not one blob.
- **Pin the field-key spellings from what came back, not from the labels.** `contracts/provided-processes.md` lists the keys the shared model emits; confirm them against a live result and correct `sdd.md` wherever a binding spells one differently (`TypeOfIncident`, never `TypeofIncident`).
Save the payload and let the checker walk every path the design reads:
```bash
python3 3a-extraction/check_extraction_keys.py <payload.json>
```
- **Write down what you used** — the project name and the model version — in `PROGRESS.md` for the next stages.
Training your own model instead of reusing the shared one: `3a-extraction/prompt-build.md` — same output shape, about an hour.
**Done when:**
- two claim forms you have never seen come back with every field group populated, the damage rows repeating correctly, and every key your design reads confirmed against a real payload.
Steps:
- Read
contracts/provided-processes.md(payload shape, field keys) andCONFIG.md(the shared IXP project) - Generate two claims and run each through the provided Extract Claim Data (IXP) process
- Read and validate a payload beside its form: six field groups present, damage rows repeating one per item
- Pin field-key spellings from the live payload; correct
sdd.mdwhere any binding differs - Run the gate:
python3 3a-extraction/check_extraction_keys.py <payload.json> - Record the project name and model version in
PROGRESS.md
Note
Prefer to train your own extraction model instead? 3a-extraction/prompt-build.md in the seed is the supported second route: same output shape, about an hour of labelling.
What the agent will review¶
- Why two claims. One claim proves the fields exist; the second proves the key set does not vary and the damage inventory repeats one row per item, not one blob.
- Keys come from the payload, never from the form's labels. The model emits
TypeOfIncident, not the printed Type of Incident. Every extraction binding downstream is optional-chained, so a wrong key never throws; it silently yields nothing, and the first symptom would be an empty field three blocks from now. That is why this block ends with a checker. - Confidence has three states, not two: confident, unconfident, and absent. A threshold rule that special-cases only one of them ends up flagging empty optional fields as data problems.
- Payload sizes are a design input. About 5,000–5,600 characters per claim, ~500 per damage row, five rows maximum. Your entity columns and agent input budgets are sized against these numbers in the next blocks.
Publishing is not deploying
The shared model is published and callers pin its version, so it needs no deployment into your folder at all. Two different verbs, two different lifecycles; keeping them apart will matter again at the app block.
The gate¶
It walks every extraction path your design reads against a real payload. A wrong key is the one defect that fails silently everywhere else.
Proof¶
Evidence from a real run of this block: a live extraction of claim CLM-2026-397530, all six field groups present, four damage rows. The part to look at is the ClaimDamageInventory array, one object per damaged item, every field carrying its own confidence.
The damage inventory, as the model returned it (expand)
[
{
"Category": { "Value": "Structure - Ceiling", "Confidence": 0.944, "OcrConfidence": 1.0 },
"Location": { "Value": "Master Bedroom", "Confidence": 0.999, "OcrConfidence": 1.0 },
"Description": { "Value": "Water-damaged ceiling panels and plaster, requiring full replacement",
"Confidence": 0.998, "OcrConfidence": 1.0 },
"EstimatedCost": { "Value": { "Value": 4500.0, "Currency": "SGD" },
"Confidence": 0.999, "OcrConfidence": 1.0 },
"RepairOrReplace":{ "Value": "Replace", "Confidence": 0.999, "OcrConfidence": 1.0 }
},
{
"Category": { "Value": "Structure - Walls", "Confidence": 0.999, "OcrConfidence": 1.0 },
"Location": { "Value": "Master Bedroom & Hallway", "Confidence": 0.999, "OcrConfidence": 1.0 },
"Description": { "Value": "Water staining and swelling on drywall, two walls affected",
"Confidence": 0.999, "OcrConfidence": 1.0 },
"EstimatedCost": { "Value": { "Value": 3200.0, "Currency": "SGD" },
"Confidence": 0.999, "OcrConfidence": 1.0 },
"RepairOrReplace":{ "Value": "Replace", "Confidence": 0.999, "OcrConfidence": 1.0 }
}
// … two more rows, same shape: Structure - Flooring, Personal Property - Electronics
]
The keys are the model's (RepairOrReplace, not the form's printed label), the rows repeat per item instead of arriving as one blob, and confidence sits on every field separately: the structure your design binds to.
And here are the same four rows as they sit on the claim form itself; compare Repair / Replace on paper with RepairOrReplace in the payload:

Two claim forms you have never seen come back with every field group populated, the damage rows repeating correctly, and every key your design reads confirmed against a real payload.