Skip to content

Latest commit

 

History

History
195 lines (164 loc) · 51 KB

File metadata and controls

195 lines (164 loc) · 51 KB
title vCache default enablement - next 50
description A ranked plan for making fak's virtual-cache, O(1) context, provider-cache, and engine-adapter cache work useful by default across pure fak, API/provider, SGLang, vLLM, and llama.cpp contexts.

vCache default enablement - next 50

Status: planning artifact, 2026-06-30. This page does not claim new shipped behavior. It refreshes the cache concepts and names the next 50 implementation items that make the cache system useful by default.

The product target is:

A user should get the right cache behavior without knowing which cache plane is firing: pure fak uses kernel-owned KV and O(1) context where it can; API/provider mode preserves provider prompt-cache economics without treating them as trust; and SGLang/vLLM/llama integrations expose their cache capability through the same evidence, scoring, and guard rails.

Concept Refresh

Use these names consistently. The old habit of saying "the cache" hides too many different mechanisms.

Plane What it is What can be default-on What must never be inferred
O(1) context/query ctxplan/recall/session memory: the full history is durable and queryable while the resident model view stays bounded. Lossless store, bounded resident view, query route, staleness/fault labels. A smaller resident view is not a quality win until task-success or faithfulness is witnessed.
Pure-fak kernel KV internal/model, radixkv, paged KV, exact-span eviction, prefix clone, local scheduler. fak owns the bytes. Safe local reuse, clone, eviction, pressure relief, quarantine, and preemption when the model runs in-process. A local KV hit is not a provider-dollar saving, and it must still pass materialization/admission gates.
Provider vCache A virtual page table over a provider prompt cache we cannot address directly. It is shaped by request bytes, timing, affinity, and telemetry. Observe, canonicalize, budget at uncached price, score realized rebates, demote false-warm beliefs. Provider cached_tokens or cache_read is cost/latency telemetry only, never proof a local value may be served.
External engine cache SGLang/vLLM/llama.cpp/Ollama/LM Studio caches behind the OpenAI-compatible wire. Some expose prefix/radix/paged KV behavior; some only expose symptoms. Capability inventory, passive observe, wire-neutral labels, adapter-specific witnesses. "fak fronts the engine" is not the same as "fak controls that engine's cache."
Cross-plane score The operator artifact that says which plane fired, how much value it produced, and what to do next. Per-plane provenance, per-family detail, cold-path correctness bit, false-warm risk, net value. A single headline hit rate must not collapse provider rebates, local KV reuse, and O(1) context value into one number.

Default-On Rule

"Fully enabled" does not mean "always warm everything." It means the safe parts are on by default, and active cache behavior arms only after evidence says it is useful:

  • Always observe: every guard, serve, and pure-fak run should emit cache events when a cache plane is available.
  • Always preserve: serializers, tools, system messages, and stable prefixes should be arranged so provider and engine caches are not accidentally defeated.
  • Always label provenance: WITNESSED kernel events, OBSERVED provider counters, FORECAST synthetic estimates, and DECISION verdicts stay separate.
  • Always keep the cold path correct: no request may depend on a provider hit landing.
  • Arm active warming only when the workload clears concentration, false-warm, secret, cold-correctness, and net-value gates.

Legacy Assumptions To Remove

The current architecture already contains many fences, but the operator story still lets old assumptions leak in. Remove these as a matter of product design:

  1. "Provider cache is 99% of the story." Provider cache may dominate token rebates, but it can hide that fak's own agentic mechanisms did not fire. Score the provider plane and the fak-authored planes separately.
  2. "A cache hit is a cache hit." Provider cache hits, local KV hits, vDSO hits, and O(1) context elisions have different trust, cost, and correctness semantics.
  3. "Synthetic Zipf is a default proof." Synthetic concentration is a forecast only. Observed snapshots and measured anchor files must win by default.
  4. "Warm means known." Provider warmth is a belief reconciled after a paid call. False-warm is the dangerous direction and must demote immediately.
  5. "Recall-by-rebuild is generally good." Single-unit chain rebuild is usually a loss. It stays gated off except for amortized fan-out.
  6. "Base URL compatibility equals cache integration." A proxy can front SGLang, vLLM, or llama.cpp without seeing or controlling their cache. Adapter support must state passive, observed, or active.
  7. "O(1) context is just compression." The product claim is queryable durable history plus a bounded resident view. Truncation without query/fault semantics is not the target.

Scoring Refresh

Replace any single "cache score" with a per-plane score and one default-usefulness fold. The fold should be conservative and explainable:

Facet Weight Evidence
Net realized value 25 WITNESSED kernel reuse and/or OBSERVED provider rebate, net of writes and gateway cost.
Agentic activation 20 ctxplan, radixkv, local KV, cachemeta, or vCache control events actually fired, not only provider counters.
Cold-path correctness 15 The full request remains correct without a hit; materialization/admission gates pass.
Granularity 15 Per-family/per-anchor/per-session detail, not one aggregate percentage.
Default coverage 10 Works in guard, serve, pure fak, and at least one external engine context.
Drift resistance 10 False-warm, serializer drift, model/provider vary axes, TTL decay, and secret gates are measured.
Operator actionability 5 The report names the next action: canonicalize, collect telemetry, build index, arm warming, or disable.

The default report should also expose four non-overlapping numbers:

  • provider_rebate: provider-relayed prompt-cache savings, OBSERVED.
  • kernel_reuse: fak-owned KV/prefix reuse, WITNESSED.
  • context_saved_work: O(1) resident-view avoided prefill/query work, WITNESSED or FORECAST with label.
  • agentic_activation: count/rate of fak cache decisions that actually fired.

Next 50 Items

These are ordered for product usefulness, with pure fak and API/provider work first.

