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.
- package/CONTRIBUTING.md +19 -15
- package/README.md +203 -286
- package/docs/anci/v0.1-DRAFT.md +420 -0
- package/docs/api/README.md +99 -0
- package/docs/api/did_we_discuss_this.md +34 -0
- package/docs/api/dismiss_suggestion.md +34 -0
- package/docs/api/explain_change_in_natural_language.md +33 -0
- package/docs/api/find_consumers_of_api.md +34 -0
- package/docs/api/get_action_patterns.md +32 -0
- package/docs/api/get_active_drift.md +32 -0
- package/docs/api/get_active_suggestions.md +25 -0
- package/docs/api/get_ai_cost_attribution.md +32 -0
- package/docs/api/get_arch_events.md +42 -0
- package/docs/api/get_architectural_drift.md +37 -0
- package/docs/api/get_architecture.md +25 -0
- package/docs/api/get_blast_radius.md +34 -0
- package/docs/api/get_canonical_pattern.md +39 -0
- package/docs/api/get_change_plan.md +34 -0
- package/docs/api/get_change_velocity.md +32 -0
- package/docs/api/get_churn_vs_blast_radius.md +32 -0
- package/docs/api/get_complexity_trend.md +39 -0
- package/docs/api/get_context.md +34 -0
- package/docs/api/get_conventions.md +32 -0
- package/docs/api/get_cross_domain.md +25 -0
- package/docs/api/get_cross_language_call_graph.md +25 -0
- package/docs/api/get_cross_repo_blast_radius.md +34 -0
- package/docs/api/get_cross_team_coupling.md +25 -0
- package/docs/api/get_data_flow.md +33 -0
- package/docs/api/get_dead_code_with_confidence.md +32 -0
- package/docs/api/get_decision_log.md +32 -0
- package/docs/api/get_dependency_surface.md +25 -0
- package/docs/api/get_domain.md +34 -0
- package/docs/api/get_domain_evolution.md +39 -0
- package/docs/api/get_domain_health.md +32 -0
- package/docs/api/get_domains_list.md +25 -0
- package/docs/api/get_drift_digest.md +32 -0
- package/docs/api/get_env_vars.md +32 -0
- package/docs/api/get_evolution_delta.md +36 -0
- package/docs/api/get_file_ownership.md +33 -0
- package/docs/api/get_file_summary.md +34 -0
- package/docs/api/get_high_impact_files.md +32 -0
- package/docs/api/get_hot_in_prod_no_tests.md +34 -0
- package/docs/api/get_hotspot_files.md +37 -0
- package/docs/api/get_iac_resources.md +25 -0
- package/docs/api/get_interface_contract.md +33 -0
- package/docs/api/get_intervention_history.md +32 -0
- package/docs/api/get_invariants.md +37 -0
- package/docs/api/get_llm_enrichment.md +33 -0
- package/docs/api/get_microservice_cut_points.md +32 -0
- package/docs/api/get_microservices_migration_cut_points.md +25 -0
- package/docs/api/get_minimal_context_for_intent.md +39 -0
- package/docs/api/get_models.md +32 -0
- package/docs/api/get_neighbors.md +39 -0
- package/docs/api/get_org_architecture.md +25 -0
- package/docs/api/get_org_domain_mapping.md +25 -0
- package/docs/api/get_pending_decisions.md +32 -0
- package/docs/api/get_predictive_risk.md +32 -0
- package/docs/api/get_progressive_disclosure_tree.md +25 -0
- package/docs/api/get_recent_decisions.md +37 -0
- package/docs/api/get_risk_weighted_blast_radius.md +32 -0
- package/docs/api/get_routes.md +25 -0
- package/docs/api/get_safety_checklist.md +33 -0
- package/docs/api/get_semantic_diff.md +34 -0
- package/docs/api/get_service_boundary_violations.md +25 -0
- package/docs/api/get_service_dependency_graph.md +25 -0
- package/docs/api/get_session_context.md +32 -0
- package/docs/api/get_similar_patterns.md +39 -0
- package/docs/api/get_stale_docs.md +25 -0
- package/docs/api/get_structure.md +25 -0
- package/docs/api/get_temporal_context.md +34 -0
- package/docs/api/get_test_coverage_map.md +25 -0
- package/docs/api/get_token_budget_report.md +36 -0
- package/docs/api/get_upgrade_risk.md +25 -0
- package/docs/api/get_working_memory.md +25 -0
- package/docs/api/ingest_otlp_traces.md +34 -0
- package/docs/api/scaffold_for_intent.md +34 -0
- package/docs/api/search_routes.md +34 -0
- package/docs/api/simulate_change_impact.md +37 -0
- package/docs/api/validate_change.md +39 -0
- package/docs/api/validate_diff.md +39 -0
- package/docs/concepts/anci.md +87 -0
- package/docs/concepts/blast-radius.md +66 -0
- package/docs/concepts/domains.md +91 -0
- package/docs/concepts/import-graph.md +102 -0
- package/docs/concepts/mcp-integration.md +148 -0
- package/docs/guides/adding-feature-safely.md +101 -0
- package/docs/guides/ci-integration.md +175 -0
- package/docs/guides/monorepo-setup.md +121 -0
- package/docs/guides/onboarding-new-engineer.md +121 -0
- package/docs/guides/pre-merge-review.md +139 -0
- package/docs/migration/v1-to-v2.md +110 -0
- package/docs/quickstart.md +95 -0
- package/docs/scale.md +129 -0
- package/docs/troubleshooting.md +180 -0
- package/package.json +12 -5
- package/scripts/gen-api-docs.js +170 -0
- package/scripts/postinstall.js +391 -24
- package/src/acp/agent.js +83 -11
- package/src/acp/config.js +64 -0
- package/src/acp/persistence.js +146 -0
- package/src/acp/providers/anthropic.js +179 -27
- package/src/acp/providers/index.js +15 -2
- package/src/acp/providers/openai.js +164 -38
- package/src/acp/providers/sse.js +82 -0
- package/src/acp/safety.js +128 -0
- package/src/acp/session.js +73 -0
- package/src/adjacent/call-graph.js +170 -0
- package/src/adjacent/iac.js +167 -0
- package/src/adjacent/llm-enrich.js +35 -0
- package/src/adjacent/runtime.js +216 -0
- package/src/adjacent/semantic-diff.js +143 -0
- package/src/agents/leiden.js +4 -4
- package/src/agents/scan-structure.js +2 -2
- package/src/ai/context-builder.js +215 -0
- package/src/ai/retrieval/lexical.js +122 -0
- package/src/ai/retrieval/rrf.js +121 -0
- package/src/ai/retrieval/semantic.js +35 -0
- package/src/ai/retrieval/structural.js +82 -0
- package/src/ai/tools.js +423 -0
- package/src/anci/consumer.js +305 -0
- package/src/anci/deserialize.js +160 -0
- package/src/anci/emit.js +85 -0
- package/src/anci/serialize.js +264 -0
- package/src/anci/yaml.js +401 -0
- package/src/bitmap/index.js +1 -1
- package/src/bitmap/tools.js +2 -2
- package/src/brain/conventions/index.js +185 -0
- package/src/brain/index.js +31 -0
- package/src/brain/invariants/index.js +252 -0
- package/src/brain/procedural/index.js +181 -0
- package/src/brain/suggestions/index.js +153 -0
- package/src/brain/working/index.js +170 -0
- package/src/cli/anci.js +237 -0
- package/src/cli/check.js +47 -1
- package/src/cli/diff.js +83 -0
- package/src/cli/doctor.js +270 -0
- package/src/cli/explain.js +61 -0
- package/src/cli/index.js +115 -0
- package/src/cli/init.js +144 -6
- package/src/cli/inspect.js +1 -1
- package/src/cli/org.js +172 -0
- package/src/cli/pr-impact.js +554 -0
- package/src/cli/serve.js +1 -1
- package/src/cli/status.js +211 -0
- package/src/cli/sync.js +2 -2
- package/src/cli/temporal.js +188 -0
- package/src/cli/validate.js +201 -0
- package/src/cli/watch.js +4 -4
- package/src/cli/why.js +101 -0
- package/src/extractors/frameworks.js +236 -0
- package/src/extractors/languages/dart.js +138 -0
- package/src/extractors/languages/go.js +11 -1
- package/src/extractors/languages/javascript.js +16 -6
- package/src/extractors/languages/kotlin.js +169 -0
- package/src/extractors/languages/php.js +195 -0
- package/src/extractors/languages/python.js +12 -1
- package/src/extractors/languages/swift.js +140 -0
- package/src/extractors/languages/typescript.js +15 -2
- package/src/extractors/plugin-api.js +102 -0
- package/src/mcp/change-plan.js +8 -8
- package/src/mcp/files-without-tests.js +285 -0
- package/src/mcp/middleware/index.js +451 -0
- package/src/mcp/server.js +2292 -0
- package/src/mcp/validate.js +1 -1
- package/src/org/detect.js +262 -0
- package/src/org/queries.js +144 -0
- package/src/org/store.js +173 -0
- package/src/org/sync.js +106 -0
- package/src/predictive/cut-points.js +83 -0
- package/src/predictive/drift-digest.js +88 -0
- package/src/predictive/ownership.js +145 -0
- package/src/predictive/risk-score.js +121 -0
- package/src/predictive/validate-change.js +55 -0
- package/src/store/store-adapter.js +3 -3
- package/src/store/{sync-v2.js → sync.js} +105 -16
- package/src/temporal/backfill.js +211 -0
- package/src/temporal/delta.js +85 -0
- package/src/temporal/events.js +180 -0
- package/src/temporal/queries.js +358 -0
- package/src/temporal/snapshot.js +151 -0
- package/src/temporal/store.js +400 -0
- package/src/mcp/server-v2.js +0 -986
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
# ANCI v0.1 DRAFT — Architecturally Normalized Code Index
|
|
2
|
+
|
|
3
|
+
> **Status:** DRAFT (unstable). Do not depend on this format in production
|
|
4
|
+
> consumers without pinning to a specific carto-md version. The wire
|
|
5
|
+
> format may change in any direction up to v1.0.
|
|
6
|
+
>
|
|
7
|
+
> **Spec:** v0.1.0-DRAFT
|
|
8
|
+
> **Reference implementation:** carto-md ≥ 2.0.9
|
|
9
|
+
> **Editor:** [@theanshsonkar](https://github.com/theanshsonkar)
|
|
10
|
+
> **License:** MIT (the spec itself)
|
|
11
|
+
> **Repository:** https://github.com/theanshsonkar/carto
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 1. Motivation
|
|
16
|
+
|
|
17
|
+
Every AI coding tool today re-discovers a codebase's architecture from
|
|
18
|
+
scratch on every session. Cursor builds its own embedding index. Cline
|
|
19
|
+
builds its own. Continue builds its own. The work duplicates across
|
|
20
|
+
tools and is lost across sessions.
|
|
21
|
+
|
|
22
|
+
ANCI fills the hole. It is a **static file format** — two files,
|
|
23
|
+
`anci.yaml` and `anci.bin`, sitting at a known location in a repository
|
|
24
|
+
— that describes that codebase's architecture in a form any AI tool can
|
|
25
|
+
read without indexing it itself.
|
|
26
|
+
|
|
27
|
+
ANCI is to codebases what OpenAPI is to REST APIs: a standardized way for
|
|
28
|
+
something to describe itself to consumers it doesn't know about.
|
|
29
|
+
|
|
30
|
+
## 2. Goals & non-goals
|
|
31
|
+
|
|
32
|
+
### Goals
|
|
33
|
+
|
|
34
|
+
* **Tool-neutral.** No assumption about which AI tool consumes ANCI.
|
|
35
|
+
* **Local-first.** ANCI files live next to the code, in `.carto/` by
|
|
36
|
+
convention. Never sent over a network unless the user chooses to.
|
|
37
|
+
* **Hybrid representation.** Human-readable header for grep / inspection;
|
|
38
|
+
binary body for fast queries on million-file repos.
|
|
39
|
+
* **Bounded size.** Target ≤ 20 MB total for a 100K-file repo.
|
|
40
|
+
* **Lossless round-trip.** Producer → file → consumer reproduces the
|
|
41
|
+
exact graph, domains, and metadata.
|
|
42
|
+
* **Forward-compatible.** New optional sections may be added in v0.x
|
|
43
|
+
releases. Consumers ignore unknown sections.
|
|
44
|
+
|
|
45
|
+
### Non-goals
|
|
46
|
+
|
|
47
|
+
* **Not a query language.** Consumers traverse the data structures with
|
|
48
|
+
their own code. ANCI is just the data.
|
|
49
|
+
* **Not a network protocol.** No RPC. No streaming. Static files only.
|
|
50
|
+
* **Not a replacement for source code.** ANCI describes structure
|
|
51
|
+
(graph, domains, routes), not source.
|
|
52
|
+
* **Not yet stable.** v0.1 DRAFT may break in v0.2, v0.3, etc. Stability
|
|
53
|
+
begins at v1.0.
|
|
54
|
+
|
|
55
|
+
## 3. File layout
|
|
56
|
+
|
|
57
|
+
A repository that ships ANCI places two files in `.carto/`:
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
.carto/
|
|
61
|
+
├── anci.yaml # Header. UTF-8 YAML. Required. Human-readable.
|
|
62
|
+
├── anci.bin # Body. Binary. Required. Machine-readable.
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Producers write both. Consumers read either independently:
|
|
66
|
+
|
|
67
|
+
* If a consumer only needs domain names and route counts, parse
|
|
68
|
+
`anci.yaml` and ignore the body.
|
|
69
|
+
* If a consumer needs blast radius or graph traversal, parse the body.
|
|
70
|
+
|
|
71
|
+
The header MUST point to the body's filename and byte length. If they
|
|
72
|
+
disagree, the body is authoritative for graph data and the header is
|
|
73
|
+
authoritative for human metadata.
|
|
74
|
+
|
|
75
|
+
## 4. Header format (`anci.yaml`)
|
|
76
|
+
|
|
77
|
+
UTF-8, YAML 1.2, **strict subset**:
|
|
78
|
+
|
|
79
|
+
* 2-space indentation
|
|
80
|
+
* `key: value` pairs only (no flow style `{}`/`[]`)
|
|
81
|
+
* All string values double-quoted (no implicit typing)
|
|
82
|
+
* Lists use `- ` prefix
|
|
83
|
+
* No multi-line strings, no anchors, no aliases, no tags
|
|
84
|
+
|
|
85
|
+
A v0.1.0-DRAFT producer MUST emit a header that conforms to this
|
|
86
|
+
schema. A consumer MAY accept other YAML inputs but reference
|
|
87
|
+
implementations only emit/parse the strict subset.
|
|
88
|
+
|
|
89
|
+
### 4.1 Schema
|
|
90
|
+
|
|
91
|
+
```yaml
|
|
92
|
+
anci:
|
|
93
|
+
version: "0.1.0-DRAFT" # required, string
|
|
94
|
+
generator: "carto-md@2.0.9" # required, string
|
|
95
|
+
generated_at: "2026-06-07T..." # required, ISO-8601 UTC
|
|
96
|
+
body:
|
|
97
|
+
file: "anci.bin" # required, relative to header
|
|
98
|
+
bytes: 12345 # required, body length on disk
|
|
99
|
+
|
|
100
|
+
project:
|
|
101
|
+
total_files: 7567 # required
|
|
102
|
+
total_routes: 86 # required
|
|
103
|
+
total_models: 12 # required
|
|
104
|
+
total_import_edges: 13420 # required
|
|
105
|
+
|
|
106
|
+
domains: # required, possibly empty
|
|
107
|
+
- name: "AUTH"
|
|
108
|
+
file_count: 42
|
|
109
|
+
route_count: 7
|
|
110
|
+
model_count: 1
|
|
111
|
+
|
|
112
|
+
high_impact: # optional, top N by transitive dep count
|
|
113
|
+
- file: "src/auth/session.ts"
|
|
114
|
+
transitive_dependents: 47
|
|
115
|
+
|
|
116
|
+
routes: # optional
|
|
117
|
+
- method: "POST"
|
|
118
|
+
path: "/auth/login"
|
|
119
|
+
file: "src/auth/login.ts"
|
|
120
|
+
framework: "express"
|
|
121
|
+
handler: "login"
|
|
122
|
+
|
|
123
|
+
models: # optional
|
|
124
|
+
- name: "User"
|
|
125
|
+
kind: "prisma"
|
|
126
|
+
file: "prisma/schema.prisma"
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Field names are stable for the v0.x line. Adding new optional fields is
|
|
130
|
+
not a breaking change. Removing or renaming a field IS breaking and
|
|
131
|
+
requires a version bump.
|
|
132
|
+
|
|
133
|
+
### 4.2 Versioning
|
|
134
|
+
|
|
135
|
+
| Field | Meaning |
|
|
136
|
+
|-----------------|-----------------------------------------------------------|
|
|
137
|
+
| `anci.version` | Spec version. v0.x is unstable. v1.0+ follows semver. |
|
|
138
|
+
| `anci.generator`| Producer identity. Free-form string, conventionally `name@version`. |
|
|
139
|
+
|
|
140
|
+
Consumers MUST refuse to parse a header whose `anci.version` is not in
|
|
141
|
+
their compatibility set. Reference consumer behavior (carto-md):
|
|
142
|
+
|
|
143
|
+
* Accepts: `0.1.x-DRAFT`
|
|
144
|
+
* Rejects: anything else
|
|
145
|
+
|
|
146
|
+
## 5. Body format (`anci.bin`)
|
|
147
|
+
|
|
148
|
+
Binary, little-endian, length-prefixed sections. Designed so a single
|
|
149
|
+
streaming pass can fully reconstruct all bitmaps, paths, and domain
|
|
150
|
+
mappings.
|
|
151
|
+
|
|
152
|
+
### 5.1 Header
|
|
153
|
+
|
|
154
|
+
| Offset | Size | Field | Value |
|
|
155
|
+
|-------:|------:|--------------|-----------------------------------------------|
|
|
156
|
+
| 0 | 4 B | magic | `0x49434E41` (`'A','N','C','I'` little-endian)|
|
|
157
|
+
| 4 | 1 B | version | `0x01` |
|
|
158
|
+
| 5 | 3 B | reserved | zero |
|
|
159
|
+
| 8 | 4 B | size_bits | u32 — bit dimension of every bitmap (= max file id + 1) |
|
|
160
|
+
|
|
161
|
+
Total fixed-header length: **12 bytes.**
|
|
162
|
+
|
|
163
|
+
### 5.2 Sections
|
|
164
|
+
|
|
165
|
+
After the fixed header, sections appear **in this order**. Each section
|
|
166
|
+
begins with a u32 count.
|
|
167
|
+
|
|
168
|
+
#### 5.2.1 `forward` — file → its imports
|
|
169
|
+
|
|
170
|
+
```
|
|
171
|
+
count_u32
|
|
172
|
+
count × {
|
|
173
|
+
from_file_id_u32
|
|
174
|
+
words_len_u32
|
|
175
|
+
words_u32 × words_len // raw Uint32Array bytes, LE
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Bit `j` of the bitmap of `from_file_id` is 1 iff the file with id
|
|
180
|
+
`from_file_id` directly imports the file with id `j`.
|
|
181
|
+
|
|
182
|
+
#### 5.2.2 `reverse` — file → its direct dependents
|
|
183
|
+
|
|
184
|
+
Same record shape as `forward`. Bit `j` set iff file `to_file_id` is
|
|
185
|
+
directly imported by file `j`.
|
|
186
|
+
|
|
187
|
+
#### 5.2.3 `popcount` — pre-computed transitive dependent counts
|
|
188
|
+
|
|
189
|
+
```
|
|
190
|
+
count_u32
|
|
191
|
+
count × {
|
|
192
|
+
file_id_u32
|
|
193
|
+
count_u32 // # of distinct dependents reachable in ≤ 5 hops
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Sorted DESC by count. Lets `getHighImpactFiles(n)` answer in O(1).
|
|
198
|
+
Producers MUST clamp BFS to 5 hops to match the carto-md reference.
|
|
199
|
+
|
|
200
|
+
#### 5.2.4 `paths` — file id → path string
|
|
201
|
+
|
|
202
|
+
```
|
|
203
|
+
count_u32
|
|
204
|
+
count × {
|
|
205
|
+
file_id_u32
|
|
206
|
+
path_len_u32
|
|
207
|
+
path_bytes (UTF-8, no NUL terminator)
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Paths are project-relative POSIX paths (forward slashes, no leading `./`).
|
|
212
|
+
|
|
213
|
+
#### 5.2.5 `file_domain` — file id → domain id
|
|
214
|
+
|
|
215
|
+
```
|
|
216
|
+
count_u32
|
|
217
|
+
count × {
|
|
218
|
+
file_id_u32
|
|
219
|
+
domain_id_u32
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
Files absent from this section have no domain assignment. A file MAY
|
|
224
|
+
have at most one domain.
|
|
225
|
+
|
|
226
|
+
#### 5.2.6 `domain_names` — domain id → human name
|
|
227
|
+
|
|
228
|
+
```
|
|
229
|
+
count_u32
|
|
230
|
+
count × {
|
|
231
|
+
domain_id_u32
|
|
232
|
+
name_len_u32
|
|
233
|
+
name_bytes (UTF-8)
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Domain names are uppercase by convention (`AUTH`, `PAYMENTS`,
|
|
238
|
+
`DATABASE`) but the spec does not constrain their contents.
|
|
239
|
+
|
|
240
|
+
### 5.3 Total layout (concrete byte map)
|
|
241
|
+
|
|
242
|
+
```
|
|
243
|
+
[ 12 B fixed header ]
|
|
244
|
+
[ forward section ]
|
|
245
|
+
[ reverse section ]
|
|
246
|
+
[ popcount section ]
|
|
247
|
+
[ paths section ]
|
|
248
|
+
[ file_domain section ]
|
|
249
|
+
[ domain_names section]
|
|
250
|
+
EOF
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
A consumer that knows the spec version can stream-parse top to bottom.
|
|
254
|
+
There is no out-of-line index — the format is designed for one
|
|
255
|
+
sequential read.
|
|
256
|
+
|
|
257
|
+
## 6. Generation algorithm (reference)
|
|
258
|
+
|
|
259
|
+
Producers SHOULD compute the body as follows:
|
|
260
|
+
|
|
261
|
+
1. Assign each file a stable, dense integer id.
|
|
262
|
+
2. For each file, build a bitmap of its forward imports (resolved
|
|
263
|
+
imports only; unresolved imports are excluded).
|
|
264
|
+
3. Reverse the forward bitmaps into `reverse`.
|
|
265
|
+
4. For each file with ≥ 1 dependent, run a 5-hop BFS over `reverse`
|
|
266
|
+
using the same self-loop guard as `bitmap/sidecar.js`:
|
|
267
|
+
a. Seed `visited` with direct dependents.
|
|
268
|
+
b. Expand frontier by one hop, mask `visited`, add result to
|
|
269
|
+
`visited`. Repeat to depth 5 or until frontier is empty.
|
|
270
|
+
c. Clear the seed bit (cycles must not count the file itself).
|
|
271
|
+
d. Record `popcount(visited)` if > 0.
|
|
272
|
+
5. Sort `popcount` records DESC.
|
|
273
|
+
6. Write sections in the order specified in §5.2.
|
|
274
|
+
|
|
275
|
+
The carto-md reference implementation lives in `src/anci/serialize.js`.
|
|
276
|
+
|
|
277
|
+
## 7. Consumer responsibilities
|
|
278
|
+
|
|
279
|
+
A consumer MUST:
|
|
280
|
+
|
|
281
|
+
* Validate magic bytes and version before reading any section.
|
|
282
|
+
* Refuse to parse if `size_bits` differs from the bitmap dimension
|
|
283
|
+
derived from any section's `words_len`.
|
|
284
|
+
* Treat unknown sections (in future v0.x releases) as opaque and skip
|
|
285
|
+
them. The reference implementation enforces strict order today, but
|
|
286
|
+
consumers SHOULD be permissive on order to ease forward compatibility.
|
|
287
|
+
|
|
288
|
+
A consumer SHOULD:
|
|
289
|
+
|
|
290
|
+
* Cache the parsed body in memory rather than re-parsing on every
|
|
291
|
+
query. The format is designed for fast load, not fast random seek.
|
|
292
|
+
* Cross-validate the header's `body.bytes` against the actual file
|
|
293
|
+
size and warn (not fail) on mismatch.
|
|
294
|
+
|
|
295
|
+
## 8. Versioning & deprecation policy
|
|
296
|
+
|
|
297
|
+
### v0.1.0-DRAFT (this spec)
|
|
298
|
+
|
|
299
|
+
* Format may change in any direction up to v1.0.
|
|
300
|
+
* Consumers pin to specific producer versions.
|
|
301
|
+
* Reference implementation is carto-md ≥ 2.0.9.
|
|
302
|
+
* No backward compatibility guarantees.
|
|
303
|
+
|
|
304
|
+
### Future v0.x (e.g. v0.2)
|
|
305
|
+
|
|
306
|
+
* MAY add optional header fields.
|
|
307
|
+
* MAY add optional body sections (appended after `domain_names`).
|
|
308
|
+
* MUST NOT remove or rename existing fields.
|
|
309
|
+
* MUST bump `anci.version` to a new minor.
|
|
310
|
+
* Reference consumer accepts the latest v0.x and the version it shipped
|
|
311
|
+
against.
|
|
312
|
+
|
|
313
|
+
### v1.0 stability
|
|
314
|
+
|
|
315
|
+
When the format is judged ready (reference partner integrations exist,
|
|
316
|
+
plus 6 months of v0.x stability), `anci.version` graduates to `1.0.0`
|
|
317
|
+
and standard semver applies thereafter:
|
|
318
|
+
|
|
319
|
+
* MAJOR: incompatible breaking change.
|
|
320
|
+
* MINOR: backward-compatible addition.
|
|
321
|
+
* PATCH: clarification only.
|
|
322
|
+
|
|
323
|
+
A v1.x consumer MUST accept all v1.x bodies. v0.x compatibility at v1.0
|
|
324
|
+
is not guaranteed — producers re-emit at the v1.0 schema.
|
|
325
|
+
|
|
326
|
+
## 9. Security considerations
|
|
327
|
+
|
|
328
|
+
ANCI is a passive description of code structure. It contains:
|
|
329
|
+
|
|
330
|
+
* File paths (project-relative).
|
|
331
|
+
* Domain names.
|
|
332
|
+
* Route paths and HTTP methods.
|
|
333
|
+
* Model names and kinds.
|
|
334
|
+
* Import graph as integer bitmaps.
|
|
335
|
+
|
|
336
|
+
ANCI does **not** contain source code, secrets, env values, or
|
|
337
|
+
user-identifying information. Producers MUST NOT include source content
|
|
338
|
+
in any field.
|
|
339
|
+
|
|
340
|
+
A repository that publishes its `.carto/anci.{yaml,bin}` to a remote
|
|
341
|
+
location is exposing its architecture. This is the same disclosure
|
|
342
|
+
level as making the directory tree public. Producers SHOULD respect
|
|
343
|
+
`.cartoignore` and SHOULD NOT include paths matching its patterns.
|
|
344
|
+
|
|
345
|
+
## 10. Why YAML + binary (and not just YAML, or just binary)
|
|
346
|
+
|
|
347
|
+
| Property | YAML alone | Binary alone | Hybrid |
|
|
348
|
+
|------------------------|:----------:|:------------:|:------:|
|
|
349
|
+
| Human-readable | ✅ | ❌ | ✅ |
|
|
350
|
+
| Grep-able from CI | ✅ | ❌ | ✅ |
|
|
351
|
+
| Compact at 100K files | ❌ (50–500 MB) | ✅ | ✅ (5–20 MB) |
|
|
352
|
+
| Fast graph queries | ❌ | ✅ | ✅ |
|
|
353
|
+
| Easy partial parse | ✅ | ⚠️ | ✅ |
|
|
354
|
+
|
|
355
|
+
The split mirrors the structure of the data: metadata is small and
|
|
356
|
+
varied (good for YAML); the graph is large and uniform (good for
|
|
357
|
+
binary).
|
|
358
|
+
|
|
359
|
+
## 11. Why these specific bitmap sections
|
|
360
|
+
|
|
361
|
+
The body ships exactly the data needed to answer the four MCP tools
|
|
362
|
+
that drive most AI-tool queries:
|
|
363
|
+
|
|
364
|
+
* `getBlastRadius(file)` → walk `reverse` BFS-style.
|
|
365
|
+
* `simulateChangeImpact(files)` → OR-aggregate `reverse` bitmaps.
|
|
366
|
+
* `getHighImpactFiles(n)` → take first N from `popcount`.
|
|
367
|
+
* `getDomainsList()` / domain membership → header + `file_domain` +
|
|
368
|
+
`domain_names`.
|
|
369
|
+
|
|
370
|
+
Everything else (cross-domain detection, similarity, change-plan
|
|
371
|
+
ranking) can be derived from these primitives. The format keeps the
|
|
372
|
+
ship surface small.
|
|
373
|
+
|
|
374
|
+
## 12. Compatibility with carto-md `bitmap.bin`
|
|
375
|
+
|
|
376
|
+
ANCI v0.1 and carto-md's internal `bitmap.bin` (magic `0x54524243`
|
|
377
|
+
"CBRT") share record-level encoding but are **distinct file formats
|
|
378
|
+
with distinct magics**. Reasons:
|
|
379
|
+
|
|
380
|
+
* `bitmap.bin` is private cache; `anci.bin` is public export.
|
|
381
|
+
* `bitmap.bin` includes `crossForward` and `domainBitmaps` (internal
|
|
382
|
+
query optimizations); ANCI omits them. Consumers can re-derive both
|
|
383
|
+
in O(N) on load.
|
|
384
|
+
* `bitmap.bin` may evolve at carto-md's pace; ANCI evolves only at
|
|
385
|
+
spec-revision pace.
|
|
386
|
+
|
|
387
|
+
A consumer MUST NOT attempt to load `bitmap.bin` as ANCI or vice versa.
|
|
388
|
+
|
|
389
|
+
## 13. Reference vs. interoperability tests
|
|
390
|
+
|
|
391
|
+
The carto-md reference implementation includes a roundtrip test suite
|
|
392
|
+
(`test/test.js` → `ANCI roundtrip`). Other implementations are
|
|
393
|
+
encouraged to:
|
|
394
|
+
|
|
395
|
+
* Run carto-md's reference suite against their own
|
|
396
|
+
serialize/deserialize code.
|
|
397
|
+
* Publish their own conformance tests for the spec to consume.
|
|
398
|
+
|
|
399
|
+
The DRAFT spec deliberately ships **without** an independent
|
|
400
|
+
conformance harness. v1.0 will require one before formalization.
|
|
401
|
+
|
|
402
|
+
## 14. Open questions (RFC-stage feedback welcome)
|
|
403
|
+
|
|
404
|
+
* **Should the body be Roaring-compressed instead of dense
|
|
405
|
+
Uint32Array?** Roaring is smaller on sparse repos but adds a
|
|
406
|
+
dependency. v0.1 ships dense; v1.0 may add an opt-in compressed
|
|
407
|
+
encoding.
|
|
408
|
+
* **Should env vars be in the header?** Currently no — they leak
|
|
409
|
+
configuration surface. Open question for partners.
|
|
410
|
+
* **Should source language be part of `paths`?** Currently no — language
|
|
411
|
+
is derivable from extension. Open if consumers ask.
|
|
412
|
+
* **Cross-repo references?** Out of scope for v0.1. Tier 3 work.
|
|
413
|
+
|
|
414
|
+
## 15. Acknowledgements
|
|
415
|
+
|
|
416
|
+
Inspired by OpenAPI's standardization play (2010-2015), Git's pack
|
|
417
|
+
reachability bitmaps (2013), and Lucene's Roaring posting lists (2014).
|
|
418
|
+
|
|
419
|
+
The spec is iterated alongside carto-md. File issues at
|
|
420
|
+
https://github.com/theanshsonkar/carto for proposed changes.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Carto MCP Tools — API Reference
|
|
2
|
+
|
|
3
|
+
Auto-generated from `src/mcp/server.js`. Re-run `node scripts/gen-api-docs.js` after adding tools.
|
|
4
|
+
|
|
5
|
+
**76 tools** across 8 categories.
|
|
6
|
+
|
|
7
|
+
## Categories
|
|
8
|
+
|
|
9
|
+
### Core graph (16)
|
|
10
|
+
- [`get_routes`](./get_routes.md)
|
|
11
|
+
- [`get_blast_radius`](./get_blast_radius.md)
|
|
12
|
+
- [`get_structure`](./get_structure.md)
|
|
13
|
+
- [`get_domain`](./get_domain.md)
|
|
14
|
+
- [`get_neighbors`](./get_neighbors.md)
|
|
15
|
+
- [`get_cross_domain`](./get_cross_domain.md)
|
|
16
|
+
- [`get_context`](./get_context.md)
|
|
17
|
+
- [`search_routes`](./search_routes.md)
|
|
18
|
+
- [`get_models`](./get_models.md)
|
|
19
|
+
- [`get_high_impact_files`](./get_high_impact_files.md)
|
|
20
|
+
- [`get_env_vars`](./get_env_vars.md)
|
|
21
|
+
- [`get_domains_list`](./get_domains_list.md)
|
|
22
|
+
- [`get_file_summary`](./get_file_summary.md)
|
|
23
|
+
- [`get_change_plan`](./get_change_plan.md)
|
|
24
|
+
- [`get_similar_patterns`](./get_similar_patterns.md)
|
|
25
|
+
- [`simulate_change_impact`](./simulate_change_impact.md)
|
|
26
|
+
|
|
27
|
+
### Episodic Memory (5)
|
|
28
|
+
- [`validate_diff`](./validate_diff.md)
|
|
29
|
+
- [`get_recent_decisions`](./get_recent_decisions.md)
|
|
30
|
+
- [`get_session_context`](./get_session_context.md)
|
|
31
|
+
- [`did_we_discuss_this`](./did_we_discuss_this.md)
|
|
32
|
+
- [`get_intervention_history`](./get_intervention_history.md)
|
|
33
|
+
|
|
34
|
+
### Temporal (9)
|
|
35
|
+
- [`get_architecture`](./get_architecture.md)
|
|
36
|
+
- [`get_architectural_drift`](./get_architectural_drift.md)
|
|
37
|
+
- [`get_domain_evolution`](./get_domain_evolution.md)
|
|
38
|
+
- [`get_hotspot_files`](./get_hotspot_files.md)
|
|
39
|
+
- [`get_complexity_trend`](./get_complexity_trend.md)
|
|
40
|
+
- [`get_churn_vs_blast_radius`](./get_churn_vs_blast_radius.md)
|
|
41
|
+
- [`get_arch_events`](./get_arch_events.md)
|
|
42
|
+
- [`get_domain_health`](./get_domain_health.md)
|
|
43
|
+
- [`get_temporal_context`](./get_temporal_context.md)
|
|
44
|
+
|
|
45
|
+
### Brain (10)
|
|
46
|
+
- [`get_invariants`](./get_invariants.md)
|
|
47
|
+
- [`get_canonical_pattern`](./get_canonical_pattern.md)
|
|
48
|
+
- [`get_conventions`](./get_conventions.md)
|
|
49
|
+
- [`get_action_patterns`](./get_action_patterns.md)
|
|
50
|
+
- [`scaffold_for_intent`](./scaffold_for_intent.md)
|
|
51
|
+
- [`get_working_memory`](./get_working_memory.md)
|
|
52
|
+
- [`get_pending_decisions`](./get_pending_decisions.md)
|
|
53
|
+
- [`get_active_drift`](./get_active_drift.md)
|
|
54
|
+
- [`get_active_suggestions`](./get_active_suggestions.md)
|
|
55
|
+
- [`dismiss_suggestion`](./dismiss_suggestion.md)
|
|
56
|
+
|
|
57
|
+
### AI-native (14)
|
|
58
|
+
- [`get_minimal_context_for_intent`](./get_minimal_context_for_intent.md)
|
|
59
|
+
- [`get_progressive_disclosure_tree`](./get_progressive_disclosure_tree.md)
|
|
60
|
+
- [`get_token_budget_report`](./get_token_budget_report.md)
|
|
61
|
+
- [`get_decision_log`](./get_decision_log.md)
|
|
62
|
+
- [`get_evolution_delta`](./get_evolution_delta.md)
|
|
63
|
+
- [`get_change_velocity`](./get_change_velocity.md)
|
|
64
|
+
- [`get_test_coverage_map`](./get_test_coverage_map.md)
|
|
65
|
+
- [`get_safety_checklist`](./get_safety_checklist.md)
|
|
66
|
+
- [`get_data_flow`](./get_data_flow.md)
|
|
67
|
+
- [`get_interface_contract`](./get_interface_contract.md)
|
|
68
|
+
- [`explain_change_in_natural_language`](./explain_change_in_natural_language.md)
|
|
69
|
+
- [`get_stale_docs`](./get_stale_docs.md)
|
|
70
|
+
- [`get_dependency_surface`](./get_dependency_surface.md)
|
|
71
|
+
- [`get_upgrade_risk`](./get_upgrade_risk.md)
|
|
72
|
+
|
|
73
|
+
### Adjacent (8)
|
|
74
|
+
- [`get_cross_language_call_graph`](./get_cross_language_call_graph.md)
|
|
75
|
+
- [`get_iac_resources`](./get_iac_resources.md)
|
|
76
|
+
- [`ingest_otlp_traces`](./ingest_otlp_traces.md)
|
|
77
|
+
- [`get_risk_weighted_blast_radius`](./get_risk_weighted_blast_radius.md)
|
|
78
|
+
- [`get_dead_code_with_confidence`](./get_dead_code_with_confidence.md)
|
|
79
|
+
- [`get_hot_in_prod_no_tests`](./get_hot_in_prod_no_tests.md)
|
|
80
|
+
- [`get_semantic_diff`](./get_semantic_diff.md)
|
|
81
|
+
- [`get_llm_enrichment`](./get_llm_enrichment.md)
|
|
82
|
+
|
|
83
|
+
### Predictive (7)
|
|
84
|
+
- [`get_predictive_risk`](./get_predictive_risk.md)
|
|
85
|
+
- [`get_microservice_cut_points`](./get_microservice_cut_points.md)
|
|
86
|
+
- [`validate_change`](./validate_change.md)
|
|
87
|
+
- [`get_file_ownership`](./get_file_ownership.md)
|
|
88
|
+
- [`get_cross_team_coupling`](./get_cross_team_coupling.md)
|
|
89
|
+
- [`get_drift_digest`](./get_drift_digest.md)
|
|
90
|
+
- [`get_ai_cost_attribution`](./get_ai_cost_attribution.md)
|
|
91
|
+
|
|
92
|
+
### Org-wide (7)
|
|
93
|
+
- [`get_org_architecture`](./get_org_architecture.md)
|
|
94
|
+
- [`get_service_dependency_graph`](./get_service_dependency_graph.md)
|
|
95
|
+
- [`get_cross_repo_blast_radius`](./get_cross_repo_blast_radius.md)
|
|
96
|
+
- [`find_consumers_of_api`](./find_consumers_of_api.md)
|
|
97
|
+
- [`get_org_domain_mapping`](./get_org_domain_mapping.md)
|
|
98
|
+
- [`get_service_boundary_violations`](./get_service_boundary_violations.md)
|
|
99
|
+
- [`get_microservices_migration_cut_points`](./get_microservices_migration_cut_points.md)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# `did_we_discuss_this`
|
|
2
|
+
|
|
3
|
+
Substring search over the episodic memory log (decisions + interventions) for prior discussions of a topic. Use to avoid re-deciding settled questions.
|
|
4
|
+
|
|
5
|
+
## Input schema
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
{
|
|
9
|
+
"type": "object",
|
|
10
|
+
"properties": {
|
|
11
|
+
"topic": {
|
|
12
|
+
"type": "string",
|
|
13
|
+
"description": "Topic to search for, e.g. \"auth\", \"snake_case\", \"blast radius\"."
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"required": [
|
|
17
|
+
"topic"
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Required arguments
|
|
23
|
+
|
|
24
|
+
- `topic`
|
|
25
|
+
|
|
26
|
+
## Properties
|
|
27
|
+
|
|
28
|
+
| Name | Type | Description |
|
|
29
|
+
|------|------|-------------|
|
|
30
|
+
| `topic` | string | Topic to search for, e.g. "auth", "snake_case", "blast radius". |
|
|
31
|
+
|
|
32
|
+
## See also
|
|
33
|
+
|
|
34
|
+
- [Index of all MCP tools](./README.md)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# `dismiss_suggestion`
|
|
2
|
+
|
|
3
|
+
Mark a suggestion ID as dismissed for the current session. Acknowledgment-only; the underlying signal still exists.
|
|
4
|
+
|
|
5
|
+
## Input schema
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
{
|
|
9
|
+
"type": "object",
|
|
10
|
+
"properties": {
|
|
11
|
+
"id": {
|
|
12
|
+
"type": "string",
|
|
13
|
+
"description": "Suggestion id from get_active_suggestions."
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"required": [
|
|
17
|
+
"id"
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Required arguments
|
|
23
|
+
|
|
24
|
+
- `id`
|
|
25
|
+
|
|
26
|
+
## Properties
|
|
27
|
+
|
|
28
|
+
| Name | Type | Description |
|
|
29
|
+
|------|------|-------------|
|
|
30
|
+
| `id` | string | Suggestion id from get_active_suggestions. |
|
|
31
|
+
|
|
32
|
+
## See also
|
|
33
|
+
|
|
34
|
+
- [Index of all MCP tools](./README.md)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# `explain_change_in_natural_language`
|
|
2
|
+
|
|
3
|
+
Given a unified diff, returns a plain-language summary + risk + violation list + suggestions. Powered by validate_diff.
|
|
4
|
+
|
|
5
|
+
## Input schema
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
{
|
|
9
|
+
"type": "object",
|
|
10
|
+
"properties": {
|
|
11
|
+
"diff": {
|
|
12
|
+
"type": "string"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"required": [
|
|
16
|
+
"diff"
|
|
17
|
+
]
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Required arguments
|
|
22
|
+
|
|
23
|
+
- `diff`
|
|
24
|
+
|
|
25
|
+
## Properties
|
|
26
|
+
|
|
27
|
+
| Name | Type | Description |
|
|
28
|
+
|------|------|-------------|
|
|
29
|
+
| `diff` | string | |
|
|
30
|
+
|
|
31
|
+
## See also
|
|
32
|
+
|
|
33
|
+
- [Index of all MCP tools](./README.md)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# `find_consumers_of_api`
|
|
2
|
+
|
|
3
|
+
Across all org repos, find every file importing a given npm/pypi/go/maven target.
|
|
4
|
+
|
|
5
|
+
## Input schema
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
{
|
|
9
|
+
"type": "object",
|
|
10
|
+
"properties": {
|
|
11
|
+
"target": {
|
|
12
|
+
"type": "string",
|
|
13
|
+
"description": "Target package or module name"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"required": [
|
|
17
|
+
"target"
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Required arguments
|
|
23
|
+
|
|
24
|
+
- `target`
|
|
25
|
+
|
|
26
|
+
## Properties
|
|
27
|
+
|
|
28
|
+
| Name | Type | Description |
|
|
29
|
+
|------|------|-------------|
|
|
30
|
+
| `target` | string | Target package or module name |
|
|
31
|
+
|
|
32
|
+
## See also
|
|
33
|
+
|
|
34
|
+
- [Index of all MCP tools](./README.md)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# `get_action_patterns`
|
|
2
|
+
|
|
3
|
+
Procedural patterns mined from git history: "when developers add X, they also touch Y". Filter by natural-language intent.
|
|
4
|
+
|
|
5
|
+
## Input schema
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
{
|
|
9
|
+
"type": "object",
|
|
10
|
+
"properties": {
|
|
11
|
+
"intent": {
|
|
12
|
+
"type": "string",
|
|
13
|
+
"description": "Optional intent filter (e.g. \"add route\")."
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"required": []
|
|
17
|
+
}
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Required arguments
|
|
21
|
+
|
|
22
|
+
_None._
|
|
23
|
+
|
|
24
|
+
## Properties
|
|
25
|
+
|
|
26
|
+
| Name | Type | Description |
|
|
27
|
+
|------|------|-------------|
|
|
28
|
+
| `intent` | string | Optional intent filter (e.g. "add route"). |
|
|
29
|
+
|
|
30
|
+
## See also
|
|
31
|
+
|
|
32
|
+
- [Index of all MCP tools](./README.md)
|