Add hosted catalog snapshot fallback#95877
Conversation
accc57e to
b1cb838
Compare
b1cb838 to
b486def
Compare
|
Codex review: needs maintainer review before merge. Reviewed June 27, 2026, 5:05 PM ET / 21:05 UTC. Summary PR surface: Source +157, Tests +302. Total +459 across 2 files. Reproducibility: not applicable. this is a feature PR, not a bug report. The relevant proof path is source inspection plus the PR body's copied live-output run showing hosted snapshot reuse after HTTP 304. Review metrics: 2 noteworthy metrics.
Stored data model Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Have maintainers review and either accept this loader-level snapshot trust contract before the persistence/config/CLI follow-ups, or hold it until they want the hosted marketplace stack evaluated together. Do we have a high-confidence way to reproduce the issue? Not applicable: this is a feature PR, not a bug report. The relevant proof path is source inspection plus the PR body's copied live-output run showing hosted snapshot reuse after HTTP 304. Is this the best way to solve the issue? Yes for the loader-level slice: the implementation is bounded to the hosted catalog loader and validates checksum, schema, expected pins, and request validators before using a snapshot. The merge decision still depends on maintainer acceptance of the remote snapshot trust contract. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 1b8b8500cee0. Label changesLabel justifications:
Evidence reviewedPR surface: Source +157, Tests +302. Total +459 across 2 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
68a85a8 to
be8678a
Compare
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
be8678a to
5f71635
Compare
|
@clawsweeper re-review Restacked after #95868 and pushed current proof at 5f71635. Please review the current head. |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
@clawsweeper re-review Added live guarded ClawHub snapshot proof to the PR body for current head 5f71635: first load writes a file-backed snapshot, second conditional load sends If-None-Match and returns source=hosted-snapshot after HTTP 304. |
|
Merged via squash.
Thanks @giodl73-repo! |
Merged via squash. Prepared head SHA: 5f71635 Co-authored-by: giodl73-repo <[email protected]> Co-authored-by: giodl73-repo <[email protected]> Reviewed-by: @giodl73-repo
Merged via squash. Prepared head SHA: 5f71635 Co-authored-by: giodl73-repo <[email protected]> Co-authored-by: giodl73-repo <[email protected]> Reviewed-by: @giodl73-repo
Merged via squash. Prepared head SHA: 5f71635 Co-authored-by: giodl73-repo <[email protected]> Co-authored-by: giodl73-repo <[email protected]> Reviewed-by: @giodl73-repo
Merged via squash. Prepared head SHA: 5f71635 Co-authored-by: giodl73-repo <[email protected]> Co-authored-by: giodl73-repo <[email protected]> Reviewed-by: @giodl73-repo
Hosted Marketplace Feed Stack
This is PR3 in the hosted marketplace feed stack. The stack should land in order, with maintainer review at each step before the later PRs wire hosted marketplace data into broader user flows.
marketplaces.feedsandmarketplaces.sourcesprofiles.openclaw plugins marketplace refreshas the explicit manual snapshot refresh path.openclaw plugins marketplace entriesas the explicit manual read path over hosted, snapshot, or bundled fallback entries.The broader follow-up after this stack is to decide whether and how marketplace entries should feed install/search/startup behavior, add automatic conditional refresh using
ETag/Last-Modified, or move to ClawHub producer-side validation for/v1/feeds/pluginsand/v1/feeds/skills.Journey Context
This is step 3 of the hosted OpenClaw feed path from RFC 19. #95846 made the bundled catalog feed-shaped. #95868 added guarded hosted fetch. This PR adds the last-known-good snapshot contract that makes the hosted path safe when the register endpoint is unchanged or temporarily unhealthy.
Current head
5f71635bbais restacked on main after #95868 merged.What This PR Does
HostedOfficialExternalPluginCatalogSnapshotStoreinterface.savedAtafter a successful hosted load.expectedSha256pinning for snapshots, so a stale cached body cannot satisfy a caller-pinned checksum it does not match.ETag/Last-Modifiedchanges.What This PR Intentionally Does Not Do
This PR does not choose a production persistence location, wire SQLite/runtime storage, enable the hosted loader by default, add source profiles, add auth, add signed envelopes, add regional feeds, or change search/install behavior. It defines the loader-level snapshot semantics that a later runtime-owned persistent store can bind to.
How To Review
Review this as fallback semantics, not as the final storage implementation. The key behavior is: hosted feed first, validated last-known-good snapshot second, bundled catalog last. A snapshot write failure is intentionally non-fatal because a good hosted response should still be usable even if cache persistence fails.
Validation
pnpm exec oxlint --deny-warnings src/plugins/official-external-plugin-catalog.ts src/plugins/official-external-plugin-catalog.test.tspnpm exec oxfmt --check src/plugins/official-external-plugin-catalog.ts src/plugins/official-external-plugin-catalog.test.tsgit diff --checkCI=1 node scripts/test-projects.mjs src/plugins/official-external-plugin-catalog.test.ts(33 tests)codex review --base origin/mainreported no actionable correctness issues.node --import tsx -source harness againsthttps://clawhub.ai/v1/feeds/pluginswith a file-backed snapshot store underC:\tmp\openclaw-feeds-proof\pr95877-live-snapshot.Real Behavior Proof
Behavior or issue addressed:
The hosted loader reuses a last-known-good hosted snapshot when a later hosted fetch cannot provide an acceptable fresh payload, while refusing stale snapshots when the caller supplied request validators that no longer match the snapshot metadata.
Real environment tested:
Windows checkout
C:\src\openclaw-prflow\.worktrees\pr-95877at head5f71635bba, live guarded HTTPS fetch tohttps://clawhub.ai/v1/feeds/plugins, and a file-backedHostedOfficialExternalPluginCatalogSnapshotStorewriting the exact snapshot body and metadata toC:\tmp\openclaw-feeds-proof\pr95877-live-snapshot\official-external-plugin-catalog.snapshot.json.Exact steps or command run after this patch:
pnpm exec oxlint --deny-warnings src/plugins/official-external-plugin-catalog.ts src/plugins/official-external-plugin-catalog.test.tspnpm exec oxfmt --check src/plugins/official-external-plugin-catalog.ts src/plugins/official-external-plugin-catalog.test.tsgit diff --checkCI=1 node scripts/test-projects.mjs src/plugins/official-external-plugin-catalog.test.tscodex review --base origin/mainnode --import tsx -with a source harness that:loadHostedOfficialExternalPluginCatalogEntries({ snapshotStore })against the live default feed,loadHostedOfficialExternalPluginCatalogEntries({ snapshotStore, ifNoneMatch: first.metadata.etag }), andsource: "hosted-snapshot"witherror: "hosted catalog feed returned HTTP 304".Evidence after fix:
Observed result after fix:
The live proof first loaded the ClawHub feed over the guarded hosted path and persisted a snapshot. The second load sent the returned live ETag as
If-None-Match, received HTTP 304 from the live service, validated the persisted snapshot metadata/body, and returnedsource: "hosted-snapshot"with the same 59-entryclawhub-officialsequence 16 feed.What was not tested:
This PR still does not test production SQLite persistence because that is the next PR in the stack. This proof uses a file-backed implementation of the snapshot-store interface to exercise the loader contract with the live hosted feed.