Phase 04 complete — committed as `cbf8e39`. **Implemented** - Honesty gate (A8): `plan_turn()` in `app/api/chat.py` — `top_score < BOR_RELEVANCE_THRESHOLD` ⇒ LOW `DEFLECT_MODE` prompt (weak-hit titles only, never doc content), `deflected` on `done` event + `query_log`; empty KB now honestly deflects too - `app/rag/suggestions.py::derive_suggestions` — deterministic 2–3 "Maybe try" chips from weak-hit titles (fallback top-up from onboarding questions) + `retriever.weak_hit_titles()` - Frontend: amber `.is-deflected` bubble + accessible "Maybe try" chip group (`.suggestion-chip`, ≥44px, `role=list` + `aria-label`); click = fill + focus (submit behavior deferred to Phase 05 per phase spec) - README Troubleshooting: deflection behavior + `BOR_RELEVANCE_THRESHOLD` tuning (incl. 0.0/1.0 extremes) **Results (all green)** - `uv run pytest --cov=app --cov-report=term-missing` → 110 passed, **99%** on `app/` (>90% ✓) - `uv run ruff check .` → clean; `uv run pyright` → 0 errors - `uv run pytest tests/e2e/test_honest_deflection.py -v --no-cov` → **3 passed** in isolation - Regressions: `test_chat_rag.py` 3✓, `test_smoke.py` 3✓, `test_import_documents.py` 3✓; UI verified at 1280px + 375px (amber #fff7e8/#f59e0b, chip contrast, clean mobile wrap) **Decisions:** strict `<` gate (0.30 ⇒ HIGH, per spec); weak hits still reported as `sources` on deflected turns; found & fixed a blank-title bug in suggestion derivation via the new unit tests; updated the stale empty-KB integration expectation (now deflected). **Next pending phase:** `05_story_suggestion_chips.md`