Core System Architecture Part 87 — Anonymous Network Content Feed, Timeline, Subscription, Recommendation, Ranking & Privacy-Preserving Discovery Architecture

SIAR — Secure, Local-First, Multi-Transport Communication Platform

Series: Core System Architecture
Part: 87
Status: Architecture specification
Primary language: Rust
Builds on: Core System Architecture Parts 32, 43, 45–48, 56, 58–59, 67–69, 74–86

Primary purpose: define SIAR's content feed, timeline, subscription, recommendation, ranking, discovery, trending, creator/subscriber privacy, local/on-device personalization, federated content ingestion, anti-manipulation, and privacy-preserving content distribution architecture without creating a centralized behavioral surveillance engine.


1. Purpose

Content feeds are powerful because they help users discover:

posts
announcements
public channels
communities
articles
media
updates

But feed systems are also one of the most privacy-invasive parts of modern platforms.

Typical centralized feeds collect:

what users viewed
what they paused on
what they clicked
what they ignored
who they follow
what topics they prefer
how long they watched

The governing principle is:

SIAR feeds should help users discover and organize content without requiring centralized behavioral profiles, global social graphs, or opaque engagement-maximizing ranking systems.


2. Architectural Position

Subscriptions / Public Sources / Local Signals
                    │
                    ▼
             Feed Candidate Set
                    │
                    ▼
            Privacy Policy Filter
                    │
                    ▼
          Local / Explicit Ranking
                    │
                    ▼
                Timeline

3. Core Separation

Keep distinct:

subscription
feed candidate
timeline item
ranking score
recommendation source
public trend signal
behavioral signal
creator identity
subscriber identity

4. Non-Goals

Part 87 does not create:

a global engagement graph
a centralized per-user interest profile
a mandatory algorithmic feed
a hidden infinite-scroll recommender optimized for addiction

5. Feed Types

#![allow(unused)]
fn main() {
pub enum FeedType {
    Chronological,
    Subscription,
    Curated,
    LocalRecommended,
    PublicDiscovery,
    Trending,
    Managed,
}
}

6. Chronological Feed

Pure time/order-based.


7. Subscription Feed

Only explicitly followed sources.


8. Curated Feed

User/admin-selected sources.


9. LocalRecommended

On-device recommendation.


10. PublicDiscovery

Public/listed content.


11. Trending

Aggregate public trend signal.


12. Managed

Organization-scoped feed.


13. Hard Rule

Chronological/subscription feed must always remain available when the feature exists.


14. Feed Source

#![allow(unused)]
fn main() {
pub enum FeedSource {
    Contact(RelationshipId),
    SocialSpace(SocialSpaceId),
    Channel(ChannelId),
    Publisher(PublisherRef),
    Federation(FederationDomainId),
    LocalCollection(LocalCollectionId),
}
}

15. Feed Source Identity

Scoped.


16. No Global User ID Requirement

Hard rule.


17. Subscription

Explicit user intent.

#![allow(unused)]
fn main() {
pub struct Subscription {
    pub subscription_id: SubscriptionId,
    pub source: FeedSource,
    pub state: SubscriptionState,
    pub delivery: SubscriptionDelivery,
}
}

18. Subscription State

#![allow(unused)]
fn main() {
pub enum SubscriptionState {
    Active,
    Muted,
    Paused,
    Unsubscribed,
}
}

19. Muted

Still subscribed but hidden from notification/high-priority feed.


20. Paused

Temporary stop.


21. Unsubscribed

No new feed items.


22. Hard Rule

Subscription does not imply public disclosure of subscriber identity.


23. Subscriber Privacy

Creator should not receive subscriber list by default.


24. Public Channels

Can expose aggregate subscriber count only.


25. No Individual Subscriber Export

Hard rule.


26. Subscription Identity

Opaque.


27. No AccountId Embedded In Feed Distribution Key

Hard rule.


28. Subscription Capability

#![allow(unused)]
fn main() {
pub struct SubscriptionCapability {
    pub source: FeedSource,
    pub permissions: SubscriptionPermissions,
    pub expires_at: Option<Timestamp>,
}
}

29. Subscription Permissions

#![allow(unused)]
fn main() {
pub struct SubscriptionPermissions {
    pub read: bool,
    pub receive_notifications: bool,
    pub fetch_archive: bool,
}
}

30. Public Source

May not require durable identity.


31. Private Source

Requires capability/membership.


32. Feed Item

#![allow(unused)]
fn main() {
pub struct FeedItem {
    pub item_id: FeedItemId,
    pub source: FeedSource,
    pub content_ref: ContentRef,
    pub published_order: FeedOrderKey,
    pub visibility: FeedVisibility,
}
}

33. Feed Item ID

Random/opaque.


