Feed Model Design
Date: 2026-03-05 Status: Approved
Problem
The existing docs describe content retrieval as one-off fetches ("Bob wants Alice's events"). In practice, users need a continuous feed — the client actively syncs and surfaces content from their social graph as their primary information source. The protocol needs an explicit feed construction model that defines: what content to fetch, in what priority order, from which social tiers, and how long to cache it.
Additionally, interaction patterns should serve as natural referral signals. If Alice interacts heavily with Bob, Alice's followers should discover Bob through that activity — not just through follow graph topology.
Feed Tiers
Three tiers replace the previous "WoT-Tiered Read Strategy" tier definitions:
| Tier | Name | Who | Feed Behavior | Cache TTL | Trust Signal |
|---|---|---|---|---|---|
| 1 | Inner Circle | Mutual follows | Continuous sync — pact-stored, always available | 30 days (pact-covered) | Bidirectional follow |
| 2 | Orbit | High-interaction authors + socially-endorsed authors | Periodic polling — client fetches on interval | 14 days | Interaction frequency + shared WoT edges |
| 3 | Horizon | 2-hop authors weighted by path count + relay discoveries | On-demand with opportunistic caching | 3 days | Edge multiplicity + relay curation |
Inner Circle content is always available because storage pacts guarantee it. This is the user's trusted social core — people they know and talk to.
Orbit is the referral layer. It contains two types of authors:
- Authors the user interacts with frequently (reactions, replies, reposts) even if the follow is unilateral
- Authors that multiple Inner Circle contacts interact with heavily — socially endorsed through observed behavior
Horizon is discovery. It covers 2-hop graph reach (authors connected through multiple paths from the user's WoT) and relay-surfaced content. This is how users encounter new voices.
Interaction-Based Referral
The protocol already makes interactions observable — reactions, replies, and reposts are public signed events. The client tracks a rolling interaction score per author:
interaction_score(author) = sum(weight[event_kind] * recency_decay(age_days))
Interaction weights:
| Event Kind | Weight | Rationale |
|---|---|---|
Reply (kind 1 with e tag) |
3 | Highest signal — active conversation |
| Repost (kind 6) | 2 | Endorsement — sharing with followers |
| Reaction (kind 7) | 1 | Lightweight engagement |
Recency decay: recency_decay(age) = exp(-age / 30) — interactions half-life is ~21 days.
What the interaction score does
- Ranks content within the feed — high-interaction authors surface first within their tier
- Creates referral signals — when multiple Inner Circle contacts have high interaction scores with the same author, that author enters the user's Orbit tier
Referral threshold
An author enters a user's Orbit when 3+ Inner Circle contacts have interaction scores above a configurable minimum with that author.
Default minimum: 5 weighted interactions in 30 days (e.g., 5 reactions, or 1 reply + 1 repost, etc.).
This captures real social behavior: if several of your close contacts are actively engaging with someone, that person is worth your attention. No algorithmic recommendation — just observable social proof.
Referral is bidirectional
When you interact heavily with an author, you're implicitly referring that author to your Inner Circle. This is not an explicit action — it's a natural consequence of your public interactions being visible to your followers. The protocol doesn't broadcast "Alice recommends Bob." Instead, Alice's followers' clients observe Alice's interactions and surface Bob when the threshold is met.
Feed Construction Flow
Client opens / background sync runs
|
+- Tier 1 (Inner Circle): Already synced via pacts
| +- Sort by: created_at (chronological)
| +- Interaction score boosts position within tier
| +- Content always available -- pact partners store it
|
+- Tier 2 (Orbit): Poll for updates
| +- For each Orbit author: fetch via gossip/cached endpoints
| +- Cache received events (TTL: 14 days)
| +- Sort by: interaction_score * recency
| +- Referral scan: check Inner Circle interactions
| | +- Author with 3+ IC contacts interacting -> add to Orbit
| +- Polling interval: configurable (default: every 15 minutes)
|
+- Tier 3 (Horizon): On-demand + opportunistic
| +- 2-hop authors weighted by shared edge count
| +- Relay-curated content (relay subscriptions)
| +- Cache received events (TTL: 3 days)
| +- Sort by: trust_score (edge count) * recency
| +- Fetched when user scrolls past Tier 1+2 content
|
+- Merged feed: interleave tiers with configurable weights
Default: 60% Inner Circle, 25% Orbit, 15% Horizon
Batch sync through pact partners
The client doesn't make one request per author. It syncs through pact partners in batches. Each pact partner stores ~20 authors' data, and social clustering means those overlap with your follow graph.
- Connect to pact partner Alice
- Send: "give me updates for our shared WoT, excluding [authors I already synced]"
- Alice computes the intersection locally and sends a batch response
- Repeat for ~5 more partners, growing the exclude list each time
- After ~5-10 connections, most IC + Orbit is covered
- Gossip/relay for the remaining uncovered follows
Coverage: 20 pact partners × ~20 stored authors = ~400 slots. With overlap and clustering, ~40-60% of follows are reachable through batch sync. The rest goes through gossip (in-WoT, resolves in 1-2 hops) or relay.
Sync plan precomputation: The client builds a coverage map (which partner stores which of your follows) and uses greedy ordering (connect to the partner covering the most uncovered authors first). Recomputed when the WoT changes.
WoT monitoring
The sync strategy depends on the WoT graph. The client monitors changes:
- Follow/unfollow events: Recompute IC/Orbit membership and sync plan
- Pact partner follow changes: Update coverage map (their stored authors may have changed)
- Pact formed/dropped: Recompute entire sync plan
- Daily resync: Full WoT recomputation once per day as a safety net — recompute all tiers, rebuild sync plan, execute full batch sync to fill gaps
Feed merge behavior
The merged feed interleaves content from all three tiers. Within each tier, content is sorted by the tier's ranking function. Across tiers, the weight determines how many items from each tier appear per screen of content.
A user with a small Inner Circle and large Orbit will see the weights auto-redistribute (same mechanism as the existing auto-redistribute in the simulation model). If a tier is empty, its budget shifts proportionally to remaining tiers.
Tiered Caching
All fetched content is cached locally, regardless of source. Cache eviction follows tier-based TTLs:
| Tier | Default TTL | Config Key | Eviction Strategy |
|---|---|---|---|
| Inner Circle | 30 days | (pact window) | Pact-managed, not cache |
| Orbit | 14 days | orbit_cache_ttl |
LRU within TTL boundary |
| Horizon | 3 days | horizon_cache_ttl |
LRU within TTL boundary |
| Relay content | 1 day | relay_cache_ttl |
LRU within TTL boundary |
Cache behavior
- Pact-covered content (Inner Circle) is not subject to cache eviction — it's stored as part of the pact obligation
- Orbit and Horizon content is cached on fetch and evicted after TTL expires or when cache storage limits are reached (whichever comes first)
- Relay content has the shortest TTL — relay-discovered content that isn't promoted to Orbit decays quickly
- All cached content participates in the cascading read-cache mechanism: if someone gossips for content you have cached, you respond regardless of tier
Storage budget
Cache storage is bounded by the existing read_cache_max_mb setting (default: 100 MB). Within that budget, tiers are not hard-partitioned — LRU eviction naturally prioritizes frequently-accessed content. The TTL ensures stale content doesn't occupy space indefinitely.
Relay Role in the Feed
Relays serve the Horizon tier. Their content appears alongside 2-hop graph discoveries but with a distinct trust signal:
- 2-hop WoT content: trust weighted by edge count (how many of your contacts follow this author)
- Relay content: trust weighted by the relay's reputation (user-configurable relay trust level)
Relay content that the user interacts with gets promoted: if you react to a relay-discovered post, that author's interaction score increases. If the threshold is met (3+ IC contacts also interact), the author enters Orbit and is fetched via mesh instead of relay.
This creates a natural flow: relay -> horizon -> orbit. Relays serve as discovery engines; the mesh absorbs content that proves socially relevant.
Simulation Model Impact
The existing WoT-Tiered Read Strategy in the simulation model should be updated to reflect these tiers:
- Direct WoT tier -> Inner Circle (same mechanics, pact-stored)
- 1-hop tier -> split between Inner Circle (mutual follows) and Orbit (non-mutual + referrals)
- 2-hop tier -> Horizon
- New: interaction scoring as a read-selection weight within each tier
- New: referral mechanism promoting 2-hop authors to Orbit based on IC interaction patterns
Default read weights update: 60% Inner Circle (was 50% direct WoT), 25% Orbit (was 30% 1-hop), 15% Horizon (was 20% 2-hop).