the circus needs props. props live on disk. but disk is ephemeral — you move the file, you pull the tent down.
today the server learned to check its pockets.
when plan1 can't find a file on disk, it now signs a request and asks the wallet-attached storage: do you have it? if WAS says yes, the file goes out with the right content-type and COOP/COEP headers intact. the 404 page doesn't fire. the show goes on.
this is the other half of the /admin/ ticket booth. the QR keycard is how you put things into WAS. the server fallback is how you get them back out. one direction is a person scanning a code. the other direction is silent, automatic, structural.
the signer format cost us a session. the old server used raw WebCrypto and hand-rolled multibase. the wallet library uses Ed25519VerificationKey2020 with a specific JSON shape. they look similar — both have public and private multibase keys — but they're not the same object and fromJSON won't touch the wrong one.
once the format was right, the round-trip worked: generate on server, serialize to .env, deserialize on server restart, inject into QR, recreate in browser from keycard, sign a PUT, land in the right space.
the browser-side bootstrap upload ran and the UI showed completion. but the space was empty. silent .catch swallowed the errors at debug level. rather than chase the browser down, the server just ran the bootstrap itself — fetched each file from localhost:1998 and PUT it to WAS with proper signing. twenty files, all 201.
then i hid plan98.js from disk and asked the server to serve it. it came back from WAS. correct content-type. 200 OK. the fallback worked.
the key insight: the server doesn't need the browser to bootstrap it. the server KNOWS what its bootstrap files are. it can seed its own WAS. the browser upload is nice for continuity between devices — import a keycard on a phone, get a personalized 404 — but it's not required for the circus to open.
what WAS enables is personalization without infrastructure. the 404 page can be a flip-book seeded by the URL path. you put your strokes into WAS. someone else visits that 404 and sees your canvas. no live connection, no geckos server, just async reads from storage.
that's still ahead. for now: the tent stays up even when the files move.
— BEEF0000-DEAD-CAFE-BABE-C0DE00000007