cocottetech/@platform/codebase/@features/ai-copilot/docs/tryst-verification.screen.md
natalie 1b719e1fd7 chore(bootstrap): initial V4 commit
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>
2026-05-18 08:11:41 -07:00

100 lines
6.4 KiB
Markdown

# tryst-verification.screen
Tryst Sumsub KYC re-up + verification status dashboard. Implements [surface-tryst.brief.md §6](./surface-tryst.brief.md). **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
1. **Verified, healthy** (>30d to expire) — green status.
2. **Expiring soon** (≤30d) — amber; copy: "Re-verify within {N} days to keep your listing live."
3. **Expiring this week** (≤7d) — pulses amber + nudge banner.
4. **Expired** — red status + high-stakes interrupt: "Verification expired. Your listing is hidden on Tryst. Re-verify to recover."
5. **In progress** (Quinn started re-verify on Sumsub but hasn't completed) — chip: "Awaiting Sumsub. Open the email Sumsub sent."
6. **Failed** (Sumsub rejected ID / face / liveness) — banner with reason + retry route.
7. **Cocotte has stale data** (lost connection per brief M) — chip: "Status may be stale; last refreshed {time}. [Refresh]"
8. **Re-verify started but Quinn abandoned** — Sumsub session times out; chip: "Last attempt timed out. Start again?"
9. **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](./surface-tryst.brief.md) — parent.
- [specialist-bookings-tryst.contract.md](./specialist-bookings-tryst.contract.md) — Never section: "never surfaces gov-name."
- [Brief K](./K-safety-blocklist.brief.md) — deadname / real-name handling.
- [Brief V](./V-data-portability-erasure.brief.md) — verification records as exportable / erasable data.
- [Brief I](./I-audit-trust-replay.brief.md) — every status fetch + re-verify = audit row.
- [Brief M §M3a](./M-error-degraded-modes.brief.md) — expired-verify is a high-stakes failure.
- [`voice.md` §V2c](./00-system-voice.md) — 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).