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.
2.4 KiB
2.4 KiB
Story: Tune How Brain Answers (Steering Notes)
Phase: 15_steering_notes.md · E2E: tests/e2e/test_steering.py
Narrative
As a user, when an answer isn't quite right (too chatty, wrong assumption, missing context), I want to tune Brain right there: a short instruction ("be more concise", "assume I'm on NixOS") that is stored in the database and read into the system prompt so every future reply follows it.
- Given an answer I don't like
- When I click "Tune" under it and save an instruction
- Then the note is persisted in Postgres, shown in the tuning panel (where it can be removed), and injected into the system prompt of every subsequent turn — verifiable in the answer.
Acceptance criteria
- New
steering_notestable (id, note, created_at) via Alembic migration 0003. - Stateless API:
GET /api/steering(newest first),POST /api/steering(1–2000 chars, 201 / 422),DELETE /api/steering/{id}(204 / 404). - System prompt: when notes exist, a
<tuning>section (numbered notes, char-budgeted) is appended to both HIGH and DEFLECT prompts; when none exist, the prompt is byte-identical to today's. - Per-turn log line gains
tuning=N. - UI: "Tune" button under every completed brain answer (deflected too) → inline form → save → confirmation; header "Tuning" toggle lists notes with per-note delete; all labeled, live regions, ≥44px targets, Phase-08 tokens.
- Notes render as text (XSS-safe).
- Unit + integration green,
app/coverage >90%, story E2E green in isolation, one--no-gpg-signcommit.
Playwright Mapping Rule
Test Scenario → tests/e2e/test_steering.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):
test_tune_under_answer_persists_and_steers— answer → Tune → note "STEEER-MARKER be concise" → saved → next answer contains the marker (note reached the system prompt) → note visible in panel with count.test_delete_note_stops_steering— delete from panel → count 0 → next answer has no marker.test_note_rendered_as_text_xss_safe— note with<script>renders as visible escaped text, never executes.test_tuning_panel_a11y— toggle aria-expanded, region label, delete buttons labeled, live region announces save/delete.