---
name: decisions
description: Key architectural and technical decisions with reasoning. Load when making design choices or understanding why something is built a certain way.
triggers:
  - "why do we"
  - "why is it"
  - "decision"
  - "alternative"
  - "we chose"
edges:
  - target: context/architecture.md
    condition: when a decision relates to system structure
  - target: context/stack.md
    condition: when a decision relates to technology choice
last_updated: [YYYY-MM-DD]
---

# Decisions

<!-- HOW TO USE THIS FILE:
     Each decision follows the format below.
     When a decision changes: DO NOT delete the old entry.
     Mark it as superseded, add the new entry above it.
     The history must be preserved — this is the event clock. -->

## Decision Log

<!-- Document key decisions using the format below.
     Include decisions that: are non-obvious, have important constraints,
     or where the reasoning prevents future mistakes.
     Do not document every decision — only ones where "why" matters.
     Minimum 3 decision entries during initial population. If you cannot identify 3,
     write placeholder entries with "[TO DETERMINE]" and explain what decision is pending.

     Format for each entry:

     ### [Decision Title]
     **Date:** YYYY-MM-DD (check git history for real dates when possible)
     **Status:** Active | Superseded by [title]
     **Decision:** [What was decided, in one sentence]
     **Reasoning:** [Why this was chosen]
     **Alternatives considered:** [What else was considered and why it was rejected]
     **Consequences:** [What this means for the codebase going forward]

     Example:

     ### Use PostgreSQL for all persistent storage
     **Date:** 2024-03-01
     **Status:** Active
     **Decision:** All persistent data lives in PostgreSQL, no secondary databases.
     **Reasoning:** Simplicity — one database to operate, backup, and reason about.
     **Alternatives considered:** Redis for sessions (rejected — adds operational complexity for minimal gain), MongoDB for user preferences (rejected — relational model fits our data).
     **Consequences:** No caching layer at database level. Application-level caching if needed.

     Example of a superseded entry:

     ### Use Redis for session storage
     **Date:** 2024-02-15
     **Status:** Superseded by "Use PostgreSQL for all persistent storage"
     **Decision:** Store user sessions in Redis.
     **Reasoning:** Fast read/write for session data.
     **Alternatives considered:** PostgreSQL (chosen later due to operational simplicity).
     **Consequences:** ~~Requires Redis infrastructure alongside PostgreSQL.~~
     **Superseded because:** Maintaining two data stores added operational complexity
     without meaningful performance benefit for our scale. -->

## Token Optimization

### Prompt Caching
When building API integrations with Claude, structure prompts for cache efficiency:
- Place stable content first (system prompt, tool definitions), variable content last (user messages).
- Anthropic caches prompt prefixes automatically. A cache hit costs 90% less than processing.
- Minimum cacheable size: 2,048 tokens (Sonnet), 4,096 tokens (Opus/Haiku).
- Cache TTL: 5 minutes (default) or 1 hour (2x write cost, pays off after 2 reads).
- If tool definitions change, all downstream cache is invalidated — keep tools stable.

### Token-Efficient Tool Use
When using Claude API with tools, add the beta header `token-efficient-tools-2025-02-19`.
This reduces output token usage for tool calls by up to 70% (average 14%).
Available for Sonnet 4.6, Opus 4.6, and Haiku 4.5.

### Why Output Brevity Matters
Output tokens cost 5x more than input tokens across all Claude models.
A single instruction like "keep responses concise" in CLAUDE.md can save more money
than elaborate input-token optimization strategies.
