phase: 182_verbatim_show_text
**Phase 182 — final verification pass (all 8 tasks already complete; this was verification + docs + one defect fix).**
- Verified: `app/rag/verbatim.py` (locator grammar, `splitlines()` slice, line-boundary cap, `resolve_answer_blocks`), `SHOW_TEXT_TOOL` + `shown_texts`, `SHOW_TEXT_CLAUSE`, `done.answer_text` (9 fields, key dropped when empty) + `ChatMessageRecord.answer_text` (≤50, 600 000-char cap counted in the 8 M budget), `verbatim.js` + 4 `{verbatim:true}` renderers, `Containerfile` minify step, `.env.example` 3 vars.
- `uv run python -c "…answer_text, show_text_max_chars, show_text_max_blocks"` → `True 12000 5`; each negative refuses startup naming its field; `0` accepted as inert ✅
- `bash .agents/validate.sh` → **validation OK**: 4320 unit+integration tests green, `TOTAL 6849 17 → 99%` (gate app/ >90% OK), `ruff check .` "All checks passed!", `pyright` 0 errors (re-run after my edits, 08:28).
- E2E, each in isolation `--no-cov`: `test_verbatim_show_text.py` 13 passed (panel bytes == `documents.content`, server caption, clipboard == server string, `/document.html?source=…&path=…`, honest unresolved state, reload+share, `show_image` regression, flag-off app) ✅; green: `test_answer_images` `test_harness_aligned_tools` `test_agent_document_tools` `test_markdown_tables` `test_markdown_inline_links_images` `test_svg_document_preview` `test_smoke` `test_document_viewer` `test_markdown_blockquotes` `test_chat_persistence` `test_thinking_timeline` `test_chat_rag` `test_settings_mobile_value_width`.
- **Defect found & fixed (pre-existing, not phase 182):** `tests/e2e/test_admin_settings_panel.py::test_admin_sees_groups_and_source_badges` failed — its whole-page `assert "reese" not in page.content()` tripped on the shell's onboarding chips, which follow the newest saved chats in the one shared E2E DB (a leftover `reeselink.json` question from a tool suite). Scoped the strict sweep to `.settings-shell` and kept a whole-page `reese:reese` credential needle → 12 passed with the leftovers still present.
- Docs: README fixed 2 inconsistencies — Quick Start omitted the **required** `BOR_ADMIN_PASSWORD`/`BOR_SESSION_SECRET` (the app fail-loud refuses boot) and the broken anchor `#chat--` → `#chat-`; full re-read of README (1816 lines) + AGENTS confirmed the phase-182 feature/settings/log/UI-contract text matches the code, and every `.env.example` var + every `Settings` field is documented.
- Notable: kept `resolve_answer_blocks` synchronous on the SSE terminal path (bounded indexed SELECTs, matching the existing `query_log` precedent and the phase's documented fence-lookup bound); no live-infra changes made.
- Next pending phase: none — `todo/` holds only 182 (its 8 task files are in `complete/`; the harness commits + moves `00_phase.md`).
This commit is contained in:
@@ -553,7 +553,7 @@ def test_admin_sees_groups_and_source_badges(page: Page, app_url: str, db_ready:
|
||||
return el.scrollHeight > el.clientHeight;
|
||||
}"""
|
||||
)
|
||||
assert scrolls, "78 rows must overflow the bounded card (the scroll must bite)"
|
||||
assert scrolls, "the catalogue rows must overflow the bounded card (the scroll must bite)"
|
||||
|
||||
# The groups render in the server's order (the pinned display
|
||||
# groups — at least these two).
|
||||
@@ -589,7 +589,19 @@ def test_admin_sees_groups_and_source_badges(page: Page, app_url: str, db_ready:
|
||||
du = page.locator('tr[data-key="database_url"]')
|
||||
assert du.locator(".settings-control").get_attribute("type") == "password"
|
||||
assert du.locator(".settings-control").input_value() == ""
|
||||
assert "reese" not in page.content(), "the DB URL's credentials leaked into the DOM"
|
||||
# The whole page carries NO trace of the URL's credential pair, and
|
||||
# the catalogue itself carries no `reese` at all (the user, the pass
|
||||
# and the DB name are all `reese`/`brain_of_reese`). The strict
|
||||
# no-`reese` sweep is scoped to the panel on purpose: the shell also
|
||||
# ships the CHAT view, whose onboarding chips follow the newest saved
|
||||
# chats in the one shared E2E database (phase 103) — a chat left by
|
||||
# an unrelated suite (its question names `reeselink.json`) is not a
|
||||
# credentials leak, and an unscoped sweep would make this assertion
|
||||
# depend on which suite saved a chat last.
|
||||
assert "reese:reese" not in page.content(), "the DB URL leaked into the DOM"
|
||||
assert "reese" not in page.locator(".settings-shell").inner_html(), (
|
||||
"the DB URL's credentials leaked into the settings catalogue"
|
||||
)
|
||||
expect(du.locator(".settings-reset")).to_be_disabled()
|
||||
assert "read-only" in (du.locator(".settings-reset").get_attribute("title") or "")
|
||||
|
||||
@@ -984,7 +996,7 @@ def test_clear_all_overrides(page: Page, app_url: str, db_ready: None) -> None:
|
||||
# The re-GET settles the badges (the status line lands BEFORE the
|
||||
# re-render — the §7.4 lifecycle); wait for the settled state
|
||||
# rather than snapshotting a mid-flight render (the combined-run
|
||||
# race — the 78-item catalog's re-GET can outlast the status
|
||||
# race — the full catalog's re-GET can outlast the status
|
||||
# poll's gap under a three-suite run, phase-173 regression pass).
|
||||
expect(page.locator(".settings-src.is-db")).to_have_count(0, timeout=30_000)
|
||||
expect(page.locator('tr[data-key="app_name"] .settings-src')).to_have_text("env")
|
||||
|
||||
Reference in New Issue
Block a user