chore(agent): phase roadmap from TODO.md — 3 phases (document modal, global tuning, git-based sources)

This commit is contained in:
2026-08-25 10:15:42 -04:00
parent 025f57beb5
commit 476aa0e066
4 changed files with 149 additions and 1 deletions
+51
View File
@@ -0,0 +1,51 @@
# Story: Global Tuning Manager (No Chat Required, Editable)
**Phase:** `27_global_tuning.md` · **E2E:** `tests/e2e/test_global_tuning.py`
## Narrative
As **the admin (owner)**, I want to **manage my global tuning notes**
without having to have a chat conversation first, and I want to be able to
**edit** a note I've already saved — not just create and delete.
- **Given** I'm the admin and I have no chat open yet
- **When** I open the "Tuning" page (from the header)
- **Then** I can add a new note, edit any existing note inline, list all
notes, and delete them — and every note is stored in Postgres and read
into the system prompt of every future turn.
## Acceptance criteria
1. New endpoint `PUT /api/steering/{id}` (200 updated note; 404 unknown;
422 empty/whitespace/over-2000; 403 anonymous) — the router keeps its
existing `require_admin` gate.
2. New page `/tuning.html` (admin-only nav link): a "Add a global tuning
note" form + a list of notes, each with inline **Edit** (textarea +
Save/Cancel) and **Delete**.
3. A note created on `/tuning.html` is persisted and steers future answers
(no chat turn needed to create it; observable in a later answer).
4. Editing a note updates its text in the list and in the `<tuning>`
prompt.
5. Delete removes the note from the list and the prompt.
6. The chat-page "Tune" button and header "Tuning" panel (phase 15) are
unchanged — create + delete still work there.
7. Anonymous users get 403 on the data and on `PUT`; the header "Tuning"
link is hidden for anonymous.
8. UI: landmarks, labeled controls, ≥44px targets, `:focus-visible`,
contrast ≥4.5:1, live-region announcements, Phase-08 tokens, no-CDN.
9. Notes render as text (XSS-safe).
10. Unit + integration green, `app/` coverage >90%, story E2E green in
isolation, one `--no-gpg-sign` commit.
## Playwright Mapping Rule
**Test Scenario → `tests/e2e/test_global_tuning.py`** (mock LLM, seeded
KB — the mock echoes the first tuning note into its answer when `<tuning>`
is present, so prompt injection is observable in the UI):
1. `test_create_note_without_chat` — `/tuning.html`, add a note, it
appears in the list + announcer.
2. `test_edit_note_inline` — Edit → change text → Save → list updated.
3. `test_delete_note` — Delete → row removed, empty state shows.
4. `test_edit_note_steers_answer` — create via `/tuning.html`, then a chat
turn shows the note's marker in the answer.
5. `test_tuning_page_a11y_and_no_cdn` — landmarks, labels, ≥44px,
focus-visible, dark theme, all assets local.
6. `test_anonymous_cannot_manage` — anonymous list empty; `PUT` → 403.