chore(agent): phase roadmap from TODO.md — 3 phases (document modal, global tuning, git-based sources)
This commit is contained in:
@@ -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.
|
||||
Reference in New Issue
Block a user