Skip to content

Usage guide (complete)

Synced verbatim from the repo on every site build. Edit the source file on GitHub (link in the page footer); do not edit the rendered copy here.

Prerequisites

  • Claude Code installed and running
  • A workspace folder that will contain all your project’s services

Setup (once per workspace)

1. Clone this repo into your workspace:

workspace/
└── ai-standards/ ← clone here

2. Copy the commands and skills folders to your workspace root:

Terminal window
cp -r ai-standards/.claude/commands .claude/commands
cp -r ai-standards/.claude/skills .claude/skills
  • commands/ makes all slash commands available in Claude Code (e.g. /init-project, /create-specs).
  • skills/ gives agents on-demand access to narrow playbooks (CORS setup, safe migrations, JWT lifecycle, Vitest patterns, etc.). Claude auto-loads each skill only when it matches the file or task at hand — zero cost when not needed. See skills reference below.

Re-run the cp commands when ai-standards updates its skills or commands. For a live link (edits in ai-standards instantly reflected), replace cp -r with a symlink: ln -s ../ai-standards/.claude/skills .claude/skills.

3. Initialize your project:

/init-project

The agent will ask for your project name and list of services, then create the project-docs folder and install the Agent model-tier enforcement hook into .claude/settings.json (source: templates/agent-model-hook.json; rationale in CLAUDE.md → “Agent model tiering”). Result:

workspace/
├── ai-standards/
│ └── workspace.md ← local config (gitignored) — all agents read this
├── {project-name}-docs/
│ ├── services.md ← your project catalog
│ ├── decisions.md ← architecture decisions (populated by Spec Analyzer)
│ ├── design-decisions.md ← frontend design decisions (populated by Frontend Developer)
│ ├── workspace.md ← local workspace config — all agents read this
│ ├── workspace.mk ← Makefile variables (service lists)
│ └── lessons-learned/ ← per-project agent mistakes, split by back.md / front.md / infra.md / general.md
└── (your services...)

{project-name}-docs/workspace.md is the single source of truth for project paths. Every agent discovers it via the pointer file ai-standards/.workspace-config-path (gitignored, one line — created by /init-project). That pointer is the only project-specific file inside ai-standards/; everything else lives in the docs repo.

Every service you create must have a CLAUDE.md pointing to ai-standards. Use this as the template:

## Standards
Read `ai-standards/CLAUDE.md` and the relevant `ai-standards/standards/*.md` before doing anything.

4. Install Playwright MCP (enables live browser verification by the Tester):

The Tester agent drives a real browser — via the Playwright MCP server — to verify visual and interactive DoD items (full-viewport gradients, rendered error copy, light/dark parity, viewport-size checks). Without it, those items fall back to “requires human verification” and slow down every /build-plan loop.

Create .mcp.json at your workspace root (the folder that contains ai-standards/ and your services — not inside any repo):

{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["-y", "@playwright/mcp@latest"]
}
}
}

Then reload Claude Code (close and reopen the session). On first use, npx downloads @playwright/mcp and Chromium (~150 MB, one-time). Verify with /mcp inside Claude Code — playwright should appear as connected.

The workspace root is intentionally outside version control in this layout, so this step is per-machine. If you set up a second machine (or a teammate joins), re-run step 4 there. The Tester agent definition (agents/tester-agent.md) and build-plan command already assume Playwright MCP is available and will instruct the subagent accordingly.


Upgrading ai-standards in an existing workspace

If you pulled a new version of ai-standards into a workspace that was already initialized (so /init-project will not run again), refresh the Agent model-tier enforcement hook by running this from the workspace root. The merge is idempotent — existing permissions and hooks for other matchers are preserved:

Terminal window
TARGET=".claude/settings.json"
TEMPLATE="ai-standards/templates/agent-model-hook.json"
if [ -f "$TARGET" ]; then
jq -s '
.[0] as $existing | .[1].hooks.PreToolUse[0] as $new_hook |
$existing
| .hooks //= {}
| .hooks.PreToolUse //= []
| .hooks.PreToolUse = (.hooks.PreToolUse | map(select(.matcher != "Agent")) + [$new_hook])
' "$TARGET" "$TEMPLATE" > "$TARGET.tmp" && mv "$TARGET.tmp" "$TARGET"
else
mkdir -p .claude && cp "$TEMPLATE" "$TARGET"
fi

After the merge, open the /hooks menu in Claude Code once (or restart the session) so the harness picks up the change. Verify with jq '.hooks.PreToolUse[] | select(.matcher == "Agent")' .claude/settings.json.


