fairlead
v0.12.0
Published
Guardrails and a guided path for coding agents: rules enforced as the agent works, tests scoped to what a change can reach, capped project memory, and KPIs.
Maintainers
Readme
A fairlead is the fitting on a boat that keeps a line running true, so it
doesn't chafe, tangle or pull off course. Fairlead does that for an agent
working in your repository. It is one Rust binary with no project-specific
logic: everything about your repository lives in your own fairlead.toml.
Why Fairlead
Join a good team and you don't start from zero. Someone tells you which module never to touch without running the migration check first, which test lies on Windows, and which "quick fix" broke production last spring. That knowledge is why a new engineer is useful in week two instead of month six.
A coding agent gets none of it. It opens your repository cold every time, reads the same code again, makes the mistake your team already paid for, and finds out in CI that it was an old lesson nobody told it. Fairlead gives every repository its own memory, so your agent starts where your team left off instead of trying things like a stranger.
- A memory for every repository. The hard lessons from past work live with
the code, per module, where the agent meets them before it acts. A lesson is
kept short, reviewed on a date, and turned into a check when it can be, so
the memory stays true instead of growing into noise.
Since 0.2.0: owner rules record which tests guard which code, and a
quarantined test applies only while the evidence holds and until its date.
Since 0.7.0: a
[[quarantine]]entry records a test that lies on one platform, such as a CRLF checkout or a path with a space. There, the plan lists it as not provable here, anddoneexcuses only the failure it expects. - Set up once, never start cold. The agent's first job is to learn
the repository: its modules, test runners, rules, and the commands that prove
a change is right. That goes into one checked config, so every session starts
where the last one left off.
Since 0.1.1:
fairlead config checkvalidates every layer, andshow --originsays where each value came from. - The right tool, not the nearest one. The agent asks what applies to the
files in front of it and gets the rule, the command and the next step for
exactly those files.
Since 0.2.0:
fairlead plannames the tests and checks a change can reach, andtest --explainsays why each one is in or out. - Plans the change, not just the tests. Before an edit, the agent sees
what it's about to touch, everything that depends on it, the rules and
lessons recorded there, and what has to pass before it's done. Afterwards,
what actually changed is checked against that brief.
Since 0.6.0:
fairlead brief <paths>answers that before the first edit,fairlead doneis the gate a change passes before it's finished,fairlead receiptcompares what changed with the brief, andfairlead nextnames the one step left. - The right skills for the code in front of it. A frontend change
shouldn't come with database advice. Fairlead picks the skills that apply to
what a change reaches, just as it picks tests, and checks the agent used them.
Since 0.8.0:
[[skills.routes]]scopes each skill, the brief lists the ones a change reaches,skills syncwrites them where each agent loads them, andskills reportmeasures whether the agent used them. - Measured, not guessed. Good and bad are numbers: whether the plan would
have caught real CI failures, rework, escaped defects, tokens and cost.
Since 0.2.0:
fairlead replayre-plans real failures from a repository's CI history, and the benchmarks measure that recall every week. Since 0.6.0:ci run --judgenames each failing test on the default branch that the merged change's plan left out. - Fast because it remembers. No rereading the codebase to rediscover what was learned last week. The graph, the plan and the lessons are already there. Since 0.2.0: the import graph is built without installing dependencies and cached between runs.
- It learns where it's blind. When a change reaches no test, Fairlead says
so and points at the rule that's missing, so the team's knowledge grows
exactly where it was thin.
Since 0.3.0:
fairlead planlists every file no test depends on, and replay suggests the owner rule or check path that would have caught a miss. - Stopped before the mistake, not after. Your rules run as the agent
works, catching a wrong move in seconds instead of minutes later in CI.
Since 0.4.0:
[guard.*]rules run in a Claude Code hook before each edit and in a git commit hook, andfairlead guard checkruns them on the tree. Since 0.7.0: the same hooks for Codex and Gemini CLI, withfairlead hooks install --codexor--gemini.
Works with
- Any test runner. Vitest, Jest, Playwright,
node --test, Bun, pytest,go test, PHPUnit and Pest: a runner is one command in your config, so Fairlead never needs a plugin for your stack. - Monorepos, precisely. pnpm, npm, yarn and bun workspaces. A pnpm lockfile change runs only the packages whose dependencies actually changed. Since 0.8.0: in a bun project, a dependency's version bump runs only the tests of the files that import it, and nothing when nothing does.
- No install needed to read your code. The import graph comes from source
alone, with tsconfig paths,
go.modand composer's autoload resolved and parsed files cached, so a plan takes a fraction of a second. - Your CI, not a new one. A GitHub Action and
ci plan --format githubfor Actions, and a JSON plan with a published schema for any other CI. - Proven on real projects. Recall is replayed from the CI history of Effect, pnpm and vitest every week, and published.
- Private by default. The CLI sends nothing you didn't ask for: no telemetry, and it never phones home.
- One binary, everywhere. Linux, macOS and Windows, installed with a shell script, PowerShell or npm.
What it reads, and what replay has proven. A language counts as proven when replaying a public project's CI history judges at least 10 failures, at high recall:
| Language | Since | Replay evidence | | --- | --- | --- | | JavaScript, TypeScript | 0.2.0 | Effect, pnpm and vitest, replayed weekly (benchmarks) | | Python | 0.5.0 | poetry: 99.2% of 122 failures | | PHP | 0.5.0 | pterodactyl/panel and invoiceninja: 100% of 27 failures | | Go | 0.5.0 | Reads, not yet proven: opentelemetry-go has too few failures to judge | | Vue, Svelte, Astro components | 0.5.0 | Reads, not yet proven: no replay yet | | Java, Kotlin (Maven, Gradle) | 0.7.0 | Reads, not yet proven: okhttp at 92.6%, most misses look flaky (#184) |
An external provider feeds the graph for any other language, and a coverage map adds what imports can't show. Framework packs and folders of several repositories are on the way (#47).
What it does
This README documents Fairlead 0.12.0. Each command, by what it's for:
- The test plan:
plan,test --explain, the import graph (graph) and coverage maps (coverage import). - Plans in CI:
ci plan(by stage, with--since-green),ci run(with--results,--judge,--onlyand--except),ci report,ci workflow, which writes a staged workflow, and the GitHub Action. - Rules as the agent works:
guard check, the hookshooks installadds, anddoctor. - The change loop:
briefbefore an edit, orcontextfor the brief with the lessons, skills, README and history to read;donebefore it's finished, thenreceiptandnext;resumepicks up where the last session on a branch stopped. - Project memory:
learnwrites a lesson,import lessonsturns a lessons document the team already keeps into one lesson per heading, andlessonslists, reviews and checks them. The brief offers the ones a change reaches. - Skills:
[[skills.routes]]scopes each SKILL.md, and the brief lists the skills a change reaches.import rulesturns path-scoped rule files into skills and routes, andskills syncwrites each skill where Claude Code, Codex and Cursor load it. - Finding things:
findsearches lessons, skills, docs headings and declared names, nearest the brief first. - Agents over MCP:
mcpserves the plan, the brief, the receipt and the other read-only commands as tools. - What agents read first:
agents synckeeps the loop, the always-on lessons and the skill index in a marked block in AGENTS.md and CLAUDE.md. - Measuring:
insights, what the event log and CI's reports say about the setup and the config changes they back;tokens, the tokens and cost of each agent session;replay, the benchmarks,skills eval, which scores skill routing on the repository's history, andskills report, the hit rate of what routing offers against what agents load. - Getting started:
initwrites a first config from what the repository shows, andinit --blueprintadds a starting point for a kind of project: config, starter skills and the CI workflow. - The config:
config check,showandschema. - Upgrading:
migrate, which brings the hooks, the config's version floor and the version pins to the release you installed. Since 0.7.0.
The quick start shows the first few, and the book covers each one.
Status
Pre-alpha. The latest release, v0.12.0, fixes a runner asked to run
everything loading another runner's tests, two first runs of the npm
package racing on the binary's download, and the Next.js pack's
end-to-end rule overriding a project's own spec owners, which is now its
own pack, next-e2e. v0.11.0 added a Next.js pack with init naming the
pack a project needs, edges across the repositories of a workspace, and
the SessionStart hook for Codex and Gemini CLI, and fixed sessions in a
linked worktree going uncounted, the weekly insights workflow lacking the
scopes replay needs, and replay leaving a Go package whose tests didn't
build unattributed. v0.10.0 connected Fairlead to the
rest of the work and measured the setup: an MCP server (fairlead mcp),
trackers that put a branch's task in the brief, escapes filed as issues
from CI, tokens and cost per session, a readiness score (doctor --score),
fairlead insights with a weekly summary job, blueprints for init,
framework packs, workspaces of several repositories, and replay setting
recurring failures aside. v0.9.0 let replay measure a project whose
pushes run the plan too, by reading its scheduled full runs (replay fetch
--event schedule), named each hop of a test --explain chain that isn't a
plain import, and had migrate refresh Codex and Gemini CLI hooks. v0.8.0
added memory and skills: lessons in .fairlead/lessons/ written by
fairlead learn or imported from a document a team already keeps, skills
routed by what a change reaches, fairlead find, fairlead context and
resume, and a block in AGENTS.md and CLAUDE.md that agents sync keeps
current. It also added CI stages: each runner and check says
when it runs (a draft, a ready pull request, a merge or a full run), a merge
skips what its pull request passed on the same tree, end-to-end runs batch
after merge, and ci workflow writes the staged workflow. v0.7.1 let a runner say what "everything" means
(all_command) and kept a run of everything whole around a held test
(exclude_arg). v0.7.0 brought the hooks to Codex and Gemini
CLI, reads Java and Kotlin in the graph and Maven and Gradle in replay, and
adds fairlead init for a first config, fairlead migrate for an upgrade, and
[[quarantine]] for a test that fails on one platform whatever the change.
v0.6.0 added the change loop for agents: fairlead brief before an edit,
fairlead done and a Stop hook that holds an agent to it, fairlead receipt
after it, and in CI fairlead ci report and ci run --judge.
Recall on real CI failures, with every miss and its cause, is in the
changelog and on the
benchmarks page.
Hooks ship for Claude Code, Codex and Gemini CLI. The roadmap
has milestones K0 to K6, each an issue
with its exit criteria.
Install
# macOS and Linux
curl -fsSL https://github.com/mahkassem/fairlead/releases/latest/download/fairlead-installer.sh | sh
# Windows (PowerShell)
powershell -c "irm https://github.com/mahkassem/fairlead/releases/latest/download/fairlead-installer.ps1 | iex"
# In a JavaScript or TypeScript project, as a dev dependency
bun add -d fairlead # or: npm i -D fairleadThen fairlead doctor says which binary, platform and config it would use.
Quick start
fairlead init # a first fairlead.toml, from what the repository shows
fairlead config check # validate fairlead.toml
fairlead plan --base main # the tests and checks this branch can affect
fairlead test --explain src/a.test.ts # why that test is in the plan, or isn't
fairlead graph why src/a.test.ts src/util.ts # how one file depends on another
fairlead brief src/util.ts # before an edit: what it reaches and what must pass
fairlead done # the gate a change passes before it's finishedDocumentation
The site is mahkassem.github.io/fairlead, and the book covers
install, configuration, the import graph, the test plan, plans in CI, guard
rules and hooks, the brief, the done gate, the receipt, replay and the
benchmarks. Its source is in docs/.
The README, the site and the book describe the latest release, and each says
which one. For an earlier release, read them at its tag, such as
v0.5.1. A release
can't be cut while any of them lags it: scripts/docs_check.py runs before the
release builds.
Brand
The logo, its colors and how to use them are in assets/brand.
License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT license (LICENSE-MIT)
at your option. Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
