Files
pbakaus_impeccable/skill/reference/ios.md
T
Paul BakausandGitHub 19786e7a22 Native leg for the verify-and-review pipeline (#546)
* Give the verify-and-review pipeline a native leg

The build-verify-review loop assumed a browser end to end while the
comp side of the system was already platform-aware: new-work.md,
visualize.md, and the asset producer all comp a native app portrait at
its device viewport, and then the verification steps asked for desktop
and mobile browser screenshots of it. Concretely:

- new-work.md step 7 ordered detect.mjs on every hookless build with no
  platform guard. routing.md declares the detector web-only and the
  design hook skips native projects, so a native build was always
  hookless and always ordered to run an HTML rule engine over
  Swift/Kotlin/RN code. The playbook now guards it: web-only, and on
  native the reviewer's floor check is the named slop gate.
- The inspection round and the SKILL.src.md batched-round principle
  named desktop and mobile as the only viewports. Both now map per
  platform: web keeps desktop and mobile; native inspects the shipped
  device classes per OS, captured from the simulator or emulator.
- ios.md and android.md carried no verification guidance at all, so
  nothing told a native run how to produce the screenshots the evidence
  chain depends on. Each gains a Verifying the build section: simctl /
  adb capture commands, dark-appearance and type-scale checks, and the
  simulator-vs-hardware honesty line.
- The finish reviewer judged native builds blind: it never runs
  context.mjs and its packet carried no platform guidance. On native
  the packet now includes the platform reference path(s) and a
  no-detector-ran line, and the reviewer's Input Contract says to judge
  in the platform's conventions.

Assisted-by: Claude Code

* fix: address PR review bot findings

- greptile: carry the capture's device selector through the
  state-changing verification commands (simctl appearance, adb uimode
  and font_scale); unqualified forms fail with several targets attached
- Copilot: align new-work.md's cross-reference with the actual heading
  (Verifying the build)
- Copilot: give the finish reviewer's Input Contract the native
  filename example new-work.md establishes (phone.png / tablet.png,
  suffixed per OS on adaptive)

Assisted-by: Claude Code

* fix: identify simulators by UDID, not display name

greptile follow-up: display names can collide across booted simulators,
so the capture and appearance commands now both key on the UDID from
simctl list devices booted.

Assisted-by: Claude Code
2026-08-09 15:09:55 -07:00

52 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# iOS platform
For native iOS / iPadOS apps: SwiftUI, UIKit, React Native, Expo, Flutter shipping to Apple hardware.
On native, the visitor mode narrows what expression may override. HIG conformance governs structure, navigation, and interaction in every mode; brand expresses through the layer the platform leaves open (tint, type, motion, content).
## The iOS slop test
Would a fluent iPhone user trust this app, or pause at off-spec controls? The tell is "ported from a website": reinvented navigation bars, custom back gestures, web-shaped buttons, hover-dependent affordances. Default to the platform's components; depart only for a reason the user would thank you for.
## Layout & structure
- **Safe area.** Lay out inside the safe-area insets. No controls under the notch, Dynamic Island, home indicator, or rounded corners. <!-- rule:ios-layout-safe-area -->
- **System navigation.** Tab bar for 25 top-level sections (sections, never actions), navigation stack for hierarchy, sheet for self-contained tasks. No custom global nav, no mixed metaphors. <!-- rule:ios-layout-standard-navigation -->
- **Edge-swipe back stays alive.** The left-edge back gesture is muscle memory; never disable or overlay it. <!-- rule:ios-layout-edge-swipe-back -->
- **Large titles** on top-level screens, collapsing to inline on scroll. Deep detail screens stay inline. <!-- rule:ios-layout-large-titles -->
## Touch targets
- **44×44 pt minimum** for every tappable control, with breathing room between adjacent targets. <!-- rule:ios-touch-target-44pt -->
## Typography
- **Dynamic Type.** Use the system text styles (Large Title through Caption) so text follows the user's reading size. No hard-coded point sizes. <!-- rule:ios-typo-dynamic-type -->
- **San Francisco carries the UI.** Body, labels, and controls stay on SF Pro / SF Compact; a brand face may appear in display moments. <!-- rule:ios-typo-system-font -->
- **11 pt floor**; Body is 17 pt. <!-- rule:ios-typo-minimum-size -->
## Color & materials
- **Semantic system colors** (label, secondaryLabel, systemBackground, separator, tint). They adapt to Dark Mode and increased contrast automatically; raw hex breaks there. <!-- rule:ios-color-semantic-system -->
- **Dark Mode is a first-class appearance.** Design and test both. <!-- rule:ios-color-dark-mode -->
- **One tint color** drives interactive elements; decoration is not its job. <!-- rule:ios-color-single-tint -->
- **System materials** for blur and translucency behind bars and sheets; no hand-rolled glassmorphism. <!-- rule:ios-color-system-materials -->
## Components & controls
- **Platform controls.** Switch, segmented control, stepper, system pickers, action sheets, alerts, context menus, swipe actions. Reinventing these for flavor is the most common native slop. <!-- rule:ios-components-native-controls -->
- **SF Symbols** for iconography: baseline-aligned, Dynamic Type-aware, weight and scale variants. Don't mix in a web icon set. <!-- rule:ios-components-sf-symbols -->
- **Deliberate modality.** Sheet for a focused dismissible sub-task, full-screen cover for immersion. Clear Cancel/Done; honor swipe-to-dismiss unless data loss requires a guard. <!-- rule:ios-components-modality -->
- **Grouped/inset lists** for settings-shaped content; no bespoke card stacks. <!-- rule:ios-components-grouped-lists -->
## Motion
- **System transitions.** Push slides, sheets rise, dismiss reverses the entrance. Custom transitions that fight the navigation model disorient. <!-- rule:ios-motion-system-transitions -->
- **Honor Reduce Motion.** Crossfade instead of parallax and large slides. <!-- rule:ios-motion-reduce-motion -->
## Verifying the build
- **Screenshots come from the Simulator, never a browser.** Build and run, then capture with `xcrun simctl io booted screenshot <path>` (with several running, replace `booted` with the target's UDID from `xcrun simctl list devices booted`; display names can collide, the UDID never does). Capture every device class the app ships to, at least one iPhone and, when iPad is a target, one iPad, and write the files where the review flow expects them. <!-- rule:ios-verify-simulator-capture -->
- **Dark Mode and Dynamic Type belong in the pass.** `xcrun simctl ui booted appearance dark` flips appearance, reusing the capture's UDID when several are booted; a check at a large Dynamic Type size catches the truncation a fixed layout hides. <!-- rule:ios-verify-appearance-and-type -->
- **Simulators give breadth; posture, gestures, and performance need hardware.** Say which one produced the evidence. <!-- rule:ios-verify-hardware-honesty -->