# Interaction registry — the affordance-closure board

> **This is a generic template.** It hard-codes no project values. Claude (the orchestrator) populates it by following the project `CLAUDE.md`, the `interaction-auditor` agent's Ledger, and the build sweep. Rebind every `<…>` placeholder per project.
>
> The **as-built reconciliation of every interactive affordance** on the finished screens — buttons, links, click-to-actions, keyboard shortcuts, form submits. Produced by the **`interaction-auditor`** agent, ruled and written here by the orchestrator (single writer). It makes the `functional fidelity` continuity invariant enforceable at **screen** scope (every affordance has a disposition), not just **path** scope (what a sweep happened to wire).
>
> **Why this exists:** the unit of build is a workflow (a path); the unit of doneness is a screen (all its affordances). A sweep wires its path and leaves a screen's other affordances untouched; reconstruction builds screens visual-only. Those off-path / reconstruction affordances become silent stubs that pass every per-path gate. This board is where they stop being invisible.
>
> **Companions:** `SCREEN_REGISTRY.md` (the lifecycle ledger) · `WORKFLOW_REGISTRY.md` (the workflow-sweep board) · `PROGRESS.md` (the dated activity log). Governing law: `CONSTITUTION.md` (§6 affordance closure · §9 wiring gate + Definition of Done).

## Generation contract — how Claude fills this in

Claude is the orchestrator (single writer) for this file. Maintain it as follows; **take every project-specific value from the sources named, never invent it:**

- **Single-writer rule (Law 3):** ONLY the orchestrator edits this file. The `interaction-auditor` returns an Interaction Ledger as a structured report; the orchestrator **rules** each row's remediation channel and writes the ruled rows here. Subagents never touch this board.
- **Scope order (Law-3 cadence):** audit each **finished workflow** at its interaction-closure step first — one `### Workflow — <name>` section per sweep; then run the **standalone whole-UI** sweep to inventory the reconstruction-era backlog (the final section).
- **Rows:** emit one row per affordance the auditor found. Record `Wired` / `Marked-stub` rows for coverage, but **the worklist is the gaps** — only gaps need an owner + action. Cite `file:line` for every handler/selector, per the project's UI conventions in `CLAUDE.md`.
- **Risk → channel:** the orchestrator routes `low + trivial + non-compliance` rows to **auto-remediation** and **asks the human** on `med` / `high` rows (compliance surface per `CLAUDE.md`). Record the ruling per row; never decide a `med`/`high` row silently.
- **Coverage line:** for each scope, state `<affordances found> = <wired> + <marked-stub> + <gaps>` so truncation can never hide behind "looks done". If you cap a sweep's scope, say what you deferred (Law 11 — no silent truncation).

## Legend

**Disposition** (exactly one per affordance):
- `Wired` ✅ — dispatches a command/query, or navigates-with-context to a real destination (mutating → write-path round-trip proven).
- `Marked stub` ✅ — visible "preview · not saved" / disabled-with-inline-reason. Honest deferral.
- `Unmarked stub` ❌ — toasts / no-ops while implying a real effect. **Wire it or mark it.**
- `Mis-wired` ❌ — opens a singleton/wrong record, a dead route, or a guarded action silently allowed.
- `Dead-end` ❌ — terminal state with no advancing CTA, or destination doesn't exist.
- `Design-gap` ❌ — affordance exists but its target interaction is undesigned (needs design before wiring).

**Risk → remediation channel:**
- `low` + trivial + non-compliance → **auto-remediate** (orchestrator routes straight to the builder).
- `med` / `high` → **ask the human** (interactively, or an `APPROVAL_INBOX` entry with options).

**Status:** `☐` open · `◐` in progress · `✅` closed (wired or marked) · `⏸` deferred (ticketed, intentional) · `❓` awaiting human decision.

**Columns:** `Affordance · Handler/Selector · Disposition · Risk · Owner · Action / options · Status`

---

## Scopes

<!-- Each finished workflow gets a `### Workflow — <name>` section; the standalone whole-UI sweep is the final section.
     The orchestrator appends rows from the interaction-auditor's Ledger after ruling risk. -->

### Workflow — `<workflow name>` · audited `<date>`

Screens: `<screen files>`. **Coverage: `<N>` affordances = `<wired>` wired + `<marked>` marked-stub + `<gaps>` gaps.** Only gaps are rowed below (wired/marked recorded for coverage). Handler-feedback toasts inside wired Save handlers are **not** stubs.

| Affordance | Handler:line | Disposition | Risk | Owner | Action / options | Status |
|---|---|---|---|---|---|---|
| `<label>` | `<file:line>` | `<disposition>` | `<low \| med \| high>` | `<owning agent>` | `<recommended action — or 2–4 options for an ask row>` | `<☐ \| ◐ \| ✅ \| ⏸ \| ❓>` |
| _… one row per gap …_ | | | | | | |

> **Repeat one `###` section per finished workflow** audited at its interaction-closure step.

### Standalone — whole built UI

_Run after the finished-workflow audits, per the scope order above. Same columns; inventories the reconstruction-era affordance debt across the whole built UI surface._

## § Accepted toasts — the fire-and-forget exceptions ledger (dead-edge-audit skill)

> Toast-only handlers that are HONEST simulations of out-of-scope side effects ("email sent", "paged on-call"), accepted by an explicit human product decision during a dead-edge audit (`/edge-audit`) or an interaction sweep. Rows here are **verified, never re-litigated** by later audits — and a row whose justification no longer holds IS a finding. Each accepted toast must also be declared in its screen's contract sidecar (`effect: "notify-sim"`); prototype-side acceptances reconstruct as Marked-stub / declared notify on the built side, never resurfacing as Unmarked-stub.
>
> Single writer: the orchestrator (via `/edge-audit` step 5 or the interaction-closure gate).

| Screen | Element | Side (prototype/built) | Justification (one line) | Sidecar `notify-sim` ✓ | Accepted by | Date |
|---|---|---|---|---|---|---|
| | | | | | | |
