# AGENTS.md — Operating Rules for All Agents on This Repo 1. **Always read `.agents/PLAN.md` first.** It contains the architecture, the LOCKED DECISIONS, the UI/UX standards, the data model, and the roadmap. Do not design anything that contradicts it. 2. **Follow the phased execution protocol in `.agents/phases/`.** Work through `.agents/phases/todo/` in numeric order. When a phase is complete, move its directory to `.agents/phases/complete/`. 3. **Strictly adhere to the LOCKED DECISIONS** (PLAN §2). If you believe a LOCKED decision is wrong, stop and flag it — do not silently deviate. 4. **"One Story, One Phase":** each user story in `.agents/user_stories/` corresponds to a distinct execution phase, and **every** phase — story-driven or owner-directed — includes its own dedicated Playwright E2E test suite (one test file for the phase, run in isolation). 5. **"UI Structure Check":** before finalizing any UI component, verify that it follows the layout principles in `.agents/PLAN.md` §7 (proper container usage, the 72rem centered reading column — every page rides the 72rem container at every viewport; phase 100 supersedes §7.1's 46rem chat column, full-width tables on Sources — no skinny wasted-space lists; the catalogue tables (RAG, Sources, History) are bounded scroll panels — `max-height: min(70vh, 64rem)` — with a sticky header row; a clipped action label shows an ellipsis hint (`.cell-clip`) with the full text kept reachable via the control's aria-label (phase 156); an in-flight turn never paints an empty answer bubble — the box is created empty as the reasoning anchor and `.msg .bubble:empty { display: none }` hides it until the first answer token (phase 166); an answer's inline `[text](url)`, `![alt](src)` and `####`+ heading render through the ONE shared renderer into an allowlist-gated `a.md-link` (underlined, never a `javascript:`/`data:` element), a container-capped `img.md-img` (`max-width: 100%` — no horizontal overflow at 375px) and an `h5`/`h6` sized into the existing type scale — never printed reference text (phase 180); an SVG document paints as a graphic — the viewer's image block adds `.doc-image-img--vector` (`width: 100%`, `object-fit: contain`) when `format` is `svg` so a `viewBox`-only drawing spans the `.doc-image` card instead of the 300×150 default box, while the chat figure and Sources thumbnail keep their fixed caps and the bytes stay an `` src (never inlined) (phase 181); the document viewer's page strip is CLASS-scoped — the primary class shows the strip in place of the text, the additive class never hides the text: Text/Pages toggle group (`aria-pressed`, Text default) with the strip behind it (phase 163); a lazily-drilled KB-tree level keeps the level the user is ON rendered while its node fetch runs, and its ONE in-flight row (`role="status"`) / alert + Retry row (`role="alert"`, a real `