133 lines
13 KiB
Markdown
133 lines
13 KiB
Markdown
|
|
# peer-feed.screen
|
|||
|
|
|
|||
|
|
Implements [brief AE §AE9](./AE-provider-social-network.brief.md) — 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`](./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. 3–8 cards typical; pull-to-refresh re-pulls (rate-limited).
|
|||
|
|
3. **`degraded`** — `peer-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 disagreement** — `peer-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.
|
|||
|
|
|
|||
|
|
## Related
|
|||
|
|
|
|||
|
|
- [Brief AE §AE9](./AE-provider-social-network.brief.md) — parent spec; aggregator + anonymity floor.
|
|||
|
|
- [Brief AE §AE11](./AE-provider-social-network.brief.md) — incognito posture; feed-disable.
|
|||
|
|
- [Brief AE §AE2](./AE-provider-social-network.brief.md) — coop / connection scope informs which peers feed into a rollup.
|
|||
|
|
- [Brief AE §AE5](./AE-provider-social-network.brief.md) — directory scope informs the peer pool for platform-wide cards.
|
|||
|
|
- [Brief L](./L-specialists-fleet.brief.md) — `peer-aggregator` worker is a `prospect-resolver` extension.
|
|||
|
|
- [Brief I](./I-audit-trust-replay.brief.md) — each aggregator run + each surfaced card writes audit rows.
|
|||
|
|
- [Brief K §K3](./K-safety-blocklist.brief.md) — PII gate on any free-text fragment surfaced in a card.
|
|||
|
|
- [Brief AD](./AD-multilingual-opaque.brief.md) — locale-faithful re-authoring of stat sentences + methodology blurbs.
|
|||
|
|
- [Brief M §M2a](./M-error-degraded-modes.brief.md) — stale / degraded surface behavior.
|
|||
|
|
- [analytics-dashboard.screen.md](./analytics-dashboard.screen.md) — panel-card register pattern shared.
|
|||
|
|
- [daily-digest.screen.md](./daily-digest.screen.md) — register usage + working/hearth/plain split pattern shared.
|
|||
|
|
- [`00-system-voice.md`](./00-system-voice.md) §V2, §V5 — register selection.
|
|||
|
|
|
|||
|
|
## 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.
|