# Agent brief: Keep SwiftUI thin: it only feeds the model

- **Lesson id:** 04-swiftui-as-thin-client
- **Goal:** Reframe PhotosPicker and preprocessing as a producer of the runtime tensor contract, not as the model.
- **Prerequisites:** Complete 03; know the original SwiftUI clothing app.
- **Inputs:** Picked or bundled image, `image` tensor contract, ten-class Fashion-MNIST label order.
- **Outputs/artifacts:** HTML diagrams from photo to tensor to logits to label; contract violation examples.
- **Concrete steps:**
  1. Show PhotosPicker, 28 by 28 grayscale preprocessing, float32 NCHW 0 to 1 data, and inference.
  2. List wrong channels, shape, range, layout, and lifecycle as contract breaks.
  3. Explain logits, argmax or softmax for display, and fixed class order.
  4. Recommend a known bundled sample for debugging.
  5. Link original app and conversion lessons.
- **Constraints:** Exact input is `[1,1,28,28]` float32; ten labels; no CUDA, Mermaid, quizzes, or em dashes.
- **Acceptance checks:** UI is explicitly thin, every listed mistake maps to a contract, the flow is HTML, and the human page links its brief.
- **Human lesson:** [04-swiftui-as-thin-client.html](04-swiftui-as-thin-client.html)

## Key concepts

- SwiftUI is a thin client. PhotosPicker and preprocessing exist to meet the tensor contract.
- The path is photo to 28x28 grayscale to float32 NCHW 0-1 to `image` to `logits`.
- Wrong channels, 0-255 bytes, or infer before prepare are contract breaks.
- The ten logits become names only through the fixed Fashion-MNIST order.

## Takeaways

- UI bugs that change the tensor are runtime contract breaks, not model bugs.
- Keep a known bundled sample to test preprocessing before you change the view.
- Thin UI means you can isolate prep and the runtime call from layout code.
