-
Notifications
You must be signed in to change notification settings - Fork 0
Cache
CommitBrief caches LLM responses on disk so re-running a review on an unchanged diff is essentially free.
<repo-root>/.commitbrief/cache/
One JSON file per cached review. The cache is per-repo —
commitbrief cache clear in one repo does not touch another
repo's cache. The directory is gitignored automatically when the
repo's .gitignore is updated by commitbrief setup --local.
SHA-256 over the concatenation:
diff_text + system_prompt + provider_name + model + lang_code + schema_version
Change any one input and you get a fresh review. In practice:
- Editing the diff (staging more files, amending the commit, etc.) → key changes.
- Editing
COMMITBRIEF.md→ key changes (system prompt differs). - Switching providers (
--provider gemini) → key changes. - Switching models (
--model gpt-4o-mini) → key changes. - Switching locale (
--lang tr) → key changes. - Bumping the cache
schema_versionconstant in a future release → all entries invalidate.
JSON document per file:
{
"version": 1,
"created_at": "2026-05-27T18:29:13Z",
"ttl": 604800,
"key": {
"diff_hash": "sha256:abc123...",
"system_prompt_hash": "sha256:def456...",
"provider": "anthropic",
"model": "claude-opus-4-7",
"lang": "en"
},
"result": {
"content": "<LLM response>",
"format": "json",
"tokens": {
"input": 2105,
"output": 526,
"cached": 0
}
}
}key.diff_hash and key.system_prompt_hash are real SHA-256
digests over their respective inputs (since v1.0.0-rc.1 / UC-26 —
pre-v1.0 the diff hash stored the first 16 chars of the composite
cache key, and the system-prompt hash was empty).
result.format is one of:
| Value | Meaning |
|---|---|
json |
Happy path — content is the structured findings JSON. |
markdown-fallback |
LLM produced unparseable JSON twice; content is the raw markdown that was rendered as fallback. |
plain-text |
CLI-tool-backed provider (claude-cli / gemini-cli); content is the host CLI's verbatim output. |
Entries are written via temp file + atomic rename, so an interrupted write (CtrlC mid-review) never leaves a half-written cache file behind. Corrupt entries (JSON unmarshal fails) are silently dropped on next read.
| Source | Value |
|---|---|
cache.ttl_days config |
Whatever you set, in days. |
| Default | 7 days. |
Hardcoded fallback (cache.DefaultTTL) |
7 days. |
An entry whose created_at + ttl < now() is treated as a miss; it
is not auto-deleted on miss (cleanup is commitbrief cache prune's
job). cache.ttl_days: 0 falls back to DefaultTTL = 7 days.
cache.enabled: false in config skips both reads and writes. No
cache directory is created, no Get/Put calls fire. Useful for CI
runners with read-only filesystems or for users who explicitly
want a fresh review every time.
Per-invocation: --no-cache flag.
On a hit, the verbose footer shows Saved: $X (the cost figure
that would have been spent) and tokens are marked as
(local cache hit). The pipeline still rebuilds the prompt (so
the dry-run cache-key matches) but skips the provider call.
# Wipe everything for this repo.
commitbrief cache clear
# Bounded cleanup with defaults (keep newest 500 + last 7 days).
commitbrief cache prune
# Trim aggressively.
commitbrief cache prune --keep-last 100 --older-than 1d
# Per-provider/model scope.
commitbrief cache prune --provider anthropic --model claude-opus-4-7See Cache command for the full flag reference.
- Cards/markdown rendering output. Only the LLM response is
cached; the renderer runs every time. Switching
--markdownon a cached review still works. - Provider latency. The cached entry remembers it for the verbose
footer, but the next invocation reports
0msif a cache hit. - Per-invocation flags that do not contribute to the key:
--verbose,--copy,--output,--compact,--quiet,--fail-on. All applied on top of the cached findings.
The cache schema is internal to CommitBrief, separate from the
public JSON output schema. A future cache-format bump invalidates
all existing entries (the version field is checked on read). No
user action needed; the next review writes fresh entries.