34. No User Identity Encoding

Hard rule.


35. Feed Visibility

#![allow(unused)]
fn main() {
pub enum FeedVisibility {
    Public,
    Subscribers,
    Members,
    RelationshipScoped,
    Managed,
}
}

36. Candidate Collection

Fetch eligible feed items.


37. Candidate Sources

subscriptions
contacts
joined social spaces
public discovery
local saved sources

38. No Global Candidate Graph

Hard rule.


39. Timeline State

#![allow(unused)]
fn main() {
pub struct TimelineState {
    pub cursor: TimelineCursor,
    pub mode: FeedType,
    pub filters: TimelineFilters,
}
}

40. Cursor

Opaque.


41. No User Behavior Embedded In Cursor

Hard rule.


42. Timeline Ordering

Separate from source publication order.


43. Chronological Ordering

Preferred default.


44. Ranking Modes

#![allow(unused)]
fn main() {
pub enum RankingMode {
    Chronological,
    UserPinned,
    LocalHeuristic,
    Curated,
}
}

45. No Opaque Server ML Ranker As Baseline

Hard rule.


46. Chronological

Deterministic.


47. UserPinned

User-defined priority.


48. LocalHeuristic

On-device.


49. Curated

Transparent source-defined list.


50. Feed Ranking Principle

Ranking should be:

explainable
local where possible
user-controllable
reversible

51. Hard Rule

Server cannot silently personalize feed using hidden behavioral history.


52. Local Ranking Inputs

Possible:

explicit follows
manual topic preference
local recency
user pin
mute state

53. Avoid

dwell time
scroll hesitation
rage-clicks
late-night behavior

as persistent cloud profile.


54. Hard Rule

Behavioral telemetry is not required for feed ranking.


55. Local Behavioral Signals

If used:

stay on device
expire quickly
opt-in

56. No Raw Behavioral Upload

Hard rule.


57. Preference-Based Ranking

User explicitly chooses interests.


58. Topic Preference

#![allow(unused)]
fn main() {
pub struct TopicPreference {
    pub topic: TopicId,
    pub weight: ExplicitPreferenceWeight,
}
}

59. Explicit Preference Weight

Small bounded range.


60. No Infinite Learned Score

Hard rule.


61. Ranking Score

#![allow(unused)]
fn main() {
pub struct LocalRankingScore {
    pub explicit_priority: i16,
    pub recency_bucket: u8,
    pub source_priority: u8,
}
}

62. No hidden psychological score.


63. Ranking Explanation

UI can say:

Because you follow this channel
Because you pinned this source
Recent from subscribed community

64. No Deceptive "Recommended For You" Without Explanation

Hard rule.


65. Feed Algorithm Transparency

User can inspect active ranking mode.


66. User Can Switch To Chronological

Hard rule.


67. Feed Candidate Deduplication

Deduplicate same content from multiple sources.


68. Dedup Key

Content identity/digest where safe.


69. Privacy Caveat

Cross-source dedup can reveal linkage.


70. Strict Mode

Dedup only local.


71. No Server-Wide Cross-User Dedup Graph

Hard rule.


72. Public Discovery

Lists public/listed content.


73. Discovery Inputs

public channels
listed communities
public publishers
public posts

74. No Private Content Leakage

Hard rule.


75. Discovery Query

#![allow(unused)]
fn main() {
pub struct DiscoveryQuery {
    pub text: Option<DiscoveryText>,
    pub topic: Option<TopicId>,
    pub scope: DiscoveryScope,
}
}

76. Discovery Scope

#![allow(unused)]
fn main() {
pub enum DiscoveryScope {
    Local,
    Tenant,
    Federation,
    PublicNetwork,
}
}

77. Search Privacy

No account identity required for public search.


78. Search Query Logging

Minimized.


79. No Long-Term Search Profile

Hard rule.


80. Public Search Result

#![allow(unused)]
fn main() {
pub struct DiscoveryResult {
    pub content_ref: ContentRef,
    pub source: FeedSource,
    pub title: Option<ContentTitle>,
    pub summary: Option<ContentSummary>,
}
}

81. No Subscriber Identity.


82. Recommendation Sources

#![allow(unused)]
fn main() {
pub enum RecommendationSource {
    ExplicitTopics,
    FollowedSources,
    LocalHistory,
    PublicTrending,
    CuratedList,
}
}

83. ExplicitTopics

Preferred.


84. FollowedSources

Safe.


85. LocalHistory

On-device only.


86. PublicTrending

Aggregate public signal.


87. CuratedList

Human/editorial.


88. No Cross-User Behavioral Collaborative Filtering By Default

Hard rule.


89. Why

It requires graphing user behavior.


90. Future Optional Private Recommendation

