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:
+37
-12
@@ -26,7 +26,13 @@
|
||||
* renders via renderDocument into #doc-title / #doc-meta /
|
||||
* #doc-content. A missing document (unknown pair, missing params,
|
||||
* network error) shows the designed not-found card with a link back
|
||||
* to the Sources page.
|
||||
* to the Sources page. Phase 79 (task 05): the content endpoint is
|
||||
* require_user-gated — a direct ANONYMOUS URL meets the inline
|
||||
* token gate instead (the page document loads; the gated data does
|
||||
* not): mountGate settles the auth (silent re-auth of a cached
|
||||
* token, then the shared cached whoami) and the boot sequence
|
||||
* (initSharedHeader + load) runs as its onAuthed — only a
|
||||
* signed-in role (admin or token user) ever fetches the content.
|
||||
*
|
||||
* XSS-safe by construction: markdown is escaped before transform, raw
|
||||
* formats are set via textContent, and every document-derived string
|
||||
@@ -63,6 +69,7 @@
|
||||
*/
|
||||
|
||||
import { fetchIsAdmin, initSharedHeader } from "./header.js";
|
||||
import { mountGate } from "./token-gate.js"; // phase 79 (task 05): the inline token gate
|
||||
|
||||
/* Phase 39: the page title's display name — window.BOR_BRAND (set at
|
||||
* parse time by the classic assets/brand.js, refreshed from
|
||||
@@ -357,16 +364,35 @@ if (document.querySelector("#doc-title")) {
|
||||
|
||||
/* Phase 19 (phase 34 task 03, owner confirmation 2026-08-26): the
|
||||
* viewer now carries the SAME standard bar as every other page —
|
||||
* nav incl. the admin-only links, Tuning toggle, Sync, New chat, the
|
||||
* auth pair — all toggled here on the module's cached whoami.
|
||||
* Independent of the doc fetch (its own IIFE — load() below never
|
||||
* waits on it).
|
||||
* (fetchIsAdmin is imported for parity with the other header
|
||||
* consumers — the module's cached promise is the single whoami per
|
||||
* page either way.) */
|
||||
(async () => {
|
||||
await initSharedHeader();
|
||||
})();
|
||||
* nav incl. the admin-only links, the auth pair — toggled on the
|
||||
* module's cached whoami (the single whoami per page; fetchIsAdmin
|
||||
* is imported for docAdminReady's parity — the same cached promise
|
||||
* either way).
|
||||
*
|
||||
* Phase 79 (task 05): the gate settles the auth FIRST — silent
|
||||
* re-auth of a cached token, then the role check (on the shared
|
||||
* cached whoami) — and the EXISTING boot sequence runs only on the
|
||||
* SETTLED role: onAuthed (the content load) for a signed-in role
|
||||
* ONLY (anonymous never fetches the content — the inline gate is
|
||||
* the surface, no not-found card for an auth failure; #main is
|
||||
* inert while the gate is visible — WCAG, the inert-pair contract),
|
||||
* and the shared header boots in the .then AFTER the gate settles
|
||||
* for EVERY role (the gate locks #main, not the header — the
|
||||
* anonymous contract is byte-identical to the shell: Sign in
|
||||
* offered, admin links ship hidden, the steering panel removed).
|
||||
* Awaiting the gate first is what makes the header race-free: a
|
||||
* silent re-auth lands before the first whoami fires, so the header
|
||||
* reads the post-auth role exactly once (no stale anonymous bar for
|
||||
* a returning token user, no second whoami). An admin (or a
|
||||
* validly cached token user) gets onAuthed immediately — the gate
|
||||
* (which ships hidden + inert) never shows. The admin-only edit
|
||||
* affordance (docAdminReady() inside renderDocument) stays
|
||||
* admin-only — it runs only in the post-auth render path. */
|
||||
mountGate(document.getElementById("main"), () => {
|
||||
load();
|
||||
}).then(() => {
|
||||
void initSharedHeader(); // every role — on the SETTLED whoami
|
||||
});
|
||||
|
||||
/* The New chat binding is module-owned (assets/header.js, phase 34
|
||||
* task 02 — the SINGLE binding): on this non-chat page it clears the
|
||||
@@ -391,5 +417,4 @@ if (document.querySelector("#doc-title")) {
|
||||
}
|
||||
}
|
||||
|
||||
load();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user