Fix #200: deleted repos vanish from explore #202

Merged
crueber merged 1 commit from fix/issue-200 into main 2026-09-08 16:50:51 +00:00
Owner

Fixes #200. A deleted repo kept showing in /explore because of THREE stacked layers (all fixed here):

Layer 1 — backend listing (ROOT CAUSE): repoRegistry.Repos/Owners (cmd/walhub/serve.go) did a RAW prefix listing. Registry.Delete sweeps every listed object, but the filesystem CAS .lock sidecars persist BY DESIGN (invisible to List, yet their directory keeps the name behind ListPrefixes). Reproduced live: after DELETE, manifest.pb gone but manifest.pb.lock + social.json.lock remain \u2192 GET /api/v1/owners/ghost/repos\u2192["demo"] with summary 404. Fix: listings are MANIFEST-gated (parallel Heads, limit 8, mirroring wal.refreshList; fail-closed like it). This also hides unborn fork-provisioned prefixes (#150, still tolerated row-side as a race). Exists/create/delete were already manifest-gated \u2192 re-create/re-import after delete sees a clean name (verified: PUT\u2192201, push works).

Layer 2 — browser HTTP cache: the endpoints answer SWR (max-age=0, stale-while-revalidate=60), so Chrome served the pre-delete list up to 60s (reproduced: server returned [] while the page still rendered the row). Fix: SDK owners.list()/repos() always send cache: no-store (web/sdk/src/core.js); data-layer 5s TTL still bounds repeats.

Layer 3 — app cache: delete/import now invalidate owners + repos:{owner} (+ repo keys on delete); repo shell renders 'repository not found' on 404 summary instead of 'loading\u2026' forever.

Tests: new Go tests (TestRepoRegistryHidesManifestlessPrefixes/UnknownOwnerEmpty/DeleteVanishesAndRecreates), new node pin (listings no-store); go vet + go test ./cmd/walhub clean; node suite 396 pass (smoke.test.js excluded: hangs fetching :8080 in isolation too, pre-existing env flake, file untouched). Browser (headless CDP): full UI delete\u2192/explore empty immediately, re-create\u2192row back, dark+light, no app errors. Docs 07 \u00a714 + 12 decisions appended. No new deps.

Fixes #200. A deleted repo kept showing in /explore because of THREE stacked layers (all fixed here): **Layer 1 — backend listing (ROOT CAUSE):** `repoRegistry.Repos/Owners` (cmd/walhub/serve.go) did a RAW prefix listing. `Registry.Delete` sweeps every listed object, but the filesystem CAS `.lock` sidecars persist BY DESIGN (invisible to `List`, yet their directory keeps the name behind `ListPrefixes`). Reproduced live: after DELETE, `manifest.pb` gone but `manifest.pb.lock` + `social.json.lock` remain \u2192 `GET /api/v1/owners/ghost/repos\u2192["demo"]` with summary 404. Fix: listings are MANIFEST-gated (parallel Heads, limit 8, mirroring `wal.refreshList`; fail-closed like it). This also hides unborn fork-provisioned prefixes (#150, still tolerated row-side as a race). `Exists`/create/delete were already manifest-gated \u2192 re-create/re-import after delete sees a clean name (verified: PUT\u2192201, push works). **Layer 2 — browser HTTP cache:** the endpoints answer SWR (`max-age=0, stale-while-revalidate=60`), so Chrome served the pre-delete list up to 60s (reproduced: server returned `[]` while the page still rendered the row). Fix: SDK `owners.list()/repos()` always send `cache: no-store` (web/sdk/src/core.js); data-layer 5s TTL still bounds repeats. **Layer 3 — app cache:** delete/import now invalidate `owners` + `repos:{owner}` (+ repo keys on delete); repo shell renders 'repository not found' on 404 summary instead of 'loading\u2026' forever. Tests: new Go tests (TestRepoRegistryHidesManifestlessPrefixes/UnknownOwnerEmpty/DeleteVanishesAndRecreates), new node pin (listings no-store); `go vet` + `go test ./cmd/walhub` clean; node suite 396 pass (smoke.test.js excluded: hangs fetching :8080 in isolation too, pre-existing env flake, file untouched). Browser (headless CDP): full UI delete\u2192/explore empty immediately, re-create\u2192row back, dark+light, no app errors. Docs 07 \u00a714 + 12 decisions appended. No new deps.
Owners/Repos listings now require manifest.pb (parallel Heads, limit 8):
delete sidecar litter (.lock persists by design) and unborn fork prefixes
no longer list. SDK owners.list/repos bypass the HTTP cache (SWR resurrected
deletes for 60s); delete/import invalidate listing keys; repo shell renders
not-found on 404 summary. Docs 07/12 decisions appended.
Sign in to join this conversation.
No description provided.