# AGENTS.md Guidance for AI agents and contributors working in this repo. Read `README.md` for commands and layout. ## Maintaining this file Every agent session reads this file in full, so its length is a cost paid on every task. Keep it the shortest thing that still changes what someone does. - **Trim as you add.** After any edit, re-read the whole file and compress: merge overlapping entries, cut prose that restates a rule, drop what the code or `README.md` already says. Question each section — same information, fewer words. - **Record the decision and the reason it turns on, nothing else.** Not the investigation, not what was tried first, not how it was verified — that belongs in the PR that made the change. - **Give every accepted risk an expiry** ("valid while X"), and delete the entry once X stops holding. - **One home per fact.** Link to it rather than restating it — the same sentence in five files is five things to update and five chances to drift. ## How to work with tasks Use the file `todo.md`. For each todo item, interview the user extensively to deeply understand the scope and goal of each. When done, check the completed task in `todo.md`. Commit all changes and push to a new branch, create a PR and merge it when the CI/CD turns green. ## Project priorities (do not erode) 1. **Simplicity** — prefer the solution that is easiest to understand, smallest, and most readable. 2. **Few dependencies** — runtime deps stay minimal (today `ejs`, `lucide-static`, `@larvit/log`). Prefer the Node standard library; justify any new dependency; do not add frameworks. The app is **stateless — no database**. Auth/identity/OAuth are **Ory sidecar services** (Kratos/Keto/Hydra, backed by Postgres), reached over their REST APIs with built-in `fetch` — no SDK. New capabilities ship as **plugin folders** under `plugins/` that fetch their data from upstream services, not as core code. 3. **Strict TypeScript** — `tsconfig.json` is strict (incl. `noUncheckedIndexedAccess`, `exactOptionalPropertyTypes`, `verbatimModuleSyntax`). Keep it that way. Prefer exact types; limit nullable and multi-option types. 4. **Environment-agnostic** — the app never asks *which environment* it runs in; no `NODE_ENV` branching. Every behaviour is an **explicit config toggle** (e.g. `CACHE_TEMPLATES`, `REQUIRE_SECURE_SECRETS`), read once in `src/config.ts`. Compose files set them per deployment. 5. **Semantic, accessible DOM** — use the right element for the job (landmarks, one `

` per page + sane heading order, lists, `` with row/column headers, `
`/``, `