Caching & resume
Pass A caches each section’s extraction on disk atgraphify-out/.intent_cache/ (next to
graph.json), keyed by a content hash of the exact prompt (source file + section path + body),
the resolved Pass A model, and a fingerprint of the system prompt + schema. Each entry is
written the moment its section completes.
- Automatic reuse. Re-running the same corpus serves already-extracted sections from
cache; only new or edited sections (their body hash changed) re-extract. The pre-flight
estimate, ETA, cost gate,
--dry-runprojection, and the post-Pass-A checkpoint all size Pass A off the cache-miss sections only, so a fully cache-warm re-run projects ~0 calls/tokens for Pass A. - Resume after an abort. If a run aborts (either the mid-Pass-A token breaker or the
post-Pass-A
--max-tokenswhole-run checkpoint before Pass B), every section that finished before the abort is already cached. Just re-run (after raising--max-tokens, or narrowing--docs) and Pass A resumes from where it left off; the abort message says so. --no-cachebypasses the cache completely for the run: no reads, no writes.- Force a refresh by deleting
graphify-out/.intent_cache/; there’s no separate “clear cache” flag. - Use a consistent
--docsspelling. The cache key embeds the source-file path string as--docsproduces it, so re-running against the same docs with a differently-spelled--docs(e.g. relative vs. absolute) can miss the cache even though the files are the same.
What a run costs
On an API backend you pay for real tokens, and it stays cheap. whyfile scales with your docs, not your lines of code (the base graphify graph for source is AST-based and free), so the bill tracks how much prose you point it at. Pass A does the reasoning onsonnet at roughly half
a cent per doc section and dominates the total; Pass B/C/D run on haiku for pennies.
On the default subscription backend there is no per-token bill: the run goes through your
Claude Pro/Max plan, so there is no separate dollar cost. But the run is not free: it still
consumes the estimated tokens in the table below against your plan’s usage limits, the same
tokens an API run would be billed for. “No bill” is not “no cost”.
| Corpus | Doc sections | Intent units | Est. tokens | API cost |
|---|---|---|---|---|
This repo’s docs/adr (measured) | 55 | 62 | 65.6k | ~$0.33 |
| Medium doc set | ~200 | ~225 | 230k | ~$1.18 |
| Large doc set | ~800 | ~900 | 914k | ~$4.71 |
sonnet 15, haiku 4.00 per Mtok). These are cold-cache,
from-scratch figures: because Pass A caches every section, a re-run costs about $0 on API
(only new or edited sections re-extract); on subscription a re-run still costs about zero
tokens, for the same cache-hit reason.
--dry-run and the end-of-run manifest report this honestly: est_cost_usd is a real number on
the API backend, but null on subscription (never 0.0, which would read as free), paired with a
billing note stating the estimated token count and that it counts against your plan.
To see the exact projection for your own corpus before spending anything, --dry-run prints it as
JSON and makes no extraction calls:
Ongoing cost per PR
Updating the intent layer on a PR is cheap: cents on an API backend (a ~$0.03 floor), or a small token draw against your plan’s usage limits on the subscription backend, no separate bill either way. A per-PR update re-anchors existing intent plus any changed doc sections; the Pass A cache means unchanged sections cost nothing on either backend. See What a run costs for the full breakdown.Two CI postures
| Posture | CI cost | Needs a secret? | Freshness |
|---|---|---|---|
| Regenerate in CI | ~cents/PR | Yes (API key) | Always current |
| Committed sidecar | $0 | No | Refreshed by a separate job |
examples/workflows/.