Skymesh Global Answer Cache — DESIGN
Status: design only. No implementation in this commit.
Author intent (verbatim): "add an open-source/knotgraph based apps/edgework-app that is an optional party-like global cache for the skymesh so that if the query is answered once by the global mesh it doesn't have to be answered again (quality checks will need to still work)." Plus: "in amplituhedron cache we have 3 layers of caching: 3/7 dimension, 66 dimension, and 196k dimension -- that stuff should be used."
Quality model (decided): TRUST STORED ATTESTATION. The cache only stores answers that PASSED the quality gate. Each entry carries its attestation plus the admitted-node provenance plus a signature. A HIT trusts that record and does NOT re-run inference. Quality preservation comes from the gate that ran at PUT time, not from re-running it at GET time.
This document maps the design onto code that already exists. It does not invent a
flat cache: it reuses the three mycelial tiers from FanoMycelialRouteCache
(dims 7 / 66 / 196884) and the @a0n/knotgraph content-addressed store, and it
mounts on the already-deployed apps/edgework-app worker.
0. The one-line idea
The amplituhedron cache (amplituhedron.rs) already does "answer once, replay"
at the prefill level inside a single station: key
(prefix_hash, prefix_len, layer_lo, layer_hi), replay returns the frozen
volume, geodesicLength:0. The Global Answer Cache is the same move one level
up: key a whole query (prompt tokens + model) to a whole gate-passing
answer and replay it across the entire mesh instead of inside one station.
"Answer once, replay" goes from per-station prefill to per-mesh query.
1. Cache contract
1.1 Entry shape
interface GlobalCacheEntry {
// ── identity / key material ──────────────────────────────────────────
queryHash: string; // canonical query hash = fp48/fp64 over (tokens, qspec) — MODEL-AGNOSTIC
queryTokens: number[]; // the exact prompt token ids that produced the key
model: string; // e.g. "qwen2.5-0.5b-instruct"; PROVENANCE only, NOT part of the key
qspecId: string; // quality-spec / gate id, e.g. "paris/v1"; part of the key (the quality bar)
// ── the answer ───────────────────────────────────────────────────────
answerTokens: number[]; // the generated token ids (the replayable payload)
answerText: string; // best-effort detokenization (display only; tokens are canonical)
// ── trusted attestation (the quality proof) ──────────────────────────
attestation: {
gate: 'paris/v1' | string; // which quality gate ran (PreflightResult.id family)
pass: true; // ONLY pass:true is ever stored; false is never cached
token: number; // gate's rank-0 argmax (e.g. 12095 " Paris")
logit: number; // gate's rank-0 logit (confidence margin)
nodeId: string; // admitted node that produced the answer (provenance)
admitted: true; // node's PARIS-gate admission flag at answer time
sig: string; // node signature over the canonical entry digest
attesterDid?: string; // node DID hash (PRISM_ATTESTER_DID_HASH provenance)
};
// ── bookkeeping ──────────────────────────────────────────────────────
ts: number; // wall-clock the answer was sealed
tier: 'fano7' | 'aeon66' | 'monster196884'; // which mycelial tier indexed it
}1.2 The KEY: canonical query hash
The key is a content hash over the canonicalized pair
(queryTokens, qspecId). MODEL-AGNOSTIC: model is deliberately NOT in the
key (it is provenance on the entry). The 7 Fano points are orthogonal to the
model dimension, so the fano-7 point is the model-independent sharing unit —
any model that shares the keying tokenizer and clears the qspec gate shares the
answer (a 0.5B and a 7B Qwen answer to the same prompt land on the SAME key).
This is deliberately the query-level analogue of the amplituhedron
prefix_hash:
amplituhedron.rs:66-94keys a frozen prefill volume on(prefix_hash: u64, prefix_len, layer_lo, layer_hi)and only ever hits on an exact match (key_matches, lines 88-94). Divergence in the token stream changes the hash and forces a miss (amplituhedron.rs:269-272, thetimeless_isomorphismcovenant). We adopt the identical discipline: the key is an exact content hash of the prompt tokens; one token differs, the key differs, the answer is not served.- We compute the hash with
cacheFingerprint48HexSync/cacheFingerprint64HexSyncfrom@a0n/bitwise/cache-fp48(open-source/bitwise/cache-fp48.ts:68-72). This is the SAME fingerprint primitive the mycelial tiers already use for their tier keys (FanoMycelialRouteCache.ts:345-361,fanoMycelialTierFp48Key->cacheFingerprint48HexSync). Using one fingerprint family across both surfaces keeps the key scheme aligned and avoids a second hashing convention. - Canonical byte layout for the key (mirrors
fanoMycelialTierKeyBytes,FanoMycelialRouteCache.ts:316-343): theqspecIdutf8 bytes, a 0x00 separator, then each token id little-endian u32. No model bytes (model is provenance, not key). fp48 (6 bytes) is the wire key; fp64 (8 bytes) is retained on the entry for collision verification. Note the fp48 doc warning (cache-fp48.ts:22-26): ~2^24 birthday resistance, so a HIT MUST confirmentry.queryTokensandentry.qspecIdequal the request before trusting it (model is NOT re-compared). This is the same "verify identity on hit" rule the fp48 module itself mandates, and it is identical in spirit to amplituhedron's exactkey_matches.
1.2.1 The keying-tokenizer cohort (the real boundary)
With model out of the key, the cohort boundary becomes the keying tokenizer +
qspec, not the model string. (tokens, qspec) unifies models that SHARE a
tokenizer (all Qwen2.5 sizes emit identical token ids → identical keys → shared
answers — the heterogeneous-Qwen fleet this is for), while models with DIFFERENT
tokenizers (Qwen vs Llama) produce different token ids → different keys → they
remain naturally separate (correct: a Llama token stream is a genuinely different
query material). Every writer/reader in a cohort MUST tokenize keys with the same
canonical keying tokenizer (today: Qwen2 BPE). Astrolabe pins this independently
of its brew model (poetry-gate.js skymeshKeyTokenizer); the bridge/mesh
currently tokenize with the served model's tokenizer — fine while the fleet is
all-Qwen, but pin a canonical keying tokenizer there before admitting a non-Qwen
serving node (follow-on).
1.3 Field-by-field quality justification
| field | why it preserves quality |
|---|---|
queryHash |
exact content key; one differing prompt token = different key = no false hit (amplituhedron key_matches / timeless_isomorphism discipline). |
queryTokens |
stored verbatim so a HIT can confirm identity past the fp48 birthday bound before trusting (cache-fp48.ts:22-26 requires on-hit identity verification). |
qspecId |
part of the key — the quality bar. A different qspec is a different key, so a stronger qspec never silently serves a weaker answer (the quality guarantee now rides the qspec alone, since model left the key). |
model |
PROVENANCE only (NOT in the key): which model produced the answer, for display/audit. Two models that share the keying tokenizer and clear the same qspec share the entry (model-agnostic). Collision policy is last-write-wins; every stored answer already cleared the qspec gate, so whichever wins is acceptable. |
answerTokens |
the canonical replay payload (the analogue of amplituhedron's frozen kv_slab/tail_residual). Tokens, not text, are authoritative; text is display-only. |
attestation.pass |
invariant: only pass:true is ever stored. A failing gate verdict is never cached. This is the entire quality guarantee. |
attestation.gate / token / logit |
the gate verdict carried verbatim from PreflightResult (monitor-control.ts:218-235). Auditable: a reader can see WHICH gate passed and at what margin. |
attestation.nodeId / admitted / attesterDid |
provenance. Only an admitted node (MonitorRelayDO.ts:140-146, admitted map; isAdmitted) may have produced a stored answer. Lets readers and re-validators trace the source. |
attestation.sig |
tamper evidence. The answer cannot be forged or rewritten by a non-admitted party because the signature is over the canonical entry digest and PUT verifies it (see section 4). Mirrors the per-subagent ECDSA signing already used in monster-swarm and the signature field on OracleGgAttestationRecord (knotgraph/src/types.ts:84-93). |
ts |
staleness accounting + LRU/liquid-density tiebreak (amplituhedron uses last_used, amplituhedron.rs:79-84). |
tier |
which mycelial tier indexed this entry; lets stats and promotion reason per tier. |
2. The 3-tier mapping (the explicit ask)
The user asked for the three amplituhedron-style layers: 3/7 dim, 66 dim,
196884 dim. We reuse the exact tier vocabulary and structure from
FanoMycelialRouteCache (FanoMycelialRouteCache.ts:25):
export type FanoMycelialRouteCacheTier = 'fano7' | 'aeon66' | 'monster196884';These are dims 7, 66, and 196884 (fanoMycelialTierKeyBytes,
FanoMycelialRouteCache.ts:316-343, encodes the tier marker 7 | 66 | 196).
We map the query->answer cache onto them as three nested lookup scopes, exactly
mirroring how FanoMycelialRouteCache.routeColumns cascades fano7 -> aeon66 ->
monster196884 (FanoMycelialRouteCache.ts:90-161):
2.1 fano7 — HOT exact-completion tier (dim 7)
The smallest, fastest, most-protected tier. It is the analogue of the
fanoCompletions map (FanoMycelialRouteCache.ts:70, keyed by
fanoCompletionCacheKey, lines 267-269) and of the fano7 route-template array
(fanoRoutes, lines 71-73). In our cache this tier holds the highest-density
exact (queryHash -> answer) hits: the small set of queries asked over and over
across the whole mesh (FAQ-class). Bucketed/indexed via
fanoMycelialTierFp48Key('fano7', ...). Tiny capacity, never evicted under
normal pressure (these are the "FAQ of the planet" answers).
2.2 aeon66 — WARM phase-template tier (dim 66)
The analogue of aeonRoutes (FanoMycelialRouteCache.ts:74, keyed by
fanoAeonPhaseCacheKey, lines 291-301). aeonRoutes stores templates
materialized into concrete decisions on hit (materializeTemplate, lines
179-222). In the answer cache this is the phase/template tier: queries
grouped by a coarser phase key (e.g. model + qspec + a normalized prompt
shape) so that the warm tier can serve the common answer for a family of
near-identical queries. Capacity is mid-sized; promotion from cold happens here.
Indexed via fanoMycelialTierFp48Key('aeon66', ...).
2.3 monster196884 — COLD full-space tier (dim 196884, capped)
The analogue of monsterRoutes (FanoMycelialRouteCache.ts:75, keyed by
fanoMonsterPairCacheKey, lines 303-314) with the capacity cap
(maxMonsterEntries = 4096, line 88; FIFO-ish eviction in rememberMonster,
lines 251-264). This is the cold full-space tier: the long tail of distinct
(queryHash -> answer) entries. It is the largest tier and the one with the hard
cap. We default this cap to the same maxMonsterEntries ceiling pattern (a
configurable bound, NOT a literal 196884-entry allocation — 196884 is the
dimension label of the tier, exactly as fanoMycelialTierKeyBytes uses 196 as
a one-byte marker, not an allocation, line 324). Eviction uses the
amplituhedron liquid-memory rule (section 6).
2.4 Lookup order (hot -> warm -> cold) and write/promotion
Lookup mirrors routeColumns (FanoMycelialRouteCache.ts:90-161):
- Probe fano7 (exact-completion). Hit -> return, bump density. (lines 102-118)
- Else probe monster196884 (exact full-space). Hit -> return, and
promote by recording into the warm/hot bucket if the entry's hit density now
warrants it. (lines 120-131: monster probed, then on a higher-tier hit it
rememberMonsters — we run the symmetric promotion upward.) - Else probe aeon66 (phase template). Hit -> materialize/return and remember into monster196884. (lines 133-149)
- Total miss -> route to the mesh (section 5), then on a gate-PASS, WRITE the
new entry into monster196884 (cold) and, if its density crosses the promotion
threshold, into aeon66 and finally fano7. This is the upward write/promotion
path; it is the inverse of the downward lookup and reuses the same density
accounting amplituhedron uses for
hit_count(amplituhedron.rs:79-84,replaybumpshit_count, lines 287-293).
Write policy: a new gate-passing answer is always written to cold
(monster196884). Promotion to aeon66 / fano7 is by density (prefix/query
length x hit_count), identical to the amplituhedron liquid-density notion
(amplituhedron.rs:300-336). Demotion is eviction (section 6).
API surface reused (cite): FanoMycelialRouteCacheTier
(FanoMycelialRouteCache.ts:25); fanoMycelialTierKeyBytes
(lines 316-343); fanoMycelialTierFp48Key (lines 345-361);
fanoCompletionCacheKey (267-269); fanoAeonPhaseCacheKey (291-301);
fanoMonsterPairCacheKey (303-314); the cascade shape of routeColumns
(90-161); the stats shape FanoMycelialRouteCacheStats (13-23).
3. knotgraph store: persistence, content-addressing, gossip
The cache substrate is @a0n/knotgraph (open-source/knotgraph). It is a
content-addressed graph store over a 54-fp64 helix block; every block is hashed
by its full state, so two writers producing the same block in any region produce
the same hash (DESIGN.md:26; block.ts:143-156 hashBlock/hashHex). That
content-addressing is exactly what a shared mesh cache needs: the same answer
sealed on two nodes lands at the same address, so there is nothing to merge.
3.1 How an entry persists as a knotgraph block
A GlobalCacheEntry maps onto one knotgraph block via buildBlock
(block.ts:44-67) using a dedicated type tag (e.g.
TYPE_TAG_GLOBAL_CACHE_ANSWER, following the
TYPE_TAG_WEIGHT_MANIFEST = 0xa1_77_4e_47 precedent in
knotgraph/src/worker.ts:271). Field/lane assignment:
entityId(dim.ts:86ENTITY_ID) = the canonicalqueryHash(fp64 numeric). This makes lookup-by-query agetEntity(worker.ts:238-258).typeTag(dim.ts:84TYPE_TAG) = the cache-answer type tag.schemaKnotHash(dim.ts:88) = hash of(model, qspecId)so a different model/qspec is a distinct schema lineage.- application FIELD lanes (
dim.ts:107FIELD_LANES = 45..50) carry the small scalars:attestation.token,attestation.logit(quantized),tiermarker (7/66/196),ts,answerTokens.length, gate id hash. provenanceDid(dim.ts:100PROVENANCE_DID, dim 51) =attestation.attesterDid(the admitted node's DID hash) — provenance is a first-class lane.freshnessClock(dim.ts:102FRESHNESS_CLOCK, dim 52) = a logical clock for read-your-writes / staleness (the knotgraph freshness contract,types.ts:133-146).- The bulky payload (
answerTokens,answerText, fullsig) is stored in R2 keyed by the block hash hex (hashHex,block.ts:154-156), exactly as knotgraph stores entity block bytes in R2 keyed by hash (worker.ts:77-78"Writes a knotchain block to R2 keyed by hash"). The block is the index/lineage row; R2 holds the bytes. This is the same split the weight-manifest path uses (worker.ts:100-102: block is the index, R2 holds the tensor).
Put/get are the existing knotgraph dispatcher ops: createEntity and
getEntity (dispatcher.ts:196-300, worker.ts:207-258). No new storage engine
is introduced.
3.2 Content addressing = automatic dedupe and CRDT merge
Because the block is content-addressed (block.ts:143-156) and indexes are
"causal CRDTs that roam regions" with "no conflict resolution because there are
no conflicts" (DESIGN.md:240-244, IndexCRDT.lean), two nodes that answer the
SAME query and seal the SAME (queryTokens, model, qspecId, answerTokens) land
at the SAME hash. The mesh-wide cache index is therefore a CRDT: merging two
nodes' caches is "take the union of blocks, sort by hash, done"
(DESIGN.md:244). A HIT on one node's index is serviceable by all.
3.3 Party-like gossip across the mesh
Two reuse paths, both already in the tree:
- PRISM teleport wire (knotgraph-native gossip).
prism-protocol.tsalready defines a signed multi-hop knot-chain wire: per-hopPRISM_PATH_HASH(dim 42),PRISM_PAYLOAD_HASH(43),PRISM_PREV_HOP_SIG_HASH(44), payload digest lanesPRISM_PAYLOAD_DIGEST_0..5(45-50),PRISM_ATTESTER_DID_HASH(51), and a chain validatorvalidatePrismChain(prism-protocol.ts:254). A new gate-passing entry gossips as a PRISM hop carrying the entry's block hash + the signed attestation; receiversvalidatePrismChainthencreateEntitylocally. This is the "statistical teleportation as the wire format" (DESIGN.md:29) applied to cache propagation, and it is the same geodesicLength:0 replay idea (section 6). - Skymesh partyline (operational fan-out). The mesh already has a
party-like room:
MonitorRelayDOis "a GLOBAL PARTYLINE room", one DO per?mesh=<id>, defaultskymesh-global, with MANY bridges sharing one room and the relay fanning frames/status to all (MonitorRelayDO.ts:4-20). A new message type{type:"cache-put", entry}rides the same uplink so an answer sealed by one node is announced to the partyline and the edgework cache worker persists it once for all. Admission already lives here: the relay tracksadmittedper node (MonitorRelayDO.ts:140-146) and only an admitted node's announcement is honored.
Either path satisfies "a hit on one node serves all": the index is content- addressed (CRDT), and propagation is opt-in gossip over PRISM and/or the partyline.
4. edgework-app surface
apps/edgework-app already deploys as a createKnotchainApp worker
(worker.ts:1724-1752) with a path-dispatched fetchInternal
(worker.ts:1577-1722) that already fronts R2 with UCAN auth
(/api/v1/r2/*, worker.ts:1651-1665, handleR2Proxy). It already imports the
knotchain shell and an R2 binding for distributed-inference artifacts
(worker.ts:65-76, DISTRIBUTED_INFERENCE?: R2Bucket). The cache mounts here as
a new route family /api/v1/cache/*, dispatched in fetchInternal right beside
the existing R2 fast-path block (worker.ts:1586-1603).
4.1 Routes to add
GET /api/v1/cache/lookup?q=<queryHash>&model=<m>&qspec=<id>
-> 200 { hit:true, entry } | 200 { hit:false }
Reads are PUBLIC (no auth). Resolves via knotgraph getEntity on the
queryHash entityId; on a block hit, fetches the answer bytes from R2
and verifies entry identity (tokens/model/qspec) past the fp48 bound.
POST /api/v1/cache/put (signed; admitted-node only)
body: GlobalCacheEntry (with attestation.pass:true required)
-> 201 { stored:true, blockHash } | 4xx { stored:false, error }
WRITE is gated: see auth below. Verifies attestation.pass === true,
verifies attestation.sig over the canonical digest, confirms nodeId is
admitted, then createEntity into knotgraph (cold tier) + R2 payload +
gossip announce.
GET /api/v1/cache/stats
-> 200 { fano7:{hits,misses,entries}, aeon66:{...},
monster196884:{...,cap}, heatReleased, optIn }
Mirrors FanoMycelialRouteCacheStats (FanoMycelialRouteCache.ts:13-23)
plus the amplituhedron eviction/heat counters (amplituhedron.rs:183-185).4.2 Mounting (cite)
Add a fast-path block in fetchInternal mirroring the existing R2 block
(worker.ts:1586-1603 early /api/v1/r2/ interception, and worker.ts:1651-1665
the canonical block). Pattern:
// inside fetchInternal, after the r2 fast-path block (worker.ts ~1603)
if (url.pathname.startsWith('/api/v1/cache/')) {
return handleGlobalCache(request, env, ctx); // new lib/global-cache.ts
}handleGlobalCache builds the knotgraph dispatcher exactly as
knotgraph/src/worker.ts:176-189 does (new Dispatcher({ lanes:[TsLane,...] }))
against the edgework D1 + the DISTRIBUTED_INFERENCE R2 bucket
(edgework worker.ts:75), and issues createEntity/getEntity operations
(dispatcher.ts:196). No bespoke storage; reuse the knotgraph dispatcher.
4.3 Opt-in flag
The cache is OPTIONAL and OFF by default (the user said "optional, party-like").
Gate the whole route family on an env flag GLOBAL_CACHE_ENABLED (default
false), surfaced in Env (edgework worker.ts:65-91). When off, /lookup
always returns {hit:false} and /put returns 503 — the mesh behaves exactly
as today (the "disabled cache short-circuits" discipline,
amplituhedron.rs:396-402). Nodes opt in to the partyline by connecting their
bridge with ?mesh=skymesh-global (MonitorRelayDO.ts:6).
4.4 Auth
- Reads (
/lookup,/stats): public. A cached answer is not secret; it already passed a public quality gate. Cheap, CDN-cacheable (block.ts:26"CDN-cacheable reads"). - Writes (
/put): admitted-node-only + signature. Two checks, both already expressible in-tree:- The body's
attestation.nodeIdmust be currently admitted. Admission is the PARIS-gate verdict tracked by the relay (MonitorRelayDO.ts:140-146,admittedmap;isAdmitted). The edgework worker confirms admission either via the partyline (the put arrived over the admitted bridge uplink) or by re-checking the relay's admitted set. attestation.sigmust verify over the canonical entry digest with the node's key. This is the same signed-attestation pattern asOracleGgAttestationRecord.signature(knotgraph/src/types.ts:84-93) and the per-subagent ECDSA signing already used in monster-swarm. UCAN gating is already present in edgework for R2 writes (worker.ts:71-75, "UCAN auth"); the cache/putreuses that gate.
- The body's
This is the cache-poisoning defense: a non-admitted party cannot PUT, and a tampered entry fails signature verification.
5. Flow (both paths)
query (prompt tokens + model + qspec)
|
v
+-----------------------------------------+
| edgework /api/v1/cache/lookup |
| key = fp48/fp64(tokens, model, qspec) |
| 3-tier probe: fano7 -> aeon66 -> |
| monster196884 |
+-----------------------------------------+
| |
HIT (valid) MISS
| |
verify identity past fp48 bound v
verify attestation.pass===true route to GLOBAL MESH
verify attestation.sig (an ADMITTED node answers)
| |
v fat-station inference path:
return cached answer /tokenize + /decode-next
NO inference (skymesh-query, /decode-next;
(geodesicLength:0 replay) NOTE /generate is broken)
|
v
QUALITY GATE on the answer
(PARIS-style PreflightResult:
pass, token, logit, model)
monitor-control.ts:218-235
|
+---------+---------+
| |
FAIL PASS
| |
return answer, sign + seal:
DO NOT cache attestation{pass,
(quality preserved) token,logit,nodeId,
admitted,sig}
|
v
POST /api/v1/cache/put (admitted+signed)
createEntity -> knotgraph block
+ R2 payload (by hash)
+ write cold (monster196884),
promote by density
|
v
GOSSIP across mesh (party-like):
PRISM hop (validatePrismChain) and/or
partyline {type:"cache-put"} on
MonitorRelayDO (skymesh-global)
|
v
return answer to caller
(next identical query anywhere -> HIT)Detail on the MISS -> answer -> attestation path:
- Route to mesh. A miss is answered by an admitted node over the existing
inference path. The reliable path is per-token autoregressive:
/tokenizethen/decode-nextwithX-Token/X-Position(open-source/gnosis/bin/skymesh-query:80-94)./generateis broken (its batched decode loop repeats the last token,skymesh-query:7-10), so the cache-fill path MUST use/decode-next, not/generate. - Produce the attestation. The quality gate is the PARIS gate the node
already runs to be admitted: prompt "The capital of France is" -> argmax
token 12095 " Paris" (
monitor-control.ts:237-240,PREFLIGHT_PROMPT/PREFLIGHT_EXPECTED_TOKEN/PREFLIGHT_EXPECTED_TEXT). The gate verdict is thePreflightResult(monitor-control.ts:218-235:{id, pass, token, text, logit, elapsedMs, model, detail?}). For the answer cache, the gate is applied to the answer being cached (the qspec named byqspecId): the node asserts the answer satisfies its quality contract and emits a pass verdict. Onlypass:trueproceeds to PUT. - Attach + sign. The node copies
pass/token/logit/modelfrom the verdict, addsnodeId/admitted(its relay admission,MonitorRelayDO.ts:140-146) andattesterDid, then signs the canonical entry digest ->attestation.sig. - Store + gossip. PUT into edgework -> knotgraph cold tier + R2, then gossip (section 3.3).
A HIT trusts attestation and returns immediately — this is where the "doesn't
have to be answered again" win lands, and it is the geodesicLength:0 replay of
the amplituhedron cache (section 6).
6. Tie to the teleport / amplituhedron cache
The Global Answer Cache is the same theorem as amplituhedron.rs, one scope
up:
| amplituhedron.rs (per-station prefill) | Global Answer Cache (per-mesh query) |
|---|---|
key (prefix_hash, prefix_len, layer_lo, layer_hi) (lines 66-94) |
key fp48/fp64(queryTokens, model, qspecId) (section 1.2) |
exact key_matches -> hit (lines 88-94) |
exact content hash + on-hit identity verify (section 1.2) |
replay returns frozen volume, skips prefill compute (lines 273-298) |
/lookup returns cached answer tokens, skips inference (section 5) |
timeless_isomorphism covenant: replay sound iff hash exact (lines 269-272) |
one differing prompt token -> different key -> miss (section 1.2) |
liquid-memory eviction: density = prefix_len * (hit_count+1), lowest density evicted, LRU tiebreak, heat_released accounting (lines 300-336) |
same rule on monster196884: density = queryLen * (hit_count+1); lowest-density cold entries vent first; heatReleased in /stats |
clinamen_swerve guard: refuse prefix_len == 0 (lines 218-222) |
refuse empty queryTokens (the same +1 clinamen guard) |
| disabled cache short-circuits (lines 396-402) | GLOBAL_CACHE_ENABLED=false short-circuits (section 4.3) |
Reuse: the eviction/density math and the enabled/short-circuit discipline are
copied verbatim in spirit from amplituhedron.rs:300-336 / 396-402. The
"answer once, replay" idea and the geodesicLength:0 framing are the shared
covenant. The amplituhedron is the field-theory functor's value on the prefill
cobordism (amplituhedron.rs:42-46); the global cache is the same functor on the
whole-query cobordism. They compose: a global HIT skips the entire query; a
global MISS still benefits from per-station amplituhedron prefill replay on the
answering node.
7. Implementation breakdown
Order matters: the cache lib is pure and testable first; the worker routes wrap it; the skymesh fill path is last because it depends on a live admitted node.
Workstream A — knotgraph cache lib with the 3 tiers
- New file:
open-source/knotgraph/src/global-cache.ts(lib, no worker). - Reuse:
FanoMycelialRouteCacheTierand the tier key helpers (FanoMycelialRouteCache.ts:25,316-361);cacheFingerprint48HexSync(cache-fp48.ts:68);buildBlock/hashBlock/hashHex(block.ts:44-67,143-156); dispatchercreateEntity/getEntity(dispatcher.ts:196). - Implement:
GlobalCacheEntrytype; canonical key; 3-tier lookup cascade (mirrorrouteColumns,FanoMycelialRouteCache.ts:90-161); liquid-density eviction on the capped cold tier (mirroramplituhedron.rs:300-336); stats shape (mirrorFanoMycelialRouteCacheStats, lines 13-23). - Export from
knotgraph/src/index.ts(currently lines 9-15) and add a./global-cacheentry toknotgraph/package.jsonexports (currently lines 8-15). - Tests: vitest, run via
./bin/monster test(NOT raw bun/vitest — see project memory; raw runners fail on the gnosis wasm/law harness).
Workstream B — edgework-app routes + storage/gossip
- New file:
apps/edgework-app/src/lib/global-cache.ts(handleGlobalCache). - Wire into
fetchInternalbeside the R2 fast-path (edgework worker.ts:1586-1603/1651-1665); addGLOBAL_CACHE_ENABLED+ cache D1/R2 bindings toEnv(worker.ts:65-91) andwrangler.toml. - Routes:
/api/v1/cache/lookup(public),/put(admitted+signed),/stats(section 4.1). Reuse the UCAN gate already used for R2 writes (worker.ts:71-75). - Gossip: add
{type:"cache-put"}to the partyline protocol onMonitorRelayDO(apps/skymesh/src/durables/MonitorRelayDO.ts, beside the existing frame/status/preflight message handling) and/or emit a PRISM hop (knotgraph/src/prism-protocol.ts:146-254).
Workstream C — skymesh query-with-cache path + attestation/signing
- Update the query entrypoint (
open-source/gnosis/bin/skymesh-query, currently uses/decode-next, lines 80-94) to FIRST call/api/v1/cache/lookup; on HIT, print the cached answer and exit (no inference). On MISS, run inference via/decode-next(NOT/generate, lines 7-10), then run the quality gate (PreflightResultfamily,monitor-control.ts:218-240), sign the entry, and POST/putonly onpass:true. - Signing key: reuse the node's existing per-node signing identity (the
per-subagent ECDSA pattern from monster-swarm;
attesterDidmaps toPRISM_ATTESTER_DID_HASH,prism-protocol.ts:69).
Risks and mitigations
- Cache poisoning -> signatures + admitted-only PUT (section 4.4). A
non-admitted node cannot write; a tampered entry fails sig verify. Reads verify
attestation.pass===trueand entry identity past the fp48 birthday bound (cache-fp48.ts:22-26) before trusting a hit. - Staleness -> the freshness clock lane (
dim.ts:102,types.ts:133-146) +ts. Entries are immutable and content-addressed, so a "newer better answer" is a new key only if model/qspec change; same model+qspec+tokens is deterministically the same answer (the amplituhedrontimeless_isomorphismdiscipline). A qspec bump (paris/v2) cleanly invalidates without mutation. - The 196884 cap -> the cold tier is bounded exactly like
maxMonsterEntries(FanoMycelialRouteCache.ts:88) with liquid-density eviction (amplituhedron.rs:300-336). 196884 is the tier label, not an allocation (fanoMycelialTierKeyBytesuses 196 as a marker byte,FanoMycelialRouteCache.ts:324). Capacity is a tuned config value. - Opt-in default off ->
GLOBAL_CACHE_ENABLED=falseby default; the mesh is unchanged when disabled (the "disabled cache short-circuits" rule,amplituhedron.rs:396-402). - fp48 collisions -> ~2^24 birthday resistance (
cache-fp48.ts:22-26); HIT MUST verify full identity (queryTokens,model,qspecId) and the fp64 retained on the entry before trusting. /generateis broken -> the fill path MUST use/decode-next(skymesh-query:7-10); a fill that used/generatewould cache a repeated- last-token answer and the gate would (correctly) fail it, but the path must not rely on the gate to catch a known-broken endpoint.
8. What this design explicitly reuses (no new primitives)
- 3 tiers:
FanoMycelialRouteCacheTierfano7 / aeon66 / monster196884 (FanoMycelialRouteCache.ts:25) + tier keying (lines 316-361) + cascade (lines 90-161) + stats (lines 13-23). - Key hashing:
cacheFingerprint48HexSync/ fp64 (open-source/bitwise/cache-fp48.ts:68). - Answer-once/replay + liquid-density eviction:
open-source/gnosis/distributed-inference/src/amplituhedron.rs:66-94,273-336,396-402. - Store:
@a0n/knotgraphcontent-addressed blocks + dispatcher createEntity/ getEntity + R2-by-hash (block.ts:44-156,dispatcher.ts:196-300,worker.ts:176-258). - Gossip: PRISM signed multi-hop wire (
knotgraph/src/prism-protocol.ts:42-254) and the Skymesh GLOBAL PARTYLINE (MonitorRelayDO.ts:4-20,140-146). - Quality gate + attestation:
PreflightResultPARIS gate (apps/skymesh/client/lib/monitor-control.ts:218-240) + relay admission (MonitorRelayDO.ts:140-146) + signed-attestation precedent (knotgraph/src/types.ts:84-93). - Host worker:
apps/edgework-appcreateKnotchainApp+fetchInternaldispatch + UCAN R2 gate (apps/edgework-app/src/worker.ts:1577-1752,71-75).