# Agent setup — tooling reference

First-time machine setup (`.env`, secrets, database): [QUICK_SETUP.md](QUICK_SETUP.md).

`AGENTS.md` keeps the rules most tasks need. This file holds the tooling
reference: what each steering file covers, how skills are mirrored, which shell
commands Codex may run, which MCP servers exist, and the full command list.

## The cycle every agent follows

```
read  → php artisan docs:brief {surface} {feature}   (registry row + Quick reference + BRD section + decisions)
        → only if needed: one doc section · brd/features/{ID}.md · DECISIONS_LOG entry · app_screens/INDEX.md lines
build → .kiro/steering/* rules (CLAUDE.md → Load on demand) → code + tests
write → feature doc (Quick reference + version) → PROJECT_BRAIN.md row → CHANGELOG.md line → DECISIONS.md row + LOG
serve → /docs (people) and the project-docs MCP server (app agents and backend agents) read the same files
```

## Token budget (TD-05)

| Where tokens went | What keeps it small |
|-------------------|---------------------|
| Rules loaded every session | `CLAUDE.md` imports `AGENTS.md` + `business-logic.md` + `api-surfaces.md` only; the rest are read on demand (Claude) or by `fileMatch` (Kiro). The Boost block is written once, to `AGENTS.md` (`config/boost.php` → `agents.claude_code.guidelines_path`). |
| Reading the whole BRD for one feature | `php artisan docs:split-brd` → `docs/brd/features/{ID}.md` (~40 lines each) + `INDEX.md` |
| Opening brain + BRD + decisions + doc for every task | `php artisan docs:brief` / MCP `get-integration-brief`: one call, one compact page |
| Long feature docs | Every doc opens with `## Quick reference`; MCP `read-doc` `outline` / `section`; old history moved to `_history/` |
| Index files turning into history logs | One short line per row (≤ 600 chars); decision detail in `DECISIONS_LOG.md` |
| Screens (images are the most expensive input) | `php artisan docs:index-screens` → `app_screens/INDEX.md`, one described line per image |
| Drift | `tests/Feature/DocsBudgetTest.php` checks every limit in `config/docs.php` → `budgets` |

## Steering files (`.kiro/steering/`)

| File | Covers |
|------|--------|
| `business-logic.md` | Sources of truth, hard rules, client decisions, BRD rules (filled by `project-init`) |
| `api-surfaces.md` | The surfaces (guards), file layout, access boundaries, Flutter/React response rules |
| `feature-documentation.md` | When/how to write feature docs, SemVer, definition of done |
| `postman-collection.md` | Generated Postman collection, field docs in Form Requests, how the docs tools read it |
| `architecture.md` | Request lifecycle, response format, services, translations, media |
| `crud-conventions.md` | Config-only admin controllers, single Form Request, BaseCRUDService |
| `code-standards.md` | PHPDoc, section separators, naming, type safety |
| `base-project-style.md` | Resource and file-shape conventions |

## Project skills

The `project-*` skills live in **`.agents/skills/`** (canonical — read by Codex,
Antigravity, OpenCode) and are mirrored to `.claude/skills/` for Claude Code.
They point to the steering files instead of copying them, so a rule changes in
one place. After editing a `project-*` skill, re-sync the mirror:

```bash
for d in .agents/skills/project-*; do rm -rf ".claude/skills/$(basename "$d")"; cp -r "$d" .claude/skills/; done
```

| Skill | Use it for |
|-------|-----------|
| `project-init` | Project setup: identity, surfaces (guards) and Flutter/React per app (step 1); BRD ingest (step 2); screens (step 3) |
| `project-feature` | Build, change or fix a feature / endpoint |
| `project-feature-docs` | Write or bump a feature doc, CHANGELOG line, registry row |
| `project-decisions` | Ambiguous requirement, BRD/screen/schema conflict, record a decision |
| `project-migrations` | Migrations, models, enums, seeders, factories |
| `project-postman` | Request field docs, regenerating the Postman collection |

