Convert the four open TODO items into executable phases (append mode,
starting at 190 after the completed 189):
190_app_name_settings_fix - the Settings-panel app name wins over the
Theme tab; the three brand strings stripped from the Theme tab
(colors-only); live brand re-apply on save, no reload
191_source_name_labels_tags - source_labels table + admin API + Sources
page editor; the separate bounded source_name_hit_bonus retrieval
boost; label surfacing in the <document> blocks and KB overview
192_verbatim_inline_midturn - an additive verbatim_block SSE frame at
the show_text success moment; in-place mid-turn fence hydration;
the done/restore per-locator dedupe; the done frame, record key,
restore and shared page stay byte-identical
193_sync_remaining_count - the running sync/upload label counts down:
"N remaining" (N = total - done), hidden at the final file; the
chunk/image/summaries/terminal parts untouched
TODO.md is cleared (its items now live in .agents/phases/todo/).
LLM-Generated: true
5.7 KiB
5.7 KiB
Task 04 — The phase E2E suite, the full gates, the docs pass, the commit
Phase: 192_verbatim_inline_midturn · Source: TODO.md:6
Story: n/a
Objective
The dedicated Playwright suite proves the owner-visible contract — the panel is on screen WHILE the answer is still streaming, the fence lands in place, nothing doubles, the kill switch is a byte-identical wire — run in isolation per AGENTS rule 4; the full gates pass; the docs are consistent; one atomic commit.
Work
tests/e2e/test_verbatim_inline_midturn.py(NEW — the module docstring names the TODO item and the A4 unchanged-contract clause) — the module-app fixture pattern (the phase-182 E2E convention — verify intests/e2e/conftest.py/ the sibling verbatim suites; the mock LLM fromtests/e2e/mock_llm.py— verify the phase-182 mock'sshow_textarm; if the mock drivesshow_textvia a fence-only turn, extend the mock with a directshow_texttool call arm intests/e2e/mock_llm.py— the mock is a test fixture, the extension is additive and the phase-182 pins must stay green):- the fixture: a small KB with one document whose content the mock's
show_textcall targets (the phase-182 fixture convention). - (a) the mid-turn arm (the TODO regression): a mock turn: an intro delta ("…here is the exact text:") → the
show_textcall (the mock arm) → the continuation deltas →done. Assert: the panel (.verbatim[data-bor-locator]with the call's locator — caption + gutter + body) is in the DOM BEFORE thedoneframe is consumed (the Playwright shape:page.wait_for_selectoron the panel resolves while the stream is still running — a sentinel delta after the call proves the stream is live; the panel's DOM position is BELOW the intro text and ABOVE the final sentinel delta — the inline position assertion, theanswer_image-position contract ofappendUnlocatedVerbatim); thedonepass adds nothing (the final panel count == 1). - (b) the fence-in-place arm: a mock turn: an intro delta → the
show_textcall forsource/path#12-20→ the final answer containing the```borfence for the SAME locator →done. Assert: the fence placeholder is hydrated IN PLACE (the panel is at the fence position — between the intro and the final sentinel delta, NOT at the answer tail) beforedone(the mid-turnhydrateVerbatimNowpass); afterdone, the total panel count for that locator == 1 (the dedupe — the task-03 arm). - (c) the two-ranges arm: a mock turn with TWO
show_textcalls — range 1–10 and range 11–20 of the same document (theshown_textsper-locator dedupe admits both) — no fences. Assert: exactly TWO panels afterdone, both at the answer position in call order, both with their own captions (the per-locator-not-per-identity pin, owner-visible). - (d) the kill-switch wire arm: the
BOR_ANSWER_TEXT=0module app — the same mock turn (the mock'sshow_textattempt hits the phase-182 refusal) → the captured SSE frame sequence (types + payloads via the house SSE-capture pattern) equals the pre-phase baseline (documented in the test); NOverbatim_blockframe, NO panel, NO placeholder in the DOM. - (e) the restore arm: run arm (a) to completion (a saved conversation — the phase-158 auto-save), reload the page, restore → exactly ONE panel for the locator (the record's
answer_textthrough the same dedupe functions — the A4 parity pin, owner-visible).
- the fixture: a small KB with one document whose content the mock's
- Regression, run in isolation: the phase-182 E2E suites (verify the exact names in
tests/e2e/— the verbatim display suite, the fence suite),tests/e2e/test_chat_history.py(the restore contract) — green unedited. - The full gates, in order:
uv run pytest(unit + integration) — 100% passing;uv run pytest --cov=app --cov-report=term-missing— >90% onapp/;uv run pytest tests/e2e/test_verbatim_inline_midturn.py -v --no-cov— green in isolation;uv run ruff check . && uv run pyright— clean.
- Documentation pass (the phase file's Documentation section):
README.md+AGENTS.mdreviewed in their entirety against the post-phase app; the verbatim section notes the mid-turn landing (ashow_textpanel appears the moment the call succeeds — in place when fenced, at the answer position when not; thedone/restore/shared contract is unchanged, the kill switch byte-identical);AGENTS.mdcorrected only where it names the done-frame resolution as the ONLY landing point. - Commit: one atomic, professional commit (Conventional Commits,
--no-gpg-sign), e.g.feat(verbatim): show_text panels land mid-turn, at the moment the call succeeds (phase 192)— the body names the additiveverbatim_blockframe, thehydrateVerbatimNowmatched-only pass, the per-locator dedupe, and the A4 unchanged contract..agents/phases/todo/192_verbatim_inline_midturn/moves to.agents/phases/complete/in the SAME commit (AGENTS rule 8).
Testing & Quality
- E2E: the suite above, isolated; the regression suites green.
- Coverage: >90% on
app/. - Lint/types: clean.
Completion Criteria
tests/e2e/test_verbatim_inline_midturn.pygreen in isolation — (a) the panel is on screen beforedone, at the inline position; (b) the same-locator fence hydrates in place mid-turn and never doubles; (c) two ranges of one file → two panels; (d) theanswer_text=Falsewire is byte-identical with no panel/placeholder; (e) the restore shows one panel per locator.uv run pytest100% passing;uv run pytest --cov=app --cov-report=term-missing>90%;uv run ruff check . && uv run pyrightclean.README.md/AGENTS.mdconsistent (the mid-turn landing clause).- the phase directory is in
.agents/phases/complete/; one atomic commit with--no-gpg-sign.