Could use privacy-preserving aggregation.


91. But

Must be reviewed separately.


92. No Custom Federated Learning Crypto

Hard rule.


93. Trending

Aggregate public signal.


94. Trend Inputs

Possible:

public views
public reshares
public reactions
public subscriptions

95. Aggregate Only


96. No Individual Viewer Tracking

Hard rule.


97. Trend Window

Bounded.


98. Example

#![allow(unused)]
fn main() {
pub struct TrendWindow {
    pub duration: Duration,
    pub minimum_count: u64,
}
}

99. Minimum Count

Protect privacy.


100. Small cohort

Do not surface.


101. Hard Rule

Trend output must satisfy minimum anonymity bucket.


102. Exact Counts

May be hidden.


103. Trend Score

Coarse.


104. Trend Class

#![allow(unused)]
fn main() {
pub enum TrendClass {
    Emerging,
    Popular,
    VeryPopular,
}
}

105. No Real-Time Per-User Trend Dashboard

Hard rule.


106. Trend Computation

Can be server aggregate.


107. Input events

Stripped of user identity where possible.


108. No Global User Identifier.


109. Abuse

Trend manipulation likely.


110. Need anti-spam/bot weighting.


111. But

Do not require real-world identity.


112. Anti-Manipulation Inputs

rate limits
proof cost
account age bucket
source diversity

113. Privacy-safe.


114. No Public Reputation Score.


115. Hard rule.


116. Creator Privacy

Creators can publish through:

public pseudonym
space-scoped identity
managed identity

117. No global real-name requirement.


118. Publisher Ref

#![allow(unused)]
fn main() {
pub enum PublisherRef {
    Pseudonym(PublisherPseudonym),
    SocialSpace(SocialSpaceId),
    Managed(ManagedPublisherId),
}
}

119. Public Publisher Pseudonym

Stable by choice.


120. Can rotate with migration policy.


121. Subscriber should not automatically learn account/login identity.


122. Hard rule.


123. Feed Subscription Delivery

Possible:

pull
push hint
mailbox fanout
pub/sub

124. Pull

Privacy-friendly.


125. Push Hint

Opaque wake hint.


126. Mailbox Fanout

Encrypted.


127. Pub/Sub

Public content.


128. No Push Payload With Sensitive Feed Details By Default

Hard rule.


129. Timeline Synchronization

Across own devices.


130. Sync state:

subscriptions
mute state
pinned sources
read position optionally

131. Read Position

Privacy-sensitive.


132. Default

DeviceLocal.


133. User may enable encrypted sync.


134. Hard Rule

Read history is not cloud-synced by default.


135. Feed Read State

#![allow(unused)]
fn main() {
pub enum FeedReadStateSync {
    LocalOnly,
    EncryptedAccountSync,
}
}

136. Creator Read Receipts

Disabled by default.


137. No Per-Subscriber View Receipts

Hard rule.


138. Public View Counts

Aggregate.


139. Minimum threshold.


140. No individual viewer list.


141. Reactions

Can be:

private
aggregate
public

142. Public reaction identity

Explicit opt-in.


143. Default public feed

Aggregate reactions.


144. No list of reactors by default.


145. Hard rule.


146. Reshare

Explicit action.


147. Reshare Graph

Potential social graph.


148. Do not globally expose chain by default.


149. Hard rule.


150. Attribution

Can show original content source.


151. No full reshare genealogy.


152. Feed Privacy Modes

#![allow(unused)]
fn main() {
pub enum FeedPrivacyMode {
    Standard,
    Private,
    MaximumAnonymity,
}
}

153. Standard

Normal subscriptions, local ranking.


154. Private

Minimal remote analytics.


155. MaximumAnonymity

Chronological/local feeds only, delayed sync, no behavioral personalization.


156. Hard Rule

Privacy mode never silently downgrades for better recommendations.


157. Local Recommendation Engine

Optional.


158. Inputs

explicit topics
local subscriptions
local saved items
local interaction history

159. Outputs

Candidate ranking.


160. No Cloud Model Requirement

Hard rule.


161. On-Device Model

Optional.


162. Model Data

Local.


163. No raw prompt/content telemetry.


164. Model Update

Signed artifact.


165. No per-user model upload.


166. Hard rule.


167. Recommendation Store

Derived/rebuildable.


168. Not authoritative user state.


169. User Can Reset

Required.


170. Reset Deletes Local recommendation state.


171. Feed Filters

#![allow(unused)]
fn main() {
pub struct TimelineFilters {
    pub topics: BTreeSet<TopicId>,
    pub muted_sources: BTreeSet<FeedSourceRef>,
    pub content_types: BTreeSet<ContentType>,
}
}

172. Filter State

Local or account-synced.


173. No filter telemetry.


