# Kickoff — AI Chatbot multi-audience build

**Created:** 2026-06-12 · **For:** the next working session/agent
**Mission:** execute `plans/ai-chatbot-blueprint.md` on top of the verified
foundation in `plans/agent-architecture-review.md`. Do not relitigate settled
decisions (blueprint §8); spend effort on the open items below.

## Read order (15 min, in this order)

1. This file.
2. `plans/ai-chatbot-blueprint.md` — the spec you are executing.
3. `plans/agent-architecture-review.md` — verified foundation; its
   "RESTRUCTURE NOW" list is the engineering backbone of Phase 1.
4. `plans/agent-capabilities-roadmap.md` — capability × status map.
5. `HANDOFF.md` (most recent sections) — what shipped in the last passes
   (flows modularized, calc_mortgage, silent-turn nudge, prompt-cache
   static/volatile split, input caps).
6. `CLAUDE.md` — build rules, deploy loop, test caps.

## Verified current state (2026-06-12, checked live)

- Runtime: **native PM2** (`channels-api` :3100, `channels-worker`, `n8n`,
  legacy `silver-oak`, `silver-oak-reporting`); Postgres/Redis via systemd;
  health `{"status":"ok","db":true}`. `docs/NEXT-SESSION-PROMPT.md`'s
  docker-compose description is **stale** — ignore it for runtime facts.
- **WhatsApp number suspended** (since ≥2026-06-11). Everything ships
  Playground/eval-first; live canary + cutover wait for the number/WABA.
- Buyer agent live in dry-run form: single-agent tool loop, slot-based
  LeadState, `crm_lead` w/ temperature + buyerType, `calc_mortgage`,
  modular flows, area-guide kb-pack staged (9 guides + 4 figure docs
  pending team verification + 3 structured JSONs in `docs/kb-pack/`).
- Eval harness `tools/agent-eval` exists and gates everything.

## Model decision (operator, 2026-06-12): DeepSeek V4

The target model is **DeepSeek V4** — confirmed directive, no longer a maybe.
The code is already built for this: `LlmClient` speaks the Anthropic Messages
API, which DeepSeek's Anthropic-compatible endpoint accepts, so the swap is a
**connection edit only** (Settings → Connections → `anthropic`: `baseUrl` →
`https://api.deepseek.com/anthropic`, `apiKey`, `model` per DeepSeek docs) —
no code change (`apps/api/src/agent/llm-config.service.ts`). Running on
`claude-haiku-4-5` until the operator provides the DeepSeek key (he will,
on request). The swap still goes through the eval gate before cutover:
tool-selection assertions at the 8–12-tool map + `[[buttons]]` marker-syntax
adherence (marker discipline varies by model). DeepSeek context caching is
automatic prefix-based — the shipped static/volatile prompt split (`1964514`)
is exactly what it rewards; keep it. The swap also retires the Anthropic
50k-TPM concurrency ceiling noted at cutover planning.

## Channels & interactive messages (already built — extend, don't invent)

The agent already does rich messages: it emits a `[[buttons]]` /list marker
block (prompt rules: ≤20-char button labels, ≤24-char list labels, ONE block
per message, only for genuinely discrete options — `system-prompt.ts:178`),
the slot engine asks for missing slots "with buttons/list when options are
discrete" (`lead-state.ts:141`), and inbound button/list taps arrive as
`interactiveId` on the message (`types.ts:20`). WhatsApp caps: 3 reply
buttons, 10 list rows.

Multi-channel direction: the marker syntax IS the channel abstraction — the
agent core stays channel-agnostic, and each channel adapter renders markers
natively (WhatsApp interactive payloads today; a future Instagram/Messenger/
web-widget adapter renders the same markers as its own quick-replies, or
falls back to numbered text options). New channels = new renderer + new
inbound normalizer in the gateway; the agent, slots, KB, and evals are
untouched. Do NOT fork the agent per channel.

## Hard rules (standing, operator-set)

1. **No eval runs or LLM API spend without explicit operator go-ahead.**
   Pace eval runs — the TPM cap 429s back-to-back runs.
2. Slot/field + deterministic rail over prompt prose, always.
3. KB answers ≤3 sentences, steer to the next missing slot.
4. Prompt-cache prefix stays stable: core modules first, volatile last
   (operator steering is last today — keep it that way).
5. Per-turn input budget ≤3.5k tokens.
6. Deploy loop per CLAUDE.md: shared build first → api/worker build →
   `pm2 restart channels-api channels-worker --update-env` → health check.
   Vitest capped at `--pool=forks --poolOptions.forks.maxForks=2`
   (pids.max=1000). Web publish needs the operator (sudo).

