knodin 0.7.6 → 0.8.2

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 (130) hide show
  1. package/README.md +19 -7
  2. package/benchmarks/competitors/SYNTHESIS.md +66 -0
  3. package/dist/bin/cli.js +2164 -108
  4. package/dist/bin/launcher.js +25 -3
  5. package/dist/src/agent-integration.js +304 -0
  6. package/dist/src/artifact-refresh.js +82 -0
  7. package/dist/src/cli-args.js +292 -0
  8. package/dist/src/cli-model.js +384 -0
  9. package/dist/src/codeflow-replay.js +81 -0
  10. package/dist/src/compact-structural.js +96 -0
  11. package/dist/src/compare.js +39 -0
  12. package/dist/src/competitive-cold-mcp.js +40 -0
  13. package/dist/src/competitive-constraints.js +21 -0
  14. package/dist/src/competitive-manifest.js +411 -0
  15. package/dist/src/competitive-measurement.js +183 -0
  16. package/dist/src/competitive-runner.js +487 -0
  17. package/dist/src/competitive-sandbox.js +108 -0
  18. package/dist/src/context-export.js +423 -0
  19. package/dist/src/context.js +102 -0
  20. package/dist/src/deterministic-random.js +34 -0
  21. package/dist/src/diagnostics-write-helper.js +473 -0
  22. package/dist/src/diagnostics.js +1476 -0
  23. package/dist/src/docs-sections.js +141 -0
  24. package/dist/src/doctor.js +382 -0
  25. package/dist/src/engine/ann-hnsw.js +261 -0
  26. package/dist/src/engine/embeddings.js +193 -0
  27. package/dist/src/engine/file-walker.js +49 -0
  28. package/dist/src/engine/git-history.js +289 -0
  29. package/dist/src/engine/index.js +14238 -0
  30. package/dist/src/engine/perf.js +115 -0
  31. package/dist/src/engine/prune.js +112 -0
  32. package/dist/src/engine/sarif-import.js +341 -0
  33. package/dist/src/engine/scip-import.js +423 -0
  34. package/dist/src/engine/source-policy.js +85 -0
  35. package/dist/src/engine/sqlite.js +71 -0
  36. package/dist/src/engine/state-paths.js +175 -0
  37. package/dist/src/engine/symbol-delete.js +58 -0
  38. package/dist/src/execution-profile.js +208 -0
  39. package/dist/src/failure-diagnosis.js +655 -0
  40. package/dist/src/fleet.js +7 -0
  41. package/dist/src/git-executable.js +31 -0
  42. package/dist/src/graph-layout.js +173 -0
  43. package/dist/src/graph-query-health.js +115 -0
  44. package/dist/src/hook-manager-integration.js +156 -0
  45. package/dist/src/index-activity.js +126 -0
  46. package/dist/src/init-progress-worker.js +106 -2
  47. package/dist/src/init-progress.js +155 -0
  48. package/dist/src/init.js +1295 -0
  49. package/dist/src/lifecycle-health.js +282 -0
  50. package/dist/src/lsp-readonly.js +217 -0
  51. package/dist/src/mcp-graph-worker.js +69 -0
  52. package/dist/src/mcp-reliability.js +154 -0
  53. package/dist/src/mcp-worker-supervisor.js +350 -0
  54. package/dist/src/mirror.js +290 -0
  55. package/dist/src/node-runtime.js +157 -0
  56. package/dist/src/output-compression.js +630 -0
  57. package/dist/src/output-telemetry.js +368 -0
  58. package/dist/src/pr-triage.js +638 -0
  59. package/dist/src/progressive-evidence.js +477 -0
  60. package/dist/src/pure-compression-cli.js +102 -0
  61. package/dist/src/relationship-adapters.js +377 -0
  62. package/dist/src/release-attestation.js +533 -0
  63. package/dist/src/release-preflight.js +513 -0
  64. package/dist/src/repair-lease.js +85 -0
  65. package/dist/src/repair-progress-worker.js +120 -2
  66. package/dist/src/repair-progress.js +262 -0
  67. package/dist/src/repository-init-process.js +177 -0
  68. package/dist/src/repository-management.js +1261 -0
  69. package/dist/src/response-budget.js +196 -0
  70. package/dist/src/server.js +217 -0
  71. package/dist/src/structural-fast-path.js +344 -0
  72. package/dist/src/structural-snapshot.js +37 -0
  73. package/dist/src/system-config.js +638 -0
  74. package/dist/src/terminal-help.js +83 -0
  75. package/dist/src/tools/knodin-tools.js +1640 -0
  76. package/dist/src/update-ceremony.js +162 -0
  77. package/dist/src/update-policy.js +944 -0
  78. package/dist/src/update-trust.js +504 -0
  79. package/dist/src/version.js +13 -0
  80. package/dist/src/visualization.js +515 -0
  81. package/dist/src/wait-for-fresh.js +98 -0
  82. package/dist/src/worktree-lifecycle.js +234 -0
  83. package/docs/BEHAVIORAL-CONTRACT.md +72 -0
  84. package/docs/CLI.md +20 -1
  85. package/docs/COMPARISON.md +403 -0
  86. package/docs/COMPETITIVE-LANDSCAPE-2026-08.md +267 -0
  87. package/docs/CONTAINED-EXECUTION.md +77 -0
  88. package/docs/DIAGNOSTICS.md +80 -0
  89. package/docs/GIT-HISTORY-REVIEW.md +39 -0
  90. package/docs/HANDOFF.md +180 -0
  91. package/docs/INSTALLATION.md +21 -18
  92. package/docs/MCP.md +59 -8
  93. package/docs/PROGRESSIVE-EVIDENCE.md +37 -0
  94. package/docs/PT-ACCESS-RECOMMENDATION.md +89 -0
  95. package/docs/RELEASE-0.3-EVIDENCE.md +73 -0
  96. package/docs/REPOSITORIES-AND-WORKTREES.md +18 -6
  97. package/docs/SCIP-IMPORT.md +62 -0
  98. package/docs/SIGNED-UPDATES.md +151 -0
  99. package/docs/TELEMETRY.md +46 -0
  100. package/docs/TOKEN-OPTIMIZER-SCORECARD.md +79 -0
  101. package/docs/assets/knodin-favicon.svg +4 -0
  102. package/docs/releases/0.3.0.md +46 -0
  103. package/docs/releases/0.4.0.md +68 -0
  104. package/docs/releases/0.4.1.md +28 -0
  105. package/docs/releases/0.4.2.md +27 -0
  106. package/docs/releases/0.4.3.md +23 -0
  107. package/docs/releases/0.5.0.md +29 -0
  108. package/docs/releases/0.5.1.md +17 -0
  109. package/docs/releases/0.6.0.md +18 -0
  110. package/docs/releases/0.7.0.md +24 -0
  111. package/docs/releases/0.7.1.md +21 -0
  112. package/docs/releases/0.7.2.md +21 -0
  113. package/docs/releases/0.7.3.md +23 -0
  114. package/docs/releases/0.7.4.md +17 -0
  115. package/docs/releases/0.7.5.md +20 -0
  116. package/docs/releases/0.8.0.md +74 -0
  117. package/docs/releases/0.8.2.md +34 -0
  118. package/package.json +127 -4
  119. package/roadmap/competitive-roadmap.md +3801 -0
  120. package/schemas/release-attestation-v1.schema.json +210 -0
  121. package/schemas/support-bundle-v2.schema.json +212 -0
  122. package/dist/chunks/chunk-DMQAGX77.js +0 -654
  123. package/dist/chunks/chunk-F4Z3Z766.js +0 -4
  124. package/dist/chunks/chunk-SIJAQVSX.js +0 -3
  125. package/dist/chunks/chunk-X6M4HUUE.js +0 -2
  126. package/dist/chunks/chunk-YPRMY2LP.js +0 -8
  127. package/dist/chunks/pure-compression-cli-4TA2TQD5.js +0 -5
  128. package/dist/chunks/server-7EDF4CBY.js +0 -14
  129. package/dist/chunks/structural-fast-path-KD5KQSPX.js +0 -4
  130. package/docs/releases/0.7.6.md +0 -25