174. Feed Item Content Types

#![allow(unused)]
fn main() {
pub enum ContentType {
    Text,
    Image,
    Video,
    Audio,
    Link,
    Announcement,
    Article,
}
}

175. Media Autoplay

DeviceLocal preference.


176. External Links

Privacy-sensitive.


177. No Automatic External Fetch In Max-Anonymity

Hard rule.


178. Link Preview

Use local/proxy according to Part 84 privacy setting.


179. Feed Preloading

Performance vs privacy.


180. Default

Bounded.


181. No Preload Hundreds Of Unseen Items

Hard rule.


182. Why

Leaks interest and wastes bandwidth.


183. Preload Policy

#![allow(unused)]
fn main() {
pub struct FeedPreloadPolicy {
    pub max_items: u16,
    pub media_prefetch: bool,
}
}

184. Strict Mode

No media prefetch by default.


185. Offline Feed

Important.


186. Cache recent subscribed content.


187. Cache policy

Bounded.


188. User controls.


189. Public discovery cache

Separate.


190. No infinite feed history.


191. Hard rule.


192. Feed Item Retention

Depends on source.


193. Public channel

Can archive.


194. Private group

Membership/history policy.


195. Local read cache

Device-controlled.


196. Deletion

Removed item tombstone if required.


197. No resurrect via stale cache.


198. Hard rule.


199. Feed Item Lifecycle

#![allow(unused)]
fn main() {
pub enum FeedItemState {
    Published,
    Updated,
    Retracted,
    Deleted,
}
}

200. Retraction

Source indicates no longer active.


201. Client cache

honors.


202. Public Archive

May preserve if policy/legal says.


203. Truthful distinction:

removed from feed
vs
globally erased

204. Hard rule.


205. Content Update

Versioned.


206. Feed Content Version

#![allow(unused)]
fn main() {
pub struct FeedContentVersion(pub u64);
}

207. Old stale update

Rejected.


208. No rollback.


209. Hard rule.


210. Feed Cursor

Source-scoped.


211. No global timeline clock required.


212. Chronological Merge

Merge multiple source cursors locally.


213. Hard Rule

No centralized ordered log of every user's feed.


214. Feed Merge Algorithm

K-way merge.


215. Local.


216. Federation

Remote feeds.


217. Federation gateway fetches public/federated content.


218. No global feed authority.


219. Hard rule.


220. Remote Publisher Identity

Domain scoped.


221. Cross-Domain Content Ref

#![allow(unused)]
fn main() {
pub struct FederatedContentRef {
    pub domain: FederationDomainId,
    pub content: RemoteContentId,
}
}

222. No account identity merge.


223. Federated Subscription

Bilateral.


224. Remote domain need not know final subscriber identity where pull model used.


225. Hard rule.


226. Federation Caching

Public content can be cached.


227. Private/member content

capability-controlled.


228. No federation gateway plaintext for E2EE group content.


229. Hard rule.


230. Federation Recommendation

Local only.


231. Remote domain provides metadata.


232. User client ranks.


233. No centralized cross-domain behavioral profile.


234. Hard rule.


235. Tenant/Managed Feed

Managed organization can publish announcements.


236. Managed feed appears in managed profile.


237. Personal feed remains separate.


238. Hard rule.


239. Tenant cannot inspect unrelated personal subscriptions.


240. Managed ranking

Org policy can pin critical announcements.


241. But

Only within managed workspace/profile.


242. No global takeover of personal feed.


243. Hard rule.


244. Critical Announcement

Higher priority.


245. Emergency broadcasts Part 41/17 style.


246. Still scoped.


247. Content Moderation

Part 86.


248. Removed public content excluded from discovery.


249. Private content moderation remains space-scoped.


250. No hidden platform-wide censorship state in local private feeds without policy authority.


251. Ranking & Moderation Separation

Hard rule.


252. Ranking should not silently shadow-ban content.


253. Moderation state explicit.


254. Ranking state explicit.


255. Visibility State

#![allow(unused)]
fn main() {
pub enum FeedVisibilityDecision {
    Eligible,
    HiddenByUser,
    HiddenByPolicy,
    RemovedBySource,
    RemovedByModeration,
}
}

256. Explainable.


257. User should distinguish:

muted
moderated
deleted
unavailable

258. Hard rule.


259. Anti-Manipulation

Threats:

bot farms
fake engagement
coordinated boosting
spam publishers

260. Responses

rate limits
minimum trend bucket
source diversity
proof cost
manual curation

261. No invasive device fingerprinting requirement.


262. Hard rule.


263. Publisher Abuse

Can be blocked/muted locally.


264. Source Block

#![allow(unused)]
fn main() {
pub enum FeedSourceState {
    Active,
    Muted,
    Blocked,
}
}

