Files
brain-of-reese/.agent/phases/complete/57_edit_document_summaries/00_phase.md
T
ducoterra 4971e2859d
Build and Push Containers / build-and-push-app (push) Successful in 12s
Build and Push Containers / build-and-push-db (push) Successful in 10s
chore(agent): track .agent/ planning tree in git
Remove the blanket .agent/ gitignore so the phase roadmap, user
stories, reports, and PLAN.md are versioned with the code. Only
runtime artifacts (.agent/phase-sessions/, .agent/pipeline.log)
remain ignored. Update AGENTS.md git protocol rule to match.
2026-09-01 10:18:22 -04:00

4.7 KiB
Raw Blame History

Phase 57 — Edit + Re-embed Document Summaries

Source: TODO.md L4 — "Be able to edit the summaries for documents in the RAG. Click an edit button in summary box and change the summary that the AI created. re-embed that document after changing the summary." Story: n/a (TODO-derived — owner roadmap confirmation 2026-08-31) Context: The summary box is the .doc-summary section rendered by the shared core in frontend/assets/document.js (page + modal surfaces) — it renders only when doc.summary is non-empty, as a labeled h2 + text-node <p> (XSS contract: textContent only). Phase 30 stores a non-markdown document's lite digest on documents.summary and indexes it as one extra embedded chunk (is_summary=True, position −1 — app/rag/importer.py:313–336). The document viewer is deliberately PUBLIC (phase 16 owner decision — only the catalog is admin-gated), so the new edit affordance and endpoint must be admin-gated (require_admin, app/core/auth.py); GET /api/whoami (app/api/auth.py:56) already drives admin reveals on static pages. Async endpoints exist in app/api/ (app/api/chat.py:223, app/api/git_sources.py:231), so the re-embed (await llm.embed([...])) fits a standard async def handler.

Objective

An admin can edit (or clear) the AI-generated summary directly in the summary box; on save the stored summary and its is_summary chunk are updated and the chunk is re-embedded — anonymous visitors see the unchanged public viewer with no edit affordance.

Dependencies

  • 56_import_extensions_env (todo, preceding)

Tasks

  1. 01_update_summary_api.md — PATCH /api/documents/summary (admin): update/clear documents.summary, replace the is_summary chunk, re-embed it (one embed call, DB untouched if the LLM fails).
  2. 02_summary_edit_ui.md — Edit button in the .doc-summary panel (admin-only) → inline textarea + Save/Cancel → live-region status on both viewer surfaces.
  3. 03_e2e_edit_summaries.md — story Playwright suite + regressions + the atomic commit.

Testing & Quality

  • Integration: the existing document-content API tests (phase 10) gain the PATCH cases — update + re-embed (chunk content + non-NULL vector + unchanged chunk count), clear (summary NULL + chunk deleted), markdown doc with no prior is_summary chunk (one created), 404 unknown pair, 403 anonymous, LLM-failure error mapping (502/503, DB unchanged).
  • Frontend source pins (house style, tests/unit/test_save_chat_ui.py pattern): document.js (whoami gate, editor wiring, PATCH path, textContent render contract), styles.css (new .doc-summary-* classes).
  • E2E (mandatory, A16): tests/e2e/test_edit_summaries.py, run in isolation (mock SUMMARY_MODE fixture KB).
  • Coverage: >90% on app/ (validate.sh gate).

Completion Criteria

  • Admin: PATCH /api/documents/summary with new text updates documents.summary, replaces the is_summary chunk's content, and stores a fresh embedding (content chunks untouched — count unchanged).
  • Admin: PATCH with an empty/whitespace summary clears documents.summary (NULL) and deletes the is_summary chunk.
  • Anonymous: 403 on PATCH; no Edit button in the viewer; the viewer otherwise renders byte-for-byte as today.
  • The Edit button appears in the summary box (document page and modal), opens a textarea prefilled with the current summary, and Save reflects the change in the panel with a live-region confirmation; Cancel restores.
  • uv run pytest green; coverage TOTAL >90%.
  • uv run pytest tests/e2e/test_edit_summaries.py -v --no-cov green in isolation (DB up).
  • Regression E2E suites green in isolation: test_document_summaries.py, test_document_viewer.py, test_cache_busting.py.
  • uv run ruff check . && uv run pyright clean.
  • One --no-gpg-sign commit; phase dir moved to .agent/phases/complete/ (.agent/ stays untracked — owner instruction, commit 281f355).

Locked decisions

  • Owner-locked (2026-08-31, roadmap confirmation, D4):
    1. Summary editing is admin-only (endpoint + UI affordance). The document viewer stays public.
    2. "Re-embed that document" = replace the is_summary chunk with a fresh embedding (one embed call). The document's content chunks are not re-embedded — the summary is the only text that changed.
    3. Clearing the summary (empty save) sets documents.summary = NULL and deletes the is_summary chunk.
  • Fail-before-write: the embedding happens before any DB mutation; an LLM failure returns an error (502/503, app/api/git_sources.py ModelUnavailableError-style mapping) and leaves the row and chunk untouched.

Commit

git add app/ frontend/ tests/ && git commit --no-gpg-sign -m "feat(kb): edit + re-embed document summaries from the viewer (admin)"