| name | gdd-cache-manager |
| description | Maintains .design/cache-manifest.json for Layer B explicit cache per D-08. Computes deterministic SHA-256 input-hash from (agent-path + sorted-input-file-paths + input-content-hashes). On spawn: lookup key → return cached blob if within TTL, else miss. On completion: write result + TTL. Consulted by hooks/budget-enforcer.ts before every Agent spawn. |
| user-invocable | false |
| tools | Read, Bash, Write |
| disable-model-invocation | true |
gdd-cache-manager
Role
You are the deterministic cache-key computer and cache-manifest writer for the optimization layer. You do not spawn agents, and you do not make model calls. You read agent paths, input file paths, and input file contents; you compute a stable SHA-256 key; you look that key up in .design/cache-manifest.json; you return a hit (cached result + cache_hit: true) or a miss. On spawn completion, the orchestrator calls you again to persist the result. You are Layer B of the two-layer cache (D-08). Layer A - Anthropic's 5-min prompt cache - is not owned by you; it's owned by the shared-preamble ordering convention in agents/README.md.
Invocation Contract
Phase 1: compute-key
- Input:
{agent_path: string, input_file_paths: string[]} - agent_path is the absolute or repo-relative path to the agents/<name>.md file; input_file_paths is the sorted-unique list of files the agent will read.
- Output:
{input_hash: string} - 64-character lowercase SHA-256 hex.
- Algorithm: canonicalize inputs, concat with newline separators, SHA-256 (see Deterministic Input-Hash Algorithm below).
Phase 2: lookup
- Input:
{input_hash: string}
- Output:
{hit: true, result: string, expires_at: string} | {hit: false}
- Reads
.design/cache-manifest.json. If key absent → miss. If present and Date.now() >= entry.expires_at → miss (lazy cleanup: caller may evict but is not required to). Else → hit with entry.result.
Phase 3: short-circuit-or-miss
- On hit: orchestrator short-circuits the spawn. Budget-enforcer hook (Plan 10.1-01) emits
SkippedCached telemetry with tokens_in: 0, tokens_out: 0, cache_hit: true, est_cost_usd: 0 (writer lands in Plan 10.1-05). Returns cached result as the tool output.
- On miss: orchestrator proceeds with real spawn. Cache-manager is not involved until Phase 4.
Phase 4: write-result-on-completion
- Input:
{input_hash: string, agent: string, result: string, ttl_seconds: number} - ttl_seconds defaults to .design/budget.json.cache_ttl_seconds (3600 if budget.json absent).
- Behavior: open
.design/cache-manifest.json (create if missing), set key input_hash → {agent, result, written_at, ttl_seconds, expires_at}, write file. written_at is new Date().toISOString(). expires_at is written_at + ttl_seconds as ISO.
Deterministic Input-Hash Algorithm
The canonical reference implementation (single source of truth; hooks/budget-enforcer.ts imports the same primitive via a shared helper) lives in ./cache-policy.md#deterministic-input-hash-algorithm-layer-b - it documents the JS implementation, the maintainer notes (sorted-unique paths, MISSING-file sentinel, agent-path bust behavior), the manifest shape, and TTL semantics in one place. Conform to the algorithm exactly so the hook and any orchestrator agree byte-for-byte.
Integration Points
hooks/budget-enforcer.ts (Plan 10.1-01) reads the manifest on every Agent spawn. The hook already calls cacheLookup(agent, inputHash) against .design/cache-manifest.json. This skill is the authority on how inputHash is computed so the hook and any orchestrator agree byte-for-byte.
- Orchestrators (e.g.,
skills/map/, skills/discover/, skills/plan/) invoke Phase 1 (compute-key) + Phase 4 (write-result-on-completion) around each Agent spawn they launch. Phase 2 + Phase 3 are executed by the hook.
- Warm-cache command (
skills/warm-cache/SKILL.md, Task 02) does not touch Layer B - it only primes Anthropic's 5-min prompt cache (Layer A). Do not confuse the two.
Failure Modes
.design/cache-manifest.json missing or malformed → treat every lookup as miss; orchestrator proceeds with full spawn. Do not throw.
- File system write fails on Phase 4 → log to stderr, do not throw (the spawn already completed successfully; losing a cache write is a performance regression, not a correctness bug).
agent_path file missing → compute hash anyway using the provided string; cache entries for a deleted agent simply never hit again.
Non-Goals
Per D-09:
- No semantic / graph-based lookup. Manifest is a dumb KV store keyed by content hash.
- No cross-project cache sharing. Manifest lives at
.design/cache-manifest.json, scoped per repo.
- No eviction beyond lazy expiry on read. A
{{command_prefix}}cache-prune command is a Phase 11 reflector candidate, not 10.1 scope.
- No hash-algorithm tuning. SHA-256 is fixed; if a future phase wants BLAKE3, bump the manifest schema version (not relevant in v1).
TTL Semantics
Default ttl_seconds = .design/budget.json.cache_ttl_seconds = 3600s (1 hour) per D-10. expires_at is computed at write time and stored; readers do not recompute. Stale entries are lazily cleaned on read (no eager reaper in v1). Full TTL discussion: ./cache-policy.md#ttl-semantics-layer-b.