carto-md 2.1.0 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/CHANGELOG.md +135 -0
  2. package/CONTRIBUTING.md +11 -8
  3. package/README.md +165 -213
  4. package/docs/anci/v0.1-DRAFT.md +132 -2
  5. package/docs/api/README.md +27 -2
  6. package/docs/api/did_we_discuss_this.md +2 -0
  7. package/docs/api/dismiss_gap.md +39 -0
  8. package/docs/api/find_consumers_of_api.md +2 -0
  9. package/docs/api/get_action_patterns.md +2 -0
  10. package/docs/api/get_arch_events.md +2 -0
  11. package/docs/api/get_architectural_drift.md +2 -0
  12. package/docs/api/get_blast_radius.md +2 -0
  13. package/docs/api/get_canonical_pattern.md +2 -0
  14. package/docs/api/get_change_velocity.md +2 -0
  15. package/docs/api/get_churn_vs_blast_radius.md +2 -0
  16. package/docs/api/get_complexity_trend.md +2 -0
  17. package/docs/api/get_conventions.md +2 -0
  18. package/docs/api/get_cross_repo_blast_radius.md +2 -0
  19. package/docs/api/get_data_flow.md +2 -0
  20. package/docs/api/get_decision_log.md +2 -0
  21. package/docs/api/get_domain_evolution.md +2 -0
  22. package/docs/api/get_domain_health.md +2 -0
  23. package/docs/api/get_file_receipts.md +34 -0
  24. package/docs/api/get_gaps.md +52 -0
  25. package/docs/api/get_hotspot_files.md +2 -0
  26. package/docs/api/get_intent.md +25 -0
  27. package/docs/api/get_intervention_history.md +2 -0
  28. package/docs/api/get_invariants.md +2 -0
  29. package/docs/api/get_microservices_migration_cut_points.md +2 -0
  30. package/docs/api/get_neighbors.md +2 -0
  31. package/docs/api/get_org_architecture.md +2 -0
  32. package/docs/api/get_org_domain_mapping.md +2 -0
  33. package/docs/api/get_pending_decisions.md +2 -0
  34. package/docs/api/get_recent_decisions.md +2 -0
  35. package/docs/api/get_service_boundary_violations.md +2 -0
  36. package/docs/api/get_service_dependency_graph.md +2 -0
  37. package/docs/api/get_session_context.md +2 -0
  38. package/docs/api/get_temporal_context.md +2 -0
  39. package/docs/api/history.md +78 -0
  40. package/docs/api/impact.md +56 -0
  41. package/docs/api/memory.md +70 -0
  42. package/docs/api/org.md +51 -0
  43. package/docs/api/patterns.md +63 -0
  44. package/docs/api/set_intent.md +45 -0
  45. package/docs/api/simulate_change_impact.md +2 -0
  46. package/docs/concepts/domains.md +75 -50
  47. package/docs/concepts/mcp-integration.md +4 -2
  48. package/docs/guides/pre-merge-review.md +2 -2
  49. package/docs/migration/v1-to-v2.md +2 -2
  50. package/docs/screenshots/carto-supabase-blast-radius.png +0 -0
  51. package/package.json +2 -1
  52. package/scripts/gen-api-docs.js +51 -19
  53. package/src/agents/domains.js +72 -24
  54. package/src/ai/tools.js +4 -2
  55. package/src/anci/consumer.js +83 -3
  56. package/src/anci/emit.js +18 -1
  57. package/src/anci/git-meta.js +171 -0
  58. package/src/anci/pack.js +288 -0
  59. package/src/anci/serialize.js +77 -6
  60. package/src/anci/staleness.js +161 -0
  61. package/src/brain/conventions/index.js +134 -20
  62. package/src/brain/invariants/index.js +76 -22
  63. package/src/cli/anci.js +27 -1
  64. package/src/cli/doctor.js +69 -0
  65. package/src/cli/export.js +128 -0
  66. package/src/cli/index.js +19 -1
  67. package/src/cli/init.js +84 -1
  68. package/src/cli/load.js +125 -0
  69. package/src/extractors/imports.js +35 -10
  70. package/src/extractors/languages/javascript.js +8 -4
  71. package/src/extractors/languages/prisma.js +1 -1
  72. package/src/extractors/languages/typescript.js +13 -49
  73. package/src/extractors/schemas.js +60 -0
  74. package/src/extractors/tree-sitter-parser.js +39 -0
  75. package/src/mcp/change-plan.js +131 -12
  76. package/src/mcp/impact.js +119 -0
  77. package/src/mcp/server.js +708 -82
  78. package/src/rules/concepts/auth-middleware.md +111 -0
  79. package/src/rules/concepts/money-as-float.md +80 -0
  80. package/src/rules/engine.js +178 -0
  81. package/src/rules/intent.js +178 -0
  82. package/src/rules/registry.js +24 -0
  83. package/src/rules/rules/auth-missing-on-mutating-route.js +255 -0
  84. package/src/rules/rules/money-as-float.js +166 -0
  85. package/src/store/config-loader.js +77 -3
  86. package/src/store/sqlite-store.js +248 -7
  87. package/src/store/sync.js +69 -39
