# Journey: Sophia grounded answer

Sophia now has a shipped customer room at `/sophia`, a live Nisaba-backed answer
route, explicit grounded/partial/ungrounded/abstained states, per-claim labels,
citation locators, Library saves, and browser return continuity. The scope is
narrower than the platform architecture: this route searches the current Nisaba
corpus and does not implement tenant source sets, freshness, retraction,
contradiction, or high-stakes review loops.

## Personas

- **Signed-in questioner** — asks up to 600 characters in the dedicated Sophia
  room and expects either cited evidence or an honest refusal.
- **Evidence reader** — inspects witness kind/weight and retrieved/synthesized
  claim attribution before following a passage into Nisaba.
- **Returning researcher** — comes back from a citation or reload and expects
  the last answer to remain available in the current browser session.
- **Library user** — saves the answer snapshot and witness trail for another
  device/context under the same account.

## Pre-conditions

- The customer can reach `/sophia`; the form posts through the BFF origin/CSRF
  boundary to `POST /v1/sophia/answer`.
- `app.domainAdapters.nisaba.searchLibrary` can search the in-process/public
  Nisaba corpus. This is the only source set used by the customer answer route.
- Optional abstractive synthesis may be configured. The deterministic extractive
  composer is always available as the fallback.
- Authenticated Library saved-items routes are available for the Save action.

## Steps

### 1. Ask in the dedicated room

`SophiaAskForm` requires non-whitespace input, disables submit while pending,
keeps the query visible, and sends `{ q }` to `/v1/sophia/answer`. Non-OK and
network failures render distinct recoverable alerts without replacing the last
valid answer with fabricated content.

Search has a related but separate entry: a focused result preview exposes its
grounded-evidence status and “Compare with OSHUN” handoff. Search does not
itself call the Sophia answer route.

### 2. Retrieve and compose the answer envelope

The BFF searches Nisaba for up to six query-relevant records and maps them to
citations with id, title, kind, summary, citation label, and a kind-based
weight. It returns `answer`, `confidence`, `citations`, `claims`, `citationMap`,
`groundingState`, `abstained`, and a confidence `meter`.

Default composition quotes the retrieved summaries, emits one `retrieved` claim
per witness, and never asserts beyond those sources. Three or more citations
produce `grounded`; one or two produce `partial`. No hits produce an
`ungrounded` abstention, while empty input at the API layer produces
`abstained`. When optional LLM synthesis fails or yields unusable claim links,
the route fails soft to extractive output.

### 3. Read grounding, witnesses, and claims

The customer card displays grounding state, confidence, citation count, answer,
witness title/summary/kind/weight, and each claim's
`retrieved | synthesized | model-only` label plus citation ids. The server
defensively removes dangling claim ids and never emits a usable `model-only`
claim.

The BFF's richer `meter` (fill, credibility factors, abstention explainer) is
not included in `SophiaAskForm`'s response interface and is not rendered. The
visible status line is therefore a summary, not the full returned meter.

### 4. Follow a passage citation into Nisaba

Passage citation ids are converted into
`/domains/nisaba?origin=sophia&path=/library/passage/<id>?locator=<excerpt>`.
The Nisaba reader asserts the exact passage id, matches and highlights the
locator text, and renders the reading frame. Before leaving, Sophia stores its
scroll position; Browser Back restores the session-stored answer and returns
near that position without refetching.

### 5. Save the answer snapshot

Save maps the answer to a `nisaba` / `assistant-excerpt` Library item containing
the answer text, witness titles, grounding/trust state, and a notebook-shaped
resume path. It writes the authenticated saved-items BFF and toggles the common
Library save telemetry. Browser coverage clears local Library cache in a second
context and proves the saved metadata/witness trail rehydrates there.

The test does not open that generated `/workspace/notebook/<answer-id>` resume
path, so a durable editable notebook representation is not proven.

## Post-conditions

