{
  "markdown": "# Repotector ⬡\n\n**The repo that remembers.**\n\nEvery AI agent that visits your repo starts from zero: it re-derives the map,\nre-discovers the conventions, re-breaks the thing the last agent just fixed.\nRepotector gives the repo itself a memory. An arriving agent knocks at the\nfront door, handshakes, and is handed the map, the standing decisions, and the\nlast visitor's briefing; on the way out it signs the register. The next agent\ncontinues in two minutes instead of wandering for an hour — and a refactor\ndoesn't quietly break what already works.\n\nPortable and self-contained: pure Node ESM, two dependencies\n(`@modelcontextprotocol/sdk`, `zod`). Works on any repo — JS/TS deeply, other\nstacks in honest orientation-lite.\n\n## Install into any repo\n\n```bash\ncd /path/to/your/repo\nnpx repotector init\n```\n\n`init` scans the repo (never fails you on day one — see *grandfathered baseline*\nbelow), wires the MCP server into `.mcp.json`, and writes the doorway blocks so\nevery arriving agent knows to handshake. It writes only inside `.repotector/`\nand inside `REPOTECTOR:BEGIN/END` markers — your prose and config are never\noverwritten. See [SECURITY.md](./SECURITY.md) for the exact posture.\n\nUnder `.repotector/`:\n\n| File            | What it is                                                            |\n|-----------------|----------------------------------------------------------------------|\n| `intent.json`   | The contract: standards, required paths, bounded contexts, canon rules. |\n| `atlas.json`    | The map: exports/imports/purpose/kind per file, routes, components, stack, and a deterministic fingerprint. |\n| `dna.json`      | Reverse-engineered entities + API contracts + intent.                |\n| `baseline.json` | The grandfathered floor — the debt that existed on day one.          |\n| `proof.json`    | Gate verdict, regressions vs grandfathered debt.                     |\n| `register.jsonl`| The visitor ledger: who entered, when, what they touched, who's inside. |\n| `dna.inferred.json` | Reverse-DNA clauses for foreign repos (skipped when a `.psx/` mirror exists). |\n\nPlus, at the repo root, a regenerated **`JOURNAL.md`** — the diario di bordo,\nnewest-first, that `handshake` serves the tail of so the next agent continues\nprior work instead of re-deriving it.\n\n## The front door (handshake-first)\n\nThe MCP server refuses deep tools until an agent calls `handshake` — and the\n`initialize` response already tells the agent to. In return the agent gets\noriented in one call, and its exit is recorded for the next one.\n\n- **`handshake({ who, model?, purpose? })`** — orientation, ground rules, live\n  gate verdict, map freshness, passport. Read-only and fast (no tree walk).\n- **`city_map()`** — intent, stack, built-vs-missing, brain pointers. On a\n  non-JS repo it says *orientation-lite* instead of faking an empty map.\n- **`find_existing({ intent })`** — REUSE: does it already exist? Don't rebuild.\n- **`blast_radius({ changedFiles? })`** — PROTECT: transitive dependents +\n  impacted routes/components. Omit `changedFiles` to use the git diff.\n- **`canon_check({ changedFiles? })`** — INTEGRATE: the repo's canon rules.\n- **`atlas_query({ query })`** — keyword search across the map.\n- **`quality_gates()`** — line-budget / structure / secret-hygiene, reported as\n  regressions vs grandfathered debt.\n- **`register()`** — who's inside now and the full crossing log.\n- **`journal({ limit? })`** — the repo's recent story: what prior agents did and\n  left unfinished. **`whats_next()`** — the sensible next work, derived from DNA\n  gaps + open threads + TODOs, every suggestion citing its evidence.\n- **`dna_query({ clause?, topic? })`** — what the repo *specified* (authored from\n  a `.psx/` mirror, or inferred, never merged). **`dna_coverage()`** — per\n  clause: implemented / partial / missing. **`dna_diff({ changedFiles? })`** —\n  which clauses a change touches.\n- **`depart({ summary? })`** — sign out; the git delta of your visit is recorded\n  even if you forget the summary. Your summary becomes the next agent's briefing.\n\n## Grandfathered baseline — never red on day one\n\nA guardian that fails your repo the moment you install it gets uninstalled the\nmoment you install it. So `init` snapshots the debt that already exists\n(oversize files, tracked secrets, missing paths). Gates then fail **only on\nregressions** against that floor — a *new* offender, an offender that *grew*, a\n*new* leak. Pre-existing debt is reported loudly, never blocking. `repotector\nbaseline` re-snapshots after you pay it down.\n\n## v1.2 \"Gatekeeper\" — from advisor to checkpoint\n\n- **Commit guard** — `repotector hooks` installs a pre-commit that runs the\n  gates; `gates` exits non-zero on regressions, so hooks and CI actually block.\n  Grandfathered baseline means it never blocks day-one debt — only new damage.\n- **Protected paths** — `intent.protect.paths` globs (CI workflows, LICENSE…)\n  that agents must not touch: change-based, never grandfathered, overridden only\n  by editing the intent (an explicit, diffable act).\n- **Claims** — `claim({ paths })` declares your work zone; overlapping claims\n  from live sessions answer `granted:false` with who/why. Advisory by design\n  (blocking would be theater on a filesystem we don't control); claims die with\n  the session.\n- **Decision records** — `depart({ decisions: [{ chose, over, because }] })`\n  writes the *why* to the register and projects `DECISIONS.md`; the handshake\n  serves standing decisions and `decisions_query` answers \"was this deliberate?\"\n  — so agent 2 doesn't undo agent 1's choice.\n- **`repotector doctor`** — one command, semaphore answer to \"how protected is\n  this repo, really?\", with a fix for every red.\n\n## v1.5 \"Mission\" — the single verifiable chain\n\nThe whole visit becomes one auditable contract:\n\n```\nhandshake → declare_mission → (auto)claim → work\n        → off-claim / forbidden reconciliation\n        → evidence pack (machine-verified vs agent-declared)\n        → depart → the next agent inherits it all\n```\n\n- **`declare_mission({ goal, acceptance, claimPaths?, forbiddenPaths?, risk? })`**\n  — bind the visit to a contract: your zone is auto-claimed (conflicts\n  surfaced), and you get a one-shot briefing (gates, merge status, standing\n  decisions, protected paths).\n- **Evidence pack at depart** — the register records what the MACHINE verified\n  (gates verdict, trial-merge clean/conflicted, files touched, off-claim,\n  forbidden violations) strictly apart from what the AGENT declared\n  (per-criterion self-report); unreported criteria are listed, never assumed.\n  \"Done\" becomes something the register can check, not a courtesy.\n- Other agents see missions in progress at handshake — what you're doing, not\n  just where.\n\n## v1.3 \"Merge Guard\" — commit without colliding\n\n- **merge_check** — a zero-damage TRIAL merge (git merge-tree) of HEAD against\n  the integration base, run BEFORE you commit: reports clean/conflicted with\n  the exact files, each attributed to who holds that zone (live claims — and,\n  in PSX Workbench repos, the Merge Machine's leases via the .psx mirror).\n  CLI: `repotector merge-check [target]` (exit 1 on conflicts, so hooks/CI\n  can gate on it). Zero network: it trial-merges against your LOCAL refs and\n  says so — fetch first for the freshest truth.\n\n## Resilient register — agents die without signing out\n\nSessions that enter and never leave (the agent was killed, the pipe closed) are\nauto-departed on the next handshake, with the git delta of what they touched.\nThe ledger never fills with immortal open sessions, and a depart carries real\nwork even when nobody called it.\n\n## CLI\n\n```bash\nnpx repotector init          # scan, wire .mcp.json, write the doors — day-one green\nnpx repotector refresh       # re-derive the map + re-stamp the doorway blocks\nnpx repotector handshake     # orientation + live gate + passport (logged visit)\nnpx repotector city-map      # built-vs-missing + brain pointers\nnpx repotector dna-coverage  # per specified clause: implemented / missing\nnpx repotector whats-next    # the sensible next work, with evidence\nnpx repotector journal       # the diario di bordo (regenerates JOURNAL.md)\nnpx repotector gates         # regressions vs grandfathered debt\nnpx repotector baseline      # re-snapshot the grandfathered floor\nnpx repotector register      # the visitor ledger\nnpx repotector lock <pass>   # optional passphrase gate on the deep map\nnpx repotector mcp           # start the stdio MCP server\n```\n\n## Docker\n\nThe image on GHCR wraps the CLI and the MCP server; the guarded repo is\nmounted, never baked in:\n\n```bash\ndocker run --rm -v \"$PWD:/repo\" ghcr.io/dir-ai/repotector init\ndocker run --rm -v \"$PWD:/repo\" ghcr.io/dir-ai/repotector gates\ndocker run -i --rm -v \"$PWD:/repo\" ghcr.io/dir-ai/repotector mcp   # stdio MCP\n```\n\nMulti-arch (amd64/arm64), built and smoke-tested by CI on every release tag\n(see [Dockerfile](./Dockerfile)).\n\n## GitHub Action\n\nGuard a repo in CI with one step — grandfathered semantics apply, so the job\nfails only on regressions, never on day-one debt:\n\n```yaml\n- uses: dir-ai/repotector@main\n  with:\n    command: gates     # default; any CLI command works\n    version: latest    # pin an exact npm version for reproducible CI\n```\n\n## Honesty\n\nRepotector guards repos, so it holds itself to its own standard. The lock is a\ncompliance signal, not filesystem access control; the register is\nappend-integrity, not tamper-proof; a static badge is self-reported. It spawns\nonly `git`, makes no network calls, and pins exact versions in `.mcp.json`. The\nfull threat model is in [SECURITY.md](./SECURITY.md) — no security theater.\n\n## Determinism\n\nThe Atlas `fingerprint` is a SHA-256 over sorted source contents (16 hex chars),\nno timestamps — the same tree always fingerprints the same. Large files (>1MB,\ngenerated/minified) are marked, never read into the fingerprint. `builtAtHead`\nstamps the git sha so freshness can be checked without a walk.\n\n## License\n\nMIT © PSX System. The core an agent needs in a repo is free forever; the\ncompounding brain (Genome cloud, authored DNA) is the premium layer.\n",
  "bytes": 10114,
  "sha": "10776bd31a143063cde34e6ceb391d1ba1d956ac50991b7c9363f62155df3a24",
  "repo_slug": "dir-ai/repotector",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_dir_ai_repotector_aba00a06/readme"
}