carto-md 2.0.8 → 2.1.0

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 (182) hide show
  1. package/CONTRIBUTING.md +19 -15
  2. package/README.md +203 -286
  3. package/docs/anci/v0.1-DRAFT.md +420 -0
  4. package/docs/api/README.md +99 -0
  5. package/docs/api/did_we_discuss_this.md +34 -0
  6. package/docs/api/dismiss_suggestion.md +34 -0
  7. package/docs/api/explain_change_in_natural_language.md +33 -0
  8. package/docs/api/find_consumers_of_api.md +34 -0
  9. package/docs/api/get_action_patterns.md +32 -0
  10. package/docs/api/get_active_drift.md +32 -0
  11. package/docs/api/get_active_suggestions.md +25 -0
  12. package/docs/api/get_ai_cost_attribution.md +32 -0
  13. package/docs/api/get_arch_events.md +42 -0
  14. package/docs/api/get_architectural_drift.md +37 -0
  15. package/docs/api/get_architecture.md +25 -0
  16. package/docs/api/get_blast_radius.md +34 -0
  17. package/docs/api/get_canonical_pattern.md +39 -0
  18. package/docs/api/get_change_plan.md +34 -0
  19. package/docs/api/get_change_velocity.md +32 -0
  20. package/docs/api/get_churn_vs_blast_radius.md +32 -0
  21. package/docs/api/get_complexity_trend.md +39 -0
  22. package/docs/api/get_context.md +34 -0
  23. package/docs/api/get_conventions.md +32 -0
  24. package/docs/api/get_cross_domain.md +25 -0
  25. package/docs/api/get_cross_language_call_graph.md +25 -0
  26. package/docs/api/get_cross_repo_blast_radius.md +34 -0
  27. package/docs/api/get_cross_team_coupling.md +25 -0
  28. package/docs/api/get_data_flow.md +33 -0
  29. package/docs/api/get_dead_code_with_confidence.md +32 -0
  30. package/docs/api/get_decision_log.md +32 -0
  31. package/docs/api/get_dependency_surface.md +25 -0
  32. package/docs/api/get_domain.md +34 -0
  33. package/docs/api/get_domain_evolution.md +39 -0
  34. package/docs/api/get_domain_health.md +32 -0
  35. package/docs/api/get_domains_list.md +25 -0
  36. package/docs/api/get_drift_digest.md +32 -0
  37. package/docs/api/get_env_vars.md +32 -0
  38. package/docs/api/get_evolution_delta.md +36 -0
  39. package/docs/api/get_file_ownership.md +33 -0
  40. package/docs/api/get_file_summary.md +34 -0
  41. package/docs/api/get_high_impact_files.md +32 -0
  42. package/docs/api/get_hot_in_prod_no_tests.md +34 -0
  43. package/docs/api/get_hotspot_files.md +37 -0
  44. package/docs/api/get_iac_resources.md +25 -0
  45. package/docs/api/get_interface_contract.md +33 -0
  46. package/docs/api/get_intervention_history.md +32 -0
  47. package/docs/api/get_invariants.md +37 -0
  48. package/docs/api/get_llm_enrichment.md +33 -0
  49. package/docs/api/get_microservice_cut_points.md +32 -0
  50. package/docs/api/get_microservices_migration_cut_points.md +25 -0
  51. package/docs/api/get_minimal_context_for_intent.md +39 -0
  52. package/docs/api/get_models.md +32 -0
  53. package/docs/api/get_neighbors.md +39 -0
  54. package/docs/api/get_org_architecture.md +25 -0
  55. package/docs/api/get_org_domain_mapping.md +25 -0
  56. package/docs/api/get_pending_decisions.md +32 -0
  57. package/docs/api/get_predictive_risk.md +32 -0
  58. package/docs/api/get_progressive_disclosure_tree.md +25 -0
  59. package/docs/api/get_recent_decisions.md +37 -0
  60. package/docs/api/get_risk_weighted_blast_radius.md +32 -0
  61. package/docs/api/get_routes.md +25 -0
  62. package/docs/api/get_safety_checklist.md +33 -0
  63. package/docs/api/get_semantic_diff.md +34 -0
  64. package/docs/api/get_service_boundary_violations.md +25 -0
  65. package/docs/api/get_service_dependency_graph.md +25 -0
  66. package/docs/api/get_session_context.md +32 -0
  67. package/docs/api/get_similar_patterns.md +39 -0
  68. package/docs/api/get_stale_docs.md +25 -0
  69. package/docs/api/get_structure.md +25 -0
  70. package/docs/api/get_temporal_context.md +34 -0
  71. package/docs/api/get_test_coverage_map.md +25 -0
  72. package/docs/api/get_token_budget_report.md +36 -0
  73. package/docs/api/get_upgrade_risk.md +25 -0
  74. package/docs/api/get_working_memory.md +25 -0
  75. package/docs/api/ingest_otlp_traces.md +34 -0
  76. package/docs/api/scaffold_for_intent.md +34 -0
  77. package/docs/api/search_routes.md +34 -0
  78. package/docs/api/simulate_change_impact.md +37 -0
  79. package/docs/api/validate_change.md +39 -0
  80. package/docs/api/validate_diff.md +39 -0
  81. package/docs/concepts/anci.md +87 -0
  82. package/docs/concepts/blast-radius.md +66 -0
  83. package/docs/concepts/domains.md +91 -0
  84. package/docs/concepts/import-graph.md +102 -0
  85. package/docs/concepts/mcp-integration.md +148 -0
  86. package/docs/guides/adding-feature-safely.md +101 -0
  87. package/docs/guides/ci-integration.md +175 -0
  88. package/docs/guides/monorepo-setup.md +121 -0
  89. package/docs/guides/onboarding-new-engineer.md +121 -0
  90. package/docs/guides/pre-merge-review.md +139 -0
  91. package/docs/migration/v1-to-v2.md +110 -0
  92. package/docs/quickstart.md +95 -0
  93. package/docs/scale.md +129 -0
  94. package/docs/troubleshooting.md +180 -0
  95. package/package.json +12 -5
  96. package/scripts/gen-api-docs.js +170 -0
  97. package/scripts/postinstall.js +391 -24
  98. package/src/acp/agent.js +83 -11
  99. package/src/acp/config.js +64 -0
  100. package/src/acp/persistence.js +146 -0
  101. package/src/acp/providers/anthropic.js +179 -27
  102. package/src/acp/providers/index.js +15 -2
  103. package/src/acp/providers/openai.js +164 -38
  104. package/src/acp/providers/sse.js +82 -0
  105. package/src/acp/safety.js +128 -0
  106. package/src/acp/session.js +73 -0
  107. package/src/adjacent/call-graph.js +170 -0
  108. package/src/adjacent/iac.js +167 -0
  109. package/src/adjacent/llm-enrich.js +35 -0
  110. package/src/adjacent/runtime.js +216 -0
  111. package/src/adjacent/semantic-diff.js +143 -0
  112. package/src/agents/leiden.js +4 -4
  113. package/src/agents/scan-structure.js +2 -2
  114. package/src/ai/context-builder.js +215 -0
  115. package/src/ai/retrieval/lexical.js +122 -0
  116. package/src/ai/retrieval/rrf.js +121 -0
  117. package/src/ai/retrieval/semantic.js +35 -0
  118. package/src/ai/retrieval/structural.js +82 -0
  119. package/src/ai/tools.js +423 -0
  120. package/src/anci/consumer.js +305 -0
  121. package/src/anci/deserialize.js +160 -0
  122. package/src/anci/emit.js +85 -0
  123. package/src/anci/serialize.js +264 -0
  124. package/src/anci/yaml.js +401 -0
  125. package/src/bitmap/index.js +1 -1
  126. package/src/bitmap/tools.js +2 -2
  127. package/src/brain/conventions/index.js +185 -0
  128. package/src/brain/index.js +31 -0
  129. package/src/brain/invariants/index.js +252 -0
  130. package/src/brain/procedural/index.js +181 -0
  131. package/src/brain/suggestions/index.js +153 -0
  132. package/src/brain/working/index.js +170 -0
  133. package/src/cli/anci.js +237 -0
  134. package/src/cli/check.js +47 -1
  135. package/src/cli/diff.js +83 -0
  136. package/src/cli/doctor.js +270 -0
  137. package/src/cli/explain.js +61 -0
  138. package/src/cli/index.js +115 -0
  139. package/src/cli/init.js +144 -6
  140. package/src/cli/inspect.js +1 -1
  141. package/src/cli/org.js +172 -0
  142. package/src/cli/pr-impact.js +554 -0
  143. package/src/cli/serve.js +1 -1
  144. package/src/cli/status.js +211 -0
  145. package/src/cli/sync.js +2 -2
  146. package/src/cli/temporal.js +188 -0
  147. package/src/cli/validate.js +201 -0
  148. package/src/cli/watch.js +4 -4
  149. package/src/cli/why.js +101 -0
  150. package/src/extractors/frameworks.js +236 -0
  151. package/src/extractors/languages/dart.js +138 -0
  152. package/src/extractors/languages/go.js +11 -1
  153. package/src/extractors/languages/javascript.js +16 -6
  154. package/src/extractors/languages/kotlin.js +169 -0
  155. package/src/extractors/languages/php.js +195 -0
  156. package/src/extractors/languages/python.js +12 -1
  157. package/src/extractors/languages/swift.js +140 -0
  158. package/src/extractors/languages/typescript.js +15 -2
  159. package/src/extractors/plugin-api.js +102 -0
  160. package/src/mcp/change-plan.js +8 -8
  161. package/src/mcp/files-without-tests.js +285 -0
  162. package/src/mcp/middleware/index.js +451 -0
  163. package/src/mcp/server.js +2292 -0
  164. package/src/mcp/validate.js +1 -1
  165. package/src/org/detect.js +262 -0
  166. package/src/org/queries.js +144 -0
  167. package/src/org/store.js +173 -0
  168. package/src/org/sync.js +106 -0
  169. package/src/predictive/cut-points.js +83 -0
  170. package/src/predictive/drift-digest.js +88 -0
  171. package/src/predictive/ownership.js +145 -0
  172. package/src/predictive/risk-score.js +121 -0
  173. package/src/predictive/validate-change.js +55 -0
  174. package/src/store/store-adapter.js +3 -3
  175. package/src/store/{sync-v2.js → sync.js} +105 -16
  176. package/src/temporal/backfill.js +211 -0
  177. package/src/temporal/delta.js +85 -0
  178. package/src/temporal/events.js +180 -0
  179. package/src/temporal/queries.js +358 -0
  180. package/src/temporal/snapshot.js +151 -0
  181. package/src/temporal/store.js +400 -0
  182. package/src/mcp/server-v2.js +0 -986
