refactor(agents): migrate .agent/ planning tree to .agents/

Standardize on the .agents/ directory (shared with project skills):
phases/, user_stories/, reports/, screenshots/, validate.sh, and
phase-sessions/ + pipeline.log all move to .agents/ (git mv preserves
history; runtime artifacts move alongside).

Updates every reference in AGENTS.md, README.md, .gitignore, app
docstrings, and test story headers. Historical KB content in data/
and the runtime pipeline.log transcript are left untouched.
This commit is contained in:
2026-09-05 10:57:07 -04:00
parent 766702c750
commit dbf2af26c6
1118 changed files with 664 additions and 664 deletions
@@ -0,0 +1,14 @@
Everything is green. Final report:
**Phase 33 — Cache Busting: final verification pass (all tasks pre-completed in commit `8fabb7e`; no code fixes needed)**
- Verified: `asset_version()` (git short SHA `8fabb7e` = HEAD here; 12-hex content-hash fallback + `"dev"` — all branch-tested), `CachingMiddleware` wired in `create_app()`
- Criteria: ① all 5 pages + `/index.html` → `Cache-Control: no-cache`, every `href`/`src` asset ref versioned `?v=8fabb7e` (incl. slash-less `assets/markdown.js`), zero unversioned refs, token stable across pages/requests — **PASS** (live curl + E2E)
- ② `/assets/*` → `public, max-age=31536000, immutable` (versioned and unversioned URLs) — **PASS**
- ③ `/api/*` + SSE untouched: no `cache-control` on `/api/health`; SSE streams to `done`; no-CDN test green — **PASS**
- `uv run pytest --cov=app --cov-report=term-missing`: **551 passed**, TOTAL 1453 st / 12 miss = **99%** ≥ pre-change baseline 1359 / 12 = 99% (measured at parent `52136fe` in a temp worktree, since removed); `app/core/caching.py` 100% — **PASS**
- `uv run pytest tests/e2e/test_cache_busting.py -v --no-cov`: **3 passed** in isolation; `test_smoke.py` **3 passed**; `test_chat_rag.py` **3 passed** (isolated) — **PASS**
- `uv run ruff check . && uv run pyright`: **clean** (0 errors) — **PASS**
- Story file `.agents/user_stories/cache-busting.md` + README "Caching / deploys" section exist; one `--no-gpg-sign` commit with the prescribed message exists; phase file move to `complete/` in place (harness finalizes the overview) — **PASS**
- Notes: commit `8fabb7e` also carries two documented prod-image defect fixes from its podman smoke (Containerfile ships `scripts/`; compose.yaml passes admin env vars). Pre-existing working-tree changes (harness phase-file moves for 30–32, owner TODO.md items) left untouched per protocol.
- Next pending phase: **none** — `todo/` contains only this phase.
@@ -0,0 +1,53 @@
........................................................................ [ 13%]
........................................................................ [ 26%]
........................................................................ [ 39%]
........................................................................ [ 52%]
........................................................................ [ 65%]
........................................................................ [ 78%]
........................................................................ [ 91%]
............................................... [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 103 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/api/sync.py 67 0 100%
app/config.py 64 0 100%
app/core/__init__.py 0 0 100%
app/core/auth.py 20 0 100%
app/core/caching.py 92 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 40 0 100%
app/models.py 53 0 100%
app/rag/__init__.py 0 0 100%
app/rag/chunker.py 206 4 98%
app/rag/importer.py 173 3 98%
app/rag/llm.py 118 0 100%
app/rag/overview.py 71 0 100%
app/rag/prompts.py 64 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 1453 12 99%
coverage gate: app/ 99% (>90%) OK
All checks passed!
0 errors, 0 warnings, 0 informations
validation OK
@@ -0,0 +1,15 @@
Task 01 complete — token returns `52136fe` (current git short SHA) with cache hits working. Report:
**Implemented**
- `app/core/caching.py`: `asset_version(static_dir: str | None = None)` — git short SHA (`git -C <repo-root> rev-parse --short HEAD`, 5s timeout) when the static dir's parent has a `.git`; SHA-256 content-hash fallback (sorted `relpath:mtime_ns:size`, 12 hex) on no-git/failure; `"dev"` for missing/empty dirs; per-process cache via `@functools.cache` (== `lru_cache(maxsize=None)`, forced by ruff UP033 — semantically identical to the locked decision).
- `tests/unit/test_caching.py`: 11 tests — git path (token == repo short SHA, cached hit verified), settings-default path, fallback (12-hex, deterministic, flips on size change, flips on mtime-only change), git failures (missing/timeout/non-zero exit/empty output → content hash, no raise), missing/empty dir → `"dev"`; autouse fixture `cache_clear()`s between cases.
**Results**
- `uv run pytest tests/unit/test_caching.py -v --no-cov` → 11 passed
- `uv run pytest --cov=app --cov-report=term-missing` → 526 passed (baseline 515); `app/core/caching.py` 100%; TOTAL 99% (12 missed — identical to pre-change baseline, so ≥ pre-change)
- `uv run ruff check .` → All checks passed
- `uv run pyright` → 0 errors, 0 warnings
**Decisions**: `functools.cache` over literal `lru_cache(maxsize=None)` spelling (ruff UP033; behavior identical). Empty-output git guard covered by a dedicated test.
**Next pending task**: `33_cache_busting/02_caching_middleware.md`
@@ -0,0 +1,53 @@
........................................................................ [ 13%]
........................................................................ [ 27%]
........................................................................ [ 41%]
........................................................................ [ 54%]
........................................................................ [ 68%]
........................................................................ [ 82%]
........................................................................ [ 95%]
...................... [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 103 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/api/sync.py 67 0 100%
app/config.py 64 0 100%
app/core/__init__.py 0 0 100%
app/core/auth.py 20 0 100%
app/core/caching.py 37 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 38 0 100%
app/models.py 53 0 100%
app/rag/__init__.py 0 0 100%
app/rag/chunker.py 206 4 98%
app/rag/importer.py 173 3 98%
app/rag/llm.py 118 0 100%
app/rag/overview.py 71 0 100%
app/rag/prompts.py 64 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 1396 12 99%
coverage gate: app/ 99% (>90%) OK
All checks passed!
0 errors, 0 warnings, 0 informations
validation OK
@@ -0,0 +1,19 @@
All green. Task 02 complete.
**Implemented**
- `app/core/caching.py`: `HTML_PAGES`, `rewrite_asset_refs()` (regex append `?v=<token>`, idempotent via `[^"?#]+`), `CachingMiddleware` (BaseHTTPMiddleware: `/assets/*` → `public, max-age=31536000, immutable` header-only; 5 HTML pages → `no-cache` + body rewrite via buffered `body_iterator` drain; everything else incl. SSE byte-identical), `configure_caching(app)`
- `app/main.py`: `configure_caching(app)` wired after routers in `create_app()`
- Unit: 12 new rewrite/middleware-branch tests in `tests/unit/test_caching.py` (incl. failure fallbacks, `_read_body` both branches); `tests/unit/test_main.py` asserts middleware present by name
- Integration: 5 new tests in `tests/integration/test_api.py` (pages `no-cache` + `?v=` token, `/index.html` variant, assets immutable, `/api/health` no injected header)
**Results**
- `uv run pytest --cov=app --cov-report=term-missing` → 551 passed; `app/core/caching.py` 100%, TOTAL 99% (≥ pre-change)
- `uv run ruff check .` → clean; `uv run pyright` → 0 errors
- Live curl: `/` → `no-cache` + `?v=52136fe` (git short SHA) on all ref styles; `/assets/styles.css` → immutable; `/api/*` untouched; SSE streams intact (endpoint's own `no-cache` preserved)
- E2E in isolation: `test_smoke.py` 3 passed, `test_chat_rag.py` 3 passed
**Decisions**
- starlette 1.6.0 has no `StreamingResponse.body()` helper and `call_next`'s `_StreamingResponse` is *not* a `StreamingResponse` subclass — drained `body_iterator` with a targeted pyright ignore; rewrite-failure path re-serves the buffered original bytes so a page can never be lost
- No commit made — the phase's atomic `--no-gpg-sign` commit belongs to task 03
**Next pending task:** `.agents/phases/todo/33_cache_busting/03_e2e_and_docs.md`
@@ -0,0 +1,53 @@
........................................................................ [ 13%]
........................................................................ [ 26%]
........................................................................ [ 39%]
........................................................................ [ 52%]
........................................................................ [ 65%]
........................................................................ [ 78%]
........................................................................ [ 91%]
............................................... [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 103 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/api/sync.py 67 0 100%
app/config.py 64 0 100%
app/core/__init__.py 0 0 100%
app/core/auth.py 20 0 100%
app/core/caching.py 92 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 40 0 100%
app/models.py 53 0 100%
app/rag/__init__.py 0 0 100%
app/rag/chunker.py 206 4 98%
app/rag/importer.py 173 3 98%
app/rag/llm.py 118 0 100%
app/rag/overview.py 71 0 100%
app/rag/prompts.py 64 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 1453 12 99%
coverage gate: app/ 99% (>90%) OK
All checks passed!
0 errors, 0 warnings, 0 informations
validation OK
@@ -0,0 +1,17 @@
Phase 33 task 03 complete — all gates green.
**Implemented**
- `tests/e2e/test_cache_busting.py` (3 tests, fresh-profile Chromium wire assertions): document responses `no-cache`; CSS/JS request URLs carry `?v=<token>` (same token, matching `asset_version()`); asset responses `public, max-age=31536000, immutable`; `/sources.html` + `/login.html` share the token; `/api/health` has no injected `cache-control`; SSE chat streams deltas → `done` (mock LLM)
- README "Caching / deploys" section; `.agents/user_stories/cache-busting.md`
- Fixed two prod-image defects found by the podman smoke (app wouldn't boot): `Containerfile` now ships the `scripts/` package (phase 32's `app/api/sync.py` imports it at module level → `ModuleNotFoundError`), and `compose.yaml` passes `BOR_ADMIN_PASSWORD`/`BOR_SESSION_SECRET` through (`:-` defaults keep `up -d db` working)
**Results**
- `uv run pytest tests/e2e/test_cache_busting.py -v --no-cov` → 3 passed (isolated, re-run post-commit)
- `uv run pytest tests/e2e/test_smoke.py` / `test_chat_rag.py` (isolated) → 3 + 3 passed
- `uv run pytest` → 551 passed; `--cov=app` → TOTAL 99% (`app/core/caching.py` 100%, ≥ pre-change)
- `uv run ruff check . && uv run pyright` → clean
- `podman compose --profile prod up -d` (fresh image) + fresh Chromium: all 3 pages `no-cache`, all 8 asset requests versioned with one token, assets immutable — recorded in commit message
**Commit:** `8fabb7e perf(ui): cache busting — HTML no-cache + versioned asset URLs (?v=) with immutable 1y asset caching` (`--no-gpg-sign`, 12 files, phase-32-style task-file renames).
**Next pending task:** none — `todo/` held only `33_cache_busting` (harness moves it on success).
@@ -0,0 +1,53 @@
........................................................................ [ 13%]
........................................................................ [ 26%]
........................................................................ [ 39%]
........................................................................ [ 52%]
........................................................................ [ 65%]
........................................................................ [ 78%]
........................................................................ [ 91%]
............................................... [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 103 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/api/sync.py 67 0 100%
app/config.py 64 0 100%
app/core/__init__.py 0 0 100%
app/core/auth.py 20 0 100%
app/core/caching.py 92 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 40 0 100%
app/models.py 53 0 100%
app/rag/__init__.py 0 0 100%
app/rag/chunker.py 206 4 98%
app/rag/importer.py 173 3 98%
app/rag/llm.py 118 0 100%
app/rag/overview.py 71 0 100%
app/rag/prompts.py 64 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 1453 12 99%
coverage gate: app/ 99% (>90%) OK
All checks passed!
0 errors, 0 warnings, 0 informations
validation OK