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,17 @@
Both commits are in; only the owner's live `TODO.md` remains uncommitted (deliberately). Final state verified — the working tree matches the committed code exactly, so all green results above apply to the committed state.
## Phase 27 completion report
**Verified (final pass — no code defects found, nothing to fix):**
- `PUT /api/steering/{note_id}` + `SteeringNoteUpdate` schema (200/404/422/403 paths, `created_at` preserved)
- `/tuning.html` + `tuning.js` CRUD, `header.js` admin-only `#nav-tuning`, Containerfile bundles the new page
- Story E2E `test_global_tuning.py`: 6/6 green in isolation (create-no-chat, inline edit, delete, edit-steers-answer via mock `<tuning>` echo, a11y/no-CDN, anonymous 403s)
- Regressions in isolation: `test_steering` 4/4, `test_header_consistency` 3/3, `test_document_viewer` 7/7, `test_smoke` 3/3, `test_document_back_navigation` 3/3
**Results:** `uv run pytest --cov=app --cov-report=term-missing` → 366 passed, TOTAL 99% (≥ pre-change 99%); `uv run ruff check . && uv run pyright` → clean.
**Criteria:** all 11 green — #1–#5 via E2E+integration (prompt reflection covered by `test_update_is_reflected_in_list_load_and_prompt`); #6–#8 as above; #9 UI check via E2E a11y test + no-CDN integration param; #10 story file present; #11 commit made (below).
**Decisions:** phase-26 work was never committed (its executors left it "to the harness"), so I made the retroactive atomic phase-26 commit `fcde1fd` first, splitting the mixed files (`styles.css`, `test_api.py`) hunk-wise; phase-27 commit `589e26d` stages only phase-27 files. Owner's in-progress `TODO.md` left uncommitted. "Tuning" header link lives on the tuning page's own header per task-04 spec (ships hidden, revealed for admin).
**Next pending phase:** `28_git_based_sources` (task `01_env_var_and_settings.md`).
@@ -0,0 +1,47 @@
........................................................................ [ 19%]
........................................................................ [ 39%]
........................................................................ [ 59%]
........................................................................ [ 78%]
........................................................................ [ 98%]
...... [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 55 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 105 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 1114 14 99%
coverage gate: app/ 99% (>90%) OK
All checks passed!
0 errors, 0 warnings, 0 informations
validation OK
@@ -0,0 +1,16 @@
All green. Task complete.
**Implemented**
- `app/schemas.py`: added `SteeringNoteUpdate` (trim-before-length-constraint, mirroring `SteeringNoteIn`)
- `app/api/steering.py`: added `PUT /api/steering/{note_id}` (in-place update, `created_at` preserved, 404 unknown id) + docstring naming the route and its reuse of the router-level `require_admin`
- `tests/unit/test_steering.py` (new): 6 tests — 200 updated/trimmed with `created_at` preserved, 2000-char boundary, 404, 422 invalid id, 422 empty/blank/2001, anonymous 403 `admin only` via the real `require_admin`
- `tests/integration/test_steering_api.py`: 6 new tests — 200 replace (DB row + preserved `created_at`), update reflected in `GET` list order + `load_steering_notes` + `build_steering_section`, 404, 422/boundary, anonymous 403 with text untouched
**Results**
- `uv run pytest --cov=app --cov-report=term-missing` → 363 passed, TOTAL **99%** (`app/api/steering.py` + `app/schemas.py` 100%)
- `uv run ruff check .` → clean; `uv run pyright` → 0 errors
**Notable**
- Renamed `tests/integration/test_steering.py` → `test_steering_api.py` (`git mv`): the task-mandated unit filename `tests/unit/test_steering.py` collides with it (pytest import mismatch; phase-15 report shows this collision pattern was previously dodged by naming). No code referenced the old path.
**Next pending task:** `02_tuning_page_html_css.md`
@@ -0,0 +1,47 @@
........................................................................ [ 19%]
........................................................................ [ 39%]
........................................................................ [ 59%]
........................................................................ [ 79%]
........................................................................ [ 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 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 55 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 105 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 1114 14 99%
coverage gate: app/ 99% (>90%) OK
All checks passed!
0 errors, 0 warnings, 0 informations
validation OK
@@ -0,0 +1,13 @@
**Task 02 complete — `/tuning.html` page + CSS**
- New `frontend/tuning.html`: standard app frame (skip-link, shared header, landmarks, footer); centered 46rem column with "Global Tuning" head, `#tune-form` (labeled textarea + "Add note"), `#tune-announcer` live region, `#tune-list` + `#tune-empty`; admin-only `#nav-tuning` (is-active) ships hidden, revealed by header.js
- `styles.css`: "Global tuning page" block (`.tuning-note` rows with dividers, ellipsizing text, brand Edit / error Delete ≥44px, `.is-editing` inline-form state, `#tune-form`/`#tune-save` composer-style, italic centered `#tune-empty`) + mobile tweaks; Phase-08 tokens, no blur/CDN
- `header.js`: `#nav-tuning` toggled for admin (same contract as `#nav-sources`)
- Minimal `frontend/assets/tuning.js` boot stub (initSharedHeader + New-chat binding) — forced by the phase-23 Containerfile parity tests, which require every page's module to exist, import `./header.js`, and be bundled; `Containerfile` stage 1 gained the tuning.js bundle + tuning.html cp lines
- Tests extended: `/tuning.html` in no-CDN + no-emoji + served checks; `test_shared_header.py` pins nav-tuning ship-hidden/is-active and the new-chat binding on tuning.js
Results: `uv run pytest` → 366 passed · `uv run pytest --cov=app` → TOTAL 99% (≥ pre-change) · `uv run ruff check . && uv run pyright` → clean · E2E regressions in isolation: test_shared_header 6 ✓, test_header_consistency 3 ✓, test_smoke 3 ✓, test_steering 4 ✓ · visual check (headless Chromium, 1280px + 360px, anon + admin): layout, active nav pill, ellipsis, inline-edit card all correct
Decisions: `#nav-tuning` ships hidden + header.js reveal (phase criterion "hidden for anonymous" + phase-19 pattern) rather than task-04's looser "ships visible" note; no commit — the tree carries uncommitted phase-26 + task-01 work, and the atomic `--no-gpg-sign` phase commit belongs to phase completion (task 04).
Next pending task: `03_tuning_js_crud.md` (tuning.js CRUD + announcer).
@@ -0,0 +1,47 @@
........................................................................ [ 19%]
........................................................................ [ 39%]
........................................................................ [ 59%]
........................................................................ [ 78%]
........................................................................ [ 98%]
...... [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 55 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 105 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 1114 14 99%
coverage gate: app/ 99% (>90%) OK
All checks passed!
0 errors, 0 warnings, 0 informations
validation OK
@@ -0,0 +1,19 @@
Everything is verified green. The `-q` summary-line quirk is a pytest reporter artifact under this shell (plain `uv run pytest` prints the count and exits 0) — unrelated to this change.
## Task 03 report — `frontend/assets/tuning.js` (tuning page CRUD)
**Implemented**
- `tuning.js` (was the task-02 header-boot stub, now full CRUD owner): `loadNotes()` (GET, keeps last list on failure), `renderNotes()` + `syncEmptyState()`, per-row `.tuning-note-text` (textContent, XSS-safe) + Edit/Delete (delete carries `aria-label "Delete tuning note: …"`), create form (POST; 201 → clear + announce "Tuning note added. Future answers will follow it." + reload; non-2xx keeps form + inline `.tuning-error` with API detail; `#tune-save` disabled in flight), inline edit (`.tuning-edit-form`, prefilled `maxlength=2000` textarea, note id on `data-note-id`, PUT → `.tuning-saved` role=status + "Tuning note updated."; failure keeps form; cancel reverts), optimistic delete (204/404 → row out + announce, 404 reloads; else re-enable + retry)
- Boot: `initSharedHeader()` then `loadNotes()` only when cached `fetchIsAdmin()` is true (Sources-page gate pattern); task-02 New-chat binding preserved
**Verification**
- `uv run pytest` → 366 passed, 0 failed
- `uv run pytest --cov=app --cov-report=term-missing` → TOTAL 99% (gate >90%)
- `uv run ruff check .` → clean; `uv run pyright` → 0 errors
- Live Playwright smoke (throwaway, removed): anon 403s + hidden nav + empty state + graceful form 403; admin create/edit/cancel/delete round-trip, newest-first, XSS note renders as text, announcer messages exact — all passed
**Decisions**
- Gated `loadNotes()` on `fetchIsAdmin()` per the task's explicit boot spec (same cached whoami — one request)
- "Saved" pill persists until the row is re-rendered (deterministic; mirrors app.js)
**Next pending task:** `todo/27_global_tuning/04_header_button_and_e2e.md` (header button + `tests/e2e/test_global_tuning.py` + phase commit)
@@ -0,0 +1,47 @@
........................................................................ [ 19%]
........................................................................ [ 39%]
........................................................................ [ 59%]
........................................................................ [ 78%]
........................................................................ [ 98%]
...... [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 55 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 105 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 1114 14 99%
coverage gate: app/ 99% (>90%) OK
All checks passed!
0 errors, 0 warnings, 0 informations
validation OK
@@ -0,0 +1,15 @@
Task 04 complete. Report:
**Implemented**
- `tests/e2e/test_global_tuning.py` (new, the story gate) — 6 tests: create-without-chat (+ Postgres persist, announcer, cleared form), inline edit (pre-filled form, Cancel revert, Save, "Saved" pill, in-place update), delete (row removed, `#tune-empty` back), edit-steers-answer (create + edit on `/tuning.html`, then chat turn echoes `(tuning: EDIT-MARKER …)` via the mock's first-`<tuning>`-line trick), a11y/no-CDN (landmarks, working skip-link, labeled controls, ≥44px targets, `:focus-visible` Tab walk, dark theme, live-region contrast pairs ≥4.5:1, all refs same-origin/`data:`), anonymous (hidden admin nav links, empty list despite seeded note, GET/PUT → 403, create form 403s with role=alert, DB untouched).
- Header "Tuning" link (work item 1) and story file (work item 5) were already in place from tasks 02/03 — verified end-to-end by the new suite (visible+`is-active`+`aria-current` for admin, hidden for anonymous). No `app.js`/`sources.html` changes, per spec.
**Results**
- `uv run pytest tests/e2e/test_global_tuning.py -v --no-cov` → 6 passed (isolation)
- Regressions in isolation: `test_steering.py` 4 passed, `test_header_consistency.py` 3 passed, `test_document_viewer.py` 7 passed, `test_smoke.py` 3 passed
- `uv run pytest --cov=app` → 366 passed, TOTAL 99% (baseline 99% — no `app/` code changed)
- `uv run ruff check . && uv run pyright` → clean (0 errors)
**Decisions**: seeded one note in-DB before load in a11y/anonymous tests (row buttons are JS-built); followed the phase criterion "link hidden for anonymous" over the looser "ships visible" phrasing. No deviations.
**Next pending task**: `28_git_based_sources/01_env_var_and_settings.md` (phase 27 will close with the harness's commit + move).
@@ -0,0 +1,47 @@
........................................................................ [ 19%]
........................................................................ [ 39%]
........................................................................ [ 59%]
........................................................................ [ 78%]
........................................................................ [ 98%]
...... [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 55 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 105 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 1114 14 99%
coverage gate: app/ 99% (>90%) OK
All checks passed!
0 errors, 0 warnings, 0 informations
validation OK