npx bearing · an intel layer for AI coding agents

Your tests catch code that breaks. Nothing catches an agent that has drifted.

A drifted agent doesn't crash. It reads a doc you abandoned in March, re-proposes the feature you already measured and killed, and writes a convincing paragraph about it. You nod. You find out three days later.

Read the source npm
  • 11 modules · each works alone
  • ~25,200 tokens a session
  • Claude Code · Zed · Codex
N E S W
The needle wanders. The north-star is what pulls it back.

The failure this exists for

Losing your bearings is a failure with no stack trace

Nothing is red. The build passes, the tests pass, the paragraph is convincing. What changed is what the agent believes the code means — and belief has no assertion.

Without

  1. 1MarchA design doc is written, then abandoned.
  2. 2Today, 14:02The agent reads it and re-proposes the feature you measured and killed.
  3. 3Today, 14:03It writes a convincing paragraph. You nod.
  4. 4Three days laterYou find out.

With bearing

  1. 1OnceYou write NS-9 — the claim that the idea was measured and rejected.
  2. 2Today, 14:02The agent forms the same intent.
  3. 3Today, 14:02The north-star outranks the abandoned doc.
  4. 4One line laterCaught, cited, and not re-proposed.
Built for a codebase where 81 documents had come to contradict each other on live production parameters.

What you get

Eleven instruments. Pick any combination.

Each works alone and none depends on another. Install one, install all eleven — --features northstars,taskcore is a complete install, and so is --features all.

North-stars

Stops killed ideas respawning six months later.

Numbered, authoritative claims about what your project is — they outrank every other doc, and they are re-injected as the session runs.

Gold practices

The mistakes that get made anyway.

Numbered GP-# rules earned from real defects, shipped with bearing and outranked by your north-stars. Every rule carries a scar, or it is not in the file.

Task-core

Survives compaction.

A dense save-state of the current task, written before the summary lands and drops the detail. It keeps the gotchas — what you already tried that failed.

Microscope

Catches code that runs perfectly and is still wrong.

One lens agent per slice of the change, each reviewing as an expert in your domain. Every finding must survive a pass that tries to refute it.

Consult

Asks about the right things, decides the rest.

If the answer is in the repo it goes and finds it. If it exists only in your head, that is the question — with options, a tradeoff and a recommendation.

Minions

Parallelises wide mechanical work.

Cheap anchored subagents return citations — FOUND, CHECKED, MISSED — never verdicts. Invasive minions apply a decided change across disjoint slices.

TypeScript / JavaScript

Catches code that compiles and is still wrong.

Numbered TS-# rules for the traps tsc and ESLint stay silent about: an as that verifies nothing, a union that falls through, || overwriting a deliberate 0.

Frontend

Stops the near-duplicate component.

Search by shape before building another table or panel. An optional prop with a safe default is yours; anything that changes what existing callers render is an ask.

React

Catches the form bugs that fail silently.

A field owns its Controller; spreading field keeps the ref that focus-on-error needs; a name typed FieldPath turns a renamed field into a compile error.

GitNexus

Turns 40 text matches into a real code graph.

Hard gates redirect symbol greps to callers and flows, and a stale index blocks until it is refreshed. Needs the GitNexus MCP server.

E2E harness

Turns "I checked it in the browser" into an exit code.

The shape and the scars, not another test framework: polling waits, assertions on the body, and blockWrites — test a destructive write without performing it. Opt-in.

Not a module

The agent files bug reports against its own tooling.

And the kit tells you when its own gates are the problem — 93 of those reports are what the rules are calibrated against. See the receipts.

North-stars

Falsifiable, or it's decoration

Docs rot. Comments lie. The agent's own inference fills the gaps — confidently. A north-star is a numbered claim about what your project is, written so that a conclusion could actually violate it.

"Be careful with risk" can't be violated, so it can't catch anything. The graveyard is the half people skip: an idea that was measured and killed stays killed until new evidence shows up.

If the agent can't cite a north-star for a load-bearing claim, it says so. That sentence is your drift alarm.

.bearing/north-stars.md

- NS-4 — Win-rate is NEVER a ranker. Only net
         expectancy is a profitability claim.

- NS-9REJECTED: averaging into a losing
         position. Measured: adds fill only on
         the weaker cases. Don't re-propose
         without new evidence.

Gold practices — the half that isn't yours

