Ship AGENTS.md, CLAUDE.md and Copilot instructions in the Apso NestJS service template
Discovered from README cross-links · today
Commit agent guidance files so generated repos follow Apso rules without MCP.
What they did
The author turned a set of uncommitted local drafts into a tracked ticket for the Apso TypeScript (NestJS) service template. The goal: any coding agent working in a repo generated by `apso init` should follow Apso's rules even when the Apso MCP server is not connected. The agent edits `.apsorc` and `extensions/` and never hand-writes what the generator produces. The drafts existed only in Matt's local checkout, so the ticket inlines the corrected contents of all three files rather than depending on that machine. Two claims in the drafts were wrong and were fixed in place: "deleted and rewritten on every `apso generate`" became "overwritten", because the CLI writes into `src/autogen/` but never deletes, so files for removed entities linger (cleanup tracked separately in apsoai/cli); and the `scopeBy` rule no longer claims tenant scope "is enforced structurally" but states its real per-language status (apsoai/cli#153, #156). The work items: add `AGENTS.md` and `CLAUDE.md` at the repo root plus `.github/copilot-instructions.md`; do not commit `.cursor/rules/apso.mdc` (15KB, identical across all three templates, duplicates AGENTS.md, will drift, and Cursor reads AGENTS.md anyway) and delete it if present; verify every command and name against the current CLI (`apso schema validate`, `apso generate`, `apso doctor` from `apso-cli/src/commands/`; the MCP tool list from `apso-cli/src/commands/mcp/serve.ts`: `design_schema`, `validate_schema`, `scaffold_api`, `setup_auth`, `start_dev_server`, `deploy_api`, `diagnose`, `report_issue`, plus the `apso://current-schema` resource; and the `src/autogen/` and `extensions/` paths against the template layout); confirm https://docs.apso.ai/rules/ resolves (it 301'd to a trailing slash on 2026-10-23); and remember the CLI clones the template at pinned tag `v2.0.0` (`apso-cli/src/lib/utils/template.ts`), so committing to main reaches nobody until a new tag is cut and the pin bumped in apsoai/cli. When apsoai/cli#153 (Python and Go) or #156 (extension guards) ships, the `scopeBy` rule gets updated in the same release. AGENTS.md carries the contract: `.apsorc` is the source of truth; never edit `src/autogen/`; product code goes in `src/extensions/` registered in `src/app.module.rest.ts`; define each relationship exactly once in the top-level `relationships` array (use `bi_directional` for the inverse); never invent `.apsorc` syntax; scope tenant-owned entities with `scopeBy` and hand-check tenant access in custom routes until #156 lands; state destructive migration and deploy risk before acting. It also documents the loop (`apso schema validate`, `apso generate`, `npm run build`, `apso doctor`), the migrate/dev/deploy commands, the directory layout, the `"http": false` trick for overriding a generated route, and traps (UUID primary keys must be `@PrimaryGeneratedColumn('uuid')`, reserved-word table names, enum `values`, indexing `ManyToOne`). CLAUDE.md is a short pointer to AGENTS.md, and the Copilot file repeats the highest-cost rules. Style rule: no em dashes. Done when `apso init` with this template produces a repo containing the three files and an agent session (e.g. Claude Code) can be shown reading AGENTS.md and putting a new feature in `.apsorc` plus `extensions/`.
How it went
The ticket is a complete, self-contained spec: corrected file contents are inlined, the wrong claims are already fixed, and the release path (tag `v2.0.0` pin bump in apsoai/cli) is called out so the change actually reaches users. It is not yet shipped: the files still need committing, every command and path verified against the current CLI, the docs URL confirmed, and the acceptance demo (an agent session reading AGENTS.md) recorded.
Worth knowing
Committing to main does nothing for users until a new template tag is cut and the pin in `apso-cli/src/lib/utils/template.ts` is bumped. The `scopeBy` rule is knowingly incomplete for custom extension routes until apsoai/cli#156, and per-language status depends on #153. The docs URL returned a 301 to a trailing slash and needs rechecking. The MCP tool list and CLI commands must be re-verified against source, since the drafts drifted once already. The acceptance test requires a manual agent session, not just a file diff.
Wiring
Files land at the template repo root (`AGENTS.md`, `CLAUDE.md`) and `.github/copilot-instructions.md`. The CLI clones the template at the pinned tag `v2.0.0` from `apso-cli/src/lib/utils/template.ts`, so the release order is: commit to the template, cut a new tag, bump the pin in apsoai/cli, then `apso init` produces repos with the files. Verification sources: `apso-cli/src/commands/` for `apso schema validate`, `apso generate`, `apso doctor`; `apso-cli/src/commands/mcp/serve.ts` for the MCP tool names and the `apso://current-schema` resource; the template's own `src/autogen/`, `src/extensions/`, `src/app.module.rest.ts` layout. `.cursor/rules/apso.mdc` is deliberately excluded because Cursor reads AGENTS.md. The `scopeBy` wording is coupled to apsoai/cli#153 and #156 and must be updated in the same release those ship.
Try it yourself
In this Apso TypeScript (NestJS) service template repo, add agent guidance files so coding agents follow Apso rules without the MCP server connected.
1. Create `AGENTS.md` at the repo root covering: `.apsorc` is the source of truth; never edit `src/autogen/` (it is overwritten, not deleted, on `apso generate`); product code goes in `src/extensions/` and is registered in `src/app.module.rest.ts`; define each relationship exactly once in the top-level `relationships` array (`bi_directional` for the inverse); never invent `.apsorc` syntax; scope tenant-owned entities with `scopeBy` and hand-check tenant access in custom routes until apsoai/cli#156; state destructive migration/deploy risk before acting. Include the loop (`apso schema validate`, `apso generate`, `npm run build`, `apso doctor`), migrate/dev/deploy commands, the directory layout, the `"http": false` route-override trick, and traps (UUID primary key must be `@PrimaryGeneratedColumn('uuid')`, reserved-word table names, enum `values`, index `ManyToOne`).
2. Create `CLAUDE.md` as a short pointer to AGENTS.md repeating only the two most expensive mistakes.
3. Create `.github/copilot-instructions.md` pointing at AGENTS.md with the top rules.
4. Do not commit `.cursor/rules/apso.mdc`; delete it if present.
5. Verify every command against `apso-cli/src/commands/`, the MCP tool list against `apso-cli/src/commands/mcp/serve.ts` (`design_schema`, `validate_schema`, `scaffold_api`, `setup_auth`, `start_dev_server`, `deploy_api`, `diagnose`, `report_issue`, `apso://current-schema`), and the `src/autogen/` and `extensions/` paths against this template. Confirm https://docs.apso.ai/rules/ resolves.
6. Note in the PR that the CLI clones this template at tag `v2.0.0`, so a new tag and a pin bump in apsoai/cli are required to ship.
No em dashes in these files.