cocottetech/@platform/codebase/@features/ai-copilot/docs/peer-feed.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

13 KiB
Raw Blame History

peer-feed.screen

Implements brief AE §AE9 — the aggregated peer feed. "What your peers are doing this week" as anonymized aggregations only. No avatars, no per-peer breakdowns, no PII, no cross-provider prospect rows. Powered by the peer-aggregator worker (extension of prospect-resolver per brief L), which enforces a k=5 anonymity floor before any rollup is published.

Reached from chat-home top-bar overflow → "Peer feed" (per FEED-Q2 lean: feed only at P0; chat-home placement deferred). Voice register: working by default, hearth on positive movement, plain on degraded / opted-out states (per 00-system-voice.md §V2).

Layout (iPhone — scrolling card stream; web companion mirrors)

┌─────────────────────────────────────────────────┐
│ ◄ Chat                                  ⚙       │ 56pt — top bar; ⚙ = mute mgmt
├─────────────────────────────────────────────────┤
│  Peer feed · this week                          │   working register header
│  refreshed 4h ago · daily                       │   cadence per FEED-Q1 lean
├─────────────────────────────────────────────────┤
│                                                 │
│ ┌─────────────────────────────────────────────┐ │   working register card
│ │ Threads activity                            │ │
│ │ Your colleagues posted 4× more on Threads   │ │   anonymized stat
│ │ this week than last.                        │ │
│ │ from 12 peers · methodology →               │ │   k≥5 disclosure
│ └─────────────────────────────────────────────┘ │
│                                                 │
│ ┌─────────────────────────────────────────────┐ │   hearth register card
│ │ Berlin coop                                 │ │
│ │ A salon you're in published 2 shared        │ │
│ │ playbooks. Worth a look in the drawer.      │ │
│ │ from 7 peers · methodology →                │ │
│ └─────────────────────────────────────────────┘ │
│                                                 │
│ ┌─────────────────────────────────────────────┐ │   working — low-confidence flag
│ │ Coop intel                                  │ │
│ │ 3 of your colleagues marked Berlin reports  │ │
│ │ low-confidence this week.                   │ │
│ │ from 8 peers · methodology →                │ │
│ └─────────────────────────────────────────────┘ │
│                                                 │
│ ┌─────────────────────────────────────────────┐ │   platform-wide rolling card
│ │ Platform-wide · 90d                         │ │
│ │ Tryst bumps are accepting 12% slower this   │ │
│ │ quarter than last.                          │ │
│ │ from 240 peers · methodology →              │ │
│ └─────────────────────────────────────────────┘ │
│                                                 │
└─────────────────────────────────────────────────┘

Components

Component Notes
Top bar Back + ⚙ (settings: muted card types, refresh cadence preview, posture quick-link to brief S settings).
Cadence header "this week" anchor + last-refresh stamp + cadence label (per FEED-Q1 lean: daily).
Aggregator card One per anonymized rollup. Three parts: kind label (e.g. "Threads activity", "Coop intel", "Platform-wide · 90d"), the anonymized stat sentence, a peer-count + methodology link. NO avatars, NO peer handles, NO per-peer detail.
k≥5 disclosure Every card shows from N peers where N ≥ 5 per the AE9 anonymity floor. Cards with N < 5 are auto-suppressed (see sensitive-segment state).
Methodology blurb Tap to expand: short explainer of what's measured, the comparison window, and the anonymization floor. Working register.
Register cue Card-level register matches the sentiment: hearth on positive ("worth a look"), working on neutral, plain when a number signals trouble (e.g. "12% slower").

States

  1. empty — no peers in any coop yet, OR all peers below k=5 across all aggregators. Copy: "Nothing to show yet. Once your coops have a handful of active peers, weekly aggregations land here." Hearth register, single line, no fake-empty placeholders.
  2. populated — default; the layout drawn above. 38 cards typical; pull-to-refresh re-pulls (rate-limited).
  3. degradedpeer-aggregator worker hit the k=5 anonymity floor on most card types this cycle. Single visible card: "Not enough peer data this week to show aggregations safely. Back next cycle." Plain register. Per AE9 brief — never lower the anonymity floor to fill the surface.
  4. opted-out — provider switched posture to incognito (AE11). The feed surface disappears from the overflow menu entirely (no "you're opted out" placeholder — incognito means no peer-facing surface, per AE11). If reached by deep link: plain cue: "Peer feed is off while you're incognito. Switch posture in settings to surface it."
  5. sensitive-segment — a candidate card would identify < 5 peers (e.g. "1 of your colleagues did X"). Auto-suppressed at worker level; never reaches the surface. If somehow surfaced: card replaced by methodology stub: "Held a card back — too few peers to publish safely."
  6. stale — last successful aggregator run > 36h ago (brief M §M2 degraded mode). Cadence header shows "refreshed 38h ago · stale" with plain register tint. Existing cards remain readable; no new ones added.
  7. muted-card-type — provider long-pressed a card kind ("mute Threads activity"). That kind suppresses; ⚙ shows it in the muted list with un-mute affordance.
  8. cold-load — skeleton placeholders per card (4 typical).
  9. VoiceOver — cards read top-to-bottom; methodology link explicitly announced; from N peers read aloud as part of each card.

Interactions

  • Tap card → expand context / methodology blurb inline (what's measured, comparison window, k-floor disclosure, last refresh).
  • Long-press card → "Mute this card type" / "Mute for one cycle" / "Why this card?" sheet. Mute persists until un-muted from ⚙.
  • Pull-to-refresh → re-pulls the latest aggregator output (rate-limited; daily cadence per FEED-Q1 lean — pull-refresh just re-fetches the same daily rollup, doesn't trigger a fresh worker run).
  • Tap ⚙ → settings sheet (muted card types, refresh cadence preview, link to brief S posture settings).
  • Tap methodology → → expand inline; tap again to collapse.
  • VoiceOver swipe order — cadence header → each card (kind label → stat sentence → peer count) → methodology where expanded.

In-the-wild copy

  • (working, default) "Your colleagues posted 4× more on Threads this week than last. from 12 peers · methodology →"
  • (hearth, positive) "A salon you're in published 2 shared playbooks. Worth a look in the drawer."
  • (working, watch-out) "3 of your colleagues marked Berlin reports low-confidence this week."
  • (working, platform-wide 90d) "Tryst bumps are accepting 12% slower this quarter than last. from 240 peers · methodology →"
  • (plain, degraded) "Not enough peer data this week to show aggregations safely. Back next cycle."
  • (plain, opted-out via deep link) "Peer feed is off while you're incognito. Switch posture in settings to surface it."
  • (working, methodology expand) "Counts posts published by peers who share at least one coop with you, rolling 7 days. Comparison: prior 7d. Floor: 5 peers minimum before publishing."

Edge cases

  • Incognito posture (AE11) ↔ feed surface — feed-disable is automatic; the surface is hidden from the overflow menu entirely. No badges, no nudges, no "you're missing out" copy. Per AE11: incognito means no peer-facing surface, ever.
  • Rare event with only one matching peer — auto-suppressed at the peer-aggregator worker per k=5. Never reaches the device. If a worker bug surfaces one anyway, the surface drops the card silently + logs to audit (brief I).
  • Platform-wide aggregations — drawn from the rolling 90d window across all consenting providers (not coop-scoped). Always show "Platform-wide · 90d" label so the scope is unambiguous.
  • Peer leaves all shared coops — their contribution drops out of next cycle's rollup; no retroactive recompute. Past cards remain (they were anonymized at publish time).
  • All peers in one coop block the provider — that coop's aggregations disappear from the feed (no peers visible → k=5 not met). No notice given (giving notice would leak the block).
  • Provider changes preferred language — card stat sentences re-author per AD opacity (no "translated from" annotation); methodology blurb localized from the per-locale voice-{locale}.yaml bank.
  • Worker disagreementpeer-aggregator and prospect-resolver produce conflicting counts (brief M §M7 conflict): card is suppressed for the cycle; plain row in audit.
  • Reduced motion — card-enter animations replaced by crossfade.
  • Dynamic Type XXL — peer count moves to its own line under the stat sentence.
  • VoiceOver + dense feed — group cards under a single landmark; each card announces its kind label first.

Out of scope

  • Per-peer breakdowns of any kind ("Sarah posted X") — never. Per AE9 brief.
  • Cross-provider prospect rows — never; preserved from brief Y §Y7.
  • Specific prospect data leaking into aggregations — gated by K3 + the aggregator's anonymization step.
  • Real-time / push-driven feed (P0 is daily-pull only per FEED-Q1 lean).
  • Chat-home placement (per FEED-Q2 lean: feed-only at P0; chat-home embed deferred).
  • Web-first feed companion (P0 surfaces iOS; web inherits later).
  • Configurable card types beyond mute (custom cards / SQL-style queries are P5+).
  • Provider-authored aggregations (this surface is read-only; peers can't publish into the feed).

Open questions

  • FEED-Q1 Refresh cadence — daily / per-vigil / live? Lean: daily. Per-vigil risks oversharing micro-movements; live risks small-N leaks under the k=5 floor. Daily lets the aggregator run cleanly + matches the daily-digest rhythm.
  • FEED-Q2 Surface in chat-home as well as dedicated feed? Lean: feed only at P0. Chat-home is already dense; the dedicated feed proves the aggregations are valuable before embedding. Revisit after a cycle of usage data.