Repository navigation
Open
Labels
queue/parkedQueue task is parked (waiting on CI, time, or an event)Queue task is parked (waiting on CI, time, or an event)status/parkedDeliberately paused with a recorded resume conditionDeliberately paused with a recorded resume conditiontask/triageQueue packet kind: verify, reproduce, and route this itemQueue packet kind: verify, reproduce, and route this itemwork/assignedQueue worker lifecycle stateQueue worker lifecycle state
Description
Design: recommendations for ID — similar objects and similar users, across all object types
Extends #5675 (querying / discovery). Related: #5677 (notes / boards / multiplayer editing), #5678 (knowledge layer), #5683 (residency & boundaries — sensitivity rules below lean on it), #5669 (staging tier — computation placement).
The gap
#5675 covers finding things in ID when you know what you're looking for (search, local and remote). It does not cover being shown things you didn't ask for: "worlds like this one", "documents people in your position read next", "users working on similar things". Search answers intent; recommendations create discovery. Drew (2026-11-04): file this for ID across all object types, not just worlds, and take similar-user view metrics into account.
Scope — all object types
The recommender treats every first-class ID object type uniformly:
- worlds, documents, notes, boards, chats / message threads, programs, and users themselves ("people working on similar things").
- Every recommendation is a typed edge:
(subject object, recommended object, signal, score, computed_at)— so any surface (a world's sidebar, a document's "read next", a home/discovery feed, a board's header) renders the same underlying data.
Signals (v1 is arithmetic, not a trained model)
- Item–item co-occurrence (Jaccard over interaction sets). Two objects are similar when the sets of users who viewed / joined / edited them overlap. Jaccard similarity over those sets is the score. This is the classic collaborative signal and needs no ML infrastructure — set arithmetic over interaction logs.
- User–user similarity ("similar users viewed"). Users are similar when their view / interaction histories overlap (Jaccard or cosine over each user's object-interaction set). A user's recommendations then include objects that similar users engaged with and the user has not seen. Drew's requirement (2026-11-04): this signal is in scope from v1, not a later phase — weighted alongside item–item, not replacing it.
- Content-based cold start. A new object has no interactions to overlap. Fall back to the embedding scan (the atlas machinery: dense cosine over descriptions / content) until interaction data accrues; a new user starts from content similarity of the objects they first touch. Cold-start edges are labeled with their signal so surfaces can present them differently if wanted.
Sensitivity rules (hard constraints, from #5683 / #5675)
- A recommendation never crosses a sensitivity boundary: an object is only ever recommended to users who could already access it. The recommender filters by the requester's visibility before ranking, not after.
- Similar-user metrics are computed only over interactions with objects visible to the requester. ("People like you read X" must never leak the existence of a private X, nor that a specific user read anything.)
- No per-user reading history is ever surfaced to another user — only aggregate similarity outcomes ("similar users viewed"), never identities or histories. An opt-out from contributing interaction data to similarity computation should exist and be cheap to honor.
Computation placement (staging tier pattern, #5669)
- Recommendations are computed periodically into tables, not per request: interaction aggregates accumulate in a staging DB; a batch pass computes similarity edges and promotes them into the core tier keyed by object, so reads are simple lookups.
- Recency decay: interactions age — a view from a year ago should weigh less than one from this week (decay function is an open question below).
- Recompute cost is bounded by the interaction graph's active slice, not the whole history.
Open questions for the design pass
- Decay + diversity: pure similarity collapses into an echo of what's already popular — what diversity / serendipity term keeps suggestions non-obvious? (At minimum: cap how many recommendations one very popular object can occupy.)
- Freshness vs stability: how often to recompute so suggestions feel alive without churning between visits?
- Feedback loop accounting: when a user follows a recommendation, that interaction itself becomes similarity data — how do we keep the system from amplifying its own suggestions into fake consensus?
- Evaluation: what do we measure — follow-through rate (clicked / joined / read), and against what baseline (recency-ordered, popularity-ordered)?
Non-goals for v1
- No trained ranking model / matrix factorization — revisit only if the arithmetic signals measurably plateau.
- No cross-server recommendation federation until id: design: Querying local and remote ID servers v1 #5675's remote querying settles its sensitivity story; v1 is per-server (or per-owner-data) only.
Metadata
Metadata
Assignees
Labels
queue/parkedQueue task is parked (waiting on CI, time, or an event)Queue task is parked (waiting on CI, time, or an event)status/parkedDeliberately paused with a recorded resume conditionDeliberately paused with a recorded resume conditiontask/triageQueue packet kind: verify, reproduce, and route this itemQueue packet kind: verify, reproduce, and route this itemwork/assignedQueue worker lifecycle stateQueue worker lifecycle state
Activity
developing-today commentedon Nov 5, 2026
CODE-1422
dezren39 commentedon Nov 5, 2026
🤖 Agent note · handed off
dezren39 commentedon Nov 5, 2026
🤖 Agent note · handed off
118 remaining items
dezren39 commentedon Nov 6, 2026
🤖 Agent note · handed off