Installs into .claude/skills of the current project.
Are you the author of Aif Docs?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/maister-dev-aif-docs-maister)
# Project Rules for /aif-docs
> Auto-generated by `/aif-evolve`. Do not edit manually.
> Last updated: 2026-09-04
> Based on: /aif-evolve 114-patch batch (2026-07-11, cursor 2026-06-16 → 2026-07-07)
> + /aif-evolve 74-patch batch (2026-09-04, cursor 2026-07-07 → 2026-09-04)
## Rules
### Classify historical vs current before editing
**Source**: 2026-06-27-17.08, 2026-06-23-14.56
**Rule**: Before rewriting any doc hit found by a sweep, classify it: **frozen-historical** (pre-change ADR bodies, dated findings/review docs — they describe the PAST and STAY; rewriting them falsifies history; annotate with a supersession pointer instead) vs **current-contract** (docs stating "what is true now" — these get rewritten). ADR history is immutable — a superseded ADR gets a pointer, never an edit. After ADR-affecting edits, re-run `validate:docs:adr:all` — every new anchor link must resolve.
2026-07..09 additions: a frozen planning artifact or spec (a 2026-06 spec whose §5 was replaced by ADR-106/125) is never edited as current guidance — cross-reference the canonical contract (`execution-policy.md`) and add a supersession BANNER naming the replacing ADRs instead of rewriting the body; an ADR's recorded count ("12 types" in ADR-077) stays with a pointer.
**Source (additions)**: 2026-09-03-17.21, 2026-07-16-14.05
### Sweep mechanics: both directions, both cases, wrap-tolerant, cited homes
**Source**: 2026-07-02-14.14, 2026-07-01-12.55, 2026-06-27-17.08, 2026-07-04-14.15-brain-review-followup, 2026-06-25-17.42
**Rule**: OpenAPI reconciliation sweeps BOTH directions — phantom params the code never reads (an `hitl_inbox` `limit`/`offset` the handler ignores) AND fields the spec lost but code returns; code wins per docs R3. Column-name greps try BOTH snake_case and the Drizzle camelCase field name (`database-schema.md` documents camelCase — a snake-only grep yields false "missing column" findings). Verify claims with single-line AND whitespace-tolerant patterns (`grep -z` / multi-line) — a load-bearing sentence wrapped across two lines evades a naive grep. When a doc cites another doc as the SSOT home for a topic, update that cited home in the SAME pass — a cross-reference to a doc that never mentions the feature is drift. Patch OpenAPI response-body parity by `operationId`/route block — replacing repeated `$ref`s without route context touches unrelated operations; run `git --no-pager diff -- docs/api/*.yaml` before validation. Attribute changes to migrations only for real DDL — a Drizzle `text({enum})` widening is app-level (no Postgres CHECK → no migration); citing a migration number for it is drift.
2026-07..09 additions: a table DROP is a contract-WIDE sweep of `database-schema.md` — the cascade tree, the index catalog AND the narrative drift independently (a self-contradicting file with a drop narrative plus "Implemented" index rows is the tell), and ERDs gain the additive columns. After spec edits prove every internal `$ref` resolves (262 checked) — a dangling ref is the obvious way to "fix" a spec into being broken. Sequence diagrams show the REAL branch ORDER (lock assert → stale check → validation → CAS) and a flat spread response is documented flat. When a code fix changes the event/trigger an interceptor keys on, `git grep` the OLD trigger phrase (`"never arbitrated"`, `` `tool_call` ``) across `docs/` acceptance bullets, mechanics prose and the ADR — a stale acceptance bullet reads as a reviewed invariant.
**Source (additions)**: 2026-07-25-11.14, 2026-07-16-15.20, 2026-07-21-23.50, 2026-07-12-10.43
### Status flips sweep every surface carrying the tag
**Source**: 2026-06-18-23.21, 2026-06-23-14.56, 2026-06-23-18.25, 2026-06-20-07.30, 2026-07-01-12.55
**Rule**: When a feature ships, grep the feature name AND its ADR number across the whole `docs/` tree INCLUDING `*.openapi.yaml` `summary`/`description` fields, screens docs, and analytics docs for the old `Designed` status word — OpenAPI status tags are the classic straggler (4 stale `ADR-105 — Designed` fork tags; `Designed (inbox card redesign)` left in `web.openapi.yaml`). Tag not-yet-emitted wire shapes `(Designed — <milestone> Phase N, not yet emitted)` — never live present tense for unbuilt emits, and no present-progressive prose under an `Implemented` tag. Superseding a section retires the old prose in the SAME edit — a deleted symbol name left in an "Implemented" section is a self-contradiction; every doc cross-reference must resolve to a file that actually carries the cited value.
2026-07..09 additions: when the UI phase of a feature lands after its backend merged, RE-RUN the as-built reconcile in the same change — a prior phase's reconcile cannot cover surfaces that did not exist yet; grep the docs tree for the feature's `Designed`/`Follow-up` tags before declaring done. A bulk flip reports the FORMS it covered, not a count: `| Designed |` in an index-table cell is a different form from `(Designed — ADR-x)` in prose — grep the OLD value afterwards and classify every remaining hit. After a provenance renumber, STATUS LABELS (`Designed`/`Accepted` → `Implemented`) and code comments are part of the grep-to-zero surface, and an ADR's Consequences paragraph cross-checks its body. A canonical `docs/system-analytics/*` artifact is an as-built surface: "planned"/"Designed" wording on shipped routes is a contract lie.
**Source (additions)**: 2026-07-12-22.40, 2026-08-06-19.10, 2026-07-24-15.19, 2026-07-27-11.00
### Translated docs keep lifecycle and gate fidelity
**Source**: 2026-07-07-11.40
**Rule**: When creating or compressing translated docs (RU), compare lifecycle tables against the canonical Mermaid state machine, not README summaries (the RU docs dropped the `HumanWorking` and `Failed` run statuses). Preserve operational gates and prerequisites even in short translations: package trust enables the setup/enablement lifecycle (not arbitrary runtime rights); readiness-gated runners (gemini/opencode/mimo) cite supervisor diagnostics + cached ACP smoke evidence; `local_merge` promotion needs no provider prerequisites while `pull_request` does. After adding or compressing translations, run an EN→RU drift audit pass.
### In-code SSOTs shipped to agents are documentation surfaces
**Source**: 2026-07-01-11.19, 2026-06-25-16.55-flow-assistant-review-fixes
**Rule**: Grammar/prompt/skill files delivered to agents (`flow-dsl-grammar.ts` — shown to the Studio assistant every turn and shipped as the `/flow-authoring` skill — plus assistant personas) are doc surfaces: when the DSL/schema/layout they teach changes, update them AND their drift-guard tests in the SAME change; a `docs/`-only sweep misses them. Keep assistant prompt examples aligned with runtime validators — docs taught flat `flows/<id>.yaml` while `validatePackageArtifacts`/installation recognize `flows/<id>/flow.yaml`; add a small regression test for canonical generated paths whenever prompt docs teach file layout.
2026-07..09 additions: an engine bump updates the agent-facing DSL grammar (`settings.plan_review` + its floor) and the current host-version docs in the same change as the constant, compatibility tests and fixtures (3.1.0 shipped with grammar and docs asserting 3.0.0). Agent-facing topology files (`.ai-factory/DESCRIPTION.md`, root `CLAUDE.md`) state the truth (the supervisor shares the host); prose retention windows ("7d") are checked against the config constant (`DEFAULT_GC_AGE_DAYS = 14`) before being repeated.
**Source (additions)**: 2026-07-15-12.41-engine-3.1-and-product-contract-sweep, 2026-09-04-00.21, 2026-07-18-14.55
### Expectations name their enforcement; motivation never becomes contract prose; rationales match mechanisms
**Source**: 2026-07-27-09.30, 2026-08-01-09.09, 2026-07-12-10.43, 2026-07-16-14.05, 2026-07-16-16.05, 2026-09-03-17.20, 2026-09-03-15.37
**Rule**: Every Expectation bullet (and every MUST in an ADR or analytics doc) NAMES what enforces it — a constraint, a CAS, a singleton, a load gate, a test; a MUST that cannot point at one is a wish: weaken it to the scope the mechanism covers ("summon-vs-summon, serialized by `domainEventDispatch: 1` + the CAS lease") or add the mechanism. Never let MOTIVATION prose become CONTRACT prose — an ADR's "so the caller learns whether its summon was accepted" copied into an Expectation and an OpenAPI operation description became a false promise; when a schema carries a qualifier ("a report, not a guarantee") the OPERATION description that returns it carries the same qualifier (callers read the operation, not the component). An ASYMMETRIC boolean (`false` hard negative, `true` weak) documents both arms. A rationale that names a mechanism is checked against it: an INVERTED rationale ("target-scoped fetch" as why a lease is safe, documented 8×, while the code is safe for the opposite reason) leads a reader to remove the real guard; a rationale naming a column nothing reads (`pr_state_checked_at`) is drift. When spec PROSE and a spec TABLE disagree, reconcile them — the prose usually carries the reasoning, the table the shortcut. Document an enforcement BOUNDARY where the reader stands (which calls the seam sees, what the backstop covers) as an Edge-cases bullet plus a comment at the exact check; record invariants such as "a refused tree-cancel MUST NOT cascade; a lost CAS after a cascade MUST be surfaced (409 or WARN), never a silent skip" in the domain's Edge cases. Record rejected alternatives with their reason.
### Read-surface sweep on stored-form changes; JSON-Schema and MCP description precision
**Source**: 2026-07-27-09.30, 2026-08-06-19.10, 2026-07-27-20.55, 2026-07-16-16.40, 2026-07-25-11.14
**Rule**: When a write path starts persisting a new textual representation (`[@<id>](/agents/<id>)` mention markers — `/agents/<id>` is not a route), every DTO that returns that text is in scope in the SAME pass (`TaskCommentDTO`, ext `CommentDTO`, MCP `comment_list`) — thorough request-side docs are what make the read-side gap invisible. MCP tool descriptions explain a null field (`relation_list` null title = redacted foreign project, not missing data) so a model does not retry; MCP `inputSchema` uses JSON-Schema forms (`type: ["string","null"]`), never the OpenAPI-only `nullable: true`. OpenAPI `format: uuid` where zod is `z.string().min(1)`, index names that differ from DDL, and mermaid transition labels stating the wrong trigger are drift; response-shape-vs-code drift is INVISIBLE to `validate:contracts` — after porting or re-authoring a schema, diff it field-by-field against the handler's return and the pre-port version.
### Operational docs: verify-before-destroy, component responsibilities, and one authoritative roadmap section
**Source**: 2026-08-01-09.09, 2026-07-13-01.45-test-database-review-findings, 2026-07-17-00.10-workspace-lifecycle-review-remediation, 2026-07-15-12.41-engine-3.1-and-product-contract-sweep, 2026-07-16-13.06, 2026-07-16-15.20
**Rule**: When a doc gives a destructive command next to a discovery filter that also matches LIVE resources (a shared `maister-run-` prefix), the verify-terminal-before-destroy step belongs IN the doc (discovery listing → verify terminal → down one resource; never prefix-wide). State explicitly which component performs each migration/seed/teardown action (wrapper vs helper vs preparation command) and treat service-level failure and per-candidate retry as distinct documented outcomes. Route-level error docs describe the DURABLE state returned after dispatch, not an upstream status the route absorbs. An env-var entry lists EVERY reader (`MAISTER_PROMOTION_CLAIM_TIMEOUT_SECONDS` also drives `canReclaimLifecycle` and the sync heartbeat at `window/4`). Keep shipped history intact, but put CURRENT sequencing and validation gates in ONE authoritative roadmap section — mixed frozen history and current status makes stale planning language look authoritative.