feat: phases 77–80 — navbar view refresh, static background, API tokens, history suggestion chips
Build and Push Containers / build-and-push-app (push) Successful in 1m45s
Build and Push Containers / build-and-push-db (push) Successful in 13s

Single consolidated commit for four completed, validated phases (77, 78,
79, 80). The pipeline run left all work uncommitted because the harness
commits only with PHASE_COMMIT=1 while child executors are forbidden from
committing; the phases themselves all passed validation and moved to
.agents/phases/complete/.

Phase 77 — navbar view refresh
- router.js dispatches bor:view-refresh on re-show / active re-click /
  popstate (gated on wasMounted; first show and boot exempt)
- History / RAG / Sources / Tuning re-fetch on refresh (admin branch);
  Chat deliberately excluded (stream survival)
- History "Refresh" button (admin-only, in-flight disable + status line)
- New story suite tests/e2e/test_navbar_refresh.py (7 tests)

Phase 78 — static background
- Removed the animated glow layers; static 44px grid over the flat --bg
  canvas; default and reduced-motion renders byte-identical
- Updated background/theme E2E suites; removed bg-glow test pins

Phase 79 — API tokens
- api_tokens model + migration 0012; hash-only token service
- Admin tokens API + Tokens admin view; POST /api/token-auth;
  live-revoking require_user on chat / suggestions / document content
- Frontend token gate with localStorage cache; anonymous E2E suites
  migrated to token login
- New story suite tests/e2e/test_api_tokens.py (9 tests)

Phase 80 — history suggestion chips
- last_questions() endpoint with SEED fallback; startNewChat() refetch
- Seed-semantics docs (config.py, .env.example, README)
- Integration state matrix + E2E suite rewritten to the 4 chip states