Landed-increment annotations (2026-07-04). This page stays a planning artifact — it ranks work, it does not certify shipped behavior. Where an item has since gained a landed increment under epic #1844 / #1490, the row's evidence cell now carries a bold cross-ref (issue + a code/metric witness) so a reader ranking the backlog can tell planned from landed. The cross-ref records the increment only; it does not change the item's own open/closed tracking status (item 26 / #1544 is a live example: the join mechanism is on the wire, yet the issue stays open because the dollar target is not yet met).

# Lane Item Default/evidence target
1 Scoring Define fak.cache.default_usefulness.v1 with the facets above. fak vcache score --json and cachevalue reports can expose per-plane fields without breaking the old schema. Landed (#1519): the fak.cache.default_usefulness.v1 schema and all seven weighted facets (net-realized-value, agentic-activation, cold-path-correctness, granularity, default-coverage, drift-resistance, operator-actionable) are defined in internal/vcachescore/score.go (DefaultUsefulnessReport/DefaultUsefulnessFacets, 029304d0) and ride additively on fak.vcache.score.v1 — witnessed by internal/vcachescore/schema_compat_test.go (b4e0dcbd), which proves both compat halves: the pre-facet JSON still decodes without loss and the current report keeps every legacy key alongside the v1 facets, so the per-plane fields expose without breaking the old schema.
2 Scoring Add agentic_activation counters to the report contract. A provider-only cache run can score provider value high while showing fak-authored cache mechanisms at zero.
3 Scoring Split active_source into provider_observed, kernel_witnessed, context_witnessed, and forecast. No report can imply provider telemetry is fak-owned reuse.
4 Scoring Add a cold-path correctness bit to every cache score. Active warming is refused when correctness depends on a hit.
5 Scoring Make measured anchors outrank synthetic Zipf whenever a snapshot exists. Synthetic is visibly FORECAST; observed family distribution is the default.
6 API/provider Persist the vcachesnapshot live window by default from guard and serve. A finished session leaves a bounded, replayable cache window without extra flags. Landed (#1524), classified gen/now: the default/evidence target is already met by shipped code under epic #1090 — a finished guard or serve session persists its live provider-cache window with NO extra flag. Both front doors write on session exit: guard at cmd/fak/guard_child.go:1355 and serve (plus the shared stdio/http shutdown tail) via persistCacheValueObservations at cmd/fak/serve.go:387, both calling writeConfiguredVCacheSnapshotvcachesnapshot.WriteConfigured, which resolves the well-known per-user path <UserConfigDir>/fak/vcache-turns.jsonl (internal/vcachesnapshot/vcachesnapshot.go ConfiguredPath/DefaultPath) unless FAK_VCACHE_SNAPSHOT=off — the env var only disables/redirects persistence, it is never required to enable it. Bounded on two axes: in-session the live window is a drop-oldest ring capped at vcacheTurnCap = 4096 turns (internal/gateway/vcache_families.go:41,66, ~48 B/turn, well under 1 MB, witnessed by internal/gateway/vcache_families_test.go TestVCacheTurnWindowBounded); across sessions vcachesnapshot.Write truncates on every write (os.Create), so the file holds only the most-recent session's window and never grows unbounded. Replayable via FAK_VCACHE_SNAPSHOT=<path> fak vcache score --json (and the default fak vcache score read path with no --telemetry), each row one vcacheobserve.Turn folded straight through vcacheobserve.Observe with no schema translation. Provenance stays separate — every row carries its per-prefix Family plus distinct provider-telemetry (cache_read/cache_creation/ephemeral_1h/5m) and fak-authored context (fak_context_events/fak_context_shed_tokens) fields (internal/vcacheobserve/vcacheobserve.go Turn), so the fold keeps provider OBSERVED telemetry, kernel WITNESSED reuse, and context/forecast planes distinct. Cold-path correct — the window is purely observational, written best-effort after the session; nothing on the request path reads it, so correctness never depends on a snapshot landing and a write failure never fails the session (internal/gateway/metrics.go:311, Law A2). Witnessed by cmd/fak/vcache_snapshot_test.go (default-on WriteConfigured, off-skip, empty-skip) + internal/vcachesnapshot/vcachesnapshot_test.go. Invalidating assumption named + refuted: the 2026-07-03 dispatch-contract overlay's ## Current state asserted persistence "is not the default at session end — it takes extra flags"; a direct code read refutes it — the #1090 wiring already persists by default, so the residual for #1524 is this closure-binding annotation, not a re-implementation (a code commit would be a no-op/false-close). Promotion evidence: the two write sites reach a normal no-flag session exit and the bounded/off-skip witnesses are green. Demotion/retirement evidence: a future front door that persisted only behind a flag, or a Write that appended instead of truncated, would demote this back to open. Per the #1519–#1528 API/provider pool in GENERATION-CACHE-CONTEXT-PROGRAM-MAP-2026-06-30.
7 API/provider Attach provider vary axes to every provider-cache row: model, endpoint, reasoning mode, tool set, serializer, region/affinity where known. A silent mode switch becomes a distinct cold family, not a blended hit-rate drop. Landed (#1525), classified gen/now: all six vary axes — model, endpoint, reasoning mode, tool set, serializer, region/affinity — are folded into every provider-cache row's family identity, so a switch on any one axis yields a distinct cold family instead of a blended hit-rate drop. The row shape is internal/cachemeta/provider.go ProviderCache (ModelID + Endpoint + ReasoningMode + ToolSetID + SerializerID + Region), and FromProviderCache hashes all six into the entry Digest (DigestBytes(Provider \x00 ModelID \x00 SerializerID \x00 Endpoint \x00 ReasoningMode \x00 ToolSetID \x00 Region)) while also surfacing each present axis as a Labels column; an unknown axis contributes only its separator, honoring "where known" so it never collapses two genuinely distinct families. The live wiring is internal/agent/chat.go providerVaryAxes, which derives endpoint (Z.AI Coding-Plan route), reasoning (reasoning_effort, then thinking.type), a STABLE tool-set digest (toolSetDigest hashes only the tools array, not the per-request body the SerializerID already covers), and an AWS-style region (regionFromBaseURL) from the endpoint host, then attaches them to each provider-cache telemetry row. Witnessed by internal/cachemeta/provider_test.go (TestProviderCacheEndpointAndReasoningModeAreVaryAxes, TestProviderCacheToolSetAndRegionAreVaryAxes: a single-axis switch flips the digest to a new family and never blends) and internal/agent/adapters_test.go (TestHTTPPlannerFoldsGLMEndpointAndReasoningVaryAxes, TestToolSetDigestAndRegionVaryAxisHelpers), on commits a76ee0f36 (cachemeta axes) + 2d4db53f4 (agent wiring, #1525). Provenance stays separate — the row is PlaneProvider / residency=provider with AdmissionDefer, and ProviderCacheVerdict marks it provider_cache=cost_latency_only, never local-kernel trust (refusal rule 6); cold-path correctness is explicit — the vary axes only re-family observational telemetry, no request depends on a provider hit landing. Horizon gen/now per the #1519–#1528 cache-observability/scoring foundation pool in GENERATION-CACHE-CONTEXT-PROGRAM-MAP-2026-06-30 (immediate scoring foundation, focused-test witness, no new serving architecture). Promotion evidence: already at gen/now — the six-axis identity ships on the live HTTPPlanner telemetry path, so no promotion is pending; the downstream lift is item 08 (#1526) firing false-warm/false-cold alarms against these now-correctly-keyed families. Demotion/retirement evidence: a provider that stops keying its implicit cache on one of these axes (e.g. a region-independent global prompt cache) retires that axis to a decorative-only label. Invalidating assumption named + checked: the item assumes these six are the silent cache-breakers and no OTHER axis (sampling temperature, a provider-specific cache namespace) silently re-families the provider cache — the enumerated six match the GLM-5.2 GLM52-HOSTED-CACHE-COHERENCE-2026-06-19.md §A2 coherence findings and the item text, so the assumption holds for the covered providers; a newly-discovered axis would still blend until it joined the digest.
8 API/provider Emit false-warm and false-cold alarms from live traffic, not only offline observe. A believed-warm miss demotes the family and appears in /debug/vars or the session footer. OPEN (#1526), classified gen/now: the false-warm/false-cold detector exists but runs offline/observe onlycmd/fak/vcache.go computes FalseWarmRate/FalseColdRate from captured snapshots (fields at vcache.go:202-203, rendered at :1093/:1361-1362, exercised by cmd/fak/vcache_observe_test.go), and the live front door only appends observed savings after the fact (cmd/fak/serve.go:386 appendObservedCacheSavings over AdjudicationSummary()); no live hook demotes a believed-warm family on an in-flight miss or surfaces the alarm in /debug/vars / the session footer, so the issue's default/evidence target is not yet met. Horizon classified gen/now (immediate cache-observability foundation, focused-test witness, no new serving architecture; #1519–#1528 pool of GENERATION-CACHE-CONTEXT-PROGRAM-MAP-2026-06-30; decisive sibling precedent #1527/item 09, already operator-groomed to generation+gen/now+G0). Implementation stays a cmd/fak (vcache/serve) leaf, NOT a docs-lane close: hook the existing detector into the live request path (serve.go over vcache.go), demote the affected family on a believed-warm miss, and render the alarm in /debug/vars or the session-footer render, witnessed by a focused Go test that drives a live believed-warm miss (and a false-cold case) through the request path and asserts (a) family demotion and (b) the alarm on the watched surface — it fails before the live emitter is wired and passes after. This alarm rides the now-correctly-keyed vary-axis families from item 07 (#1525). Provenance stays separate — provider cached_tokens/cache_read is cost/latency telemetry (MatProviderPrefix), never local-kernel trust; the alarm keeps provider / kernel / context / forecast planes distinct, and cold-path correctness is explicit (a demoted family fails to a full re-prefill, never a stale serve). Promotion evidence (→ resolve): the focused live-miss test green plus captured live-alarm output. Demotion/retirement evidence: a program-map revision moving #1519–#1528 out of gen/now, or the live alarm proving to require the new serving architecture, demotes this to gen/next. Invalidating assumption named + checked: the classification assumes the detector already exists and only needs a live-emission site — confirmed at HEAD (offline observe only, no live hook; git log --grep "#1526" empty, closure unbound); if a new heuristic were required, scope widens beyond this triage. This docs annotation records the classification only; it does not close #1526 — the live-traffic emitter remains the open cmd/fak leaf.
9 API/provider Make provider-cache secret classification default-deny for active warming. Secret/regulated prefixes can still be sent normally, but no pre-warm/pin is scheduled. Landed (#1527), classified gen/now: the secret-class default-deny fence is now the FIRST gate in the warm-admission path — internal/compute/prewarm_admit.go's PrewarmCandidate carries a SecretClassified field and DecidePrewarmAdmission short-circuits a secret/regulated prefix to WarmSkip / ReasonSecretClass (fence 0) AHEAD of every economics fence (byte-known / pool-pressure / timeliness), so no property (byte-known, free pool, inviting window) can schedule a pre-warm/pin for secret content. The default/evidence target — "Secret/regulated prefixes can still be sent normally, but no pre-warm/pin is scheduled" — is witnessed by internal/compute/prewarm_admit_test.go TestDecidePrewarmAdmissionSecretClassDefaultDeny: an otherwise-perfect (byte-known, free-pool, wide-window) secret candidate is refused for warming with a ZERO defer, while a byte-identical NON-secret control still WarmNows; the secret reason also wins over every economics reason (fence 0 dominates); and at the plan/aggregate level the secret candidate rolls into Skipped with zero TokensWarmed — its prefill rows are never scheduled. The fence gates ONLY active warming: the ordinary send path never routes through this decision, so a secret prefix is still SENT normally, it is simply never pre-warmed or pinned. Provenance stays separate — this is a DECISION verdict (ReasonSecretClass), not a provider counter or kernel-reuse witness; cold-path correctness is explicit — a refused warm only ever costs a cold prefill (the status quo), never a wrong answer or a dropped send. This is the security gate that makes epic #1490's default-on warming (rows 06–08, #1524–#1526) safe to arm. Horizon gen/now (immediate cache safety fence, focused-test witness, no new serving architecture; #1519–#1528 pool of GENERATION-CACHE-CONTEXT-PROGRAM-MAP-2026-06-30); this commit citing #1527 is the closure binding the "not yet in the warm-admission path" gap named. Promotion evidence: the fence rides on the pure decision surface with a green unit witness — promotion to a LIVE serve-path witness needs a real classifier feeding SecretClassified at the tool-call boundary (the decision CONSUMES a caller-supplied verdict; it does not itself classify). Demotion/retirement evidence: if a provider offered a proven-ephemeral warm primitive that never persists secret bytes past the turn, the hard default-deny could relax to a per-provider allow. Invalidating assumption named + checked: the fence assumes SecretClassified is set truthfully by an upstream secret/regulated classifier reachable at the warm-admission site — this row consumes that verdict and does not create it, so a boundary that never populates the field leaves a secret prefix warmable until the classifier is wired (the field defaults false); the smallest-increment leaf here is the fence plus its witness, and the live-classifier wiring is the follow-on this row still tracks.
10 API/provider Add exact serialized-prefix fingerprinting to the cache event path. Cache keys are hashes of wire bytes, not logical message structs.
11 Pure fak Promote the O(1) session query path to a first-class CLI/API surface. A user can query a real fak session image without using a demo binary. OPEN (#1529), classified gen/next: the O(1) session-query path exists as library machinery, but no first-class verb runs a content query against a REAL session image, so the evidence target is not yet met. The pieces are all present: the model-callable planner facade ctxplan.PlanQuery.PlanPlanView (internal/ctxplan/query.go, whose own doc-comment fences "a tool wrapper (in cmd/fak or internal/agent) registers this as the model-callable tool … intentionally NOT done here"), the demand-page working-set query recall.Session.Recall(ctx, query, k) over a persisted core image (internal/recall), and the portable, integrity-checked session image itself (internal/sessionimage LoadDir/LoadArchive/Recall()/Rehydrate). A first-class verb already LOADS + integrity-verifies a real image — fak snapshot info --file <dir or .faksession> (cmd/fak/snapshot_cli.gosessionimage.LoadDir) — but it prints only Meta (session_id/model/host/parts/drive); it does NOT run the query. The query is exercised ONLY through demo binaries: fak recall is explicitly "the session-recall demo" (cmd/fak/recall.go — it fabricates a synthetic airline session, then calls Session.Recall), fak snapshot demo fabricates the same, and fak debug --cmd context-plan-preview (cmd/fak/debug_ctxplan.go) plans over SYNTHETIC demoLongRunSpans, never a real image. So "query a real fak session image without a demo binary" is unmet. Horizon gen/next per the #1529–#1548 default-on-vCache pool in GENERATION-CACHE-CONTEXT-PROGRAM-MAP-2026-06-30 (siblings #1532/#1537/#1540/#1563 in the same pool are all gen/next); the surface is runnable soon but still needs the CLI adapter plus a focused real-image test (a default-exposure proof), which is why it is next-gen, not gen/now. Provenance stays separate — a session-query surface reports WITNESSED kernel/context evidence (recall demand-page content + ctxplan resident-view plan), never a provider rebate (provider cached_tokens/cache_read stays cost/latency-only). Cold-path correctness is explicit: the recall query fails closed — a quarantined/sealed page is REFUSED across the image boundary even after a witness clear (content re-screen), and a forecast miss is a recoverable demand-page fault, never a lost fact. Implementation stays a cmd/fak (session-query) leaf, NOT a docs-lane close: this annotation records the classification only and does NOT close #1529 — the first-class real-image query verb remains the open cmd/fak/internal/session leaf named in the issue's own contract overlay. Promotion evidence (→ resolve, → gen/now): the cmd/fak verb built plus a focused Go test that dumps a REAL (non-demo) session image, reloads it via sessionimage.LoadDir, runs the query, and asserts the working-set result, with captured fak <verb> output. Demotion/retirement evidence: a first-class verb already running the query against a real image (absent at HEAD — git log --grep 1529 empty, closure unbound) or a program-map revision moving #1529–#1548 out of gen/next. Invalidating assumption named + checked: the classification assumes the query path needs only a CLI adapter, not a re-implementation — confirmed (PlanQuery.Plan / Session.Recall / sessionimage.LoadDir all exist and compose; only the verb wiring is missing); if the intended host entry point were a different package, the residual leaf moves but the open/gen/next verdict stands.
12 Pure fak Wire ctxplan bounded resident views into the live guard/serve loop in shadow mode. The report says what would be resident, what would fault, and what query would recover.
13 Pure fak Move the planned-elision-to-KV-eviction bridge from proof to live HTTP loop behind a gate. When a span is elided from the resident view, local KV residency shrinks too.
14 Pure fak Turn local radix/prefix reuse into a default in-kernel session option when --engine inkernel is used. Shared stable prefixes are cloned or reused without requiring a benchmark harness. Landed (#1532), classified gen/next: radix/prefix KV reuse is ON by default in the in-kernel session — agent.NewInKernelPlanner constructs the internal/radixkv prefix tree unless FAK_INKERNEL_RADIX=off (internal/agent/inkernel_planner.go NewInKernelPlanner, the runtime gate), and --engine inkernel (the default engine, cmd/fak/serve.go -engine) boots exactly that constructor through the gateway's in-kernel planner boot (internal/gateway/gateway.go:1649). The shared-prefix clone/reuse is witnessed WITHOUT a benchmark harness by internal/agent/inkernel_reuse_test.go (TestInKernelReuseMatchesFullPrefill: a second turn reuses the shared system/tool-schema prefix through an edge split, bit-identical to a full re-prefill on both the f32 and served-Q8 forwards; the PERF/POISON/RACE arms drive the same live planner, no fanbench/ablate). Provenance stays separate: this is WITNESSED kernel KV reuse, not a provider rebate. Cold-path correctness is explicit — a reuse miss fails open to a full prefill, and a device backend keeps authoritative KV in the HAL store (host reuse only where Config.InKernelBackendPrefixReuseSupported, e.g. GLM-MoE-DSA). Horizon gen/next per the #1529-#1548 default-on-vCache pool in GENERATION-CACHE-CONTEXT-PROGRAM-MAP-2026-06-30; this commit citing #1532 is the closure binding the item's "No commit cites #1532" gap named.
15 Pure fak Make paged KV the default under a memory budget once parity witnesses pass on the target models. Pressure relief frees blocks instead of forcing whole-session reset.
16 Pure fak Connect quarantine/result-side rejection to exact-span KV eviction in the served in-kernel path. Poisoned tool output is removed from resident KV, not only from transcript state.
17 Pure fak Add a public prefix-clone API for multi-agent in-kernel fan-out. The 50-turn x 5-agent value stack becomes a product path, not only a benchmark.
18 Pure fak Rehydrate session images into ctxplan plus cachemeta records. Archived work resumes with queryable history and explicit cache invalidation state.
19 Pure fak Put cachemeta.MaterializeVerdict in front of every local cache serve path. Local reuse remains governed by scope, freshness, taint, and quality evidence. Target already governed (#1537), classified triage: a serve-path audit finds the default/evidence target already met — every local reuse serve path is governed by the shared cachemeta materialization key/verdict primitives that MaterializeVerdict itself composes. The cross-tenant/provider gates call it directly: internal/cachemeta/pool.go PoolReuseVerdict returns MaterializeVerdict(MatKVSpan, …) (pool.go:212) and internal/gateway/metrics.go uses MaterializeVerdict(MatProviderPrefix, …) (metrics.go:1401). The two local-KV serve paths fail closed on the SAME axes before serving: internal/radixkv BoundTree.Lookup/Reusable gates on cachemeta.MaterializationKey.Complete/.Matches before touching the tree (binding.go; the bare token-only Tree.Lookup is test-only — no production serve caller), and internal/contextq GateKVView mirrors the identical Complete/Matches + QualityEvidence.Acceptable axes inline (kvview.go:110). Invalidating assumption named + refuted: the contract assumed radixkv/contextq/vdso were UNGATED; verification refutes it. internal/vdso emitStaticHit (cachemeta_emit.go:163, called from vdso.go:394) is an OBSERVABILITY emit lowering a tier-3 static-table serve into a cachemeta hit EVENT, not a KV reuse serve — a tier-3 static answer is keyed by tool name only, args/epoch-independent, and carries no model/tokenizer/position materialization key, so MaterializeVerdict is structurally inapplicable there. Cold-path correctness stays explicit: an incomplete/mismatched key MISSES (fails closed), never serves. Provenance stays separate: pool = kernel-witnessed local reuse, provider_prefix = cost/latency telemetry (never local trust), tier-3 static = args-independent constant. Residual (behavior-preserving, NOT a correctness gap): unifying contextq GateKVView's inline mirror onto a literal MaterializeVerdict call is a gen/next contextq-lane dedup, out of the docs lane and out of this triage's scope. Per the #1529–#1548 default-on-vCache pool in GENERATION-CACHE-CONTEXT-PROGRAM-MAP-2026-06-30.
20 Pure fak Add a turn-tax adaptive planner that picks reuse, query, or cold prefill per turn. Pure fak makes a cache decision by default and records why.
21 API/provider Extend provider telemetry parsing across OpenAI Chat, OpenAI Responses, Anthropic Messages, Gemini, and xAI-compatible responses. All API modes can feed the same scorecard when counters exist.
22 API/provider Preserve Anthropic cache_control and OpenAI-compatible stable prefix bytes through guard/serve transformations. The gateway's safety layer does not defeat provider reuse by rewriting stable prefixes. Landed (part): #1850 gated 1h cache_control TTL upgrade (dbf5aaa4b, witness metric fak_gateway_cache_ttl_upgrade_total) + #1851 uncached-remainder trim (e717e4403, witness metric fak_gateway_uncached_trim_shed_tokens_total), both fak gateway under #1844 C6/C7 (CLOSED). Landed (#1540), classified gen/next: both halves of the preservation contract are repo-witnessed. Anthropic half — the guard passthrough forwards the inbound /v1/messages body byte-for-byte (internal/gateway/gateway_test.go TestAnthropicMessagesPassthroughPreservesCacheAndAdjudicates), every gated body transform keeps the cache_control head byte-identical (ctxview on/off incl. streaming: TestCtxViewHTTPAnthropicPassthrough* / TestCtxViewStreamPassthrough*; compaction/elision prefix boundary: TestMaybeCompactOnShortensKeepsPrefix, internal/gateway/messages_elide_test.go; the #1850 1h TTL upgrade splices on the original bytes, internal/agent/anthropic_cachebp_test.go), the adapter honors a raw Anthropic body verbatim with per-turn sampling re-injection as a no-op (internal/agent/adapters_test.go TestHTTPPlannerRawBodyPassthrough), and the runtime coherence digest (internal/gateway/harness_coherence.go inboundProtectedPrefixDigest) watches the protected prefix live. OpenAI-compatible half — no cache_control grammar exists, so the contract is deterministic append-only re-marshal: internal/agent/openai_prefix_stability_test.go (#1540's contract witness) proves turn N's model+messages head is a byte-prefix of turn N+1's body across all three wire transforms (per-turn sampling/stream re-injection rides behind the head; the pre-send quarantine redaction QuarantineOutboundMessages — the safety layer on this wire — is deterministic and ordinal-stable, so a redacted turn re-serializes to identical stub bytes even after a second quarantine lands behind it; the opt-in OpenAIToolMessagesAsText lowering is per-message and order-preserving), and the openai_ignores_raw_body arm of the same passthrough test proves raw Anthropic bytes never leak onto an OpenAI wire. Provenance separate: provider-prefix reuse stays cost/latency telemetry (MatProviderPrefix, internal/gateway/metrics.go), never local-kernel trust — kernel KV reuse is item 14's separate witness. Cold-path correctness: prefix preservation is an economics property, not a serving dependency — a busted prefix degrades to a provider cache miss and a semantically identical full re-prefill, and quarantine redaction fires regardless of cache posture. Promotion evidence (→ gen/now): a live multi-turn guard/serve run through an active transform whose provider counters stay warm (cache_read_input_tokens on Anthropic, prompt_tokens_details.cached_tokens on OpenAI-compat), folded into docs/nightrun/cache-savings.jsonl. Demotion/retirement evidence: a transform added ahead of the messages head that cannot be made deterministic, or a provider re-keying its automatic cache, demotes this to per-transform gating. Invalidating assumption: OpenAI-compatible servers key their automatic prefix cache on the leading token run of messages (+ tools) and ignore trailing sampling fields — if a served engine hashed the entire raw body, head byte-stability alone would not preserve reuse. Horizon gen/next per the #1529–#1548 default-on-vCache pool in GENERATION-CACHE-CONTEXT-PROGRAM-MAP-2026-06-30.
23 API/provider Add an explicit "passive only" label for providers with no safe active warm primitive. The operator sees observe/preserve/score but no active scheduler.
24 API/provider Implement provider constants as measured records with freshness, not hard-coded defaults. TTL/min-prefix/read-discount are MEASURED or HYPOTHESIS with date and source.
25 API/provider Add a cache-budget dry run to fak guard startup. Before a session starts, the user sees expected uncached budget and cache rebate is not pre-credited.
26 API/provider Join Track 2 provider-dollar rows into fak cachevalue report. Provider-dollar claims become net OBSERVED economics, not token-only proxies. Join live, item still OPEN (#1544): docs/nightrun/cache-savings.jsonl + the two-track fold are joined by fak cachevalue report, but the dollars are DEFAULT-priced projections (pricing_source=default:…), not the net-OBSERVED economics this item targets — see cache-value-rollup.md.
27 API/provider Add provider-cache card fields for write cost, read rebate, hit rate, false-warm, and agentic activation. A high provider hit rate cannot hide zero fak-authored cache decisions. OPEN (#1545): false-warm and agentic-activation card fields still planned. Landed (part): write-premium / read-rebate / spend / net _usd fields in cache-savings.jsonl + the per-owner/per-mechanism attribution card (#1491 CLOSED, with the #2179 CLOSED 1h-write pricing-tier fix).
28 API/provider Add per-family cache review rows to docs/cache-frontier/review-ledger.jsonl. Weekly reviews can say which families are useful, flat, drifting, or disabled.
29 API/provider Gate dedicated warming on break-even, false-warm risk, secret class, and rate headroom. Active warm does not arm just because a prefix is long.
30 API/provider Add send-one-then-fan scheduling for any active provider warm/fan-out path. Dependents wait until the first request has made the prefix readable.
31 External engines Build a cache capability inventory for SGLang, vLLM, llama.cpp, Ollama, and LM Studio. Each adapter row says passive observe, active warm, exact evict, prefix clone, paged KV, or unknown.
32 External engines Add a wire-neutral engine.CacheCapability contract. Gateway reports what the upstream engine can expose without importing engine-specific packages into core.
33 External engines Add a vLLM prefix-cache observation adapter. vLLM-fronted sessions can report observed prefix reuse or explicitly say unavailable.
34 External engines Add an SGLang radix/prefix-cache observation adapter. SGLang-fronted sessions can map radix cache evidence into the same score lanes.
35 External engines Add a llama.cpp/llama-server session-cache observation adapter. llama-backed local sessions report cache state or a passive/no-evidence label.
36 External engines Add adapter conformance tests for "fronted" vs "cache-integrated." A base-url proxy cannot accidentally claim active cache integration.
37 External engines Add active warm/fan-out harnesses only for engines whose capability row proves support. Engine-specific active cache use is opt-in by evidence, not by brand.
38 External engines Add per-engine cold-path correctness witnesses. A cache miss on SGLang/vLLM/llama still sends full required context.
39 External engines Compare pure-fak, vLLM, SGLang, and llama paths on the same session geometry. The value stack is reported as mechanism value plus engine throughput, not blended.
40 External engines Surface external-engine cache lanes in /debug/vars and fak cachevalue report. Operators see whether external engine cache evidence is missing, passive, or active.
41 O(1) context Make "query old session memory" part of the default agent loop contract. Agents stop relying on growing transcripts or stale recall for prior work.
42 O(1) context Add faithfulness/task-success witnesses for bounded resident views. O(1) context claims can graduate from economics to quality-preserving default.
43 O(1) context Add cache invalidation from fak_changes into ctxplan/recalled pages. Cross-agent edits tombstone stale pages before they are served.
44 O(1) context Score resident-view decisions by saved prefill, query latency, and miss/fault rate. Context value is granular and debuggable, not a single compression ratio.
45 O(1) context Tie sys-prompt overlays to cache fingerprints. System prompt changes invalidate affected prefixes instead of silently poisoning reuse. Landed (#1563), classified gen/next: the sys-prompt-overlay→fingerprint tie is a pure, witnessed cachemeta primitive — ComputePrefixFingerprint(resident, overlay) folds the active system-prompt overlay's identity (each after-breakpoint segment's Kind+Content+Witness) into the authoritative Combined prefix fingerprint, and PrefixFingerprint.DecideReuse returns the reuse-vs-invalidate verdict (internal/cachemeta/sysprompt_fingerprint.go, commit d25ed307d). The default/evidence target is proven at the unit level by internal/cachemeta/sysprompt_fingerprint_test.go (4/4 green): with a fixed resident spine+policy span, an UNCHANGED overlay reuses the prefix while a CHANGED overlay (edited body or rotated witness) flips Combined and INVALIDATES the affected prefix (miss → cold prefill), attributed to the overlay (OverlayChanged) and never silently reused; a resident-span edit still invalidates but is not mis-attributed to the overlay. Provenance stays separate — this is a WITNESSED overlay-identity fold that changes WHAT invalidates a prefix, not a provider rebate and not a new serving path (cachemeta stays wire-neutral, taking PromptSegments, never importing syspromptmmu); cold-path correctness is explicit — an invalidated prefix misses and sends the full changed span. Horizon gen/next per the #1559–#1563 pool in GENERATION-CACHE-CONTEXT-PROGRAM-MAP-2026-06-30. Invalidating assumption named + checked: the gen/next class assumes the fold still needs a live serve-path consumer before it delivers product-level default-on reuse safety — verification confirms it (ComputePrefixFingerprint/DecideReuse have no caller outside their witness test, so the resident-vs-overlay PromptSegments are not yet fed from the live serve seam), so the primitive is a ready-but-unwired leaf and promotion to gen/now needs the serve-seam wiring witness (which cachemeta consumer keys the served reuse decision on Combined) — that live-wiring increment is the follow-on this row still tracks open.
46 Remove legacy Add docs/claims lint for cache headlines that omit plane/provenance. "99% cache" or "cache win" without provider/kernel/context labels fails review. Landed (#1564), classified gen/now: the docs/claims lint ships as tools/check_cache_headlines.py — a --audit-tree/--audit-staged gate mirroring tools/check_provenance_labels.py — wired into make ci via a standalone cache-headline-lint target (a pure-Python gate alongside claims-lint/salience, no dos/Go dependency). It flags a cache "win" headline drawn from a fixed set of known legacy shapes ("cache win", "NN% cache", "cache is NN% of the story") that carries NO co-located plane/provenance label, and passes any headline naming a plane (provider / kernel / context / forecast) or a provenance verb (OBSERVED / WITNESSED / FORECAST). The default/evidence target is witnessed by tools/check_cache_headlines_test.py (12/12 green): an unlabeled "99% cache" / "cache win" fixture FAILS the lint while provider-, kernel-, and context-labeled fixtures PASS, and the honest carve-outs (a legacy phrasing quoted to REMOVE it, a real "cache window", a hyphenated hit-rate stat) are not flagged; --audit-tree over the committed corpus is clean (exit 0), proving it false-positive-free. Provenance stays separate — the lint is the enforcement that KEEPS provider/kernel/context/forecast planes distinct in wording; it reads no request path and changes no cache computation, so cold-path correctness is untouched. Narrow by design (like check_provenance_labels): it enforces the label, never the truth of the number (that stays with internal/vcachescore). Promotion evidence: the green unit witness + clean tree audit + the cache-headline-lint ci: wiring. Demotion/retirement evidence: a Go internal/hooks gate + parity test would promote it into the pre-commit fast path (today it is a make ci Python target only, like claims-lint/salience). Invalidating assumption named + checked: the lint's LABEL vocabulary is assumed to cover the plane/provenance words real docs use — a legitimate new headline using a plane name outside the vocabulary would false-red until the vocabulary is extended (staged escape hatch ALLOW_CACHE_HEADLINE_DRIFT=1). Per the #1564–#1568 cache-observability pool in GENERATION-CACHE-CONTEXT-PROGRAM-MAP-2026-06-30.
47 Remove legacy Replace old "provider cache as trust" wording with "cost/latency only" everywhere. The provider-not-trust invariant is impossible to miss.
48 Remove legacy Remove stale docs that imply vCache active provider loop is fully live. Status pages distinguish shipped observe/score from future active warming. Target already met (#1566), classified gen/now: a repo audit finds the default/evidence target already satisfied — no status surface implies the vCache active provider loop is fully live; every one distinguishes shipped decision-witness/observe/score from future/gated active warming. Ground truth is cmd/fak/vcache.go:1261, whose fak vcache status string reads "M5 governor decision witness and provider-action planner live; spendful heartbeat/explicit-cache transport still gated; full vCache provider loop not yet executing warms". The status pages already mirror it: INNOVATIONS-INDEX grades the vCache family MIXED (governor SHIPPED; live transport [STUB]); VCACHE-CONCEPT-REFRESH-2026-06-30 marks M5 "decision witness live; actions gated OFF" and M4 "UP but gated OFF"; vcache-scorecard-playbook says the governor "is live and off-path; calibration/warming/recall stages are issue-tracked"; and FAQ.md already models the honest "why is its KV-residency layer not fully live" form. A repo-wide Select-String for present-tense active-loop overclaims (governor/vCache warms/pins/evicts/routes with no gated/off-path/not-yet hedge) returns zero residual hits — the only "fully live" matches are benchmark arm-A methodology (SESSION-VALUE-STACK-RESULTS.md, the-real-4x.md), unrelated to the provider loop. Provenance stays separate (provider cached_tokens/cache_read is cost/latency telemetry, never kernel trust) and cold-path correctness is explicit (nothing on the request path depends on a warm landing). Horizon gen/now per the #1564–#1568 cache-observability pool in GENERATION-CACHE-CONTEXT-PROGRAM-MAP-2026-06-30 (docs honesty, no new serving architecture); this commit citing #1566 is the closure binding the "no commit cites #1566" gap named. Promotion evidence: the zero-residual overclaim grep plus the vcache.go:1261 ground-truth cross-ref. Demotion/retirement evidence: a doc that reintroduced an unhedged "active provider loop is live" claim, or the loop actually shipping warms (making the honest framing itself stale), reopens this. Invalidating assumption named + checked: the audit assumes the canonical status surfaces are the enumerated set (INNOVATIONS-INDEX, PRODUCT-STATUS, MATURITY-SCORECARD, supported/features, the VCACHE notes, FAQ) — a status page outside that set still carrying the overclaim would reopen the item; the enumerated set is clean at HEAD.
49 Remove legacy Make unsupported active cache paths fail closed with a named reason. Unknown engine/provider capabilities do not silently fall back to optimistic claims.
50 Release gate Add a cache-default readiness gate to maturity/CI. Regressions in per-plane scoring, cold-path correctness, or provenance labels block default-on claims. Landed (#1568), classified gen/now: the release gate is now a NAMED CI target — make cache-default-readiness (Makefile, wired into the ci: chain) runs go test ./internal/vcachescore/ -run '^TestDefaultReadiness' and exits non-zero if the vcachescore.DefaultReadiness fold stops failing closed. That fold (internal/vcachescore/readiness.go, schema fak.cache.default_readiness.v1) is the binary default-on gate: it consumes the per-plane Report and blocks (OK=false, Verdict="blocked") on exactly the three regression classes this row names — per-plane scoring (a provider-only report with a non-default_ready default-usefulness verdict), cold-path correctness (ColdPathCorrect false ⇒ a request that could depend on a hit landing), and provenance labels (any plane whose WITNESSED/OBSERVED/FORECAST label collapses, or a forecast plane that is not kept separate). The default/evidence target is witnessed by internal/vcachescore/readiness_test.go (4/4 green): a witnessed-planes report stays default_ready while a provider-only report, a KernelKV plane flipped to OBSERVED, and an unsupported-active-cache reason each flip the verdict to blocked. Provenance stays separate — the gate's whole job is to refuse a default-on claim that collapses provider/kernel/context/forecast provenance; it reads no request path and changes no cache computation, so cold-path correctness is untouched (it only asserts the cold-path bit). These tests already run inside go test ./... (.github/workflows/ci.yml), so GH enforcement predates this row; item 50's increment is the NAMED, discoverable release-gate entry point (make cache-default-readiness) so "cache-default readiness" is a gate an operator can point to rather than an anonymous unit test. Per the #1564–#1568 cache-observability pool in GENERATION-CACHE-CONTEXT-PROGRAM-MAP-2026-06-30 (CI/docs honesty, no new serving architecture). Promotion evidence: the green go test -run '^TestDefaultReadiness' witness (4/4) + the cache-default-readiness ci: wiring. Demotion/retirement evidence: dropping the target from the ci: chain, or DefaultReadiness gaining a live caller that feeds it a Report built from real per-plane telemetry (which would promote this from a fold-logic gate to a live-report gate), reopens/retires the row. Invalidating assumption named + checked: the gate guards the DefaultReadiness FOLD against constructed Reports — it assumes some producer will feed it a Report built from real telemetry, but DefaultReadiness still has NO caller outside its witness tests (grep -rn DefaultReadiness over cmd/,internal/,tools/ finds only the apihostprobe homonym), so like item 45 this is a ready-but-unwired leaf: the CI gate proves the release-gate LOGIC blocks, not yet that a live default-on decision path is gated. Promotion to a live-report gate needs the serve-seam wiring witness (which consumer builds the Report and calls DefaultReadiness on the real path).

First Wave

The first useful slice is items 1-10 plus 11, 12, 21, 24, 27, 31, 32, 36, 46, and 47. That slice makes the system honest by default before it tries to warm more aggressively:

  1. Reports split provider value from fak-authored cache activation.
  2. guard/serve leave replayable snapshots without flags.
  3. Pure-fak session memory becomes queryable as a product surface.
  4. External engines get a capability vocabulary that prevents overclaiming.
  5. Legacy cache language starts failing review when it hides provenance.

Only after that should dedicated warming, chain recall, or engine-specific active cache paths be armed.

Completion Test

This goal is complete only when a fresh user can run these surfaces and see a coherent, per-plane cache story:

fak guard -- <agent>
fak vcache score --json
fak cachevalue report --since <date> --json
fak cachevalue review --since <date> --json
fak serve --engine inkernel
fak serve --provider openai --base-url <sglang-or-vllm-or-llama-server>/v1

The evidence must prove:

  • provider rebate is visible but not treated as trust;
  • fak-authored cache decisions are counted separately;
  • O(1) context/query is available on a real session;
  • pure-fak local KV reuse and eviction have live-path witnesses;
  • external engine adapters say exactly what cache capability they expose;
  • cold-path correctness remains true when every cache hit misses.