Merge contract

15-question review gate

ShippedReview gate

The fleet questionnaire. Six questions are merge blockers. The rest need an explicit answer or N/A. Use it while you work, then again on the PR.

Merge blockers are Q1, Q2, Q6, Q8, Q9, Q14. Pre-commit questions can become ast-grep/CI. Review questions need judgment — unchecked means an explicit rationale or N/A, not silence.

Type & expression

  1. Q1

    Enums over magic strings

    merge blockerpre-commit

    Every string that is really a finite set (states, labels, error kinds, allowlists, lanes, list markers) is an enum with exhaustive switches; CaseIterable where tests should iterate.

  2. Q2

    Codable on the wire

    merge blockerpre-commit

    No hand-built JSON string literals in production code. Error frames, DTOs, and happy-path fixtures encode from types. Byte-equality where wire shape matters. macOS 26 JSONEncoder randomizes key order per-process — stable bytes need a canonical writer (Exhibit 13).

  3. Q3

    Smallest clear expression

    review

    Function vs computed property — honest about cost. Prefer switch over chained ifs; guard let for early exit, if let for local branch, for case let for filtered pattern-matching.

  4. Q4

    Protocol vs enum

    review

    Protocols only where implementations genuinely vary. Finite variation = enum, not a protocol hierarchy.

  5. Q5

    Functional Swift where it fits

    review

    map/compactMap/flatMap/reduce when the source is a collection and the transform is pure. Keep streaming loops when collecting would allocate, delay results, or hide side effects.

Concurrency & streams

  1. Q6

    Actors / Sendable

    merge blockerpre-commit

    Shared mutable state is actor-isolated or value-typed Sendable. Every @unchecked Sendable carries a written justification. Cross-boundary values conform to Sendable.

  2. Q7

    Smallest honest lifetime model

    review

    Value, one-shot async function, or AsyncSequence? Choose the smallest model that represents the real lifetime. Combine only at real publisher boundaries.

Observability & security

  1. Q8

    Emoji telemetry at every decision point

    merge blockerpre-commit

    Each meaningful branch emits a typed event with a glyph through one enum surface. A new decision point without an event fails the gate.

  2. Q9

    Secrets & data posture

    merge blockerpre-commit

    No ambient environment inheritance. Auth before privileged side effects. No PII in logs. Brokered secrets, never embedded. App Control /state never dumps Keychain.

UI

  1. Q10

    Xcode Previews

    review

    Every new UI state covered: loading / empty / error / long content / Dynamic Type / dark mode. Preview-parity suites where the repo has them.

  2. Q11

    Snapshot tests

    review

    Layout/rendering regressions that matter have snapshots — baselines are CI-recorded, never studio-recorded. A green suite against a void baseline proves nothing (Exhibit 7).

  3. Q12

    Interaction feedback

    review

    Intentional haptics for meaningful taps; a11y labels; identifiers for control vs labels for humans. No fake live states.

Quality

  1. Q13

    Performance

    review

    Hot path allocation-conscious. No sync work on the main/timeline thread. No accidental O(n²).

  2. Q14

    Exhaustive proof

    merge blockerpre-commit

    CaseIterable drives tests. Behavioral changes carry a rendered sequence/flow diagram; UI changes carry a snapshot gallery. E2E paths proven by running them — receipts posted, not vibes.

  3. Q15

    Better shape?

    review

    Is there a simpler API — fewer types, less indirection — that still keeps Q1–Q14? If not, say why in the PR.