Change the claim shape
The Claim document is the contract between everything. Change it in one place, then let the type checker walk you through the rest.
As an example, we add a claimant.preferredContact field: how the claimant asked to be contacted, so the drafting and call-assist capabilities can respect it.
Steps
-
Edit the schema in
packages/shared/src/claim.ts. Give the new field a default unless every host can genuinely supply it:packages/shared/src/claim.tsexport const Claimant = z.object({// …preferredContact: z.enum(['phone', 'email', 'post', 'unknown']).default('unknown').describe('How the claimant asked to be contacted'),});.default()keeps it optional on input and present on output, so no consumer has to handleundefined..describe()text appears in the generated reference and in the JSON Schema the generator puts in its prompt, so write it for both readers.- Prefer an honest empty default (
'unknown','',[],0) over a plausible one. Absence must read as absence.
-
Follow the type errors.
npm run typecheckA new defaulted field rarely breaks anything. A renamed or retyped field will surface in the fixtures (
packages/shared/src/fixtures/), the tools (api/src/capabilities/), the claim brief (api/src/chat/context.ts),claimView.tsand the screens. -
Use it. Decide who needs it:
- A tool that should return it.
get_claim_sectionreturns whole sections, so the field is already readable as part ofclaimant. - The claim brief, only if the model needs it on every turn. Keep the brief small.
- A playbook, to tell the model what to do with it (
capability.document_production,capability.call_assist). - The screens, through
deriveClaimView, if a handler should see it.
- A tool that should return it.
-
Update the fixtures so the examples the generator learns from use it, then run the tests:
npm testThe shared contract tests check every fixture still parses and that the required core is still exactly the eight fields hosts are told about. If you made the field required, that test fails on purpose: update it, the integration guide and the claim mapping together.
-
Regenerate the reference.
npm run docs:reference -
Think about stored data. Defaulted fields need nothing: old documents parse and pick up the default. A new required field, a removed enum value or a changed type means stored claims will fail
Claim.parse. Regenerate them, or migrate the stored JSON deliberately. -
Tell hosts. An embedding host maps its own claim onto the contract. A new optional field is an opportunity for them; a breaking change is a coordinated release. Update the claim mapping page with what the field switches on.
Rules of thumb
- Additive and defaulted is the default kind of change. It needs no data migration and no host changes.
- Never add a sentinel. A fake date or a zero that means "unknown" turns into a plausible wrong answer.
- Keep the required core small. Eight fields is what a host can map in twenty minutes. Every addition to it is a cost to every host.
- The document is the source of truth. The denormalised columns in the
claimstable (line_of_business,scenario,status,title) exist for listing. If a change touches one of those, update both adapters'upsert.