---
name: aif-rules-check
description: Run a standalone read-only rules compliance gate against changed files or a git ref. Use when you need a dedicated project-rules check without a full review or verify pass.
argument-hint: "[git ref | empty]"
allowed-tools: Read Glob Grep Bash(git *) AskUserQuestion
disable-model-invocation: false
metadata:
author: AI Factory
version: "1.0"
category: quality
---
# Rules Compliance Gate
Run a standalone read-only rules gate for project rules. This command checks rule compliance only; it does not replace `/aif-review` or `/aif-verify`.
## Step 0: Load Contract
- Read `references/RULES-CHECK-CONTRACT.md` first.
- Treat it as the canonical source for verdict semantics and report structure.
- If examples in this file drift from the reference, follow the reference.
## Step 1: Load Config
**FIRST:** Read `.ai-factory/config.yaml` if it exists to resolve:
- `paths.rules_file`
- `paths.rules`
- `paths.plan`
- `paths.plans`
- `language.ui`
- `git.enabled`
- `git.base_branch`
- `rules.base`
- named `rules.` entries
- `workflow.plan_id_format` (default: `slug`) — used by the optional branch-based plan-context lookup in Step 2.3.
Active values: `slug` and `sequential`. Plan context may be a root full-plan
file or direct child ultra `index.md`; numbered lookup covers both shapes.
`timestamp` and `uuid` are **reserved values** and currently behave like `slug`.
Treat any unknown value as `slug`.
If config is missing or partial, use defaults:
- `paths.rules_file`: `.ai-factory/RULES.md`
- `paths.rules`: `.ai-factory/rules/`
- `paths.plan`: `.ai-factory/PLAN.md`
- `paths.plans`: `.ai-factory/plans/`
- `git.enabled`: `true`
- `git.base_branch`: detect the repo default branch from git metadata; fall back to `main` only when detection is unavailable
- `rules.base`: `.ai-factory/rules/base.md`
- `workflow.plan_id_format`: `slug`
If `paths.rules_file` is missing from config, default to `.ai-factory/RULES.md` instead of treating config as incomplete.
If `git.base_branch` is missing from config, resolve the repository default branch from git metadata when possible; use `main` only as the final fallback.
### Step 1.1: Load Skill Context
**Read `.ai-factory/skill-context/aif-rules-check/SKILL.md`** - MANDATORY if the file exists.
This file contains project-specific rules accumulated by `/aif-evolve` from patches,
codebase conventions, and tech-stack analysis. These rules are tailored to the current project.
**How to apply skill-context rules:**
- Treat them as project-level overrides for this skill's general instructions.
- When a skill-context rule conflicts with a general rule in this file, the skill-context rule wins.
- When there is no conflict, apply both.
- Skill-context rules apply to all outputs of this skill, including verdict wording and report structure.
**Enforcement:** Before presenting the final report, verify it against all skill-context rules and fix any drift.
## Step 2: Resolve Inputs
Resolve two inputs before checking any rule:
1. **Changed scope** - the diff and file list you are evaluating
2. **Resolved rule sources** - the rule artifacts that may apply to that scope
### Step 2.1: Resolve Changed Scope
**If the user provided a git ref:**
1. Validate it first:
```bash
git rev-parse --verify
```
2. If valid, use:
```bash
git diff --name-only ...HEAD
git diff ...HEAD
```
3. If invalid, ask:
```
AskUserQuestion: `` is not a valid git ref. What should I check instead?
Options:
1. Check staged / working-tree changes
2. Cancel
```
**Without arguments:**
1. Prefer staged work:
```bash
git diff --cached --name-only
git diff --cached
```
2. If nothing is staged, fall back to working tree:
```bash
git diff --name-only
git diff
```
3. If there is still no local diff and `git.enabled = true`, fall back to branch diff:
```bash
git diff --name-only ...HEAD
git diff ...HEAD
```
If there are still no changed files, return `WARN` rather than a hard failure.
### Step 2.2: Resolve Rule Sources
Load rule sources in this order:
1. The resolved `paths.rules_file` artifact
2. The resolved `rules.base` file
3. Any named `rules.` files from config that clearly match the changed scope
Area rules are optional and scoped:
- Use changed file paths, folder names, and optional plan context to judge relevance.
- If relevance is ambiguous, mention the rule source as uncertain and keep the outcome at `WARN`, not `FAIL`.
If no rules sources resolve, return `WARN` rather than a hard failure.
### Step 2.3: Optional Plan Context
Optional plan context: use the active plan file only when it helps interpret scope or area relevance; absence of a plan is never a failure.
Plan resolution order:
1. Compute the **canonical branch stem** the same way as `/aif-plan`,
`/aif-implement`, and `/aif-improve`:
- get current branch via `git branch --show-current` (git mode only);
- `branch_stem` = current branch with every `/` replaced by `-`
(for example `feature/user-auth` → `feature-user-auth`).
2. Branch-based lookup using ``:
- when `workflow.plan_id_format = sequential`, glob both
`paths.plans/[0-9][0-9][0-9][0-9]_.md` and
`paths.plans/[0-9][0-9][0-9][0-9]_/index.md`; Read every
directory candidate and retain it only when it contains exactly one
``, then pick the highest-numbered valid
artifact and warn when multiple valid candidates exist; prefer ultra if
both shapes share the highest prefix;
- otherwise/fallback check `paths.plans//index.md` and
`paths.plans/.md`; Read the directory entrypoint first, ignore
it unless it contains exactly one ultra marker, and warn/prefer ultra if
both valid shapes exist.
3. A single named artifact in `paths.plans`: count root `*.md` full plans and
direct child `*/index.md` entrypoints containing
``; exclude
the resolved fast-plan path and never count phase files.
4. The fast plan at `paths.plan`.
For ultra, read `index.md` first and only the linked phase files relevant to the
changed area when extra scope detail is needed. Do not fail the rules check
because a plan artifact is missing or ambiguous.
An automatically discovered directory entrypoint counts only when it contains
exactly one ``; ignore unrelated `*/index.md` files.
## Step 3: Evaluate Rules
Read the changed files from the resolved scope and compare them against the resolved rules.
Classification rules:
- `PASS` when at least one applicable rule was checked and no clear violations were found.
- `WARN` when no applicable rules were resolved, the evidence is ambiguous, or there are no changed files to evaluate.
- `FAIL` when an explicit hard rule is clearly violated by the inspected diff or changed files.
Only return `FAIL` when an explicit hard rule is clearly violated by the inspected diff or changed files.
Evidence rules:
- Tie every blocking violation to specific rule text and at least one concrete file/path or diff hunk.
- If a rule sounds like a preference, is too vague, or cannot be verified confidently from the diff, do not escalate it past `WARN`.
- Missing optional files or partially configured rules hierarchy are `WARN`, not `FAIL`.
## Step 4: Read-Only Boundary
This command is read-only: do not edit `RULES.md`, `rules/base.md`, `rules.`, plan files, or source code.
If rules are missing, stale, or need refinement:
- Suggest `/aif-rules ` for axioms
- Suggest `/aif-rules area:` for area-specific rules
## Step 5: Output
Use the exact verdict semantics and section order from `references/RULES-CHECK-CONTRACT.md`.
Required content:
- overall verdict
- files checked
- gate results
- blocking violations
- suggested fixes
- suggested rule updates
- final machine-readable `aif-gate-result` fenced JSON block
When useful, suggest the next best workflow:
- `/aif-review` for broader code review
- `/aif-verify` for full plan-completeness verification
- `/aif-rules` when the underlying rules need to be captured or corrected
Machine-readable gate result:
- Append one final fenced `aif-gate-result` JSON block after the human-readable rules report.
- Use `"gate": "rules"`.
- Map the human rules verdict exactly: `PASS` -> `pass`, `WARN` -> `warn`, and `FAIL` -> `fail`.
- Use `"blocking": true|false`; set it to `true` only for explicit hard-rule violations that produce a human `FAIL`.
- Include only hard-rule violations in `"blockers": [`.
- Include changed or inspected paths in `"affected_files": [`.
- Set `"suggested_next": {` to `/aif-rules` when rules should be added or clarified, `/aif-fix` when code must change, or `null` when no allowed next command fits.
- Do not use `/aif-review` in the JSON `suggested_next.command`; it may appear only in human-readable workflow suggestions.
```aif-gate-result
{
"schema_version": 1,
"gate": "rules",
"status": "warn",
"blocking": false,
"blockers": [],
"affected_files": [],
"suggested_next": {
"command": "/aif-rules",
"reason": "Rules are missing or ambiguous for the changed scope."
}
}
```
Schema reminder: `"status": "pass|warn|fail"`, `"blocking": true|false`, `"blockers": [`, `"affected_files": [`, `"suggested_next": {`.