Skip to content

feat: tag-affinity recommendation engine#1803

Draft
MrDirkelz wants to merge 1 commit into
mainfrom
app-cms-api-shared-suggest-recommendation-engine
Draft

feat: tag-affinity recommendation engine#1803
MrDirkelz wants to merge 1 commit into
mainfrom
app-cms-api-shared-suggest-recommendation-engine

Conversation

@MrDirkelz

Copy link
Copy Markdown
Collaborator

Adds a per-user recommendation profile built on existing FTS/tag infra instead of a new ML system or second database. A client-authoritative affinity map (tag id -> decayed score) drives a hybridQuery over parentTags, ranked by tag-overlap with a seam for FTS+RRF fusion later.

Cross-device sync of a per-user-private doc has no home in Luminary's group-only permission model, so UserAffinity is delivered out-of-band: authIdentity attaches the caller's own doc to JwtUserDetails, shipped via the existing clientConfig socket payload (like accessMap). It is excluded from /query and the socket update fan-out (same containment as the internal Crypto doctype) and never gets a sync design doc, so it scales by doc count with zero fan-out. Writes are owner-only (id derived from userId) and ride the existing localChanges -> /changerequest drain, with the working copy kept in localStorage (not Dexie docs) so deleteRevoked can't purge it.

Signal weighting distinguishes a passive open from stronger, more deliberate engagement: bookmarking, finishing a video/audio track, and highlighting a passage all weight the profile more than merely opening content.

Adds a per-user recommendation profile built on existing FTS/tag infra
instead of a new ML system or second database. A client-authoritative
affinity map (tag id -> decayed score) drives a hybridQuery over
parentTags, ranked by tag-overlap with a seam for FTS+RRF fusion later.

Cross-device sync of a per-user-private doc has no home in Luminary's
group-only permission model, so UserAffinity is delivered out-of-band:
authIdentity attaches the caller's own doc to JwtUserDetails, shipped
via the existing clientConfig socket payload (like accessMap). It is
excluded from /query and the socket update fan-out (same containment
as the internal Crypto doctype) and never gets a sync design doc, so
it scales by doc count with zero fan-out. Writes are owner-only
(id derived from userId) and ride the existing localChanges ->
/changerequest drain, with the working copy kept in localStorage
(not Dexie docs) so deleteRevoked can't purge it.

Signal weighting distinguishes a passive open from stronger, more
deliberate engagement: bookmarking, finishing a video/audio track, and
highlighting a passage all weight the profile more than merely
opening content.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant