chore(agent): track .agent/ planning tree in git
Build and Push Containers / build-and-push-app (push) Successful in 12s
Build and Push Containers / build-and-push-db (push) Successful in 10s

Remove the blanket .agent/ gitignore so the phase roadmap, user
stories, reports, and PLAN.md are versioned with the code. Only
runtime artifacts (.agent/phase-sessions/, .agent/pipeline.log)
remain ignored. Update AGENTS.md git protocol rule to match.
This commit is contained in:
2026-09-01 10:18:22 -04:00
parent 5fa620fde5
commit 4971e2859d
818 changed files with 23964 additions and 4 deletions
@@ -0,0 +1,19 @@
All verification complete. The remaining processes are pre-existing user dev servers (not mine) — left untouched.
## Phase 30 — Document Summaries: final verification pass — GREEN
**Verified (no code changes needed; all 6 task files already complete, commit `572a419` in place):**
- `uv run pytest --cov=app --cov-report=term-missing` → **434 passed, TOTAL 99%** (>90% gate)
- `uv run ruff check .` → clean; `uv run pyright` → **0 errors**
- `uv run pytest tests/e2e/test_document_summaries.py -v --no-cov` (isolation) → **2 passed** (sentinel: full source doc, not summary digest, reached the LLM)
- Required existing suites in isolation (`test_chat_rag`, `test_retrieval_quality`, `test_import_documents`, `test_whole_document_context`) → all exit 0; **entire `tests/e2e` dir → exit 0 (120 passed)**
- Real import `uv run python -m scripts.import_docs` (live corpus + live `lite`): 521 files, `summaries=317 summary_errors=1`
**Completion criteria:** all ✅ —
1. SQL-audited: every non-md doc has `summary` + exactly one `is_summary` chunk (pos −1, embedded, pointer line, col==chunk); markdown docs: neither (the single no-summary doc is the criterion-3 case)
2. Live turn: best match = summary chunk → grounded answer from full source doc; per-turn log shows **`summary_hits=2`**
3. Fail-soft proven live: 496-byte file got a runaway 6761-char summary → embed token cap → doc indexed without summary, ERROR logged, counted
4–8. ✅ (tests/coverage, E2E, ruff/pyright, story file, `.env.example` + README both document `BOR_LLM_SUMMARY_MODEL`/`BOR_SUMMARY_MAX_CHARS`)
9. Commit `572a419` exact-message, phase-files-only; phase-dir move is the harness's (task files already moved; leftover `D …/06_mock_and_e2e.md` is harness bookkeeping)
**Notable:** the one live summary failure (filebeat.yaml) is by-design best-effort; a failed summary won't retry on unchanged re-import (locked decision, noted). **Next pending phase: `31_kb_overview_prompt`.**
@@ -0,0 +1,49 @@
........................................................................ [ 16%]
........................................................................ [ 33%]
........................................................................ [ 49%]
........................................................................ [ 66%]
........................................................................ [ 82%]
........................................................................ [ 99%]
.. [100%]
=============================== warnings summary ===============================
.venv/lib/python3.13/site-packages/fastapi/testclient.py:1
/var/home/ducoterra/Projects/Personal/brain_of_reese/.venv/lib/python3.13/site-packages/fastapi/testclient.py:1: StarletteDeprecationWarning: Using `httpx` with `starlette.testclient` is deprecated; install `httpx2` instead.
from starlette.testclient import TestClient as TestClient # noqa
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
================================ tests coverage ================================
_______________ coverage: platform linux, python 3.13.13-final-0 _______________
Name Stmts Miss Cover
--------------------------------------------
app/__init__.py 1 0 100%
app/api/__init__.py 0 0 100%
app/api/auth.py 22 0 100%
app/api/chat.py 98 0 100%
app/api/docs.py 23 0 100%
app/api/health.py 10 0 100%
app/api/steering.py 42 0 100%
app/api/suggestions.py 8 0 100%
app/config.py 62 0 100%
app/core/__init__.py 0 0 100%
app/core/auth.py 20 0 100%
app/core/debugging.py 29 2 93%
app/core/logging.py 13 0 100%
app/db.py 21 0 100%
app/main.py 36 0 100%
app/models.py 48 0 100%
app/rag/__init__.py 0 0 100%
app/rag/chunker.py 206 4 98%
app/rag/importer.py 173 5 97%
app/rag/llm.py 118 0 100%
app/rag/prompts.py 44 0 100%
app/rag/retriever.py 94 3 97%
app/rag/suggestions.py 27 0 100%
app/rag/summarizer.py 24 0 100%
app/schemas.py 68 0 100%
--------------------------------------------
TOTAL 1187 14 99%
coverage gate: app/ 99% (>90%) OK
All checks passed!
0 errors, 0 warnings, 0 informations
validation OK
@@ -0,0 +1,18 @@
Task 01 complete. All criteria met:
**Implemented**
- `app/config.py`: `llm_summary_model: str = "lite"` (env `BOR_LLM_SUMMARY_MODEL`), documented alongside the other LLM settings (A5 extended)
- `app/rag/llm.py`: `LLMClient.chat(messages, model=None)` — non-streaming one-shot (`temperature=0.2`, `max_tokens=2048`, `stream=False`), default model from the new setting, explicit `model=` override; returns stripped content; raises `LLMError` (base URL in message) on transport/HTTP failure, empty `choices`, or empty/missing/whitespace `content`
- `.env.example`: `BOR_LLM_SUMMARY_MODEL=lite` documented
- `README.md`: config-reference row for `BOR_LLM_SUMMARY_MODEL` next to `turbo`/`embed`
- Tests: 8 new `chat()` unit tests (trimmed content + locked params, setting default, model override, HTTP failure wrap + base URL, LLMError pass-through, no choices, missing/whitespace content) + `_FakeCompletion` fake; config tests for default `lite` + env override
**Results**
- `uv run pytest tests/unit/test_llm_client.py tests/unit/test_config.py -v --no-cov` → 46 passed
- `uv run pytest --cov=app --cov-report=term-missing` → 399 passed (baseline 390), TOTAL 99% (1133 stmts / 14 miss — ≥ pre-change; `app/rag/llm.py` 100%)
- `uv run ruff check . && uv run pyright` → All checks passed / 0 errors
**Notes**
- No changes to `embed`/`chat_stream` behavior; no commit made (single phase commit belongs to task 06 per phase completion criteria)
**Next pending task:** `.agent/phases/todo/30_document_summaries/02_migration_summary_columns.md`
@@ -0,0 +1,47 @@
........................................................................ [ 18%]
........................................................................ [ 36%]
........................................................................ [ 54%]
........................................................................ [ 72%]
........................................................................ [ 90%]
....................................... [100%]
=============================== warnings summary ===============================
.venv/lib/python3.13/site-packages/fastapi/testclient.py:1
/var/home/ducoterra/Projects/Personal/brain_of_reese/.venv/lib/python3.13/site-packages/fastapi/testclient.py:1: StarletteDeprecationWarning: Using `httpx` with `starlette.testclient` is deprecated; install `httpx2` instead.
from starlette.testclient import TestClient as TestClient # noqa
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
================================ tests coverage ================================
_______________ coverage: platform linux, python 3.13.13-final-0 _______________
Name Stmts Miss Cover
--------------------------------------------
app/__init__.py 1 0 100%
app/api/__init__.py 0 0 100%
app/api/auth.py 22 0 100%
app/api/chat.py 95 0 100%
app/api/docs.py 23 0 100%
app/api/health.py 10 0 100%
app/api/steering.py 42 0 100%
app/api/suggestions.py 8 0 100%
app/config.py 61 0 100%
app/core/__init__.py 0 0 100%
app/core/auth.py 20 0 100%
app/core/debugging.py 29 2 93%
app/core/logging.py 13 0 100%
app/db.py 21 0 100%
app/main.py 36 0 100%
app/models.py 46 0 100%
app/rag/__init__.py 0 0 100%
app/rag/chunker.py 206 4 98%
app/rag/importer.py 150 5 97%
app/rag/llm.py 118 0 100%
app/rag/prompts.py 44 0 100%
app/rag/retriever.py 93 3 97%
app/rag/suggestions.py 27 0 100%
app/schemas.py 68 0 100%
--------------------------------------------
TOTAL 1133 14 99%
coverage gate: app/ 99% (>90%) OK
All checks passed!
0 errors, 0 warnings, 0 informations
validation OK
@@ -0,0 +1,18 @@
Task complete. Dev DB is at 0004 (head); task 02's files are staged in the working tree (commit belongs to task 06 per the phase's "one atomic commit" criterion).
**Implemented**
- `alembic/versions/0004_summary_columns.py` — new revision (down 0003): adds `documents.summary TEXT NULL` + `chunks.is_summary BOOLEAN NOT NULL DEFAULT false`; reversible downgrade drops both.
- `app/models.py` — `Document.summary: Mapped[str | None]` (Text, default None, phase-30 comment) and `Chunk.is_summary: Mapped[bool]` (Boolean, default False, phase-30 comment), per task spec.
- `tests/integration/test_migration_0004.py` — drives the real Alembic engine (mirrors `test_migration_0002.py`'s information_schema style): upgrade to head → both columns exist with correct types/defaults + insert-without-column defaults `false`; downgrade to 0003 → both gone; upgrade again → round-trip back. Fixture guarantees the dev DB is never left below head.
**Test / lint / coverage**
- `uv run alembic upgrade head` / `downgrade -1` / `upgrade head` — clean round-trip, `alembic current` = 0004 (head)
- `uv run pytest tests/integration/test_migration_0004.py -v --no-cov` — 4 passed
- `uv run pytest` — 403 passed
- `uv run pytest --cov=app --cov-report=term-missing` — TOTAL 99% (models.py 100%, ≥ pre-change)
- `uv run ruff check . && uv run pyright` — clean (0 errors)
**Decisions**
- Migration test runs alembic in-process (`alembic.command` + `Config()` without the ini file, URL from app settings) — the task's round-trip requirement goes beyond 0002's static-state style.
**Next pending task:** `.agent/phases/todo/30_document_summaries/03_summarizer_module.md`
@@ -0,0 +1,47 @@
........................................................................ [ 17%]
........................................................................ [ 35%]
........................................................................ [ 53%]
........................................................................ [ 71%]
........................................................................ [ 89%]
........................................... [100%]
=============================== warnings summary ===============================
.venv/lib/python3.13/site-packages/fastapi/testclient.py:1
/var/home/ducoterra/Projects/Personal/brain_of_reese/.venv/lib/python3.13/site-packages/fastapi/testclient.py:1: StarletteDeprecationWarning: Using `httpx` with `starlette.testclient` is deprecated; install `httpx2` instead.
from starlette.testclient import TestClient as TestClient # noqa
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
================================ tests coverage ================================
_______________ coverage: platform linux, python 3.13.13-final-0 _______________
Name Stmts Miss Cover
--------------------------------------------
app/__init__.py 1 0 100%
app/api/__init__.py 0 0 100%
app/api/auth.py 22 0 100%
app/api/chat.py 95 0 100%
app/api/docs.py 23 0 100%
app/api/health.py 10 0 100%
app/api/steering.py 42 0 100%
app/api/suggestions.py 8 0 100%
app/config.py 61 0 100%
app/core/__init__.py 0 0 100%
app/core/auth.py 20 0 100%
app/core/debugging.py 29 2 93%
app/core/logging.py 13 0 100%
app/db.py 21 0 100%
app/main.py 36 0 100%
app/models.py 48 0 100%
app/rag/__init__.py 0 0 100%
app/rag/chunker.py 206 4 98%
app/rag/importer.py 150 5 97%
app/rag/llm.py 118 0 100%
app/rag/prompts.py 44 0 100%
app/rag/retriever.py 93 3 97%
app/rag/suggestions.py 27 0 100%
app/schemas.py 68 0 100%
--------------------------------------------
TOTAL 1135 14 99%
coverage gate: app/ 99% (>90%) OK
All checks passed!
0 errors, 0 warnings, 0 informations
validation OK
@@ -0,0 +1,12 @@
Everything is green. Final report:
**Task 03 — summarizer module: complete**
- `app/rag/summarizer.py` (new): `SUMMARY_MODE` marker + locked instruction (`SYSTEM_PROMPT`), `build_summary_prompt()` with content capped at `BOR_SUMMARY_MAX_CHARS` (cut at cap + shared `TRUNCATION_MARKER` on overflow), `generate_summary()` calling `llm.chat(..., model=llm.settings.llm_summary_model)` with defensive empty-reply `LLMError` and the code-appended `Source: <source>/<path>` pointer line; `SummaryLLM` protocol (mirrors importer's `Embedder` pattern)
- `app/config.py`: `summary_max_chars: int = 12_000` (`BOR_SUMMARY_MAX_CHARS`)
- `tests/unit/test_summarizer.py` (new, 13 tests) + config default/env-override test; `.env.example` documents the new var
- `uv run pytest --cov=app --cov-report=term-missing` → 417 passed; `app/rag/summarizer.py` 100%, TOTAL 99% (>90%)
- `uv run ruff check .` → clean; `uv run pyright` → 0 errors
- Decisions: marker on its own line after the cut (`content[:cap] + "\n" + marker`); source/path kept in `build_summary_prompt` signature per spec but deliberately excluded from the prompt so the model can't echo the pointer; no endpoint changes (integration is task 05)
Next pending task: `.agent/phases/todo/30_document_summaries/04_importer_summary_integration.md`
@@ -0,0 +1,48 @@
........................................................................ [ 17%]
........................................................................ [ 34%]
........................................................................ [ 51%]
........................................................................ [ 69%]
........................................................................ [ 86%]
......................................................... [100%]
=============================== warnings summary ===============================
.venv/lib/python3.13/site-packages/fastapi/testclient.py:1
/var/home/ducoterra/Projects/Personal/brain_of_reese/.venv/lib/python3.13/site-packages/fastapi/testclient.py:1: StarletteDeprecationWarning: Using `httpx` with `starlette.testclient` is deprecated; install `httpx2` instead.
from starlette.testclient import TestClient as TestClient # noqa
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
================================ tests coverage ================================
_______________ coverage: platform linux, python 3.13.13-final-0 _______________
Name Stmts Miss Cover
--------------------------------------------
app/__init__.py 1 0 100%
app/api/__init__.py 0 0 100%
app/api/auth.py 22 0 100%
app/api/chat.py 95 0 100%
app/api/docs.py 23 0 100%
app/api/health.py 10 0 100%
app/api/steering.py 42 0 100%
app/api/suggestions.py 8 0 100%
app/config.py 62 0 100%
app/core/__init__.py 0 0 100%
app/core/auth.py 20 0 100%
app/core/debugging.py 29 2 93%
app/core/logging.py 13 0 100%
app/db.py 21 0 100%
app/main.py 36 0 100%
app/models.py 48 0 100%
app/rag/__init__.py 0 0 100%
app/rag/chunker.py 206 4 98%
app/rag/importer.py 150 5 97%
app/rag/llm.py 118 0 100%
app/rag/prompts.py 44 0 100%
app/rag/retriever.py 93 3 97%
app/rag/suggestions.py 27 0 100%
app/rag/summarizer.py 24 0 100%
app/schemas.py 68 0 100%
--------------------------------------------
TOTAL 1160 14 99%
coverage gate: app/ 99% (>90%) OK
All checks passed!
0 errors, 0 warnings, 0 informations
validation OK
@@ -0,0 +1,18 @@
Everything is green and verified. The diff is clean — only the intended files changed, and no task/phase/PLAN files were touched.
## Report
**Implemented (task 04 — importer summary integration):**
- `app/rag/importer.py`: `Embedder` protocol gains `chat()`; `ImportSummary` gains `summaries`/`summary_errors` counters in the PLAN §9 log line; non-markdown files get a `lite` summary after the doc+chunks commit — stored on `documents.summary` + one embedded `is_summary` chunk (position −1), best-effort fail-soft (`LLMError`/`EmbeddingError` → rollback, count, log, document kept). Summary storage extracted to `_store_summary()` (behavior identical to the task's inline spec) so the mandated old-summary replacement is directly unit-testable.
- `scripts/import_docs.py`: final print gains `summaries=… summary_errors=…`.
- Tests: `FakeEmbedder.chat` (deterministic, `SUMMARY-BLOWUP` sentinel → `LLMError`), 7 new unit tests (non-md happy path, md exclusion, fail-soft ×2, replacement ×2, log line), integration fixture test extended, `FakeRagLLM` (shared chat fake) gained `chat`, E2E `#stat-chunks` assertion updated for summary chunks.
**Results:**
- `uv run pytest --cov=app --cov-report=term-missing` → 424 passed; app/ TOTAL 99% (98.82% ≥ 98.79% pre-change); `app/rag/importer.py` 97% (>90%)
- `uv run ruff check . && uv run pyright` → clean (0 errors)
- Manual `python -m scripts.import_docs --source <smoke>` vs dev DB + real `lite`: `summaries=2 summary_errors=0` (md skipped), pointer line verified, then pruned — dev KB untouched
- Full E2E: `uv run pytest tests/e2e --no-cov` → 118 passed (incl. all 4 suites named in phase criteria)
**Notable decisions:** summary chunk appended through the `doc.chunks` relationship (sessions run `expire_on_commit=False` — a plain `session.add` left stale collections and could orphan the chunk on same-session re-import); `summary.chunks` counts content chunks only (summary chunks tracked 1:1 by `summaries`).
**Next pending task:** `.agent/phases/todo/30_document_summaries/05_pipeline_summary_resolution.md`
@@ -0,0 +1,48 @@
........................................................................ [ 16%]
........................................................................ [ 33%]
........................................................................ [ 50%]
........................................................................ [ 67%]
........................................................................ [ 84%]
................................................................ [100%]
=============================== warnings summary ===============================
.venv/lib/python3.13/site-packages/fastapi/testclient.py:1
/var/home/ducoterra/Projects/Personal/brain_of_reese/.venv/lib/python3.13/site-packages/fastapi/testclient.py:1: StarletteDeprecationWarning: Using `httpx` with `starlette.testclient` is deprecated; install `httpx2` instead.
from starlette.testclient import TestClient as TestClient # noqa
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
================================ tests coverage ================================
_______________ coverage: platform linux, python 3.13.13-final-0 _______________
Name Stmts Miss Cover
--------------------------------------------
app/__init__.py 1 0 100%
app/api/__init__.py 0 0 100%
app/api/auth.py 22 0 100%
app/api/chat.py 95 0 100%
app/api/docs.py 23 0 100%
app/api/health.py 10 0 100%
app/api/steering.py 42 0 100%
app/api/suggestions.py 8 0 100%
app/config.py 62 0 100%
app/core/__init__.py 0 0 100%
app/core/auth.py 20 0 100%
app/core/debugging.py 29 2 93%
app/core/logging.py 13 0 100%
app/db.py 21 0 100%
app/main.py 36 0 100%
app/models.py 48 0 100%
app/rag/__init__.py 0 0 100%
app/rag/chunker.py 206 4 98%
app/rag/importer.py 173 5 97%
app/rag/llm.py 118 0 100%
app/rag/prompts.py 44 0 100%
app/rag/retriever.py 93 3 97%
app/rag/suggestions.py 27 0 100%
app/rag/summarizer.py 24 0 100%
app/schemas.py 68 0 100%
--------------------------------------------
TOTAL 1183 14 99%
coverage gate: app/ 99% (>90%) OK
All checks passed!
0 errors, 0 warnings, 0 informations
validation OK
@@ -0,0 +1,16 @@
All completion criteria are met. The work is complete:
**Implemented (task 05 — pipeline summary resolution):**
- `app/rag/retriever.py`: `RetrievedChunk.is_summary: bool = False` (documented); `_vector_candidates` passes `chunk.is_summary`; `_LEXICAL_SQL` selects `c.is_summary` and `_lexical_candidates` passes `row.is_summary`; `fuse` unchanged (dataclass passthrough).
- `app/api/chat.py`: `TurnPlan.summary_hits: int = 0`; `plan_turn` computes it from selected-doc ids in **both** HIGH and LOW branches; per-turn log line now reads `… fts_hits=N summary_hits=N tuning=N …` (PLAN §9 extension). Prompts and `select_documents` untouched.
- Tests: 7 new in `tests/unit/test_retriever.py` (flag survives vector/lexical candidates, `fuse` double-hit + lexical-only, legacy default stays False); 4 new in `tests/unit/test_chat_gate.py` (summary on selected top doc → 1, outside top-N → 0, LOW branch counts, no summaries → 0). No prompt changes — existing prompt tests byte-verify.
**Results:**
- `uv run pytest` → **434 passed**
- `uv run pytest --cov=app --cov-report=term-missing` → **TOTAL 99%** (>90%); `app/api/chat.py` 100%, `app/rag/retriever.py` 97% (3 pre-existing uncovered lines, unchanged)
- `uv run ruff check . && uv run pyright` → clean (0 errors)
- Sanity: `uv run pytest tests/e2e/test_chat_rag.py -v --no-cov` → 3 passed
**Decisions:** existing log-format test (`test_steering_api.py`) uses substring asserts, so it needed no change; duck-typed fake sessions in unit tests use the repo's `pyright: ignore[reportArgumentType]` convention; "record in the phase's locked decisions" left to the harness (task/phase files are edit-forbidden).
**Next pending task:** `.agent/phases/todo/30_document_summaries/06_mock_and_e2e.md`
@@ -0,0 +1,49 @@
........................................................................ [ 16%]
........................................................................ [ 33%]
........................................................................ [ 49%]
........................................................................ [ 66%]
........................................................................ [ 82%]
........................................................................ [ 99%]
.. [100%]
=============================== warnings summary ===============================
.venv/lib/python3.13/site-packages/fastapi/testclient.py:1
/var/home/ducoterra/Projects/Personal/brain_of_reese/.venv/lib/python3.13/site-packages/fastapi/testclient.py:1: StarletteDeprecationWarning: Using `httpx` with `starlette.testclient` is deprecated; install `httpx2` instead.
from starlette.testclient import TestClient as TestClient # noqa
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
================================ tests coverage ================================
_______________ coverage: platform linux, python 3.13.13-final-0 _______________
Name Stmts Miss Cover
--------------------------------------------
app/__init__.py 1 0 100%
app/api/__init__.py 0 0 100%
app/api/auth.py 22 0 100%
app/api/chat.py 98 0 100%
app/api/docs.py 23 0 100%
app/api/health.py 10 0 100%
app/api/steering.py 42 0 100%
app/api/suggestions.py 8 0 100%
app/config.py 62 0 100%
app/core/__init__.py 0 0 100%
app/core/auth.py 20 0 100%
app/core/debugging.py 29 2 93%
app/core/logging.py 13 0 100%
app/db.py 21 0 100%
app/main.py 36 0 100%
app/models.py 48 0 100%
app/rag/__init__.py 0 0 100%
app/rag/chunker.py 206 4 98%
app/rag/importer.py 173 5 97%
app/rag/llm.py 118 0 100%
app/rag/prompts.py 44 0 100%
app/rag/retriever.py 94 3 97%
app/rag/suggestions.py 27 0 100%
app/rag/summarizer.py 24 0 100%
app/schemas.py 68 0 100%
--------------------------------------------
TOTAL 1187 14 99%
coverage gate: app/ 99% (>90%) OK
All checks passed!
0 errors, 0 warnings, 0 informations
validation OK
@@ -0,0 +1,19 @@
Task 06 complete. Final report:
**Implemented**
- `mock_llm.py`: `SUMMARY_MODE` branch (before `DEFLECT_MODE`) → byte-stable 24-token digest of the user content (stream + non-stream).
- Story fixture KB `tests/fixtures/summary_kb/`: `quadlet/qwen-llamacpp.yaml` (question-token-dense header comment, diluted 3.3k body, tail sentinel `RESE-SUMMARY-SENTINEL-7f3a`) + `notes/qwen-llamacpp-notes.md` (markdown control, ranks first → yaml last in `<documents>`).
- `tests/e2e/test_document_summaries.py`: sentinel proves summary hit → full source doc; asserts byte-stable summary text, `is_summary` chunk state, summary = yaml's best fused chunk, chips, `deflected=false`; markdown-control test (no summary, raw chunk counts).
- `.agent/user_stories/document-summaries.md`; README "Document summaries" section + `BOR_SUMMARY_MAX_CHARS` table row; one `--no-gpg-sign` commit (`572a419`, 32 files, includes 01–05 todo→complete move).
**Gates (all green)**
- `uv run pytest tests/e2e/test_document_summaries.py -v --no-cov` → 2 passed in isolation (re-run twice, stable).
- Regression in isolation: `test_chat_rag` 3✓, `test_retrieval_quality` 4✓, `test_import_documents` 3✓, `test_whole_document_context` 3✓.
- `uv run pytest` → 434 passed; `uv run pytest --cov=app --cov-report=term-missing` → TOTAL 99% (1187 stmts, 14 miss — equal to pre-change).
- `uv run ruff check .` clean; `uv run pyright` → 0 errors.
- Live log line verified: `top_score=0.678 fts_hits=4 summary_hits=1 … deflected=False`.
**Notable decisions**
- Fixture doc lives in a story-dedicated `tests/fixtures/summary_kb/`, not under the shared `tests/fixtures/docs/` — ~20 suites pin `added == 8` there (task's parenthetical path followed in name only: `quadlet/qwen-llamacpp.yaml`).
**Next pending task:** `.agent/phases/todo/31_kb_overview_prompt/01_migration_kb_overview.md`
@@ -0,0 +1,49 @@
........................................................................ [ 16%]
........................................................................ [ 33%]
........................................................................ [ 49%]
........................................................................ [ 66%]
........................................................................ [ 82%]
........................................................................ [ 99%]
.. [100%]
=============================== warnings summary ===============================
.venv/lib/python3.13/site-packages/fastapi/testclient.py:1
/var/home/ducoterra/Projects/Personal/brain_of_reese/.venv/lib/python3.13/site-packages/fastapi/testclient.py:1: StarletteDeprecationWarning: Using `httpx` with `starlette.testclient` is deprecated; install `httpx2` instead.
from starlette.testclient import TestClient as TestClient # noqa
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
================================ tests coverage ================================
_______________ coverage: platform linux, python 3.13.13-final-0 _______________
Name Stmts Miss Cover
--------------------------------------------
app/__init__.py 1 0 100%
app/api/__init__.py 0 0 100%
app/api/auth.py 22 0 100%
app/api/chat.py 98 0 100%
app/api/docs.py 23 0 100%
app/api/health.py 10 0 100%
app/api/steering.py 42 0 100%
app/api/suggestions.py 8 0 100%
app/config.py 62 0 100%
app/core/__init__.py 0 0 100%
app/core/auth.py 20 0 100%
app/core/debugging.py 29 2 93%
app/core/logging.py 13 0 100%
app/db.py 21 0 100%
app/main.py 36 0 100%
app/models.py 48 0 100%
app/rag/__init__.py 0 0 100%
app/rag/chunker.py 206 4 98%
app/rag/importer.py 173 5 97%
app/rag/llm.py 118 0 100%
app/rag/prompts.py 44 0 100%
app/rag/retriever.py 94 3 97%
app/rag/suggestions.py 27 0 100%
app/rag/summarizer.py 24 0 100%
app/schemas.py 68 0 100%
--------------------------------------------
TOTAL 1187 14 99%
coverage gate: app/ 99% (>90%) OK
All checks passed!
0 errors, 0 warnings, 0 informations
validation OK