From 412a560348fe24d7efc50900815242d9dfbb8e38 Mon Sep 17 00:00:00 2001 From: ducoterra Date: Tue, 8 Sep 2026 01:56:37 -0400 Subject: [PATCH] phase: 85_mobile_menu_gate_overlap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All verification complete. Final report: **Phase 85 final verification pass — all green** (tasks 01–03 already complete; independently re-verified from scratch) - Verified fix in tree: `styles.css` `.auth-gate` z-index 500→15 + rewritten stacking comment (no `z-index: 500` left); `index.html`/`document.html` comment-only; `token-gate.js` docstring-only (logic byte-identical); `test_mobile_hamburger_nav.py` real-click conversion + new `test_anonymous_toggle_tappable_with_gate_up`; new `tests/unit/test_gate_header_stacking.py` (3 pins); `test_api_tokens.py` untouched - `uv run pytest` → 1717 passed, 1 warning (exit 0) - `uv run pytest --cov=app --cov-report=term-missing` → TOTAL **99%** (>90%) - E2E in isolation: `test_mobile_hamburger_nav.py` **8 passed**; `test_api_tokens.py` **9 passed** (unchanged); `test_smoke.py` **3 passed**; `test_document_viewer.py` **7 passed** - `uv run ruff check . && uv run pyright` → clean / 0 errors - Live probe (375×812, anonymous, fresh server): on `/` and `/history.html` `elementFromPoint` at toggle → SVG `path`, never `#auth-gate`; real click opens menu (`aria-expanded=true`); exactly one visible nav link (Chat) + sign-in copy; Chat link topmost over gate; `#main` inert — criteria 1, 2, 3 confirmed directly - Criteria: (1) real-click menu on / + /history ✅ (2) dropdown above gate ✅ (3) anonymous contents + #main inert ✅ (4) admin byte-identical (phase-46 tests green) ✅ (5) doc-viewer gate under bar (CSS pin + doc-viewer suite) ✅ (6) full gate green ✅ (7) diff scoped to the 5 code files + new unit test + phase files, nothing in `app/` ✅ (8) commit + todo→complete move left to harness per executor rules (task files already in `complete/`) - Note: `.agents/remediation_plan.md` (untracked) is a pre-existing artifact of the earlier security audit — left untouched; a missing "N passed" line seen mid-pass was my own `-q`+addopts `-q` = `-qq` quirk, not a defect - Next pending phase: `86_history_page_width` --- .../85_mobile_menu_gate_overlap/00_phase.md | 0 .../01_gate_below_header.md | 0 .../02_e2e_pin_updates.md | 0 .../03_verify_and_commit.md | 0 ..._mobile_menu_gate_overlap__00_phase.a1.err | 0 ...5_mobile_menu_gate_overlap__00_phase.a1.md | 12 ++ ...le_menu_gate_overlap__00_phase.a1.validate | 85 +++++++++ ..._gate_overlap__01_gate_below_header.a1.err | 0 ...u_gate_overlap__01_gate_below_header.a1.md | 17 ++ ..._overlap__01_gate_below_header.a1.validate | 85 +++++++++ ...nu_gate_overlap__02_e2e_pin_updates.a1.err | 0 ...enu_gate_overlap__02_e2e_pin_updates.a1.md | 19 ++ ...te_overlap__02_e2e_pin_updates.a1.validate | 85 +++++++++ ..._gate_overlap__03_verify_and_commit.a1.err | 0 ...u_gate_overlap__03_verify_and_commit.a1.md | 11 ++ ..._overlap__03_verify_and_commit.a1.validate | 85 +++++++++ .../livecheck_admin_menu.png | Bin 0 -> 45480 bytes .../livecheck_anonymous_menu_over_gate.png | Bin 0 -> 29326 bytes frontend/assets/styles.css | 27 +-- frontend/assets/token-gate.js | 10 +- frontend/document.html | 5 +- frontend/index.html | 10 +- tests/e2e/test_mobile_hamburger_nav.py | 172 ++++++++++++++---- tests/unit/test_gate_header_stacking.py | 126 +++++++++++++ 24 files changed, 692 insertions(+), 57 deletions(-) rename .agents/phases/{todo => complete}/85_mobile_menu_gate_overlap/00_phase.md (100%) rename .agents/phases/{todo => complete}/85_mobile_menu_gate_overlap/01_gate_below_header.md (100%) rename .agents/phases/{todo => complete}/85_mobile_menu_gate_overlap/02_e2e_pin_updates.md (100%) rename .agents/phases/{todo => complete}/85_mobile_menu_gate_overlap/03_verify_and_commit.md (100%) create mode 100644 .agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__00_phase.a1.err create mode 100644 .agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__00_phase.a1.md create mode 100644 .agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__00_phase.a1.validate create mode 100644 .agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__01_gate_below_header.a1.err create mode 100644 .agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__01_gate_below_header.a1.md create mode 100644 .agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__01_gate_below_header.a1.validate create mode 100644 .agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__02_e2e_pin_updates.a1.err create mode 100644 .agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__02_e2e_pin_updates.a1.md create mode 100644 .agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__02_e2e_pin_updates.a1.validate create mode 100644 .agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__03_verify_and_commit.a1.err create mode 100644 .agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__03_verify_and_commit.a1.md create mode 100644 .agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__03_verify_and_commit.a1.validate create mode 100644 .agents/reports/85_mobile_menu_gate_overlap/livecheck_admin_menu.png create mode 100644 .agents/reports/85_mobile_menu_gate_overlap/livecheck_anonymous_menu_over_gate.png create mode 100644 tests/unit/test_gate_header_stacking.py diff --git a/.agents/phases/todo/85_mobile_menu_gate_overlap/00_phase.md b/.agents/phases/complete/85_mobile_menu_gate_overlap/00_phase.md similarity index 100% rename from .agents/phases/todo/85_mobile_menu_gate_overlap/00_phase.md rename to .agents/phases/complete/85_mobile_menu_gate_overlap/00_phase.md diff --git a/.agents/phases/todo/85_mobile_menu_gate_overlap/01_gate_below_header.md b/.agents/phases/complete/85_mobile_menu_gate_overlap/01_gate_below_header.md similarity index 100% rename from .agents/phases/todo/85_mobile_menu_gate_overlap/01_gate_below_header.md rename to .agents/phases/complete/85_mobile_menu_gate_overlap/01_gate_below_header.md diff --git a/.agents/phases/todo/85_mobile_menu_gate_overlap/02_e2e_pin_updates.md b/.agents/phases/complete/85_mobile_menu_gate_overlap/02_e2e_pin_updates.md similarity index 100% rename from .agents/phases/todo/85_mobile_menu_gate_overlap/02_e2e_pin_updates.md rename to .agents/phases/complete/85_mobile_menu_gate_overlap/02_e2e_pin_updates.md diff --git a/.agents/phases/todo/85_mobile_menu_gate_overlap/03_verify_and_commit.md b/.agents/phases/complete/85_mobile_menu_gate_overlap/03_verify_and_commit.md similarity index 100% rename from .agents/phases/todo/85_mobile_menu_gate_overlap/03_verify_and_commit.md rename to .agents/phases/complete/85_mobile_menu_gate_overlap/03_verify_and_commit.md diff --git a/.agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__00_phase.a1.err b/.agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__00_phase.a1.err new file mode 100644 index 0000000..e69de29 diff --git a/.agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__00_phase.a1.md b/.agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__00_phase.a1.md new file mode 100644 index 0000000..bef412d --- /dev/null +++ b/.agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__00_phase.a1.md @@ -0,0 +1,12 @@ +All verification complete. Final report: + +**Phase 85 final verification pass — all green** (tasks 01–03 already complete; independently re-verified from scratch) +- Verified fix in tree: `styles.css` `.auth-gate` z-index 500→15 + rewritten stacking comment (no `z-index: 500` left); `index.html`/`document.html` comment-only; `token-gate.js` docstring-only (logic byte-identical); `test_mobile_hamburger_nav.py` real-click conversion + new `test_anonymous_toggle_tappable_with_gate_up`; new `tests/unit/test_gate_header_stacking.py` (3 pins); `test_api_tokens.py` untouched +- `uv run pytest` → 1717 passed, 1 warning (exit 0) +- `uv run pytest --cov=app --cov-report=term-missing` → TOTAL **99%** (>90%) +- E2E in isolation: `test_mobile_hamburger_nav.py` **8 passed**; `test_api_tokens.py` **9 passed** (unchanged); `test_smoke.py` **3 passed**; `test_document_viewer.py` **7 passed** +- `uv run ruff check . && uv run pyright` → clean / 0 errors +- Live probe (375×812, anonymous, fresh server): on `/` and `/history.html` `elementFromPoint` at toggle → SVG `path`, never `#auth-gate`; real click opens menu (`aria-expanded=true`); exactly one visible nav link (Chat) + sign-in copy; Chat link topmost over gate; `#main` inert — criteria 1, 2, 3 confirmed directly +- Criteria: (1) real-click menu on / + /history ✅ (2) dropdown above gate ✅ (3) anonymous contents + #main inert ✅ (4) admin byte-identical (phase-46 tests green) ✅ (5) doc-viewer gate under bar (CSS pin + doc-viewer suite) ✅ (6) full gate green ✅ (7) diff scoped to the 5 code files + new unit test + phase files, nothing in `app/` ✅ (8) commit + todo→complete move left to harness per executor rules (task files already in `complete/`) +- Note: `.agents/remediation_plan.md` (untracked) is a pre-existing artifact of the earlier security audit — left untouched; a missing "N passed" line seen mid-pass was my own `-q`+addopts `-q` = `-qq` quirk, not a defect +- Next pending phase: `86_history_page_width` diff --git a/.agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__00_phase.a1.validate b/.agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__00_phase.a1.validate new file mode 100644 index 0000000..0914b55 --- /dev/null +++ b/.agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__00_phase.a1.validate @@ -0,0 +1,85 @@ +........................................................................ [ 4%] +........................................................................ [ 8%] +........................................................................ [ 12%] +........................................................................ [ 16%] +........................................................................ [ 20%] +........................................................................ [ 25%] +........................................................................ [ 29%] +........................................................................ [ 33%] +........................................................................ [ 37%] +........................................................................ [ 41%] +........................................................................ [ 46%] +........................................................................ [ 50%] +........................................................................ [ 54%] +........................................................................ [ 58%] +........................................................................ [ 62%] +........................................................................ [ 67%] +........................................................................ [ 71%] +........................................................................ [ 75%] +........................................................................ [ 79%] +........................................................................ [ 83%] +........................................................................ [ 88%] +........................................................................ [ 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 52 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 94 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 98 0 100% +app/api/tokens.py 28 0 100% +app/config.py 141 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/errors.py 5 0 100% +app/core/logging.py 13 0 100% +app/core/rate_limit.py 44 0 100% +app/core/security_headers.py 19 0 100% +app/core/tokens.py 33 0 100% +app/db.py 21 0 100% +app/main.py 64 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 217 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 232 0 100% +-------------------------------------------------- +TOTAL 3237 12 99% +coverage gate: app/ 99% (>90%) OK +All checks passed! +0 errors, 0 warnings, 0 informations +validation OK diff --git a/.agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__01_gate_below_header.a1.err b/.agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__01_gate_below_header.a1.err new file mode 100644 index 0000000..e69de29 diff --git a/.agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__01_gate_below_header.a1.md b/.agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__01_gate_below_header.a1.md new file mode 100644 index 0000000..7321af2 --- /dev/null +++ b/.agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__01_gate_below_header.a1.md @@ -0,0 +1,17 @@ +Task 01 complete — all green. + +**Implemented** +- `frontend/assets/styles.css`: `.auth-gate` `z-index: 500 → 15` (the one-value fix, A1) + stacking comment rewritten to the phase-85 contract (15 gate < 20 header < 21 dropdown; skip-link 100 / 1000-family overlays unaffected; `#main` lock is JS, not z-order) +- `frontend/index.html` / `frontend/document.html`: gate-section comments reworded (header stays reachable; `#main` stays inert) — markup byte-identical, comment-only +- `frontend/assets/token-gate.js`: docstring sweep only — "only interactive surface" → "only CONTENT-level interactive surface" + phase-85 note; logic byte-identical +- New `tests/unit/test_gate_header_stacking.py`: 3 source-level z-order pins (gate=15, header=20 with gate15) + the gate still covers content (fixed/inset:0, `[hidden]` display:none) + +**Test / lint results** +- `uv run pytest tests/unit/test_gate_header_stacking.py -v` → 3 passed +- `uv run pytest --cov=app --cov-report=term-missing` → 1717 passed, `app/` TOTAL **99%** (>90% ✓) +- `uv run ruff check .` → All checks passed; `uv run pyright` → 0 errors, 0 warnings +- `git diff --stat` limited to the 4 frontend files (CSS value + comments only) + the new test; `grep "z-index: 500"` no longer matches anything + +**Decisions**: the dropdown's `z-index: 21` lives on the base `.app-nav` rule (shared with `.is-open`), so the pin targets `.app-nav` in the ≤640px block — same as the existing phase-46 pin; value 15 kept as owner-decided. + +**Next pending task**: `02_e2e_pin_updates.md` (same phase — real-click conversion + TODO-regression E2E pin). diff --git a/.agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__01_gate_below_header.a1.validate b/.agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__01_gate_below_header.a1.validate new file mode 100644 index 0000000..0914b55 --- /dev/null +++ b/.agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__01_gate_below_header.a1.validate @@ -0,0 +1,85 @@ +........................................................................ [ 4%] +........................................................................ [ 8%] +........................................................................ [ 12%] +........................................................................ [ 16%] +........................................................................ [ 20%] +........................................................................ [ 25%] +........................................................................ [ 29%] +........................................................................ [ 33%] +........................................................................ [ 37%] +........................................................................ [ 41%] +........................................................................ [ 46%] +........................................................................ [ 50%] +........................................................................ [ 54%] +........................................................................ [ 58%] +........................................................................ [ 62%] +........................................................................ [ 67%] +........................................................................ [ 71%] +........................................................................ [ 75%] +........................................................................ [ 79%] +........................................................................ [ 83%] +........................................................................ [ 88%] +........................................................................ [ 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 52 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 94 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 98 0 100% +app/api/tokens.py 28 0 100% +app/config.py 141 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/errors.py 5 0 100% +app/core/logging.py 13 0 100% +app/core/rate_limit.py 44 0 100% +app/core/security_headers.py 19 0 100% +app/core/tokens.py 33 0 100% +app/db.py 21 0 100% +app/main.py 64 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 217 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 232 0 100% +-------------------------------------------------- +TOTAL 3237 12 99% +coverage gate: app/ 99% (>90%) OK +All checks passed! +0 errors, 0 warnings, 0 informations +validation OK diff --git a/.agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__02_e2e_pin_updates.a1.err b/.agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__02_e2e_pin_updates.a1.err new file mode 100644 index 0000000..e69de29 diff --git a/.agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__02_e2e_pin_updates.a1.md b/.agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__02_e2e_pin_updates.a1.md new file mode 100644 index 0000000..6dc01c4 --- /dev/null +++ b/.agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__02_e2e_pin_updates.a1.md @@ -0,0 +1,19 @@ +All green. Task 02 is complete. + +**Implemented** +- `tests/e2e/test_mobile_hamburger_nav.py`: retired `_js_open_menu` (JS-dispatch drive) — anonymous tests now use the real-click helper `_open_menu` (`page.click("#nav-toggle")`), docstring rewritten to the phase-85 contract (gate z 15 below header z 20) +- New regression pin `test_anonymous_toggle_tappable_with_gate_up`: with the gate up (`#main` inert), `elementFromPoint` at the toggle center resolves to the toggle/SVG child, never `#auth-gate`; real click opens the menu above the gate (Chat link visible + topmost at its center, gate still up); Esc settles closed +- Module docstring: phase-85 stacking paragraph + numbered mapping entry; all phase-79 "intercepted by the gate" test docstrings/comments swept (assertions kept exactly: one visible "Chat" link, Esc refocus, outside-click at (10,780) doesn't close, 180ms pins) +- `test_api_tokens.py`: verified no hamburger pins (grep clean); run unchanged, green + +**Results** +- `uv run pytest tests/e2e/test_mobile_hamburger_nav.py -v --no-cov` → 8 passed (isolation) +- `uv run pytest tests/e2e/test_api_tokens.py -v --no-cov` → 9 passed, file unchanged (isolation) +- `uv run pytest tests/e2e/test_smoke.py -v --no-cov` → 3 passed +- `uv run pytest --cov=app --cov-report=term-missing` → 1717 passed, coverage 99% (>90%) +- `uv run ruff check . && uv run pyright` → clean +- Criterion grep `querySelector('#nav-toggle').click()` → no matches; my diff touches only the one E2E file (frontend changes in tree are task-01's, committed atomically by the harness at phase end) + +**Deviations** — none; the JS helper was folded into `_open_menu` rather than duplicated (identical real-click body + same 3 assertions). + +**Next pending task:** `.agents/phases/todo/85_mobile_menu_gate_overlap/03_verify_and_commit.md` diff --git a/.agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__02_e2e_pin_updates.a1.validate b/.agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__02_e2e_pin_updates.a1.validate new file mode 100644 index 0000000..0914b55 --- /dev/null +++ b/.agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__02_e2e_pin_updates.a1.validate @@ -0,0 +1,85 @@ +........................................................................ [ 4%] +........................................................................ [ 8%] +........................................................................ [ 12%] +........................................................................ [ 16%] +........................................................................ [ 20%] +........................................................................ [ 25%] +........................................................................ [ 29%] +........................................................................ [ 33%] +........................................................................ [ 37%] +........................................................................ [ 41%] +........................................................................ [ 46%] +........................................................................ [ 50%] +........................................................................ [ 54%] +........................................................................ [ 58%] +........................................................................ [ 62%] +........................................................................ [ 67%] +........................................................................ [ 71%] +........................................................................ [ 75%] +........................................................................ [ 79%] +........................................................................ [ 83%] +........................................................................ [ 88%] +........................................................................ [ 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 52 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 94 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 98 0 100% +app/api/tokens.py 28 0 100% +app/config.py 141 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/errors.py 5 0 100% +app/core/logging.py 13 0 100% +app/core/rate_limit.py 44 0 100% +app/core/security_headers.py 19 0 100% +app/core/tokens.py 33 0 100% +app/db.py 21 0 100% +app/main.py 64 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 217 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 232 0 100% +-------------------------------------------------- +TOTAL 3237 12 99% +coverage gate: app/ 99% (>90%) OK +All checks passed! +0 errors, 0 warnings, 0 informations +validation OK diff --git a/.agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__03_verify_and_commit.a1.err b/.agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__03_verify_and_commit.a1.err new file mode 100644 index 0000000..e69de29 diff --git a/.agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__03_verify_and_commit.a1.md b/.agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__03_verify_and_commit.a1.md new file mode 100644 index 0000000..67ce83c --- /dev/null +++ b/.agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__03_verify_and_commit.a1.md @@ -0,0 +1,11 @@ +Screenshot confirms the fix visually: the anonymous menu (Chat + Sign in) renders **above** the gate card. Phase 85 is fully gated. + +**Report — Phase 85, task 03 (verify & commit)** + +- Full gate green: `uv run pytest` → 1717 passed; `--cov=app` → TOTAL **99%** (>90% floor, no `app/` change) +- E2E in isolation: `test_mobile_hamburger_nav.py` → 8 passed (real-click contract + new `elementFromPoint` pin); `test_api_tokens.py` → 9 passed, **file unchanged** (phase-79 lock contract intact); `test_smoke.py` → 3 passed; `test_document_viewer.py` → 7 passed +- `uv run ruff check . && uv run pyright` → clean (0 errors/warnings) +- Live check (dev server :8000, 375×812, not signed in): 12/12 checks passed — real tap opens the menu above the gate (Chat + sign-in visible, token card behind/below), `elementFromPoint` at toggle resolves to the SVG (never `#auth-gate`), wrong-token error line + menu independence (Esc closes, gate stays), admin menu unchanged; log + 2 screenshots in `.agents/reports/85_mobile_menu_gate_overlap/` +- Working tree verified: only `styles.css` (z 500→15 + comment), `index.html`/`document.html` (comments only), `token-gate.js` (docstring only), `test_mobile_hamburger_nav.py`, new `tests/unit/test_gate_header_stacking.py` + phase files — nothing in `app/`, `pyproject.toml`, `uv.lock` +- Deviation (per executor rules, overrides task steps 3–4): **no `git commit` made and phase dir not moved** — all changes left in the working tree for the harness's single atomic phase commit and the `todo/ → complete/` move +- Next pending task: none in this phase (task 03 was the last); following phases: `86_history_page_width`, `87_big_read_progress` diff --git a/.agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__03_verify_and_commit.a1.validate b/.agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__03_verify_and_commit.a1.validate new file mode 100644 index 0000000..0914b55 --- /dev/null +++ b/.agents/reports/85_mobile_menu_gate_overlap/85_mobile_menu_gate_overlap__03_verify_and_commit.a1.validate @@ -0,0 +1,85 @@ +........................................................................ [ 4%] +........................................................................ [ 8%] +........................................................................ [ 12%] +........................................................................ [ 16%] +........................................................................ [ 20%] +........................................................................ [ 25%] +........................................................................ [ 29%] +........................................................................ [ 33%] +........................................................................ [ 37%] +........................................................................ [ 41%] +........................................................................ [ 46%] +........................................................................ [ 50%] +........................................................................ [ 54%] +........................................................................ [ 58%] +........................................................................ [ 62%] +........................................................................ [ 67%] +........................................................................ [ 71%] +........................................................................ [ 75%] +........................................................................ [ 79%] +........................................................................ [ 83%] +........................................................................ [ 88%] +........................................................................ [ 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 52 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 94 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 98 0 100% +app/api/tokens.py 28 0 100% +app/config.py 141 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/errors.py 5 0 100% +app/core/logging.py 13 0 100% +app/core/rate_limit.py 44 0 100% +app/core/security_headers.py 19 0 100% +app/core/tokens.py 33 0 100% +app/db.py 21 0 100% +app/main.py 64 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 217 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 232 0 100% +-------------------------------------------------- +TOTAL 3237 12 99% +coverage gate: app/ 99% (>90%) OK +All checks passed! +0 errors, 0 warnings, 0 informations +validation OK diff --git a/.agents/reports/85_mobile_menu_gate_overlap/livecheck_admin_menu.png b/.agents/reports/85_mobile_menu_gate_overlap/livecheck_admin_menu.png new file mode 100644 index 0000000000000000000000000000000000000000..953aac7232ee4522906d9ad37b9079b8ebc02397 GIT binary patch literal 45480 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 literal 0 HcmV?d00001 diff --git a/frontend/assets/styles.css b/frontend/assets/styles.css index 848036e..d5291d0 100644 --- a/frontend/assets/styles.css +++ b/frontend/assets/styles.css @@ -1631,23 +1631,28 @@ details.thinking .thinking-text ul { margin: 0 0 0.5rem; } /* Phase 79 (task 05): the in-app token gate — the gate surface of the two token-only pages (the shell + the document viewer, one shared .auth-gate markup each). A body-level FIXED overlay (the - body-level doc-modal precedent): while visible it is the ONLY - interactive surface — assets/token-gate.js locks the root (#main, - inert) so focus and keyboard traversal stay inside the gate - (WCAG, the inert-pair contract). - Stacking: z-index 500 — above the app content (the sticky header is - 20, the skip-link 100) but BELOW the doc-modal (1000), which can - only be opened from the unlocked app anyway. Solid --bg: the canvas - + grid texture live on (the body stays transparent), so the - overlay reads as the app's own surface — no blur (the phase-08 - perf anchor). + body-level doc-modal precedent): while visible it is the only + CONTENT-level interactive surface — assets/token-gate.js locks the + root (#main, inert) so focus and keyboard traversal stay inside + the gate (WCAG, the inert-pair contract). + Stacking (phase 85, TODO.md L3): z-index 15 — ABOVE all app + content (static) but BELOW the sticky header (20) and its mobile + dropdown (21, inside the header's stacking context): the + unauthenticated visitor keeps a reachable hamburger + menu while + the gate still covers and locks the app content (#main stays + inert — the lock is JS, not z-order — phase 79). The skip-link + (100) and the 1000-family overlays (doc-modal, sync backdrop) are + unaffected — all above 15; the doc-modal can only be opened from + the unlocked app anyway. Solid --bg: the canvas + grid texture + live on (the body stays transparent), so the overlay reads + as the app's own surface — no blur (the phase-08 perf anchor). The centered card reuses the #sources-gate visual language (surface card + hairline + glyph + heading + sub + action) in a tighter column. */ .auth-gate { position: fixed; inset: 0; - z-index: 500; + z-index: 15; display: flex; /* the card is the only in-flow child — margin: auto centers it */ overflow-y: auto; /* short viewports: the card scrolls fully into view */ background: var(--bg); diff --git a/frontend/assets/token-gate.js b/frontend/assets/token-gate.js index 8de5944..d18300e 100644 --- a/frontend/assets/token-gate.js +++ b/frontend/assets/token-gate.js @@ -193,9 +193,13 @@ export async function mountGate(lockRoot, onAuthed) { /* Anonymous: reveal the gate (drop hidden AND inert — the inert-pair contract), lock the app, focus the token input. The gate is the - only interactive surface while visible: the lock root is inert, - so Tab never reaches the locked app (the composer on the shell, - the content on the viewer). */ + only CONTENT-level interactive surface while visible: the lock + root is inert, so Tab never reaches the locked app (the composer + on the shell, the content on the viewer). The header was never + the lock root (and is never inert) — it was only visually + covered pre-phase-85: the gate's z-index (15) now sits below the + header (20), so the mobile hamburger + menu stay reachable while + the app content stays inert-locked (TODO.md L3). */ if (gate) { gate.hidden = false; gate.inert = false; diff --git a/frontend/document.html b/frontend/document.html index 86183a7..1ed7474 100644 --- a/frontend/document.html +++ b/frontend/document.html @@ -162,7 +162,10 @@ root; the existing boot sequence (whoami → load content) runs as onAuthed — an admin (or a validly cached token user) gets it immediately, the gate never shows. SHIPS hidden + inert - (the phase-16 ship-hidden pattern). --> + (the phase-16 ship-hidden pattern). Phase 85 (TODO.md L3): + same stacking as the shell gate — the overlay (z-index 15) + sits below the viewer's sticky bar (20), so the hamburger + + menu stay reachable while #main stays inert-locked. -->