refactor(agents): migrate .agent/ planning tree to .agents/

Standardize on the .agents/ directory (shared with project skills):
phases/, user_stories/, reports/, screenshots/, validate.sh, and
phase-sessions/ + pipeline.log all move to .agents/ (git mv preserves
history; runtime artifacts move alongside).

Updates every reference in AGENTS.md, README.md, .gitignore, app
docstrings, and test story headers. Historical KB content in data/
and the runtime pipeline.log transcript are left untouched.
This commit is contained in:
2026-09-05 10:57:07 -04:00
parent 766702c750
commit dbf2af26c6
1118 changed files with 664 additions and 664 deletions
+49
View File
@@ -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.