Skip to the content.

Cache-Value Roll-Up

The cache-value roll-up is the front door for reading whether fak’s cache work is paying off. It keeps the kernel-reuse proof and the provider-dollar economics in separate tracks so the report can show a trend without blending unlike evidence.

The Problem

Before the roll-up, cache-effectiveness evidence was scattered across five places:

That made single-session evidence easy to inspect but hard to trend. The roll-up is the reader-facing layer over those sinks: one place to ask what moved, what evidence supports it, and what must not be inferred from it.

The Two Tracks

Track What it answers Evidence Current status
Track 1: WITNESSED kernel value Did fak’s own kernel reuse KV-prefix work on multi-turn sessions? cachevalueledger.Row fields: prompt_tokens, reused_tokens, turn regimes, and weekly buckets from internal/cachevaluereport. Shipped for realized reuse trend.
Track 2: OBSERVED net-dollar savings Did the deployed gateway reduce provider spend after its own costs and provider-cache behavior? cachevaluereport.SavingsRow fields: provider/mechanism, cache read/write tokens, compaction shed tokens, rebate/write/spend/net dollars, and weekly buckets. Shipped 2026-07-02 as a sibling ledger + two-track fold (docs/nightrun/cache-savings.jsonl); live rows accrue as sessions append savings evidence. Provenance caveat (as of 2026-07-04): the read/write token counts are OBSERVED, but the dollar columns are computed at DEFAULT list prices (pricing_source=default:…) — a list-price equivalent, not a metered provider invoice — and non-Anthropic (codex/openai) rows stay dollar_blind. The net-OBSERVED-economics target is still open (#1544; the #2179 1h-write pricing-tier fix has landed). See the 2026-07-04 review.

The tracks stay unblended because they answer different questions. Track 1 is a mechanism proof: fak authored reuse inside the kernel and can witness the token counters. Track 2 is an economic outcome: the provider bill, prompt-cache discount, and gateway overhead decide whether the mechanism saved money. A combined number would hide the failure mode where reuse is real but not net-positive, or where dollars improve for a reason unrelated to kernel reuse.

Fleet Aggregate

fak cachevalue report also prints Fleet aggregate, an all-time roll-up by default (or caller-windowed with --since). It joins the two cache ledgers with .fak/nightrun/gateway-usage.jsonl (the live runtime default of --usage-ledger) so long-horizon guard use has cumulative counters:

Fleet Posture Census

The aggregate above answers “what did the ledgers record?”. fak cachevalue census (#3650) answers the live-fleet question the trust-but-verify epic needs first: how much of the fleet running right now has managed cache ACTIVE, and among those, how many ever fired a 1h-TTL upgrade?

fak cachevalue census          # render the census: ACTIVE share, and upgrade-fired share among ACTIVE
fak cachevalue census --json   # the same fold as JSON, for a periodic poster or dashboard

It reads the guard-session index every fak guard launch appends to, keeps the LIVE rows, GETs each worker’s /debug/vars with that session’s read-scoped bearer, and folds the managed_cache posture block (guardvars.ManagedCacheVars) into fak-managed-cache-adoption-census/1cachevaluereport.FoldCensus, pure and deterministic: rows in, report out. Three rules keep both headlines honest:

This is deliberately not the weekly digest’s posture-adoption line (#3646), which INFERS posture from durable exit rows and so reads an ACTIVE worker that fired nothing as passive. The census reads the resolved posture flag off the live worker, so ACTIVE-with-no-evidence and genuinely PASSIVE stay distinct. It is a diagnostic read, not a gate: a mostly-PASSIVE fleet reports MOSTLY_PASSIVE and still exits 0, and an empty or entirely dark fleet reports INSUFFICIENT rather than a fabricated zero. Cadence today is the weekly digest plus an operator running the census on demand; --json is the poster-ready surface if the census itself is ever put on a schedule.

Session Shapes

The views above answer “how much reuse did we get, and did it move?”. fak cachevalue shapes (#3115) answers the orthogonal question the week × session_type trend hides: which KINDS of sessions earn KV-prefix reuse? It re-folds the same Track-1 WITNESSED kernel ledger into (length × outcome) clusters — cachevaluereport.FoldShapes (internal/cachevaluereport/shapes.go), pure and deterministic, rows in, report out — so a reader can see whether a handful of long warm sessions carries most of the realized reuse while single-turn cold runs dominate the row count, a fact the time trend averages away.

fak cachevalue shapes                        # the static (length × outcome) cluster table
fak cachevalue shapes --json                 # the same fold as fak-cache-value-shapes/1 JSON
fak cachevalue shapes --trend                # each shape's week-over-week reuse-share drift
fak cachevalue shapes --ledger PATH --since 2026-07-01

The one-line synopsis and full flag surface live in the CLI reference under fak cachevalue shapes.

Both axes are modelling choices, not findings

The band edges are cutoffs the fold chose, not breaks measured in the data. They are code constants in internal/cachevaluereport/shapes.go, pinned by go test ./internal/cachevaluereport — read them there rather than trusting a number retyped into prose.

Length band (turn count; MinShortTurns, MinLongTurns):

Band Turns Why this boundary
single 1 A single-turn run has no previous turn to reuse from. It is structurally reuse-free, so it gets its own band instead of being averaged into a reuse number it could never earn.
short 2–4 >= 2 is the multi-turn floor the rest of the ledger already uses; the shape view inherits it rather than inventing a second definition of “multi-turn”.
long >= 5 A chosen split that gives “does a long trajectory earn its warm KV?” a clean population — not a measured elbow. If the corpus later shows a different natural break, this constant is the one place to move it.

Outcome band (realized reuse ratio = reused_tokens / prompt_tokens; coldOutcomeMax, warmOutcomeMin):

Band Realized reuse Why this boundary
n/a — (single-turn only) Never folded into cold. Recording a structurally impossible reuse as a cold failure would slander the shape and inflate any “we run cold” reading.
cold < 0.10 Below a tenth of prompt tokens reused, a multi-turn session paid essentially full prefill every turn. The tenth is a legible round number, not a measured cliff.
partial 0.10< 0.50 The near-miss band: reuse is happening, but most of the prompt is still re-prefilled.
warm >= 0.50 Majority of prompt tokens reused. Half is a deliberately conservative, legible line — not a target, a ratchet, or a claimed steady state.

health — the failure mode a neutral cluster list buries

health is a pure function of the (length × outcome) pair (classifyHealth), not a separate measurement. It exists so the expensive failure class cannot hide in a table that treats every cell as equally interesting:

health Clusters Reading
earning any warm, plus single × n/a Fine. The single × n/a cluster is earning by definition — reuse-free by structure, not by failure.
weak short × cold, short × partial Cheap and low-stakes: a 2–4 turn session that earns little reuse wastes little.
underwarmed long × partial A near-miss worth a look.
wasteful long × cold The expensive failure: turn after turn of full prompt cost with effectively no realized KV-prefix reuse. The report also surfaces it as wasteful_sessions / wasteful_session_share, and names it in next_action (check for cache-busting prefix churn).

--trend — the longitudinal complement

The static table is one all-corpus snapshot. --trend swaps it for cachevaluereport.FoldShapeTrend (fak-cache-value-shape-trend/1): the same clustering run within each ISO week, then each shape’s within-week share of reused tokens compared with that same shape’s previous week, using the report’s existing reuseEpsilon dead-band (internal/cachevaluereport/cachevaluereport.go) so flat means “inside noise” exactly as it does on the weekly card. Every point is new / improved / flat / regressed, and the header names which shapes gained and lost share in the latest week.

Read it for the signal the snapshot cannot show: a shrinking long × warm share of reused tokens is an early regression even while the headline reuse ratio holds, because it means the reuse is migrating to shapes that carry fewer tokens.

The fence, and reading an empty ledger

The #1066 fence below applies verbatim to both shape reports: the outcome bands are cut on WITNESSED realized reuse (reused_tokens / prompt_tokens) only, and the vs-naive 1/(1-reuse) re-prefill multiple is never computed. Both envelopes carry the self-labels publishable_value_family and vs_naive_multiple_excluded: true, so a downstream card cannot mistake one for the other.

The default --ledger is docs/nightrun/cache-value.jsonl, a gitignored local nightrun artifact. On a fresh checkout it is absent, and the verb reports the empty read rather than a fabricated zero. Running fak cachevalue shapes on a tree with no ledger prints:

cache-value session shapes (Track 1, WITNESSED kernel reuse) — INSUFFICIENT
  0 session(s), all single-turn; no multi-turn shape to cluster reuse on yet
  fence: marginal-over-tuned-warm-KV (~1.0x single-session; the vs-naive 1/(1-reuse) re-prefill multiple is excluded per #1066)

That INSUFFICIENT is the thin-corpus fence falling open, not a broken verb — ok stays true and the verb exits 0. Point --ledger at your own Track-1 JSONL to fold rows meanwhile.

No populated cluster figures are quoted here. The populated table is per-machine, local, and moves every nightrun, so any number retyped into this doc would rot silently and could not be re-derived. Run the verb against your own ledger and read the columns it prints:

Column Meaning
length, outcome, health the cluster key and its classification, as above
sessions, turns rows and turns folded into the cluster
reuse the cluster’s aggregate reused_tokens / prompt_tokens
sess% the cluster’s share of all sessions
reuse-tok% the cluster’s share of all reused tokens — the column that shows a rare shape carrying most of the reuse
by session_type attribution back to the front door (guard / serve / run), so a shape stays traceable to where it came from

Honesty Fences

Reading The Card

A cache-value card should be read top-down:

Reproduce

The shipped Track-1 witness on current main is:

fak nightrun score --json

That command reads docs/nightrun/cache-value.jsonl, excludes single-turn cold runs, prints the realized reuse ratio, and carries the #1066 self-labels. The weekly fold behind the roll-up is pinned by:

go test ./internal/cachevaluereport

The cachevalue front-door spelling for a dated operator report is:

fak cachevalue report --since 2026-06-22

To answer “how much longer did this extend a long-horizon session?” for a known budget:

fak cachevalue report --since 2026-06-22 --context-budget-tokens 150000

The Slack/feed spelling uses the same two ledgers and can be previewed without posting:

fak cachevalue feed --since 2026-06-22 --context-budget-tokens 150000 --dry-run

For the cache-frontier product review, generate the human note and appendable JSONL row from the same ledgers:

fak cachevalue review \
  --since 2026-06-22 \
  --date 2026-06-29 \
  --source-markdown reviews/2026-06-29.md \
  --append-ledger docs/cache-frontier/review-ledger.jsonl \
  --markdown-out docs/cache-frontier/reviews/2026-06-29.md

Use --json without --append-ledger to inspect the row first. The review artifact is still a planning artifact: it keeps Track 1 and Track 2 separate, names thin or missing evidence, and points to the missing dogfood/product witnesses.

Grafana Surface

The roll-up is not only a Slack card — the same two-track fold is exposed as a live Grafana dashboard so an operator can watch it move over time and see the offline feature ablation alongside it. The pipeline pulls straight from the durable logs, so it needs no live gateway:

  1. Expositionfak cachevalue metrics folds the SAME three ledgers (cache-value.jsonl, cache-savings.jsonl, gateway-usage.jsonl) via the identical cachevaluereport.FoldTwoTrackWithUsage recipe the Slack card uses, plus the fak ablate report JSONs under experiments/ablate/, and renders a Prometheus text exposition under the fak_cachevalue_* (P&L) and fak_ablation_* (feature arms) namespaces. Because it reuses the report fold, the dashboard and the fak cachevalue feed card can never drift — they are two projections of one number.
  2. Scrapefak cachevalue metrics --serve --addr 127.0.0.1:9097 serves /metrics, re-folding the ledgers on each scrape (so ledger appends show up live). Prometheus scrapes it as the fak_cachevalue job (tools/grafana/prometheus.yml), and tools/grafana/up.sh starts it beside the gateway/fleet sources.
  3. DashboardFAK Cache Value — Roll-up & Ablation (uid fak-cache-value-rollup, generated by tools/grafana/gen_dashboard.py, provisioned from tools/grafana/dashboards/). It carries the headline verdict + cumulative NET $, Track-1 realized reuse, the Track-2 owner-split P&L and run-rate, and the ablation per-arm speedup — every $ panel labelled OBSERVED/projected and split by owner, so the honesty fence above survives into Grafana.
  4. Report into Slack — the dashboard is registered in docs/grafana/links.json (category rollup), so fak grafana post --rollup (the scheduled #grafana feeder, tools/register_grafana_rollup.ps1) folds its link into the channel card.

The Prometheus families are not dollars-blended: fak_cachevalue_saved_token_equiv, fak_cachevalue_api_cost_avoided_usd, and fak_cachevalue_usd_avoided_per_day each carry an owner="provider|fak|total" label, and every _usd family is an OBSERVED/projected cost model (never a fak-WITNESSED dollar). The ablation fak_ablation_arm_speedup_ratio is baseline_mean / arm_mean from a $0 deterministic replay — a WITNESSED replay counter, not a live provider claim. A metric that would be NaN (e.g. a nil pointer field) is omitted rather than emitted as a zero, and fak_cachevalue_report_present stays 1 whenever the exporter is alive, so a dead scrape is distinguishable from a real zero.

Preview the exposition without a stack:

fak cachevalue metrics                    # render the fak_cachevalue_* + fak_ablation_* families to stdout
fak cachevalue metrics --serve            # serve /metrics on 127.0.0.1:9097 for Prometheus
python tools/grafana/gen_dashboard.py     # regenerate the dashboard JSON after a metric rename

See Also