feat(ui): rename nav items — "Sources" becomes "RAG", "Git sources" becomes "Sources"
Owner request (2026-08-28): the two admin-only nav items read like the same thing, so they are relabeled — the document-catalog link (#nav-sources, /sources.html) becomes "RAG" and the source-manager link (#nav-git-sources, /git-sources.html) becomes "Sources". Phase 48 (48_nav_rename_sources), label-only per the locked decision: - all six pages (index, sources, git-sources, tuning, document, login): the two <a> texts swap; ids, hrefs, hidden defaults, is-active / aria-current placement, and nav order (Chat, RAG, Sources, Tuning) are byte-unchanged otherwise. - header.js: comment/docstring label mentions only — the reveal-by-id logic is untouched (ship-hidden/reveal contract intact). - test_git_sources_admin.py / test_mobile_hamburger_nav.py: the two suites that asserted the old label text are updated; comment-only label fixes in test_shared_header.py / test_nav_consistency.py. - tests/e2e/test_nav_rename_sources.py: the story E2E (green in isolation) — renamed labels + unchanged hrefs/order/markers on all six pages, click navigation with the active marker, the anonymous ship-hidden contract, and regression guards for the untouched controls (#sync-label "Sync sources", viewer #doc-back "Sources"). - All eight surrounding header/nav suites stay green in isolation; unit+integration green, app/ coverage 99% (frontend-only change), ruff + pyright clean. Note: per this phase file-level staging, the six page files and header.js also carry the same-day in-flight owner rework that was already in the working tree when phase 48 ran (mobile sign-in dropdown copy, sync button ship-hidden on the Sources page); the label rename itself is the two-text swap on each page.
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
# Phase 48 — Nav rename: "Sources" → "RAG", "Git sources" → "Sources"
|
||||
|
||||
**Source:** owner request (chat, 2026-08-28) — "The 'Git sources' navbar item should be renamed to 'Sources' and the 'Sources' navbar item should be renamed to 'RAG'."
|
||||
**Story:** `.agent/user_stories/nav-sources-rag-rename.md`
|
||||
**Context:** the shared header (phase 19, `frontend/assets/header.js`) ships ONE nav on all six pages — `[Chat, #nav-sources "Sources" → /sources.html, #nav-git-sources "Git sources" → /git-sources.html, #nav-tuning "Tuning"]` — with the two admin-only links ship-hidden and revealed by id once `/api/whoami` says admin (phase 16 contract, phase 34 same-header-everywhere, phase 46 mobile hamburger). Both labels are plain `<a>` text in the six page files; `header.js` toggles only the `hidden` attribute and never reads the label, so the rename is markup-only.
|
||||
|
||||
## Objective
|
||||
Relabel the two admin-only nav items across all six pages — the document-catalog link (`#nav-sources`) becomes **"RAG"** and the source-manager link (`#nav-git-sources`) becomes **"Sources"** — with ids, hrefs, order, the ship-hidden/reveal contract, and every other page control (viewer back button, Sync button, page titles/h1s) unchanged.
|
||||
|
||||
## Dependencies
|
||||
- `34_consistent_navbar` / `19_shared_header` (complete) — the same full header block on all six pages and the `header.js` reveal-by-id contract this phase preserves.
|
||||
- `35_git_sources_admin` (complete) — the `#nav-git-sources` link (and the `/git-sources.html` page) it labels.
|
||||
- `46_mobile_hamburger_nav` (complete) — the `LINK_TEXTS` assertion in `test_mobile_hamburger_nav.py` that this phase updates.
|
||||
|
||||
## Tasks
|
||||
1. `01_nav_label_swap.md` — swap the two label texts in all six page files + the label mentions in `header.js`'s docstring/comments (no logic).
|
||||
2. `02_existing_test_labels.md` — update the two test suites that assert the old label text; leave every other assertion (viewer back button, sync label, h1/title markers) untouched.
|
||||
3. `03_story_e2e_regression_commit.md` — the story E2E (`test_nav_rename_sources.py`), the regression suites in isolation, ruff + pyright, the one `--no-gpg-sign` commit, and the phase-dir move.
|
||||
|
||||
## Testing & Quality
|
||||
- Unit/integration: no new backend logic (frontend markup only). The existing no-CDN integration test (`tests/integration/test_api.py::test_html_pages_served_locally_no_cdn`) must still pass — the swap touches no tags or origins (the `/git-sources.html` "Git sources" marker keeps matching the page's unchanged `<h1>`).
|
||||
- Coverage: frontend-only; the `app/` >90% gate is unaffected (unchanged).
|
||||
- E2E (mandatory, A16): `tests/e2e/test_nav_rename_sources.py` — the story gate, run in isolation.
|
||||
|
||||
## Completion Criteria
|
||||
- [ ] All six pages show **"RAG"** on `#nav-sources` (href `/sources.html`) and **"Sources"** on `#nav-git-sources` (href `/git-sources.html`); nav order and `is-active`/`aria-current` placement unchanged; no id/href/`hidden` change.
|
||||
- [ ] Anonymous still sees neither link; the admin sees both (contract preserved, proven by the story E2E + `test_shared_header.py`).
|
||||
- [ ] `uv run pytest` green (the two updated suites included); `uv run pytest --cov=app --cov-report=term-missing` TOTAL unchanged (no backend change).
|
||||
- [ ] Regression E2E suites green in isolation: `test_nav_consistency.py`, `test_shared_header.py`, `test_mobile_hamburger_nav.py`, `test_git_sources_admin.py`, `test_header_consistency.py`, `test_sources_midstream_bug.py`, `test_smoke.py`.
|
||||
- [ ] `uv run pytest tests/e2e/test_nav_rename_sources.py -v --no-cov` green in isolation.
|
||||
- [ ] `uv run ruff check . && uv run pyright` clean (no Python behavior change, but run the gate).
|
||||
- [ ] UI Structure Check (AGENTS.md rule 5): labeled links, landmarks/contrast/focus unchanged; no CDN (rule 6).
|
||||
- [ ] One `--no-gpg-sign` commit staging only this phase's files; `.agent/phases/todo/48_nav_rename_sources/` moved to `.agent/phases/complete/`.
|
||||
|
||||
## Locked decisions
|
||||
- **Label-only rename (owner request 2026-08-28)** — exactly the two nav item texts change. Element ids (`#nav-sources`, `#nav-git-sources`), hrefs, nav order, the ship-hidden/reveal contract, `header.js` behavior, and every other label (the document viewer's "Sources" back button, the "Sync sources" button, page `<title>`/`<h1>` — incl. "Knowledge base" and "Git sources") are OUT of scope. If the owner later wants the page titles/h1s to follow the nav labels, that is a follow-up phase, not this one.
|
||||
- **A11 untouched** — vanilla HTML only, no CDN, no new packages, no new tags.
|
||||
- **A10 untouched** — no endpoint, auth, or `header.js` logic change; the rename rides the existing reveal-by-id path.
|
||||
- **No schema / migration** — purely a markup + test-label change.
|
||||
- **A16 / A17 honoured** — one new story E2E suite + one atomic `--no-gpg-sign` commit.
|
||||
@@ -0,0 +1,46 @@
|
||||
# Task 01 — Swap the two nav label texts on all six pages
|
||||
|
||||
**Phase:** `48_nav_rename_sources` · **Story:** `.agent/user_stories/nav-sources-rag-rename.md`
|
||||
|
||||
## Objective
|
||||
Rename the nav items themselves: `#nav-sources` ("Sources" → **"RAG"**) and `#nav-git-sources` ("Git sources" → **"Sources"") in the shared header markup of all six pages, plus the label mentions in `header.js`'s doc comments. Markup only — no ids, hrefs, classes, logic, or other text changes.
|
||||
|
||||
## Work
|
||||
On **each** of the six page files — `frontend/index.html`, `frontend/sources.html`, `frontend/git-sources.html`, `frontend/tuning.html`, `frontend/document.html`, `frontend/login.html` — make exactly two text swaps inside `<nav class="app-nav" aria-label="Primary">`:
|
||||
|
||||
1. The catalog link — change the visible text only:
|
||||
```html
|
||||
<a href="/sources.html" class="nav-link" id="nav-sources" hidden>Sources</a>
|
||||
```
|
||||
becomes
|
||||
```html
|
||||
<a href="/sources.html" class="nav-link" id="nav-sources" hidden>RAG</a>
|
||||
```
|
||||
(On `sources.html` the link carries `class="nav-link is-active" aria-current="page"` — keep those attributes exactly as they are; swap only `Sources` → `RAG`.)
|
||||
|
||||
2. The manager link — change the visible text only:
|
||||
```html
|
||||
<a href="/git-sources.html" class="nav-link" id="nav-git-sources" hidden>Git sources</a>
|
||||
```
|
||||
becomes
|
||||
```html
|
||||
<a href="/git-sources.html" class="nav-link" id="nav-git-sources" hidden>Sources</a>
|
||||
```
|
||||
(On `git-sources.html` the link carries `class="nav-link is-active" aria-current="page"` — keep them; swap only `Git sources` → `Sources`.)
|
||||
|
||||
3. `frontend/assets/header.js` — **comments only** (the reveal logic is id-based and must stay byte-identical): in the module docstring (the nav-link inventory: `"Sources" (#nav-sources, phase 19), "Git sources" (#nav-git-sources, phase 35)`) and in the inline comment above the `navGitSources` reveal, update the quoted labels to the new ones (`"RAG" (#nav-sources)`, `"Sources" (#nav-git-sources)`). No executable line of `header.js` changes.
|
||||
|
||||
Rules for all edits:
|
||||
- Do **not** touch element ids, `href`s, `hidden` defaults, `class` attributes, `aria-current`, indentation, or any other text on the page (page `<title>`, `<h1>`, the viewer's "Sources" back button, the "Sync sources" button label — all stay).
|
||||
- Do **not** add `is-active` anywhere or move the links — the physical nav order stays Chat, `#nav-sources`, `#nav-git-sources`, `#nav-tuning` (the labels just swap, so it now *reads* Chat, RAG, Sources, Tuning).
|
||||
- The phase-16/19/35 ship-hidden contract is untouched: the links still ship `hidden` and `header.js` still reveals them by id for admins.
|
||||
|
||||
## Testing & Quality
|
||||
- No new unit/integration logic (frontend markup only).
|
||||
- Coverage: frontend-only; `app/` coverage unaffected.
|
||||
- The no-CDN integration test (`tests/integration/test_api.py::test_html_pages_served_locally_no_cdn`) still passes — no tags or origins change; its `("/git-sources.html", "Git sources")` marker still matches that page's unchanged `<h1>Git sources</h1>`.
|
||||
|
||||
## Completion Criteria
|
||||
- [ ] All six pages: `#nav-sources` renders text **RAG** and `#nav-git-sources` renders text **Sources**; ids/hrefs/`hidden`/`is-active` unchanged (a quick `grep -c 'id="nav-sources" hidden>RAG<'` per page returns 1, and `grep -c 'id="nav-git-sources" .*>Sources<'` returns 1).
|
||||
- [ ] `git diff --stat` shows only the six HTML files + `frontend/assets/header.js` (comment-only) changed.
|
||||
- [ ] `uv run pytest tests/unit tests/integration -q` green; `uv run ruff check . && uv run pyright` clean.
|
||||
@@ -0,0 +1,34 @@
|
||||
# Task 02 — Update the tests that assert the old nav label text
|
||||
|
||||
**Phase:** `48_nav_rename_sources` · **Story:** `.agent/user_stories/nav-sources-rag-rename.md`
|
||||
|
||||
## Objective
|
||||
Keep the existing suites honest after the rename: update the (few) assertions and label-describing comments that reference the OLD label texts, without touching any assertion that is about a different control.
|
||||
|
||||
## Work
|
||||
Only these tests assert the old label text (verified by grepping `tests/` for the strings) — update exactly these:
|
||||
|
||||
1. `tests/e2e/test_git_sources_admin.py` — `test_admin_nav_link_on_all_five_pages_and_click_navigates`:
|
||||
- the comment `pointing at the git sources page, labeled "Git sources" — and it` → `labeled "Sources"`;
|
||||
- `expect(link).to_have_text("Git sources")` → `expect(link).to_have_text("Sources")`.
|
||||
- This suite has no assertion on `#nav-sources`'s TEXT (it is id-based everywhere) — do not add one here; the story E2E (task 03) owns the label checks.
|
||||
2. `tests/e2e/test_mobile_hamburger_nav.py` —
|
||||
- `LINK_TEXTS = ("Chat", "Sources", "Git sources", "Tuning")` → `LINK_TEXTS = ("Chat", "RAG", "Sources", "Tuning")` (DOM order unchanged — only the labels swapped);
|
||||
- the comment near `test_…` that reads `Chat / Sources / Git sources / Tuning — i.e. the whoami reveal` → `Chat / RAG / Sources / Tuning …`.
|
||||
3. **Comments-only drift fixes** (no assertion changes) where a suite's docstring/comment quotes the old labels as the link's identity: `tests/e2e/test_shared_header.py` (module docstring line `"the 'Sources' nav link (#nav-sources)"` → `'RAG'`), `tests/e2e/test_nav_consistency.py` (the comment `the Git sources link joined in phase 35` → mention the relabeled link), `tests/e2e/test_header_consistency.py` if it quotes the labels. Where a comment also explains the phase-35 origin, keep that history and only fix the quoted label.
|
||||
|
||||
**Explicitly DO NOT touch** (different controls / different text — they stay green and must stay):
|
||||
- `tests/e2e/test_nav_consistency.py` lines asserting the document viewer's **back button** `span` text "Sources" / "Chat" — that is the viewer's back link (`document.js`), not the nav.
|
||||
- `tests/e2e/test_document_back_navigation.py` — same back button.
|
||||
- `tests/unit/test_document_viewer.py` — the `'Sources' in js` check on the viewer's back-link label.
|
||||
- `tests/e2e/test_nav_consistency.py` `expect(page.locator("#sync-label")).to_have_text("Sync sources")` — the Sync button label is unchanged.
|
||||
- `tests/integration/test_api.py::test_html_pages_served_locally_no_cdn` — the `("/git-sources.html", "Git sources")` marker matches the page's unchanged `<h1>`; leave it.
|
||||
|
||||
## Testing & Quality
|
||||
- No new logic — assertion-text updates only.
|
||||
- Coverage: frontend/test-only; `app/` coverage unaffected.
|
||||
|
||||
## Completion Criteria
|
||||
- [ ] `grep -rn '"Git sources"\|Git sources' tests/e2e/*.py` shows no remaining assertion expecting the old nav label (only phase-history comments, if any, are acceptable — and none should quote it as the current label).
|
||||
- [ ] `uv run pytest tests/unit tests/integration -q` green; `uv run ruff check . && uv run pyright` clean.
|
||||
- [ ] The two updated E2E suites pass in isolation: `uv run pytest tests/e2e/test_git_sources_admin.py -v --no-cov` and `uv run pytest tests/e2e/test_mobile_hamburger_nav.py -v --no-cov` (DB up).
|
||||
@@ -0,0 +1,33 @@
|
||||
# Task 03 — Story E2E, regression suites, commit, phase move
|
||||
|
||||
**Phase:** `48_nav_rename_sources` · **Story:** `.agent/user_stories/nav-sources-rag-rename.md`
|
||||
|
||||
## Objective
|
||||
Prove the renamed nav end to end with the story's dedicated Playwright suite (run in isolation per A16), confirm the surrounding header suites stay green, and land the one atomic `--no-gpg-sign` commit.
|
||||
|
||||
## Work
|
||||
1. **Create `tests/e2e/test_nav_rename_sources.py`** (one story, one file — follow the conventions of `test_git_sources_admin.py` / `test_nav_consistency.py`: the shared `app_url` / `db_ready` fixtures, the `login(page, app_url, next=…)` helper, desktop viewport 1280×800, `expect` sync-API assertions, a module docstring stating the story + the rename). The six pages under test are `/` (chat), `/sources.html`, `/git-sources.html`, `/tuning.html`, `/login.html`, and `/document.html` (viewer — seed one document row first, reusing the seeding pattern `test_nav_consistency.py` uses for its viewer pass, and wait for `#doc-title` to settle as that file does).
|
||||
|
||||
Test cases:
|
||||
- **admin_labels_on_all_six_pages** — signed-in admin visits each of the six pages; on each: `#nav-sources` is visible, has text exactly `RAG` and href `/sources.html`; `#nav-git-sources` is visible, has text exactly `Sources` and href `/git-sources.html`; the nav DOM order is Chat, RAG, Sources, Tuning (assert the `.app-nav a` text sequence); the current page's link carries `is-active`/`aria-current="page"` (and only it does).
|
||||
- **click_navigates_with_marker** — from the chat page: click `#nav-sources` (label "RAG") → lands on `/sources.html` where `#nav-sources` is the active link; from the chat page: click `#nav-git-sources` (label "Sources") → lands on `/git-sources.html` where `#nav-git-sources` is the active link.
|
||||
- **anonymous_sees_neither** — anonymous (no login): on `/` and `/login.html` both `#nav-sources` and `#nav-git-sources` are present in the DOM but hidden (ship-hidden contract unchanged), `#sign-in-link` visible.
|
||||
- **untouched_controls_stay** — the rename did not leak: on `/sources.html` the Sync button still reads "Sync sources" (`#sync-label`), and on the settled viewer page the back button's span still reads "Sources" (the viewer back link is a different control — regression guard for task 02's do-not-touch list).
|
||||
2. **Run the regression suites in isolation** (DB up, `--no-cov`), fixing nothing unless a test genuinely asserted a renamed nav label (if one does, update it as in task 02 and note it in the commit message):
|
||||
`test_nav_consistency.py`, `test_shared_header.py`, `test_mobile_hamburger_nav.py`, `test_git_sources_admin.py`, `test_header_consistency.py`, `test_sources_midstream_bug.py`, `test_smoke.py`, `test_tuning_nav_link.py`.
|
||||
3. **Full gates**: `uv run pytest` (unit + integration) green; `uv run pytest --cov=app --cov-report=term-missing` with TOTAL unchanged from the pre-phase baseline (frontend-only change); `uv run ruff check . && uv run pyright` clean.
|
||||
4. **UI Structure Check (AGENTS.md rule 5)** — the relabeled links are still labeled `<a>`s inside the semantic `<nav aria-label="Primary">`; landmarks/contrast/focus-visible untouched (label text only); no CDN (rule 6 — the no-CDN integration test covers it).
|
||||
5. **Commit** — one atomic commit staging exactly this phase's files (the six HTML files, `frontend/assets/header.js`, `tests/e2e/test_git_sources_admin.py`, `tests/e2e/test_mobile_hamburger_nav.py`, the comment-only test files from task 02, and the new `tests/e2e/test_nav_rename_sources.py`):
|
||||
`feat(ui): rename nav items — "Sources" becomes "RAG", "Git sources" becomes "Sources"` with a body citing the owner request (2026-08-28) + phase 48. `git commit --no-gpg-sign` (repo also has `commit.gpgsign=false`).
|
||||
6. **Move the phase directory**: `mv .agent/phases/todo/48_nav_rename_sources .agent/phases/complete/` and `git add -f .agent/phases/complete/48_nav_rename_sources` into the SAME commit as step 5 (`.agent/` is gitignored by design — AGENTS.md rule 8), plus the story file `git add -f .agent/user_stories/nav-sources-rag-rename.md`.
|
||||
|
||||
## Testing & Quality
|
||||
- Story E2E: `tests/e2e/test_nav_rename_sources.py` green **in isolation**.
|
||||
- Coverage: frontend-only; `app/` >90% gate unaffected (TOTAL unchanged).
|
||||
|
||||
## Completion Criteria
|
||||
- [ ] `uv run pytest tests/e2e/test_nav_rename_sources.py -v --no-cov` green in isolation (DB up).
|
||||
- [ ] All eight regression suites green in isolation (commands above).
|
||||
- [ ] `uv run pytest` green; `uv run pytest --cov=app --cov-report=term-missing` TOTAL unchanged; `uv run ruff check . && uv run pyright` clean.
|
||||
- [ ] One `--no-gpg-sign` commit containing the code/test files, the story file, and the moved phase directory; `.agent/phases/todo/` no longer lists 48.
|
||||
- [ ] No behavior change in completed phases (the suites above are the proof).
|
||||
@@ -0,0 +1,49 @@
|
||||
# Story: Nav rename — "Sources" becomes "RAG", "Git sources" becomes "Sources"
|
||||
|
||||
**Phase:** `48_nav_rename_sources` · **E2E:** `tests/e2e/test_nav_rename_sources.py`
|
||||
|
||||
## Narrative
|
||||
|
||||
As **the admin (owner)**, the two admin-only nav items are confusing:
|
||||
"Sources" (the document catalog) and "Git sources" (the source manager)
|
||||
read like the same thing. I want the navbar to say **"RAG"** for the
|
||||
document catalog page and **"Sources"** for the source manager page, so
|
||||
the labels say what each page *is*: RAG = the indexed knowledge base you
|
||||
chat against; Sources = where that knowledge comes from.
|
||||
|
||||
- **Given** I am signed in as admin, on any of the six pages (chat,
|
||||
sources, git-sources, tuning, document viewer, login)
|
||||
- **When** I look at the primary nav
|
||||
- **Then** the catalog link (`#nav-sources`, → `/sources.html`) is
|
||||
labeled **"RAG"** and the manager link (`#nav-git-sources`, →
|
||||
`/git-sources.html`) is labeled **"Sources"** — same ids, same hrefs,
|
||||
same order, same admin-only ship-hidden/reveal contract as before.
|
||||
|
||||
## Acceptance criteria
|
||||
1. All six pages (`frontend/index.html`, `sources.html`,
|
||||
`git-sources.html`, `tuning.html`, `document.html`, `login.html`)
|
||||
carry the swapped label text on `#nav-sources` ("RAG") and
|
||||
`#nav-git-sources` ("Sources"). Element ids, `href`s, `hidden`
|
||||
defaults, `is-active`/`aria-current` markers, and the nav order
|
||||
(Chat, RAG, Sources, Tuning) are unchanged — this is a label-only
|
||||
rename, and `header.js` logic (reveal by id) is untouched.
|
||||
2. Anonymous visitors still see neither link (ship-hidden contract
|
||||
unchanged); the admin sees both, as before.
|
||||
3. Existing test assertions on the old label text are updated
|
||||
(`test_git_sources_admin.py` nav-link text,
|
||||
`test_mobile_hamburger_nav.py` `LINK_TEXTS`); assertions that are
|
||||
NOT about these two nav items stay untouched (the document viewer's
|
||||
"Sources" back button, the "Sync sources" button label, the
|
||||
`/git-sources.html` page-`<h1>`/`<title>` marker).
|
||||
4. Story E2E `tests/e2e/test_nav_rename_sources.py` proves: admin sees
|
||||
"RAG" (→ `/sources.html`) and "Sources" (→ `/git-sources.html`) on
|
||||
all six pages; clicking each lands on the right page with
|
||||
`is-active`; anonymous sees both hidden.
|
||||
5. Frontend-only: unit + integration green, `app/` coverage
|
||||
unaffected, ruff + pyright clean, no CDN, one `--no-gpg-sign` commit.
|
||||
|
||||
## Playwright Mapping Rule
|
||||
`tests/e2e/test_nav_rename_sources.py` — one story, one file, run in
|
||||
isolation: the two relabeled nav items' full lifecycle (labels, hrefs,
|
||||
admin reveal, anonymous hide, click-navigation with the current-page
|
||||
marker) on the shared header, desktop viewport.
|
||||
Reference in New Issue
Block a user