Status: decided (2026-07-24) · Supersedes the P3 discovery finding “two sources of truth”
Linked from:registry-index.md·docs/README.md· guides registry stack
Three writers touched two registry indexes:
RegistryClient (CLI/SDK) → R2 registry.json (canonical, etag-guarded)publishVersion, npmPublish) → public/registry/registry.json + local storage/ only, never R2Consequences observed during the alignment sweep: double-scoped r2Keys
(@factorywager/@factorywager/...), phantom versions (versions listed with no
release — removed 2026-07-24), fake seed checksums, divergent package sets per
consumer (portal reads file, Pages Functions read R2, monitoring reads file).
public/registry/registry.json is a generated snapshot, refreshed by
bun run factory:snapshot / ops:snapshot — never hand-edited, never a
write target for new writers.X-Registry-Lane: local-dev) and docs must not present them as the
production path.RegistryClient.publish (R2), then a
snapshot refresh. The Pages Functions stay read-only (405 for non-GET)
until an authenticated edge writer is deliberately designed.lib/registry/contracts.ts validateRegistryIndex (with the
versions↔releases invariant) is the guard: bun run integrity:check fails if
the snapshot and the invariant diverge.%40 + preserved /)
— fixed in f4aaafbf4.bun publish --registry https://registry.factory-wager.com
works must be corrected to name the local lane until the edge writer exists.RegistryClient.publish when R2 env is present
(single-writer consolidation).factory:snapshot merge/warn instead of blind overwrite when the file has
local-only packages.PUT in Pages Functions (design doc required — token scope,
replay protection, R2 write perms).docs/harness/tenants/remaining-work.md)Verified via SigV4 ListObjectsV2 against factory-wager-registry:
registry.json, 17 packages,
metadata + inline README), an ops-summary.json stub, and the channels/*
telegram event streams + consumer cursor. No storage/ artifact objects
exist — no publish has landed artifact bytes in R2 to date. What
bun install resolves (packuments + tarballs) is served from the committed
static mirror (public/registry/@factorywager/*). Decision 1 (“R2 is the
single source of truth … and artifacts”) stands for the index; the
storage/ artifact write plane is deferred until deliberately activated
(one real factory publish + verification), at which point this addendum is
removed.lib/factory/http-keys.ts) — channels/* keys can never be
served publicly; anonymous reads only get allowlisted keys. Split into a
dedicated channels bucket only if write-scope separation is ever required.registry-write.internal.factory-wager.com is retired. The documented
private publish plane was never provisioned (no DNS, no server). The surface
is status = "retired" in config/surfaces.toml; write origins remain the
local gateway (:3000, Bearer) and direct-to-R2 SigV4 (factory publish).channels/_probe/channel-plane.txt (leftover probe) was
deleted from the bucket 2026-07-28 (12 → 11 objects).