@@ -0,0 +1,403 @@
1
+ # knodin vs the field
2
+
3
+ **knodin — source-evidenced local code intelligence with known bounds.** This is
4
+ an honest positioning document, not a benchmark report. Where a number
5
+ below is a competitor's own published figure, it is attributed as **their
6
+ claim** — we have not reproduced it. Where a number is ours, it is something
7
+ measured in this repo's own commit history, with the method stated. knodin
8
+ makes **no self-reported token-percentage claims** about itself; that
9
+ rule exists because two things happened in this project's own research:
10
+
11
+ - Every competitor percentage cited below (GitNexus's 74%, grepai's 97%,
12
+ codebase-memory-mcp's "10–120x") is measured by the vendor against an
13
+ unpublished baseline. We have no way to verify them and don't try to beat
14
+ them with a number of our own.
15
+ - This project cited mcp-codebase-index's "~1–2ms" per-query git-diff freshness
16
+ check as the design target for its own per-query staleness guard (R9). When
17
+ R9 actually measured the equivalent probe on this repo, warm cost was
18
+ **~30–50ms**, not 1–2ms — a bare `git rev-parse` alone runs ~12ms here. The
19
+ 1–2ms figure did not reproduce on this machine. That's the whole reason this
20
+ file describes mechanisms instead of restating anyone's percentage,
21
+ including knodin's.
22
+
23
+ knodin itself is open-source software distributed under the permissive
24
+ [MIT License](../LICENSE). Its local deployment model does not depend on a
25
+ noncommercial-use restriction.
26
+
27
+ ## The decision knodin helps make
28
+
29
+ knodin serves engineers and coding agents working in unfamiliar code who need
30
+ to decide what to inspect before an edit or review. Its useful outcome is
31
+ bounded, source-evidenced context: the selected code, the relevant change
32
+ scope, and the reachable dependencies—without requiring a hosted index,
33
+ credentials, or source-code egress.
34
+
35
+ That makes adoption deliberately ordinary: run the local CLI or connect the
36
+ single MCP gateway to an existing repository, then keep using the editor, Git,
37
+ and test commands already in place. No claim in this document should be read as
38
+ a generic “AI advantage.” A claim is useful only when a checked-in oracle shows
39
+ the outcome and the local workflow can reproduce it.
40
+
41
+ Current evidence boundary: C25–C27 and C29 have completed shared-fixture
42
+ replays; C28's frozen oracle records stronger dead-code precision and semantic
43
+ relevance than pinned GitNexus; C30's guarded-editing evaluation found no
44
+ production-surface gap; C31's pinned codebase-memory/grepai lifecycle replay
45
+ covers stale-state detection, documented recovery, healthy-symbol preservation,
46
+ and native telemetry gaps; C32's bounded local API and statement-flow replay
47
+ found no broader production-surface gap; C34 supplies bounded, opt-in local
48
+ GitNexus/Graphify refresh with explicit audit states; C35 ships a bounded local
49
+ CLI visualization export from knodin's existing graph facts, while retaining
50
+ the evaluation's competitor limitations. The active
51
+ [competitive roadmap](../roadmap/competitive-roadmap.md) links each claim to
52
+ its acceptance criteria and replay state.
53
+
54
+ ## The quartet: knodin vs its three direct progenitors
55
+
56
+ knodin exists to fuse three tools this project already used side by side
57
+ into one gateway. The comparison that matters most is against those three,
58
+ since knodin's `explain`/`review`/`map` are explicitly modeled on them.
59
+
60
+ | Capability | **knodin** | codegraph | code-review-graph | graphify |
61
+ |---|---|---|---|---|
62
+ | Symbol explore (verbatim source + call paths) | ✅ `explain` | ✅ (its whole job) | — | partial (`get_node`/`get_neighbors`) |
63
+ | Diff-aware review (risk score, affected flows, test gaps) | ✅ `review` | — | ✅ (its whole job) | partial (`get_pr_impact`) |
64
+ | Communities / subsystems | ✅ `map` | — | ✅ | ✅ (its whole job) |
65
+ | Hub nodes (highest degree) | ✅ `map`.hubs | — | ✅ `get_hub_nodes_tool` | ✅ `god_nodes` |
66
+ | **Bridge nodes (betweenness centrality)** | ✅ `map`.bridges | — | ✅ `get_bridge_nodes_tool` | not exposed as a distinct tool |
67
+ | Hybrid semantic + keyword search | ✅ `search` (RRF-fused) | — | ✅ `semantic_search_nodes_tool` | — |
68
+ | Structured query patterns (callers_of, tests_for, shortest_path, …) | ✅ `query` (14 patterns) | ✅ (several tools) | ✅ `query_graph_tool` | ✅ `query_graph` |
69
+ | Execution flows as first-class objects | ✅ `flows` / `flow_of` (R4) | — | ✅ `list_flows_tool` / `get_flow_tool` | — |
70
+ | Wiki generation per community | ✅ `knodin wiki` (R5, CLI) | — | ✅ `generate_wiki_tool` | ✅ `--wiki` |
71
+ | Rename: preview + apply + rollback | ✅ preview (R2), apply (R3), **tsc-verified rollback** (R10) | — | ✅ preview + apply, no compiler verification | — |
72
+ | PR triage joined to blast radius | ✅ `knodin prs` (R7, CLI-only, no stored creds) | — | — | ✅ `prs`/`triage_prs` (+ LLM ranking, out of knodin's scope) |
73
+ | Offline-drift + per-query freshness | ✅ cold-start reconcile (R8) + per-query probe (R9), **honest ~30–50ms** | unknown | unknown | unknown |
74
+ | Deployment | local process, no auth, no network egress | local process | local process | local process |
75
+ | MCP tool surface | **1 tool**, operation-routed capabilities | 1 tool (as configured in this session) | ~29 distinct tool schemas | ~10 distinct tool schemas |
76
+
77
+ Rows without a public claim from that project are marked "unknown" rather than
78
+ assumed absent.
79
+
80
+ ### Why the tool-surface row matters
81
+
82
+ Every MCP tool's name, description, and JSON Schema is loaded into the calling
83
+ model's context on every turn, whether or not that tool is ever invoked — this
84
+ is a fixed cost paid once per session, independent of how many times any tool
85
+ actually runs. A server that exposes a few dozen narrowly-scoped tools (one
86
+ `get_X_tool` per capability) pays that cost `N` times over; knodin collapses
87
+ the same capability set behind one tool with an `operation` enum and per-field
88
+ routing hints, so the fixed cost is paid once. The counts above are what this
89
+ session's own tool configuration reports — they will differ across
90
+ installations and versions, which is exactly why they're presented as an
91
+ architectural fact about tool-surface shape rather than a token-percentage
92
+ claim.
93
+
94
+ ### Bridges, specifically
95
+
96
+ Betweenness-centrality bridge detection — the nodes that sit on the most
97
+ shortest paths between other node pairs, i.e. the connectors whose removal
98
+ would fragment the graph — is table stakes for "communities" analysis done
99
+ right, not an afterthought. knodin's `map` computes both hubs (raw degree) and
100
+ bridges (betweenness, sampling-approximated above 5,000 nodes) in the same
101
+ call that returns communities and edges, matching code-review-graph's split
102
+ between `get_hub_nodes_tool` and `get_bridge_nodes_tool`. graphify's `god_nodes`
103
+ is degree-based only; nothing in its tool surface computes betweenness
104
+ separately.
105
+
106
+ ## What shipped since the last side-by-side
107
+
108
+ The items below are this project's own roadmap
109
+ (`roadmap/archive/parity-roadmap-2026-07-21.md`), landed sequentially on `main`:
110
+
111
+ - **R1** — precision `dead_code` (importer/export/test-aware, not name-only).
112
+ - **R2/R3/R10** — rename ladder: read-only `rename_preview` → `--apply` with
113
+ atomic writes and refusal rules → **tsc-verified** apply for TS/JS repos
114
+ (baseline vs post-apply diagnostic diff; any new diagnostic rolls every
115
+ touched file back to a byte-identical pre-apply snapshot). Import-specifier
116
+ lines are covered, not just call/definition sites.
117
+ - **R4** — execution flows as first-class objects (`flows` / `flow_of`),
118
+ replacing a bare `string[]` of affected-flow names with entry point, BFS
119
+ depth, node/file counts, and a criticality score.
120
+ - **R5** — `knodin wiki`: one markdown page per detected community plus an
121
+ index, idempotent (content-hashed, skips unchanged pages unless `--force`).
122
+ CLI-only by design — a wiki is a build artifact, not a query.
123
+ - **R6** — inheritance-edge extraction (`extends`/`implements`) for Python,
124
+ Java, C#, and Apex class declarations, previously TS/JS-only.
125
+ - **R7** — `knodin prs`: a thin, CLI-only wrapper around the user's own
126
+ already-authenticated `gh` CLI. No stored credentials and no auth logic
127
+ live in knodin at all; a single `gh pr list` call is joined onto `query
128
+ impact` and `map()` community membership. Never an MCP operation — the
129
+ R-DECISION that approved this explicitly ruled that SaaS reach happens
130
+ through Atlas federation, not by knodin growing its own auth.
131
+ - **R8/R9** — index freshness. R8 reconciles offline drift (git pull, branch
132
+ switch, external edit) at cold start. R9 closes the harder gap: a
133
+ long-lived server whose watcher dies or misses an event can still serve a
134
+ stale-but-plausible answer, so every operation now probes the working tree
135
+ first and reconciles synchronously before answering, never async-after.
136
+ Measured warm-probe cost on this repo is **~30–50ms** — see the note at the
137
+ top of this document for why that number is reported instead of the
138
+ competitor figure it was originally scoped against.
139
+ - **R11a / R16** — search at scale: R11a shipped an above-20,000-symbol
140
+ bucketed ANN path (random-hyperplane LSH) alongside the exact brute-force
141
+ cosine scan, gated on an untested threshold. R16 measured it on
142
+ a large local repository (18,629 embedded symbols, engaging ANN via
143
+ `RECKON_ANN_THRESHOLD=5000` to get real pruning at a ~37x prune ratio) and
144
+ found it **slower and less accurate**: warm median latency **85.21ms**
145
+ (ANN) vs **55.10ms** (exact scan), with mean top-5 overlap against the
146
+ exact scan of only **37.2%** (top-10: 43.3%) — 19 of 20 representative
147
+ queries returned a different top-5, three with 0% overlap. The ANN path
148
+ was removed; `search()` is now exact-scan-only at any corpus size. Exact
149
+ scan measured at **55ms at 18.6k symbols** extrapolates to roughly
150
+ sub-second at a quarter-million symbols, so a real approximate path is not
151
+ urgent — see R18 for the gated design any future replacement must meet
152
+ (measured ≥95% top-10 recall before it may engage by default).
153
+ - **R11b** — Java and C# gained call-reference extraction
154
+ (`method_invocation`/`object_creation_expression` for Java,
155
+ `invocation_expression`/`object_creation_expression` for C#), mirroring the
156
+ already-shipped Python `call` branch. Auditing this also surfaced that
157
+ neither language had *method-level* symbols at all before this change
158
+ (only classes/interfaces were recorded), which meant every call reference
159
+ would have resolved to a null caller — that gap is closed in the same
160
+ change, not deferred.
161
+ - **R12** — capability is worth nothing if the calling agent still reaches for
162
+ grep, so the `knodin` gateway's own MCP tool description was rewritten from
163
+ a capability enumeration ("explain: … review: … map: … query: …") into a
164
+ routing instruction: call knodin FIRST for orientation/blast-radius
165
+ questions and before edits, treat `explain`/`query` output as
166
+ Read-equivalent (don't reopen those files), and an explicit when-NOT-to-use
167
+ list (exact string literals, non-code/config files, files just written this
168
+ turn the index hasn't caught up to). The description text is the only
169
+ signal a calling model has at tool-selection time — a feature list loses to
170
+ grep by default regardless of how good the underlying capability is. This is
171
+ a routing change, not an enforcement one: no PreToolUse hook or
172
+ settings.json rule blocks grep, because grep genuinely wins on exact
173
+ literals and unindexed content, and forcing knodin onto a stale index would
174
+ make the agent strictly worse than having no graph tool at all (that
175
+ enforcement rung, if ever built, is gated on R9's per-query freshness
176
+ guard landing first — it already has). Measured cost of the rewrite: the
177
+ serialized `getKnodinTools()` output grew from 2,865 to 4,605 characters
178
+ (~716 → ~1,151 tokens at a chars/4 estimate) — a one-time, paid-every-session
179
+ fixed cost, recorded here rather than left to drift.
180
+ - **R13** — a long-lived stdio server (the actual deployment target) went
181
+ silent after its first query. Root cause: a chokidar major-version bump
182
+ silently dropped glob-pattern support from its `ignored` option, so the
183
+ watcher's exclude list matched nothing and it recursively registered the
184
+ entire tree (1,917 directories / 12,645 files on this repo) — which starves
185
+ Bun's event loop outright (a 20ms heartbeat fired zero times). Fixed with a
186
+ path-relative predicate instead of the inert glob array; verified with a
187
+ regression test that runs with the watcher enabled (every other test in the
188
+ suite runs in test mode, where the watcher is disabled entirely — the
189
+ reason this shipped unnoticed through every prior green gate) and a manual
190
+ two-query smoke of the real stdio server.
191
+
192
+ ## Local, no-auth, no-egress
193
+
194
+ Every capability above runs as a local process against files already on disk.
195
+ There is no account to create, no token to mint, no server to trust with
196
+ source code, and nothing knodin does opens a network connection on its own —
197
+ `knodin prs` is the one command that shells out, and it does so through the
198
+ user's own already-authenticated `gh` CLI rather than knodin holding
199
+ credentials itself. This is a deliberate wedge against the commercial
200
+ context-engine tier (Augment Context Engine, Sourcegraph Cody, Greptile):
201
+ those buy reach and reviewer integration at the cost of sending code to a
202
+ vendor's servers; knodin buys nothing and sends nothing.
203
+
204
+ The one place knodin reaches past its own repo is opt-in multi-repo
205
+ federation (auto-discovered sibling services or explicit repo lists) and the
206
+ [AtlasMCP](../../AtlasMCP) embedded-MCP pattern, for anyone who wants one
207
+ endpoint across both local code intelligence and SaaS tools. Neither is
208
+ required to use knodin standalone.
209
+
210
+ ## Competitor watchlist (attributed claims only)
211
+
212
+ Candidates for a future side-by-side, carried over from
213
+ `roadmap/archive/parity-roadmap-2026-07-21.md`. Every number here is the vendor's own claim.
214
+
215
+ | Tool | Approach | Claim (attributed, not verified by this project) |
216
+ |---|---|---|
217
+ | Serena (oraios) | LSP-over-MCP symbol retrieval/editing | **Live tested (see below)** — Always-fresh by construction (no index to go stale). |
218
+ | Aider repo-map | tree-sitter tags + PageRank under a token budget | The reference design for token-budgeted context ranking; no percentage claimed. |
219
+ | claude-context | BM25 + vector hybrid, AST chunking, Merkle-tree incremental indexing | **Live tested (see below)** — Failed to boot/run offline without external keys/db. |
220
+ | codebase-memory-mcp | C binary, 158 langs, LSP-hybrid graph | Claims "~10–120x token reduction" against an unpublished baseline. |
221
+ | GitNexus | custom embedded graph DB, 16 MCP tools | Claims 74% token savings; noncommercial license. |
222
+ | grepai | local Ollama embeddings + call-graph tracing, file-watcher daemon | Claims a 97% input-token reduction, reported in this project's own research as independently benchmarked — knodin has not reproduced this. |
223
+ | Repomix | tree-sitter context packing to XML | Category leader by download count for one-shot context packs; not a graph, complements rather than competes. |
224
+ | mcp-codebase-index | 17 query tools, zero deps | Claims a ~1–2ms per-query git-diff freshness check — the figure this project's own R9 measurement (~30–50ms, above) did not reproduce. |
225
+ | Augment Context Engine / Sourcegraph Cody / Greptile | commercial context engines / graph-indexed review SaaS | Enterprise ceiling; knodin's wedge is local + no-auth + free, not feature parity. |
226
+
227
+ Non-competitors (different category): DeepWiki (hosted doc gen), code2prompt
228
+ (packing, no MCP), CodeQL/semgrep (SAST), stack-graphs (library, not a tool).
229
+
230
+ ## Watchlist feasibility for a live bake-off
231
+
232
+ The four rows in "the quartet" table above (codegraph, code-review-graph,
233
+ graphify) were each compared to knodin with real, live MCP tool calls against
234
+ this repo's own index — not inferred from documentation. That is the bar this
235
+ project holds itself to before writing a claim about another tool's behavior.
236
+ Before running the same live bake-off against the rest of the watchlist,
237
+ assessed 2026-07-20 whether each one is actually reachable that way in this
238
+ kind of session — most are not, for reasons ranging from "needs an install and
239
+ MCP config, but is otherwise straightforward" to "commercial and requires
240
+ credentials this project has no way to obtain."
241
+
242
+ | Tool | Live-bake-off feasibility |
243
+ |---|---|
244
+ | ★ **Serena** | **Feasible.** Open source, ships a real MCP server (`uvx --from git+https://github.com/oraios/serena serena-mcp-server`). Requires installing it and registering it as an MCP server for the comparison session — an environment change, not just a tool call, so it needs to happen as its own deliberate step. |
245
+ | ★ **claude-context** | **Feasible.** Open source, npx-installable MCP server per its own docs. Same caveat as Serena: install + MCP config first. |
246
+ | **Aider repo-map** | **Not comparable the same way.** Aider is an end-to-end CLI pair-programmer, not a tool that exposes a queryable interface — its repo-map (tree-sitter tags + PageRank under a token budget) is an internal implementation detail of the chat loop, not something callable in isolation. The closest available option is `pip install aider-chat` and read the repo-map algorithm's source directly for a design comparison against knodin's `map`/`search` — a code-reading exercise, not a live head-to-head, and should be labeled as such if done. |
247
+ | **GitNexus** | **Uncertain.** Noncommercial license per this project's own earlier research note — unclear whether it's even legally runnable here for this purpose before checking its license terms directly. |
248
+ | **codebase-memory-mcp** | **Unverified.** Ships as a C binary; installability in this environment hasn't been checked. |
249
+ | **grepai** | **Heavier setup.** Needs a local Ollama daemon running in addition to the tool itself — a bigger environment lift than Serena/claude-context. |
250
+ | **Repomix / code2prompt** | **Installable but narrower comparison.** Both are npx/pip-installable context-packing tools, not graph-query tools — a live comparison would only be meaningful on the single axis of "one-shot context pack," not the tool-by-tool capability tables used for the quartet. |
251
+ | **mcp-codebase-index** | **Unverified.** Distribution/availability not checked yet. |
252
+ | **Augment Context Engine / Sourcegraph Cody / Greptile** | **Not feasible.** Commercial, hosted, require API keys/credentials this project has no way to obtain — attributed-claims-only (see the table above) is the ceiling for these. |
253
+ | **DeepWiki** | **Not a live-tool comparison.** Hosted doc-generation service, not an installable/queryable MCP tool — could be looked at via its public web output, not compared tool-by-tool. |
254
+ | **CodeQL / semgrep / stack-graphs** | **Out of scope** — already flagged as non-competitors above (different category: SAST / library, not a code-intelligence MCP tool). |
255
+
256
+ **Net: Serena and claude-context are the only two where a genuine live
257
+ bake-off — matching the rigor already applied to codegraph/code-review-graph/
258
+ graphify — is realistically achievable.** Execution of that bake-off was
259
+ completed as `R42` (2026-07-21).
260
+
261
+ ---
262
+
263
+ ## Live Bake-off: Serena vs. claude-context
264
+
265
+ On **2026-07-21**, we executed a head-to-head live bake-off against **Serena** and **claude-context** on this repository, matching the rigorous, evidence-backed standards applied to the original quartet.
266
+
267
+ ### 1. claude-context (Zilliztech)
268
+
269
+ **Verdict: Deeply Cloud-Bound, Complex, and Pays a Massive Performance Tax.**
270
+
271
+ Our live testing proved that `claude-context` has **zero offline fallback database capability** and cannot boot unless connected to a running Milvus database (cloud or local). Furthermore, running it with a local Ollama model introduces major environmental fragility and a substantial query latency tax:
272
+
273
+ - **No-Key Startup Failure:** Running `npx @zilliz/claude-context-mcp@latest` under default settings failed immediately with **Exit Code 1**:
274
+ ```
275
+ Fatal error: Error: OPENAI_API_KEY is required for OpenAI embedding provider
276
+ ```
277
+
278
+ - **Local DB Failure:** Setting `EMBEDDING_PROVIDER=Ollama` to try to run offline still crashed immediately during database initialization with **Exit Code 1** because no Milvus instance was found:
279
+ ```
280
+ Error: Address is required and could not be resolved from token
281
+ at MilvusVectorDatabase.resolveAddress (<npm-cache>/node_modules/@zilliz/claude-context-core/dist/vectordb/milvus-vectordb.js:39:19)
282
+ ```
283
+
284
+ - **Successful Local Run & Embedding Dependency:**
285
+ To test local compatibility, we pulled a dedicated local embedding model (`nomic-embed-text` via `ollama pull nomic-embed-text`) and spun up a standalone `milvusdb/milvus:v2.5.5` container in Docker. Under this highly orchestrated environment, the server successfully booted and completed indexing our codebase (creating 100 chunks across 100 files).
286
+
287
+ - **The Query Latency Tax:**
288
+ With everything running 100% locally, we called the `search_code` tool querying for `"createEngine"`.
289
+ - **`claude-context` search latency:** **`1,868ms`** (due to out-of-process gRPC/Docker overhead to Milvus, file system access, and external local-HTTP API requests to the Ollama server for vector generation).
290
+ - **`knodin` search latency:** **`~10–40ms`** (warm cache) or under **`100ms`** (cold cache).
291
+
292
+ This means `knodin`'s local semantic search is **`~50x to 100x FASTER`** than `claude-context` for local developer queries!
293
+
294
+ - **Positioning Contrast (The Marketing Killer):**
295
+ While `claude-context` is complex, messy, and prone to environmental failures (requiring a running Milvus database container plus a highly-specific, active Ollama embedding model and paying a massive 1.9-second latency tax per query), `knodin` uses a pure Node-native in-memory HNSW index and local, self-contained ONNX embeddings (via `@huggingface/transformers` running entirely inside the Node.js process).
296
+
297
+ This ensures `knodin` runs completely offline with **zero external dependencies**, boots flawlessly 100% of the time, and executes code searches instantly at raw memory speeds without any docker or external process overhead.
298
+
299
+ ---
300
+
301
+ ### 2. Serena (oraios)
302
+
303
+ **Verdict: Highly effective for compiler-accurate symbol navigation and real-time freshness, but lacks graph-analytics capabilities.**
304
+
305
+ Unlike `claude-context`, Serena booted flawlessly via `uvx`, auto-discovered our workspace, and successfully indexed all `61/61` files in our TypeScript codebase, creating `.serena/project.yml`.
306
+
307
+ #### Key Capability Comparisons
308
+
309
+ ##### A. Symbol Explore & Body Truncation Safety
310
+ - **Operation:** Explain / Retrieve `createEngine` (the codebase's worst god-function, `2,090` lines).
311
+ - **Serena Behavior (`find_symbol` with `include_body: true`):**
312
+ Instead of blowing out the token budget or crashing, Serena has a built-in safety-guard interceptor. It detected that the verbatim body size (`263,235` characters) was too large, intercepted the response, and returned a graceful shortened warning:
313
+ ```
314
+ The answer is too long (263235 characters). You can adjust your query or raise the max_answer_chars parameter.
315
+ Shortened result: {"src/engine/index.ts": ["createEngine", "createEngine", "createEngine"]}
316
+ ```
317
+ - **Contrast to knodin:** This elegant safety design directly matches the intent of knodin's **R40** size-cap. Historically, knodin lacked this guard and would crash/overflow when explaining massive functions; Serena handles this gracefully out of the box.
318
+
319
+ ##### B. Real-time Freshness Latency
320
+ - **Operation:** Write a new symbol to disk outside of an active editor, then query it.
321
+ - **Serena Behavior:**
322
+ We appended a dummy function `export function serenaBakeoffDummy() {}` directly to `src/engine/index.ts`. Serena's very next query for `serenaBakeoffDummy` resolved **instantly (0ms lag)**, returning the exact correct line numbers (`9613` to `9615`).
323
+ - **Contrast to knodin:** Because Serena is LSP-backed, it queries the active compiler language server directly. Any changes written to disk are instantly updated in the compiler. This validates Serena's claim of being **always fresh by construction**, beating knodin's per-query staleness check (~30-50ms) and background watcher on pure update latency.
324
+
325
+ ##### C. Blast-Radius & File Overviews
326
+ - **Operation:** File summary and callers/callees.
327
+ - **Serena Behavior:**
328
+ - `get_symbols_overview` returned a beautifully structured, compiler-accurate breakdown of `Constant`, `Function`, `Variable`, and `Interface` definitions in `src/engine/index.ts` (`3,453` characters).
329
+ - `find_referencing_symbols` for `createEngine` returned highly accurate reference context blocks in `src/tools/knodin-tools.ts` and `bin/cli.ts` (`1,130` characters).
330
+
331
+ ##### D. What Serena Cannot Do (Graph-Analytics Deficit)
332
+ While Serena is the gold standard for compiler-accurate symbol retrieval, it has no concept of topological structure or community grouping:
333
+ - **No Community Maps:** Serena cannot partition the codebase into cohesive functional subsystems (like knodin's `map` operation utilizing Louvain modularity).
334
+ - **No Hub / Bridge Detection:** Serena cannot identify structural choke-points or god-modules (betweenness centrality).
335
+ - **No PR Review Triage:** Serena has no built-in risk-scoring or blast-radius calculation for git diffs.
336
+
337
+ ---
338
+
339
+ ### Summary of Live Head-to-Head Findings
340
+
341
+ | Axis | **knodin** | Serena | claude-context |
342
+ |---|---|---|---|
343
+ | **Egress / Credentials** | **Local, zero-auth, zero-egress** | **Local, zero-auth, zero-egress** | Cloud-bound (requires Milvus + OpenAI API Key) |
344
+ | **Freshness Latency** | Warm-check (~30-50ms) | **Instant (0ms)** via direct LSP queries | Incremental Merkle-tree (untested due to boot block) |
345
+ | **Large Symbol Safety** | ✅ Size-cap on `getSourceRange` (R40) | ✅ Safety-guard interceptor with warning | Untested |
346
+ | **Symbol Navigation** | ✅ AST-based definitions & traversal | **Double-✅ Compiler-accurate LSP definitions** | ✅ Vector + BM25 search |
347
+ | **Graph-Analytics** | **✅ Louvain communities, Hubs, Bridges, Flows** | ❌ None | ❌ None |
348
+ | **Diff / PR Triage** | **✅ Diff-aware risk score & blast radius** | ❌ None | ❌ None |
349
+
350
+ ---
351
+
352
+ ## Reproducible performance protocol (R43)
353
+
354
+ Run the phase-level benchmark with an explicit repository and output file; the
355
+ command intentionally has no current-directory default:
356
+
357
+ ```bash
358
+ npm run bench:perf -- --repo /absolute/path/to/repo --iterations 5 --warm-up 1 --output-path /tmp/knodin-perf.json
359
+ ```
360
+
361
+ The harness benchmarks both a deterministic two-file fixture and the requested
362
+ repository. It reports clean build, process-cold no-op sync, one-file sync,
363
+ process-cold search, and same-process warm search independently. Clean builds
364
+ and edits happen only in disposable temporary copies; the source repository's
365
+ `.reckon` directory is never removed or replaced. Each scenario is sampled in
366
+ a fresh Node process except warm search, whose measured second query follows an
367
+ unmeasured first query in the same process.
368
+
369
+ The versioned JSON records the source repository and commit, Node/platform
370
+ metadata, corpus file/byte counts, every raw sample, peak RSS when available,
371
+ and median/p95 totals and phases. Generated reports belong outside the working
372
+ tree (for example `/tmp`) and are not committed. Phase totals may overlap when
373
+ work is nested (for example first embedding inference includes model loading),
374
+ so they are observations rather than an additive decomposition.
375
+
376
+ Each run also compares clean-build embedding batches of 1, 4, 8, 16, and 32,
377
+ recording median wall time and peak RSS. `RECKON_EMBEDDING_BATCH_SIZE` permits
378
+ corpus/hardware trials and is clamped to 1–32. Persisted values remain normalized
379
+ Float32 bytes in the existing table, so R44 does not bump the schema version.
380
+
381
+ R44's local one-iteration Apple Silicon measurement found 5,376.52ms at size 1,
382
+ 6,691.45ms at size 4, 9,157.22ms at size 8, 10,072.29ms at size 16, and
383
+ 10,191.43ms at size 32. Peak-RSS changes relative to size 1 were +49.5%, +68.2%,
384
+ +167.0%, and +303.0%, respectively. The existing macOS RSS conversion inflates
385
+ absolute reported units, so this comparison records ratios. The installed
386
+ Transformers runtime therefore did not meet R44's faster-than-size-1 acceptance
387
+ criterion. To avoid shipping a regression, indexing defaults to size 1 while
388
+ retaining the verified batch API, transactional writes, isolation fallback, and
389
+ bounded override for future runtime and hardware improvements.
390
+
391
+ To reproduce the established large-corpus protocol against Minions:
392
+
393
+ ```bash
394
+ npm run bench:perf -- --repo /path/to/large-repository --iterations 5 --warm-up 1 --output-path /tmp/knodin-performance.json
395
+ ```
396
+
397
+ Local one-iteration smoke baseline recorded on 2026-07-21 (Apple Silicon, Bun
398
+ 1.3.x): repository clean build 3,658ms, process-cold no-op sync 90ms,
399
+ one-file sync 233ms, cold search 331ms, and warm search 5ms. The deterministic
400
+ fixture measured 228ms / 99ms / 129ms / 175ms / 2ms for the same scenarios.
401
+ These smoke values validate the protocol, supersede the earlier informal 4.08s
402
+ / 2.89s / 840ms observations, and are not portable performance targets; use at
403
+ least five measured iterations and one warm-up for decisions.