265. Blocked

No feed candidates.


266. Stale sync cannot unblock.


267. Hard rule.


268. Content Safety

External media/link fetch.


269. Sandboxed rendering.


270. No active HTML/JS execution in feed.


271. Hard rule.


272. Markdown/structured content

Sanitize.


273. Images/video

Decode safely.


274. Link Preview

Privacy policy.


275. Content Metadata

Bounded.


276. No arbitrary gigantic metadata.


277. Feed Storage

Local:

subscriptions
timeline cache
read state
local recommendation state

278. Server:

public content index
source metadata
aggregate trend counters

279. Server Must Not Store

global per-user read timeline
behavioral interest vector
subscriber edge graph

280. Hard rule.


281. Search

Part 32 integration.


282. Public feed search

server/public index allowed.


283. Private feed search

local.


284. No private content indexing centrally.


285. Hard rule.


286. Saved Items

Local/account encrypted.


287. Save action not public.


288. Creator not notified.


289. Hard rule.


290. Read Later

Same.


291. Bookmark Sync

Encrypted account state.


292. No bookmark analytics.


293. Hard rule.


294. Feed Notification

Separate.


295. Push notification uses opaque hint.


296. Content fetched after wake.


297. No full sensitive feed item in push payload.


298. Hard rule.


299. Feed Refresh

Pull-based.


300. Refresh Interval

Battery/network aware.


301. No high-frequency polling for dormant feeds.


302. Strict Mode

More batched.


303. Timeline Pagination

Bounded page size.


304. No unbounded infinite page response.


305. Hard rule.


306. Timeline Cursor Privacy

Opaque, non-user-identifying.


307. Cursor expiry.


308. No permanent cursor correlation token.


309. Hard rule.


310. Feed Sync Across Devices

Sync:

subscriptions
mutes
pins
saved items
optional read position

311. Not sync:

scroll velocity
dwell time
local ephemeral ranking history

312. Hard rule.


313. Feed Conflict Policy

Subscriptions:

set union/removal tombstone.


314. Block/mute:

restrictive wins where applicable.


315. Pin order:

user merge/manual or deterministic.


316. Read state:

device-local unless opted in.


317. No server LWW for security/privacy block state.


318. Hard rule.


319. Timeline Repository

#![allow(unused)]
fn main() {
pub trait TimelineRepository {
    fn page(
        &self,
        state: &TimelineState,
        limit: usize,
    ) -> Result<TimelinePage, FeedError>;
}
}

320. Subscription Repository

#![allow(unused)]
fn main() {
pub trait SubscriptionRepository {
    fn subscribe(
        &self,
        source: FeedSource,
    ) -> Result<SubscriptionId, FeedError>;

    fn unsubscribe(
        &self,
        id: SubscriptionId,
    ) -> Result<(), FeedError>;
}
}

321. Candidate Provider

#![allow(unused)]
fn main() {
pub trait FeedCandidateProvider {
    fn candidates(
        &self,
        context: &FeedContext,
    ) -> Result<Vec<FeedCandidate>, FeedError>;
}
}

322. Ranker

#![allow(unused)]
fn main() {
pub trait FeedRanker {
    fn rank(
        &self,
        candidates: &mut [FeedCandidate],
        mode: RankingMode,
    ) -> Result<(), FeedError>;
}
}

323. Public Discovery Service

#![allow(unused)]
fn main() {
pub trait PublicDiscoveryService {
    fn search(
        &self,
        query: DiscoveryQuery,
    ) -> Result<Vec<DiscoveryResult>, FeedError>;
}
}

324. Trend Aggregator

#![allow(unused)]
fn main() {
pub trait TrendAggregator {
    fn aggregate(
        &self,
        window: TrendWindow,
    ) -> Result<Vec<TrendSignal>, FeedError>;
}
}

325. No User-Level Trend API

Hard rule.


326. Ranking Policy

#![allow(unused)]
fn main() {
pub struct FeedRankingPolicy {
    pub allowed_modes: BTreeSet<RankingMode>,
    pub default_mode: RankingMode,
    pub allow_behavioral_local: bool,
}
}

327. Server cannot override user's chronological choice.


328. Hard rule.


329. Recommendation Policy

#![allow(unused)]
fn main() {
pub struct RecommendationPolicy {
    pub enabled: bool,
    pub allowed_sources: BTreeSet<RecommendationSource>,
    pub local_only_behavioral: bool,
}
}

330. Default

ExplicitTopics + FollowedSources + PublicTrending.


331. LocalHistory

Opt-in.


332. No Cloud Behavioral Model.


333. Hard rule.


334. Feed Explanation

