Why does CI keep failing on mistakes you have seen before?
CI runs a project’s checks on every change, in the cloud, before the change can merge. When it fails, someone reads the log, fixes the change, pushes again and waits again. With several coding agents pushing to one project, that loop can repeat many times a day.
We went through the failed GitHub Actions runs in our own repositories from 24 August to 23 October 2026 and sorted each one by what caused it:
In our own repositories: 497 failed CI runs. Only about 1 in 20 was a new bug. About 3 in 10 repeated a known mistake. They cost about two-thirds of what failures wasted. For about half, the lesson was already written down.
- What counts as a run: each failed attempt counts, so a re-run that failed again counts twice.
- Most of the rest had nothing to do with the change being tested: runs that never started because of the Actions budget or a failed payment, Dependabot update jobs, new security advisories, and flaky tests.
- What “failures wasted” means: the Actions time spent on failed runs and on the re-runs they forced, priced at GitHub’s list prices. It is not our bill.
- What this is: one team’s repositories over two months, classified by us. It is not a benchmark, and it says nothing about your repositories.
Why is writing the lesson down not enough?
For about half of the repeated mistakes, the lesson had been written down before the failure, mostly in a coding agent’s own memory notes, sometimes in the project brain. The next session still made the mistake.
A written lesson works only if the right session reads it at the right moment and remembers it while it edits a file. Instruction files grow, sessions start fresh, and one agent’s private notes never reach another agent or a teammate. Nothing checked the lesson against the change.
Some lessons can be checked mechanically. A new route that is missing from the server’s route list, a test file that never got wired into the test command, a file whose line endings a Windows editor rewrote: each of these is visible in the diff. Those are the lessons worth turning into checks.
The other lessons still have to reach the right session. In Klypix, when a session tells brain_sync which files it plans to change, up to four lessons that name those files come first in what it gets back, under “Lessons for your files”.
How do lessons become checks?
In Klypix, agents and people record lessons in the project brain while they work. A lesson that names a file and a pattern can become a project rule: a small, deterministic check over the diff. No model runs when a rule is checked; it is file-name, pattern and line-ending work, and it runs on your computer.
| Kind | What it catches | Example lesson |
|---|---|---|
listed-in | A new file, or a new line matching a pattern, that must also appear in a registry file | Every new route must be in the route list |
forbid-pattern | An added line that matches a pattern in the files the rule covers | Tests in this folder must not import @/… |
preserve-eol | A change that rewrites a file’s line endings | A test pins the bytes of a file with mixed line endings |
cloud-required | A change to paths that start the expensive CI jobs (advice only) | Changing the lockfile starts the full build matrix |
The same rule runs at three points:
- When the agent plans.
brain_syncnames the rules for the files in the session’s scope, with the fix and the lesson. - When the agent edits. In Claude Code and Codex the warning names the file, the line and the fix. Codex gets the warning but cannot be stopped mid-edit.
- When anyone commits. An opt-in git pre-commit and pre-push hook checks the change for every tool and every person.
Rules live in the repository, in .klypix/rules.json, and each one cites the lesson it came from.
What does an agent see?
Here is a made-up web app. Its routes live in web/src/App.tsx, and the server keeps a list of known routes. A lesson in its brain says that every new route must also be listed on the server, or a direct link to it returns 404. That lesson was approved as the rule routes-registered. This is the real output of klypix-mcp on that project.
An agent declares that it will change web/src/App.tsx, and brain_sync tells it:
KLYPIX project rules for the files in your scope (from this brain's lessons; checked again on each edit and before commit):
- ⚠ web/src/App.tsx: Every new route in App.tsx must also be listed in known-routes.ts, or a direct link to it returns 404. Fix: Add "the new entry" to KNOWN_ROUTES in server/src/routes/known-routes.ts. (rule routes-registered, lesson txt_routes_lesson)The agent adds a /reports route but forgets the server list. The check names the line and the fix:
$ npx klypix-mcp check
KLYPIX project rules (.klypix/rules.json):
⚠ WARNING — project rule `routes-registered` (lesson txt_routes_lesson)
Found: web/src/App.tsx:11 adds `<Route path="/reports"`, but `"/reports"` is not in server/src/routes/known-routes.ts
Why: Every new route in App.tsx must also be listed in known-routes.ts, or a direct link to it returns 404.
Fix: Add "/reports" to KNOWN_ROUTES in server/src/routes/known-routes.ts.The agent adds "/reports" to the server list, and the next check passes:
$ npx klypix-mcp check
KLYPIX project rules: all pass.Who decides what becomes a rule?
A person does. An agent can draft a rule from a lesson, but a draft is a candidate and checks nothing.
- Propose. An agent calls
brain_rulesto sort the brain’s lessons into checkable rules, instructions and notes, and drafts the checkable ones. - Approve. In their own terminal, the person runs
npx klypix-mcp rules code promote <rule>. It prints the rule in full and a short code to give the agent. The command refuses to run in an agent’s shell, so an agent cannot approve its own rule by accident. - Choose warn or block. Approved rules warn. Adding
--blockwhen approving makes the rule stop the commit or push where the git hooks are on and, in Claude Code, a forbidden line before it is written. - Commit the rules file.
.klypix/rules.jsonreaches every clone, and changes to it show up in review.
Exceptions stay on the record. One-hour overrides, commits that skipped a blocking rule and false alarms become cards in the brain, and npx klypix-mcp rules shows how often each rule fired, was overridden or was reported as a false alarm on that computer, so a rule that does not earn its place can be narrowed or retired.
How do other approaches compare?
| Approach | When it acts | How it decides | Where it lives | Main limitation |
|---|---|---|---|---|
Rules files (AGENTS.md, CLAUDE.md) | When an agent reads the file, usually at the start of a session | The agent follows the instruction | Plain text in Git | Nothing checks that the instruction was followed |
| Hooks you write (Claude Code hooks; git hooks with pre-commit, Husky or Lefthook) | Before a tool call (a Claude Code PreToolUse hook can deny it), or before a commit | Whatever your script checks; deterministic | Settings and hook files, often in the repository | Every check is written and maintained by hand, and nothing links it to the lesson behind it |
| Linters and static analysis (ESLint custom rules, Semgrep) | In the editor, before a commit and in CI | Deterministic, and aware of the language’s syntax | Configuration in the repository | Rules are written by hand, per language, and focus on patterns in code |
| AI review that learns from feedback (Cursor Bugbot, CodeRabbit, Greptile, Qodo) | Mostly on the pull request, after it is opened; CodeRabbit also reviews local changes from its CLI and editor extension | A model reviews the change, guided by rules learned from reactions, replies and accepted suggestions; it can catch problems no fixed pattern describes | Mostly in the vendor’s service (Cursor and CodeRabbit have dashboards); Qodo also reads a best_practices.md file in the repository | Reviews a change after it is written, mostly on the pull request; a learned rule guides the model’s review rather than running as a fixed check |
| GitHub Copilot Memory | When Copilot’s cloud agent, code review or CLI works on the repository | Repository facts, with citations checked against the current branch before use | GitHub; unused memories are deleted after 28 days | Guides Copilot’s own features rather than checking a change |
| Klypix project rules | When the agent plans, edits (Claude Code and Codex) and commits | Deterministic checks over the diff, each approved by a person | .klypix/rules.json in the repository, each rule citing its lesson in the project brain | Only lessons that can be checked in a diff; edit-time warnings only in Claude Code and Codex |
These fit together. A linter knows your language, an AI reviewer can judge a change no rule describes, and a project rule carries a lesson your team already learned into the next session that touches the same files.
What does it not do?
- It does not replace CI. A rule reads the diff. It does not run tests, type checks or builds.
- It covers only some lessons. Many lessons are about how to work or need judgement; they stay instructions or notes. New bugs, flaky tests and infrastructure failures are outside rules.
- It is as good as its pattern. A rule written for fixed paths leaves other cases alone.
- Edit-time warnings are for Claude Code and Codex. Other tools get the planning notice through
brain_syncand the opt-in commit hook. - The commit hooks are opt-in per clone. A clone without them still gets the planning and editing warnings.
- Approval codes prevent accidents, not determined misuse. Review of
.klypix/rules.jsonand the bypass cards are the backstop.
Try it on one project
Project rules ship in the open-source klypix-mcp engine, version 1.107.1 or later. In a project with a brain, set it up once:
npx klypix-mcp installAsk your agent to propose rules from the brain’s lessons with brain_rules, approve the ones you want in your own terminal, commit .klypix/rules.json, and turn on the commit hooks in each clone that should check commits:
npx klypix-mcp rules code promote <rule>
npx klypix-mcp check --install-hookThe same check can also run as a step in CI, over everything a branch adds: npx klypix-mcp check --base origin/main.
To see what a set of rules would have flagged in your own repository’s GitHub Actions history, use the backtest in the klypix-mcp repository, scripts/brain-rules-proof.mjs. It only reads your Actions history and your checkout.
The full reference, with every field and exception command, is in the project rules documentation. For the brain itself, start with shared project memory for Claude Code, Codex and Cursor and the klypix-mcp setup guide.
Questions
Does Klypix run my tests or replace CI?
No. A rule reads the change: file names, added lines, line endings and which paths changed. It does not run tests, type checks or builds, so CI still does that. A rule can flag a known mistake earlier: while the agent works and before the commit.
Will a rule stop my agent?
Only if a person approved that rule with --block. Warn is the default: the agent is told what is wrong and how to fix it, and the work goes on.
Which coding tools get the warnings?
A session that calls brain_sync is told which rules apply to the files it plans to change. While editing, Claude Code and Codex get the warning with the file, the line and the fix; Codex is warned but cannot be stopped mid-edit. The opt-in git hook, in a clone where it is turned on, checks each commit, whichever tool or person made it.
Where do the rules live?
In the repository, in .klypix/rules.json, so every change to a rule shows up in a pull request. Each rule cites the lesson card it came from in the project brain.