Back to the catalog

io.github.dir-ai/repotector

The repo guardian AI agents handshake with before they touch your code.

Open source Open in the app JSON README (API)

About

The repo guardian AI agents handshake with before they touch your code.

Details

Kind
MCP servers
Topic
No topic detected
Publisher
dir-ai
Origin
official
Category
ferramentas
Transport
local
Version
1.6.0
Last push
2026-07-18T20:36:17Z
Repository state
ativo
Language
JavaScript
License
MIT
Added
2026-08-29 03:02:42
Updated
2026-08-29 03:02:42
Origin id
io.github.dir-ai/repotector

README

# Repotector ⬡

**The repo that remembers.**

Every AI agent that visits your repo starts from zero: it re-derives the map,
re-discovers the conventions, re-breaks the thing the last agent just fixed.
Repotector gives the repo itself a memory. An arriving agent knocks at the
front door, handshakes, and is handed the map, the standing decisions, and the
last visitor's briefing; on the way out it signs the register. The next agent
continues in two minutes instead of wandering for an hour — and a refactor
doesn't quietly break what already works.

Portable and self-contained: pure Node ESM, two dependencies
(`@modelcontextprotocol/sdk`, `zod`). Works on any repo — JS/TS deeply, other
stacks in honest orientation-lite.

## Install into any repo

```bash
cd /path/to/your/repo
npx repotector init
```

`init` scans the repo (never fails you on day one — see *grandfathered baseline*
below), wires the MCP server into `.mcp.json`, and writes the doorway blocks so
every arriving agent knows to handshake. It writes only inside `.repotector/`
and inside `REPOTECTOR:BEGIN/END` markers — your prose and config are never
overwritten. See [SECURITY.md](./SECURITY.md) for the exact posture.

Under `.repotector/`:

| File            | What it is                                                            |
|-----------------|----------------------------------------------------------------------|
| `intent.json`   | The contract: standards, required paths, bounded contexts, canon rules. |
| `atlas.json`    | The map: exports/imports/purpose/kind per file, routes, components, stack, and a deterministic fingerprint. |
| `dna.json`      | Reverse-engineered entities + API contracts + intent.                |
| `baseline.json` | The grandfathered floor — the debt that existed on day one.          |
| `proof.json`    | Gate verdict, regressions vs grandfathered debt.                     |
| `register.jsonl`| The visitor ledger: who entered, when, what they touched, who's inside. |
| `dna.inferred.json` | Reverse-DNA clauses for foreign repos (skipped when a `.psx/` mirror exists). |

Plus, at the repo root, a regenerated **`JOURNAL.md`** — the diario di bordo,
newest-first, that `handshake` serves the tail of so the next agent continues
prior work instead of re-deriving it.

## The front door (handshake-first)

The MCP server refuses deep tools until an agent calls `handshake` — and the
`initialize` response already tells the agent to. In return the agent gets
oriented in one call, and its exit is recorded for the next one.

- **`handshake({ who, model?, purpose? })`** — orientation, ground rules, live
  gate verdict, map freshness, passport. Read-only and fast (no tree walk).
- **`city_map()`** — intent, stack, built-vs-missing, brain pointers. On a
  non-JS repo it says *orientation-lite* instead of faking an empty map.
- **`find_existing({ intent })`** — REUSE: does it already exist? Don't rebuild.
- **`blast_radius({ changedFiles? })`** — PROTECT: transitive dependents +
  impacted routes/components. Omit `changedFiles` to use the git diff.
- **`canon_check({ changedFiles? })`** — INTEGRATE: the repo's canon rules.
- **`atlas_query({ query })`** — keyword search across the map.
- **`quality_gates()`** — line-budget / structure / secret-hygiene, reported as
  regressions vs grandfathered debt.
- **`register()`** — who's inside now and the full crossing log.
- **`journal({ limit? })`** — the repo's recent story: what prior agents did and
  left unfinished. **`whats_next()`** — the sensible next work, derived from DNA
  gaps + open threads + TODOs, every suggestion citing its evidence.
- **`dna_query({ clause?, topic? })`** — what the repo *specified* (authored from
  a `.psx/` mirror, or inferred, never merged). **`dna_coverage()`** — per
  clause: implemented / partial / missing. **`dna_diff({ changedFiles? })`** —
  which clauses a change touches.
- **`depart({ summary? })`** — sign out; the git delta of your visit is recorded
  even if you forget the summary. Your summary becomes the next agent's briefing.

## Grandfathered baseline — never red on day one

A guardian that fails your repo the moment you install it gets uninstalled the
moment you install it. So `init` snapshots the debt that already exists
(oversize files, tracked secrets, missing paths). Gates then fail **only on
regressions** against that floor — a *new* offender, an offender that *grew*, a
*new* leak. Pre-existing debt is reported loudly, never blocking. `repotector
baseline` re-snapshots after you pay it down.

## v1.2 "Gatekeeper" — from advisor to checkpoint

- **Commit guard** — `repotector hooks` installs a pre-commit that runs the
  gates; `gates` exits non-zero on regressions, so hooks and CI actually block.
  Grandfathered baseline means it never blocks day-one debt — only new damage.
