phase: 92_theme_save_and_coverage
**Phase 92 final verification pass — all green.** This pass re-verified the completed tasks (all 5 task files already in `complete/`) against every completion criterion; no defects found, nothing to fix. - Verified: 9th identity var `grid_line` end-to-end (migration `0015` at head, model/`theming.py`/schemas/API, 422 + built-in→NULL tests present); `styles.css` zero hardcoded literals outside `:root` + derived `--brand-*` vars; 9th picker in theme form; wordmark themed; `theme.js` save/reset/re-show/mount live-sync; dedicated E2E suite + phase-91 suite updated. - `uv run pytest --cov=app --cov-report=term-missing` → **1845 passed, exit 0, TOTAL 99%** (>90%) - `uv run ruff check .` → clean; `uv run pyright` → 0 errors, 0 warnings - `uv run pytest tests/e2e/test_theme_save_and_coverage.py -v --no-cov` → **3 passed** (save-live, reset-live, whole-site) - `uv run pytest tests/e2e/test_admin_theme_tab.py -v --no-cov` → **5 passed** - Criteria: (1) Save/Reset repaint open page, no nav, SPA-nav survives, pre-paint intact ✅; (2) both `rg` gates green (only `:root` + documented `#fff` Stop label; zero SVG hex attrs), grid/selection/hovers/wash/wordmark E2E-proven ✅; (3) no-op contract live-checked: row-less `/` = no tag + exact A1 CSP, grid-only row = 9-var tag in `COLOR_FIELDS` order + sha256 CSP, with-row ≡ row-less bytes ✅; (4) full suite/coverage/lint/both E2E ✅; (5) commit left to the harness per instructions. - Deviations (previously made, probe-verified, kept): live repaint uses CSSOM `<html>` overrides because Chromium blocks `<style>` textContent mutations under the locked sha256-only CSP (tag text still mirrors the next load; `<html>` style exact-saved after Save, empty after Reset); wordmark themed via 3 `.brand-mark` CSS rules instead of inline styles (task 03's inline attrs were CSP-blocked — fixed during task 04). - Next pending phase: none — `todo/` contains only `92_theme_save_and_coverage`.
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
**Phase 92 final verification pass — all green.** This pass re-verified the completed tasks (all 5 task files already in `complete/`) against every completion criterion; no defects found, nothing to fix.
|
||||
|
||||
- Verified: 9th identity var `grid_line` end-to-end (migration `0015` at head, model/`theming.py`/schemas/API, 422 + built-in→NULL tests present); `styles.css` zero hardcoded literals outside `:root` + derived `--brand-*` vars; 9th picker in theme form; wordmark themed; `theme.js` save/reset/re-show/mount live-sync; dedicated E2E suite + phase-91 suite updated.
|
||||
- `uv run pytest --cov=app --cov-report=term-missing` → **1845 passed, exit 0, TOTAL 99%** (>90%)
|
||||
- `uv run ruff check .` → clean; `uv run pyright` → 0 errors, 0 warnings
|
||||
- `uv run pytest tests/e2e/test_theme_save_and_coverage.py -v --no-cov` → **3 passed** (save-live, reset-live, whole-site)
|
||||
- `uv run pytest tests/e2e/test_admin_theme_tab.py -v --no-cov` → **5 passed**
|
||||
- Criteria: (1) Save/Reset repaint open page, no nav, SPA-nav survives, pre-paint intact ✅; (2) both `rg` gates green (only `:root` + documented `#fff` Stop label; zero SVG hex attrs), grid/selection/hovers/wash/wordmark E2E-proven ✅; (3) no-op contract live-checked: row-less `/` = no tag + exact A1 CSP, grid-only row = 9-var tag in `COLOR_FIELDS` order + sha256 CSP, with-row ≡ row-less bytes ✅; (4) full suite/coverage/lint/both E2E ✅; (5) commit left to the harness per instructions.
|
||||
- Deviations (previously made, probe-verified, kept): live repaint uses CSSOM `<html>` overrides because Chromium blocks `<style>` textContent mutations under the locked sha256-only CSP (tag text still mirrors the next load; `<html>` style exact-saved after Save, empty after Reset); wordmark themed via 3 `.brand-mark` CSS rules instead of inline styles (task 03's inline attrs were CSP-blocked — fixed during task 04).
|
||||
- Next pending phase: none — `todo/` contains only `92_theme_save_and_coverage`.
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
........................................................................ [ 3%]
|
||||
........................................................................ [ 7%]
|
||||
........................................................................ [ 11%]
|
||||
........................................................................ [ 15%]
|
||||
........................................................................ [ 19%]
|
||||
........................................................................ [ 23%]
|
||||
........................................................................ [ 27%]
|
||||
........................................................................ [ 31%]
|
||||
........................................................................ [ 35%]
|
||||
........................................................................ [ 39%]
|
||||
........................................................................ [ 42%]
|
||||
........................................................................ [ 46%]
|
||||
........................................................................ [ 50%]
|
||||
........................................................................ [ 54%]
|
||||
........................................................................ [ 58%]
|
||||
........................................................................ [ 62%]
|
||||
........................................................................ [ 66%]
|
||||
........................................................................ [ 70%]
|
||||
........................................................................ [ 74%]
|
||||
........................................................................ [ 78%]
|
||||
........................................................................ [ 81%]
|
||||
........................................................................ [ 85%]
|
||||
........................................................................ [ 89%]
|
||||
........................................................................ [ 93%]
|
||||
........................................................................ [ 97%]
|
||||
............................................ [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 13 0 100%
|
||||
app/api/doc_drafts.py 94 0 100%
|
||||
app/api/docs.py 50 0 100%
|
||||
app/api/git_sources.py 229 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/api/ui_settings.py 55 0 100%
|
||||
app/config.py 132 0 100%
|
||||
app/core/__init__.py 0 0 100%
|
||||
app/core/auth.py 45 0 100%
|
||||
app/core/caching.py 124 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 20 0 100%
|
||||
app/core/theming.py 38 0 100%
|
||||
app/core/tokens.py 33 0 100%
|
||||
app/db.py 21 0 100%
|
||||
app/main.py 66 0 100%
|
||||
app/models.py 110 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 190 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 253 0 100%
|
||||
--------------------------------------------------
|
||||
TOTAL 3413 12 99%
|
||||
coverage gate: app/ 99% (>90%) OK
|
||||
All checks passed!
|
||||
0 errors, 0 warnings, 0 informations
|
||||
WARNING: there is a new pyright version available (v1.1.411 -> v1.1.413).
|
||||
Please install the new version or set PYRIGHT_PYTHON_FORCE_VERSION to `latest`
|
||||
|
||||
validation OK
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
All remaining rg matches are legitimate (0014-migration schema descriptions, unrelated llm-batch comment, and the template-pinning comments owned by task 03). The full suite, coverage, and linters all ran green on the final code.
|
||||
|
||||
**Task 01 complete — `--grid-line` 9th identity variable, end-to-end server-side**
|
||||
|
||||
- `alembic/versions/0015_grid_line.py`: additive `grid_line VARCHAR(7) NULL` on `ui_settings`; upgrade → downgrade → upgrade round-trips cleanly (DB now at 0015 head).
|
||||
- `app/models.py` `UiSettings.grid_line` (after `line`), `app/core/theming.py` `BUILTIN_COLORS["grid_line"] = "#4a2626"` (→ 9-tuple `COLOR_FIELDS`, structural-first order), docstring tables updated; `app/schemas.py` `UiSettingsIn/Out` fields; `app/api/ui_settings.py` docstrings only — all logic was `COLOR_FIELDS`-driven, zero loop changes.
|
||||
- `frontend/assets/styles.css`: `--grid-line: #4a2626;` added to `:root` (required by the drift guard to pass this task; `body::before` re-anchoring stays with task 02).
|
||||
- Tests: drift guard 9-names, 9-tuple field order, exact 9-var tag bytes, grid-only middleware tag test (new, `test_caching.py`), `grid_line` 422 + built-in→NULL normalization (unit + live API), `test_models.py` key set; stale-row resilience added to `test_theming.py` DB tests (defect found: they assumed row-missing with no cleanup).
|
||||
- Verified live: row-less GET → 12 keys incl. `grid_line: "#4a2626"`; grid-only PUT → exact 9-var tag with CSP hash; built-in (uppercased) PUT → column NULL, tag removed, plain A1.
|
||||
|
||||
Results: `uv run pytest --cov=app --cov-report=term-missing` → 1844 passed, **99%** app coverage; `uv run ruff check . && uv run pyright` → clean.
|
||||
|
||||
Notable: phase-91 E2E (`test_admin_theme_tab.py`) will fail until its owned 9th-palette-key update in task 05 (8-key `PALETTE` vs 9-field tag); E2E is outside the default suite and task 03 owns the `test_frontend_router.py` picker-count comments.
|
||||
|
||||
Next pending task: `.agents/phases/todo/92_theme_save_and_coverage/02_css_variable_coverage.md`
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
........................................................................ [ 3%]
|
||||
........................................................................ [ 7%]
|
||||
........................................................................ [ 11%]
|
||||
........................................................................ [ 15%]
|
||||
........................................................................ [ 19%]
|
||||
........................................................................ [ 23%]
|
||||
........................................................................ [ 27%]
|
||||
........................................................................ [ 31%]
|
||||
........................................................................ [ 35%]
|
||||
........................................................................ [ 39%]
|
||||
........................................................................ [ 42%]
|
||||
........................................................................ [ 46%]
|
||||
........................................................................ [ 50%]
|
||||
........................................................................ [ 54%]
|
||||
........................................................................ [ 58%]
|
||||
........................................................................ [ 62%]
|
||||
........................................................................ [ 66%]
|
||||
........................................................................ [ 70%]
|
||||
........................................................................ [ 74%]
|
||||
........................................................................ [ 78%]
|
||||
........................................................................ [ 81%]
|
||||
........................................................................ [ 85%]
|
||||
........................................................................ [ 89%]
|
||||
........................................................................ [ 93%]
|
||||
........................................................................ [ 97%]
|
||||
............................................ [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 13 0 100%
|
||||
app/api/doc_drafts.py 94 0 100%
|
||||
app/api/docs.py 50 0 100%
|
||||
app/api/git_sources.py 229 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/api/ui_settings.py 55 0 100%
|
||||
app/config.py 132 0 100%
|
||||
app/core/__init__.py 0 0 100%
|
||||
app/core/auth.py 45 0 100%
|
||||
app/core/caching.py 124 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 20 0 100%
|
||||
app/core/theming.py 38 0 100%
|
||||
app/core/tokens.py 33 0 100%
|
||||
app/db.py 21 0 100%
|
||||
app/main.py 66 0 100%
|
||||
app/models.py 110 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 190 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 253 0 100%
|
||||
--------------------------------------------------
|
||||
TOTAL 3413 12 99%
|
||||
coverage gate: app/ 99% (>90%) OK
|
||||
All checks passed!
|
||||
0 errors, 0 warnings, 0 informations
|
||||
WARNING: there is a new pyright version available (v1.1.411 -> v1.1.413).
|
||||
Please install the new version or set PYRIGHT_PYTHON_FORCE_VERSION to `latest`
|
||||
|
||||
validation OK
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
All green. Final report:
|
||||
|
||||
**Task 02 complete — `styles.css` whole-site variable coverage**
|
||||
|
||||
- `:root`: kept `--grid-line: #4a2626` (comment reworded to spec), added derived block `--brand-hover/-busy/-stop` (color-mix, documented as computed/not-stored)
|
||||
- Full replacement table applied: grid texture, `::selection`, hairline (brand fade, comment reworded), 2 `pre` blocks, 6 surface backgrounds, 17 button hovers → `var(--brand-hover)`, disabled/busy/stop states, 3 chip washes, ok/err alpha derivatives, 4 backdrops, spinner track, user-code bg; comments re-anchored (grid, is-stop, spinner)
|
||||
- Gate green: `rg -e '#[0-9a-fA-F]{3,6}\b|rgba?\(' frontend/assets/styles.css` → matches only in first `:root` + the single documented `#fff` Stop-label line (rg 15.2 rejects `-E`; used `-e`, same pattern)
|
||||
- Updated 7 pre-existing CSS guardrail unit tests in place (old-literal pins → new mechanism, intent preserved); real-Chromium sanity: PASS (default + saved palette drive grid/hover/hairline)
|
||||
|
||||
**Results**
|
||||
- `uv run pytest --cov=app --cov-report=term-missing` → 1844 passed, TOTAL **99%** (>90%)
|
||||
- `uv run ruff check .` → clean; `uv run pyright` → 0 errors, 0 warnings
|
||||
- E2E: `test_background_no_motion` + `test_dark_tech_theme` green; `test_admin_theme_tab.py` has **3 pre-existing failures from task 01** (9-var server vs 8-picker form — verified by stashing only my files; suite update + 9th picker are task 03/05 scope)
|
||||
|
||||
**Deviations**
|
||||
- `.doc-modal-panel` shadow: `rgb(0 0 0 / 0.55)` → `color-mix(in srgb, black 55%, transparent)` — design said "unchanged" but the gate forbids `rgb(` outside `:root`; rendered color identical (depth-black, not themed), documented inline
|
||||
- is-stop comment cites exact computed ratios (5.8:1/8.5:1/3.4:1, default ≈(187,50,73)) instead of the doc's approximation (5.9:1)
|
||||
|
||||
**Next pending task:** `03_tab_ninth_picker_and_brand_mark.md`
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
........................................................................ [ 3%]
|
||||
........................................................................ [ 7%]
|
||||
........................................................................ [ 11%]
|
||||
........................................................................ [ 15%]
|
||||
........................................................................ [ 19%]
|
||||
........................................................................ [ 23%]
|
||||
........................................................................ [ 27%]
|
||||
........................................................................ [ 31%]
|
||||
........................................................................ [ 35%]
|
||||
........................................................................ [ 39%]
|
||||
........................................................................ [ 42%]
|
||||
........................................................................ [ 46%]
|
||||
........................................................................ [ 50%]
|
||||
........................................................................ [ 54%]
|
||||
........................................................................ [ 58%]
|
||||
........................................................................ [ 62%]
|
||||
........................................................................ [ 66%]
|
||||
........................................................................ [ 70%]
|
||||
........................................................................ [ 74%]
|
||||
........................................................................ [ 78%]
|
||||
........................................................................ [ 81%]
|
||||
........................................................................ [ 85%]
|
||||
........................................................................ [ 89%]
|
||||
........................................................................ [ 93%]
|
||||
........................................................................ [ 97%]
|
||||
............................................ [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 13 0 100%
|
||||
app/api/doc_drafts.py 94 0 100%
|
||||
app/api/docs.py 50 0 100%
|
||||
app/api/git_sources.py 229 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/api/ui_settings.py 55 0 100%
|
||||
app/config.py 132 0 100%
|
||||
app/core/__init__.py 0 0 100%
|
||||
app/core/auth.py 45 0 100%
|
||||
app/core/caching.py 124 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 20 0 100%
|
||||
app/core/theming.py 38 0 100%
|
||||
app/core/tokens.py 33 0 100%
|
||||
app/db.py 21 0 100%
|
||||
app/main.py 66 0 100%
|
||||
app/models.py 110 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 190 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 253 0 100%
|
||||
--------------------------------------------------
|
||||
TOTAL 3413 12 99%
|
||||
coverage gate: app/ 99% (>90%) OK
|
||||
All checks passed!
|
||||
0 errors, 0 warnings, 0 informations
|
||||
WARNING: there is a new pyright version available (v1.1.411 -> v1.1.413).
|
||||
Please install the new version or set PYRIGHT_PYTHON_FORCE_VERSION to `latest`
|
||||
|
||||
validation OK
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
All complete and green. The working tree also carries tasks 01/02's changes (the harness makes one atomic phase commit); my delta for task 03 is the five wordmarks, the picker cell, the theme.js count comments, and the test pin.
|
||||
|
||||
**Report — task 03 (tab's 9th picker + brand-mark wordmark theming)**
|
||||
|
||||
- `frontend/index.html`: added the 9th picker cell (`theme-grid-line`, `Grid lines (--grid-line)`, `type="color"`, static built-in `value="#4a2626"`) immediately after the Border cell, mirroring `COLOR_FIELDS` order; fieldset legend untouched (no stated 8/11 counts existed in the theme view — "update only where stated")
|
||||
- Brand-mark SVG in all five files (`index`, `login`, `document`, `shared`, `doc-edit`): hex presentation attrs → inline styles resolving from `:root` (`fill: var(--surface); stroke: var(--brand)` / `fill: var(--brand)` / `fill: none; stroke: var(--brand-ink)`); still byte-identical across the five files; default render identical (same built-in values)
|
||||
- `theme.js`: docstring + comment counts updated per the phase overview (11→12 inputs/values, 8→9 pickers/overrides)
|
||||
- `tests/unit/test_frontend_router.py`: scaffold pin now 9 (docstring + comment) and the id loop gained `theme-grid-line` after `theme-line`
|
||||
|
||||
**Results**
|
||||
- Gates: `rg 'fill="#|stroke="#' frontend/*.html` → 0 matches; `rg "theme-grid-line" frontend/` → only the index.html label+input
|
||||
- `uv run pytest tests/unit/test_frontend_router.py -v --no-cov` → 28 passed
|
||||
- `uv run pytest --cov=app` → 1844 passed, app coverage 99% (>90%)
|
||||
- `uv run ruff check .` → clean; `uv run pyright` → 0 errors, 0 warnings
|
||||
|
||||
**Notes:** live dev-server check (work item 6) is deferred by design — the preview binding lands in task 04; E2E proof is task 05's. Left for later tasks (not touched): `tests/e2e/test_admin_theme_tab.py` count comments (task 05).
|
||||
|
||||
**Next pending task:** `04_live_theme_apply.md`
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
........................................................................ [ 3%]
|
||||
........................................................................ [ 7%]
|
||||
........................................................................ [ 11%]
|
||||
........................................................................ [ 15%]
|
||||
........................................................................ [ 19%]
|
||||
........................................................................ [ 23%]
|
||||
........................................................................ [ 27%]
|
||||
........................................................................ [ 31%]
|
||||
........................................................................ [ 35%]
|
||||
........................................................................ [ 39%]
|
||||
........................................................................ [ 42%]
|
||||
........................................................................ [ 46%]
|
||||
........................................................................ [ 50%]
|
||||
........................................................................ [ 54%]
|
||||
........................................................................ [ 58%]
|
||||
........................................................................ [ 62%]
|
||||
........................................................................ [ 66%]
|
||||
........................................................................ [ 70%]
|
||||
........................................................................ [ 74%]
|
||||
........................................................................ [ 78%]
|
||||
........................................................................ [ 81%]
|
||||
........................................................................ [ 85%]
|
||||
........................................................................ [ 89%]
|
||||
........................................................................ [ 93%]
|
||||
........................................................................ [ 97%]
|
||||
............................................ [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 13 0 100%
|
||||
app/api/doc_drafts.py 94 0 100%
|
||||
app/api/docs.py 50 0 100%
|
||||
app/api/git_sources.py 229 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/api/ui_settings.py 55 0 100%
|
||||
app/config.py 132 0 100%
|
||||
app/core/__init__.py 0 0 100%
|
||||
app/core/auth.py 45 0 100%
|
||||
app/core/caching.py 124 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 20 0 100%
|
||||
app/core/theming.py 38 0 100%
|
||||
app/core/tokens.py 33 0 100%
|
||||
app/db.py 21 0 100%
|
||||
app/main.py 66 0 100%
|
||||
app/models.py 110 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 190 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 253 0 100%
|
||||
--------------------------------------------------
|
||||
TOTAL 3413 12 99%
|
||||
coverage gate: app/ 99% (>90%) OK
|
||||
All checks passed!
|
||||
0 errors, 0 warnings, 0 informations
|
||||
WARNING: there is a new pyright version available (v1.1.411 -> v1.1.413).
|
||||
Please install the new version or set PYRIGHT_PYTHON_FORCE_VERSION to `latest`
|
||||
|
||||
validation OK
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
All verified. The diff is coherent and complete.
|
||||
|
||||
## Report — Task 04: live theme apply (no reload, no revert)
|
||||
|
||||
**Implemented**
|
||||
- `theme.js`: `FIELDS` + 9th entry (`grid_line`), `BUILTINS` capture (static input values, pre-`loadSettings`), `themeRootContent` (pure; byte-identical to `theme_style_tag`'s inner content; `null` = no-op), `applyServedTheme` (syncs `#bor-theme` DOM text: remove/create/update), `loadSettings()` now returns the settled settings or `null`, all four call sites (save / reset / `bor:view-refresh` / mount self-heal), docstring reworked.
|
||||
- **Deviation (flagged, per AGENTS.md rule 3):** the task's stated mechanism ("CSSOM on `<style>` is CSP-clean") is **empirically false** — E2E probe against this repo's live phase-82/91 CSP: Chromium re-checks a `<style>` element's content against `style-src` on *every* DOM-API change (`textContent` on the served tag, `createElement`+append, `replaceChildren` all blocked; a fresh palette's sha256 can never be in the page's policy). Reworked fix, server + CSP untouched: tag DOM text still mirrors the next load, and the **9 identity vars as `<html>` inline custom properties** (the preview's CSSOM mechanism — verified clean under both A1 and themed hash policies) repaint the open page. Hence after Save the `<html>` style attribute holds exactly the saved non-default values (never a stale pick; empty after Reset) — the "attribute empty" letter of the criterion is unsatisfiable under the locked CSP while computed = saved hex.
|
||||
- **Fixed a defect in completed work (task 03):** the wordmark's inline `style="…"` attributes in the 5 HTML files are CSP-blocked (hashes never cover style attributes) — 3 console violations per page, wordmark rendered black, `test_security_headers.py` (phase 82) red. Moved the 3 `var()` declarations into `styles.css` (`.brand-mark path:nth-child(1)`, `circle`, `path:nth-child(3)`), removed the attributes; zero violations, default render identical, wordmark follows the saved theme (E2E-verified).
|
||||
|
||||
**Test / lint / coverage**
|
||||
- `uv run pytest --cov=app --cov-report=term` → **1844 passed**, app coverage **99%** (>90%).
|
||||
- `uv run ruff check . && uv run pyright` → **clean** (0 errors).
|
||||
- Live E2E (scratch suite, deleted after green): save applies with NO navigation (tag text + all 9 computed + byte-identical served tag), reset removes tag + paints built-ins, re-show re-syncs an externally-changed row, mount self-heals; SPA nav keeps the theme. E2E regression set (security-headers, header/nav/shared-header, dark-tech, configurable-brand, ui-customization, background, smoke) → **45 passed**.
|
||||
|
||||
**Known pre-existing, NOT fixed (explicitly task 05's scope, work item 5):** `test_admin_theme_tab.py::test_theme_tab_admin_save` + `test_saved_theme_is_pre_paint_for_everyone` — suite's `PALETTE` dict lacks the 9th `grid_line` key (task 01's server change); verified failing identically before my change; other 3 phase-91 tests pass.
|
||||
|
||||
**Next pending task:** `.agents/phases/todo/92_theme_save_and_coverage/05_e2e_save_and_coverage.md`
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
........................................................................ [ 3%]
|
||||
........................................................................ [ 7%]
|
||||
........................................................................ [ 11%]
|
||||
........................................................................ [ 15%]
|
||||
........................................................................ [ 19%]
|
||||
........................................................................ [ 23%]
|
||||
........................................................................ [ 27%]
|
||||
........................................................................ [ 31%]
|
||||
........................................................................ [ 35%]
|
||||
........................................................................ [ 39%]
|
||||
........................................................................ [ 42%]
|
||||
........................................................................ [ 46%]
|
||||
........................................................................ [ 50%]
|
||||
........................................................................ [ 54%]
|
||||
........................................................................ [ 58%]
|
||||
........................................................................ [ 62%]
|
||||
........................................................................ [ 66%]
|
||||
........................................................................ [ 70%]
|
||||
........................................................................ [ 74%]
|
||||
........................................................................ [ 78%]
|
||||
........................................................................ [ 81%]
|
||||
........................................................................ [ 85%]
|
||||
........................................................................ [ 89%]
|
||||
........................................................................ [ 93%]
|
||||
........................................................................ [ 97%]
|
||||
............................................ [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 13 0 100%
|
||||
app/api/doc_drafts.py 94 0 100%
|
||||
app/api/docs.py 50 0 100%
|
||||
app/api/git_sources.py 229 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/api/ui_settings.py 55 0 100%
|
||||
app/config.py 132 0 100%
|
||||
app/core/__init__.py 0 0 100%
|
||||
app/core/auth.py 45 0 100%
|
||||
app/core/caching.py 124 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 20 0 100%
|
||||
app/core/theming.py 38 0 100%
|
||||
app/core/tokens.py 33 0 100%
|
||||
app/db.py 21 0 100%
|
||||
app/main.py 66 0 100%
|
||||
app/models.py 110 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 190 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 253 0 100%
|
||||
--------------------------------------------------
|
||||
TOTAL 3413 12 99%
|
||||
coverage gate: app/ 99% (>90%) OK
|
||||
All checks passed!
|
||||
0 errors, 0 warnings, 0 informations
|
||||
WARNING: there is a new pyright version available (v1.1.411 -> v1.1.413).
|
||||
Please install the new version or set PYRIGHT_PYTHON_FORCE_VERSION to `latest`
|
||||
|
||||
validation OK
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
Everything is green in the final state. Final verification summary complete.
|
||||
|
||||
**Report — Phase 92, task 05 (E2E: save/reset apply live + whole-site coverage)**
|
||||
|
||||
- Implemented `tests/e2e/test_theme_save_and_coverage.py` (3 tests, house per-module scaffold mirroring the phase-91 file): save-applies-live-no-reload (9-var computed palette + synced `#bor-theme` DOM text + exact `<html>` override set, server raw tag, SPA nav to Chat keeps theme), reset-applies-live (tag removed from live doc, built-ins painted, byte-identical with-row vs row-less), whole-site (grid `body::before` 60% `--grid-line`, `::selection` 45% brand, `--brand-hover` hovers ≠ legacy indigo, nav wash = brand-soft exact, wordmark = surface exact, pre-paint raw tag + CSP hash) — with a premultiplied sRGB `color-mix` helper parsing the browser's `color(srgb …)` serialization at ±1/channel.
|
||||
- Updated `tests/e2e/test_admin_theme_tab.py` in place: `PALETTE` gains `grid_line: "#2b3550"` (required — 12-key PUT echo + 9-field DB row assert) and count comments 8→9 / 11→12 only.
|
||||
- Deviation (documented in the new file's docstring): the task's literal "empty `<html>` style after Save" is impossible under the repo CSP — probe-verified that Chromium re-checks `style-src` on every `<style>` DOM-text mutation (textContent/createElement/replaceChildren all blocked), so task 04's CSSOM `<html>` overrides are the only CSP-clean repaint path; test 1 asserts "overrides are EXACTLY the saved palette" (no stale pick) instead. Also added mount-settle gates (race: out-of-order mount `loadSettings` could re-reconcile onto a stale read), and used an `""` absent-tag sentinel (Playwright `wait_for_function` serializes Python `None` as JS `undefined`).
|
||||
- Pin verified: test 1 FAILS (15s timeout) with the phase-91 `theme.js` swapped in, passes with task 04's code.
|
||||
- Results: `uv run pytest tests/e2e/test_theme_save_and_coverage.py -v --no-cov` → 3 passed (isolation); `uv run pytest tests/e2e/test_admin_theme_tab.py -v --no-cov` → 5 passed (isolation); `uv run pytest --cov=app --cov-report=term-missing` → 1844 passed, app coverage 99%; `uv run ruff check . && uv run pyright` → clean (0 errors).
|
||||
- No changes to `app/`, `.agents/`, or other completed work; no commits (left for the harness).
|
||||
- Next pending task: none in `92_theme_save_and_coverage` (task 05 is the last — phase complete).
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
........................................................................ [ 3%]
|
||||
........................................................................ [ 7%]
|
||||
........................................................................ [ 11%]
|
||||
........................................................................ [ 15%]
|
||||
........................................................................ [ 19%]
|
||||
........................................................................ [ 23%]
|
||||
........................................................................ [ 27%]
|
||||
........................................................................ [ 31%]
|
||||
........................................................................ [ 35%]
|
||||
........................................................................ [ 39%]
|
||||
........................................................................ [ 42%]
|
||||
........................................................................ [ 46%]
|
||||
........................................................................ [ 50%]
|
||||
........................................................................ [ 54%]
|
||||
........................................................................ [ 58%]
|
||||
........................................................................ [ 62%]
|
||||
........................................................................ [ 66%]
|
||||
........................................................................ [ 70%]
|
||||
........................................................................ [ 74%]
|
||||
........................................................................ [ 78%]
|
||||
........................................................................ [ 81%]
|
||||
........................................................................ [ 85%]
|
||||
........................................................................ [ 89%]
|
||||
........................................................................ [ 93%]
|
||||
........................................................................ [ 97%]
|
||||
............................................ [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 13 0 100%
|
||||
app/api/doc_drafts.py 94 0 100%
|
||||
app/api/docs.py 50 0 100%
|
||||
app/api/git_sources.py 229 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/api/ui_settings.py 55 0 100%
|
||||
app/config.py 132 0 100%
|
||||
app/core/__init__.py 0 0 100%
|
||||
app/core/auth.py 45 0 100%
|
||||
app/core/caching.py 124 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 20 0 100%
|
||||
app/core/theming.py 38 0 100%
|
||||
app/core/tokens.py 33 0 100%
|
||||
app/db.py 21 0 100%
|
||||
app/main.py 66 0 100%
|
||||
app/models.py 110 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 190 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 253 0 100%
|
||||
--------------------------------------------------
|
||||
TOTAL 3413 12 99%
|
||||
coverage gate: app/ 99% (>90%) OK
|
||||
All checks passed!
|
||||
0 errors, 0 warnings, 0 informations
|
||||
validation OK
|
||||
Reference in New Issue
Block a user