matter_type + forum into the intake input — closing #1292 (app half)The Add-Matter wizard collects a coarse matter type (Story-1281/1282) and a
forum (Story-1289), but neither reached Atlas: buildWizardInput
— the function that maps the wizard drafts onto the AtlasIntakeInput wire shape —
sent neither. So every Step-5 run launched without its declared grounding priors, and Atlas inferred the
dispute nature purely from counsel's free text. This is the follow-through on the deliberate descope in
Story-1289 ("the Atlas grounding (forum + matter_type) is split into a separate coordinated
functions+brain+app ticket"). This slice is the app sender half per ADR-031.
AtlasIntakeInput in
pramaan-agents/agents/atlas/models.py. Two facts gate this work:
matter_type: str | None is already declared (Story-1282, the grounded
ECA prior). The app simply never sent it. Sending it now takes effect immediately.extra="forbid" → Pydantic's default
ignore applies. An undeclared field (forum, until the
agents half lands part B) is silently dropped by the brain, not a validation error. So
sending forum now cannot break a Step-5 run — it is forward-compatible.extra="forbid" model; this model ignores extras.| Piece | What & why |
|---|---|
| Snapshot shape | atlas-rail.ts — WizardSnapshot gains optional matterType?: string | null and forum?: string | null (the selected names, not ids — Atlas grounds on counsel's words, e.g. "Domestic Arbitration" / "SIAC"). |
| The send | buildWizardInput spreads matter_type / forum into the wire object only when present: { ...(matterType ? { matter_type } : {}) }. Tolerant — a null/blank/whitespace pick is omitted, never sent empty, so Atlas falls back to inferring from free text (pramaan-docs ADR-115 D1). |
| Name resolution | add-matter-wizard.tsx resolves the names from the live picker option lists by id (matterTypes.find(m => m.id === matterTypeId)?.name ?? null, same for forums/forumId) and threads them into the useAtlasRail snapshot. null when counsel hasn't picked — preset path may derive the type server-side. |
| Re-launch correctness | The grounding fields are part of buildWizardInput, which is the inputSig Atlas re-launches on. Changing the matter type or forum in Step 2 and returning to Review now correctly re-grounds the run — for free, no extra wiring. |
| Tests | Two new buildWizardInput cases in atlas-rail.test.ts: (1) sends matter_type+forum when collected; (2) omits both when unset, and treats null/whitespace as unset. |
None. matter_type and forum are wire data fields, not user-facing
copy — no new strings, no en.json/hi.json change.
forum: str | None to AtlasIntakeInput
(pramaan-agents) + broker passthrough (pramaan-functions). Until then the app's forum
field is ignored by the brain — harmless. Because the app send is non-breaking, it does not need to wait;
the producer halves can land independently. The OpenAPI mirror (openapi/app-api.json)
is in sync and untouched — the intake model is a BAML/Pydantic agent contract, not part of
the app HTTP contract, so no pnpm codegen was run.pnpm tsc clean pnpm lint clean (0 errors; 4 pre-existing warnings, none introduced by this diff) pnpm build green vitest full suite 514 passed (89 files) — incl. 2 new buildWizardInput grounding cases openapi drift diff -q against functions main: identical (no contract/codegen change)
src/lib/agents/ plus the snapshot wiring in the wizard.3 file(s), +82 / -1 lines
| Path | Role | + | - |
|---|---|---|---|
| src/components/add-matter/add-matter-wizard.tsx | Component | +10 | -1 |
| src/lib/agents/__tests__/atlas-rail.test.ts | Library | +50 | -0 |
| src/lib/agents/atlas-rail.ts | Library | +22 | -0 |