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,16 @@
**Implemented (task 01 — sticky bottom composer)**
- `frontend/assets/styles.css` `.composer`: added `position: sticky;` + `bottom: env(safe-area-inset-bottom);` (the sticky-bottom pair), with a phase-52 rationale comment. Solid `--surface` bg, border, radius, shadow kept; **no z-index**, no DOM/JS change.
- `tests/unit/test_pinned_composer.py` (new, 8 house-style source pins): the sticky pair + no `top`; opaque composer (no translucency); no z-index on the composer + header z-20 / `.doc-modal` z-1000 intact; pin not undone in the ≤640px block (`.composer` padding-only, `main` safe-area padding kept); no clipping/inner-scroll ancestor (`.chat-shell`/`.app-main`/`.messages` overflow-free, `.messages` no height cap); composer is still the **last child** of `.chat-shell` with `#composer`/`#message-input`/`#send-btn`/`#send-status` + `novalidate`; `app.js` gained **zero** page-scroll sites (1 `window.scrollTo` inside `scrollReveal`, 0 `scrollIntoView`, 0 `window.scrollY`, no scroll listener / IntersectionObserver, 1 thinking-window `scrollTop` pin, `focus({preventScroll:true})` kept).
- Verified geometry in real Chromium (throwaway scripts, not committed): over-viewport chat → composer flush to the viewport bottom at scroll top/mid (`top 735 / bottom 800`) and settled back into flow above the footer at document bottom; empty/short chat → normal flow position, page not scrollable, footer untouched; in flight at scrollY 0 → Stop visible, hit-testable and clicked with **no window scroll** (server logged `turn cancelled`, no error banner, label back to "Send"); mobile 390×700 with an 8-line textarea → grows upward, Send stays clickable.
**Gates**
- `uv run pytest tests/unit/test_pinned_composer.py -v` → 8 passed (mutation-checked: removing the sticky pair fails it).
- `uv run pytest --cov=app --cov-report=term-missing` → **1018 passed**, TOTAL **99%** (>90%).
- `uv run ruff check .` → All checks passed · `uv run pyright` → 0 errors.
- E2E regressions, in isolation `--no-cov`: `test_no_reply_autoscroll` 6 ✓, `test_stop_generation` 3 ✓, `test_chat_persistence` 4 ✓, `test_mobile_hamburger_nav` 7 ✓, plus `test_responsive_polish` 7 ✓, `test_loading_feedback` 5 ✓.
**Notes / deviations**
- Phase assumption held literally: `env(safe-area-inset-bottom)` with no fallback arg (index.html already ships `viewport-fit=cover`, so the inset resolves on notched devices); no `index.html` or `app.js` change was needed.
- No commit made — the phase's single atomic commit belongs to task 02 (A17); working tree left functional with `styles.css` modified + the new test file untracked.
**Next pending task:** `.agent/phases/todo/52_pinned_composer/02_e2e_pinned_composer.md` (story Playwright suite + regressions + commit).
@@ -0,0 +1,66 @@
........................................................................ [ 7%]
........................................................................ [ 14%]
........................................................................ [ 21%]
........................................................................ [ 28%]
........................................................................ [ 35%]
........................................................................ [ 42%]
........................................................................ [ 49%]
........................................................................ [ 56%]
........................................................................ [ 63%]
........................................................................ [ 70%]
........................................................................ [ 77%]
........................................................................ [ 84%]
........................................................................ [ 91%]
........................................................................ [ 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 131 0 100%
app/api/chats.py 105 0 100%
app/api/config.py 7 0 100%
app/api/docs.py 23 0 100%
app/api/git_sources.py 143 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 81 0 100%
app/config.py 79 0 100%
app/core/__init__.py 0 0 100%
app/core/auth.py 20 0 100%
app/core/caching.py 93 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 50 0 100%
app/models.py 68 0 100%
app/rag/__init__.py 0 0 100%
app/rag/agent.py 78 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 173 3 98%
app/rag/llm.py 189 0 100%
app/rag/overview.py 71 0 100%
app/rag/prompts.py 65 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 165 0 100%
-----------------------------------------------
TOTAL 2180 12 99%
coverage gate: app/ 99% (>90%) OK
All checks passed!
0 errors, 0 warnings, 0 informations
validation OK
@@ -0,0 +1,17 @@
**Implemented (phase 52, task 02 — pinned composer E2E + commit)**
- `tests/e2e/test_pinned_composer.py` (new story suite, 4 tests): composer flush with the viewport bottom at every scroll position across the whole sticky range, then settling back into flow above the footer at the document bottom.
- The TODO.md L3 scenario: mid-turn, scrolled to the top, `#send-btn.is-stop` is visible + clickable with no scrolling; the click keeps the partial + `.stopped-note`, no error banner, viewport unchanged (±1px), `stopped: true` restored after reload.
- Empty/short chat: composer stays in normal flow, never overlaps `.app-footer`; ≤640px pin holds with the Send target ≥44px and the box under the z-20 sticky header (no z-index added).
- Overflow built from real UI turns (6 grounded questions / 4 on mobile); sticky-range premise asserted, so the suite can't silently stop testing.
- Validated as a true regression gate: with the task-01 `position: sticky; bottom` pin reverted, 3 of the 4 tests fail ("composer runs BELOW the viewport bottom", "Stop is off-screen").
- Committed `8207539 feat(chat): pin the composer to the viewport bottom — Stop is always reachable while reading` (`--no-gpg-sign`, stages styles.css + both test files + the 01 phase-file move).
**Gates**
- `uv run pytest --cov=app --cov-report=term-missing` → 1018 passed, TOTAL 99% (>90%).
- `uv run pytest tests/e2e/test_pinned_composer.py -v --no-cov` → 4 passed (isolation).
- Regressions in isolation, all green: `test_stop_generation` 3, `test_no_reply_autoscroll` 6, `test_chat_persistence` 4, `test_mobile_hamburger_nav` 7; extra spot-checks (`responsive_polish`, `loading_feedback`, `long_answers`, `retry_answer`, `thinking_scroll`, `smoke`, `chat_rag`, `chat_history`, `share_chat`, `honest_deflection`, `markdown_tables`) also green.
- `uv run ruff check .` → All checks passed; `uv run pyright` → 0 errors.
**Notes**: phase-42 no-autoscroll contract untouched (no JS change); phase dir left in `todo/` for the harness to move.
**Next pending task**: `.agent/phases/todo/53_stale_saved_chats/01_sources_version_and_migration.md`.
@@ -0,0 +1,66 @@
........................................................................ [ 7%]
........................................................................ [ 14%]
........................................................................ [ 21%]
........................................................................ [ 28%]
........................................................................ [ 35%]
........................................................................ [ 42%]
........................................................................ [ 49%]
........................................................................ [ 56%]
........................................................................ [ 63%]
........................................................................ [ 70%]
........................................................................ [ 77%]
........................................................................ [ 84%]
........................................................................ [ 91%]
........................................................................ [ 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 131 0 100%
app/api/chats.py 105 0 100%
app/api/config.py 7 0 100%
app/api/docs.py 23 0 100%
app/api/git_sources.py 143 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 81 0 100%
app/config.py 79 0 100%
app/core/__init__.py 0 0 100%
app/core/auth.py 20 0 100%
app/core/caching.py 93 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 50 0 100%
app/models.py 68 0 100%
app/rag/__init__.py 0 0 100%
app/rag/agent.py 78 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 173 3 98%
app/rag/llm.py 189 0 100%
app/rag/overview.py 71 0 100%
app/rag/prompts.py 65 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 165 0 100%
-----------------------------------------------
TOTAL 2180 12 99%
coverage gate: app/ 99% (>90%) OK
All checks passed!
0 errors, 0 warnings, 0 informations
validation OK