Keep no catalog on the box, and let cached icons expire - #420
Merged
Conversation
The brain no longer writes the catalog snapshot to disk. It holds one in memory, re-fetches it, and shows an empty store when it cannot reach the endpoint. Browsing a stale catalog was never the same as installing from it, since installing pulls images over the same network, and a box pinned to an old copy can offer a manifest the store no longer publishes. - remote.go: loadCache/cachePath/cacheFileName and the write-through in syncOnce are gone. RemoteOptions.CacheDir became AssetCacheDir, which is now what it says: proxied icons and screenshots only. - New MALMO_CATALOG_FILE seeds the store from a local snapshot for the dev and test lanes that have no control plane (make dev-app, both QEMU bootstraps). Read once, never written back; unset on a real box. - Assets keep their disk cache but expire after 24h. Filenames are stable per app, so without a TTL the first icon a box fetched was the icon it served forever. An expired asset whose refetch fails is served stale rather than broken. - testdata/snapshot.json is now synthetic: three hand-written fake apps covering the full key surface, replacing a copy of the published catalog. App artifacts are authored in malmoos/store and reach a box only through the published snapshot. A -update flag re-stamps the fixture digest after a shape edit. TestNoUnmodeledFields can no longer detect that the published shape moved, since both sides of the comparison now live here. Its doc comment and APP_STORE.md say so; that check belongs on the publish side. Docs: DECISIONS.md 2026-08-17 (flips part of 2026-07-02), APP_STORE.md, architecture.md, NEXT.md, CLAUDE.md, contributing.md, running-locally.md, authoring-apps-with-an-agent.md, progress/catalog-no-box-side-copy.md.
Confidence Score: 5/5The PR appears safe to merge because no blocking failure remains in the eligible follow-up scope. No blocking failure remains.
|
| Filename | Overview |
|---|---|
| internal/catalog/remote.go | Removes persistent snapshot caching, adds optional read-only seed loading, preserves last-good in-memory state across refresh failures, and introduces expiring asset caching with stale fallback. |
| cmd/brain/main.go | Renames catalog cache configuration around asset-only storage and wires the optional snapshot seed into the remote catalog. |
| internal/hostagent/brainlaunch/brainlaunch.go | Conditionally forwards the local catalog seed path into the brain container while retaining the same-path data-directory mount. |
| internal/catalog/remote_test.go | Covers seed loading, empty startup, refresh preservation, asset expiration, stale fallback, and concurrent fetch collapsing. |
| dev/test-qemu/bootstrap.sh | Replaces the air-gapped lane’s writable catalog cache seed with a read-only snapshot staged under the brain’s mounted data directory. |
| dev/cloud/test/bootstrap.sh | Updates the hosted boot-proof lane to stage and forward a read-only catalog snapshot for its offline app-install scenario. |
| internal/catalog/wire.go | Updates fixture-related wire validation support while retaining snapshot schema and digest verification. |
Reviews (2): Last reviewed commit: "Say which lanes actually seed a snapshot" | Re-trigger Greptile
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
The brain no longer writes the catalog snapshot to disk. It holds one in memory, re-fetches it, and shows an empty store when it cannot reach the endpoint. Browsing a stale catalog was never the same as installing from it, since installing pulls images over the same network, and a box pinned to an old copy can offer a manifest the store no longer publishes.
remote.go:loadCache/cachePath/cacheFileNameand the write-through insyncOnceare gone.RemoteOptions.CacheDirbecameAssetCacheDir, which is now what it says: proxied icons and screenshots only.MALMO_CATALOG_FILEseeds the store from a local snapshot for the dev and test lanes that have no control plane (make dev-app, both QEMU bootstraps). Read once, never written back; unset on a real box.testdata/snapshot.jsonis now synthetic: three hand-written fake apps covering the full key surface, replacing a copy of the published catalog. App artifacts are authored inmalmoos/storeand reach a box only through the published snapshot. A-updateflag re-stamps the fixture digest after a shape edit.Spec(s) touched
DECISIONS.md2026-08-17 (flips part of 2026-07-02),APP_STORE.md,architecture.md,NEXT.md, plusCLAUDE.md,contributing.md,running-locally.md,authoring-apps-with-an-agent.mdandprogress/catalog-no-box-side-copy.md.What was tested
make test-nopam,fmt-check,vet,openapi-checkgreen locally. On CI,CI / GoandCI / Cloud imageare both green on the branch — the cloud lane boots a real VM, so it exercisesMALMO_CATALOG_FILEon a booted box. New unit tests:TestRemoteKeepsNoSnapshotOnDisk,TestRemoteSnapshotFileSeed,TestRemoteSnapshotFileInvalid,TestRemoteAssetExpires,TestRemoteExpiredAssetSurvivesFailedRefresh.Known gaps & deviations
TestNoUnmodeledFieldscan no longer detect that the published shape moved, because both sides of the comparison now live in this repo. Its doc comment andAPP_STORE.mdsay so; that check belongs on the publish side.TestRemoteLastGoodFallback(the on-disk last-good cache) andTestVerifyRealSnapshot(the real published snapshot fixture, now synthetic).Closesline below has no number yet.Definition of done
make dev), and integration-tested against the real system if it touches one.make checkgreen (frontend changes:make check-webtoo).TestRemoteLastGoodFallbacktested the on-disk fallback this PR removes, andTestVerifyRealSnapshotverified a copy of the published catalog that no longer lives here. No test is newly skipped, and no new test is environment-gated.docs/progress/catalog-no-box-side-copy.md); indexes in both READMEs updated; Up-next re-ordered if needed.internal/catalog/wire.go) or the store views, said whether malmo's other store surface needs the same change (docs/specs/APP_STORE.md# What the box models, and what it drops).DECISIONS.mdentry if a locked decision flipped.#instead), no hard-wrapped markdown,log/slogonly, conventions perCLAUDE.md.dev, PR intodev.Closes #