faultline

See the lines your code must not cross.

Declare your systems and the rules between them. faultline redraws the map on every edit and stops coding agents at the boundary.

Read the docs
Request handling → Dev server, from the Astro map below.The rule, the import and the suggested route are real.
01

The real map

The Astro monorepo, 22 systems, with one simulated edit that crosses a rule. Click the red edge for the import behind it, or double-click a system to open it.

withastro/astro · 22 systems · 2 rulesThe systems and rules are an example, not the Astro team's.
02

What crossed

Coding agents did two real tasks in the Astro repo, three times each, where the obvious import breaks a declared rule. The same rules were given to them as written docs, or through faultline.

TaskRules in docsfaultline
Warn when a page takes over 500 ms 1import { getTimeStat } from '../../../core/build/util.js'crossedheld
Warn when a page takes over 500 ms 2crossedheld
Warn when a page takes over 500 ms 3crossedheld
Add an error header for coding agents 1import { isRunByAgent } from '../../cli/agent.js'heldheld
Add an error header for coding agents 2crossedheld
Add an error header for coding agents 3crossedheld
Crossed5 of 60 of 6

Every run finished its task. Runs through faultline used more tokens. It is a small pilot; the prompts, the rules and every diff are in bench/agent-ab.

03

How it works

Declare

fault init drafts faultline.yml from your folders and imports. You name the systems and write the rules that matter.

systems: - { id: web, paths: [src/web/**] } - { id: db, paths: [src/db/**] } rules: - deny: web -> db

Watch

fault map redraws on every edit. A new dependency appears in green, a crossed rule in red, each with the import behind it.

Web UI → Database src/web/page.tsx imports query from src/db/client.ts

Stop

Agents read the map before they write and hear about a crossed rule the moment it lands. fault check holds it in CI.

✗ Crosses a fault line Allowed route: web → api → db
An agent crosses a line, is stopped, and reroutes.Watch the 37 second film
04

One file every agent respects

fault setup connects the MCP server, hooks, AGENTS.md and a pre-commit check for the agents your repo uses.

Claude Code, Codex, Cursor, Copilot, Gemini CLI, Kiro, Zed and opencode, and anything with a shell.

The same faultline.yml gates every pull request, with one comment that says what changed in the architecture and why.

# .github/workflows/faultline.yml
on: pull_request
jobs:
  faultline:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with: { fetch-depth: 0 }
      - uses: anzal1/faultline@v0
05

The map keeps itself current

Where code lives is a fact, so faultline keeps it up to date. What may depend on what is a decision, so it stays with people.

Placement
A new folder joins the system its imports go to. fault sync --apply writes it, and agents may run it.
Suggestions
Rules come from your history. If one system has never imported another in 200 commits, faultline offers to keep it that way.
Loosening
Only a person can loosen a rule. The agent hook refuses the edit, and fault check fails until someone approves it.
06

What your code costs to load

Pick an entry point and the map shows everything it loads at startup: how much of each system, which packages, the shortest import chain behind any file, and the one import that would drop the most.

On Astro's production entry it found zod imported at startup to read a couple of constants.

The footprint of Astro's production entry, with the import chain that loads zod drawn on the map
07

Install

Node 20 or newer. It runs on your machine, and nothing leaves it.

$ npm install -g @anzalabidi/faultline
$ fault init     # draft faultline.yml
$ fault map      # open the live map
$ fault setup    # connect your agents
$ fault check    # the CI gate

Reads TypeScript, JavaScript, Astro, Vue, Svelte, Python, Go, Rust, Java, Kotlin, Scala, C#, C, C++, Ruby, PHP, Swift, Dart, Elixir, Lua, Haskell and Zig.