Skip to content

feat: centrality "Rediscover" strip over the entity graph (P13e-2)#149

Open
blokzdev wants to merge 1 commit into
mainfrom
claude/p13e2-rediscover
Open

feat: centrality "Rediscover" strip over the entity graph (P13e-2)#149
blokzdev wants to merge 1 commit into
mainfrom
claude/p13e2-rediscover

Conversation

@blokzdev
Copy link
Copy Markdown
Owner

@blokzdev blokzdev commented Jun 3, 2026

P13e-2 — Centrality "Rediscover"

Second PR of P13e. Resurfaces central-but-stale items — well-connected in the library's web yet not opened in a while — as a "Rediscover" strip on the Dashboard and Library.

Every-device (graph only, no embedder), reusing P13e-1's Cozo pulls. No schema change, no deps.

Algorithm

PageRank, not betweenness: betweenness is O(V·E) — too costly for a query-time strip, and more apt for e-3's path/bridge work (deferred to BACKLOG). PageRank is a cheap, deterministic power iteration that ranks "how woven into the library is this item."

How it works

  • centrality.dart (new, pure — sits beside community_clustering.dart)buildItemGraph(...) builds a weighted undirected item↔item adjacency from the entity graph (each shared uploader/playlist/tag bucket +1, each co-download edge +1; over-generic buckets dropped, the e-1 rule); pageRank(...) is deterministic weighted power iteration with dangling-mass redistribution.
  • GraphQueryService.itemCentrality()id → score over the entity graph; reuses entityMembershipScript()/coDownloadPairsScript() (decode shared with communityClusters via a new private _entityGraph() helper). {} when the store is unavailable.
  • rediscover.dart (new, pure)rankRediscover: score = centrality × staleness, where staleness grows with days since last touch (lastAccessedAt ?? createdAt, capped at 30d); items touched within 14 days are excluded so it never echoes "Recently opened". Top 12, deterministic ordering.
  • rediscoverProvider hydrates the scored ids from Drift + ranks them; RediscoverRow (mirrors RecentMediaRow, auto-hides when empty) renders the strip on the Dashboard (below "Recently opened") and atop the Library (only when not searching/filtering/selecting, so it never intrudes).

Tests (CI; native Cozo is APK-verified)

  • centrality_test — weight accumulation across shared buckets + co-download, bucket pruning, hub outranks leaf, determinism, dangling-node safety.
  • graph_query_service_testitemCentrality() decode + {} when unavailable.
  • rediscover_testrankRediscover: fresh-exclusion, staleness lifting an older item over a more-central recent one, cap, skip-unknown, empty.
  • rediscover_provider_test — fake graph + in-memory Drift (mixed fresh/stale) → central-but-stale items, excluding the freshly-opened one; [] when unavailable.
  • rediscover_row_test — renders header + tiles; hidden when empty.
  • Full suite green (909 tests), dart format + flutter analyze clean.

Docs

  • P13-PLAN.md — e-2 [~] + as-built; GRAPH-SPEC.md §7 — centrality row realized at e-2 (PageRank × staleness; betweenness deferred); VERIFICATION.md — P13e-2 checklist; BACKLOG.md — betweenness, shared item-graph builder extraction, tuning/"See all".

Verification

  • ✅ CI gates green locally (format · analyze · 909 tests).
  • APK spot-check owed (native Cozo): the Rediscover strip surfaces sensible central-but-stale items on Dashboard + Library for an established library, excludes recently-opened items, hides on a fresh library / while filtering / when the graph is off, and works on a low-end device.

Next: e-3 path/bridge discovery + graph-view polish — closes P13e.

https://claude.ai/code/session_013JoYmLCosYt5tQ8qwdbL1T


Generated by Claude Code

Resurface central-but-stale library items — woven into the library's web yet
not opened lately — as a "Rediscover" strip on the Dashboard and Library.
Pure-Dart PageRank over the entity item-graph (shared uploader/playlist/tag +
co-download, reusing P13e-1's Cozo pulls) scored by staleness (days since last
touch, excluding items opened in the last ~2 weeks). Every-device (graph only,
no embedder). The strip auto-hides on small/new libraries, while
searching/filtering, and when the graph is unavailable. No schema, no deps.

https://claude.ai/code/session_013JoYmLCosYt5tQ8qwdbL1T
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.

2 participants