Also included: phase-76 report artifacts and the repo restore-test-db
skill (previously untracked), scripts/* ruff fixes from phase 77.

Final gate state (phase 80 final pass, covers everything above):
- uv run pytest --cov=app → 1637 passed, 0 failed, app/ coverage 99%
- uv run ruff check . && uv run pyright → clean, 0 errors
- Per-phase story E2E suites green in isolation
This commit is contained in:
2026-09-07 12:39:01 -04:00
parent 495d042a98
commit 7fce6572d0
215 changed files with 10142 additions and 1643 deletions
@@ -0,0 +1,13 @@
All completion criteria verified green — no defects found, no fixes needed. Final report:
**Phase 80 (history_suggestion_chips) — final verification pass: ALL GREEN**
- Verified implementation: `last_questions()` + seed-fallback in `app/api/suggestions.py` (100% cov); `startNewChat()` refetch via `loadSuggestions()` in `app.js`; seed-semantics docs in `config.py` docstring, `.env.example:55`, README L114/L823; integration state matrix in `test_suggestions_api.py`; E2E suite rewritten to the 4 states + carried-over story behavior.
- `uv run pytest tests/e2e/test_suggestion_chips.py -v --no-cov` → **7 passed** (isolated).
- `uv run pytest --cov=app --cov-report=term-missing` → **1637 passed**, TOTAL **99%** (>90%).
- `uv run ruff check . && uv run pyright` → **All checks passed / 0 errors, 0 warnings**.
- Criterion: E2E isolated green → ✅.
- Criterion: deflection unchanged → ✅ (`app/rag/suggestions.py` no diff vs HEAD; `test_honest_deflection.py` 3 passed; 100% cov).
- Criterion: full suite + coverage + lint/types → ✅ (above).
- Criterion: atomic commit + phase dir move → deferred per harness override: all changes left uncommitted in the working tree; task files already in `complete/80_history_suggestion_chips/`; harness commits and moves the phase dir.
- Notable: none — no defects found in prior work.
- Next pending phase: **none** (phase 80 is the last in the roadmap; `todo/` contains only this phase).
@@ -0,0 +1,81 @@
........................................................................ [ 4%]
........................................................................ [ 8%]
........................................................................ [ 13%]
........................................................................ [ 17%]
........................................................................ [ 21%]
........................................................................ [ 26%]
........................................................................ [ 30%]
........................................................................ [ 35%]
........................................................................ [ 39%]
........................................................................ [ 43%]
........................................................................ [ 48%]
........................................................................ [ 52%]
........................................................................ [ 57%]
........................................................................ [ 61%]
........................................................................ [ 65%]
........................................................................ [ 70%]
........................................................................ [ 74%]
........................................................................ [ 79%]
........................................................................ [ 83%]
........................................................................ [ 87%]
........................................................................ [ 92%]
........................................................................ [ 96%]
..................................................... [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 40 0 100%
app/api/chat.py 178 0 100%
app/api/chats.py 110 0 100%
app/api/config.py 7 0 100%
app/api/doc_drafts.py 93 0 100%
app/api/docs.py 50 0 100%
app/api/git_sources.py 212 0 100%
app/api/health.py 10 0 100%
app/api/steering.py 42 0 100%
app/api/suggestions.py 29 0 100%
app/api/sync.py 101 0 100%
app/api/tokens.py 28 0 100%
app/config.py 140 0 100%
app/core/__init__.py 0 0 100%
app/core/auth.py 45 0 100%
app/core/caching.py 108 0 100%
app/core/debugging.py 29 2 93%
app/core/docs_push.py 39 0 100%
app/core/logging.py 13 0 100%
app/core/tokens.py 33 0 100%
app/db.py 21 0 100%
app/main.py 62 0 100%
app/models.py 94 0 100%
app/rag/__init__.py 0 0 100%
app/rag/agent.py 222 0 100%
app/rag/archive_upload.py 128 0 100%
app/rag/chunker.py 206 4 98%
app/rag/git_sources.py 14 0 100%
app/rag/importer.py 180 3 98%
app/rag/llm.py 216 0 100%
app/rag/overview.py 71 0 100%
app/rag/prompts.py 88 0 100%
app/rag/retriever.py 150 3 98%
app/rag/scaffolding.py 55 0 100%
app/rag/source_removal.py 41 0 100%
app/rag/sources_meta.py 16 0 100%
app/rag/suggestions.py 27 0 100%
app/rag/summarizer.py 24 0 100%
app/schemas.py 231 0 100%
-----------------------------------------------
TOTAL 3154 12 99%
coverage gate: app/ 99% (>90%) OK
All checks passed!
0 errors, 0 warnings, 0 informations
validation OK
@@ -0,0 +1,10 @@
**Task 01 complete** — `/api/suggestions` now returns the last 3 questions asked, seed before the first.
- `app/api/suggestions.py`: module-level `last_questions(db, limit=3)` — `saved_chats` walked `updated_at DESC, created_at DESC`, each `bor.chat.v1` message list walked in reverse, `who=="user"` non-blank trimmed texts, exact case-sensitive dedup, cap 3; endpoint returns `qs if qs else get_settings().suggestions` (phase-79 `require_user` gate kept, `db` dep now used).
- New `tests/integration/test_suggestions_api.py` (10 tests): empty DB → seed; 4-q chat → `[q4,q3,q2]`; distinct-`updated_at` chat order; verbatim cross-chat dedup; case-sensitive dedup; exactly-2 and exactly-1 chips (no seed top-up); brain/blank-skip + all-brain → seed; anonymous → 401.
- Fixed stale pre-change pins in `tests/integration/test_api.py` (shape pin no longer assumes ≥3; env-override pin now conditioned on empty `saved_chats`, documented as the module's DB exception).
- `app/rag/suggestions.py` (deflection "Maybe try") untouched; its suites green.
Results: `uv run pytest --cov=app --cov-report=term` → 1637 passed, app/ coverage 99% (suggestions.py 100%); `uv run ruff check .` clean; `uv run pyright` → 0 errors.
No deviations. Dev DB left as found (saved_chats empty). Next pending task: `02_seed_semantics_docs.md`.
@@ -0,0 +1,81 @@
........................................................................ [ 4%]
........................................................................ [ 8%]
........................................................................ [ 13%]
........................................................................ [ 17%]
........................................................................ [ 21%]
........................................................................ [ 26%]
........................................................................ [ 30%]
........................................................................ [ 35%]
........................................................................ [ 39%]
........................................................................ [ 43%]
........................................................................ [ 48%]
........................................................................ [ 52%]
........................................................................ [ 57%]
........................................................................ [ 61%]
........................................................................ [ 65%]
........................................................................ [ 70%]
........................................................................ [ 74%]
........................................................................ [ 79%]
........................................................................ [ 83%]
........................................................................ [ 87%]
........................................................................ [ 92%]
........................................................................ [ 96%]
..................................................... [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 40 0 100%
app/api/chat.py 178 0 100%
app/api/chats.py 110 0 100%
app/api/config.py 7 0 100%
app/api/doc_drafts.py 93 0 100%
app/api/docs.py 50 0 100%
app/api/git_sources.py 212 0 100%
app/api/health.py 10 0 100%
app/api/steering.py 42 0 100%
app/api/suggestions.py 29 0 100%
app/api/sync.py 101 0 100%
app/api/tokens.py 28 0 100%
app/config.py 140 0 100%
app/core/__init__.py 0 0 100%
app/core/auth.py 45 0 100%
app/core/caching.py 108 0 100%
app/core/debugging.py 29 2 93%
app/core/docs_push.py 39 0 100%
app/core/logging.py 13 0 100%
app/core/tokens.py 33 0 100%
app/db.py 21 0 100%
app/main.py 62 0 100%
app/models.py 94 0 100%
app/rag/__init__.py 0 0 100%
app/rag/agent.py 222 0 100%
app/rag/archive_upload.py 128 0 100%
app/rag/chunker.py 206 4 98%
app/rag/git_sources.py 14 0 100%
app/rag/importer.py 180 3 98%
app/rag/llm.py 216 0 100%
app/rag/overview.py 71 0 100%
app/rag/prompts.py 88 0 100%
app/rag/retriever.py 150 3 98%
app/rag/scaffolding.py 55 0 100%
app/rag/source_removal.py 41 0 100%
app/rag/sources_meta.py 16 0 100%
app/rag/suggestions.py 27 0 100%
app/rag/summarizer.py 24 0 100%
app/schemas.py 231 0 100%
-----------------------------------------------
TOTAL 3154 12 99%
coverage gate: app/ 99% (>90%) OK
All checks passed!
0 errors, 0 warnings, 0 informations
validation OK
@@ -0,0 +1,15 @@
Task 02 complete. All four doc sites updated (docs-only, no behavior change):
- **`app/config.py`** — comment block above `suggestions: list[str]` now documents the SEED semantics: shown only while no saved chat has ever asked a question; afterwards `GET /api/suggestions` serves the last 3 questions (deployment-wide, newest first); `BOR_SUGGESTIONS` overrides the seed. Default list untouched.
- **`.env.example:55`** — comment now reads "JSON seed chips — shown only before any question has been saved (phase 80)".
- **`README.md` env-table row** — "JSON seed for the onboarding chips — shown only before the first saved question; afterwards the chips are the last 3 questions asked (phase 80)".
- **`README.md` chat feature description** — one sentence added: onboarding chips follow the last 3 questions asked, seeding from `BOR_SUGGESTIONS` on a fresh deployment. Deflection note and access-table row left as-is (unchanged contracts).
**Verification:**
- `uv run pytest --cov=app --cov-report=term-missing` → 1637 passed, `app/` coverage **99%** (>90% gate)
- `uv run ruff check .` → All checks passed
- `uv run pyright` → 0 errors, 0 warnings
**Notable:** no defects found; deflection contract (`app/rag/suggestions.py` + suites) green and untouched. The e2e story-suite rewrite for the new chip semantics remains deferred to task 04 per the phase plan (phase-76 precedent), so the old-contract e2e pins are expected to go until then.
**Next pending task:** `03_chips_new_chat_refetch.md` (app.js refetch on New chat + source pin).
@@ -0,0 +1,81 @@
........................................................................ [ 4%]
........................................................................ [ 8%]
........................................................................ [ 13%]
........................................................................ [ 17%]
........................................................................ [ 21%]
........................................................................ [ 26%]
........................................................................ [ 30%]
........................................................................ [ 35%]
........................................................................ [ 39%]
........................................................................ [ 43%]
........................................................................ [ 48%]
........................................................................ [ 52%]
........................................................................ [ 57%]
........................................................................ [ 61%]
........................................................................ [ 65%]
........................................................................ [ 70%]
........................................................................ [ 74%]
........................................................................ [ 79%]
........................................................................ [ 83%]
........................................................................ [ 87%]
........................................................................ [ 92%]
........................................................................ [ 96%]
..................................................... [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 40 0 100%
app/api/chat.py 178 0 100%
app/api/chats.py 110 0 100%
app/api/config.py 7 0 100%
app/api/doc_drafts.py 93 0 100%
app/api/docs.py 50 0 100%
app/api/git_sources.py 212 0 100%
app/api/health.py 10 0 100%
app/api/steering.py 42 0 100%
app/api/suggestions.py 29 0 100%
app/api/sync.py 101 0 100%
app/api/tokens.py 28 0 100%
app/config.py 140 0 100%
app/core/__init__.py 0 0 100%
app/core/auth.py 45 0 100%
app/core/caching.py 108 0 100%
app/core/debugging.py 29 2 93%
app/core/docs_push.py 39 0 100%
app/core/logging.py 13 0 100%
app/core/tokens.py 33 0 100%
app/db.py 21 0 100%
app/main.py 62 0 100%
app/models.py 94 0 100%
app/rag/__init__.py 0 0 100%
app/rag/agent.py 222 0 100%
app/rag/archive_upload.py 128 0 100%
app/rag/chunker.py 206 4 98%
app/rag/git_sources.py 14 0 100%
app/rag/importer.py 180 3 98%
app/rag/llm.py 216 0 100%
app/rag/overview.py 71 0 100%
app/rag/prompts.py 88 0 100%
app/rag/retriever.py 150 3 98%
app/rag/scaffolding.py 55 0 100%
app/rag/source_removal.py 41 0 100%
app/rag/sources_meta.py 16 0 100%
app/rag/suggestions.py 27 0 100%
app/rag/summarizer.py 24 0 100%
app/schemas.py 231 0 100%
-----------------------------------------------
TOTAL 3154 12 99%
coverage gate: app/ 99% (>90%) OK
All checks passed!
0 errors, 0 warnings, 0 informations
validation OK
@@ -0,0 +1,19 @@
Task 03 complete — all gates green.
**Implemented**
- `frontend/assets/app.js`: `startNewChat()` (the `bor:new-chat` handler) now calls `loadSuggestions()` right after the empty state is restored — the onboarding chips refetch `/api/suggestions` so the row reflects the current last-3 state, never the stale boot fetch. Progressive enhancement unchanged (swallows 401/network failures); boot path untouched; in-flight-turn guard still exempts a live turn.
- `tests/unit/test_chat_persistence.py`: source pin in `test_new_chat_clears_key_and_ui` — containment assertion that `loadSuggestions()` appears in the `startNewChat` function-body slice (house style, two literals).
**Test / lint / coverage**
- `node --check frontend/assets/app.js` — valid JS
- `uv run pytest -q` (unit + integration) — exit 0, all passed
- `uv run pytest --cov=app --cov-report=term-missing` — TOTAL **99%** (>90% floor)
- `uv run ruff check .` — All checks passed; `uv run pyright` — 0 errors
- `uv run pytest tests/unit/test_chat_persistence.py::test_new_chat_clears_key_and_ui` — passed
**Decisions / notes**
- Pin placed in `test_chat_persistence.py` (the existing `startNewChat` body-slice pin — the file the task names first).
- `.agents/PLAN.md` is absent from the repo; the phase files carry the binding decisions (no deviation).
- E2E refetch assertion belongs to task 04's suite (per task file); no other files touched. My diff is only the 2 files above (working tree also carries uncommitted harness work from phases 77–79, left as-is).
**Next pending task:** `.agents/phases/todo/80_history_suggestion_chips/04_e2e_suite_commit.md`
@@ -0,0 +1,215 @@
........................................................................ [ 4%]
........................................................................ [ 8%]
........................................................................ [ 13%]
........................................................................ [ 17%]
........................................................................ [ 21%]
........................................................................ [ 26%]
........................................................................ [ 30%]
........................................................................ [ 35%]
........................................................................ [ 39%]
........................................................................ [ 43%]
........................................................................ [ 48%]
........................................................................ [ 52%]
........................................................................ [ 57%]
........................................................................ [ 61%]
........................................................................ [ 65%]
........................................................................ [ 70%]
........................................................................ [ 74%]
........................................................................ [ 79%]
........................................................................ [ 83%]
........................................................................ [ 87%]
........................................................................ [ 92%]
........................................................................ [ 96%]
..................................................... [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 40 0 100%
app/api/chat.py 178 0 100%
app/api/chats.py 110 0 100%
app/api/config.py 7 0 100%
app/api/doc_drafts.py 93 0 100%
app/api/docs.py 50 0 100%
app/api/git_sources.py 212 0 100%
app/api/health.py 10 0 100%
app/api/steering.py 42 0 100%
app/api/suggestions.py 29 0 100%
app/api/sync.py 101 0 100%
app/api/tokens.py 28 0 100%
app/config.py 140 0 100%
app/core/__init__.py 0 0 100%
app/core/auth.py 45 0 100%
app/core/caching.py 108 0 100%
app/core/debugging.py 29 2 93%
app/core/docs_push.py 39 0 100%
app/core/logging.py 13 0 100%
app/core/tokens.py 33 0 100%
app/db.py 21 0 100%
app/main.py 62 0 100%
app/models.py 94 0 100%
app/rag/__init__.py 0 0 100%
app/rag/agent.py 222 0 100%
app/rag/archive_upload.py 128 0 100%
app/rag/chunker.py 206 4 98%
app/rag/git_sources.py 14 0 100%
app/rag/importer.py 180 3 98%
app/rag/llm.py 216 0 100%
app/rag/overview.py 71 0 100%
app/rag/prompts.py 88 0 100%
app/rag/retriever.py 150 3 98%
app/rag/scaffolding.py 55 0 100%
app/rag/source_removal.py 41 0 100%
app/rag/sources_meta.py 16 0 100%
app/rag/suggestions.py 27 0 100%
app/rag/summarizer.py 24 0 100%
app/schemas.py 231 0 100%
-----------------------------------------------
TOTAL 3154 12 99%
coverage gate: app/ 99% (>90%) OK
I001 [*] Import block is un-sorted or un-formatted
--> tests/e2e/test_toggle_after_nav.py:2:1
|
1 | """Quick diagnostic: does the toggle still work after SPA navigation?"""
2 | / import pytest
3 | | from playwright.sync_api import Browser, expect
| |_______________________________________________^
4 |
5 | def test_toggle_after_spa_nav(browser, app_url, db_ready):
|
help: Organize imports
|
4 |
5 +
6 | def test_toggle_after_spa_nav(browser, app_url, db_ready):
|
F401 [*] `pytest` imported but unused
--> tests/e2e/test_toggle_after_nav.py:2:8
|
1 | """Quick diagnostic: does the toggle still work after SPA navigation?"""
2 | import pytest
| ^^^^^^
3 | from playwright.sync_api import Browser, expect
|
help: Remove unused import: `pytest`
|
1 | """Quick diagnostic: does the toggle still work after SPA navigation?"""
- import pytest
2 | from playwright.sync_api import Browser, expect
|
F401 [*] `playwright.sync_api.Browser` imported but unused
--> tests/e2e/test_toggle_after_nav.py:3:33
|
1 | """Quick diagnostic: does the toggle still work after SPA navigation?"""
2 | import pytest
3 | from playwright.sync_api import Browser, expect
| ^^^^^^^
4 |
5 | def test_toggle_after_spa_nav(browser, app_url, db_ready):
|
help: Remove unused import: `playwright.sync_api.Browser`
|
2 | import pytest
- from playwright.sync_api import Browser, expect
3 + from playwright.sync_api import expect
4 |
|
W293 [*] Blank line contains whitespace
--> tests/e2e/test_toggle_after_nav.py:15:1
|
13 | timeout=10_000,
14 | )
15 |
| ^^^^^^^^
16 | # Open the menu
17 | page.click("#nav-toggle")
|
help: Remove whitespace from blank line
|
14 | )
-
15 +
16 | # Open the menu
|
W293 [*] Blank line contains whitespace
--> tests/e2e/test_toggle_after_nav.py:19:1
|
17 | page.click("#nav-toggle")
18 | expect(page.locator("#nav-toggle")).to_have_attribute("aria-expanded", "true")
19 |
| ^^^^^^^^
20 | # Navigate to a different view via SPA
21 | page.click("#nav-sources")
|
help: Remove whitespace from blank line
|
18 | expect(page.locator("#nav-toggle")).to_have_attribute("aria-expanded", "true")
-
19 +
20 | # Navigate to a different view via SPA
|
W293 [*] Blank line contains whitespace
--> tests/e2e/test_toggle_after_nav.py:23:1
|
21 | page.click("#nav-sources")
22 | expect(page).to_have_url(app_url + "/sources.html", timeout=15_000)
23 |
| ^^^^^^^^
24 | # Menu should be closed
25 | expect(page.locator("#nav-toggle")).to_have_attribute("aria-expanded", "false")
|
help: Remove whitespace from blank line
|
22 | expect(page).to_have_url(app_url + "/sources.html", timeout=15_000)
-
23 +
24 | # Menu should be closed
|
W293 [*] Blank line contains whitespace
--> tests/e2e/test_toggle_after_nav.py:26:1
|
24 | # Menu should be closed
25 | expect(page.locator("#nav-toggle")).to_have_attribute("aria-expanded", "false")
26 |
| ^^^^^^^^
27 | # NOW try to open the menu again - THIS IS THE BUG CHECK
28 | page.click("#nav-toggle")
|
help: Remove whitespace from blank line
|
25 | expect(page.locator("#nav-toggle")).to_have_attribute("aria-expanded", "false")
-
26 +
27 | # NOW try to open the menu again - THIS IS THE BUG CHECK
|
E501 Line too long (104 > 100)
--> tests/e2e/test_toggle_after_nav.py:30:101
|
28 | page.click("#nav-toggle")
29 | try:
30 | expect(page.locator("#nav-toggle")).to_have_attribute("aria-expanded", "true", timeout=3000)
| ^^^^
31 | print("PASS: Toggle still works after SPA navigation")
32 | except Exception as e:
|
Found 8 errors.
[*] 7 fixable with the `--fix` option.
0 errors, 0 warnings, 0 informations
validation FAILED (see output above)
@@ -0,0 +1,15 @@
Everything is green — the only "error" match is pyright's "0 errors" line.
**Fixed**
- `tests/e2e/test_toggle_after_nav.py` (stray diagnostic file, pre-existing lint debt that failed the harness gate): removed unused imports (`pytest`, `Browser`), fixed the isort order (third-party `playwright` block, then first-party `e2e.auth_helpers` — house style), stripped whitespace-only lines, wrapped the >100-char `expect(...)` line. Preserved the file's current semantics (phase-79 `login(page, app_url, next="/")` admin wait — the variant present on disk).
**Test / lint / coverage**
- `bash .agents/validate.sh` (the harness gate) — **exit 0, "validation OK"**
- Inside it: `uv run pytest --cov=app` — all unit + integration passed; TOTAL **99%** (>90% floor)
- `uv run ruff check .` — All checks passed; `uv run pyright` — 0 errors
**Decisions / notes**
- The diagnostic file was being updated concurrently (a parallel process overwrote my first fix with the `login`-helper variant); I lint-cleaned that on-disk variant instead and re-validated immediately — final state verified green.
- Task-03 work (app.js `loadSuggestions()` in `startNewChat()` + the source pin in `test_chat_persistence.py`) remains in the tree, untouched and green.
**Next pending task:** `.agents/phases/todo/80_history_suggestion_chips/04_e2e_suite_commit.md`
@@ -0,0 +1,81 @@
........................................................................ [ 4%]
........................................................................ [ 8%]
........................................................................ [ 13%]
........................................................................ [ 17%]
........................................................................ [ 21%]
........................................................................ [ 26%]
........................................................................ [ 30%]
........................................................................ [ 35%]
........................................................................ [ 39%]
........................................................................ [ 43%]
........................................................................ [ 48%]
........................................................................ [ 52%]
........................................................................ [ 57%]
........................................................................ [ 61%]
........................................................................ [ 65%]
........................................................................ [ 70%]
........................................................................ [ 74%]
........................................................................ [ 79%]
........................................................................ [ 83%]
........................................................................ [ 87%]
........................................................................ [ 92%]
........................................................................ [ 96%]
..................................................... [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 40 0 100%
app/api/chat.py 178 0 100%
app/api/chats.py 110 0 100%
app/api/config.py 7 0 100%
app/api/doc_drafts.py 93 0 100%
app/api/docs.py 50 0 100%
app/api/git_sources.py 212 0 100%
app/api/health.py 10 0 100%
app/api/steering.py 42 0 100%
app/api/suggestions.py 29 0 100%
app/api/sync.py 101 0 100%
app/api/tokens.py 28 0 100%
app/config.py 140 0 100%
app/core/__init__.py 0 0 100%
app/core/auth.py 45 0 100%
app/core/caching.py 108 0 100%
app/core/debugging.py 29 2 93%
app/core/docs_push.py 39 0 100%
app/core/logging.py 13 0 100%
app/core/tokens.py 33 0 100%
app/db.py 21 0 100%
app/main.py 62 0 100%
app/models.py 94 0 100%
app/rag/__init__.py 0 0 100%
app/rag/agent.py 222 0 100%
app/rag/archive_upload.py 128 0 100%
app/rag/chunker.py 206 4 98%
app/rag/git_sources.py 14 0 100%
app/rag/importer.py 180 3 98%
app/rag/llm.py 216 0 100%
app/rag/overview.py 71 0 100%
app/rag/prompts.py 88 0 100%
app/rag/retriever.py 150 3 98%
app/rag/scaffolding.py 55 0 100%
app/rag/source_removal.py 41 0 100%
app/rag/sources_meta.py 16 0 100%
app/rag/suggestions.py 27 0 100%
app/rag/summarizer.py 24 0 100%
app/schemas.py 231 0 100%
-----------------------------------------------
TOTAL 3154 12 99%
coverage gate: app/ 99% (>90%) OK
All checks passed!
0 errors, 0 warnings, 0 informations
validation OK
@@ -0,0 +1,17 @@
Task 04 complete — all gates green. Report:
**Implemented**
- Rewrote `tests/e2e/test_suggestion_chips.py` (7 tests) to the phase-80 contract: **seed** state (chips == exact `SEED` literal copied from the `Settings.suggestions` default, role=list/buttons/style pins), **last-3** (2 chats via `POST /api/chats`, 5 questions, older saved first → fresh load shows exactly the 3 newest, newest-first), **partial** (2 saved questions → exactly 2 chips, no seed top-up), **new-chat refetch** (click `#new-chat-btn` → chips become Q + a second `GET /api/suggestions` in the request log, timestamped after the click) — plus carried-over one-tap submit, Tab+Enter keyboard walk, and the mobile single-scroll-row contract.
- Added an autouse `clean_chats` fixture truncating `saved_chats` before/after every test — this also fixed pre-existing defects I found: the old suite (unmodified by prior tasks) was already failing 2/4 because auto-saved chat rows leaked between tests and the new DB-derived contract turned them into 1 deduped chip.
**Results**
- `uv run pytest tests/e2e/test_suggestion_chips.py -v --no-cov` → 7 passed (green in isolation, repeated runs stable)
- `uv run pytest --cov=app --cov-report=term-missing` → 1637 passed, **99%** on `app/` (`app/api/suggestions.py` 100%)
- `uv run ruff check .` → clean; `uv run pyright` → 0 errors
- Deflection untouched: `app/rag/suggestions.py` has no diff; `uv run pytest tests/e2e/test_honest_deflection.py --no-cov` → 3 passed
**Notes**
- No `git add`/`commit` and no phase-dir move performed — the harness owns the atomic commit and the move (overrides the task's commit step).
- Playwright's `APIRequestContext.post` in this version has no `json=` kwarg — JSON is sent via `data=` + `Content-Type: application/json`.
**Next pending task:** none — task 04 was the final task; phase 80 is complete, awaiting the harness commit.
@@ -0,0 +1,81 @@
........................................................................ [ 4%]
........................................................................ [ 8%]
........................................................................ [ 13%]
........................................................................ [ 17%]
........................................................................ [ 21%]
........................................................................ [ 26%]
........................................................................ [ 30%]
........................................................................ [ 35%]
........................................................................ [ 39%]
........................................................................ [ 43%]
........................................................................ [ 48%]
........................................................................ [ 52%]
........................................................................ [ 57%]
........................................................................ [ 61%]
........................................................................ [ 65%]
........................................................................ [ 70%]
........................................................................ [ 74%]
........................................................................ [ 79%]
........................................................................ [ 83%]
........................................................................ [ 87%]
........................................................................ [ 92%]
........................................................................ [ 96%]
..................................................... [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 40 0 100%
app/api/chat.py 178 0 100%
app/api/chats.py 110 0 100%
app/api/config.py 7 0 100%
app/api/doc_drafts.py 93 0 100%
app/api/docs.py 50 0 100%
app/api/git_sources.py 212 0 100%
app/api/health.py 10 0 100%
app/api/steering.py 42 0 100%
app/api/suggestions.py 29 0 100%
app/api/sync.py 101 0 100%
app/api/tokens.py 28 0 100%
app/config.py 140 0 100%
app/core/__init__.py 0 0 100%
app/core/auth.py 45 0 100%
app/core/caching.py 108 0 100%
app/core/debugging.py 29 2 93%
app/core/docs_push.py 39 0 100%
app/core/logging.py 13 0 100%
app/core/tokens.py 33 0 100%
app/db.py 21 0 100%
app/main.py 62 0 100%
app/models.py 94 0 100%
app/rag/__init__.py 0 0 100%
app/rag/agent.py 222 0 100%
app/rag/archive_upload.py 128 0 100%
app/rag/chunker.py 206 4 98%
app/rag/git_sources.py 14 0 100%
app/rag/importer.py 180 3 98%
app/rag/llm.py 216 0 100%
app/rag/overview.py 71 0 100%
app/rag/prompts.py 88 0 100%
app/rag/retriever.py 150 3 98%
app/rag/scaffolding.py 55 0 100%
app/rag/source_removal.py 41 0 100%
app/rag/sources_meta.py 16 0 100%
app/rag/suggestions.py 27 0 100%
app/rag/summarizer.py 24 0 100%
app/schemas.py 231 0 100%
-----------------------------------------------
TOTAL 3154 12 99%
coverage gate: app/ 99% (>90%) OK
All checks passed!
0 errors, 0 warnings, 0 informations
validation OK