#![allow(unused)]
fn main() {
pub enum RecommendationReason {
    FollowedSource,
    ExplicitTopic,
    PublicTrending,
    Curated,
    LocalHistory,
}
}

335. Every recommended item can expose one reason.


336. No hidden reason category.


337. Feed Control UX

User should have:

Chronological
Subscriptions only
Recommendations on/off
Reset local personalization
Mute/block source

338. Hard rule.


339. No Dark Pattern Against Chronological Mode

Hard rule.


340. Feed Quality

Optimize:

relevance
freshness
source diversity
user intent

341. Not optimize solely:

session length
screen time
compulsive engagement

342. Hard rule.


343. Source Diversity

Avoid one publisher dominating.


344. Local diversity rule.


345. Example

max N consecutive items from same source.


346. No hidden political/content viewpoint balancing requirement.


347. Just source diversity.


348. Discovery Safety

Public search can surface malicious content.


349. Moderation status.


350. User filters.


351. Sensitive content labels optional.


352. No invasive identity inference.


353. Hard rule.


354. Content Classification

Can be publisher-declared/moderator-applied.


355. No centralized psychographic classification of user.


356. Hard rule.


357. Creator Analytics

Privacy-sensitive.


358. Allowed aggregate metrics:

public view bucket
public reaction count
subscriber count bucket

359. Not allowed by default:

viewer identity
exact read timestamp
viewer location
contact overlap

360. Hard rule.


361. Creator Insights

Thresholded.


362. Minimum cohort.


363. No small audience deanonymization.


364. Hard rule.


365. Public Metrics

Coarsened.


366. Example subscriber count:

100+
1K+
10K+

367. Strict mode can hide.


368. Feed Telemetry

Safe:

refresh success
candidate fetch latency
ranking latency
trend pipeline health

369. Forbidden:

per-user read sequence
dwell-time profile
per-user interest vector

370. Hard rule.


371. Operational Logs

Source/service level.


372. No user content interaction history.


373. Feed SLO

Examples:

timeline load latency
subscription update propagation
public discovery availability

374. Privacy SLO

0 cloud behavioral profiles
0 subscriber identity export
0 viewer identity export

375. Security SLO

0 private content appearing in public discovery

376. Failure Modes

feed source outage
directory outage
trend service outage
ranking model failure
federation outage

377. Source Outage

Other sources continue.


378. Directory Outage

Cached subscriptions continue.


379. Trend Service Outage

Trending section disappears.


380. No fallback to invasive ranking.


381. Hard rule.


382. Ranking Failure

Fallback:

chronological

383. Hard rule.


384. Recommendation Engine Failure

Disable recommendations.


385. Do not block subscription feed.


386. Hard rule.


387. Federation Outage

Local/federated cached feed continues within validity.


388. No identity-leaking direct fallback.


389. Hard rule.


390. Account Lifecycle

Part 83.


391. Deleted/deactivated account subscriptions handled per policy.


392. Deleted account cannot continue cloud feed sync.


393. Local cached public content may remain until local cleanup.


394. Profile Integration

Part 84.


395. Explicit topic preferences may sync encrypted.


396. Local behavioral preference remains local.


397. Contact Integration

Part 85.


398. Contacts may be feed sources.


399. Contact relationship does not imply follow/subscription.


400. Hard rule.


401. Social Space Integration

Part 86.


402. Joined space can auto-subscribe only if space policy/user setting says.


403. User can mute.


404. Group membership and feed subscription remain separate.


405. Hard rule.


406. Authorization Integration

Part 81.


407. Candidate eligibility checked before ranking.


408. Ranking cannot grant access.


409. Hard rule.


410. Authentication Integration

Part 82.


411. Public discovery may be unauthenticated.


412. Managed feed requires org auth.


413. Feed token not auth token.


414. Hard rule.


415. Edge Integration

Part 78.


416. Public feed APIs L7.


417. Private content remains E2EE.


418. WAF does not inspect encrypted private content.


419. Internal Service Integration

Part 79.


420. Feed services use workload identity/mTLS.


421. Secrets Integration

Part 80.


422. Publisher signing keys scoped.


423. No global feed signing secret.


424. Event Bus Integration

Part 75.


425. Publication events may feed public index/trend aggregation.


426. No user interaction event stream.


427. Hard rule.


428. Database Integration

Part 74.


429. Public content index separate from private subscription state.


430. No central table:

user_id, viewed_item_id, dwell_time

431. Hard rule.


432. Storage Model

Client:

subscriptions
timeline cache
local ranking state
saved items
optional read state

Server:

public content
public discovery metadata
aggregate trends

433. No Global Behavioral Store.


434. Search Integration

Part 32.


435. Private feed search local.


436. Public feed search public index.


437. No private index upload.


438. Hard rule.


439. Content Portability

Export subscriptions/saved items.


