cocottetech/@platform/codebase/@features/ai-copilot/docs/multi-surface-fanout.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

14 KiB
Raw Blame History

multi-surface-fanout.screen

The fan-out approval centerpiece — one decision, N adapter dispatches across the 24-surface roster (brief O). Pairs with brief H §H4 (multi-surface card pattern) and §H5 (density: H5a accordion · H5b compact · H5c anchor-and-rest · H5d cross-cutting rules · H5e split-card). Voice register: working (00-system-voice.md §V2b); plain on failures and high-stakes elevation. Sibling to approval-card.screen.md (single-surface). Where the single-surface card is one diff, one approve, this is one diff, many surfaces, one approve — and at Quinn's actual roster size, density is the design.

Layout

Four variants rendered below. Picker is automatic per H5 thresholds, never Quinn-toggleable. Approve button stays pinned to card bottom in every variant; internal scroll only inside the body.

Flat (≤5 surfaces) — full ASCII card

┌─────────────────────────────────────────────────┐
│ ┃ ▢ Update about-me on 4 surfaces       ⋯ menu │
│ ┃ [profile-copy] · medium · 0.81              │
│ ┃                                              │
│ ┃ ◉ [Tryst]      "Independent escort…"   142c │
│ ┃ ◉ [TS4Rent]    "Independent escort,…"  138c │
│ ┃ ◉ [Slixa]      "SF-based independent…" 165c │
│ ┃ ◉ [tqftw.com]  "Independent escort…"   320c │
│ ┃                                              │
│ ┃ Why: dropping "corporate" everywhere.        │
│ ┃                                              │
│ ┃ [ Edit ] [ Set aside ] [ Approve 4 ]        │
└─────────────────────────────────────────────────┘

Accordion (612 surfaces) — H5a, grouped by O categories

Collapsed-default state when total > 8:

┌─────────────────────────────────────────────────┐
│ ┃ ▢ Update about-me on 10 surfaces       ⋯    │
│ ┃ [profile-copy] · medium · 0.78              │
│ ┃                                              │
│ ┃ Escort directories · 8         [6/8 ▾]      │
│ ┃ Brand sites · 2                [2/2 ▴]      │
│ ┃   ◉ [tqftw.com]   "Independent escort…"     │
│ ┃   ◉ [a.t.t.com]   "Tour-focused…"           │
│ ┃                                              │
│ ┃ Why: dropping "corporate" everywhere.        │
│ ┃                                              │
│ ┃ [ Edit ] [ Set aside ] [ Approve 8 ]        │
└─────────────────────────────────────────────────┘

Expanded state of directories group (H5a per-group bulk toggle visible):

│ ┃ Escort directories · 8         [6/8 ▴]      │
│ ┃   All on · All off · Custom                 │
│ ┃   ◉ [Tryst]        "Independent escort…"   │
│ ┃   ◉ [TS4Rent]      "Independent escort,…"  │
│ ┃   ◉ [Slixa]        "SF-based indep…"       │
│ ┃   ◉ [PD]           "Indep. companion…"     │
│ ┃   ◉ [Seeking]      "Independent comp…"     │
│ ┃   ◉ [TSEscorts]    "Indep. SF escort…"     │
│ ┃   ○ [Eros]         (blocked — name change) │
│ ┃   ○ [AdultSearch]  "Indep. SF escort…"     │

Compact rows (≥8 in one group) — H5b, one-line-per-surface

When the directories group alone has ≥8 (the canonical N2 case from brief O):

│ ┃ Escort directories · 12        [10/12 ▴]   │
│ ┃   filter surfaces…                          │
│ ┃   ◉ [Tryst]        · 142c · ✓              │
│ ┃   ◉ [TS4Rent]      · 138c · ✓              │
│ ┃   ◉ [Slixa]        · 165c · ✓              │
│ ┃   ◉ [PD]           · 144c · ✓              │
│ ┃   ◉ [Seeking]      · 220c · ⓘ longer       │
│ ┃   ◉ [TSEscorts]    · 158c · ✓              │
│ ┃   ◉ [AdultSearch]  · 410c · ✓              │
│ ┃   ◉ [AdultLook]    · 488c · ⓘ near cap     │
│ ┃   ◉ [EroticMonkey] · 142c · ✓              │
│ ┃   ◉ [SkipTheGames] · 144c · ✓              │
│ ┃   ○ [Eros]         · blocked               │
│ ┃   ○ [MegaPers]     · not started           │

