# 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 the catalogue pages — 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)`,
`` 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 RAG-table 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 `