chore(agent): phase 53 — record task 06 completion move to complete/

This commit is contained in:
2026-08-31 00:04:17 -04:00
parent 32b7bfd4b3
commit 9518d9d5d1
@@ -0,0 +1,28 @@
# Task 06 — E2E: Stale Saved Chats + Regressions + Commit
**Phase:** `53_stale_saved_chats` · **Source:** `TODO.md:4` — "Make sure the saved chats are invalidated if the docs are synced, that way it generates a new answer with new data" (this task verifies the full loop in the browser)
**Story:** n/a (TODO-derived)
## Objective
One isolated Playwright story suite for the whole invalidation loop: save → KB-changing sync (version bump) → stale surfaced → Regenerate → current again.
## Work
1. `tests/e2e/test_stale_saved_chats.py` (new) — the story suite (isolated run; `mock_llm` deterministic; real DB per the e2e prerequisite):
- As admin: ask a question (mock LLM answers deterministically), Save via the chat-page button → `GET /api/chats` (admin cookie) reports the row with `stale: false`.
- Produce the KB change the way a real sync does: the test process (which shares the app's environment) imports `bump_sources_version` from `app.rag.sources_meta` and bumps the seed row through a short `SessionLocal()` — deterministic, no dependency on configured git sources in the E2E environment (see the ASSUMPTION).
- `/history.html`: the row now carries the Stale pill; `GET /api/chats` carries `stale: true`.
- Open the row (`/?chat=<id>`, the same URL the History table links): the `#stale-banner` is visible with the Regenerate button; click it → the fresh answer streams in place (the mock LLM's deterministic text replaces the old last brain bubble, phase-49 contract), the banner clears once the row is re-saved; `GET /api/chats/<id>` reports `stale: false` and its last brain message is the fresh answer; the History pill is gone.
- Anonymous: share the (now fresh) chat, open `/shared/<token>` without a session — the page renders the snapshot with NO staleness surface (phase 51 unchanged).
2. Regressions, each in isolation (`uv run pytest tests/e2e/<file> -v --no-cov`): `test_chat_history.py`, `test_share_chat.py`, `test_sync_button.py`, `test_retry_answer.py` (the `retryLastTurn` return-promise change), `test_chat_persistence.py`.
3. One `--no-gpg-sign` commit staging `.agent/ app/ alembic/versions/ scripts/ frontend/ tests/` (message per the phase overview); move `.agent/phases/todo/53_stale_saved_chats/` to `.agent/phases/complete/`.
- ASSUMPTION: the E2E bumps the version via `bump_sources_version` directly (a test-only DB step) — the Sync button's end-to-end clone/import path stays covered by `test_sync_button.py`, and the bump GATES are covered by this phase's integration tests (task 02); the E2E proves the user-visible invalidation loop, not git plumbing.
## Testing & Quality
- E2E (mandatory, A16): `tests/e2e/test_stale_saved_chats.py` green in isolation.
- The five regression suites green in isolation; no assertion edits outside the new contract (the phase-49 retry pins, the phase-50/51 save/share pins stay intact).
## Completion Criteria
- [ ] `uv run pytest tests/e2e/test_stale_saved_chats.py -v --no-cov` green in isolation (DB up).
- [ ] `test_chat_history.py`, `test_share_chat.py`, `test_sync_button.py`, `test_retry_answer.py`, `test_chat_persistence.py` green in isolation.
- [ ] `uv run pytest` + coverage TOTAL >90%; `uv run ruff check . && uv run pyright` clean.
- [ ] One `--no-gpg-sign` commit; phase dir moved to `.agent/phases/complete/`.