phase: 99_kb_tree_table_and_back_nav
Build and Push Containers / build-and-push-app (push) Successful in 1m55s
Build and Push Containers / build-and-push-db (push) Successful in 12s

All verification is complete and green. Final report:

**Phase 99 — final verification pass (all 3 tasks already in `complete/`)**

- Verified the one-line Description clamp: `.kb-desc-cell` flex wrapper + `.kb-desc-text` ellipsis triad + `nowrap` column + in-cell Edit button + hover `title` + untouched level block (source diffs match D1; unit pins present)
- Verified the back-button breadcrumb nav: `applyTarget(target, push)` state-only `pushState`, no-duplicate gate, popstate adopt/reset, `bor:view-refresh` alignment before `loadTree()`, anonymous gate listener-free, router.js untouched (D2)
- `uv run pytest --cov=app`: **2180 passed**, coverage **99%** (>90% gate)
- `uv run ruff check .`: clean; `uv run pyright`: **0 errors, 0 warnings**
- `uv run pytest tests/e2e/test_kb_tree_nav.py -v --no-cov` (isolated, DB up): **4/4 passed** (back-walk, jump-then-back, fresh-nav/active-reclick, measured clamp incl. row-height parity ±4px, computed styles, full text in DOM/title/level block)
- Regression suites isolated: `test_kb_tree.py` 8✓, `test_ls_tree_drilldown.py` 3✓, `test_navbar_refresh.py` 7✓, plus `test_sync_summary_visibility.py` 3✓ (marker pin updated to `kb-desc-text kb-summary-pending` — the sanctioned class-pair change) and `test_edit_summaries.py` 4✓
- Criteria 1–4: **met** (each as above). Criterion 5 (atomic commit): left to the harness per executor rules — no `git add`/`commit` run; all changes left in the working tree
- No defects found in prior phases; no deviations. Stray `__pycache__/test_zz_smoke_tree_ui.*.pyc` is a leftover (no `.py` on disk) — inert, not touched
- Next pending phase: **none** — `todo/` will be empty once the harness moves this phase
This commit is contained in:
2026-09-13 01:57:40 -04:00
parent f665a83b1a
commit 8476dc1e07
22 changed files with 1755 additions and 53 deletions
+18 -7
View File
@@ -548,23 +548,34 @@ def _pin_refresh_listener(js: str, gate: str, listener_call: str, name: str) ->
"""Shared shape of the task-02 pin: the view module listens for
``bor:view-refresh`` on its own root, the listener re-runs the
view's existing load, and the listener is armed ONLY in the ADMIN
branch — after the whoami gate (anonymous never fetches)."""
branch — after the whoami gate (anonymous never fetches). The
body is sliced to the listener's close: the block-arrow forms
(phase 99 task 02: the rag view's history-alignment step runs
before the load) close with ``});``, the inline-arrow forms close
with ``());`` (the slice then runs to the NEXT ``});`` in the file
— or to its end — harmless, the inline call sits at the slice's
start)."""
listener = js.find('addEventListener("bor:view-refresh"')
assert listener != -1, f"{name} must listen for the refresh event on the view root"
gate_i = js.find(gate)
assert 0 <= gate_i < listener, (
f"{name}: the listener must be armed in the ADMIN branch (after {gate!r})"
)
assert listener_call in js[listener : listener + 120], (
end = js.find("});", listener)
body = js[listener:] if end == -1 else js[listener : end + 3]
assert listener_call in body, (
f"{name}: the listener must re-run the view's load ({listener_call!r})"
)
def test_rag_view_refetches_on_reshow() -> None:
"""Phase 77 task 02 (+ phase 97 task 04): the RAG (knowledge base)
view re-fetches on a user-initiated re-show — sources.js listens
and re-runs ``loadTree()`` (the phase-97 catalog load: ONE fetch of
``GET /api/docs/tree``). The load is race-tokened (phase 79) and
"""Phase 77 task 02 (+ phase 97 task 04, + phase 99 task 02):
the RAG (knowledge base) view re-fetches on a user-initiated
re-show — sources.js listens and re-runs ``loadTree()`` (the
phase-97 catalog load: ONE fetch of ``GET /api/docs/tree``), now
AFTER the phase-99 history alignment (adopt the entry's kb / reset
to the top — a block-arrow listener, hence the ``});`` close in
the pin helper below). The load is race-tokened (phase 79) and
the RE-ENTRANT render — ``renderLevel`` clears BOTH row containers
at the TOP before filling them (the History pattern from task 01,
extended to the folders table) — so a refresh from a populated
@@ -572,7 +583,7 @@ def test_rag_view_refetches_on_reshow() -> None:
of leaving ghost rows."""
js = _asset("sources.js")
_pin_refresh_listener(
js, "const admin = await fetchIsAdmin();", "() => loadTree()", "sources.js"
js, "const admin = await fetchIsAdmin();", "loadTree()", "sources.js"
)
load = js.find("async function loadTree()")
assert load != -1, "loadTree must exist"
+326 -20
View File
@@ -357,16 +357,40 @@ def test_breadcrumb_links_go_up_and_the_top_reset() -> None:
assert "span.textContent = label" in cur
def test_navigation_is_client_side_only() -> None:
"""goTo() is the ONLY navigation: set `current`, re-render. No
fetch (the tree is already in memory), no URL change (history is
untouched — the deep-link contract of the shell is unchanged)."""
def test_drill_navigation_pushes_state_only_entries() -> None:
"""Phase 99 (task 02, D2): every user-initiated drill is a history
entry — ``goTo`` is the push variant of ``applyTarget``: when the
target DIFFERS from the current level (a re-click of the current
row/segment pushes NO duplicate entry), it FIRST records a
STATE-ONLY entry — ``history.pushState({ view: "rag", kb: target },
"")`` — the second arg is ``""`` and there is no third (the URL
stays the shell's pathname: no new route, the phase-76 deep-link
surface is untouched) — then sets ``current`` + re-renders. The
drill still never fetches (the tree is in memory) and the module
never ``replaceState``s."""
js = _js()
body = js[js.find("function goTo(") : js.find("function makeSourceRow(")]
assert "current = { source: target.source, folder: target.folder };" in body
assert "renderLevel();" in body
start = js.find("function applyTarget(")
assert start != -1, "applyTarget must exist (the two-step drill)"
body = js[start : js.find("function makeSourceRow(")]
gate_i = body.find(
"if (push && (target.source !== current.source || target.folder !== current.folder)) {"
)
push_i = body.find('history.pushState({ view: "rag", kb: target }, "")')
set_i = body.find("current = { source: target.source, folder: target.folder };")
render_i = body.find("renderLevel();")
assert -1 < gate_i < push_i < set_i < render_i, (
"push gate (target differs from current) → pushState → set current → render"
)
# STATE-ONLY: exactly ONE pushState call site — the "" second arg,
# no third (no URL change).
assert _code(body).count("pushState") == 1, (
"ONE pushState call site — the state-only drill entry"
)
assert "replaceState" not in _code(js), "no replaceState anywhere in the module"
# goTo is the push variant — every drill call site keeps calling it.
go = body[body.find("function goTo(") :]
assert "applyTarget(target, true)" in go, "goTo pushes (the user-initiated drill)"
assert "fetch(" not in body, "the drill never fetches (client-side only)"
assert "pushState" not in body and "replaceState" not in body, "no URL change"
# ---------- the level rendering ----------
@@ -577,16 +601,30 @@ def test_load_tree_wired_at_exactly_the_three_refresh_points_plus_boot() -> None
assert _code(js).count("loadTree()") == 5, (
"the definition + the 4 call sites, no others (code, not comments)"
)
# 1. the view-refresh listener, armed in the admin branch.
# 1. the view-refresh listener, armed in the admin branch — since
# Phase 99 (task 02, D2) its body is the ALIGNMENT step (a
# kb-carrying history.state entry keeps the drill — the
# active-link re-click; a kb-less entry starts at the top — a
# fresh nav visit) BEFORE the re-fetch.
listener = js.find('addEventListener("bor:view-refresh"')
assert listener != -1
gate = js.find("const admin = await fetchIsAdmin();")
assert -1 < gate < listener, "armed after the whoami gate (the phase-77 pin)"
assert "() => loadTree()" in js[listener : listener + 120]
listener_body = js[listener : js.find('window.addEventListener("popstate"')]
state_i = listener_body.find("history.state && history.state.kb")
adopt_i = listener_body.find("applyTarget(kb, false)")
reset_i = listener_body.find("applyTarget({ source: null, folder: null }, false)")
load_i = listener_body.find("loadTree();")
assert -1 < state_i < adopt_i < reset_i < load_i, (
"align with history.state (adopt kb / reset to top) BEFORE the re-fetch"
)
assert "pushState" not in _code(listener_body), ("the alignment adopts only — no push")
# 2. the boot load — the last statement of mount, right after the
# listener is armed (the mount's own load is the first fetch).
assert 'root.addEventListener("bor:view-refresh", () => loadTree());\n loadTree();' in js, (
"the boot load follows the listener"
# listeners are armed (the mount's own load is the first fetch).
pop = js.find('window.addEventListener("popstate"')
boot = js[js.find("});", pop) + 3 :] # past the popstate listener's close
assert boot.strip().startswith("loadTree();"), (
"the boot load follows the listeners (no pushState on boot)"
)
# 3. applySyncSuccess (the sync's terminal — the KB just changed).
success = js[js.find("function applySyncSuccess(") : js.find("function applySyncFailure(")]
@@ -746,13 +784,16 @@ def test_row_description_cell_builds_text_and_always_present_edit() -> None:
the text gates on the node state, the button never does). The
button is a real type=button with a human aria-label, and the
shared editor is wired with a CONSTANT target { node, source,
folder }."""
folder }. Phase 99 (task 01, D1): text + button live in ONE
`div.kb-desc-cell` flex wrapper (the <td> holds only the wrapper),
and the editor's container IS the wrapper (the open/close swaps
fill it — the cell layout survives the editor swap)."""
body = _fn(_js(), "makeDescCell")
# The Edit button is built unconditionally — the whole button
# block (from its creation to the append) carries no `if` gate on
# the stored description or the pending flag.
btn_block = body[
body.find("const btn = document.createElement") : body.find("td.append(text, btn)")
body.find("const btn = document.createElement") : body.find("wrap.append(text, btn)")
]
assert "if (" not in btn_block, (
"always present: no gate on the stored description"
@@ -761,10 +802,20 @@ def test_row_description_cell_builds_text_and_always_present_edit() -> None:
assert 'btn.className = "kb-summary-edit"' in body
assert 'btn.textContent = "Edit"' in body
assert 'btn.setAttribute("aria-label", `Edit description: ${label}`)' in body
assert "td.append(text, btn)" in body
assert 'wrap.className = "kb-desc-cell"' in body, "the ONE flex wrapper"
assert "wrap.append(text, btn)" in body, "text + button, in order, in the wrapper"
assert "td.append(wrap)" in body, "the <td> holds the wrapper (no new td class)"
assert "container: wrap" in body, (
"the editor's container is the WRAPPER (Phase 99 — the swap fills it)"
)
assert "getTarget: () => ({ node, source, folder })" in body, (
"a row's target is a constant (its own node)"
)
# The level block's editor is UNTOUCHED — its container is still
# .kb-level-body (the D1 escape hatch keeps its full text).
js = _js()
wire = js[js.find("levelEditor = wireDescriptionEdit({") : js.find("/* ---------- view boot")]
assert "container: levelBody" in wire
def test_desc_cell_pending_marker_branch() -> None:
@@ -786,7 +837,12 @@ def test_desc_cell_pending_marker_branch() -> None:
assert "kb-summary-pending" not in stored, "a stored summary is NEVER the marker"
assert "Summary pending" not in stored
pending = body[pending_i:empty_i]
assert 'text.className = "kb-summary-pending"' in pending
assert 'text.classList.add("kb-summary-pending")' in pending, (
"Phase 99: the marker TOGGLES onto the .kb-desc-text base class"
)
assert 'text.className = "kb-summary-pending"' not in body, (
"a bare className re-assignment would drop the clamp's base class"
)
assert 'text.textContent = "Summary pending"' in pending, "the D4 marker copy"
assert (
'text.title = "No stored description yet — the next sync will generate one."'
@@ -841,13 +897,23 @@ def test_close_editor_rederives_the_pending_display() -> None:
close = body[body.find("function closeEditor(") : body.find("function openEditor()")]
flag_i = close.find('const pending = node !== null && stored === "" && node.summary_pending;')
value_i = close.find("const value = pending && pendingText ? pendingText : stored;")
class_i = close.find('textEl.className = pending ? "kb-summary-pending" : "";')
class_i = close.find('textEl.classList.toggle("kb-summary-pending", pending);')
title_i = close.find("if (pendingTitle) textEl.title = pendingTitle;")
hover_i = close.find('} else if (stored && textEl.classList.contains("kb-desc-text")) {')
full_i = close.find("textEl.title = stored;")
clear_title_i = close.find('textEl.removeAttribute("title")')
render_i = close.find("textEl.textContent = value")
assert -1 < flag_i < value_i < class_i < title_i < clear_title_i < render_i, (
"flag → value → class → title (set/clear) → text, in order"
assert -1 < flag_i < value_i < class_i < title_i < hover_i < full_i, (
"flag → value → class toggle → title (pending / hover-full), in order"
)
assert full_i < clear_title_i < render_i, "title-set → title-clear → text, in order"
# Phase 99 (task 01): the class line is a TOGGLE (the base classes
# survive — the row's span keeps .kb-desc-text, the clamp; the
# level's <p> keeps none), and the CLAMPED row span's title is
# re-derived from the stored text (the D1 hover escape hatch — a
# stale pre-edit title cannot survive a save; the unclamped
# level's <p> is gated out by the kb-desc-text check).
assert 'textEl.className' not in close, "no bare className re-assignment"
# The row passes its marker copy + the EXACT D4 tooltip…
cell = _fn(_js(), "makeDescCell")
assert 'pendingText: "Summary pending"' in cell
@@ -1212,3 +1278,243 @@ def test_module_docstring_documents_the_pending_markers() -> None:
in header
), "the level block's pending note"
assert "node.summary_pending = false" in header, "the in-place clear"
# ---------- the one-line Description clamp (phase 99, task 01) ----------
# D1: the clamp is VISUAL only — the row's Description cell is ONE flex
# row (text flexes + ellipsizes, the Edit button stays fixed), the full
# text stays in the DOM + on the span's hover title, and the level
# block keeps the full unclamped description. The measured-height proof
# lands in the phase's E2E (task 03); this module pins the structure
# and the CSS.
def _css_rule(css_text: str, selector: str) -> str:
"""The declarations of the rule with exactly this selector (the
task-named classes own their base rule — no compound matches)."""
m = re.search(r"(?<![\w-])" + re.escape(selector) + r"\s*\{([^}]*)\}", css_text)
assert m, f"styles.css must define {selector}"
return m.group(1)
def test_desc_cell_hover_title_covers_real_description_text_only() -> None:
"""Phase 99 (task 01, D1): the text span (`.kb-desc-text` — the
base class, set UNCONDITIONALLY before the three-state branch) AL-
WAYS carries `title` = the FULL description text for real
(non-empty) stored text — the hover escape hatch of the visual
clamp; the phase-98 marker keeps its OWN D4 title (never over-
ridden by the hover rule); the empty cell carries no title at all.
textContent/title only — the house rule (no innerHTML)."""
body = _fn(_js(), "makeDescCell")
base_i = body.find('text.className = "kb-desc-text"')
stored_i = body.find("if (node && node.summary) {")
pending_i = body.find("else if (node && node.summary_pending) {")
empty_i = body.find("} else {")
assert -1 < base_i < stored_i, "the base clamp class is set before the state branch"
stored = body[stored_i:pending_i]
assert "text.title = node.summary;" in stored, "stored → title = the full text (hover)"
assert "Summary pending" not in stored, "the stored branch never touches the marker"
pending = body[pending_i:empty_i]
assert (
'text.title = "No stored description yet — the next sync will generate one."'
in pending
), "the marker keeps its OWN D4 title"
empty = body[empty_i : empty_i + 200]
assert "text.title" not in empty, "the empty cell carries no title"
code = re.sub(r"//.*?$|/\*.*?\*/", "", body, flags=re.S | re.M)
assert "innerHTML" not in code, "the house rule: no innerHTML in the cell builder"
def test_close_editor_rederives_the_hover_title_from_the_stored_text() -> None:
"""Phase 99 (task 01, D1): the hover title is the escape hatch for
the CLAMPED text, so a Save/Cancel must re-derive it — a stale
pre-edit title cannot survive a save (the span is re-inserted
into the wrapper by the swap, attributes included). The re-
derivation is gated on the kb-desc-text class: only the clamped
row span gets the full-text title; the unclamped level's <p>
(full text visible) keeps its no-title behavior, and an emptied
(cleared) cell loses its title."""
body = _fn(_js(), "wireDescriptionEdit")
close = body[body.find("function closeEditor(") : body.find("function openEditor()")]
gate_i = close.find('} else if (stored && textEl.classList.contains("kb-desc-text")) {')
set_i = close.find("textEl.title = stored;")
clear_i = close.find('textEl.removeAttribute("title")')
assert -1 < gate_i < set_i < clear_i, "gated set (stored + clamped span) → clear, in order"
assert close.count("textEl.title =") == 2, (
"exactly: pendingTitle (the marker's own) + stored (the hover full text) — nothing else"
)
def test_styles_carry_the_one_line_clamp() -> None:
"""Phase 99 (task 01, D1): the Description cell is one flex row —
.kb-desc-cell (flex + center + the 0.4rem gap that replaces the
button's old margin-left + min-width: 0) and .kb-desc-text (flex:
1 1 auto + min-width: 0 — the flex item may shrink — + the
ellipsis triad). The column itself is white-space: nowrap (was
normal — the column width is the clamp's budget; the min/max width
+ font-size stay). The button's margin-left rule is GONE, the
level block's margin-top rule is untouched, and the open editor
fills the flex wrapper (flex: 1 1 auto + min-width: 0). .kb-level
p is UNTOUCHED (the full unclamped description — D1), and the
phase-97 block carries no new hue (the phase-92 invariant)."""
css = _text(STYLES_CSS)
cell = _css_rule(css, ".kb-desc-cell")
for prop in ("display: flex", "align-items: center", "gap: 0.4rem", "min-width: 0"):
assert prop in cell, f".kb-desc-cell must carry {prop!r}"
text = _css_rule(css, ".kb-desc-text")
for prop in (
"flex: 1 1 auto",
"min-width: 0",
"overflow: hidden",
"text-overflow: ellipsis",
"white-space: nowrap",
):
assert prop in text, f".kb-desc-text must carry {prop!r}"
col_i = css.find(".kb-folders-table td:nth-child(3) {")
assert col_i != -1
col = css[col_i : col_i + 400]
col = col[: col.find("\n}")]
assert "white-space: nowrap" in col, "the column is one line (was: normal)"
assert "white-space: normal" not in col
for prop in ("min-width: 18rem", "max-width: 44rem", "font-size: 0.88rem"):
assert prop in col, f"the column keeps {prop!r} (the clamp's budget)"
assert ".kb-folders-table .kb-summary-edit" not in css, (
"the button's margin-left is gone — the wrapper's gap replaces it"
)
lvl_i = css.find(".kb-level-body .kb-summary-edit")
assert lvl_i != -1
assert "margin-top: 0.5rem" in css[lvl_i : lvl_i + 80], (
"the level block's spacing rule is untouched"
)
fill_i = css.find(".kb-desc-cell .kb-summary-editor")
assert fill_i != -1
fill = css[fill_i : fill_i + 80]
assert "flex: 1 1 auto" in fill and "min-width: 0" in fill, (
"the open editor fills the flex wrapper"
)
# The level block keeps the FULL unclamped description (D1) — its
# rule is unchanged (no white-space/ellipsis additions).
m = re.search(r"(?<![\w-])\.kb-level p\s*\{([^}]*)\}", css)
assert m, "the level block's <p> rule must exist"
assert "white-space" not in m.group(1) and "text-overflow" not in m.group(1)
block = _css_block(css, "KB drill-down tree (phase 97", "Git sources page (phase 35)")
assert ".kb-desc-cell" in block and ".kb-desc-text" in block, (
"the clamp lives in the phase-97 tree region"
)
assert not re.search(r"#[0-9a-fA-F]{3,8}\b", block), "no new hue (phase-92 invariant)"
assert not re.search(r"rgba?\(", block), "no new hue (phase-92 invariant)"
def test_module_docstring_documents_the_one_line_clamp() -> None:
"""The house per-phase module-note convention: the phase-99
task-01 section records the flex wrapper structure (text flexes +
ellipsizes, button fixed), the VISUAL-only clamp (full text in the
DOM + on the hover title), the marker's own title, and the wrapper
as the editor's container (the level block's container stays
.kb-level-body)."""
js = _js()
header = js[: js.find("import { fetchIsAdmin }")]
assert "Phase 99 (task 01, D1)" in header
assert "kb-desc-cell" in header and "kb-desc-text" in header
assert "VISUAL only" in header, "the clamp is documented as visual only"
assert "title" in header, "the hover escape hatch is documented"
assert "kb-level-body" in header, "the level block's container is documented as kept"
# ---------- the history integration (phase 99, task 02, D2) ----------
# The drill state IS the history state: every drill pushes a state-
# only entry (no URL change), Back/Forward adopt the entry's kb (or
# reset to the top), the re-show aligns before the re-fetch, and the
# anonymous gate installs no listeners. The browser proof lands in
# the phase's E2E (task 03); this module pins the wiring.
def test_popstate_adopts_the_entry_kb_or_resets_to_top() -> None:
"""Phase 99 (task 02, D2): the window popstate — armed exactly
ONCE, in the ADMIN branch (after the whoami gate, next to the
refresh listener) — ADOPTS the popped entry's ``event.state.kb``
via the no-push variant (the browser owns its entries —
adopt/reset never push), and an entry WITHOUT a kb (the boot
entry, the router's view entries, any foreign state) RESETS the
drill to the TOP level. Rendering a currently-hidden view is
harmless: the router's own popstate (registered earlier, at shell
boot) owns the view switch for foreign entries; rag-internal
entries never change the pathname, so this listener's render is
the visible one."""
js = _js()
assert js.count('window.addEventListener("popstate"') == 1, (
"armed exactly once (mount-once — the router mounts a view ONCE)"
)
pop = js.find('window.addEventListener("popstate"')
gate = js.find("const admin = await fetchIsAdmin();")
refresh = js.find('root.addEventListener("bor:view-refresh"')
assert -1 < gate < refresh < pop, (
"armed in the admin branch, after the gate, next to the refresh listener"
)
body = js[pop : js.find("});", pop)]
kb_i = body.find("event.state && event.state.kb")
adopt_i = body.find("applyTarget(kb, false)")
reset_i = body.find("applyTarget({ source: null, folder: null }, false)")
assert -1 < kb_i < adopt_i < reset_i, (
"read event.state.kb → adopt (no push) / reset to the top"
)
assert "pushState" not in _code(body), ("adopt/reset never push (the browser owns its entries)")
def test_refresh_alignment_adopts_history_state_before_the_refetch() -> None:
"""Phase 99 (task 02, D2): the bor:view-refresh listener (the
phase-77 re-show) aligns ``current`` with ``history.state``
BEFORE ``loadTree()`` — a kb-carrying top entry (the active-link
re-click pushed NOTHING — the drilled entry is still on top)
KEEPS the drill (``applyTarget(kb, false)``); a kb-less entry (a
fresh nav visit) RESETS to the top level. The alignment adopts —
it never pushes."""
js = _js()
listener = js.find('root.addEventListener("bor:view-refresh"')
assert listener != -1
body = js[listener : js.find("});", listener)]
state_i = body.find("history.state && history.state.kb")
adopt_i = body.find("applyTarget(kb, false)")
reset_i = body.find("applyTarget({ source: null, folder: null }, false)")
load_i = body.find("loadTree();")
assert -1 < state_i < adopt_i < reset_i < load_i, (
"align (adopt kb / reset to top) BEFORE the re-fetch"
)
assert "pushState" not in _code(body), "the alignment never pushes"
def test_anonymous_branch_installs_no_navigation_listeners() -> None:
"""Phase 99 (task 02): the anonymous gate installs NO listeners at
all — no popstate, no refresh (the phase-16 rule: anonymous shows
the gate, fetches nothing, and owns no drill state — both
listeners are armed only in the admin branch)."""
js = _js()
start = js.find("if (!admin) {")
end = js.find("if (gateEl) gateEl.hidden = true;")
assert -1 < start < end, "the anonymous branch must exist"
branch = js[start:end]
assert "addEventListener" not in branch, (
"the anonymous branch arms no listeners (no popstate, no refresh)"
)
def test_module_docstring_documents_the_history_integration() -> None:
"""The house per-phase module-note convention: the phase-99
task-02 section records the push/adopt/reset rules — the
STATE-ONLY push (the URL STAYS PUT, no new route — the phase-76
deep-link surface untouched), the duplicate-push skip, the
popstate adopt/reset, the refresh alignment before the re-fetch,
the no-boot-push contract, the UNCHANGED (no-push)
resetVanishedLocation, and the UNTOUCHED router module."""
js = _js()
header = js[: js.find("import { fetchIsAdmin }")]
assert "Phase 99 (task 02, D2)" in header
assert "STATE-ONLY" in header, "the state-only push is documented"
assert "STAYS PUT" in header, "the URL-stays-put note"
assert "no duplicate history" in header, "the duplicate-push skip"
assert "ADOPTS" in header and "popstate" in header, "the popstate adopt"
assert "RESETS the drill to the TOP level" in header, "the reset branch"
assert "BEFORE the re-fetch" in header, "the refresh alignment"
assert "Boot pushes NOTHING" in header, "no pushState on boot"
assert "resetVanishedLocation is UNCHANGED" in header
assert "module is UNTOUCHED" in header, "the router module is untouched"