Tap a row → that row expands inline (others collapse) to show full preview + inline edit. One row expanded at a time.

Anchor-and-rest (tours per H5c)

┌─────────────────────────────────────────────────┐
│ ┃ ▢ Add Berlin tour · Oct 37            ⋯    │
│ ┃ [tour] · medium · 0.84                      │
│ ┃                                              │
│ ┃ Anchors                          [3/3]      │
│ ┃   ◉ [Tryst]      "in Berlin Oct 37"       │
│ ┃   ◉ [TS4Rent]    "Berlin · Oct 37"        │
│ ┃   ◉ [tqftw.com]  "tour: Berlin · Oct"      │
│ ┃                                              │
│ ┃ Other directories · 9            [7/9 ▾]   │
│ ┃ Brand sites · 1                  [1/1 ▾]   │
│ ┃                                              │
│ ┃ Why: anchors always expanded; rest curated. │
│ ┃                                              │
│ ┃ [ Edit ] [ Set aside ] [ Approve 11 ]      │
└─────────────────────────────────────────────────┘

Anchors never collapse. Rest stays collapsed until Quinn taps to curate.

Components

Component Notes
Stakes color band 4pt left edge per 00-system-visual-system.md §F1. Aggregate band; escalates per H5d if any row is high-stakes standalone.
Header Verb + N-surfaces count + ⋯ menu (see-full-reasoning · talk-to-{specialist} · split-this-card · report).
Chip row Action-kind chip (profile-copy / tour / availability-policy) · stakes label · aggregate confidence (enabled rows only, per H5d).
Group header Category label + count + aggregate state glyph (✓ N · ⓘ M · ⚠ K · ○ blocked) + per-group bulk-toggle (All on / All off / Custom) + caret.
Surface row (full) Surface chip (F5 iconography) · per-surface preview · checkbox · char count vs cap.
Surface row (compact, H5b) Single line: [chip] name · Nc · status-glyph. Tap-to-expand.
Filter input Appears above accordion when total ≥ 12 (H5d). Filters across groups; never hides approve.
"Why" line Aggregate rationale; tap expands per-surface rationales stacked.
Action bar Edit · Set aside · Approve N. Pinned bottom safe-area. Approve label always shows enabled-row count.
Split connector When H5e applies, a hairline + caption ties two stacked cards together.

States

Flat

Default for ≤5 surfaces. All rows visible, no accordion chrome. Approve enabled when ≥1 row checked.

Accordion-collapsed

Default for >8 total. Group headers visible; bodies hidden. Per-group counts let Quinn approve without expanding ("6/8 looks right · approve"). Caret ▾ on collapsed, ▴ on expanded.

Accordion-expanded (single group)

Tapping a group caret expands that group only; siblings stay in their current state. Bulk-toggle row appears at top of expanded body. Internal scroll bound to body, not card.

Compact-row-expanded

H5b only. Tapping a compact row expands it inline to a full row (preview + char cap visualization + inline-edit affordance). Tapping another compact row collapses the prior — one-at-a-time.

Search-filtered

H5d. Filter input typed; non-matching rows hide; group counts update to (matching / total). Approve count reflects all enabled rows including hidden — clear caption: "Approve 10 (3 hidden by filter)".

Split-card (H5e + K3i)

When the specialist splits at draft time, two stacked cards appear in chat with a connector:

┌─ routine ───────────────────────────────────┐
│ ▢ Update about-me on 8 surfaces             │
│   [ Edit ] [ Set aside ] [ Approve 8 ]     │
└─────────────────────────────────────────────┘
       │  These 8 go together
       │  This 1 wants your eyes
┌─ brand-sensitive ───────────────────────────┐
│ ▢ Update about-me on tqftw.com              │
│   (single-surface diff card — H2 shape)     │
│   [ Edit ] [ Set aside ] [ Approve ]       │
└─────────────────────────────────────────────┘

The split is the specialist's call (brief H5e), surfaced to Quinn as one visual unit.

Dispatch-in-progress (per-row)

Approve tapped → action bar replaced by a progress strip ("Pushing to 10 surfaces · 4 done"). Each enabled row shows its own state: spinner → ✓ or ✗. Failed rows stay in card; succeeded rows fade slightly. Card cannot be dismissed mid-dispatch.

Post-dispatch with 2/8 failed