## Open items — who owns what

### Agent (engineering) — in this order

- **K1. pgvector + hybrid retrieval** — ✅ CODE LANDED 2026-07-03 (see
  HANDOFF.md same date): guarded migration + `EmbeddingService` + RRF fusion
  in `search_knowledge`, dormant until pgvector installed on the DB +
  `EMBEDDINGS_API_KEY` set (O3). Remaining: deploy, live-DB migration,
  `embedMissing()` backfill (gated), retrieval evals, Arabic mini-eval.
  Original scope (arch-review item 4, blueprint §5.1–3):
  Additive migration: `embedding vector` column on knowledge_chunks; embed
  via **BGE-M3 on OpenRouter ($0.01/1M) or SiliconFlow** (decision made —
  blueprint §8 #7; DeepSeek has no embeddings endpoint); RRF (k≈60) fusion
  with the existing lexical leg inside the same `search_knowledge` tool;
  cache embeddings by chunk hash. Acceptance: retrieval evals pass on the
  existing fixture set; Arabic mini-eval (BGE-M3 vs mE5-large vs
  Qwen3-Embedding) specced and **costed for operator approval** before any
  bulk re-embedding.
- **K2. Tool consolidation to the 8–12 namespaced map** (arch-review item 2)
  + per-intent conditional tool exposure (item 3). Re-validate tool-selection
  evals after ANY model swap.
- **K3. LeadRat credentialed API spike.** Docs: https://apidoc.leadrat.info/
  (Enterprise API) + https://apidocs.leadrat.com/. Known: API key + secret →
  Global Settings → Developer Resources; token endpoint w/ `Tenant` header;
  **token expires in 60 min** (adapter must cache ≤55 min and re-auth);
  unmapped lead params become notes. To verify with real credentials:
  (a) does `PUT /lead` expose a tier/tag/label field → upgrade temperature
  from the `[HOT]/[WARM]/[COLD]` note prefix to a real field;
  (b) assignment semantics (primary/secondary user ids);
  (c) any webhook/poll surface for assignment + stage changes (post-sale
  client sync + returning-lead routing depend on it).
  Ask the operator for the key/secret/tenant — do not hunt for them in n8n
  workflow JSON (they're hardcoded in 01B; moving them to an n8n credential
  is itself an open item in `docs/n8n-migration-runbook.md`).
- **K4. Events table + KPI views + n8n Monday digest** (blueprint §7) —
  ~2 person-days, do it before cutover so the shadow period produces data.
- **K5. Multi-audience router + profiles** (blueprint §2): extend the
  existing deterministic audience route (job-seeker module already exists)
  with staff allowlist (internal mode) and known-client match (post-sale
  intake-only). Each profile = prompt-module set + tool subset + SQL ACL
  (`audience text[]` on kb_documents). Adversarial eval case: client
  persona asked for commission data must refuse.

### Operator — blocks the agent where noted

- **O1.** Go-ahead (and budget) for: Arabic embedding mini-eval; each eval
  expansion run; the DeepSeek-vs-Haiku tool-calling comparison (gates the
  model swap; arch-review item 5b).
- **O2.** LeadRat API key + secret + tenant name for K3.
- **O3.** Provision the embeddings API key (OpenRouter or SiliconFlow).
- **O4.** Chase team verification of the 4 staged figure docs
  (`docs/kb-pack/*-verified.md` + service-charges) → then import via
  `tools/kb-import` and enable. Bot's factual range roughly triples.
- **O5.** WhatsApp number/production-WABA status — when it returns: live
  canary → re-engagement worker → cutover gate (agent-phase-3 plan W3–W5).
- **O6.** Commission ops: post-sale data audit owner (gates Phase 3 status
  flows) + management approval for the listings/inventory source (gates
  property discovery — explicitly pending per the capabilities roadmap).

### Team / ops (not engineering)

- Verify staged figure docs (O4). Post-sale data audit (O6). Owner
  assignment for the 9 knowledge asset classes (blueprint §3).

## What NOT to build (verified premature — arch review)

Multi-agent/orchestrator anything; LLM audience router replacing the
deterministic one; embedding infra beyond pgvector-in-Postgres; hot-lead
alerts / re-engagement / after-hours as *agent tools* (they are deterministic
worker/n8n jobs triggered by agent outputs).

## Definition of done for the next session

At least K1 landed behind the existing `search_knowledge` tool with green
retrieval fixtures (no operator-gated runs needed if you reuse recorded
fixtures), OR K3 completed if the operator supplies credentials first.
Update `HANDOFF.md` when you stop; keep this kickoff current by ticking
items, not rewriting it.
