22 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. |
.claude/CLAUDE.md |
Claude-specific agent governance supplement. |
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:
npmonly, with committedpackage-lock.jsonfiles; do not switch the repo topnpm,yarn, orbun
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.10prismaand@prisma/client:6.16.2exactly, kept on the same versionclass-validator:0.15.1class-transformer:0.5.1jose:6.2.2reflect-metadata:0.2.2rxjs:7.8.1- backend
typescript:5.7.3
Frontend generation baseline:
reactandreact-dom:19.2.4react-adminandra-data-simple-rest:5.14.5@mui/materialand@mui/icons-material:7.3.9@emotion/react:11.14.0@emotion/styled:11.14.1vite: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.
prismaand@prisma/clientmust 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 onlygenerator_nest_resources— NestJS resource modules onlygenerator_react_admin_resources— React Admin resource UI onlygenerator_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:
explorerfor repository discovery, execution-path inspection, scaffold checks, and local seam tracingdocs_researcherfor official documentation verification and version-sensitive framework behavior- parent contract freeze and shared scaffold/auth/runtime planning
- specialized generators after contract freeze, in parallel when safe:
generator_prismagenerator_nest_resourcesgenerator_react_admin_resourcesgenerator_data_access
- parent integration and validation
revieweronly 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.jsondocker-compose.ymlserver/Dockerfileclient/Dockerfileclient/nginx/default.confserver/docker-entrypoint.shdb-seed/Dockerfiledb-seed/import.shserver/.env.exampleclient/.env.example- shared integration seams and final validation outputs explicitly delegated by prompts
Specialized generator write zones:
generator_prismaserver/prisma/schema.prisma- optional machine-readable schema summary or structured handoff artifact when the parent explicitly requests it
generator_nest_resourcesserver/src/modules/**- backend registration touchpoints only when explicitly delegated by the parent contract
generator_react_admin_resourcesclient/src/resources/**- frontend resource registration touchpoints only when explicitly delegated by the parent contract
generator_data_accessclient/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)
- 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 asdocker-compose.ymlandtoir-realm.jsonare recreated; they are not prerequisites. - Read
AGENTS.mdandprompts/general-prompt.md. - Run discovery first with
explorerand verify framework-sensitive behavior withdocs_researcherbefore designing shared seams. - Read the active
api API.<EntityName>block + its DTOs + its enums fromdomain/toir.api.dsl(entity-scoped — do not inject the full DSL as a blob). - Load the companion rule files required for the active stage:
prompts/prisma-rules.mdprompts/backend-rules.mdprompts/frontend-rules.mdprompts/auth-rules.mdprompts/runtime-rules.mdprompts/validation-rules.md
- Freeze a normalized structured contract and bounded write-zones before launching any specialized generator.
- 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
- Parent generates shared auth platform skeleton and deploy/runtime skeleton per
prompts/auth-rules.mdandprompts/runtime-rules.md. - Launch specialized generators after contract freeze, in parallel when safe:
generator_prismaforserver/prisma/schema.prismagenerator_nest_resourcesfor backend resource modulesgenerator_react_admin_resourcesfor frontend resource modulesgenerator_data_accessforclient/src/dataProvider.ts
- Accept or reject each delegated output using the acceptance protocol above. Only after acceptance may the parent integrate results.
- Refresh
api-summary.jsononly when validation/tooling requires the auxiliary freshness artifact:npm run generate:api-summary. - Run:
node tools/validate-generation.mjs --artifacts-only - Run:
npm run eval:generation - Fix all failures before considering the task complete.
- Hand the final integrated result to
reviewerbefore 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):
Equipment→equipment(irregular — stays as-is)EquipmentType→equipment-typesRepairOrder→repair-orders- General: PascalCase → kebab-case → append
s(oresif ends ins; 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, andclient/.env.exampleunless 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,
/apiproxying, 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.prismais 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 toprisma db push; when migrations exist, runtime must useprisma 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 deployonly, with thedb pushfallback 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):
AGENTS.md(this file) — project governance, mutation boundaries, tier hierarchyprompts/general-prompt.md— master orchestration prompt: mission, stage ownership, delegation model, completion criteriadomain/toir.api.dsl §API.<EntityName>— active api block only, plus its referenced DTOs and enums
Companion zone (load when the matching stage is active):
prompts/prisma-rules.md— Prisma schema generation detailsprompts/backend-rules.md— NestJS generation detailsprompts/frontend-rules.md— React Admin generation detailsprompts/auth-rules.md— auth seam and realm requirementsprompts/runtime-rules.md— scaffold, env, and bootstrap requirementsprompts/validation-rules.md— success gate requirements
Auxiliary zone (never authoritative):
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 ambiguousdocs/generation-playbook.md— step-by-step workflow referencedocs/future-work.md— deferred items (Rules 7 and 8)