- Every non-abstaining emitted claim has at least one citation id present in the
  answer's citation list; no `model-only` or dangling claim is accepted.
- No-hit and empty-query API branches decline rather than inventing sources.
- The last valid answer survives reload in sessionStorage, and citation return
  restores the answer and approximate scroll position.
- A saved answer snapshot and witness trail are readable from the BFF in a
  cache-free second context.

## Failure modes

- **Nisaba search unavailable/no hits** — retrieval becomes an honest
  no-citation abstention rather than a 500 or uncited prose.
- **Synthesizer failure/timeout** — falls back to deterministic extractive
  composition.
- **Dangling/model-only synthesis** — invalid citation ids are filtered;
  claimless output abstains.
- **Customer route outage** — non-2xx and network errors preserve the query and
  expose retryable alert copy.
- **Source-scope overclaim** — the answer route does not take tenant/source-set
  identity and searches Nisaba only.
- **Freshness/retraction overclaim** — Nisaba results carry no retraction flag;
  `retracted-source` is a reserved state that this route never produces.
- **Meter invisibility** — API consumers receive credibility detail, but the
  customer card does not render it.
- **Saved resume path** — saved-item rehydration is covered; opening the
  synthetic notebook destination is not.

## E2E coverage

- [`apps/oshun/web/e2e/sophia-answer-bff.spec.ts`](../../apps/oshun/web/e2e/sophia-answer-bff.spec.ts)
  proves the live grounded, partial, no-hit, and empty-query envelopes, meter,
  query aliases, and no model-only/dangling claims.
- [`apps/oshun/web/e2e/sophia-grounded-answer-page.spec.ts`](../../apps/oshun/web/e2e/sophia-grounded-answer-page.spec.ts)
  drives form states, live answer branches, session restore, citation locator
  handoff/Back, BFF save metadata, cache-free second-context Library hydration,
  and outage alerts.
- [`apps/oshun/web/e2e/assistant-grounding-state.spec.ts`](../../apps/oshun/web/e2e/assistant-grounding-state.spec.ts)
  covers the adjacent assistant grounding-state presentation, not the Sophia
  route's retrieval engine.
- **Coverage depth: deep** for the current Nisaba-backed answer envelope and
  page. Tenant/freshness/retraction/review loops and saved resume remain open.

## Per-view files touched

- [`customer/02-home-discovery/search.md`](../customer/02-home-discovery/search.md)
  — result preview grounding entry.
- [`customer/07-nisaba/nisaba.md`](../customer/07-nisaba/nisaba.md) — citation
  destination and locator highlight.
- [`customer/02-home-discovery/library.md`](../customer/02-home-discovery/library.md)
  — saved answer snapshot and second-context read-back.
- [`shell/04-auth-session.md`](../shell/04-auth-session.md) — protected customer
  page versus public BFF read semantics.

## Cross-references

- [`search-explore-deep-read-library-save.md`](./search-explore-deep-read-library-save.md)
  — Search preview and shared Library contract.
- [`citation-drift-resolution.md`](./citation-drift-resolution.md) — separate
  citation lifecycle after source movement.
- [`nisaba-scholarly-read.md`](./nisaba-scholarly-read.md) — deeper reading
  tools after the locator handoff.
- Sources: `apps/oshun/web/src/app/sophia/SophiaAskForm.tsx`,
  `apps/oshun/bff/src/sophia/answer-composer.ts`, and the Sophia block in
  `apps/oshun/bff/src/routes/domain-stubs.ts`.

## Open questions

- How should tenant/source-set identity enter this route without leaking across
  scopes?
- Which source metadata enables honest freshness, retirement/retraction, and
  credibility-factor rendering?
- Should the customer page render the returned confidence meter and abstention
  explainer?
- Should Save create a real notebook/excerpt artifact whose resume destination
  is browser-proven, rather than only saved-item metadata?
- Which questions require a high-stakes fact-check/review gate before answer
  presentation?
