Self-Repair (Self-Correcting Rules Engine)
A self-correcting memory and learning engine that records corrections, project conventions, and bug fixes into a persistent ruleset file (autofix.json). It ensures the agent continuously adapts, eliminates repeat mistakes across sessions, and adheres strictly to user preferences.
Why this works: AI agents tend to repeat the same default assumptions or stylistic errors across fresh sessions. By externalizing learned knowledge into an imperative, versioned JSON ruleset with strict precedence (newer rules win), the agent retains hard boundaries tailored to the specific user and repository.
Storage & Configuration
The skill looks for the ruleset file in one of the following locations (in order of priority):
.agents/autofix.jsonautofix.json(at workspace root).rules/autofix.json
If none exists when a new rule needs to be added, it creates .agents/autofix.json (or root autofix.json depending on project convention).
Rule Schema
Each rule is stored inside a JSON array with the following schema:
[
{
"Rule_number": 1,
"Category": "CODE",
"Instruction": "Never use default exports for React components - always use named exports.",
"Why": "Ensures consistency with the codebase and simplifies refactoring."
}
]
Allowed Categories
| Category | Description | Examples |
|---|---|---|
[STYLE] | Code formatting, naming conventions, import ordering, comments | "Always use camelCase for helper functions" |
[CODE] | Language patterns, library choices, type definitions, error handling | "Never use any in TypeScript; use unknown with type guards" |
[ARCH] | Directory structure, module boundaries, architectural layers | "API routes live in src/server/routes/, not src/api/" |
[TOOL] | CLI commands, build tools, package managers, testing frameworks | "Always use pnpm instead of npm or yarn" |
[PROCESS] | Git workflow, commit messages, PR requirements, test gates | "Never add emojis to commit messages" |
[DATA] | Database schemas, migrations, caching strategies, state shapes | "Always include created_at and updated_at timestamps on tables" |
[UX] | UI behaviors, copy conventions, accessibility standards | "Always provide an explicit aria-label for icon-only buttons" |
[OTHER] | General project or domain-specific preferences | "Always document public API endpoints in markdown table format" |
Operational Workflow
[Session Start / Task Received]
│
▼
┌───────────────────────────────┐
│ 1. Pre-Task Scan │ ◄── Read autofix.json
│ - Load all rules │
│ - Resolve conflicts (new>old)
│ - Build active constraints │
└───────────┬───────────────────┘
│
▼
┌───────────────────────────────┐
│ 2. Task Execution │
│ - Apply constraints │
│ - Execute code / edits │
└───────────┬───────────────────┘
│
├─────────────────────────────────────────┐
│ │
[No Corrections] [Trigger Detected]
│ │
▼ ▼
┌───────────────────────────────┐ ┌───────────────────────────────┐
│ Task Complete │ │ 3. Self-Repair & Capture │
│ Deliver output to user │ │ - Formulate imperative rule│
└───────────────────────────────┘ │ - Append to autofix.json │
│ - Acknowledge learning │
└─────────────┬─────────────────┘
│
▼
┌───────────────────────────────┐
│ 4. Re-execute & Correct │
│ Fix current task output │
└───────────────────────────────┘
Detailed Step-by-Step Execution
1. Pre-Task Scan (Before Doing Anything)
Before planning or modifying files in any task:
- Locate and load
autofix.json. - Scan the rules:
- Check if any rule directly applies to the files, tools, or patterns involved in the current prompt.
- Resolve conflicts:
- If two rules give conflicting guidance, the higher-numbered (newer) rule wins.
- Hold constraints active:
- Treat all active rules as hard constraints (equivalent to prompt contract
CONSTRAINTS).
- Treat all active rules as hard constraints (equivalent to prompt contract
2. When to Add a Rule (Trigger Conditions)
Immediately trigger rule capture when any of the following happens:
- User explicitly corrects output: e.g., "No, don't use X, do it with Y", "We don't use class components here".
- User rejects a file, approach, or pattern: e.g., "Don't put test files next to source code".
- User states a personal/team preference: e.g., "Always format commit messages as Conventional Commits", "Never use emojis in docs".
- A bug was caused by wrong assumptions: Agent assumed a library or file location that caused a failure.
- User runs
/learnor asks to remember a rule.
3. Appending a New Rule
When a trigger occurs, perform the following atomic update:
- Read the existing
autofix.jsonarray. - Determine the next sequential
Rule_number:- If the highest existing rule number is $N$, the new rule is $N + 1$.
- If the file is empty or new, start at
1.
- Format the new rule object:
- Rule_number: Sequential integer.
- Category: One of the standard categories (
STYLE,CODE,ARCH,TOOL,PROCESS,DATA,UX,OTHER). - Instruction: Written in strict imperative format:
"Never/Always do X - because Y." - Why: Brief reason (e.g. "user preference", "codebase pattern", "framework limitation").
- Append the rule into the JSON array and save the file formatted with 2-space indentation.
- Never delete existing rules. If an old rule is superseded, write the new rule so that its higher number takes precedence.
- Briefly notify the user:
"Learned rule #
<N>([CATEGORY]):<Instruction>— recorded inautofix.json."
4. Example Rules File (autofix.json)
[
{
"Rule_number": 1,
"Category": "PROCESS",
"Instruction": "Never add emojis to commit messages - keep commit titles plain Conventional Commits.",
"Why": "user preference"
},
{
"Rule_number": 2,
"Category": "ARCH",
"Instruction": "Always place API route handlers in 'src/server/routes/', never in 'src/api/' - maintain consistent backend architecture.",
"Why": "existing codebase pattern"
},
{
"Rule_number": 3,
"Category": "CODE",
"Instruction": "Always use Zod schemas for input validation on all external entry points - prevent untyped runtime inputs.",
"Why": "prevents runtime errors and enforces types"
}
]
Best Practices & Edge Cases
- Atomic JSON Writing: Always parse the existing JSON array, append the new object, and write back valid JSON. Never corrupt the file with unescaped text.
- Concrete & Imperative: Write rules that another AI can follow unambiguously. Avoid vague advice like "Write clean code"; prefer "Always export types alongside component implementations in
.types.tsfiles". - No Infinite Loops: When recording a rule, do not trigger a separate self-repair loop for the rule file itself.
- Superseding Rules: If Rule 1 says "Use Axios" and the user later instructs "Migrate everything to Fetch", add Rule 4 "Always use native Fetch instead of Axios" with
Why: "user requested migration to native fetch (supersedes Rule 1)".