- **Protected paths** — `intent.protect.paths` globs (CI workflows, LICENSE…)
  that agents must not touch: change-based, never grandfathered, overridden only
  by editing the intent (an explicit, diffable act).
- **Claims** — `claim({ paths })` declares your work zone; overlapping claims
  from live sessions answer `granted:false` with who/why. Advisory by design
  (blocking would be theater on a filesystem we don't control); claims die with
  the session.
- **Decision records** — `depart({ decisions: [{ chose, over, because }] })`
  writes the *why* to the register and projects `DECISIONS.md`; the handshake
  serves standing decisions and `decisions_query` answers "was this deliberate?"
  — so agent 2 doesn't undo agent 1's choice.
- **`repotector doctor`** — one command, semaphore answer to "how protected is
  this repo, really?", with a fix for every red.

## v1.5 "Mission" — the single verifiable chain

The whole visit becomes one auditable contract:

```
handshake → declare_mission → (auto)claim → work
        → off-claim / forbidden reconciliation
        → evidence pack (machine-verified vs agent-declared)
        → depart → the next agent inherits it all
```

- **`declare_mission({ goal, acceptance, claimPaths?, forbiddenPaths?, risk? })`**
  — bind the visit to a contract: your zone is auto-claimed (conflicts
  surfaced), and you get a one-shot briefing (gates, merge status, standing
  decisions, protected paths).
- **Evidence pack at depart** — the register records what the MACHINE verified
  (gates verdict, trial-merge clean/conflicted, files touched, off-claim,
  forbidden violations) strictly apart from what the AGENT declared
  (per-criterion self-report); unreported criteria are listed, never assumed.
  "Done" becomes something the register can check, not a courtesy.
- Other agents see missions in progress at handshake — what you're doing, not
  just where.

## v1.3 "Merge Guard" — commit without colliding

- **merge_check** — a zero-damage TRIAL merge (git merge-tree) of HEAD against
  the integration base, run BEFORE you commit: reports clean/conflicted with
  the exact files, each attributed to who holds that zone (live claims — and,
  in PSX Workbench repos, the Merge Machine's leases via the .psx mirror).
  CLI: `repotector merge-check [target]` (exit 1 on conflicts, so hooks/CI
  can gate on it). Zero network: it trial-merges against your LOCAL refs and
  says so — fetch first for the freshest truth.

## Resilient register — agents die without signing out

Sessions that enter and never leave (the agent was killed, the pipe closed) are
auto-departed on the next handshake, with the git delta of what they touched.
The ledger never fills with immortal open sessions, and a depart carries real
work even when nobody called it.

## CLI

```bash
npx repotector init          # scan, wire .mcp.json, write the doors — day-one green
npx repotector refresh       # re-derive the map + re-stamp the doorway blocks
npx repotector handshake     # orientation + live gate + passport (logged visit)
npx repotector city-map      # built-vs-missing + brain pointers
npx repotector dna-coverage  # per specified clause: implemented / missing
npx repotector whats-next    # the sensible next work, with evidence
npx repotector journal       # the diario di bordo (regenerates JOURNAL.md)
npx repotector gates         # regressions vs grandfathered debt
npx repotector baseline      # re-snapshot the grandfathered floor
npx repotector register      # the visitor ledger
npx repotector lock <pass>   # optional passphrase gate on the deep map
npx repotector mcp           # start the stdio MCP server
```

## Docker

The image on GHCR wraps the CLI and the MCP server; the guarded repo is
mounted, never baked in:

```bash
docker run --rm -v "$PWD:/repo" ghcr.io/dir-ai/repotector init
docker run --rm -v "$PWD:/repo" ghcr.io/dir-ai/repotector gates
docker run -i --rm -v "$PWD:/repo" ghcr.io/dir-ai/repotector mcp   # stdio MCP
```

Multi-arch (amd64/arm64), built and smoke-tested by CI on every release tag
(see [Dockerfile](./Dockerfile)).

## GitHub Action

Guard a repo in CI with one step — grandfathered semantics apply, so the job
fails only on regressions, never on day-one debt:

```yaml
- uses: dir-ai/repotector@main
  with:
    command: gates     # default; any CLI command works
    version: latest    # pin an exact npm version for reproducible CI
```

## Honesty

Repotector guards repos, so it holds itself to its own standard. The lock is a
compliance signal, not filesystem access control; the register is
append-integrity, not tamper-proof; a static badge is self-reported. It spawns
only `git`, makes no network calls, and pins exact versions in `.mcp.json`. The
full threat model is in [SECURITY.md](./SECURITY.md) — no security theater.

## Determinism

The Atlas `fingerprint` is a SHA-256 over sorted source contents (16 hex chars),
no timestamps — the same tree always fingerprints the same. Large files (>1MB,
generated/minified) are marked, never read into the fingerprint. `builtAtHead`
stamps the git sha so freshness can be checked without a walk.

## License

MIT © PSX System. The core an agent needs in a repo is free forever; the
compounding brain (Genome cloud, authored DNA) is the premium layer.

More