Files
toir-automatization/AGENTS.md
2026-04-07 19:40:41 +03:00

23 KiB

KIS-TOiR — Agent Operating Rules

Read this file at the start of every session before reading any other file.


What this repository is

KIS-TOiR is a fullstack CRUD application (NestJS backend + React Admin frontend) for equipment maintenance management (Техническое обслуживание и ремонт).

Generation is driven by a single authoritative source file:

  • domain/toir.api.dsl — the complete API contract: enums, DTOs, endpoints, HTTP methods, pagination

Source-of-truth hierarchy

Tier 1 — authoritative (hand-authored; never overwritten by generation)

File Authoritative for
domain/*.api.dsl Enums, DTO shapes per operation, nullability, HTTP verb+path per endpoint, endpoint names, pagination contracts. Single source of truth. Drives: NestJS modules + React Admin resources + Prisma schema.
prompts/*.md Auth rules, runtime rules, framework scaffold rules, Prisma rules, validation rules, generation policy, naming conventions.
AGENTS.md (this file) Agent workflow, mutation boundaries, verification contract.
docs/completion-contract.md Operational definition of done, success tiers, failure modes, recovery rules.
.codex/AGENTS.md Codex-specific agent governance supplement (Codex runtime only).
.claude/CLAUDE.md Claude Code-specific agent governance supplement. MANDATORY for Claude Code sessions. Defines subagent registry, orchestration entry points, write-zone enforcement, MCP tool access.
prompts/claude-orchestration-rules.md Claude Code orchestration and subagent delegation rules. MANDATORY when orchestrating subagents. Defines shallow delegation pattern, contract freeze, acceptance protocol, failure handling, write-zone boundaries.

Tier 2 — deterministic derivative (generated by script; never edited manually)

File Generated from Command
api-summary.json domain/*.api.dsl npm run generate:api-summary

Tier 3 — LLM-generated artifacts (never edit manually after generation)

These outputs are end-state generation targets. During a repo-wide full regeneration driven by prompts/general-prompt.md, they may be absent at the start of the run and are recreated from Tier 1 sources plus official CLI scaffolding.

Zone Generated from
server/src/modules/<entity>/ domain/*.api.dsl + prompts/backend-rules.md
client/src/resources/<entity>/ domain/*.api.dsl + prompts/frontend-rules.md
server/src/app.module.ts Module registrations derived from api.dsl api blocks
client/src/App.tsx Resource registrations derived from api.dsl api blocks
server/prisma/schema.prisma domain/*.api.dsl + prompts/prisma-rules.md
server/src/auth/ prompts/auth-rules.md
client/src/auth/ prompts/auth-rules.md
client/src/dataProvider.ts prompts/auth-rules.md
toir-realm.json prompts/auth-rules.md
docker-compose.yml prompts/runtime-rules.md
server/Dockerfile prompts/runtime-rules.md
client/Dockerfile prompts/runtime-rules.md
client/nginx/default.conf prompts/runtime-rules.md
server/docker-entrypoint.sh prompts/runtime-rules.md
db-seed/Dockerfile prompts/runtime-rules.md
db-seed/import.sh prompts/runtime-rules.md
server/.env.example prompts/runtime-rules.md
client/.env.example prompts/runtime-rules.md

Tier 4 — handwritten / framework-managed support files

  • Framework scaffold and bootstrap helpers that remain manually maintained unless a repair task says otherwise: server/nest-cli.json, server/tsconfig*.json, client/vite.config.*, etc.

Runtime / Deploy Contract

  • Tier 3 runtime/deploy outputs are first-class generation targets and must be regenerated from the companion rules when they drift.
  • Tier 4 support files are framework-managed rather than hand-authored sources of truth.
  • Runtime/deploy readiness is part of completion, not an optional follow-up.

Approved Stack Version Policy

Future full-regeneration runs must normalize scaffolded package manifests and runtime inputs to the approved versions below. Do not use latest, caret ranges, or unreviewed major bumps when the repository regenerates or repairs the stack.

Runtime baseline:

  • Node.js: prefer the Node 22 LTS line; minimum approved version is 22.12.0
  • Package manager: npm only, with committed package-lock.json files; do not switch the repo to pnpm, yarn, or bun

Backend generation baseline:

  • @nestjs/common, @nestjs/core, @nestjs/platform-express, @nestjs/testing: 11.1.18
  • @nestjs/config: 4.0.3
  • @nestjs/cli: 11.0.17
  • @nestjs/schematics: 11.0.10
  • prisma and @prisma/client: 6.16.2 exactly, kept on the same version
  • class-validator: 0.15.1
  • class-transformer: 0.5.1
  • jose: 6.2.2
  • reflect-metadata: 0.2.2
  • rxjs: 7.8.1
  • backend typescript: 5.7.3

Frontend generation baseline:

  • react and react-dom: 19.2.4
  • react-admin and ra-data-simple-rest: 5.14.5
  • @mui/material and @mui/icons-material: 7.3.9
  • @emotion/react: 11.14.0
  • @emotion/styled: 11.14.1
  • vite: 8.0.3
  • @vitejs/plugin-react: 6.0.1
  • frontend typescript: 5.9.3
  • keycloak-js: 26.2.3

Policy rules:

  • When official CLIs scaffold newer dependency sets, repair the scaffold and then pin it back to the approved versions above before generation continues.
  • prisma and @prisma/client must always stay on the same exact version.
  • Do not upgrade Prisma from v6 to v7 as part of routine regeneration; treat that as a separate explicit migration task with updated prompts, runtime checks, and verification.

Forbidden mutations during any generation run

NEVER write to *.dsl files. They are read-only inputs. To change the API contract or domain model, edit domain/*.api.dsl as a separate explicit task.

NEVER manually edit files under server/src/modules/ or client/src/resources/. To change generated code: update domain/*.api.dsl and regenerate.

NEVER edit server/prisma/schema.prisma directly. It is LLM-generated from domain/*.api.dsl following prompts/prisma-rules.md.


Multi-agent orchestration model

Full-generation runs use a parent-orchestrated, bounded multi-agent model. The parent agent is the orchestrator/integrator. It is not the default broad feature implementer.

Parent-only responsibilities:

  • discovery orchestration
  • docs verification orchestration
  • contract freeze
  • shared platform scaffold
  • auth platform skeleton
  • deploy/runtime skeleton
  • shared platform wiring and env/runtime conventions
  • launching specialized generators
  • accepting or rejecting generator outputs
  • final integration
  • validation
  • final handoff to reviewer

Specialized generation agents:

  • generator_prisma — schema/model generation only
  • generator_nest_resources — NestJS resource modules only
  • generator_react_admin_resources — React Admin resource UI only
  • generator_data_access — frontend data-access seam only

The old universal generator agent is removed from the active orchestration model and must not be used for full-generation workflows.

Delegation order

Use agents in this order:

  1. explorer for repository discovery, execution-path inspection, scaffold checks, and local seam tracing
  2. docs_researcher for official documentation verification and version-sensitive framework behavior
  3. parent contract freeze and shared scaffold/auth/runtime planning
  4. specialized generators after contract freeze, in parallel when safe:
    • generator_prisma
    • generator_nest_resources
    • generator_react_admin_resources
    • generator_data_access
  5. parent integration and validation
  6. reviewer only at the final review stage

If a runtime does not expose named subagents, keep the same separation of responsibilities inside one agent and preserve the same handoff boundaries.

Write-zone ownership

Parent-only write zones:

  • shared scaffold and framework repair surfaces
  • server/src/auth/
  • client/src/auth/
  • toir-realm.json
  • docker-compose.yml
  • server/Dockerfile
  • client/Dockerfile
  • client/nginx/default.conf
  • server/docker-entrypoint.sh
  • db-seed/Dockerfile
  • db-seed/import.sh
  • server/.env.example
  • client/.env.example
  • shared integration seams and final validation outputs explicitly delegated by prompts

Specialized generator write zones:

  • generator_prisma
    • server/prisma/schema.prisma
    • optional machine-readable schema summary or structured handoff artifact when the parent explicitly requests it
  • generator_nest_resources
    • server/src/modules/**
    • backend registration touchpoints only when explicitly delegated by the parent contract
  • generator_react_admin_resources
    • client/src/resources/**
    • frontend resource registration touchpoints only when explicitly delegated by the parent contract
  • generator_data_access
    • client/src/dataProvider.ts
    • narrowly delegated frontend integration seams only when explicitly delegated by the parent contract

Specialized generators must not redesign shared auth, runtime, deploy, scaffold, or platform seams outside their delegated zones.

Contract freeze (required before specialized generation)

Before launching specialized generators, the parent must produce a normalized structured handoff from the DSL and prompt contracts. This contract freeze is a required protocol owned by the parent; it does not replace domain/*.api.dsl.

The frozen contract must cover, where relevant:

  • entities
  • fields
  • scalar and enum types
  • ids and composite keys
  • relations
  • enums
  • endpoint conventions
  • route and path conventions
  • naming rules
  • auth surface expectations
  • validator and eval compatibility constraints
  • allowed write-zones per generator

Specialized generators start only after the parent freezes this contract and delegates a bounded write-scope.

Acceptance protocol for generator outputs

Parent acceptance is explicit, never implicit. A delegated output is accepted only if all of the following are true:

  • only allowed zones were modified
  • the frozen contract is respected
  • there are no unauthorized cross-layer edits
  • the output is integration-ready
  • relevant validation or build checks were attempted where applicable
  • unresolved issues are surfaced explicitly

Failure handling:

  • allow at most one bounded repair pass for a rejected generator output
  • reject explicitly if the output is still not usable after that pass
  • use manual fallback only after explicit rejection, never as a silent completion of half-finished delegated work

Role guidance

  • explorer
    • use first for codebase discovery, file/symbol tracing, scaffold inspection, and local evidence gathering
  • docs_researcher
    • use for official documentation verification, framework semantics, and version-sensitive claims
  • generator_prisma
    • launch after contract freeze when schema/model artifacts need generation or repair
  • generator_nest_resources
    • launch after contract freeze when backend resource modules need generation or repair
  • generator_react_admin_resources
    • launch after contract freeze when frontend resource views and registrations need generation or repair
  • generator_data_access
    • launch after contract freeze when React Admin to backend integration seams need generation or repair
  • reviewer
    • use only after parent integration and validation, as the final correctness/security/test-gap review gate

Documentation-first rule for parent planning

Before the parent designs or repairs framework-sensitive shared seams, it must review current official documentation rather than relying on memory alone.

Use Context7 first for:

  • React Admin authProvider and dataProvider expectations
  • NestJS modules, controllers, providers, guards, and auth attachment patterns
  • Prisma schema and relation behavior
  • Vite, Docker, and nginx behavior relevant to scaffold/runtime work
  • Keycloak, OIDC, JWT, and JWKS integration guidance when available

Use external web research only for current, unstable, or missing documentation details. Parent auth, data-access, and runtime planning must not be done purely from memory when framework-specific guidance matters.


Generation workflow (required sequence)

  1. For a repo-wide full regeneration driven by prompts/general-prompt.md, start from the Tier 1/Tier 2 contract without pre-existing Tier 3 app/runtime outputs. In that mode, server/, client/, db-seed/, and root runtime artifacts such as docker-compose.yml and toir-realm.json are recreated; they are not prerequisites.
  2. Read AGENTS.md and prompts/general-prompt.md.
  3. Run discovery first with explorer and verify framework-sensitive behavior with docs_researcher before designing shared seams.
  4. Read the active api API.<EntityName> block + its DTOs + its enums from domain/toir.api.dsl (entity-scoped — do not inject the full DSL as a blob).
  5. Load the companion rule files required for the active stage:
    • prompts/prisma-rules.md
    • prompts/backend-rules.md
    • prompts/frontend-rules.md
    • prompts/auth-rules.md
    • prompts/runtime-rules.md
    • prompts/validation-rules.md
  6. Freeze a normalized structured contract and bounded write-zones before launching any specialized generator.
  7. Verify or repair framework scaffolds before domain generation:
    • official Nest CLI for backend workspace creation/repair
    • official Vite React TypeScript CLI for frontend workspace creation/repair
    • official Prisma CLI when Prisma initialization or repair is required
  8. Parent generates shared auth platform skeleton and deploy/runtime skeleton per prompts/auth-rules.md and prompts/runtime-rules.md.
  9. Launch specialized generators after contract freeze, in parallel when safe:
    • generator_prisma for server/prisma/schema.prisma
    • generator_nest_resources for backend resource modules
    • generator_react_admin_resources for frontend resource modules
    • generator_data_access for client/src/dataProvider.ts
  10. Accept or reject each delegated output using the acceptance protocol above. Only after acceptance may the parent integrate results.
  11. Refresh api-summary.json only when validation/tooling requires the auxiliary freshness artifact: npm run generate:api-summary.
  12. Run: node tools/validate-generation.mjs --artifacts-only
  13. Run: npm run eval:generation
  14. Fix all failures before considering the task complete.
  15. Hand the final integrated result to reviewer before claiming completion.

Context budget rule: Before generating any DTO or component, quote the field definitions from the DSL api block verbatim, then generate from those quotes. This prevents training-data contamination. See prompts/general-prompt.md.


Type mappings

DSL type Prisma type TS DTO type React Admin component
uuid String @id @default(uuid()) string TextInput / TextField
string String string TextInput / TextField
text String string TextInput / TextField
integer Int number NumberInput / NumberField
number Float number NumberInput / NumberField
decimal Decimal string NumberInput / NumberField
date DateTime string DateInput / DateField
boolean Boolean boolean (appropriate boolean input)
enum name enum name string SelectInput / SelectField

Naming conventions

Resource name (plural, kebab-case):

  • Equipmentequipment (irregular — stays as-is)
  • EquipmentTypeequipment-types
  • RepairOrderrepair-orders
  • General: PascalCase → kebab-case → append s (or es if ends in s; irregular cases explicit)

Default sort field (when not declared in api.dsl): Priority: inventoryNumber > number > code > name > primary key


Verification gate (two-stage)

Stage 1 — Structural gate

node tools/validate-generation.mjs --artifacts-only

Checks: scaffold/build readiness, required runtime/deploy artifact presence, api-summary freshness, auth seam contracts, realm structure, env/runtime contract, Docker/nginx/compose invariants, and whether build verification ran or was explicitly skipped. This gate validates the post-generation repository state. It is not a prerequisite for the clean-slate start of a full regeneration run.

Full structural verification (requires installed node_modules):

node tools/validate-generation.mjs

Stage 2 — Eval harness (Rule 6)

npm run eval:generation

Fixture-based semantic checks from tools/eval/fixtures/. Checks: DSL fidelity, CRUD method/path behavior, DTO field coverage and decorators, natural-key semantics, FK/reference wiring, Content-Range behavior, and React Admin UX/component invariants.

Reviewed eval fixtures are the authoritative semantic gate. They may be scaffolded from source-of-truth as a helper, but a full regeneration run must not auto-rewrite the committed eval corpus as part of step 0.

See tools/eval/README.md for fixture authoring and eval-driven development workflow.

Generation is incomplete unless both stages pass.


Proven-Good Runtime References

Existing runnable runtime/deploy artifacts are baseline behavior, not disposable examples.

  • Preserve repository-proven behavior in docker-compose.yml, server/Dockerfile, client/Dockerfile, client/nginx/default.conf, server/.env.example, and client/.env.example unless the DSL, prompt contract, or an explicit task requires a change.
  • When these artifacts are regenerated, preserve still-valid production behavior such as SPA routing, /api proxying, external Keycloak, PostgreSQL topology, and container startup flow.
  • Do not claim runtime/deploy readiness from file presence alone; these artifacts remain part of completion and verification.

Prisma Migration Policy

Current repository policy:

  • server/prisma/schema.prisma is generated from the DSL and is the immediate database contract for generation runs.
  • Committed Prisma migrations are preferred but not currently required for every schema change.
  • The current repository state is accepted temporary technical debt: when server/prisma/migrations/ is absent, local/runtime flows may fall back to prisma db push; when migrations exist, runtime must use prisma migrate deploy.

Target policy:

  • Every DSL-driven schema change should produce a reviewed committed migration under server/prisma/migrations/.
  • Production/runtime execution should rely on prisma migrate deploy only, with the db push fallback removed after migration discipline is established.

Pre-commit hook

Install with npm run install-hooks. The hook runs both the structural gate and the eval harness before every commit. Commits are blocked when either fails.


Auth and runtime defaults

Full auth contract: prompts/auth-rules.md

Working defaults (do not regress to localhost):

  • Keycloak base: https://sso.greact.ru
  • Realm/client: toir / toir-frontend / toir-backend
  • Production frontend: https://toir-frontend.greact.ru
  • CORS: http://localhost:5173,https://toir-frontend.greact.ru

OpenRouter configuration

OPENAI_API_KEY=<openrouter-key>
OPENAI_BASE_URL=https://openrouter.ai/api/v1
OPENAI_MODEL=<model-id>

These variables are used by tools/api-format-to-openapi/convert.mjs --mode llm.


Reading order for generation tasks

Critical zone (load first, never drop):

  1. AGENTS.md (this file) — project governance, mutation boundaries, tier hierarchy
  2. prompts/general-prompt.md — master orchestration prompt: mission, stage ownership, delegation model, completion criteria
  3. domain/toir.api.dsl §API.<EntityName> — active api block only, plus its referenced DTOs and enums

Companion zone (load when the matching stage is active):

  1. prompts/prisma-rules.md — Prisma schema generation details
  2. prompts/backend-rules.md — NestJS generation details
  3. prompts/frontend-rules.md — React Admin generation details
  4. prompts/auth-rules.md — auth seam and realm requirements
  5. prompts/runtime-rules.md — scaffold, env, and bootstrap requirements
  6. prompts/validation-rules.md — success gate requirements

Auxiliary zone (never authoritative):

  1. api-summary.json — optional inventory/freshness artifact for validators and supporting tooling; do not use it instead of the DSL

Reference only (do not load proactively):

  • domain/dsl-spec.md — DSL syntax reference; load only if DSL is ambiguous
  • docs/generation-playbook.md — step-by-step workflow reference
  • docs/future-work.md — deferred items (Rules 7 and 8)