North-stars say what your project is. gold-practices.md ships with bearing and says how the work is done anywhere — numbered GP-#, cited the same way, and outranked by your NS-# whenever they disagree. Every rule carries a scar, and a rule without one is not in the file.

GP-3 — Test at the seam the bug lives at. A unit test that passes an argument the real pipeline never produces is green and dead. Scar: a context-window fix tested as resolve(300_000, undefined) while the shipped config always passed a number — so the fix could not run, and did not, for two releases.

The honest number

What it costs your context — measured, not guessed

Every intel layer costs tokens. Most don't tell you how many. bearing's share is fixed per session, and half of it isn't even bearing: the graph tool schemas are there whenever the MCP server is connected, with or without this package.

200k context window~25,200 tokens · 13%
1M context window~25,200 tokens · 2.5%
Fixed, every session
bearing's contract block~10,300
GitNexus MCP tool schemas (17 tools)~14,900
total~25,200

Skills load on demand, not up front — a session typically pulls one or two, at about 1,500 tokens each. Install less and bearing's own share falls to ~2,400 (intel only) or ~1,600 (north-stars and task-core).

What one "what breaks if I change this?" costs
repographgrep + readsaved
lead-sniffer (234 files)65,645199,7373.0×
Sourcerer-Be (709 files)71,446945,33813.2×

Like for like: every call site, against grep's hits plus the 40 lines around each one. Asking only for counts and risk is cheaper again — 19× and 125× — but that is a different question, so it is a different row.

Don't take my repos for it. npm run bearing:token-benchmark runs the same comparison on yours — and reports the losses too. On lead-sniffer the graph loses one symbol in eight, and the table says so. A benchmark that never admits that is advertising.

It tells you when it's the problem

A tool that can block your work should show you when it was wrong to

Every enforcement tool believes its own rules are correct. This one assumes they might not be — and keeps the evidence, with the graph state that produced it: version, node and edge counts, the indexed commit. Not "the graph was wrong once", but this query, on this index, at this commit.

93fallback reports filed by the agent against its own tooling
47commits they span
3weeks on one real project
30of them empty results for things that demonstrably existed

Read together they stopped being complaints and became a diagnosis. That corpus is what the rules are calibrated against — and the gates are measured too:

$ npm run bearing:scorecard

 Enforcement is 49% of graph interaction:
  57 redirects vs 60 graph calls.

It refuses to draw the conclusion for you. Nothing leaves your repo. There is no telemetry endpoint.

Where it fires by itself

Enforcement needs hooks, and not every runtime has them

Only Claude Code exposes tool-interception hooks, and a dash is not always absence: the task-core skill and its contract section install everywhere, so you can invoke it by name — what Claude Code adds is the nudge that fires it unprompted. Minions and the GitNexus gates genuinely need the hooks and are not there at all.

Fires without being askedClaude CodeZedCodex
North-stars — loaded as authorityyesyesyes
North-stars — re-anchored mid-sessionyesnot on this runtimenot on this runtime
Gold practices — cited as authorityyesyesyes
Task-core — survives compactionyesnot on this runtimenot on this runtime
Microscope — domain-expert reviewyesyesnot on this runtime
Consult — ask vs decideyesyesnot on this runtime
Minions — anchored fan-outyesnot on this runtimenot on this runtime
TypeScript / JavaScript — traps that compileyesyesyes
Frontend — structure and blast radiusyesyesyes
React — what the types do not catchyesyesyes
GitNexus — hard gatesyesnot on this runtimenot on this runtime
E2E — browser verificationyesyesyes

Install

One command, and it explains each module before it writes anything

$ npx bearing
# interactive — explains each module

$ npx bearing install . \
    --runtime claude \
    --features northstars,taskcore

# or take the lot
$ npx bearing install . --features all

# later
$ npx bearing update .      # keeps your choices
$ npx bearing uninstall .   # restores what it overwrote

Node ≥ 22.9.0 · a git repo · macOS, Linux, Windows or WSL. The GitNexus module additionally needs the GitNexus MCP server. Then restart your IDE.

Contributing to a repo that isn't yours?

A normal install is a team decision: hooks, skills and a contract, committed, and everyone who pulls gets them. That is right for a repo you own and wrong for one you contribute to.

$ npx bearing install . --stealth

Stealth makes one promise, and it is testable: git status is exactly as clean after the install as it was before. Ignores go in .git/info/exclude, which is per-clone and untracked, so the rules can't travel. It refuses to convert a repo where bearing is already committed — un-tracking it for your whole team is a deliberate, visible act.