The shared cache substrate for the async org: pipeline, db, framework, local, chat, flow.
Not a database. Not a sync engine. Typed cache entries, stable keys, stale-while-revalidate, singleflight, tag invalidation, and a small adapter contract (memory, file, IndexedDB) — with a deliberately tiny browser surface.
Status: pre-v1, spec-driven build. Nothing is published yet. The repo is being built to spec, ticket by ticket.
docs/spec.md canonical v1 spec (decision log D1–D14, contracts, milestones M0–M6)
tickets/ one file per unit of work — see tickets/README.mdThe workspace copy at ../_docs/cache/spec.md mirrors docs/spec.md; this repo's copy is canonical.
zero runtime dependencies
./browser + IndexedDB adapter ≤ 5 KB min+gzip
src/browser may not import src/server, src/build, or node:*
CacheEntry + CacheStoreAdapter are additive-only; frozen at end of M3
@async/cache imports no @async/* package — it is a dependency sink
Rule of Two: a capability enters core only when two consumers need
identical semanticssrc/
core/ entry, key, freshness, errors, events
server/ createCache, getOrLoad, invalidate, http handlers
browser/ createBrowserCache, compact stored shape
build/ keygen, manifest emit
adapters/
memory/
file/ node-only, blobs
indexeddb/ browser-only
test/
train.json consumer repos for the train gateExports: . (server), ./browser, ./build, ./adapters/*, plus optional ./browser/broadcast and ./browser/debug.
Node ≥ 24, TypeScript strict, ESM only, vitest. fake-indexeddb for the IndexedDB adapter tests. No runtime deps — devDeps only.
- Pick the lowest-numbered
openticket whoseDependsare alldone(tickets/README.mdhas the order). - Read the spec sections the ticket lists before writing code.
- One ticket = one PR. Check every acceptance box; flip
Status: open→donein the ticket file inside the same PR. - If implementation contradicts the spec, stop and update the spec (or file an ADR in
docs/adr/after the M3 freeze) — don't silently diverge.
Weekly dependency train to all consumers, gated by reverse-dependency CI (train.json + M0-03 workflow): pack the RC, run every consumer's own test suite against it, any red = no publish. Spec §15.
The local train-gate dry run is:
npm run train:gate -- --dry-runConsumers that do not yet declare @async/cache are reported as skipped until their migration tickets land.