# District Companion developer handoff

This package translates the current deterministic web prototype into a platform-neutral implementation reference. It describes the behavior developers need to reproduce without claiming that React prototype files can be dropped directly into the native app.

## Package contents

- `district-companion-contract.json` — canonical conversation states, independent capability conditions, reducer events, timing, exact 240-unit face geometry, and the sample action plan.
- `DistrictCompanionContract.swift` — Foundation-only reference enums and models for a native state store.
- `district-companion-states.svg` — reusable vector symbols for the ten face poses.
- `district-companion-motion.md` — motion timing, reduced-motion behavior, and transition guidance.

## Recommended native architecture

1. Mount one companion coordinator above the app’s changing page hierarchy so the collapsed entry and active conversation persist across navigation.
2. Let a tap on the collapsed orb reveal adjacent Listen, Type, and Dismiss actions. Keep the expanded companion non-modal; it can be dismissed while ongoing thinking, action, or speech state continues in the persistent entry.
3. Use one reducer or state store as the source of truth. Keep `conversationState` independent from microphone permission, Mic on/off, capture, keyboard, and the `collapsed | quick-actions | expanded` surface state.
4. Route typed and transcribed input through the same input-received event. Keyboard is closed by default.
5. Drive progress from real service callbacks. The JSON timing values are for prototype pacing and visual expressions, not backend orchestration.
6. Require explicit confirmation before purchases, bookings, cancellations, or account changes.
7. Preserve committed external steps when interruption occurs. Mark only unstarted future steps as cancelled and ask what the user wants next.

## State flow

The common informational path is:

`ready → listening → acknowledged → thinking → speaking → ready`

A missing detail branches from `thinking` to the single canonical `clarification` state. Consequential actions branch to `awaiting-confirmation`, then `taking-action`, `speaking`, `completed`, and back to `ready`.

## Interaction rules

- First voice use requests microphone permission. Denial preserves typed input and bot-output capability.
- Mic off stops capture; it does not mean bot audio is off.
- Speaking can be interrupted by voice or tap.
- Taking action can only be interrupted by explicit tap.
- The rest of the District screen remains usable during every companion state.
- The draggable entry persists across app pages, stays clamped inside the visible screen, and re-clamps saved offsets after viewport changes; its final production eligibility rules are still open.

## Integration boundaries

The package does not contain real microphone capture, speech recognition, text-to-speech, model calls, navigation, app-action APIs, analytics, localization, or native accessibility announcements. Those require production platform ownership and should emit events into the contract rather than being embedded in the visual component.

## Validation checklist

- Informational request resolves and returns to Ready.
- Consequential action cannot start without confirmation.
- Permission denial offers keyboard and recovery paths.
- Keyboard remains closed until explicitly opened.
- Underlying app controls remain usable while the overlay is open.
- Voice interrupts Speaking but not Taking action; tap can interrupt both.
- Partial completion never claims committed work was undone.
- Collapse preserves session context and stops active capture.
- Reduced motion retains distinct readable state poses.
