ADR-0015: Local-first product boundaries (scope gate)¶
- Status: Accepted
- Date: 2026-07-30
- Context: LinkedIn / B2C chatbot scope — embedded assistants get used as free ChatGPT, burning tokens off-product.
Decision¶
Daari enforces an optional product boundary before L0–L6 routing:
- Configurable —
boundaries.enabled(default off),mode: warn|block, and a full editable definition (product description, allow/deny topics, examples, thresholds, stage toggles) via config.yaml, env, andPATCH /v1/daari/config. - Local-first ladder — B0 topic/example overlap (optional L1-embedder cosine) → B1 cheap local judge on ambiguous → B2 N-vote local quorum → B3 rare frontier judge (off by default; daily USD cap).
- Hard refuse when clearly out and
mode: block— responsetier=boundary, zero model tokens. - Warn/dry-run — classify and attach
daari_meta.boundarybut still answer, to tune false-refuse rate.
Consequences¶
- Distinct from F2 regex guardrails (injection/PII) and Lt PolicyEngine (tool allow/deny).
- Org policy sync may push the full
boundariesblob and rebuild the engine. - Learning proposals (
propose-boundaries) stay review-gated; never auto-promote.
Alternatives rejected¶
- System-prompt only (“stay on topic”) — models ignore.
- Always-on frontier judge — defeats token savings.
- Regex-only deny lists — too brittle alone (kept as B0 assist).