Blueprints and the cache
read as.mdA blueprint is a render promoted to a reusable recipe. The first time your agent asks for a feedback card, ggui generates one. The stored result — component code, the contract it satisfies, the intent that produced it — becomes a candidate the matcher can serve the next time an ask looks the same. Where gadgets are ingredients and tools are actions, blueprints are the already-solved screens.
Blueprints live in a per-app pool. Matching happens at ggui_handshake, before any generation is attempted; ggui_render then executes whichever path the handshake chose.
The reuse key
Section titled “The reuse key”Two values decide identity. contractHash is the canonical hash of the data contract — fields, types, specs — so the same hash means the same data flow. variantKey is the canonical hash of the design-time variance (persona, aesthetic, seed prompt, context). The pair is the reuse key: the same pair reuses one component, and a different variant of the same contract gets its own row.
Passing override.contract on render always generates cold and mints a fresh id, even for a contract identical to one already cached. That is deliberate — an explicit override is a request for new code, not a cache probe.
The match pipeline
Section titled “The match pipeline”Matching has two tiers, and they have very different costs and postures.
Tier 1 — exact contract-key equality. When your agent supplied a contract, the matcher looks up the canonical key directly. It is deterministic, it calls no model at all, and a hit is a guaranteed-correct reuse: the same canonical contract means the same data flow.
Tier 2 — retrieval plus a rerank judge. When tier 1 misses, candidates are retrieved by cosine similarity over embeddings and a fast model is asked to pick among them. The judge is shown your intent prose and a one-line structural summary of each candidate contract — slots=name:type; actions=name(payloadFields); streams=name; props=name:type — and nothing else. It never sees props values or event payloads. A judge that declines every candidate, or picks one below the confidence threshold, falls through to cold generation rather than serving a wrong blueprint.
The reranker exists because raw cosine similarity cannot tell a sendChip action that carries {chipText} apart from a payload-less sendChip — and serving the wrong one silently drops the user’s input.
The outcome surfaces on the handshake as suggestion.origin: cache (a blueprint matched), agent (generate against your draft), or synth (generate against an amended draft). See How ggui works for the full five-moment walk-through.
What a hit costs
Section titled “What a hit costs”Nothing. Only generation is priced, from the tokens of the LLM call it made — so a render matched against a cached blueprint has nothing to bill. Details on Credits, billing & BYOK.
Be honest with yourself about what the cache buys: today it saves the generation charge, not wall-clock time. Treat it as a cost lever and a consistency lever — the same ask returns the same component — rather than a latency guarantee.
Promotion
Section titled “Promotion”Promotion is automatic and best-effort, not something you call.
When a render misses the cache, generates successfully, and the deployment has a blueprint cache bound, the produced component is registered into the pool as part of finishing that render. If the registry write fails — a full disk, a misconfigured vector index — the render still succeeds and returns normally. Only the future cache hit is lost, and a cache_write_failed event is logged. The registry write is a performance optimization, never a correctness dependency, which is why it can never fail a render that already produced working code.
Two other write paths put rows in the same pool, and the matcher reads all three identically:
| Path | Who triggers it |
|---|---|
| Cold generation | Automatic, on a successful ggui_render that missed the cache |
ggui_ops_register_blueprint |
You, deliberately — hand-authored or imported rows |
ggui blueprint install |
You, installing a marketplace or local artifact |
The pool is capped per kind and evicts the lowest-hit entry first when full. Installed rows are exempt from that eviction — the install bridge owns their lifecycle.
Durability
Section titled “Durability”Blueprints carry no TTL. Unlike renders, which an agent can bound with ttlSeconds, a blueprint is not on a clock.
A registration that mints a fresh row writes through to a durable pair: the compiled body goes to object storage keyed by its content hash, and the metadata row points at that hash. The body is written first, deliberately. An orphan body is invisible and reclaimable; a row naming a hash with no body behind it is a lie that fails later, at the exact point it looked like it would succeed. If the body write fails, the row is still recorded — without the code hash, a state the protocol already models as “metadata recorded, no body stored”.
Reclamation is operator-invoked, never scheduled: a takedown, an app retirement, or collection of bodies that have gone unreferenced long enough to be safely orphaned. A takedown records the content hash as a tombstone, and both halves of the durable write consult it — body upload and metadata row alike, with a consistent read. That is what makes removal stick: bodies are content-addressed, so without the body-side gate a later cold generation producing byte-identical code would simply re-upload to the same key.
Retention across renders, blueprints, and account deletion is laid out in Trust & security.
Sharing a pool
Section titled “Sharing a pool”A pool is per-app by default, but it does not have to stay there.
- Between your own deployments.
ggui export-poolwrites this deployment’s reusable blueprints as a directory artifact; another deployment loads it withggui serve --seed-pool <dir>. Seed pools are read-only, additive, and exact-key only — they are never written at runtime. - Publicly. A blueprint repo carries a
ggui.blueprint.jsonmanifest and publishes as a signed, versioned, content-addressable artifact. Browse what others have published at hub.ggui.ai, or install withggui blueprint install. The mechanics, signing postures, and what a signature does and does not prove are on the marketplace page.
Measuring your hit ratio
Section titled “Measuring your hit ratio”Three surfaces exist today, and none of them is a dashboard.
Per render, on the wire. ggui_render returns a cache marker alongside the render:
// ggui_render output — the cache marker:{ hit: true, // a stored component was served, no code generated llmCallsAvoided: 1, // generation calls skipped (0 on a fresh generation) cachedBlueprintId: "bp_…", // the matched component id similarity: 0.91, // cosine similarity — semantic matches only kind: "full-template", // full-template = stored component served; cold = freshly generated reason: "match-exact: …" // why this render reused or generated}Log hit and llmCallsAvoided per call and you have your own hit ratio, computed from the same values the server used. reason is available by default — you do not need a verbose trace to find out why a match was declined.
Per handshake. suggestion.origin tells you the routing decision one call earlier, before you commit.
Per app, on the control plane. ggui_ops_list_blueprints enumerates blueprint metadata under an app you operate, filterable by contract hash, generator, persona, or intent keywords. It returns metadata only — code bodies stay in the store and are fetched by a render on a hit.
The ggui console’s per-app Blueprints tab manages your named blueprint library — rename, edit metadata, view source, delete — and shows a render count per named blueprint. It is not a view of the auto-promoted generation pool, and it does not aggregate a hit rate.