version.js (9/9).platform.js (20/20).view.js (11/11).nav.js,
routes are a parser-printer parse.js (18+12).parse.js (parse ↔ print laws).ledger.js (12/12), fairness laws.assistant.js + llm.js (8/8),
senses (LLM/speech) modeled as dependencies.pear.live.js (4/4): REAL hypercore
replication proven; DHT discovery needs a UDP host.pay.js (10/10): a charge is a
side-effect behind a pay dependency; verified
webhooks mint via the ledger.solana/…/ledger.solana.rs +
canonical Anchor localnet test; the on-chain twin of
ledger.js. Builds/runs on a normal toolchain host.Total: 123 checks green (119 core + 4 Pear).
sync.js) but not wired into a running host;
keep the admin token server-side. Pear needs a
UDP-capable box to discover peers.pay.stripe.md), OR go
Solana-first and let wallets pay the program directly
(no server). x402/Cloudflare is a later fiat option —
VERIFY its docs before building.Every event carries a v (schema version). The rules that fold a given
version live behind a version→handler map. Enforced SemVer
(Semantic Versioning):
package.json#version is the single source of truth for “current
version”.1 up to current. Missing one = build error, not a
runtime surprise.package.json is more than a minor bump above what the code
can handle, that is also a build error (you skipped a migration).migrate(event) chain upgrades an old event to the current shape
before evolve sees it, so replay of an ancient log still folds.
Peers exchange their version; the lower version drives until both
upgrade. Write this as a small, well-tested module — it is the spine of
long-lived logs.Model the runtime as a recursive tree of type → subtype → … → leaf,
declared as data, not if ladders. Sketch:
platform:
web: [ react, svelte, plain-html ] # by transitive deps
serverless: [ cloudflare-worker, gcp, firebase-fn ]
runtime: [ node, bun, deno ]
native: [ react-native ]
Each leaf declares its capabilities (can it run @instantdb/admin? a
Holepunch swarm? only memory?). platform.js today is the flat first
draft; promote it to this declarative tree and derive recommend()
from the leaf’s capabilities. ENUM here means a closed, exhaustive
set — the compiler/tests should fail if a leaf is unhandled.
Goal: render the same store-state to three targets from one source.
Path forward: the ascii kits (ui.js, store-ui.js) already prove
state → view-tree → string. Generalize the middle: components return a
neutral view node ({ kind, props, children }), and three thin
backends walk it — toAscii, toReact, toReactNative. That neutral
node IS the DSL (Domain-Specific Language); start it minimal (box, text,
row, button) and grow only as screens demand.
Right now the arcade shell holds nav and settings as plain vars.
Promote them into a real archetype whose state includes the current
screen, addressable by URI: aces://<user>/device/<id>/screen. A
setting (glyph size, sound) becomes folded state, so it syncs and
replays like everything else. The arcade HTML is the throwaway sketch of
this.
Build each to SPEC.md with InstantDB sync: Notes (folders/files, nesting, tags), Reminders (lists, nesting, tags). Skip Photos and the web browser for now; calculator is done. KEY shared design: tags are a first-class cross-app entity — a tag applied in Notes is the same tag seen in Reminders. Model tags once, link many. Build the shared tag/entity schema FIRST, then the apps, so they stay consistent. Good candidates for parallel subagents once the shared schema exists.
Extend the store archetype to host and sell things. “Cloudflare’s new payment protocol” — likely agentic HTTP-402 (x402). VERIFY current details against the docs before building; do not assume.
getadb.com/provision/<uuid> (fresh UUID
each time), then inject instantAdminSync({appId, adminToken}).
UUID = Universally Unique Identifier.pearSync to a real hypercore + hyperswarm on
node/bun. multisync.combineSync([...]) already fans writes to both
with per-backend timeouts and dedups reads — that stays unchanged.