Skip to content

feat(synthesis): cache per-article map extracts to skip redundant LLM calls#192

Merged
bryanmatthewsimonson merged 1 commit into
mainfrom
feat/corpus-map-cache
Jul 18, 2026
Merged

feat(synthesis): cache per-article map extracts to skip redundant LLM calls#192
bryanmatthewsimonson merged 1 commit into
mainfrom
feat/corpus-map-cache

Conversation

@bryanmatthewsimonson

Copy link
Copy Markdown
Owner

Problem

Corpus synthesis re-ran the entire map (one LLM call per member) on every "Analyze corpus" click. Nothing persisted the per-article extracts — xray-audits stored only runs/predictions/resolutions/case-briefs, and only the final brief was saved. So running synthesis 3× over a 129-member case paid for ~3× the map, which is the bulk of the cost (129 map calls vs 1 reduce). (The audit runs cache, keyed by article hash, is a separate feature; the corpus map path was uncached.)

Fix

A corpus-extracts store (xray-audits v3), keyed by corpusExtractKey — a SHA-256 over the exact map inputs: sent text + claim digest + case framing + CORPUS_PROMPT_VERSION.

  • The runner checks the cache before the confirm dialog, so the spend preview reads "N of M cached — reused for free."
  • Cached members short-circuit with no LLM call; misses call and persist the extract.
  • The reduce still runs each time (one call, must see the full current extract set).

Effect: after run 1, a re-run over an unchanged corpus costs only the reduce call; adding one article costs one map call, not 129.

Invalidation falls out of the key

  • Body edit → memberText changes → new key.
  • A Suggest pass adds claims → claim digest changes → that article (and only it) re-maps — which is exactly right (deliberately keyed on inputs, not the article hash alone, or it would serve a stale extract after claims were added).
  • Prompt bump → version changes → new key.

Quality

No wire kind, no prompt change — identical outputs, brief quality unchanged. This is pure cost reuse. (Pairs with #191: the claim-join fix enriches inputs; this makes re-running cheap enough to A/B the brief.)

Verification

  • New tests: corpus-extracts store CRUD + v1/v2 coexistence across the v3 upgrade; corpusExtractKey determinism + each invalidation trigger. Updated the backup dump-shape assertion for the new store.
  • npm test → 1973 pass · npm run build clean · npm run lint 0 errors.

🤖 Generated with Claude Code

… calls

Corpus synthesis re-ran the entire map (one LLM call per member) on every
"Analyze corpus", because nothing persisted the per-article extracts —
only the final brief was saved. Three runs over a 129-member case paid
for ~3x the map, which is the bulk of the cost.

Adds a corpus-extracts store (xray-audits v3) keyed by corpusExtractKey:
a SHA-256 over the exact map inputs (sent text + claim digest + case
framing + CORPUS_PROMPT_VERSION). The runner checks the cache before the
confirm (spend preview shows "N of M cached — reused for free"),
short-circuits cached members with no LLM call, and persists each miss.

Invalidation falls out of the key: a body edit changes the text; a
Suggest pass changes the claim digest (so that article re-maps); a
prompt bump changes the version. The reduce still runs each time (one
call over the full extract set). After run 1, an unchanged corpus costs
only the reduce; adding one article costs one map call, not 129.

- keyed on inputs, not article hash, so a claims change re-maps correctly
- cache rides the export-included audit DB; reconcilable, never auto-dropped
- no wire kind, no prompt change — identical outputs, brief quality unchanged
- tests: store CRUD + v1/v2 coexistence; key determinism + invalidation

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@bryanmatthewsimonson
bryanmatthewsimonson merged commit 51b6a69 into main Jul 18, 2026
1 check passed
@bryanmatthewsimonson
bryanmatthewsimonson deleted the feat/corpus-map-cache branch July 18, 2026 16:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant