# Phase 20.5: Modal State Architectural Audit — Context

**Gathered:** 2026-04-16
**Status:** Ready for planning

<domain>
## Phase Boundary

Inventory every modal and overlay component in the app, document every callback in/out, identify every place modal state is read or mutated, and produce a canonical state diagram in `.planning/MODAL-STATE.md`. This is a documentation-only audit — no code changes, no bug fixes, no feature additions.

</domain>

<decisions>
## Implementation Decisions

### Audit Scope
- **D-01:** Audit covers ALL overlay components with open/close state, not just PopupWindow-based modals. This includes: lookup-modal, state-transition-modal, settings-modal, add-product-form, recipient-detail sidebar, and product-detail sidecar. The sidebar/sidecar have state machines that interact with modals (e.g., Esc handler priority, focus management).

### Documentation Format
- **D-02:** State diagrams use Mermaid `stateDiagram-v2` syntax — already established in the MODAL-STATE.md placeholder, renderable in GitHub/VS Code, machine-parseable.
- **D-03:** Callback inventory uses structured markdown tables with columns: Callback Name | Direction (in/out) | Source File | Handler File | Side Effects.

### Callback Documentation Depth
- **D-04:** Document full callback chains end-to-end (e.g., `card.slint callback` → `dashboard.slint forwarding` → `main.rs handler` → SQLite write / sync trigger / UI update). The fragility comes from incomplete chain understanding — half-traced chains are why modals break.

### Fragile Pattern Documentation
- **D-05:** Known fragile patterns documented inline within each modal's section, with cross-references to RETRO-AGENT-FAILURE-PATTERNS.md section IDs (e.g., C-3, B-1). Warning placed where someone editing that modal will see it.

### Claude's Discretion
- Internal organization of MODAL-STATE.md sections (grouping by modal vs. by concern)
- Level of detail in Mermaid diagrams (simple vs. nested states)
- Whether to include a summary "interaction map" showing how modals interact with each other

</decisions>

<canonical_refs>
## Canonical References

**Downstream agents MUST read these before planning or implementing.**

### Modal Architecture
- `.planning/MODAL-STATE.md` — Current placeholder to be replaced with audit output
- `.planning/RETRO-AGENT-FAILURE-PATTERNS.md` — Source of M-4 mitigation; documents 71% modal fragility finding, failure taxonomy (F1-F6), and concrete parallel-path-drift commits

### Code Tips
- `code_tips/SLINT_TIPS.md` — Slint-specific gotchas (B-1 through B-7 patterns)
- `code_tips/CALLBACK_PIPELINE.md` — Callback invariants (INV-1/INV-2/INV-3) with full callsite inventory

### Data Flow
- `.planning/DATA-FLOW.md` — Data architecture rules; relevant for understanding which modal callbacks trigger data writes

### Modal Source Files (Slint)
- `crates/app/ui/lookup-modal.slint` — Lookup modal component
- `crates/app/ui/state-transition-modal.slint` — State transition modal
- `crates/app/ui/settings-modal.slint` — Settings modal
- `crates/app/ui/add-product-form.slint` — Add product form modal
- `crates/app/ui/recipient-detail.slint` — Recipient detail sidebar (overlay with state)
- `crates/app/ui/product-detail.slint` — Product detail sidecar (overlay with state)
- `crates/app/ui/dashboard.slint` — Dashboard (forwards modal callbacks, owns visibility flags)
- `crates/app/ui/card.slint` — Card component (triggers modal opens)

### Modal Handler Files (Rust)
- `crates/app/src/main.rs` — Primary callback wiring site
- `crates/app/src/live_client.rs` — Data operations triggered by modal callbacks

</canonical_refs>

<code_context>
## Existing Code Insights

### Reusable Assets
- MODAL-STATE.md placeholder already exists with the table structure and Mermaid template
- RETRO-AGENT-FAILURE-PATTERNS.md has a comprehensive catalog of modal-related failure patterns with commit SHAs
- CALLBACK_PIPELINE.md has callsite inventory (INV-1/INV-2/INV-3) that partially overlaps with modal callback chains

### Established Patterns
- Modal visibility controlled by boolean properties in dashboard.slint (e.g., `show-lookup-modal`, `show-settings`)
- Callbacks forwarded through component hierarchy: card.slint → dashboard.slint → main.rs
- Esc handler priority: inline-edit cancel → modal dismiss → global navigation (established in Phase 20.1.1)
- Modal state reset required in both modal component AND parent dashboard (bac9584 lesson)

### Integration Points
- This audit produces MODAL-STATE.md which becomes a mandatory-read checkpoint per CLAUDE.md
- Subsequent modal changes must update MODAL-STATE.md in the same commit (enforcement rule already in CLAUDE.md)
- BUGSWEEPER can verify modal state programmatically via `/api/ui/property/` and `/api/ui/callback/` endpoints

</code_context>

<specifics>
## Specific Ideas

- The audit should capture the Esc handler priority chain explicitly — this is the #1 source of modal bugs (C-3, D-4 in retro)
- Include the "modal close drops focus; global key handler dies" pattern (C-3) as a documented hazard in each modal's section
- Cross-reference specific commits where parallel-path drift manifested in modals (bac9584, dc622640, af4c8b8)

</specifics>

<deferred>
## Deferred Ideas

None — discussion stayed within phase scope.

### Reviewed Todos (not folded)
- "Unify Shopify and Discord token section styling in settings modal" — UI change, not audit scope; settings modal will be documented by this audit
- "Centralized modular search modal with shared UX patterns" — new feature, not audit scope; audit findings may inform this future phase
- "Unit assignment not reflected in lookup modal or product detail sidecar" — bug fix, not audit scope
- "Lookup modal — new options for assigned serial unit" — feature addition, not audit scope
- "Creating product from lookup modal does not create ww-product GH Issue" — bug fix, not audit scope
- "State change unassigns unit from card even without unassign checkbox" — bug fix touching state-transition modal, not audit scope

</deferred>

---

*Phase: 20.5-modal-state-architectural-audit-inserted*
*Context gathered: 2026-04-16*