440. Exclude behavioral state by default.


441. Recommendation model state optional local export.


442. No hidden cloud profile to export.


443. Hard rule.


444. Backup

Subscriptions and explicit preferences can be backed up.


445. Local behavior model optional/rebuildable.


446. Read state optional.


447. No server restoring revoked/deleted source.


448. Hard rule.


449. Deletion

Source delete/retract propagated.


450. Cached copies may persist according to retention/public archive.


451. No claim universal erasure.


452. Hard truth.


453. Trend Privacy

Aggregate counters retention short.


454. No indefinite raw trend event history.


455. Hard rule.


456. Trend Input Event

#![allow(unused)]
fn main() {
pub struct PublicTrendEvent {
    pub content: PublicContentRef,
    pub event_class: PublicTrendEventClass,
    pub coarse_epoch: TrendEpoch,
}
}

457. No user ID.


458. Trend Event Class

#![allow(unused)]
fn main() {
pub enum PublicTrendEventClass {
    View,
    Reaction,
    Reshare,
    Subscribe,
}
}

459. Dedup Abuse

Need approximate anonymous controls.


460. Could use scoped rate token/ephemeral source bucket.


461. No permanent identity.


462. Hard rule.


463. Trend Aggregation Windows

hourly
daily
weekly

464. No second-by-second public user behavior.


465. Hard rule.


466. Curated Lists

Human/admin curated.


467. Curator identity scoped.


468. Transparency.


469. No hidden sponsored insertion without explicit label if product adds monetization later.


470. Feed Policy separates organic/curated.


471. Monetization Not Core

Part 54 economics separate.


472. Crate Layout

Recommended:

crates/
├── siar-feed-core/
├── siar-subscription/
├── siar-timeline/
├── siar-feed-candidate/
├── siar-feed-ranking/
├── siar-feed-recommendation/
├── siar-public-discovery/
├── siar-trending/
├── siar-feed-federation/
├── siar-feed-observability/
└── siar-feed-testkit/

473. siar-feed-core

Owns:

feed IDs
modes
errors

474. siar-subscription

Subscription state/capabilities.


475. siar-timeline

Cursor/pagination/local merge.


476. siar-feed-candidate

Candidate eligibility.


477. siar-feed-ranking

Chronological/local/curated rankers.


478. siar-feed-recommendation

Local explicit-topic recommendation.


479. siar-public-discovery

Public search/listing.


480. siar-trending

Thresholded aggregate trend signals.


481. siar-feed-federation

Remote feed ingestion.


482. siar-feed-observability

Aggregate pipeline metrics only.


483. siar-feed-testkit

ranking/privacy/federation/trend tests.


484. Error Taxonomy

#![allow(unused)]
fn main() {
pub enum FeedError {
    SourceNotFound,
    SubscriptionDenied,
    ContentUnavailable,
    ContentNotAuthorized,
    CursorExpired,
    RankingUnavailable,
    RecommendationDisabled,
    DiscoveryDenied,
    FederationUnavailable,
    SourceBlocked,
    Internal,
}
}

485. Testing

Need feed/discovery testkit.


486. Test Scenarios

chronological mode
subscription mode
local recommendation
trend aggregation
source block

487. Chronological Test

Order deterministic.


488. Ranking Failure Test

Fallback chronological.


489. Recommendation Disabled Test

No recommended candidates.


490. Local History Test

Signal never leaves device.


491. Subscription Privacy Test

Creator cannot enumerate subscribers.


492. Read-State Test

Not synced unless opt-in.


493. Viewer Privacy Test

No individual viewer list.


494. Trending Test

Minimum bucket required.


495. Manipulation Test

Rate limits/source diversity.


496. Private Content Test

Never enters public discovery.


497. Moderation Test

Removed content excluded but moderation != ranking.


498. Contact Test

Contact relationship does not auto-follow.


499. Group Test

Group membership and feed subscription separate.


500. Federation Test

Remote domain receives no subscriber identity.


501. Managed Feed Test

Org pin affects managed profile only.


502. Deletion Test

Retracted/deleted source not resurrected by stale cache.


503. Telemetry Test

No per-user interest vector/log.


504. Fuzzing

Fuzz:

feed cursor
discovery result
subscription envelope
trend event
federated feed envelope

505. Property Tests

Properties:

unauthorized candidate can never enter ranked timeline
chronological mode never invokes behavioral ranker
disabled recommendation produces no recommendation items
private content never appears in public discovery

506. Formal Verification Targets

Strong candidates:

candidate eligibility before ranking
subscription state
trend threshold privacy
federated content scope

507. Kani Candidate

ranking eligibility/filter order.


508. TLA+ Candidate

publication/retraction/cache/federation propagation.


