# Command dashboard live read-only contract smoke

Use when a sensitive command dashboard moves from mock-only to the first real read-only domain adapter and the user asks to validate against a genuinely local backend, not just fake responses.

## Core pattern

1. Keep the adapter mode-gated: `mock` default, `live_readonly` explicit, `disabled` safe degraded fallback.
2. Discover the local backend start path from read-only project metadata first: README, pyproject/package scripts, editable install `.pth`, router files, runbooks, pid files. Avoid opening productive DBs, secrets, exports, raw reports, or backup folders.
3. Start only a local backend bound to `127.0.0.1`/`localhost`, preferably with an existing venv/runtime. Do not modify the domain repo unless explicitly approved.
4. Set live env only in the current shell/process, not in committed `.env`:
   - `FINANCE_ADAPTER_MODE=live_readonly` or equivalent domain mode
   - local `*_API_BASE_URL=http://127.0.0.1:<port>`
   - exact-value flags disabled
5. Before using the dashboard gateway, probe only the approved GET endpoints with a structural reader that records endpoint status, response category, key/type shapes, counts, and whether sensitive key classes exist. Do not persist raw JSON beyond ignored `.tmp/`; never commit raw responses or real values.
6. Run the live smoke through the dashboard gateway, not directly against the domain API only. Validate:
   - gateway starts with live_readonly active
   - registry/source health show live source type (`http_api` or equivalent)
   - overview/module snapshot validates against the existing contract
   - forbidden strings, amounts, account names, transactions, paths, secrets, and stack traces are absent
   - no POST/PUT/PATCH/DELETE calls are made
7. If real shapes differ from assumptions, harden the sanitizer with allowlist-only mapping and add synthetic fixtures that mimic structure without real values.
8. Document only a redacted structural contract review: reachable yes/no, HTTP status, response category, used fields, ignored classes, sensitive classes observed, MVP suitability. Never paste raw responses, exact values, paths, account names, transaction text, tokens, or hostnames beyond localhost examples.

## Sanitizer lessons

- Provider/status endpoints may return a list, not a dict. Aggregate only status-like flags to `yes/no/unknown`; do not copy provider names/messages.
- Runtime/status endpoints often contain path-like fields. Use only boolean/status flags; redact any error message path fragments before putting them into `SourceHealth`.
- Audit endpoints may contain many account/transaction/budget-like structural keys. Use only known safe counters (e.g. review-needed counts) and ignore all unknown nested fields.
- Unknown fields should be counted or ignored, never passed through. Dynamic keys from live responses should not become UI labels.

## Tests to add

- Realistic synthetic live-shape fixtures under the gateway tests directory.
- Dirty synthetic fixture containing amount/account/transaction/path/secret-like keys to prove removal.
- Contract mapping tests: realistic shape -> safe ModuleSnapshot; unknown fields ignored; dirty all-endpoint shape remains safe.
- Smoke contract tests: partial endpoint failure returns safe degraded/offline snapshot; dirty endpoint data still cannot leak.
- Safety scanner allowlist only for the sanitizer, dedicated dirty tests, and synthetic dirty fixtures — never a whole app/test directory.

## Cleanup and verification

- Remove ignored `.tmp`, build output, Playwright reports, and logs before commit.
- Stop any backend process the agent started.
- Run the fast verification suite plus live smoke while the local domain backend is still running.
- Commit only code, synthetic fixtures, and redacted mapping docs.
