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.
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
# 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
|
||||
1. New `steering_notes` table (id, note, created_at) via Alembic
|
||||
migration 0003.
|
||||
2. Stateless API: `GET /api/steering` (newest first),
|
||||
`POST /api/steering` (1–2000 chars, 201 / 422),
|
||||
`DELETE /api/steering/{id}` (204 / 404).
|
||||
3. 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.
|
||||
4. Per-turn log line gains `tuning=N`.
|
||||
5. 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.
|
||||
6. Notes render as text (XSS-safe).
|
||||
7. Unit + integration green, `app/` coverage >90%, story E2E green in
|
||||
isolation, one `--no-gpg-sign` commit.
|
||||
|
||||
## 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):
|
||||
1. `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.
|
||||
2. `test_delete_note_stops_steering` — delete from panel → count 0 →
|
||||
next answer has no marker.
|
||||
3. `test_note_rendered_as_text_xss_safe` — note with `<script>` renders
|
||||
as visible escaped text, never executes.
|
||||
4. `test_tuning_panel_a11y` — toggle aria-expanded, region label,
|
||||
delete buttons labeled, live region announces save/delete.
|
||||
Reference in New Issue
Block a user