Files
brain-of-reese/.agent/phases/complete/29_tuning_nav_link/00_phase.md
T

4.4 KiB
Raw Blame History

Phase 29 — Global Tuning nav link

Source: .agent/phases/complete/27_global_tuning — the /tuning.html page and its create/edit/delete machinery shipped, but the "Tuning" header link that was supposed to expose the page (27 task 04: *"Expose the tuning page via an admin-only header link") only exists on tuning.htmlitself. It is not present on the Chat or Sources pages, so there is no way to reach/tuning.htmlfrom anywhere except typing the URL. **Story:**.agent/user_stories/global-tuning.md**Context:** The shared header (phase 19) renders[Chat, Sources — admin only]in

on the Chat and Sources pages.frontend/assets/header.jsalready contains logic to reveal an admin-only#nav-tuninglink for admins (lines 69–70) — but that element is never inindex.html/sources.html` markup, so the reveal is a no-op. This phase adds the missing markup so the link the JS already handles actually exists.

Objective

Make the Global Tuning page reachable by adding the admin-only "Tuning" nav link to the shared headers of the Chat (index.html) and Sources (sources.html) pages — hidden by default, revealed for admins by the existing header.js whoami gate (the exact same pattern as the Sources link). No backend, schema, or API change.

Dependencies

  • 19_shared_header (complete) — the <nav class="app-nav"> contract, the shared header markup/ids, and the 64px header-height rule on the Chat and Sources pages.
  • 16_admin_auth (complete) — the /api/whoami gate + header.js fetchIsAdmin() that reveals admin-only nav links.
  • 27_global_tuning (complete) — the /tuning.html page and PUT/POST/DELETE /api/steering endpoints that this link points to.

Tasks

  1. 01_tuning_links_markup.md — add the admin-only #nav-tuning link to the Chat (index.html) and Sources (sources.html) headers, hidden by default.
  2. 02_tuning_nav_e2e_and_regression.md — add the story E2E suite (test_tuning_nav_link.py) + verify no regressions in the header/shared-header/no-CDN suites and commit.

Testing & Quality

  • Unit/integration: no new backend logic (frontend-only markup). The existing no-CDN integration test (tests/integration/test_api.py::test_index_html_served_locally) must still pass — the new link is same-origin <a>, no new tags.
  • Coverage: frontend-only; the app/ >90% gate is unaffected (unchanged).
  • E2E (mandatory, A16): tests/e2e/test_tuning_nav_link.py — the story gate, run in isolation.

Completion Criteria

  • On the Chat page (/), a signed-in admin sees a "Tuning" link (next to Chat/Sources) that navigates to /tuning.html; an anonymous visitor does not see it (ships hidden, header.js reveals only for admin).
  • Same on the Sources page (/sources.html).
  • The link is absent from the anonymous DOM-reveal (verified via test_anonymous behavior); header markup stays valid and semantic.
  • uv run pytest green; uv run pytest --cov=app --cov-report=term-missing TOTAL unchanged (no backend change).
  • Existing header suites stay green in isolation: test_header_consistency.py (64px height + nav structure unchanged), test_shared_header.py, test_smoke.py, test_global_tuning.py.
  • uv run pytest tests/e2e/test_tuning_nav_link.py -v --no-cov green in isolation.
  • uv run ruff check . && uv run pyright clean (no Python change, but run the gate).
  • UI Structure Check (AGENTS.md rule 5): the link is a labeled, focus-visible <a>; header landmarks/contrast unchanged; no CDN.
  • One --no-gpg-sign commit staging only this phase's files; .agent/phases/todo/29_tuning_nav_link/ moved to .agent/phases/complete/.

Locked decisions

  • A11 untouched — vanilla HTML/CSS/JS, no CDN, no new packages; the link is a same-origin <a href="/tuning.html">.
  • A10 untouched — no new endpoint or auth surface; the link reuses the existing #nav-sources reveal path (header.js already gates #nav-tuning on fetchIsAdmin()).
  • No schema / migration — purely a markup addition.
  • A16 / A17 honoured — one new story E2E suite + one atomic --no-gpg-sign commit.
  • Scope boundary — only the Chat and Sources pages (the two that share the standard app-nav with the Sources link). The viewer page (document.html) uses a different .doc-header-actions header variant and the login page is the auth gate; both stay out of scope for this fix.