Clean successor to V3 (forge: lilith/atlilith). Seeded from local Mac working tree at ~/Code/@projects/@cocottetech/. node_modules and build artifacts excluded via .gitignore. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6.4 KiB
6.4 KiB
tryst-verification.screen
Tryst Sumsub KYC re-up + verification status dashboard. Implements surface-tryst.brief.md §6. Sensitive — deadname risk handling is central. Reached from a Tryst-flagged re-verify approval card or from settings → Safety → Verifications. Voice: plain.
Layout (full-screen sheet)
┌─────────────────────────────────────────────────┐
│ ◄ Back Verification │ 56pt
├─────────────────────────────────────────────────┤
│ │
│ ─── Status ─── │
│ Verified ✓ — expires 2027-03-04 │
│ Last verified: 2026-03-04 │
│ Method: Sumsub (govt ID + selfie + liveness) │
│ │
│ ─── If you need to re-verify ─── │
│ Tryst will prompt automatically when needed. │
│ Cocotte will surface it here when that happens. │
│ [ Start re-verification → ] │ manual trigger if needed
│ │
│ ─── About your records ─── │ privacy section
│ Tryst stores: govt ID image + face scan + │
│ liveness check + expiration date. │
│ Cocotte stores: verification status + expires │
│ date. **NOT** the ID image or your gov-name. │
│ Sumsub stores: per their privacy policy. │
│ │
│ ─── Deadname / gov-name handling ─── │
│ Your gov-name from your ID is **never** shown │
│ to clients on Tryst. Tryst's compliance team │
│ sees it; Cocotte never logs it visibly; no │
│ agent reads it. │
│ [ Read the full policy → ] │
│ │
└─────────────────────────────────────────────────┘
Status states
- Verified, healthy (>30d to expire) — green status.
- Expiring soon (≤30d) — amber; copy: "Re-verify within {N} days to keep your listing live."
- Expiring this week (≤7d) — pulses amber + nudge banner.
- Expired — red status + high-stakes interrupt: "Verification expired. Your listing is hidden on Tryst. Re-verify to recover."
- In progress (Quinn started re-verify on Sumsub but hasn't completed) — chip: "Awaiting Sumsub. Open the email Sumsub sent."
- Failed (Sumsub rejected ID / face / liveness) — banner with reason + retry route.
- Cocotte has stale data (lost connection per brief M) — chip: "Status may be stale; last refreshed {time}. [Refresh]"
- Re-verify started but Quinn abandoned — Sumsub session times out; chip: "Last attempt timed out. Start again?"
- VoiceOver — status block read first; privacy section explicitly announced.
Privacy mechanics (this screen is the disclosure point)
The screen exists to make the privacy boundary visible:
- Cocotte never stores Quinn's ID image or gov-name.
- Cocotte never displays gov-name to any specialist, log, or audit row.
- Tryst's compliance team sees gov-name per their policy.
- Quinn can read the full policy via the link; it lives at cocotte.io/privacy/verification.
- Deadname risk: Quinn's gov-name on the ID may differ from her display name. Cocotte's job is to keep the gov-name compartmentalized — used for Tryst's verify, never elsewhere.
Interactions
- Tap "Start re-verification" → opens an in-app browser to Sumsub's flow (Quinn does the ID + selfie + liveness step there); Cocotte detects completion via webhook and updates the status.
- Tap "Read the full policy" → routes to in-app privacy page (cocotte.io/privacy/verification rendered in-app).
- Long-press status block → "View audit trail of past verifications" (recent N audit rows of
action_type='verify_status_check').
Edge cases
- Quinn previously verified on Tryst before connecting to Cocotte — status pulled from Tryst on connect; chip: "Verified pre-Cocotte; first-fetched from Tryst on {date}."
- Sumsub flags the ID (suspected fake) — Cocotte surfaces neutrally: "Sumsub couldn't verify. Tryst's compliance will contact you." No accusatory tone.
- Multiple verifications in past 12 months (Quinn re-verified for non-renewal reasons) — audit shows the full history.
- iCloud / system-keychain prompts for ID image during Sumsub flow — out-of-Cocotte; Cocotte doesn't see it.
- Quinn declines to re-verify — Cocotte respects: status stays "expiring"; listing eventually hides; Cocotte never coerces.
Generalization callout
KYC re-up screens differ per surface:
- TS4Rent: same Sumsub vendor — screen reuses ~100% with surface-name swap.
- Slixa: different vendor (Stripe Identity? to be confirmed) — same shape, different "method" field.
- OnlyFans: their own verify system — screen pattern reuses; backend integration differs.
- X / Instagram: not applicable.
The privacy-disclosure block + status states + re-verify flow generalize fully; the vendor name + method specifics vary.
Related
- surface-tryst.brief.md §6 — parent.
- specialist-bookings-tryst.contract.md — Never section: "never surfaces gov-name."
- Brief K — deadname / real-name handling.
- Brief V — verification records as exportable / erasable data.
- Brief I — every status fetch + re-verify = audit row.
- Brief M §M3a — expired-verify is a high-stakes failure.
voice.md§V2c — plain register throughout.
Out of scope
- Sumsub's flow interior (it's a 3rd-party in-app web flow).
- Privacy-policy text (linked, not duplicated).
- Multi-jurisdiction verification (Quinn's gov-ID is one country; multi-country verify is a defer-to-later concern).