package/README.md CHANGED
@@ -5,9 +5,9 @@
5
5
  [![MIT License](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
6
6
  [![npm downloads](https://img.shields.io/npm/dm/carto-md)](https://www.npmjs.com/package/carto-md)
7
7
 
8
- **The structural intelligence layer for AI coding tools.**
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.
9
9
 
10
- Your AI coding tool sees files. Carto sees architecture — domains, blast radius, import graph, routes. Every AI tool you use stops guessing about your codebase and starts knowing it.
10
+ > *"Touch that file and 22 things could break. That's exactly what you want to know before refactoring."* Claude Code, on supabase
11
11
 
12
12
  ```bash
13
13
  npm install -g carto-md
@@ -15,412 +15,329 @@ cd your-project
15
15
  carto init
16
16
  ```
17
17
 
18
- That's it. Carto auto-wires itself into every AI tool you have installed. Restart your AI tool and it now knows your codebase architecturally.
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.
19
19
 
20
- **Works with:** Cursor · Claude Code · Codex · Kiro · Claude Desktop · Windsurf · VS Code Copilot · JetBrains · Zed
20
+ **Works with:** Cursor · Claude Code · Codex · Kiro · Claude Desktop · Windsurf · VS Code Copilot · Zed · JetBrains
21
21
 
22
- ---
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.
23
23
 
24
- ## Use it with your AI tool
24
+ ## What Carto actually does
25
25
 
26
- `carto init` auto-wires the MCP server into every AI tool it detects. If yours wasn't detected, here's the manual config — **one block, copy-paste, done.**
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
+ ─────────────────────────────────────────────────────────────────────
58
+ ```
59
+
60
+ ---
27
61
 
28
- ### Cursor
62
+ <details>
63
+ <summary>Manual MCP wiring (if your tool wasn't auto-detected)</summary>
29
64
 
30
- `carto init` writes this for you. Manual: `~/.cursor/mcp.json`
65
+ ### Cursor `~/.cursor/mcp.json`
31
66
  ```json
32
67
  { "mcpServers": { "carto": { "command": "carto", "args": ["serve"], "cwd": "/your/project" } } }
33
68
  ```
34
69
 
35
- ### Claude Code (CLI)
36
-
37
- `carto init` writes `<project>/.mcp.json` for you when Claude Code is detected (`claude` binary on PATH or `~/.claude/` exists). Manual:
70
+ ### Claude Code — `<project>/.mcp.json`
38
71
  ```bash
39
72
  claude mcp add carto -- carto serve
40
73
  ```
41
- Or create `.mcp.json` at the project root:
42
- ```json
43
- { "mcpServers": { "carto": { "command": "carto", "args": ["serve"] } } }
44
- ```
45
-
46
- ### Codex (CLI)
47
74
 
48
- `carto init` writes `~/.codex/config.toml` for you when Codex is detected (`codex` binary on PATH or `~/.codex/` exists). Manual:
49
- ```bash
50
- codex mcp add carto -- carto serve
51
- ```
52
- Or edit `~/.codex/config.toml`:
75
+ ### Codex `~/.codex/config.toml`
53
76
  ```toml
54
77
  [mcp_servers.carto]
55
78
  command = "carto"
56
79
  args = ["serve"]
57
- cwd = "/your/project"
58
- enabled = true
59
80
  ```
60
81
 
61
- ### Kiro
62
-
63
- `carto init` writes this for you. Manual: `~/.kiro/settings/mcp.json`
82
+ ### Kiro — `~/.kiro/settings/mcp.json`
64
83
  ```json
65
84
  { "mcpServers": { "carto": { "command": "carto", "args": ["serve"], "cwd": "/your/project" } } }
66
85
  ```
67
86
 
68
87
  ### Claude Desktop
69
-
70
- `carto init` writes this for you (cross-platform). Manual paths:
71
88
  - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
72
89
  - Windows: `%APPDATA%\Claude\claude_desktop_config.json`
73
- - Linux: `~/.config/Claude/claude_desktop_config.json` (community Linux builds)
90
+ - Linux: `~/.config/Claude/claude_desktop_config.json`
74
91
 
75
92
  ```json
76
93
  { "mcpServers": { "carto": { "command": "carto", "args": ["serve"], "cwd": "/your/project" } } }
77
94
  ```
78
95
 
79
- ### VS Code Copilot
80
-
81
- `carto init` writes `<project>/.vscode/mcp.json` for you when the `code` binary is on PATH. Manual: `.vscode/mcp.json` in your project root, or Command Palette → `MCP: Add Server`. Note: VS Code uses `servers` (not `mcpServers`) and requires `"type": "stdio"`.
96
+ ### VS Code Copilot — `.vscode/mcp.json`
82
97
  ```json
83
98
  { "servers": { "carto": { "type": "stdio", "command": "carto", "args": ["serve"] } } }
84
99
  ```
85
100
 
86
- ### Windsurf
87
-
88
- `carto init` writes this for you when Windsurf is detected. Manual: `~/.codeium/windsurf/mcp_config.json`
101
+ ### Windsurf — `~/.codeium/windsurf/mcp_config.json`
89
102
  ```json
90
103
  { "mcpServers": { "carto": { "command": "carto", "args": ["serve"], "cwd": "/your/project" } } }
91
104
  ```
92
105
 
93
- ### Zed / JetBrains / VS Code (full agent mode)
94
-
95
- Carto also runs as a full **ACP agent** — not just a passive MCP server, but an active coding agent with architectural awareness. See [ACP Agent](#acp-agent-zed--jetbrains--vs-code) below.
106
+ </details>
96
107
 
97
108
  ---
98
109
 
99
- ## What changes for your AI
110
+ ## What's actually different
100
111
 
101
- Without carto, your AI greps text and guesses. With carto, it queries structural facts:
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.
102
113
 
103
- > *"Add rate limiting to /api/users"*
114
+ Carto does that too and then layers five kinds of memory on top:
104
115
 
105
- **Without carto:** AI grep-searches your codebase, finds 12 files mentioning "users", picks 3 at random, hopes for the best.
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.
106
121
 
107
- **With carto:** AI calls `get_change_plan("add rate limiting to /api/users")` and gets back:
108
- - The exact route handler file
109
- - All 7 files that import it (blast radius)
110
- - The AUTH domain it lives in
111
- - Similar middleware patterns already in the codebase
112
- - Cross-domain dependencies that could break
122
+ Your AI tool sees files. Carto sees architecture *and history*. Every chat starts where the last one left off.
113
123
 
114
- Your AI's response goes from "here's a guess" to "here's the right change with the architectural context."
124
+ ---
115
125
 
116
- ### Catching bad changes before save
126
+ ## What it looks like in practice
117
127
 
118
- The harder problem isn't finding the right file — it's stopping a confident-sounding AI from writing a refactor that breaks the rest of the repo. Carto exposes a diff-shaped query the AI can call before the user accepts a change:
128
+ ### Stopping a bad refactor before you see the diff
119
129
 
120
- > *AI proposes a 12-line patch to `packages/pg-meta/src/pg-format/index.ts`. Before showing the diff, it calls `validate_diff(patch)`.*
130
+ The AI is about to propose a 12-line patch. Before showing it to you, it calls `validate_diff`:
121
131
 
122
132
  ```
123
- # Diff Validation
124
-
125
- **Risk:** 🔴 HIGH
126
- **Files changed:** 1
127
- **Union blast radius:** 83 transitive dependents
133
+ Risk: 🔴 HIGH
134
+ Files changed: 1
135
+ Union blast radius: 83 transitive dependents
128
136
 
129
- ## Violations (1)
130
-
131
- | Severity | Kind | File | Detail |
132
- |----------|-------------|----------------------------------------|-----------------------------------------------------------------|
133
- | HIGH | high_blast | `packages/pg-meta/src/pg-format/index.ts` | Modifying this file affects 83 transitive dependents (>50). |
137
+ Violations
138
+ HIGH · high_blast · packages/pg-meta/src/pg-format/index.ts
139
+ 83 transitive dependents (threshold: 50)
134
140
  ```
135
141
 
136
- The AI sees this *before* it proposes the diff. It revises its plan, splits the change, or asks the user. The bad refactor never makes it to the screen. Sub-millisecond on a 7,000-file repo — see the **Benchmarks** section below.
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.
137
143
 
138
- Every `validate_diff` call is also written to a local SQLite log, so a session that runs five hours later can ask `did_we_discuss_this("snake_case naming")` and get back the prior decision. The AI stops re-deciding settled questions.
144
+ ### Packing context that actually fits
139
145
 
140
- ### In the wild
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+.
141
147
 
142
- ![Claude Code reviewing the supabase repo through carto's MCP server](docs/screenshots/claude-code-supabase.png)
148
+ ### Remembering decisions across sessions
143
149
 
144
- *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. The agent's own verdict at the bottom: "useful, especially for a large codebase like supabase. The blast radius + cross-domain tools are the most valuable."*
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.
145
151
 
146
- ---
147
-
148
- ## Languages and frameworks
152
+ ### Spotting the bug before the bug
149
153
 
150
- ### Import graph + symbols (any repo)
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.
151
155
 
152
- | Language | Extensions |
153
- |----------|-----------|
154
- | JavaScript / TypeScript | `.js` `.jsx` `.ts` `.tsx` `.mjs` `.cjs` |
155
- | Python | `.py` |
156
- | Go | `.go` |
157
- | Rust | `.rs` |
158
- | Java | `.java` |
159
- | C / C++ | `.cpp` `.cc` `.cxx` `.h` `.hpp` |
160
- | C# | `.cs` |
161
- | Ruby | `.rb` |
156
+ ---
162
157
 
163
- ### Route extraction (framework-aware)
158
+ ## In the wild
164
159
 
165
- | Framework | Language |
166
- |-----------|---------|
167
- | Express, Next.js (App + Pages), tRPC, React Router | TypeScript / JavaScript |
168
- | FastAPI, Flask, Django | Python |
169
- | Gin, Echo, Chi, net/http | Go |
170
- | Actix-web, Axum, Rocket | Rust |
171
- | Spring MVC / Boot, JAX-RS | Java |
172
- | ASP.NET Core | C# |
173
- | Rails, Sinatra | Ruby |
160
+ ![Claude Code reviewing the supabase repo through carto's MCP server](docs/screenshots/claude-code-supabase.png)
174
161
 
175
- ### Model extraction
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.
176
163
 
177
- | ORM / Schema | Language |
178
- |-------------|---------|
179
- | Prisma, Zod, Drizzle, TypeScript interfaces | TypeScript / JavaScript |
180
- | Pydantic, SQLAlchemy | Python |
181
- | Go structs | Go |
182
- | Rust structs | Rust |
183
- | JPA `@Entity`, Java records | Java |
184
- | EF Core, C# records | C# |
185
- | ActiveRecord | Ruby |
164
+ ---
186
165
 
187
- ### TypeScript path aliases
166
+ ## How fast
188
167
 
189
- Reads `tsconfig.json` / `jsconfig.json` `paths` config. `@/components/Button` resolves to the actual file in the import graph — blast radius works correctly for Next.js and Vite projects.
168
+ Measured on real open-source repos, fresh runs on Apple M-series, 8 CPUs, 8 GB RAM.
190
169
 
191
- ---
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 |
192
176
 
193
- ## ACP Agent (Zed / JetBrains / VS Code)
177
+ **Query latency** on vscode (7,567 files):
194
178
 
195
- Beyond MCP, Carto runs as a full **ACP agent** an active coding agent with built-in architectural awareness.
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
196
183
 
197
- ```
198
- User: "Add rate limiting to /api/users"
199
-
200
- Carto auto-queries its own SQLite:
201
- - Blast radius of relevant files
202
- - Domain context (AUTH)
203
- - Similar patterns in codebase
204
-
205
- Builds rich prompt with structural context
206
-
207
- Sends to LLM (your API key) → streams answer + diffs back to editor
208
- ```
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>`.
209
185
 
210
- ### Setup in Zed
186
+ ---
211
187
 
212
- `~/.config/zed/settings.json`:
213
- ```json
214
- {
215
- "agent_servers": {
216
- "Carto": { "command": "carto", "args": ["agent"] }
217
- }
218
- }
219
- ```
188
+ ## Tools your AI can call
220
189
 
221
- ### Bring Your Own Key
190
+ About 75 tools, grouped by what they're for:
222
191
 
223
- Carto supports any LLM provider — configure in your editor:
192
+ | Group | Tools |
193
+ |---|---|
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` |
224
202
 
225
- | Provider | Models |
226
- |----------|--------|
227
- | Anthropic | Claude Sonnet 4, Haiku |
228
- | OpenAI | GPT-4o, GPT-4o-mini, o1, o3 |
229
- | Google Gemini | Gemini 2.5 Pro, 2.5 Flash |
230
- | Ollama | Any local model (free) |
231
- | OpenRouter | Any model via single API |
232
- | Groq | Ultra-fast inference |
233
- | Together AI | Open-source models |
234
- | Azure OpenAI | Enterprise deployments |
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.
235
204
 
236
205
  ---
237
206
 
238
- ## The 22 MCP tools
239
-
240
- Once carto is wired in, your AI tool can call any of these mid-task. You don't need to memorize them — your AI will pick the right ones.
241
-
242
- | Tool | What it returns |
243
- |------|----------------|
244
- | `get_architecture()` | 500-word project overview: domains, entry points, stack, key patterns. **Use this first.** |
245
- | `get_change_plan(intent)` | Given "add rate limiting to /api/users" → files to touch, domains affected, blast radius, similar patterns |
246
- | `get_blast_radius(file)` | All files affected by changing a given file, with hop distance |
247
- | `simulate_change_impact(files)` | Union of all files transitively affected by changing **multiple** files at once. Powered by the bitmap engine — sub-millisecond on 7K-file repos. |
248
- | `validate_diff(diff)` | Given a unified diff: violations (cross-domain imports, high-blast files), blast radius per file, risk level (SAFE/LOW/MEDIUM/HIGH), suggestions. Each call is recorded in the **episodic memory** log so other tools can ask "did we discuss this?". Sub-15ms p99. |
249
- | `get_context(file)` | Everything about a file: domain, blast radius, neighbors, routes, models |
250
- | `get_file_summary(file)` | What a file does, its role, key deps and dependents |
251
- | `get_similar_patterns(file)` | Files with same domain, route shape, or shared deps — find conventions before writing new code |
252
- | `get_routes()` | All API endpoints with file mapping |
253
- | `get_structure()` | Import graph, entry points, high-impact files, tech stack |
254
- | `get_domain(name)` | All routes, models, functions for a domain. Lazily regenerated when stale. |
255
- | `get_neighbors(file, hops)` | Import graph neighbors: nodes and edges |
256
- | `get_cross_domain()` | Import edges that cross domain boundaries |
257
- | `search_routes(query)` | Search API routes by path or method |
258
- | `get_models(domain?)` | All data models, optionally filtered by domain |
259
- | `get_high_impact_files(n)` | Top N files by blast radius |
260
- | `get_env_vars(domain?)` | All env vars with domain mapping |
261
- | `get_domains_list()` | All detected domains with file, route, model counts |
262
- | `get_recent_decisions(time_range, kind?)` | Recent validation decisions and architectural choices the AI has made in this project |
263
- | `get_session_context(session_id?)` | Full context for an AI session: every decision and intervention, ordered chronologically |
264
- | `did_we_discuss_this(topic)` | Substring search over the episodic memory log — avoid re-deciding settled questions |
265
- | `get_intervention_history(file?)` | Past Carto-issued violations and suggestions, optionally filtered by file |
266
-
267
- **All MCP queries:** **<5ms** on every benchmarked repo.
268
-
269
- ## Episodic Memory
270
-
271
- Carto remembers every diff it validates. The `validate_diff` tool writes one row per call into a local SQLite log (`ai_sessions`/`decisions`/`interventions` tables) — so a session that runs five hours later can still ask `did_we_discuss_this("snake_case naming")` and get back the prior decision. The log lives next to the index in `.carto/carto.db` — never sent over the network, never shared between projects.
207
+ ## Multi-repo
272
208
 
273
- ---
209
+ Register a group of repos under one org. Carto builds a service graph across them — npm, pypi, go-mod, maven edges all resolved.
274
210
 
275
- ## Domain detection
211
+ ```bash
212
+ carto org init
213
+ carto org add ../service-a ../service-b ../service-c
214
+ carto org sync
215
+ ```
276
216
 
277
- Carto uses **Leiden+CPM graph clustering** — files that import each other heavily cluster together. Domain names are inferred from path tokens, with keyword hints for well-known patterns (AUTH, PAYMENTS, DATABASE, etc.).
217
+ Then ask: *"if I rename `User.email` in service-a, who notices?"* one `get_cross_repo_blast_radius` call away.
278
218
 
279
- **Adaptive strategy:** Repos under 100 files use keyword-only clustering (avoids over-fragmentation). Larger repos with dense import graphs get graph-based clustering with a gamma that scales continuously with repo size.
219
+ ---
280
220
 
281
- Works on any repo — not just SaaS apps. vscode gets AUTH/EVENTS/DATABASE. zed (Rust) gets DATABASE/AUTH/EVENTS. A game engine would get RENDERER/PHYSICS/AUDIO.
221
+ ## MCP middleware
282
222
 
283
- Custom domains via `carto.config.json`:
284
- ```json
285
- {
286
- "domains": {
287
- "EDITOR": ["editor", "monaco", "text"],
288
- "WORKBENCH": ["workbench", "layout", "panel"]
289
- }
290
- }
291
- ```
223
+ Carto can sit in front of *any* MCP server and block bad writes before they reach the model:
292
224
 
293
- Full schema with anchor pinning (forces files into a domain regardless of clustering):
294
- ```json
295
- {
296
- "domains": {
297
- "AUTH": {
298
- "keywords": ["auth", "login", "session"],
299
- "anchor": ["src/auth/session.ts", "src/auth/middleware.ts"]
300
- }
301
- }
302
- }
225
+ ```bash
226
+ carto mcp-middleware --block-on HIGH -- claude-code
303
227
  ```
304
228
 
305
- **Stability tracking:** Carto tracks domain assignments across syncs. If >5% of files change domain, `carto check` flags it as unstable. Two consecutive syncs with no code changes always produce 0% drift.
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.
306
230
 
307
231
  ---
308
232
 
309
- ## CLI commands
233
+ ## Languages and frameworks
310
234
 
311
- | Command | What it does |
312
- |---------|-------------|
313
- | `carto init` | Detect project, index codebase, generate AGENTS.md, install git hooks (pre-commit, post-checkout, post-merge, post-rewrite), auto-wire MCP into every AI tool found |
314
- | `carto sync` | Full re-index (skips unchanged files via mtime+size cache). Called automatically by git hooks on commit/checkout/merge/rebase. |
315
- | `carto serve` | Start MCP server (called by your AI tool — usually you don't run this directly). On every file-aware query the server mtime+size-checks the file and re-parses inline if stale. |
316
- | `carto watch` | **Optional.** Live re-index on every file save. Not required — git hooks + lazy MCP re-parse keep the index fresh by default. Use only for AI-heavy workflows that write 50+ files between commits. |
317
- | `carto agent` | Start ACP agent mode (for Zed / JetBrains / VS Code) |
318
- | `carto impact <file>` | Blast radius: risk level, affected files, routes at risk |
319
- | `carto check` | Cross-domain violations, high-risk uncommitted changes, domain health |
320
- | `carto inspect` | Read-only diagnostic: index paths, sizes, freshness, bitmap sidecar shape, top-impact files, schema version, sync timestamps. `--json` for piping into `jq`. Never triggers a rebuild. |
321
- | `carto remove` | Remove AGENTS.md and .carto/ from project |
235
+ <details>
236
+ <summary>Import graph + symbols (any repo)</summary>
322
237
 
323
- ---
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) |
324
254
 
325
- ## Benchmarks
255
+ TypeScript path aliases from `tsconfig.json` / `jsconfig.json` are resolved into the import graph. `@/components/Button` lands on the real file.
326
256
 
327
- Measured on real open-source repos. Apple M-series, 8 CPUs, 8GB RAM. SHAs pinned in `~/carto-test-repos`. Reproducible via `~/carto-test-repos/run-bench.sh`.
257
+ </details>
328
258
 
329
- ### Indexing speed
259
+ <details>
260
+ <summary>Route + model extraction</summary>
330
261
 
331
- | Repo | Language | Indexed Files | First Run | Second Run | DB Size | Import Edges |
332
- |------|----------|---------------|-----------|------------|---------|--------------|
333
- | [prisma/prisma](https://github.com/prisma/prisma) | TypeScript | 961 | **961ms** | **431ms** | 0.7 MB | 1,387 |
334
- | [supabase/supabase](https://github.com/supabase/supabase) | TypeScript | 6,330 | **5.4s** | **1.2s** | 4.0 MB | 5,321 |
335
- | [microsoft/vscode](https://github.com/microsoft/vscode) | TypeScript | 7,567 | **7.7s** | **1.0s** | 6.7 MB | 13,420 |
336
- | [zed-industries/zed](https://github.com/zed-industries/zed) | Rust | 1,752 | **3.0s** | **491ms** | 4.4 MB | 2,113 |
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.
337
263
 
338
- **Indexed Files** counts what Carto actually parses `.ts/.js/.py/.go/.rs/...` after excluding `node_modules`, build output, and per-file `*.test.*` / `*.spec.*` / `*.stories.*` / `test_*.py` patterns. The on-disk file count of the repo is larger.
264
+ **Models:** Prisma, Zod, Drizzle, TS interfaces, Pydantic, SQLAlchemy, Go structs, Rust structs, JPA, EF Core, ActiveRecord.
339
265
 
340
- **Second Run** = `carto sync` after no changes. mtime+size checked before reading content — if nothing changed, nothing is re-parsed.
266
+ </details>
341
267
 
342
- ### MCP query latency (bitmap engine vs SQLite)
268
+ ---
343
269
 
344
- Carto's MCP query path is bitmap-backed on five tools, plus a sixth (`simulate_change_impact`) that's only feasible with bitmap OR-aggregation. Speedups measured against the same data, same DB, same machine — bitmap path vs the equivalent SQLite path.
270
+ ## CLI
345
271
 
346
- | Tool | vscode (7,567 files) | Speedup vs SQLite |
347
- |------|---------------------:|------------------:|
348
- | `get_blast_radius` | sub-ms | **10.7×** |
349
- | `get_cross_domain` | 2.1ms | **6.2×** |
350
- | `get_high_impact_files` | sub-ms | **559×** |
351
- | `get_similar_patterns` | sub-ms | **73×** |
352
- | `simulate_change_impact` | sub-ms | **6.5×** (no SQLite equivalent at this latency) |
272
+ | Command | What it does |
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) |
276
+ | `carto serve` | Start the MCP server (your AI tool runs this) |
277
+ | `carto agent` | ACP agent mode for Zed / JetBrains |
278
+ | `carto impact <file>` | Blast radius of one file |
279
+ | `carto pr-impact` | Diff-shaped impact report between two refs |
280
+ | `carto check` | Domain health, cross-domain violations, drift |
281
+ | `carto status` | One-screen project health |
282
+ | `carto doctor` | 9-check setup diagnostic |
283
+ | `carto why <file>` | 3-line file summary |
284
+ | `carto explain <intent>` | Natural-language intent → architectural plan |
285
+ | `carto inspect` | Index paths, sizes, freshness (read-only) |
353
286
 
354
- Median speedup across all five tools on vscode: **10.7×**. Smaller repos hit higher peaks — laravel-framework `get_high_impact_files` clocks at 155× on the smaller graph. Reproducible via `npm run bench:bitmap -- --repo <path>`.
287
+ ---
355
288
 
356
- ### `validate_diff` latency
289
+ ## ACP agent (Zed / JetBrains / VS Code)
357
290
 
358
- The new diff-shaped query that lets the AI ask "is this patch safe?" before showing it to the user. Profiled with a representative 20-line diff against 20 random mid-blast-radius files per repo, 1000 calls each.
291
+ Carto also runs as a full ACP agent not just a passive MCP server. It pulls its own context, streams tokens, applies diffs.
359
292
 
360
- | Repo | Files | p50 | p99 |
361
- |------|-------|----:|----:|
362
- | supabase | 6,259 | **0.082ms** | **0.298ms** |
363
- | vscode | 7,567 | **0.084ms** | **0.489ms** |
293
+ ```json
294
+ { "agent_servers": { "Carto": { "command": "carto", "args": ["agent"] } } }
295
+ ```
364
296
 
365
- Budget was p50 5ms, p99 15ms. Both targets are cleared by 30-60×. The bitmap engine handles every blast-radius and cross-domain query in microseconds; what's left is diff parsing + result aggregation. Reproducible via `node bench/validation-perf/index.js --repo <path>`.
297
+ Bring your own key: Anthropic, OpenAI, Gemini, Groq, Ollama, OpenRouter, Together, Azure.
366
298
 
367
- ### Domains detected
299
+ ---
368
300
 
369
- | Repo | Domains |
370
- |------|---------|
371
- | prisma | CORE · DATABASE · AUTH · EVENTS |
372
- | supabase | CORE · AUTH · DATABASE · PAYMENTS · NOTIFICATIONS · EVENTS · TRPC |
373
- | vscode | EXTENSIONS · AUTH · EVENTS · DATABASE · EXTENSION · CLI · CORE |
374
- | zed (Rust) | CORE · DATABASE · AUTH · EVENTS · PAYMENTS · TRPC · NOTIFICATIONS |
301
+ ## GitHub Action
375
302
 
376
- vscode at 7,567 indexed files in under 8 seconds. Rust import graph working on zed (2,113 edges from `mod` declarations and `use crate::` paths).
303
+ Drop Carto onto every PR. Sticky comment with blast radius, cross-domain violations, affected routes, risk badge.
377
304
 
378
- ### Accuracy
305
+ ```yaml
306
+ - uses: theanshsonkar/carto@v2.0.9
307
+ ```
379
308
 
380
- 12 corpus repos pass `node test/accuracy-corpus.js --samples 100` full parity between the bitmap path and the SQLite path on `blastRadius`, `crossDomain`, `highImpactFiles`, and `simulateChangeImpact`. The bitmap layer is a speedup, never a behavior change.
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).
381
310
 
382
311
  ---
383
312
 
384
- ## How it works
313
+ ## ANCI the open format for codebases describing themselves to AI
385
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: [...] }
386
328
  ```
387
- carto init
388
-
389
- Discovers all files (no cap — SQLite handles the volume)
390
- mtime+size check → skip unchanged files
391
- tree-sitter parse → imports + symbols (0.05–0.2ms/file)
392
- Babel deep parse → routes + models (API handler files only)
393
- Leiden+CPM graph clustering → auto-detects domains
394
- Computes reverse deps → blast radius for every file
395
- Writes AGENTS.md + .carto/context/*.md (lazy, on-demand)
396
- Auto-wires MCP into every AI tool found
397
- Installs 4 git hooks: pre-commit, post-checkout, post-merge, post-rewrite
398
-
399
- [no daemon, no watcher, no background process]
400
-
401
- ─── Freshness mechanism 1: git hooks (90% of cases) ───
402
- You commit / pull / switch branches / rebase
403
- → hook runs `carto sync` quietly in <1s
404
- → only changed files re-parsed
405
-
406
- ─── Freshness mechanism 2: lazy mtime check (the gap) ───
407
- You edit files between commits, AI asks "blast radius of db.ts?"
408
- → MCP server stats db.ts (mtime+size vs DB row)
409
- → if stale, re-parses just that file inline (<50ms)
410
- → returns fresh answer
411
-
412
- ─── Optional: carto watch (AI-heavy workflows only) ───
413
- File saved → debounce 50ms → re-parse 1 file → SQLite write → <50ms
414
- ```
329
+
330
+ > Status: v0.1.0-DRAFT — wire format may change up to v1.0.
415
331
 
416
332
  ---
417
333
 
418
334
  ## What Carto never does
419
335
 
420
- - **Sends your code anywhere.** Local only. SQLite on disk.
336
+ - **Sends your code anywhere.** Local only. SQLite on disk. No telemetry.
421
337
  - **Writes secrets into AGENTS.md.** `.cartoignore` blocks `.env` and credential files by default.
422
- - **Touches your manual notes.** Writes only between `<!-- CARTO:AUTO:START -->` and `<!-- CARTO:AUTO:END -->`.
423
- - **Costs money.** MIT license. Free forever.
338
+ - **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
+ - **Costs money.** MIT. Free forever.
424
341
 
425
342
  ---
426
343
 
@@ -428,9 +345,9 @@ File saved → debounce 50ms → re-parse 1 file → SQLite write → <50ms
428
345
 
429
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.
430
347
 
431
- To make the AI inside Emfirge understand infrastructure, I wrote a module called `cartography.py`. It mapped AWS resources, built a graph of how they connected, and wrote it into a structured map. The AI stopped hallucinating. It worked with facts, not guesses.
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.
432
349
 
433
- Carto is the same idea, applied to source code. Same insight: AI agents stop guessing once they can query the architecture.
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.
434
351
 
435
352
  ---
436
353
 
@@ -440,4 +357,4 @@ MIT. Free forever.
440
357
 
441
358
  ---
442
359
 
443
- *Your code changes. Carto knows. Every AI you use knows.*
360
+ *Your code changes. Carto knows. Every AI you use knows — and remembers.*