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.
- package/README.md +19 -7
- package/benchmarks/competitors/SYNTHESIS.md +66 -0
- package/dist/bin/cli.js +2164 -108
- package/dist/bin/launcher.js +25 -3
- package/dist/src/agent-integration.js +304 -0
- package/dist/src/artifact-refresh.js +82 -0
- package/dist/src/cli-args.js +292 -0
- package/dist/src/cli-model.js +384 -0
- package/dist/src/codeflow-replay.js +81 -0
- package/dist/src/compact-structural.js +96 -0
- package/dist/src/compare.js +39 -0
- package/dist/src/competitive-cold-mcp.js +40 -0
- package/dist/src/competitive-constraints.js +21 -0
- package/dist/src/competitive-manifest.js +411 -0
- package/dist/src/competitive-measurement.js +183 -0
- package/dist/src/competitive-runner.js +487 -0
- package/dist/src/competitive-sandbox.js +108 -0
- package/dist/src/context-export.js +423 -0
- package/dist/src/context.js +102 -0
- package/dist/src/deterministic-random.js +34 -0
- package/dist/src/diagnostics-write-helper.js +473 -0
- package/dist/src/diagnostics.js +1476 -0
- package/dist/src/docs-sections.js +141 -0
- package/dist/src/doctor.js +382 -0
- package/dist/src/engine/ann-hnsw.js +261 -0
- package/dist/src/engine/embeddings.js +193 -0
- package/dist/src/engine/file-walker.js +49 -0
- package/dist/src/engine/git-history.js +289 -0
- package/dist/src/engine/index.js +14238 -0
- package/dist/src/engine/perf.js +115 -0
- package/dist/src/engine/prune.js +112 -0
- package/dist/src/engine/sarif-import.js +341 -0
- package/dist/src/engine/scip-import.js +423 -0
- package/dist/src/engine/source-policy.js +85 -0
- package/dist/src/engine/sqlite.js +71 -0
- package/dist/src/engine/state-paths.js +175 -0
- package/dist/src/engine/symbol-delete.js +58 -0
- package/dist/src/execution-profile.js +208 -0
- package/dist/src/failure-diagnosis.js +655 -0
- package/dist/src/fleet.js +7 -0
- package/dist/src/git-executable.js +31 -0
- package/dist/src/graph-layout.js +173 -0
- package/dist/src/graph-query-health.js +115 -0
- package/dist/src/hook-manager-integration.js +156 -0
- package/dist/src/index-activity.js +126 -0
- package/dist/src/init-progress-worker.js +106 -2
- package/dist/src/init-progress.js +155 -0
- package/dist/src/init.js +1295 -0
- package/dist/src/lifecycle-health.js +282 -0
- package/dist/src/lsp-readonly.js +217 -0
- package/dist/src/mcp-graph-worker.js +69 -0
- package/dist/src/mcp-reliability.js +154 -0
- package/dist/src/mcp-worker-supervisor.js +350 -0
- package/dist/src/mirror.js +290 -0
- package/dist/src/node-runtime.js +157 -0
- package/dist/src/output-compression.js +630 -0
- package/dist/src/output-telemetry.js +368 -0
- package/dist/src/pr-triage.js +638 -0
- package/dist/src/progressive-evidence.js +477 -0
- package/dist/src/pure-compression-cli.js +102 -0
- package/dist/src/relationship-adapters.js +377 -0
- package/dist/src/release-attestation.js +533 -0
- package/dist/src/release-preflight.js +513 -0
- package/dist/src/repair-lease.js +85 -0
- package/dist/src/repair-progress-worker.js +120 -2
- package/dist/src/repair-progress.js +262 -0
- package/dist/src/repository-init-process.js +177 -0
- package/dist/src/repository-management.js +1261 -0
- package/dist/src/response-budget.js +196 -0
- package/dist/src/server.js +217 -0
- package/dist/src/structural-fast-path.js +344 -0
- package/dist/src/structural-snapshot.js +37 -0
- package/dist/src/system-config.js +638 -0
- package/dist/src/terminal-help.js +83 -0
- package/dist/src/tools/knodin-tools.js +1640 -0
- package/dist/src/update-ceremony.js +162 -0
- package/dist/src/update-policy.js +944 -0
- package/dist/src/update-trust.js +504 -0
- package/dist/src/version.js +13 -0
- package/dist/src/visualization.js +515 -0
- package/dist/src/wait-for-fresh.js +98 -0
- package/dist/src/worktree-lifecycle.js +234 -0
- package/docs/BEHAVIORAL-CONTRACT.md +72 -0
- package/docs/CLI.md +20 -1
- package/docs/COMPARISON.md +403 -0
- package/docs/COMPETITIVE-LANDSCAPE-2026-08.md +267 -0
- package/docs/CONTAINED-EXECUTION.md +77 -0
- package/docs/DIAGNOSTICS.md +80 -0
- package/docs/GIT-HISTORY-REVIEW.md +39 -0
- package/docs/HANDOFF.md +180 -0
- package/docs/INSTALLATION.md +21 -18
- package/docs/MCP.md +59 -8
- package/docs/PROGRESSIVE-EVIDENCE.md +37 -0
- package/docs/PT-ACCESS-RECOMMENDATION.md +89 -0
- package/docs/RELEASE-0.3-EVIDENCE.md +73 -0
- package/docs/REPOSITORIES-AND-WORKTREES.md +18 -6
- package/docs/SCIP-IMPORT.md +62 -0
- package/docs/SIGNED-UPDATES.md +151 -0
- package/docs/TELEMETRY.md +46 -0
- package/docs/TOKEN-OPTIMIZER-SCORECARD.md +79 -0
- package/docs/assets/knodin-favicon.svg +4 -0
- package/docs/releases/0.3.0.md +46 -0
- package/docs/releases/0.4.0.md +68 -0
- package/docs/releases/0.4.1.md +28 -0
- package/docs/releases/0.4.2.md +27 -0
- package/docs/releases/0.4.3.md +23 -0
- package/docs/releases/0.5.0.md +29 -0
- package/docs/releases/0.5.1.md +17 -0
- package/docs/releases/0.6.0.md +18 -0
- package/docs/releases/0.7.0.md +24 -0
- package/docs/releases/0.7.1.md +21 -0
- package/docs/releases/0.7.2.md +21 -0
- package/docs/releases/0.7.3.md +23 -0
- package/docs/releases/0.7.4.md +17 -0
- package/docs/releases/0.7.5.md +20 -0
- package/docs/releases/0.8.0.md +74 -0
- package/docs/releases/0.8.2.md +34 -0
- package/package.json +127 -4
- package/roadmap/competitive-roadmap.md +3801 -0
- package/schemas/release-attestation-v1.schema.json +210 -0
- package/schemas/support-bundle-v2.schema.json +212 -0
- package/dist/chunks/chunk-DMQAGX77.js +0 -654
- package/dist/chunks/chunk-F4Z3Z766.js +0 -4
- package/dist/chunks/chunk-SIJAQVSX.js +0 -3
- package/dist/chunks/chunk-X6M4HUUE.js +0 -2
- package/dist/chunks/chunk-YPRMY2LP.js +0 -8
- package/dist/chunks/pure-compression-cli-4TA2TQD5.js +0 -5
- package/dist/chunks/server-7EDF4CBY.js +0 -14
- package/dist/chunks/structural-fast-path-KD5KQSPX.js +0 -4
- 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.
|