Building a feature

Every feature follows the same four-step flow:

1. /create-specs

Describe the feature in plain business language. No technical details needed.

“I want users to invite others to a board by email”

The agent asks clarifying questions, warns about incompatibilities, and creates:

{project-name}-docs/specs/{Aggregate}/{feature-name}-specs.md

2. /refine-specs

Point to the spec file created in step 1. The agent reads the codebase, fills in technical details, and produces:

{feature-name}-specs.md ← updated with architecture decisions
{feature-name}-plan.md ← execution plan with agent phases
{feature-name}-task.md ← Definition of Done checklist

3. /build-plan

Point to the plan file. The agent orchestrates the full implementation:

  • Spawns isolated subagents per phase
  • Runs Backend + Frontend in parallel
  • Runs reviewers in parallel, loops until approved
  • Runs tests, loops until they pass
  • Calls /update-specs automatically as the last step — syncs the spec with the code, distills the plan + task into an ## As-built notes section, and retires the plan/task files (deleted on simple/standard complexity; archived under specs/_archive/{feature}/ on complex). After a successful /build-plan, you should not need to call /update-specs.

4. /update-specs (rarely invoked manually)

/build-plan runs this for you on every successful feature. Call it manually only when:

  • You edited the implementation directly (outside /build-plan) and the spec is now stale.
  • /build-plan aborted mid-run and the spec was never closed — re-run /update-specs pointing at the same spec so the plan and task are properly distilled and retired.
  • A later bugfix changed something documented in a previous ## As-built notes (rare — usually better to create a new -fix-specs.md feature instead).

The agent compares spec vs actual implementation, updates the spec to match, appends the ## As-built notes section, and deletes or archives the plan/task files.


Spec file lifecycle

Each feature produces a triplet under {project-name}-docs/specs/{Aggregate}/:

FileLifespan
{feature}-specs.mdPermanent — durable contract, read by future features and agents.
{feature}-plan.mdEphemeral — deleted by /update-specs after simple/standard features; moved to specs/_archive/{feature}/ after complex features.
{feature}-task.mdSame as the plan.

The non-obvious rationale from plan + task (complexity choice, files explicitly excluded from scope, deviations from the plan, test deltas) is distilled into an ## As-built notes section appended to {feature}-specs.md before the plan/task are retired. That keeps the specs folder lean while preserving what would otherwise be lost. INDEX.md marks archived features with 📦.

If you want to keep plan/task for a specific feature (e.g. to review before deletion), tell the orchestrator during /update-specs — it will skip retirement but still update the spec and INDEX.


Commands reference

CommandWhen to useInvokes
/init-projectOnce, when starting a new project
/create-specsWhen you have a new feature to build
/refine-specsAfter create-specs, to produce the technical spec and plan
/build-planAfter refine-specs, to implement the full feature/update-specs (automatic, last step)
/update-specsRarely by hand — see “When to run this manually” in commands/update-specs-command.md
/check-web <url>Manual on-demand audit of a deployed UI — find symptoms (5xx, 4xx, console errors, axe violations, deprecations), group them by inferred root cause, emit paste-ready /create-specs prompts. Read-only navigation, never submits forms or triggers destructive actions. Requires npm install once in scripts/check-web/.Web Auditor agent

Make commands (workspace-level)

The root Makefile in ai-standards/ orchestrates every service in the workspace using the BACKEND_SERVICES and FRONTEND_SERVICES lists from {project-name}-docs/workspace.mk (generated by /init-project; located via the .workspace-config-path pointer file). Run these from the ai-standards/ directory.

Lifecycle

CommandWhat it does
make infra-upStarts shared infrastructure only (PostgreSQL, RabbitMQ, Mailpit)
make infra-downStops shared infrastructure
make upStarts infrastructure first, then every service (docker compose up -d)
make downStops every service, then the infrastructure
make buildRebuilds all service images
make updatemake build + make up (use after changing composer.json, Dockerfile, or any file in the Docker build context)

Observability

CommandWhat it does
make psShows container status for infrastructure + all services
make logsTails infrastructure logs

Tests

CommandWhat it does
make testUnit + integration on every service
make test-unitUnit tests only
make test-integrationBackend integration tests only (frontends don’t have integration tier)

Quality gates

CommandWhat it does
make lintPHP-CS-Fixer dry-run (backends) + ESLint + Prettier check (frontends)
make staticPHPStan level 9 (backends) + vue-tsc --noEmit (frontends)
make qualitylint + static + test — the full gate bar across the workspace

