feat: phases 77–80 — navbar view refresh, static background, API tokens, history suggestion chips
Single consolidated commit for four completed, validated phases (77, 78, 79, 80). The pipeline run left all work uncommitted because the harness commits only with PHASE_COMMIT=1 while child executors are forbidden from committing; the phases themselves all passed validation and moved to .agents/phases/complete/. Phase 77 — navbar view refresh - router.js dispatches bor:view-refresh on re-show / active re-click / popstate (gated on wasMounted; first show and boot exempt) - History / RAG / Sources / Tuning re-fetch on refresh (admin branch); Chat deliberately excluded (stream survival) - History "Refresh" button (admin-only, in-flight disable + status line) - New story suite tests/e2e/test_navbar_refresh.py (7 tests) Phase 78 — static background - Removed the animated glow layers; static 44px grid over the flat --bg canvas; default and reduced-motion renders byte-identical - Updated background/theme E2E suites; removed bg-glow test pins Phase 79 — API tokens - api_tokens model + migration 0012; hash-only token service - Admin tokens API + Tokens admin view; POST /api/token-auth; live-revoking require_user on chat / suggestions / document content - Frontend token gate with localStorage cache; anonymous E2E suites migrated to token login - New story suite tests/e2e/test_api_tokens.py (9 tests) Phase 80 — history suggestion chips - last_questions() endpoint with SEED fallback; startNewChat() refetch - Seed-semantics docs (config.py, .env.example, README) - Integration state matrix + E2E suite rewritten to the 4 chip states Also included: phase-76 report artifacts and the repo restore-test-db skill (previously untracked), scripts/* ruff fixes from phase 77. Final gate state (phase 80 final pass, covers everything above): - uv run pytest --cov=app → 1637 passed, 0 failed, app/ coverage 99% - uv run ruff check . && uv run pyright → clean, 0 errors - Per-phase story E2E suites green in isolation
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
# Phase 78 — Static background (the animated glow layers are removed)
|
||||
|
||||
**Source:** `TODO.md` L4 — "Remove the animated css background, it's too resource intensive"
|
||||
**Story:** n/a (TODO-derived — supersedes the fading-glow contract of `.agents/user_stories/background-no-motion.md` (phase 25), which itself superseded `background-animation.md` (phase 08))
|
||||
**Context:** `frontend/assets/styles.css` (the background block, ~lines 70–155: the STATIC grid texture on `body::before`, the three opacity-fading glow spots on `body::after` / `html::before` / `html::after`, the `@keyframes bg-glow-a/b/c` blocks, and the `prefers-reduced-motion` rule that stills those layers), `tests/unit/test_background_animation.py` + `tests/unit/test_background_no_motion.py` (source-level pins of the glow contract), `tests/e2e/test_background_no_motion.py` (the phase-25 suite — computed-style fade assertions) + `tests/e2e/test_background_animation.py` (the phase-22 E2E repurposed as the phase-25 no-motion regression — same story, `background-no-motion.md` — its fade assertions directly contradicted by the new contract), `tests/e2e/test_dark_tech_theme.py` (palette assertions — must stay green UNCHANGED), `frontend/assets/themes/` (configurable theme files — the built-in palette is the scope; verify they carry no glow rules).
|
||||
|
||||
## Objective
|
||||
Delete the animated background: the three opacity-fading glow pseudo-layers and their keyframes stop existing — the owner reports they are too resource-intensive (the infinite CSS animations run continuously on every page, in every tab). The background becomes fully static: the 44px grid texture stays (it is static — zero animation cost).
|
||||
|
||||
## Owner decisions (chat, 2026-09-06 — recorded per AGENTS.md rule 3)
|
||||
- **A2 confirmed:** "the animated css background" = the three fading glow spots (the ONLY animated part of the background). The static grid (`body::before`) STAYS. If the owner later wants the grid gone too, that is a one-line follow-up — out of scope here.
|
||||
- Other UI animations (the mobile nav slide, modal fades, typing dots, …) are NOT the background — they stay untouched.
|
||||
|
||||
## Design (shared by both tasks)
|
||||
- `body::before` (the grid) stays BYTE-IDENTICAL: 44px cells, 1px lines at 60% `--line` alpha, the widened radial mask.
|
||||
- Deleted from `styles.css`: the `body::after`, `html::before`, and `html::after` glow rules; the three `@keyframes bg-glow-*` blocks; the `prefers-reduced-motion` rule whose only job was stilling these background layers — FIRST verify it references nothing else (if any non-background selector sits in it, strip only the background selectors).
|
||||
- The block's comment header (the phase-08/25 owner-direction prose) is replaced with a 3–4 line phase-78 note: the animated layers were removed at owner direction (TODO.md L4) as too resource-intensive; the static grid remains.
|
||||
- **Test rewrites (the house pattern — the premise changed, so the suites pin the NEW contract; the phase-76 precedent rewrote the phase-20 suite the same way):**
|
||||
- `tests/unit/test_background_no_motion.py` → rewritten as the static-contract source pin: no `@keyframes bg-glow-*` in `styles.css`; none of the four pseudo-element selectors (`body::before/after`, `html::before/after`) carries an `animation:` declaration; `body::before` (the grid) is present with its 44px `background-size` and no animation.
|
||||
- `tests/unit/test_background_animation.py` → **DELETED** (the phase-25 unit source-pin suite — its entire premise, three fading glows / exactly three `bg-glow-*` keyframe blocks, is gone; superseded chain 08 → 25 → 78).
|
||||
- `tests/e2e/test_background_no_motion.py` → rewritten: Playwright computed-style checks — the three glow pseudo-elements report `animation-name: none` and no background-image; `body::before` still carries the grid background. Docstring updated to the phase-78 contract.
|
||||
- `tests/e2e/test_background_animation.py` → **DELETED** (the phase-22 E2E repurposed as the phase-25 regression — its premise, that the glow layers fade, is removed; its story (`background-no-motion.md`) is carried on by the rewritten `test_background_no_motion.py`, the single story suite going forward).
|
||||
- `tests/e2e/test_dark_tech_theme.py` must stay green UNCHANGED — the PALETTE is untouched; only the light spots go.
|
||||
- `tests/unit/test_themes.py` + `frontend/assets/themes/indigo.css` — verify no glow/keyframe carry-over; if a theme file re-introduces animated background layers, the owner's direction applies to the whole background (report before deviating — the built-in palette is the confirmed scope).
|
||||
|
||||
## Dependencies
|
||||
— (none)
|
||||
|
||||
## Tasks
|
||||
1. `01_remove_glow_layers.md` — the CSS deletion + the four test-file rewrites/deletions.
|
||||
2. `02_regression_sweep_commit.md` — theme + smoke E2E, the visual check, the full gate, the atomic commit.
|
||||
|
||||
## Testing & Quality
|
||||
- Unit: the rewritten source-pin file + `tests/unit/test_themes.py` green.
|
||||
- E2E: the rewritten static-background suite in isolation (DB up) + `test_dark_tech_theme.py` + `test_smoke.py` unchanged-green.
|
||||
- Coverage: **>90%** on `app/` (CSS-only phase — the floor is preserved).
|
||||
|
||||
## Completion Criteria
|
||||
- [ ] No `animation` / `@keyframes` remains for the background in `styles.css` (`rg "bg-glow" frontend/ tests/ app/` → zero hits); the grid renders as before (visual check in a real browser).
|
||||
- [ ] The rewritten suites are green; the deleted suites are gone; `test_dark_tech_theme.py` green UNCHANGED.
|
||||
- [ ] `uv run pytest` green; `uv run pytest --cov=app --cov-report=term-missing` >90%; `uv run ruff check . && uv run pyright` clean.
|
||||
- [ ] One atomic `--no-gpg-sign` Conventional-Commits commit (e.g. `perf(ui): remove the animated background glow layers — static grid only`); phase dir moved to `.agents/phases/complete/`.
|
||||
@@ -0,0 +1,25 @@
|
||||
# Task 01 — Delete the glow layers + keyframes; re-pin the background contract
|
||||
|
||||
**Phase:** `78_static_background` · **Source:** `TODO.md:4` — "Remove the animated css background, it's too resource intensive"
|
||||
**Story:** n/a (TODO-derived)
|
||||
|
||||
## Objective
|
||||
The animated background no longer exists: the three glow pseudo-layers, their keyframes, and their reduced-motion rule are deleted from `styles.css`, and the unit/e2e background suites are rewritten to pin the new static contract (or deleted where the premise is gone).
|
||||
|
||||
## Work
|
||||
1. `frontend/assets/styles.css` — delete the three glow rules (`body::after`, `html::before`, `html::after`), the `@keyframes bg-glow-a` / `bg-glow-b` / `bg-glow-c` blocks, and the `prefers-reduced-motion` block that stills the background — the file carries EIGHT `@media (prefers-reduced-motion: reduce)` blocks; delete the ONE that contains only `body::before, body::after, html::before, html::after { animation: none; }` (~line 1353) whole, and leave the other seven (typing dots, spinner, toasts, nav slide, etc. — unrelated UI) untouched. Keep the `body::before` grid rule byte-identical (44px cells, the 60% `--line` alpha gradients, the radial mask). Replace the large phase-08/25 comment header with a 3–4 line phase-78 note: owner direction (TODO.md L4) — the animated background was removed as too resource-intensive; the static grid remains.
|
||||
2. `tests/unit/test_background_no_motion.py` — rewrite to the static contract (source-level, house pattern): `styles.css` contains no `@keyframes bg-glow-*`; none of `body::before` / `body::after` / `html::before` / `html::after` carries an `animation:` declaration (assert the three glow selectors are ABSENT or animation-free — they will be absent); `body::before` is present with `background-size: 44px 44px` and no animation. Update the docstring to the phase-78 contract.
|
||||
3. DELETE `tests/unit/test_background_animation.py` (the phase-25 unit source-pin suite — its premise, exactly three fading glows with named keyframe cycles, is removed; superseded chain 08 → 25 → 78).
|
||||
4. `tests/e2e/test_background_no_motion.py` — rewrite: Playwright computed-style checks on a loaded page — `body::before` still carries the grid (background-image non-empty, animation-name `none`); `body::after`, `html::before`, `html::after` report no background-image and `animation-name: none` (or the pseudo-element has no box). Update the docstring.
|
||||
5. DELETE `tests/e2e/test_background_animation.py` (the phase-22 E2E repurposed as the phase-25 no-motion regression — its fade assertions contradict the new contract; the story `background-no-motion.md` is carried on by the rewritten `test_background_no_motion.py`).
|
||||
6. Verify nothing else references the removed names: `rg "bg-glow" app/ frontend/ tests/` → zero hits; `tests/unit/test_themes.py` and `frontend/assets/themes/*.css` do not re-introduce glow/animated-background rules (grep for `bg-glow` / `@keyframes` on background selectors — report before deviating if a theme file carries them).
|
||||
|
||||
## Testing & Quality
|
||||
- Unit: the rewritten pin file (item 2) + `tests/unit/test_themes.py` green.
|
||||
- E2E: the rewritten suite (item 4) in isolation (DB up): `uv run pytest tests/e2e/test_background_no_motion.py -v --no-cov`.
|
||||
- Coverage: n/a (CSS only) — the `app/` floor preserved.
|
||||
|
||||
## Completion Criteria
|
||||
- [ ] `rg "bg-glow" frontend/ tests/ app/` → no hits; the three glow rules + keyframes are gone from `styles.css`; the grid rule is untouched.
|
||||
- [ ] Rewritten unit + e2e suites green; the two animation suites deleted; `tests/e2e/test_dark_tech_theme.py` green UNCHANGED.
|
||||
- [ ] `uv run ruff check . && uv run pyright` clean — the gate runs after this task.
|
||||
@@ -0,0 +1,20 @@
|
||||
# Task 02 — Regression sweep + the commit
|
||||
|
||||
**Phase:** `78_static_background` · **Source:** `TODO.md:4` — "Remove the animated css background, it's too resource intensive"
|
||||
**Story:** n/a (TODO-derived)
|
||||
|
||||
## Objective
|
||||
Prove the deletion regressed nothing (palette, theme, smoke, full pipeline) and land the atomic commit.
|
||||
|
||||
## Work
|
||||
1. E2E (DB up, each in isolation): `uv run pytest tests/e2e/test_background_no_motion.py -v --no-cov`, then `uv run pytest tests/e2e/test_dark_tech_theme.py -v --no-cov` (UNCHANGED file — if it breaks, the deletion touched the palette; fix the deletion, not the test), then `uv run pytest tests/e2e/test_smoke.py -v --no-cov`.
|
||||
2. Visual check in a real browser (real server, not the mock): the page background is the static grid over the flat `--bg` canvas — no pulsing light spots at the top-left / bottom-right / bottom-left corners; a `prefers-reduced-motion` browser profile sees the same static page; the theme CSS (indigo) still applies cleanly if set.
|
||||
3. Full gate: `uv run pytest --cov=app --cov-report=term-missing` (>90% on `app/`), `uv run ruff check . && uv run pyright`.
|
||||
4. ONE atomic `--no-gpg-sign` Conventional-Commits commit — e.g. `perf(ui): remove the animated background glow layers — static grid only` — body cites TODO.md L4 + the resource-intensity reason + the confirmed scope (glow spots gone, static grid stays). Move the phase dir to `.agents/phases/complete/`.
|
||||
|
||||
## Testing & Quality
|
||||
- The full suite IS the test; coverage **>90%** on `app/`.
|
||||
|
||||
## Completion Criteria
|
||||
- [ ] Items 1–3 all green.
|
||||
- [ ] Committed; phase dir in `.agents/phases/complete/`.
|
||||
Reference in New Issue
Block a user