forgo.cloud
Sign in
Repo workspace

forkjoin-ai/gnosis

Skymesh Global Answer Cache — DESIGN

distributed-inference/docs/GLOBAL_CACHE_DESIGN.md
forkjoin-ai/gnosis

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-94 keys 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, the timeless_isomorphism covenant). 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 / cacheFingerprint64HexSync from @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): the qspecId utf8 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 confirm entry.queryTokens and entry.qspecId equal 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 exact key_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):

  1. Probe fano7 (exact-completion). Hit -> return, bump density. (lines 102-118)
  2. 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.)
  3. Else probe aeon66 (phase template). Hit -> materialize/return and remember into monster196884. (lines 133-149)
  4. 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, replay bumps hit_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:86 ENTITY_ID) = the canonical queryHash (fp64 numeric). This makes lookup-by-query a getEntity (worker.ts:238-258).
  • typeTag (dim.ts:84 TYPE_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:107 FIELD_LANES = 45..50) carry the small scalars: attestation.token, attestation.logit (quantized), tier marker (7/66/196), ts, answerTokens.length, gate id hash.
  • provenanceDid (dim.ts:100 PROVENANCE_DID, dim 51) = attestation.attesterDid (the admitted node's DID hash) — provenance is a first-class lane.
  • freshnessClock (dim.ts:102 FRESHNESS_CLOCK, dim 52) = a logical clock for read-your-writes / staleness (the knotgraph freshness contract, types.ts:133-146).
  • The bulky payload (answerTokens, answerText, full sig) 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:

  1. PRISM teleport wire (knotgraph-native gossip). prism-protocol.ts already defines a signed multi-hop knot-chain wire: per-hop PRISM_PATH_HASH (dim 42), PRISM_PAYLOAD_HASH (43), PRISM_PREV_HOP_SIG_HASH (44), payload digest lanes PRISM_PAYLOAD_DIGEST_0..5 (45-50), PRISM_ATTESTER_DID_HASH (51), and a chain validator validatePrismChain (prism-protocol.ts:254). A new gate-passing entry gossips as a PRISM hop carrying the entry's block hash + the signed attestation; receivers validatePrismChain then createEntity locally. 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).
  2. Skymesh partyline (operational fan-out). The mesh already has a party-like room: MonitorRelayDO is "a GLOBAL PARTYLINE room", one DO per ?mesh=<id>, default skymesh-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 tracks admitted per 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:
    1. The body's attestation.nodeId must be currently admitted. Admission is the PARIS-gate verdict tracked by the relay (MonitorRelayDO.ts:140-146, admitted map; 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.
    2. attestation.sig must verify over the canonical entry digest with the node's key. This is the same signed-attestation pattern as OracleGgAttestationRecord.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 /put reuses that gate.

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: /tokenize then /decode-next with X-Token/X-Position (open-source/gnosis/bin/skymesh-query:80-94). /generate is 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 the PreflightResult (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 by qspecId): the node asserts the answer satisfies its quality contract and emits a pass verdict. Only pass:true proceeds to PUT.
  • Attach + sign. The node copies pass/token/logit/model from the verdict, adds nodeId/admitted (its relay admission, MonitorRelayDO.ts:140-146) and attesterDid, 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: FanoMycelialRouteCacheTier and the tier key helpers (FanoMycelialRouteCache.ts:25,316-361); cacheFingerprint48HexSync (cache-fp48.ts:68); buildBlock/hashBlock/hashHex (block.ts:44-67,143-156); dispatcher createEntity/getEntity (dispatcher.ts:196).
  • Implement: GlobalCacheEntry type; canonical key; 3-tier lookup cascade (mirror routeColumns, FanoMycelialRouteCache.ts:90-161); liquid-density eviction on the capped cold tier (mirror amplituhedron.rs:300-336); stats shape (mirror FanoMycelialRouteCacheStats, lines 13-23).
  • Export from knotgraph/src/index.ts (currently lines 9-15) and add a ./global-cache entry to knotgraph/package.json exports (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 fetchInternal beside the R2 fast-path (edgework worker.ts:1586-1603 / 1651-1665); add GLOBAL_CACHE_ENABLED + cache D1/R2 bindings to Env (worker.ts:65-91) and wrangler.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 on MonitorRelayDO (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 (PreflightResult family, monitor-control.ts:218-240), sign the entry, and POST /put only on pass:true.
  • Signing key: reuse the node's existing per-node signing identity (the per-subagent ECDSA pattern from monster-swarm; attesterDid maps to PRISM_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===true and 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 amplituhedron timeless_isomorphism discipline). 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 (fanoMycelialTierKeyBytes uses 196 as a marker byte, FanoMycelialRouteCache.ts:324). Capacity is a tuned config value.
  • Opt-in default off -> GLOBAL_CACHE_ENABLED=false by 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.
  • /generate is broken -> the fill path MUST use /decode-next (skymesh-query:7-10); a fill that used /generate would 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: FanoMycelialRouteCacheTier fano7 / 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/knotgraph content-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: PreflightResult PARIS 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-app createKnotchainApp + fetchInternal dispatch + UCAN R2 gate (apps/edgework-app/src/worker.ts:1577-1752,71-75).