Repository navigation
Derive community listing icons from the package's published commit - #725
Conversation
Community icon URLs and caches were keyed only by the listing's pinned snapshot commit, so publishing updated community-icon.* files on a saved package never became visible: the listing kept serving the icon derived from the old pinned commit (30-day KV descriptor + R2 asset + 1h HTTP cache all keyed by the stale commit). Listing reads now join entity_sources so each listing carries an iconCommit (the owner package's current published commit, falling back to the pinned commit when the source row is gone). Icon URLs embed the icon commit, descriptors and R2 assets are keyed by it, and the icon route serves the icon commit or the pinned commit and 404s anything else. Package publish prunes superseded icon cache entries by listing prefix and invalidates the public listing data cache; republish, unpublish, hard delete, and account deletion clean up both commits.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
✅ Files skipped from review due to trivial changes (1)
📝 WalkthroughWalkthroughCommunity listing icons now use the package’s current published commit or pinned snapshot commit for URL generation, cache keys, asset storage, validation, cleanup, account deletion, and publish-time refresh. Documentation and tests reflect the updated behavior. ChangesCommunity icon commit flow
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant Publisher as Package publisher
participant Projection as Package projection
participant IconRefresh as Icon refresh
participant Cache as Community icon cache
Publisher->>Projection: finalize published package source
Projection-->>Publisher: projection refresh succeeds
Publisher->>IconRefresh: refresh community icon
IconRefresh->>Cache: remove superseded icon revisions
IconRefresh-->>Publisher: publish continues
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
🔎 Preview deployed: https://kody-pr-725.kody-a99.workers.dev Worker: Mocks:
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/use/community-packages.md`:
- Around line 53-58: Update the icon URL documentation to state that URLs use
the package’s current published commit when source is available, but fall back
to the pinned commit when the package source is unavailable. Preserve the
existing guidance about icon priority and removing superseded files.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: e2d1c917-36e8-4d0c-b545-aa9a2c504139
📒 Files selected for processing (25)
docs/contributing/architecture/data-storage.mddocs/contributing/architecture/primitives.yamldocs/contributing/community-packages.mddocs/guides/package-authoring.mddocs/use/community-packages.mdpackages/worker/src/app/account-deletion.node.test.tspackages/worker/src/app/account-deletion.tspackages/worker/src/app/community-public.tspackages/worker/src/app/handlers/community-detail.frame.node.test.tspackages/worker/src/app/handlers/community-icon.node.test.tspackages/worker/src/app/handlers/community-icon.tspackages/worker/src/app/handlers/community.frame.node.test.tspackages/worker/src/app/handlers/community.node.test.tspackages/worker/src/app/routes.tspackages/worker/src/app/ssr-render.node.test.tspackages/worker/src/community/community-icon.node.test.tspackages/worker/src/community/community-icon.tspackages/worker/src/community/community-icon.workers.test.tspackages/worker/src/community/community-service.node.test.tspackages/worker/src/community/repo.tspackages/worker/src/community/service.tspackages/worker/src/community/types.tspackages/worker/src/repo/artifact-file.tspackages/worker/src/repo/external-publish.node.test.tspackages/worker/src/repo/external-publish.ts
Problem
Publishing updated
community-icon.*files on a saved package (e.g. viapackage_publish_external_push) never became visible on the public community pages. Confirmed in production forkit,hydrawise,transistor,venstar, andgoogle: the packages' Artifacts HEAD carried the new icons (published 2026-07-11 05:34 UTC), while/community/:listingIdkept serving icons for the pinned commit from 2026-07-10.Root cause: community icon URLs, KV descriptors (~30-day TTL), and R2 assets were all keyed by the listing's pinned snapshot commit, which only moves on an explicit
community_publish. A package publish updatedentity_sources.published_commitbut nothing about the listing icon, so every cache layer kept the stale key alive indefinitely — shorter TTLs would not have fixed this, since the URL itself never changed.Fix
The listing icon now tracks an icon commit: the owner package's current published commit, falling back to the pinned commit when the package source row is gone.
LEFT JOIN entity_sources(scoped to owner + package) and exposeiconCommitonCommunityListingRecord./community/:listingId/icon/:iconCommit; KV descriptors and R2 assets are keyed by the same commit, so a package publish busts every cache layer by key change (content identity, not TTL).community-icon.*from the Artifacts repo at the icon commit via a newreadFirstArtifactFileAtCommit(one shallow fetch, candidate paths probed in priority order); pinned-commit requests keep the snapshot fast path for SVGs.finalizePublishedEntitySource(external push + repo-session publish lanes) calls a new best-effortrefreshCommunityIconForPackagePublish: prunes superseded KV/R2 icon entries by listing prefix and invalidates the public listing data cache.Note for the affected packages:
kit,hydrawise, andtransistoraddedcommunity-icon.pngwhile leaving the oldcommunity-icon.svgin place — svg wins by documented priority, so those repos also need the stale svg deleted (handled as post-deploy verification, not in this PR). Docs now warn about this trap.Testing
npm run validategreen locally (format, lint, typecheck, 809 unit tests, 13 Playwright E2E, MCP E2E), re-ran unit suite after rebasing ontomain.System recap — extends existing primitives (medium risk)
Mode: recap · Base:
main@ff425827· Head:2b919149Classification: extends — the community listing read model and icon cache contract change shape (icon commit joins the package source); no new primitives.
Primitives touched
community-listingsentity_sources; icon route param is the icon commitcommunity-assets-r2bundle-artifacts-kvartifacts-reposreadFirstArtifactFileAtCommitprobes icon paths in one fetchrepo-sessionsaccount-exportSystem map
A package publish flows through the publish finalizer into the community icon cache, and public listing reads now join the package source to build icon URLs.
Legend: green = composes (wiring only) · amber = extended by this PR · red = new primitive · gray = context (unchanged, included only when an edge crosses it).
flowchart LR repoSessions["repo-sessions<br/>Repo-backed editing sessions"]:::touched communityListings["community-listings<br/>Community package listings"]:::extended communityAssetsR2["community-assets-r2<br/>Community asset storage (R2)"]:::extended bundleArtifactsKv["bundle-artifacts-kv<br/>Bundle artifacts KV"]:::touched artifactsRepos["artifacts-repos<br/>Artifacts source repos"]:::touched d1AppDb["d1-app-db<br/>D1 app database"]:::untouched repoSessions -->|"finalizePublishedEntitySource → refreshCommunityIconForPackagePublish"| communityListings communityListings -->|"LEFT JOIN entity_sources.published_commit AS iconCommit"| d1AppDb communityListings -->|"prune + write community-icon:v1/{listingId}/{commit}/asset"| communityAssetsR2 communityListings -->|"descriptor derived-cache:v1:community-icon:v1:{listingId}:{commit}"| bundleArtifactsKv communityListings -->|"readFirstArtifactFileAtCommit(community-icon.*) @ iconCommit"| artifactsRepos classDef touched fill:#1a7f37,color:#fff classDef extended fill:#9a6700,color:#fff classDef added fill:#cf222e,color:#fff classDef untouched fill:#57606a,color:#fffBefore / after
Invariants
Per-user isolation: the
entity_sourcesjoin is constrained to the listing'sowner_user_id,entity_kind = 'package', andpackage_id, so a foreign source row can never contribute a commit (or icon bytes) to another user's listing. The icon read path keeps the existing owner/package/source validation before touching the Artifacts repo.Summary by CodeRabbit