# AGENTS.md — working with Grout as an AI agent

This file is for coding agents and assistants. It is served at https://grout.app/developer/AGENTS.md and lives in the GroutApp-WS repository root. It covers two audiences: agents **integrating with the Grout Institution API**, and agents **editing this docs site**.

## 1. Integrating with the Grout Institution API

### Discover
1. Fetch https://grout.app/developer/llms.txt — every page with a summary.
2. Fetch https://grout.app/developer/SKILLS.md — task recipes with scopes, endpoints and request templates.
3. Fetch https://grout.app/developer/openapi-v1.json for exact parameters (live copy: https://serverless.grout.app/v1/openapi.json).
4. Any docs page is readable as markdown by appending `.md` to its path, e.g. https://grout.app/developer/documentation/people/students.md.

### Facts you can rely on
- Base URL `https://serverless.grout.app/v1`. Auth header `Authorization: Bearer grt_live_…`. No cookies, no OAuth.
- Keys are institution-scoped. You can never read or write another institution's data, and no request accepts an `institution_id`.
- Scopes gate every route; `x:write` implies `x:read`. `GET /v1/me` shows the key's scopes — call it before any write.
- Envelope: `{ "success": true, "data": … }` or `{ "success": false, "error": "<code>", "message": "…" }`. Validation errors are 422 with `issues[]`.
- Pagination: `?page&limit` (limit ≤ 200) → `{ items, page, limit, total, totalPages }`.
- Rate limit per key (default 600/min) exposed in `X-RateLimit-*`; on 429/503 honour `Retry-After`.
- Every response carries `X-Request-Id`. Surface it in any error you report to a human.
- People path params accept the internal id **or** the generated login email.
- Provisioning (`POST /students`, `/faculty`, `/groups`) is **not** idempotent. Store returned ids/login emails and check before creating. Merit credits and point awards **are** idempotent on `ref`.
- Webhook deliveries are at-least-once; dedupe on the envelope `id`. Verify `X-Grout-Signature` (HMAC-SHA256 over `"<t>.<raw body>"`, 300 s tolerance, two `v1=` values during rotation).

### Guardrails
- Ask a human before: suspending people, revoking licenses or keys, voiding submissions, deleting groups/exams/endpoints, or crediting merits above a stated budget.
- Never print or store the plaintext API key, webhook secret or hidden-test key in logs, commits or chat.
- Never return a student's personal email, license key or proctoring recordings to anyone who did not ask with a key that has `submissions:write`.
- Prefer several narrow keys (one per job) over one broad key.

### Minimal loop
```bash
curl -s $API/me -H "Authorization: Bearer $KEY"                              # confirm scopes
curl -s "$API/students?student_id=S-0142" -H "Authorization: Bearer $KEY"    # look before you create
curl -s -X POST $API/students -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' \
  -d '{"full_name":"Asha Rao","student_id":"S-0142","personal_email":"asha@example.com"}'
```

## 2. Editing the docs site (GroutApp-WS)

### Where things live
- Content: `docs/documentation/**/*.md` (frontmatter `title`, `description`). Navigation and order: `src/docs/nav.ts`. Changelog: `docs/CHANGELOG.md`. Vendored spec: `docs/openapi-v1.json` (`npm run docs:sync-openapi` refreshes it).
- Engine: `src/docs/loader.ts` (frontmatter, container preprocessing, TOC), `src/docs/highlight.ts`, `src/components/Docs/*` (layout, markdown renderer, search, API reference), pages under `src/pages/developer/**`.
- Agent surfaces are generated by `scripts/build-docs-artifacts.mjs` into `public/developer/` (llms.txt, llms-full.txt, per-page .md, search-index.json, AGENTS.md, SKILLS.md). It runs from `npm run build` and `npm run deploy`.

### Authoring rules
- One H1 is the page title from frontmatter; start the body at `##`.
- Custom blocks: `:::tip|note|warning|danger [Title] … :::`, `:::cards` with `- [Title](href) — text`, `:::steps` with `### Step` headings, `:::tabs` with `### Tab` headings, `:::codegroup` wrapping fenced blocks that carry `title="…"`.
- Links to other docs pages are absolute (`/developer/documentation/...` with trailing slash). External links open in a new tab automatically.
- Add a page: create the markdown file, add `{ slug, title }` to the right group in `src/docs/nav.ts`. The route, prev/next, search index and llms.txt update on build.
- Do not use raw HTML in markdown; the renderer does not allow it.
- Keep `docs/openapi-v1.json` in sync with production when endpoints change, then `npm run docs:artifacts`.

### Build and deploy
- Site is Next 12 + static export, one build per locale (`scripts/build-locales.mjs`). Docs are English-only but exported under every locale prefix; that is expected.
- Install with **npm** (`package-lock.json` is authoritative). Verify with `npm run check-types` and `npm run build`. Deploy with `npm run deploy` (Cloudflare Pages project `grout-ws` → grout.app).
- Redirect `/docs → /developer/documentation/` is in `public/_redirects`; markdown/text content types for `/developer/*` are in `public/_headers`.