After all rows resolve, card transforms into a receipt with a per-group failure banner per H5d (one banner per group with failures, not per row):

│ ┃ ✓ 8 surfaces updated · 2 failed             │
│ ┃ Escort directories · 6 of 8        ⚠       │
│ ┃   2 failed — tap to retry                   │
│ ┃ Brand sites · 2 of 2                ✓      │
│ ┃                                              │
│ ┃ [ Retry 2 ] [ See details ] [ Dismiss ]    │

Tap retry → just the failed rows re-dispatch; tap details → row-by-row in audit drawer (brief I).

Stakes-escalated (all-high)

Per H5d, any single row at high stakes elevates the whole card. Visual: stakes band → rose; Approve button gets a confirm step ("Approve 10 — high stakes"). Voice shifts to plain register: "Ten surfaces. High stakes from Eros's name-change flag. Approve all, or split out Eros?"

Gestures

  • Tap group caret → expand/collapse that group only.
  • Tap compact row → inline expand; auto-collapses any other expanded compact row.
  • Long-press surface row → quick actions (skip · edit just this · open surface settings).
  • Long-press group header → bulk action menu (All on · All off · Skip this group).
  • Right-swipe card → Approve N (haptic confirm threshold per F §F4); blocked when in dispatch-in-progress or stakes-escalated states.
  • Left-swipe card → Set aside (moves to pending-approvals).
  • Two-finger swipe down → minimize-to-inbox.
  • Pinch-out on group header → expands all groups at once (escape hatch from collapsed-default).
  • Tap "Why" → expand per-surface rationales stacked.

In-the-wild copy

Working register throughout except where noted.

H3 tour fan-out (anchor-and-rest header):

Berlin Oct 37 ready on 11 surfaces. Anchors set. Eros is off — flip on if you want them included.

H5b compact-row with near-cap notice (ⓘ hover):

AdultLook caps at 500 — this draft lands at 488. Tight but fits.

H5e split-card connector (K3i):

These 8 go together · This 1 wants your eyes.

Post-dispatch 2/8 failed (plain — failure register):

8 surfaces updated. AdultSearch and Eros rejected the push. Retry, or set them aside.

Edge cases

  • Single group exceeds compact threshold but total is small (e.g. 9 directories, no brand sites) — H5b activates for that group; the card still feels flat because there's only one group. Acceptable; predictability over polish.
  • All surfaces in one group blocked (e.g. all N2 pending verification after a coop-intel mass-flag per brief N) — group header shows ⚠ all-blocked; Approve count drops to 0; action bar reads "Nothing to approve · review blockers".
  • Confidence below threshold on enabled-only average — Approve disabled; "ask Cocotte to try again" surfaces beneath action bar (mirrors single-surface card edge case).
  • Card stale (>24h) — same gentle warning as single-surface card; re-draft re-runs the per-surface diff pass.
  • Filter input typed during dispatch-in-progress — input disabled; tap surfaces a one-line hint ("Pushing — filter unlocks when done").
  • VoiceOver order — header → aggregate stakes/confidence → "Why" → group headers (with counts) → expanded rows → action bar. Group counts are critical: a blind user must hear "6 of 8 directories enabled" without expanding.
  • Reduced motion — accordion expand/collapse becomes instant; dispatch progress strip skips per-row spinner animation, jumps row-state on settle.
  • Dynamic Type XXL — compact rows force-promote to full rows (compact-format unreadable at largest sizes); accordion remains.
  • Org-context (brief W) — if active org has a surface subset enabled, disabled-by-org rows render with a tiny lock glyph; tap to see "disabled in {Org} context".
  • Kill switch active (brief K) — card greys; action bar replaced by "Auto-actions paused — resume to dispatch".
  • brief H §H4 — multi-surface approval-card pattern (anatomy).
  • brief H §H5ae — density rules (accordion / compact / anchor-and-rest / cross-cutting / split-card).
  • brief A §approval — chat-surface integration; this card appears inline.
  • brief K §K3i — split-card boundary (routine vs brand-sensitive).
  • brief O — the 24-surface roster that makes density mandatory.
  • brief R §R3 — tour fan-out is this card's H5c anchor-and-rest shape, used by the tours backbone.
  • approval-card.screen.md — sibling single-surface pattern.
  • brief I §3 — per-row audit lineage post-dispatch.
  • 00-system-voice.md §V2b + §V2c — working register for body, plain on failures/escalation.