Run make quality before a push. See standards/quality-gates.md for the full rules and templates/ for the installable CI / hook / Makefile assets per service.

Framework self-checks

CommandWhat it does
make smokeStatic checks over the ai-standards/ repo (agent model tier, command→agent wiring, skill folder/name drift, docs path refs, CLAUDE.md index coverage, reviewer checklist rule IDs). 0 tokens. Runs on every CI push.
make smoke-dynamicLocal only. Runs /build-plan against a minimal fixture (tests/fixtures/standard/), intercepts the first Agent spawn, asserts the model tier + context-bundle invariants. Real API tokens. Run before cutting a release, or after changing commands/build-plan-command.md, any file under agents/, or standards/agent-reading-protocol.md. See tests/README.md.

What’s NOT in the root Makefile

Per-service commands — make lint, make static, make quality — also exist inside each service directory after you install the quality snippets. The root targets iterate over services; the per-service targets run directly via docker compose exec.


Workspace structure (after setup)

workspace/
├── .claude/
│ ├── commands/ ← slash commands (copied from ai-standards/.claude/commands/)
│ └── skills/ ← on-demand playbooks (copied from ai-standards/.claude/skills/)
├── ai-standards/ ← this repo (standards, agents, commands, skills) + `.workspace-config-path` pointer
├── {project-name}-docs/
│ ├── services.md ← project service catalog
│ ├── decisions.md ← architecture decisions (Spec Analyzer)
│ ├── design-decisions.md ← frontend design decisions (Frontend Developer)
│ ├── workspace.md ← workspace config — path source of truth for agents
│ ├── workspace.mk ← Makefile variables (BACKEND_SERVICES, FRONTEND_SERVICES)
│ ├── lessons-learned/ ← per-project agent mistakes (back / front / infra / general)
│ │ ├── README.md
│ │ ├── general.md
│ │ ├── back.md
│ │ ├── front.md
│ │ └── infra.md
│ └── specs/
│ ├── INDEX.md
│ ├── _archive/ ← complex features: plan + task preserved here after /update-specs
│ │ └── {feature-name}/
│ │ ├── {feature}-plan.md
│ │ └── {feature}-task.md
│ └── {Aggregate}/
│ ├── {feature}-specs.md ← durable contract (with ## As-built notes after /update-specs)
│ ├── {feature}-plan.md ← ephemeral — retired on /update-specs
│ └── {feature}-task.md ← ephemeral — retired on /update-specs
├── {service-1}/ ← your backend/frontend services
├── {service-2}/
└── ...

Multi-developer use

The framework is designed for one developer per workspace at a time. The orchestrator, lessons-learned files, Phinx migration timestamping, and the model-tier hook all assume a single concurrent operator. Some scenarios still work in practice; others are untested. Be explicit about which one you are in.

No friction

  • Two developers each running /build-plan against different services on different branches.
  • Reading specs, standards, and reference files in parallel — nothing in the framework writes to those during a feature.

Expected merge conflicts (normal git, not a bug)

When two developers complete features in parallel and merge to master, plain text-diff conflicts can appear in any append-only or shared file the project keeps under {project-docs}/:

  • Per-domain notes the project chooses to maintain (e.g. lessons-learned files split by back / front / general / infra, or whatever layout the project adopted) — append-only by convention; conflicts resolve cleanly by keeping both entries.
  • {project-docs}/specs/INDEX.md — same append-only pattern.
  • {project-docs}/services.md, {project-docs}/decisions.md, {project-docs}/workspace.md — touched only when the framework or services list changes; rarer.

These are normal git conflicts. Resolve them in the second-merger’s PR.

Concurrent state to be aware of

  • /check-web appends findings to {project-docs}/web-flows.md (the auditor’s append-only memo). Two parallel runs against the same checkout will produce a normal git merge conflict on that file — resolve like any append-only conflict by keeping both blocks. Two parallel runs against the same uncommitted working copy would collide in-memory (last writer wins on disk before either commits). Serialise the runs in that case, or each developer should work on their own branch.

Not supported / untested

  • Two /build-plan runs on the same service at the same time. The model-tier hook is global per workspace, dev/test containers are per-service (so they share state when both runs hit the same service), and Phinx migrations following the project’s M_NNNN_* sequence-numbered convention will collide on the next free integer if both runs create one. Don’t rely on it.
  • Two /update-specs runs on the same feature concurrently. The spec file is the single source of truth; last writer wins silently.
  • Concurrent edits to ai-standards/ itself (the framework repo). Treat upgrades as a single-operator event coordinated through release-please, not parallel work.
  • Branch naming collisions: two developers picking the same feature/{aggregate}/{description} will conflict at push time. Coordinate branch names beforehand or include a dev identifier (feature/board/add-archived-flag-mario).

If a multi-dev scenario you care about is not listed here, treat it as “untested” — open an issue with the exact workflow before relying on it.


Standards reference

Standards are split into rules (concise, always loaded by agents) and reference (full examples, loaded conditionally).

FileWhat it governs
standards/invariants.mdNon-negotiable rules — read first by all agents
standards/agent-reading-protocol.mdCanonical reading order for every agent (build-plan + standalone modes)
standards/tech-stack.mdAuthoritative versions (minimums, open to update) + upgrade procedure
standards/backend.mdPHP/Symfony: architecture rules (concise)
standards/backend-reference.mdFull code examples, configs, scaffold usage
standards/backend-review-checklist.mdClosed list of verifiable rules consumed by the Backend Reviewer agent
standards/frontend.mdVue 3/TS: rules (concise)
standards/frontend-reference.mdFull code examples, test patterns
standards/frontend-review-checklist.mdClosed list of verifiable rules consumed by the Frontend Reviewer agent
standards/security.mdHeaders, CORS, JWT, rate limiting, input validation, XSS, redirect allowlist
standards/secrets.mdSecret classification, project manifest, injection matrix, rotation, redaction
standards/performance.mdDatabase indexing, pagination, N+1, response envelope, frontend perf budget
standards/caching.mdHTTP cache headers, Redis keys/TTLs, invalidation, stampede protection
standards/observability.mdOpenTelemetry tracing, RED metrics, health endpoints, SLO shape
standards/logging.mdStructured JSON logs, Monolog config, sensitive-field redaction
standards/api-contracts.mdURL versioning, OpenAPI as contract, breaking-change protocol, deprecation headers
standards/data-migrations.mdSchema evolution strategy, expand-contract, backfills, zero-downtime deploy matrix
standards/authorization.mdVoter pattern, Subject VO, tenant scoping, RBAC + ABAC hybrid model
standards/i18n.mdLocale negotiation, UI strings vs content translations, fallback chain, plurals/dates/currency formatting, vue-i18n
standards/gdpr-pii.mdFour-tier PII classification, encryption, DSAR + RTBF workflow, consent ledger, sub-processors, DPIA
standards/attack-surface-hardening.mdOWASP Top 10 coverage, CSP/HSTS, CSRF, SSRF (SafeHttpClient), XXE/SSTI, lockout, bot, SBOM, container scan, gitleaks, DAST
standards/llm-integration.mdLlmGatewayInterface Domain seam, prompt versioning, JSON schema, retries/circuit breaker, cost spans, PiiPromptGuard, tool-use loop
standards/payments-and-money.mdMoney VO (integer minor units + ISO 4217), append-only ledger, deterministic webhook idempotency, state machines, multi-party splits, reconciliation
standards/file-and-media-storage.mdBucket layout, presigned PUT/GET, magic-byte verification, antivirus state machine, video transcode pipeline, retention, observability
standards/geo-search.mdgeography(Point, 4326) storage, GiST indexes, Postgres FTS before any dedicated search engine, MatchScoreCalculator, score → label translation
standards/audit-log.mdAppend-only audit_log table, AuditLogProjector wiring, same-tx-or-outbox synchrony, mandatory entries on success AND denial, retention
standards/feature-flags.mdFlag taxonomy (release / operational / experiment / permission), registry, FlagGatewayInterface Domain seam, sticky bucketing, removal procedure
standards/analytics-readonly-projection.mdFour-tier projection model (T1 read-on-operational / T2 materialized / T3 replica / T4 warehouse), schema isolation, replica lag, mandatory Voter
standards/pwa-offline.mdFour progressive levels (L0 SPA → L3 offline writes + push), Workbox-generated SW, manifest, IndexedDB never holding Sensitive-PII, push consent per category
standards/digital-signature-integration.mdSignatureGatewayInterface Domain seam, modality (simple / advanced / qualified), versioned templates, SigningRequest state machine, signed-document document_sha256, signature-verify-before-parse webhooks
standards/adr.mdArchitecture Decision Record format — ID convention, status lifecycle, structure, when to write one
standards/critical-paths/Curated rule subsets per feature kind (CRUD, auth, PII, payment, LLM, file upload, signature, geo-search, PWA, async handler, public-facing deploy)
standards/new-service-checklist.mdPre-commit checklist for new services
standards/quality-gates.mdCI + pre-commit + Makefile quality rules (PHPStan L9, vue-tsc, tests)
scaffolds/Copy-verbatim PHP classes (AppController, ApiExceptionSubscriber, LoggingMiddleware, SecurityHeadersSubscriber, Subject + Voter, Money + Currency + CurrencyMismatchException, SafeHttpClient + SsrfBlockedException, LlmGatewayInterface + LlmRequest + LlmResponse, AuditLogProjector, AssertMaxQueriesTrait + QueryCountMiddleware)
templates/ci/GitHub Actions workflow templates (backend + frontend)
templates/hooks/Git pre-commit hooks (backend + frontend)
templates/makefile/Makefile quality snippets to drop into a service Makefile
templates/agent-model-hook.jsonPreToolUse hook that rejects Agent invocations without a model argument — installed by /init-project into .claude/settings.json
.claude/skills/On-demand playbooks (see below)

Skills reference

Skills are narrow, auto-loading playbooks. Claude reads only each skill’s description at session start (cheap) and loads the full body only when the active task matches. This replaces reading big reference files end-to-end.

SkillActivates when
cors-nelmio-configurationConfiguring NelmioCorsBundle, adding a new frontend origin, debugging CORS preflight failures
docker-env-reloadEditing .env / env_file; when env-var changes aren’t taking effect in a running container
docker-frontend-deps-syncRunning npm install, adding/removing packages in a Dockerized Vue/Vite frontend
shadcn-vue-component-addBefore/after npx shadcn-vue add <component> — to catch silent overwrites of unrelated files
new-service-bootstrapScaffolding a new PHP/Symfony service (Kernel, bundles, routes, Flex cleanup, composer.lock sync)
doctrine-migration-safeWriting a Phinx migration — tables, columns, indexes, safe ALTER patterns
symfony-messenger-asyncConfiguring buses, RabbitMQ transports, cross-service message contracts, consumer workers
messenger-logging-middlewareWiring LoggingMiddleware, configuring Monolog JSON-to-stdout, sensitive field redaction
jwt-securityImplementing JWT auth, refresh-token rotation, httpOnly cookie storage, Lexik config
rate-limiting-authAdding Symfony RateLimiter to login/register/password-reset/token-refresh endpoints
vue-composable-mutationWriting a Vue 3 composable with TanStack Query useMutation for write operations
pinia-store-patternCreating/modifying a Pinia store — canonical setup-store shape, destructuring rules, reactive() in tests
empty-loading-error-statesWriting a Vue page that renders server data — canonical loading / error / filtered-empty / initial-empty branches
openapi-controller-docsAdding #[OA\...] attributes on a Symfony controller — request body, response schemas, error envelope, security
vitest-composable-testWriting Vitest tests for composables, stores, pages (mocks, captured callbacks, jsdom shims)
quality-gates-setupInstalling CI workflow, pre-commit hook, and Makefile quality targets in a new or existing service
backend-finder-service-throw-on-missWriting or reviewing a service that locates an aggregate by id/email/slug — repository nullable, FinderService throws, one variant per class
backend-service-placement-decisionCreating a new service class — Domain vs Application placement, one-public-method rule, naming convention
backend-controller-handler-shapeWriting a new controller + command/query handler pair — thin controller, one-per-message handler, OpenAPI + ApiExceptionSubscriber wiring
backend-voter-patternAdding an authorization-protected endpoint — Subject VO, tenant-scoping-first, isGranted-before-side-effect, audit log on grant AND deny
backend-pii-write-flowImplementing or reviewing an endpoint that stores personal data — single-commit checklist (migration + inventory + redaction + projector + tests)
backend-async-failure-subscriberWiring a Symfony Messenger consumer’s failure path — WorkerMessageFailedEvent subscriber, idempotency time-bucket, exception unwrapping (BE-070..072)
backend-cache-headersAdding HTTP cache headers to a new GET endpoint — decision tree for Cache-Control / Vary / ETag, public vs per-user vs per-tenant
frontend-perf-vite-budgetConfiguring or reviewing the bundler’s chunk budget — initial JS / per-route / LCP image / virtualization / font-display

All skills can also be invoked manually with /skill-name. See each skill’s SKILL.md for the full content.