# Cache Discipline

> Content-Keyed Cache Discipline

- Skill: `poloplay0114/cache-discipline` (Agent Skill)
- Install (CLI): `npx skillmds@latest add poloplay0114/cache-discipline`
- Raw SKILL.md: https://api.skillmd.com/api/skills/poloplay0114/cache-discipline/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: poloplay0114 (https://skillmd.com/u/poloplay0114)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/poloplay0114/cache-discipline

---


# Content-Keyed Cache Discipline

## When to use this

Any time you think "this was already computed / already verified, don't do it again" — build artifact
caches, incremental testing, flattened data-page caches, memoization, cross-period artifact stores.
A cache is the first blade you reach for on performance, and **correctness's most insidious enemy**:
when a cache serves a wrong value, the value itself looks entirely reasonable (it *was* correct once),
only **the source is stale** — and nothing about it feels absurd enough to alert you at the moment it
happens. The most insidious bug a cache can ship: a plausible value from a stale source.
This skill is about making "fast" not something you pay for with "correct."

---

## Core rules

### Rule 1: A shortcut is provable equivalence, not a skipped check

"It hit the cache, so we don't recompute or re-verify" is legitimate only because of a provable chain
of reasoning: **same content key → same bytes → same result, and those bytes were fully verified at
the moment they were built**. Break any of the three links and the shortcut is a hole in verification.
- Key does not match → **fall back to the full path, or bark**; never wave it through as "doesn't
  match but probably close enough." Waving it through silently is a hole.
- The last link in the chain (verified at build time) is Rule 4.

### Rule 2: Keys must be composite; a bare hash is the doorway to silently wrong values

A content key is at minimum a three-part composite: **content hash + size + identity (path/name)**.
- A short hash (a 32-bit CRC, say) used alone as a key can, in theory, be shared by two different
  contents — and the consequence of a collision is not an error, it is **silently serving the old
  content as the new** (last period's data page served as this period's), so everything downstream is
  correct and every source is wrong.
- Adding size blocks "content changed, hash happened not to"; adding identity blocks "the same hash in
  different places eating each other." All three would have to coincide at once, which pushes the
  probability down to engineering-negligible.
- Key selection has its own economics too: a hash you can read straight from container metadata
  (no decompression) beats one that requires expanding the full content — the entire reason the cache
  exists is to save that expansion (for the cost reasoning, see engineering-economy).

### Rule 3: Every cache entry carries a manifest, is verified on open, and never serves a value silently

Each cache entry writes a manifest **at the moment the write completes**: the source composite key +
scale statistics (row count / cell count) + a content digest + (where applicable) which verification
layers it already passed. **Verify the manifest before every use**:
- Mismatched / missing / truncated (a half-seeded entry from a crash) → **treat it as a miss and
  re-seed**, and log the event; never serve a suspect entry as a good one.
- The digest must be able to catch "same row count, content tampered" (an XOR or rolling digest, not
  just counting rows).
- Keep **breaking tests on standby**: truncate an entry → it must bark and re-seed; tamper with the
  content → the digest must not match and it must bark; forge a manifest → it must bark. A gate whose
  pre-check barks is a gate (echoing verification-discipline's "never trust a self-report" — a cache is
  a form of self-report too).

### Rule 4: A hit propagates the proof (the cache entry carries the verification conclusion)

An ordinary cache only saves the computation; recording in the manifest **which verifications this
content passed when it was built** means a hit also legitimately propagates the conclusion "already
verified" — **the cache becomes the carrier of a verification conclusion**, and that is what makes
incremental verification valid (for the parts that did not change, last time's pass still holds).
Two preconditions, and it is fake without either:
- The verification done at build time was **complete** (everything that layer should verify was
  verified, not a spot-check masquerading as a full one);
- "Did not change" means **Rule 1/2-grade unchanged** (the composite key matches), not "nobody seems to
  have touched it."
Any check the cache lets you skip must be traceable to an equivalent completion at build time — you are
saving repetition, not coverage (echoing verification-discipline's "should be there and isn't").

### Rule 5: Cache hygiene — the cost you saved must not grow back somewhere else

A cache trades disk for time, and that ledger has to stay positive over time:
- The cache directory has a **size limit and an eviction policy** (LRU by mtime, for instance); a cache
  without a limit is a slow disk leak.
- **Orphan keys must be reclaimable**: entries whose source no longer exists, or that can never be hit
  again, must be identifiable and removable.
- Every entry **reports its own disk usage** so the total ledger is visible — "how much faster" and
  "how much space" must both be measurable, not felt.

### Rule 6: One scan feeds many consumers

Seeding a cache already requires scanning the source completely — that scan is a **cost already paid**,
so extract everything later consumers will want into the same cache entry along the way (values +
statistics + verification inputs + domain signals) instead of having each consumer scan for itself.
- The anti-pattern: the production flow scans once for values and the verification flow scans again for
  statistics — the same large source expanded twice, with the cache rescuing only half of it.
- Extracting things opportunistically to "record now, assert later" also pays off: the signal sits in
  the manifest, and when you do wire up a check it is a one-line change with no rescan needed
  (for a gate whose decision is not yet made, get the ingredients ready first).

---

## Case files from this project (supporting evidence, not required for the general rules)

- **Rules 1/2 together**: one financial-reporting automation project's dependency-page cache used a
  three-part composite key (CRC32 + uncompressed size + part path) — the reviewer asked three separate
  times for "the key's complete composition" before letting it through, on the grounds that "this cache
  feeds the current period's correctness directly; a collision means silently serving the wrong
  period." Reading the CRC straight from the ZIP central directory, avoiding decompressing 296MB, is
  exactly Rule 2's key-selection economics.
- **Rule 3**: the cache entry (a SQLite value store) verifies its manifest on open (quick_check + cell
  count), with a deep check via an XOR digest to catch "same cell count, values tampered"; both
  breaking tests (truncate → re-seed with correct values; tamper → digest mismatch) actually barked
  before it was accepted.
- **Rule 4**: thanks to "verify at build time + record the passed layers in the manifest," the
  verification stage skipped re-parsing the dependency page entirely (a huge sheet with 245K formulas)
  — one report's verification went from a 150-second full load to point lookups, while not a single
  cell of the seven-dimension cell-by-cell verification on the report page was skipped: repetition
  saved, coverage not.
- **Rule 5**: LRU eviction plus disk-usage reporting were pushed into the first version by the reviewer
  on "don't move the waste elsewhere" grounds, rather than added afterwards.
- **Rule 6**: values and page-level statistics land in the same SQLite in the same streaming pass;
  period signals were extracted into the manifest opportunistically, to "record now, assert later" —
  the corresponding gate was still with the decision-maker at the time, so the ingredients were
  prepared, and wiring it up after the ruling was a one-line change.
- **Sister skills**: the equivalence gate sitting at the content layer, and coincidence windows being
  false greens → verification-discipline, Comparison 5; a cache's cost ledger and performance
  assertions → engineering-economy Rule 12; the streaming physics of seeding a cache from a large file
  → xlsx-surgery Rule 8.