509. Loom Candidate

concurrent subscription update + timeline refresh + source block.


510. Performance

Timeline hot path.


511. Candidate set bounded.


512. Ranking local/in-memory.


513. No remote ML inference.


514. Pagination.


515. Media lazy load.


516. Public search indexed.


517. Trend aggregate async.


518. No per-scroll server event.


519. Hard rule.


520. Timeline Cache

Bounded by:

item count
bytes
age

521. Eviction local.


522. No infinite scroll storage.


523. Content blobs separate.


524. Previews bounded.


525. Source Fairness

One source cannot monopolize queue/cache.


526. Local scheduling.


527. No server per-user fairness profile.


528. Security, Privacy & Correctness Invariants

Mandatory:

1. Chronological/subscription-only feed modes remain available and cannot be silently replaced by opaque behavioral ranking.
2. Private/member-scoped content is filtered for authorization before ranking and can never appear in public discovery.
3. User behavioral signals, read sequences, dwell time, scroll behavior, and local interest models remain local by default and are not uploaded as centralized behavioral profiles.
4. Subscriptions do not expose subscriber identities to creators or public APIs by default.
5. Public trending and creator analytics use thresholded aggregate signals without individual viewer/subscriber identities.
6. Ranking decisions are explainable through explicit reasons such as follow, topic, curation, or public trend.
7. Recommendation systems are optional, resettable, local-first, and never required for basic feed usability.
8. Managed/enterprise feeds affect only managed profiles and cannot inspect or reorder unrelated personal feeds by default.
9. Federation transports public/federated content and capabilities without creating a cross-domain user-interest or subscriber graph.
10. Ranking state, moderation state, and authorization state remain separate; ranking cannot grant access or silently substitute for moderation.
11. Feed telemetry contains pipeline/service metrics only and never becomes a per-user interest vector, view history, or engagement timeline.
12. Deleted/retracted/blocked content and sources cannot be resurrected into active timelines by stale caches, backups, or federated replicas.

529. Initial Production Scope

Implement first:

typed FeedSource/FeedItem/Subscription
chronological feed
subscription-only feed
local merge/pagination
mute/block/pin controls
explicit topic preferences
local heuristic ranking
recommendations opt-in
public discovery
aggregate thresholded trending
creator subscriber-count buckets
local-only read state by default
encrypted subscription sync
federated public-feed ingestion
managed feed isolation
privacy-safe metrics
feed testkit

Then add:

on-device recommendation model
privacy-preserving aggregate recommendation research
cross-provider feed portability
advanced public trend robustness
local diversity-aware ranking
formal feed/privacy verification

530. Definition of Done

Part 87 is complete when:

  • subscription/chronological feeds work without recommendation infrastructure
  • feed candidates are authorized before ranking
  • ranking modes are explicit and user-controlled
  • behavioral personalization stays local by default
  • subscriptions do not reveal subscriber identities
  • public analytics/trending use minimum aggregate thresholds
  • creator insights do not expose viewer identities
  • private/public feed search boundaries are explicit
  • managed and personal feeds remain separate
  • federation does not create cross-domain interest graphs
  • stale caches cannot resurrect removed/deleted content
  • telemetry excludes per-user engagement profiles
  • ranking/privacy/trend/federation/fuzz/formal tests are specified

531. Final Architecture

            SUBSCRIPTIONS / PUBLIC SOURCES
                         │
                         ▼
                 CANDIDATE COLLECTION
                         │
                         ▼
               AUTHORIZATION / PRIVACY
                         │
                         ▼
            CHRONOLOGICAL / LOCAL RANKING
                         │
                         ▼
                      TIMELINE
                         │
                ┌────────┼────────┐
                │        │        │
              SAVE      MUTE    SUBSCRIBE
                │        │        │
                └────────┼────────┘
                         ▼
                  LOCAL USER STATE

Feed safety model:

explicit subscriptions
+
authorization before ranking
+
chronological fallback
+
local personalization
+
thresholded public trends
+
subscriber/viewer privacy
+
no behavioral cloud profile

not:

record every interaction, build a hidden psychographic profile, and rank content to maximize time-on-screen

532. Final Principle

A feed should help users organize and discover content according to explicit intent without requiring the platform to know what keeps each person scrolling.

The correct model is:

follow explicitly
+
rank locally
+
recommend optionally
+
aggregate publicly only when privacy-safe
+
keep subscriber/viewer identities hidden
+
separate moderation from ranking
+
never centralize behavioral profiles

This architecture gives SIAR a privacy-preserving foundation for timelines, subscriptions, recommendations, trending, discovery, public channels, creators, federated feeds, and managed announcements while preserving the anonymity, local-first, least-authority, and social-graph privacy guarantees established across Parts 34–86.