The other skills (`laravel-best-practices`, `testing-best-practices`,
`infer-conventions`, `tailwindcss-development`) are managed by Laravel Boost —
refresh them with `php artisan boost:update`, don't edit them.

## Codex command rules

`.codex/rules/project.rules` decides which shell commands Codex may run on its own
(`.codex/config.toml` holds only the Boost MCP entry):

| Decision | Commands |
|----------|----------|
| allow | `php artisan test / route:list / db:show / db:table / config:show / list / about / postman:generate`, `vendor/bin/pint`, `vendor/bin/phpunit`, `composer validate / show` |
| ask first | `php artisan migrate*` / `db:seed`, `boost:install` / `boost:update`, `key:generate`, `composer require / remove / update / install`, `git push / commit / reset / rebase / checkout / switch / merge` |
| never | `php artisan db:wipe`, `git push --force / -f / --force-with-lease` |

Check a command: `codex execpolicy check --pretty --rules .codex/rules/project.rules -- php artisan migrate:fresh`

## MCP servers

Markdown docs hold the **business memory**; MCP servers give **live facts** about
the code. Prefer checking with a tool over guessing.

| Server | Use it for | Config |
|--------|-----------|--------|
| **Laravel Boost** | Database schema, read-only queries, route list, config, logs, version-specific Laravel docs search | `laravel/boost` (dev). `.mcp.json` (Claude Code), `.codex/config.toml` (Codex), `opencode.json` (OpenCode), `.agents/mcp_config.json` (Antigravity). Never runs in production. |
| **project-docs** | The docs of this repo: registry, briefs, BRD, decisions, feature docs, endpoint catalog — for app teams' agents **and** agents working in this repo | `routes/ai.php`, `app/Mcp/`. HTTP `{APP_URL}/mcp/docs`; stdio `php artisan mcp:start project-docs`, configured in `.mcp.json`, `.codex/config.toml`, `opencode.json`, `.agents/mcp_config.json` (re-check after `boost:update`). Guide: [MCP_AGENT_GUIDE.md](MCP_AGENT_GUIDE.md) |
| **Postman** | Syncing/testing the generated collection | Needs authentication in the MCP client |
| **Figma** | Reading designs when a feature doc maps screens to endpoints | Optional |

When an MCP server is unavailable, fall back to `php artisan route:list`,
`php artisan db:show` / `db:table`, and reading migrations.

## Docs viewer, API console, access gate

| URL | What |
|-----|------|
| `/docs` | Browser viewer of `docs/` (markdown, SQL, images, dashboard with MCP snippets) |
| `/tester` | API console over `docs/postman-collection.json`: in-process proxy to this API + **Quick Auth** demo tokens |
| `/mcp/docs` | `project-docs` MCP server (HTTP) |

All three share `App\Http\Middleware\DocsAccess` and `config/docs.php`:
served in every environment **except production** (`production`, `prod`); a
`DOCS_TOKEN` makes them require the token (`Authorization: Bearer`, `X-Docs-Token`,
or `/docs?token=` once in the browser). Production answers 404 unless
`DOCS_ENABLED=true` and `DOCS_TOKEN` are both set, and never issues demo tokens.

## Commands

```bash
php artisan test --compact                       # run tests
php artisan test --compact --filter=DocsViewerTest
vendor/bin/pint --dirty                          # format changed PHP files
php artisan postman:generate                     # regenerate docs/postman-collection.json
php artisan route:list --path=api/v1/client
php artisan docs:brief client auth               # compact brief of one feature (start every feature here)
php artisan docs:split-brd [--dry-run]           # BRD → docs/brd/features/{ID}.md + INDEX.md
php artisan docs:index-screens                   # docs/app_screens/INDEX.md
php artisan test --compact --filter=DocsBudgetTest   # token budgets
php artisan mcp:start project-docs                # docs MCP server over stdio
php artisan mcp:inspector mcp/docs               # debug the docs MCP server
```
