# Architecture Decision Records This directory records the **why** behind notable choices in this codebase, so future developers and Claude Code sessions don't re-litigate settled questions or undo hard-won fixes. We use the [Michael Nygard ADR format](https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions); [0001](0001-record-architecture-decisions.md) is the template and the rules. **New to the project? Read this index first**, then open the ADRs relevant to what you're touching before exploring the code. ## How to add one - Copy the section layout of [0001](0001-record-architecture-decisions.md): Context / Decision / Consequences / Rejected alternatives. - Name it `000N-short-title.md`, the next number in sequence. Never reuse or renumber. Never delete — supersede instead (mark the old one `Superseded by [000M]` and link forward). - Add a one-line row to the table below. - Write one whenever you make a non-trivial architectural/design decision, debug something worth remembering, or rule out an approach after real investigation — don't wait to be asked. ## Index | # | Title | Status | Summary | |---|-------|--------|---------| | [0001](0001-record-architecture-decisions.md) | Record architecture decisions | Accepted | Use Nygard-format ADRs in `docs/decisions/`; number sequentially, supersede never delete. | | [0002](0002-ai-first-rendering-with-deterministic-fallback.md) | AI-first price replies with a deterministic fallback | Accepted | Grounded LLM renders prices; deterministic formatters are the fallback; not-found skips the LLM. | | [0003](0003-lexical-search-with-fuzzy-and-abstention.md) | Hand-tuned lexical search with fuzzy matching and an abstention floor | Accepted | Weighted lexical signals + difflib fuzzy + relevance cutoff + score floor (abstain), not embeddings yet. | | [0004](0004-firestore-database-id-pricelystmeta1.md) | Firestore: target `pricelystmeta1` via `database_id=` | Accepted | Fix 404s: use firebase-admin `database_id=`, default DB `pricelystmeta1`. | | [0005](0005-conversation-transcript-and-distillation-store.md) | Capture transcript at transport chokepoints; separate distillation store | Accepted | Log every msg via webhook + wrapped senders into `chat_logs`; grounded pairs go to `training_examples`. | | [0006](0006-promotions-source-and-dynamic-retailers.md) | Promotions from `/api/v1/promotions`; dynamic retailer buttons | Accepted | Use the open promotions feed (`pivot.promo_price`); build retailer buttons from `retailer_id`; deals feed is auth-gated. |