Skip to content

ADR-0009: Live factual queries (L2-live) and external fetch (Lt-fetch)

Date: 2026-06-15
Status: accepted

Context

Users may ask live factual questions that do not need an LLM:

  • "How is the weather today?"
  • "What's the current price of AAPL?"
  • "Who won the game last night?"

Sending these to L3/L6 wastes tokens and may hallucinate. Better: fetch from a real source, format locally, cache briefly — same philosophy as Lt for dev commands.

This is not L2-dev (coding commands). It is a parallel pattern: L2-live.

Decision

Add L2-live rules + Lt-fetch backends + CCS (short TTL):

L2-live (detect)  →  Lt-fetch (call source)  →  CCS (cache)  →  reply
   rules                 API / search              30–60 min TTL    no model

1. L2-live — factual / live-data rules (extends L2)

Pattern class Examples Lt-fetch backend
weather "weather today", "temperature in SF" Weather API (Open-Meteo, etc.)
web_search "search for X", "latest news on Y" Search API or fetch (configurable)
finance "stock price AAPL" Finance API (if configured)
general_fact low-confidence → escalate to L3 —

Rules in ~/.daari/sources.yaml — user enables providers and API keys.

2. Lt-fetch — external data backends (extends Lt)

Lt-fetch is part of the Tool executor module — not a new tier letter:

daari/tools/
  shell.py      # L2-dev → local commands
  fetch.py      # L2-live → HTTP APIs
  search.py     # optional web search provider
Source type MVP approach Browser?
Weather Structured API (Open-Meteo — free, no key) No
Web search Search API (Brave, SerpAPI, etc.) if user configures key No
Generic URL HTTP GET + extract (readability) No
Browser automation Playwright/Puppeteer Phase C2+ — opt-in; ADR-0010
Google Custom Search API Official JSON API Phase C1 — API key
Browser extension User's Google session Phase C2 — recommended Google auth path

Lt-fetch priority (user config): structured API → Google CSE API → browser extension → L3 fallback.

Default for Phase C1: Open-Meteo + optional Google CSE. Browser extension in C2 for users who want Google login without API keys.

3. CCS for live data

Same Command Context Store as ADR-0008, different TTL:

Query type CCS TTL
Weather 30–60 min
Stock price 1–5 min
News search 5–15 min

Follow-up "what about tomorrow?" may need new fetch or L3 — router decides.

Routing placement

L0 → CCS → L1 → L2-dev → L2-live → L2 generic → Lt (shell | fetch) → L3 … L6

Weather example:

"How's the weather today?"
  → L2-live match (weather)
  → CCS miss (or stale)
  → Lt-fetch → Open-Meteo API
  → format answer locally (template, no LLM)
  → CCS write (TTL 30m)
  → return "72°F, sunny in San Francisco"

No L3/L6 invoked.

Privacy & cost

Concern Policy
Network egress Lt-fetch does call external APIs — user configures in sources.yaml
vs L6 Still cheaper and more accurate than LLM guessing
API keys User-owned, local config
Disable sources.enabled: false → weather queries fall through to L3 or error clearly
Telemetry Off by default (ADR-0006)

Phase

Component Phase
L2-live weather + Open-Meteo B.1 or C1
Web search provider C1 Google CSE API; C2 browser extension
Browser extension (Google auth) C2 — ADR-0010
Browser automation (Playwright) C2+ opt-in
.daari/sources.yaml C1

Not in Phase A tracer bullet.

Module placement

Piece Module
L2-live patterns daari/rules/live_facts.py
Lt-fetch executors daari/tools/fetch.py, daari/tools/weather.py
CCS (live TTL) daari/cache/command_context.py (shared with ADR-0008)
Provider config ~/.daari/sources.yaml

Consequences

Positive - Extends "no AI when unnecessary" beyond dev commands - Accurate live data vs hallucination - CCS avoids hammering APIs

Negative - External dependency + network required for live queries - Not "fully offline" for weather — honest limitation - Browser path is complex; defer to APIs first

  • ADR-0008 — L2-dev + CCS pattern (same shape)
  • PRD user stories #62–64