package/README.md CHANGED
@@ -1,13 +1,52 @@
1
- # carto
1
+ # Carto
2
+
3
+ **The portable AI container for your codebase. Package a repo once - every AI tool understands it in seconds, and knows what breaks before it changes anything.**
4
+
5
+ [Docs](docs/) · [Quickstart](docs/quickstart.md) · [Tools](#tools-your-ai-can-call) · [ANCI Spec](docs/anci/v0.1-DRAFT.md) · [Benchmarks](docs/scale.md) · [Changelog](CHANGELOG.md)
2
6
 
3
7
  [![CI](https://github.com/theanshsonkar/carto/actions/workflows/test.yml/badge.svg)](https://github.com/theanshsonkar/carto/actions/workflows/test.yml)
4
8
  [![npm version](https://img.shields.io/npm/v/carto-md)](https://www.npmjs.com/package/carto-md)
5
9
  [![MIT License](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
6
10
  [![npm downloads](https://img.shields.io/npm/dm/carto-md)](https://www.npmjs.com/package/carto-md)
7
11
 
8
- **Carto gives your AI tools a brain for your codebase.** One that remembers decisions across chats, tracks how the code evolves, and flags risky edits before they ship.
12
+ ---
13
+
14
+ > **Docker made apps portable. Carto makes codebases portable for AI.**
15
+
16
+ Every AI tool re-reads your entire codebase from scratch, every single session. Cursor builds its own index. Copilot builds its own. Claude Code builds its own. Same parsing, every tool, every time - and none of them remember what they learned yesterday.
17
+
18
+ Carto fixes that. It packages a repository into a **portable AI container** that captures its architecture, dependencies, engineering history, and safety context - so any AI coding assistant understands the project in seconds instead of rediscovering it from scratch. And because the container knows how everything connects, it can tell you **what breaks before you change it.**
19
+
20
+ One SQLite file on your disk. No network. No telemetry. No cloud.
9
21
 
10
- > *"Touch that file and 22 things could break. That's exactly what you want to know before refactoring."* Claude Code, on supabase
22
+ > **Passive context vs. active guardrail.** Most tools hand the AI context and hope for the best. Carto grades every proposed diff *before* it lands - blast radius, risk, cross-domain violations - and can block a HIGH-risk edit before it ever reaches disk. Context that pushes back.
23
+
24
+ ![Carto answering a blast-radius query on the supabase repo, inside an MCP client (Kiro CLI, running Claude)](docs/screenshots/carto-supabase-blast-radius.png)
25
+
26
+ | | |
27
+ |---|---|
28
+ | 🗺️ **Architecture** | Import graph, routes, models, and auto-detected domains - the whole shape of the repo, mapped once. |
29
+ | 💥 **Blast Radius** | "Touch this file and 22 things break." Transitive impact of any change, in microseconds. |
30
+ | 🧠 **Memory** | Every decision and validated diff is remembered across sessions. Ask *"did we agree on snake_case here?"* six weeks later and get the actual verdict. |
31
+ | ⏳ **History** | Snapshots every commit. Tracks drift, churn, and architectural events. The container gets smarter the longer the repo lives. |
32
+ | 🎯 **Predictive Risk** | Every file scored 0–1: *P(this causes the next incident)*. High-risk files surface before the PR is opened. |
33
+ | 📦 **Portable (ANCI)** | The **structural core** is an open format - `.carto/anci.{yaml,bin}`, stamped with its source commit + a content digest so it's versioned and verifiable. Any AI tool can read it without re-indexing. |
34
+ | 🔐 **Verifiable** | Every container is stamped with its source commit, grammar versions, and a sha256 content digest. Same repo → same digest. Integrity is checked on load. |
35
+
36
+ ---
37
+
38
+ ## Use Carto
39
+
40
+ | | |
41
+ |---|---|
42
+ | ### 🧑‍💻 I use AI coding tools | ### 🔧 I'm building AI dev tools |
43
+ | Install once and Carto auto-wires into every AI tool on your machine. Your assistant instantly knows your architecture, remembers past decisions, and gets blocked from risky edits. **[→ Quick start](#quick-start)** | Consume the portable container directly via the ANCI format, or query it live through a compact MCP surface (a core-10 plus parameterized families). Stop building your own index. **[→ Build on Carto](#build-on-carto)** |
44
+
45
+ **Works with:** Cursor · Claude Code · Codex · Kiro · Claude Desktop · Windsurf · VS Code Copilot · Zed · JetBrains
46
+
47
+ ---
48
+
49
+ ## Quick start
11
50
 
12
51
  ```bash
13
52
  npm install -g carto-md
@@ -15,71 +54,46 @@ cd your-project
15
54
  carto init
16
55
  ```
17
56
 
18
- That's it. Carto auto-wires into every AI tool installed on your machine. Restart it. Your AI now knows your codebase and keeps a memory of every decision it makes inside it.
57
+ That's it. `carto init` reads your repo, builds the container, and wires itself into every AI tool it finds. Restart the tool. Your AI now knows your codebase - and keeps a memory of every decision it makes inside it.
19
58
 
20
- **Works with:** Cursor · Claude Code · Codex · Kiro · Claude Desktop · Windsurf · VS Code Copilot · Zed · JetBrains
59
+ ### Wiring it into your AI tool
21
60
 
22
- Six weeks later, a new chat can ask "did we agree on snake_case here?" and get the actual prior verdict back. Nothing is re-decided.
61
+ `carto init` auto-detects the AI tools on your machine and writes each one's MCP config for you. If you'd rather wire it by hand, the MCP server config is just:
23
62
 
24
- ## What Carto actually does
25
-
26
- ```
27
- ─────────────────────────────────────────────────────────────────────
28
- carto init reads your repo, builds the map (imports, routes,
29
- models, domains, blast radius), wires every AI tool
30
- on your machine. one minute, done.
31
-
32
- every chat your AI gets the 6–12 files it actually needs.
33
- every diff it proposes runs validate_diff first —
34
- risky ones blocked before they hit your screen.
35
- carto also pushes nudges back: "coupling jumped in
36
- AUTH", "two sessions are editing this file."
37
-
38
- brain invariants and conventions are mined from your
39
- import graph. action patterns ("when a route is
40
- added, auth/middleware is touched 89% of the time")
41
- are mined from your git history. nobody writes
42
- these rules.
43
-
44
- timeline every commit takes a snapshot. drift, churn, and
45
- architectural events accumulate. your AI can read
46
- the whole story at any time: "AUTH grew 18 files
47
- and lost stability when payments/billing.ts moved
48
- out." carto gets smarter the longer the repo lives.
49
-
50
- predicts every file is scored: P(causes the next bug).
51
- the score blends blast radius × churn × past
52
- interventions × test coverage. high-risk files
53
- surface on every PR, before the PR is opened.
54
-
55
- always one SQLite file on your disk. no network, no
56
- telemetry, no cloud.
57
- ─────────────────────────────────────────────────────────────────────
63
+ ```json
64
+ {
65
+ "mcpServers": {
66
+ "carto": {
67
+ "command": "carto",
68
+ "args": ["serve"]
69
+ }
70
+ }
71
+ }
58
72
  ```
59
73
 
60
- ---
74
+ Point any MCP client at that and restart it - the tool spawns `carto serve` on demand, and every chat starts with your architecture, blast radius, and past decisions already loaded. Exact config file per tool is below.
61
75
 
62
76
  <details>
63
- <summary>Manual MCP wiring (if your tool wasn't auto-detected)</summary>
77
+ <summary>Manual MCP wiring for every other tool (if it wasn't auto-detected)</summary>
64
78
 
65
- ### Cursor `~/.cursor/mcp.json`
79
+ ### Cursor - `~/.cursor/mcp.json`
66
80
  ```json
67
81
  { "mcpServers": { "carto": { "command": "carto", "args": ["serve"], "cwd": "/your/project" } } }
68
82
  ```
69
83
 
70
- ### Claude Code `<project>/.mcp.json`
84
+ ### Claude Code - `<project>/.mcp.json`
71
85
  ```bash
72
86
  claude mcp add carto -- carto serve
73
87
  ```
74
88
 
75
- ### Codex `~/.codex/config.toml`
89
+ ### Codex - `~/.codex/config.toml`
76
90
  ```toml
77
91
  [mcp_servers.carto]
78
92
  command = "carto"
79
93
  args = ["serve"]
80
94
  ```
81
95
 
82
- ### Kiro `~/.kiro/settings/mcp.json`
96
+ ### Kiro - `~/.kiro/settings/mcp.json`
83
97
  ```json
84
98
  { "mcpServers": { "carto": { "command": "carto", "args": ["serve"], "cwd": "/your/project" } } }
85
99
  ```
@@ -93,177 +107,163 @@ args = ["serve"]
93
107
  { "mcpServers": { "carto": { "command": "carto", "args": ["serve"], "cwd": "/your/project" } } }
94
108
  ```
95
109
 
96
- ### VS Code Copilot `.vscode/mcp.json`
110
+ ### VS Code Copilot - `.vscode/mcp.json`
97
111
  ```json
98
112
  { "servers": { "carto": { "type": "stdio", "command": "carto", "args": ["serve"] } } }
99
113
  ```
100
114
 
101
- ### Windsurf `~/.codeium/windsurf/mcp_config.json`
115
+ ### Windsurf - `~/.codeium/windsurf/mcp_config.json`
102
116
  ```json
103
117
  { "mcpServers": { "carto": { "command": "carto", "args": ["serve"], "cwd": "/your/project" } } }
104
118
  ```
105
119
 
106
120
  </details>
107
121
 
108
- ---
122
+ ### How it works
109
123
 
110
- ## What's actually different
124
+ 1. **`carto init` builds the container.** It parses your repo (imports, routes, models, domains, blast radius), writes it to `.carto/`, and auto-wires every AI tool on your machine.
125
+ 2. **Your AI loads it instead of re-reading everything.** Every chat starts with the architecture already known - the right 6–12 files, not the usual 40+.
126
+ 3. **Every proposed diff is checked first.** Risky changes are graded *before* they hit your screen - and `carto mcp-middleware` can block a HIGH-risk edit before it ever reaches disk. Carto also nudges: *"coupling jumped in AUTH," "two sessions are editing this file."*
127
+ 4. **The container remembers - and knows when it's stale.** Decisions, validations, and drift accumulate in one SQLite file, so the next session picks up where the last left off. And if the repo moves ahead of the index, queries warn *"graph is N commits stale"* instead of silently serving old numbers.
111
128
 
112
- Most code indexers build a snapshot. Cursor's index, Sourcegraph's graph, GitHub's search — they all tell your AI what's in the repo *right now*. That's table stakes.
129
+ ---
113
130
 
114
- Carto does that too and then layers five kinds of memory on top:
131
+ ## An index is not a container
115
132
 
116
- - **Episodic** every diff it validated, every decision it made. Six weeks later, your AI can ask `did_we_discuss_this("snake_case naming")` and get back the prior verdict.
117
- - **Temporal** — snapshots, churn, deltas. *"AUTH grew 18 files this quarter and lost stability when `payments/billing.ts` moved out."*
118
- - **Semantic** — invariants and conventions mined from the import graph itself, not declared by humans.
119
- - **Procedural** — patterns mined from git history. *"When a route gets added, the auth middleware is touched 89% of the time."*
120
- - **Working** — one call that returns what's open, what's drifting, what warnings are unresolved. Read at the start of every session.
133
+ Most tools build an **index** - a snapshot of what's in the repo *right now*. Stateless. Thrown away at the end of the session. Rebuilt from scratch by the next tool.
121
134
 
122
- Your AI tool sees files. Carto sees architecture *and history*. Every chat starts where the last one left off.
135
+ A **container** is different: portable, versioned, and verifiable. Carto's engine keeps **five kinds of memory** a plain index can't - all queryable **live** over MCP:
123
136
 
124
- ---
137
+ - **Structural** - imports, routes, models, domains, blast radius.
138
+ - **Episodic** - every diff validated, every decision made. Queryable weeks later.
139
+ - **Temporal** - snapshots, churn, deltas. *"AUTH grew 18 files and lost stability when `billing.ts` moved out."*
140
+ - **Semantic** - invariants and conventions mined from the import graph, not declared by humans.
141
+ - **Procedural** - patterns mined from git history. *"When a route is added, auth middleware is touched 89% of the time."*
125
142
 
126
- ## What it looks like in practice
143
+ All five run live in the engine - one SQLite file (`.carto/carto.db`), queried over MCP. The **portable container file** - the open [ANCI](docs/anci/v0.1-DRAFT.md) export any tool can read *without* Carto's runtime - today carries the **structural core** (import graph, domains, routes, models, blast radius), stamped with its source commit + a content digest so it's versioned and verifiable. Making the other four memories portable *in the file* is on the roadmap.
127
144
 
128
- ### Stopping a bad refactor before you see the diff
145
+ Your AI tool sees files. Carto's container sees architecture, history, *and* consequences.
129
146
 
130
- The AI is about to propose a 12-line patch. Before showing it to you, it calls `validate_diff`:
147
+ ---
131
148
 
132
- ```
133
- Risk: 🔴 HIGH
134
- Files changed: 1
135
- Union blast radius: 83 transitive dependents
149
+ ## Is this Docker?
136
150
 
137
- Violations
138
- HIGH · high_blast · packages/pg-meta/src/pg-format/index.ts
139
- 83 transitive dependents (threshold: 50)
140
- ```
151
+ No. Docker containerizes **compute** - the OS, libraries, and binaries a CPU needs to run your code anywhere. Carto containerizes **context** - the import graph, blast radius, and structural boundaries an LLM needs to reason about your code without re-reading it.
141
152
 
142
- The AI sees this *before* the diff hits your screen. It revises, splits the change, or asks. Sub-millisecond on a 7,000-file repo.
153
+ There's no daemon, no image pull, no virtual network. A Carto container is just a lightweight `.carto/` folder: a local SQLite database plus an open [ANCI](docs/anci/v0.1-DRAFT.md) map. It costs nothing while idle, answers a blast-radius query in microseconds on a 7,500-file repo, and never touches the cloud. Any AI agent - Claude Code, Cursor, or your CI pipeline - taps into it instantly instead of re-indexing from scratch.
143
154
 
144
- ### Packing context that actually fits
155
+ ---
145
156
 
146
- You ask: *"add rate limiting to /api/users."* The AI calls `get_minimal_context_for_intent` with a 4,000-token budget. Carto runs hybrid retrieval (structural + lexical + semantic), fuses the channels with RRF, boosts files in the same domain and recent churn, and returns the smallest file set that covers the intent — usually 6–12 files instead of the usual 40+.
157
+ ## Build once, load anywhere
147
158
 
148
- ### Remembering decisions across sessions
159
+ The whole point of a container is that it's *one file you can move.* Build it on one machine, load it on another - no re-index, no Carto runtime needed to read it.
149
160
 
150
- Every `validate_diff` call writes a row into `.carto/carto.db`. Five hours later, a different chat asks `did_we_discuss_this("snake_case naming")` and gets back the prior decision verbatim. Your AI stops re-deciding settled questions.
161
+ ```bash
162
+ # machine A - build and pack into a single file
163
+ carto init
164
+ carto export --out myrepo.anci # one file: yaml + bitmap + manifest
151
165
 
152
- ### Spotting the bug before the bug
166
+ # machine B - load it, no re-parsing the repo
167
+ carto load myrepo.anci # unpacks + verifies the content digest
168
+ carto impact src/auth/session.ts # blast radius, instantly
169
+ ```
153
170
 
154
- `get_predictive_risk` returns a 0–1 score per file: P(this file causes the next incident). It combines blast radius, commit churn, cross-domain coupling, prior intervention history, and test coverage. High-risk files surface in `carto check` and on every PR.
171
+ Copy it, attach it to a release, or hand it to a teammate - the receiving machine gets the full structural container in seconds. The digest is verified on load, and loaded contents are treated as **untrusted data, never instructions.**
155
172
 
156
173
  ---
157
174
 
158
- ## In the wild
175
+ ## Under the hood
159
176
 
160
- ![Claude Code reviewing the supabase repo through carto's MCP server](docs/screenshots/claude-code-supabase.png)
177
+ ```
178
+ your repo
179
+
180
+ carto init ──────────── parse (tree-sitter, 17 languages)
181
+
182
+ ┌─────────────────────────────────────────────────────┐
183
+ │ the container ── .carto/ │
184
+ │ │
185
+ │ ├── carto.db SQLite: graph, routes, models, │
186
+ │ │ domains, decisions, history │
187
+ │ ├── bitmap.bin Roaring Bitmap reverse-dep │
188
+ │ │ graph - blast radius in µs │
189
+ │ └── anci.{yaml,bin} portable open format - `carto export` │
190
+ │ packs it into one verifiable .anci file │
191
+ └─────────────────────────────────────────────────────┘
192
+
193
+ your AI tool ── loads it via MCP (core-10 + families) or ANCI directly
194
+ ```
161
195
 
162
- Claude Code analyzing the [supabase](https://github.com/supabase/supabase) repo via carto. Real session, no editing 5,974 files indexed in ~780ms, 86 routes, 4,839 import edges, 7 domains.
196
+ **Blast radius is not search.** Search finds files that *mention* something. Blast radius finds files that *break* when you change something - transitively, over the real import graph. On a 7,500-file repo, one query returns in ~3 microseconds thanks to the bitmap engine.
163
197
 
164
198
  ---
165
199
 
166
- ## How fast
200
+ ## Build on Carto
167
201
 
168
- Measured on real open-source repos, fresh runs on Apple M-series, 8 CPUs, 8 GB RAM.
202
+ The container is an open format. Read it without running Carto's engine:
169
203
 
170
- | Repo | Files | First index | Re-index | DB size |
171
- |---|--:|--:|--:|--:|
172
- | [cal.com](https://github.com/calcom/cal.com) | 4,352 | 3.9s | 805ms | 3.1 MB |
173
- | [supabase/supabase](https://github.com/supabase/supabase) | 6,358 | 5.9s | 967ms | 4.8 MB |
174
- | [vercel/next.js](https://github.com/vercel/next.js) | 6,193 | 6.9s | 978ms | 15.1 MB |
175
- | [microsoft/vscode](https://github.com/microsoft/vscode) | 7,567 | 8.6s | 1.1s | 14.3 MB |
176
-
177
- **Query latency** on vscode (7,567 files):
204
+ ```js
205
+ const { loadAnci } = require('carto-md/src/anci/consumer');
206
+ const reader = loadAnci('./.carto');
178
207
 
179
- - `validate_diff` p50 **84 µs**, p99 **489 µs** (budget was 5 ms / 15 ms)
180
- - `get_blast_radius` — p50 **2.7 µs**, **10.7×** faster than the SQLite path
181
- - `get_high_impact_files` p50 **750 ns**, **559×** faster
182
- - `simulate_change_impact` — p50 **19.3 µs**, multi-file blast radius via bitmap OR-aggregation
208
+ reader.domains; // [{ name: 'AUTH', file_count: 42 }, ...]
209
+ reader.getHighImpactFiles(5); // top 5 by transitive dependents
210
+ reader.blastRadius('src/auth/session.ts'); // { count, hops, files: [...] }
211
+ ```
183
212
 
184
- Bitmap-backed reverse dependency graph. Median speedup across five core tools on vscode: **10.7×**. Synthetic stress at 50K files holds `blast_radius` p50 at **22 µs**. Full table in [`docs/scale.md`](docs/scale.md). Reproducible via `npm run bench:bitmap -- --repo <path>`.
213
+ Or query it live through the MCP server your AI tool already runs.
185
214
 
186
215
  ---
187
216
 
188
217
  ## Tools your AI can call
189
218
 
190
- About 75 tools, grouped by what they're for:
219
+ A small **core** is exposed by default (≈10 tools), with the rest collapsed into a handful of
220
+ **parameterized families** - so your AI tool spends its context on your codebase, not on a tool menu.
191
221
 
192
- | Group | Tools |
222
+ | Core tool | What it's for |
193
223
  |---|---|
194
- | **Structure** | `get_change_plan` · `get_blast_radius` · `simulate_change_impact` · `validate_diff` · `get_context` · `get_routes` · `get_models` · `get_cross_domain` · `get_high_impact_files` |
195
- | **Episodic memory** | `did_we_discuss_this` · `get_decision_log` · `get_session_context` · `get_pending_decisions` · `get_intervention_history` |
196
- | **Temporal** | `get_architectural_drift` · `get_domain_evolution` · `get_hotspot_files` · `get_arch_events` · `get_temporal_context` · `get_change_velocity` · `get_complexity_trend` |
197
- | **Brain** | `get_invariants` · `get_conventions` · `get_canonical_pattern` · `get_action_patterns` · `get_working_memory` · `get_active_suggestions` · `scaffold_for_intent` |
198
- | **Predictive** | `get_predictive_risk` · `get_safety_checklist` · `get_drift_digest` · `get_test_coverage_map` |
199
- | **Retrieval** | `get_minimal_context_for_intent` · `get_progressive_disclosure_tree` |
200
- | **Org / multi-repo** | `get_org_architecture` · `get_service_dependency_graph` · `get_cross_repo_blast_radius` · `find_consumers_of_api` · `get_service_boundary_violations` |
201
- | **Adjacent** | `get_cross_language_call_graph` · `get_iac_resources` · `ingest_otlp_traces` · `get_risk_weighted_blast_radius` · `get_dead_code_with_confidence` · `get_semantic_diff` |
202
-
203
- Full reference at [`docs/api/`](docs/api/). You don't need to memorize any of these — your AI picks the right one mid-task.
204
-
205
- ---
206
-
207
- ## Multi-repo
208
-
209
- Register a group of repos under one org. Carto builds a service graph across them npm, pypi, go-mod, maven edges all resolved.
210
-
211
- ```bash
212
- carto org init
213
- carto org add ../service-a ../service-b ../service-c
214
- carto org sync
215
- ```
216
-
217
- Then ask: *"if I rename `User.email` in service-a, who notices?"* — one `get_cross_repo_blast_radius` call away.
224
+ | `get_architecture` · `get_context` | Orient in the repo; full context for one file |
225
+ | `impact` | Blast radius / multi-file simulate / neighbors / data flow - *what breaks if I touch this?* (`mode=`) |
226
+ | `validate_diff` | Grade a proposed diff (risk + violations) |
227
+ | `get_change_plan` | Natural-language intent files to touch |
228
+ | `memory` | Episodic memory - search past decisions, logs, sessions, interventions (`kind=`) |
229
+ | `history` | Temporal history - drift, hotspots, evolution, churn, health (`view=`) |
230
+ | `patterns` | Mined invariants / conventions / canonical exemplar / co-change patterns (`kind=`) |
231
+ | `get_predictive_risk` · `get_minimal_context_for_intent` | Risk score per file; token-budgeted context picker |
232
+
233
+ Beyond the core, `org(view=…)` covers multi-repo, and advanced/experimental tools (`get_routes`,
234
+ `get_models`, `get_gaps`, `scaffold_for_intent`, …) are available by widening the surface with
235
+ `CARTO_MCP_TIER=advanced` (or `all`), or `carto.config.json` → `mcp.tier`. The ~30 former sibling
236
+ tools (`get_blast_radius`, `did_we_discuss_this`, …) still resolve as **deprecated shims** that
237
+ forward to the new families with byte-identical output.
238
+
239
+ Full reference at [`docs/api/`](docs/api/). You don't need to memorize any of these - your AI picks the right one mid-task.
218
240
 
219
241
  ---
220
242
 
221
- ## MCP middleware
243
+ ## How fast
222
244
 
223
- Carto can sit in front of *any* MCP server and block bad writes before they reach the model:
245
+ Fresh runs on real open-source repos (Apple M-series, 8 CPUs, 8 GB RAM):
224
246
 
225
- ```bash
226
- carto mcp-middleware --block-on HIGH -- claude-code
227
- ```
247
+ | Repo | Files | First index | Re-index | Container size |
248
+ |---|--:|--:|--:|--:|
249
+ | [cal.com](https://github.com/calcom/cal.com) | 4,352 | 3.9s | 805ms | 3.1 MB |
250
+ | [supabase/supabase](https://github.com/supabase/supabase) | 6,358 | 5.9s | 967ms | 4.8 MB |
251
+ | [vercel/next.js](https://github.com/vercel/next.js) | 6,193 | 6.9s | 978ms | 15.1 MB |
252
+ | [microsoft/vscode](https://github.com/microsoft/vscode) | 7,567 | 8.6s | 1.1s | 14.3 MB |
228
253
 
229
- Every `tools/call` that writes to disk is intercepted. Carto synthesizes a unified diff, runs `validate_diff`, and rejects HIGH-risk writes with the violation reasons surfaced back to the AI. Works with any stdio-based MCP server.
254
+ Query latency on vscode (7,567 files): `validate_diff` p50 **84 µs** · `get_blast_radius` p50 **2.7 µs** · `get_high_impact_files` p50 **750 ns**. Full table in [`docs/scale.md`](docs/scale.md).
230
255
 
231
256
  ---
232
257
 
233
- ## Languages and frameworks
258
+ ## Languages
234
259
 
235
- <details>
236
- <summary>Import graph + symbols (any repo)</summary>
260
+ **Import graph + symbols:** JavaScript/TypeScript · Python · Go · Rust · Java/Kotlin · C/C++ · C# · Ruby · PHP · Swift · Dart · R · Prisma · HTML
237
261
 
238
- | Language | Extensions |
239
- |---|---|
240
- | JavaScript / TypeScript | `.js` `.jsx` `.ts` `.tsx` `.mjs` `.cjs` |
241
- | Python | `.py` |
242
- | Go | `.go` |
243
- | Rust | `.rs` |
244
- | Java / Kotlin | `.java` `.kt` |
245
- | C / C++ | `.cpp` `.cc` `.h` `.hpp` |
246
- | C# | `.cs` |
247
- | Ruby | `.rb` |
248
- | PHP | `.php` |
249
- | Swift | `.swift` |
250
- | Dart | `.dart` |
251
- | R | `.r` `.R` |
252
- | Prisma schema | `.prisma` |
253
- | HTML | `.html` (for `fetch()` discovery) |
254
-
255
- TypeScript path aliases from `tsconfig.json` / `jsconfig.json` are resolved into the import graph. `@/components/Button` lands on the real file.
262
+ **Routes:** Express · Next.js · tRPC · React Router · FastAPI · Flask · Django · Gin · Echo · Chi · Actix · Axum · Rocket · Spring · JAX-RS · ASP.NET · Rails · Sinatra
256
263
 
257
- </details>
264
+ **Models:** Prisma · Zod · Drizzle · Pydantic · SQLAlchemy · Django · Go structs · Rust structs · JPA · ActiveRecord · Eloquent
258
265
 
259
- <details>
260
- <summary>Route + model extraction</summary>
261
-
262
- **Routes:** Express, Next.js (App + Pages), tRPC, React Router, FastAPI, Flask, Django, Gin, Echo, Chi, net/http, Actix-web, Axum, Rocket, Spring MVC, JAX-RS, ASP.NET Core, Rails, Sinatra.
263
-
264
- **Models:** Prisma, Zod, Drizzle, TS interfaces, Pydantic, SQLAlchemy, Go structs, Rust structs, JPA, EF Core, ActiveRecord.
265
-
266
- </details>
266
+ > _Planned (not yet extracted end-to-end):_ EF Core.
267
267
 
268
268
  ---
269
269
 
@@ -271,10 +271,11 @@ TypeScript path aliases from `tsconfig.json` / `jsconfig.json` are resolved into
271
271
 
272
272
  | Command | What it does |
273
273
  |---|---|
274
- | `carto init` | Index, generate AGENTS.md, install git hooks, wire MCP into every AI tool found |
275
- | `carto sync` | Re-index changed files (auto-runs on commit / checkout / merge / rebase) |
274
+ | `carto init` | Build the container, generate AGENTS.md, install git hooks, wire every AI tool found |
275
+ | `carto sync` | Re-build changed files (auto-runs on commit / checkout / merge / rebase) |
276
+ | `carto export` | Pack the container into one portable, verifiable `.anci` file |
277
+ | `carto load <file>` | Load an `.anci` container into a queryable `.carto/` - no re-index, digest verified |
276
278
  | `carto serve` | Start the MCP server (your AI tool runs this) |
277
- | `carto agent` | ACP agent mode for Zed / JetBrains |
278
279
  | `carto impact <file>` | Blast radius of one file |
279
280
  | `carto pr-impact` | Diff-shaped impact report between two refs |
280
281
  | `carto check` | Domain health, cross-domain violations, drift |
@@ -282,72 +283,23 @@ TypeScript path aliases from `tsconfig.json` / `jsconfig.json` are resolved into
282
283
  | `carto doctor` | 9-check setup diagnostic |
283
284
  | `carto why <file>` | 3-line file summary |
284
285
  | `carto explain <intent>` | Natural-language intent → architectural plan |
285
- | `carto inspect` | Index paths, sizes, freshness (read-only) |
286
-
287
- ---
288
-
289
- ## ACP agent (Zed / JetBrains / VS Code)
290
-
291
- Carto also runs as a full ACP agent — not just a passive MCP server. It pulls its own context, streams tokens, applies diffs.
292
-
293
- ```json
294
- { "agent_servers": { "Carto": { "command": "carto", "args": ["agent"] } } }
295
- ```
296
-
297
- Bring your own key: Anthropic, OpenAI, Gemini, Groq, Ollama, OpenRouter, Together, Azure.
298
-
299
- ---
300
-
301
- ## GitHub Action
302
-
303
- Drop Carto onto every PR. Sticky comment with blast radius, cross-domain violations, affected routes, risk badge.
304
-
305
- ```yaml
306
- - uses: theanshsonkar/carto@v2.0.9
307
- ```
308
-
309
- `fail-on: HIGH | MEDIUM | LOW` gates the workflow on Carto's verdict. Full config in [`docs/guides/ci-integration.md`](docs/guides/ci-integration.md).
310
-
311
- ---
312
-
313
- ## ANCI — the open format for codebases describing themselves to AI
314
-
315
- Every AI tool today re-indexes from scratch on every session. Cursor builds its own. Cline builds its own. Continue builds its own. Same parsing, every tool, every time.
316
-
317
- **ANCI** (Architecturally Normalized Code Index) fixes that. Two files at `.carto/anci.{yaml,bin}` that describe a codebase's architecture in a form any AI tool can read without doing its own indexing. OpenAPI did this for REST APIs. ANCI does it for codebases.
318
-
319
- `carto sync` writes both files automatically. Spec at [`docs/anci/v0.1-DRAFT.md`](docs/anci/v0.1-DRAFT.md). Carto is the reference implementation; any tool can consume an ANCI pair:
320
-
321
- ```js
322
- const { loadAnci } = require('carto-md/src/anci/consumer');
323
- const reader = loadAnci('./.carto');
324
-
325
- reader.domains; // [{ name: 'AUTH', file_count: 42 }, ...]
326
- reader.getHighImpactFiles(5); // top 5 by transitive dependents
327
- reader.blastRadius('src/auth/session.ts'); // { count, hops, files: [...] }
328
- ```
329
-
330
- > Status: v0.1.0-DRAFT — wire format may change up to v1.0.
331
286
 
332
287
  ---
333
288
 
334
289
  ## What Carto never does
335
290
 
336
291
  - **Sends your code anywhere.** Local only. SQLite on disk. No telemetry.
337
- - **Writes secrets into AGENTS.md.** `.cartoignore` blocks `.env` and credential files by default.
292
+ - **Writes secrets into the container.** `.cartoignore` blocks `.env` and credential files by default.
338
293
  - **Touches your manual notes.** Only writes between `<!-- CARTO:AUTO -->` markers.
339
- - **Forces you to install a C++ toolchain.** Prebuilt binaries for macOS arm64, Linux x64 (glibc + musl), Windows x64. Other platforms fall back to source build, then regex-only extraction.
340
294
  - **Costs money.** MIT. Free forever.
341
295
 
342
296
  ---
343
297
 
344
298
  ## Origin
345
299
 
346
- I was building [Emfirge](https://www.emfirge.cloud) a cloud security agent that maps AWS infrastructure into a graph and simulates the blast radius of every change.
347
-
348
- The AI inside Emfirge kept hallucinating about resources it had only half-seen. So I wrote a module called `cartography.py` that mapped every account into a structured graph the AI could query directly. The hallucinations stopped. The AI worked with facts.
300
+ I was building [Emfirge](https://www.emfirge.cloud) - a cloud security agent that maps AWS infrastructure into a graph and simulates the blast radius of every change. The AI inside it kept hallucinating about resources it had only half-seen, so I wrote a module that mapped every account into a structured graph the AI could query directly. The hallucinations stopped.
349
301
 
350
- Carto is that idea, applied to source code. Same insight: agents stop guessing once they can query the architecture — and they stop forgetting once the architecture remembers them.
302
+ Carto is that idea, applied to source code: package a system into a container the AI can query - and it stops guessing, and stops forgetting.
351
303
 
352
304
  ---
353
305
 
@@ -357,4 +309,4 @@ MIT. Free forever.
357
309
 
358
310
  ---
359
311
 
360
- *Your code changes. Carto knows. Every AI you use knows and remembers.*
312
+ *Your code changes. Carto knows. Every AI you use knows - and remembers.*