@quolu/lattice 0.1.0 → 0.12.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 (370) hide show
  1. package/README.md +87 -4
  2. package/bin/lattice-bridge.mjs +87 -0
  3. package/bin/lattice-dashboard.mjs +70 -0
  4. package/bin/lattice-mcp.mjs +9 -9
  5. package/bin/lattice.mjs +61 -8
  6. package/docs/bridge-setup.md +87 -0
  7. package/docs/schemas/lattice.plan_create_input.v1.schema.json +56 -0
  8. package/docs/schemas/lattice.plan_create_input.v2.schema.json +72 -0
  9. package/docs/schemas/lattice.plan_create_input.v3.schema.json +81 -0
  10. package/package.json +19 -7
  11. package/sensor/dist/bin/command-supervision.d.ts +1 -1
  12. package/sensor/dist/bin/command-supervision.js +4 -4
  13. package/sensor/dist/bin/command-supervision.js.map +1 -1
  14. package/sensor/dist/bin/fatal-handler.js +2 -2
  15. package/sensor/dist/bin/fatal-handler.js.map +1 -1
  16. package/sensor/dist/bin/{codegraph.js → lattice-sensor.js} +207 -328
  17. package/sensor/dist/bin/node-version-check.d.ts +7 -5
  18. package/sensor/dist/bin/node-version-check.d.ts.map +1 -1
  19. package/sensor/dist/bin/node-version-check.js +19 -14
  20. package/sensor/dist/bin/node-version-check.js.map +1 -1
  21. package/sensor/dist/context/index.d.ts +1 -1
  22. package/sensor/dist/context/index.js +6 -6
  23. package/sensor/dist/context/index.js.map +1 -1
  24. package/sensor/dist/db/index.d.ts +5 -5
  25. package/sensor/dist/db/index.d.ts.map +1 -1
  26. package/sensor/dist/db/index.js +7 -7
  27. package/sensor/dist/db/index.js.map +1 -1
  28. package/sensor/dist/db/migrations.js +1 -1
  29. package/sensor/dist/db/migrations.js.map +1 -1
  30. package/sensor/dist/db/queries.d.ts +1 -1
  31. package/sensor/dist/db/queries.js +5 -5
  32. package/sensor/dist/db/queries.js.map +1 -1
  33. package/sensor/dist/db/schema.sql +2 -2
  34. package/sensor/dist/db/sqlite-adapter.d.ts +2 -2
  35. package/sensor/dist/db/sqlite-adapter.js +3 -3
  36. package/sensor/dist/db/sqlite-adapter.js.map +1 -1
  37. package/sensor/dist/db/wal-valve.d.ts +1 -1
  38. package/sensor/dist/db/wal-valve.d.ts.map +1 -1
  39. package/sensor/dist/db/wal-valve.js +2 -2
  40. package/sensor/dist/db/wal-valve.js.map +1 -1
  41. package/sensor/dist/directory.d.ts +27 -63
  42. package/sensor/dist/directory.d.ts.map +1 -1
  43. package/sensor/dist/directory.js +78 -134
  44. package/sensor/dist/directory.js.map +1 -1
  45. package/sensor/dist/errors.d.ts +15 -15
  46. package/sensor/dist/errors.d.ts.map +1 -1
  47. package/sensor/dist/errors.js +21 -21
  48. package/sensor/dist/errors.js.map +1 -1
  49. package/sensor/dist/extraction/dynamic-import.d.ts +1 -1
  50. package/sensor/dist/extraction/dynamic-import.js +1 -1
  51. package/sensor/dist/extraction/extraction-version.d.ts +1 -1
  52. package/sensor/dist/extraction/extraction-version.js +1 -1
  53. package/sensor/dist/extraction/generated-detection.d.ts +1 -1
  54. package/sensor/dist/extraction/generated-detection.js +1 -1
  55. package/sensor/dist/extraction/grammars.d.ts +3 -3
  56. package/sensor/dist/extraction/grammars.js +5 -5
  57. package/sensor/dist/extraction/grammars.js.map +1 -1
  58. package/sensor/dist/extraction/index.d.ts +6 -6
  59. package/sensor/dist/extraction/index.js +50 -50
  60. package/sensor/dist/extraction/index.js.map +1 -1
  61. package/sensor/dist/extraction/kernel/decode.d.ts +1 -1
  62. package/sensor/dist/extraction/kernel/decode.js +1 -1
  63. package/sensor/dist/extraction/kernel/index.d.ts +3 -3
  64. package/sensor/dist/extraction/kernel/index.js +6 -6
  65. package/sensor/dist/extraction/kernel/index.js.map +1 -1
  66. package/sensor/dist/extraction/kernel/layout.d.ts +1 -1
  67. package/sensor/dist/extraction/kernel/layout.js +1 -1
  68. package/sensor/dist/extraction/kernel/loader.d.ts +6 -6
  69. package/sensor/dist/extraction/kernel/loader.js +13 -13
  70. package/sensor/dist/extraction/kernel/loader.js.map +1 -1
  71. package/sensor/dist/extraction/languages/cfquery.d.ts +1 -1
  72. package/sensor/dist/extraction/languages/cfquery.js +1 -1
  73. package/sensor/dist/extraction/languages/lua.d.ts +11 -0
  74. package/sensor/dist/extraction/languages/lua.d.ts.map +1 -1
  75. package/sensor/dist/extraction/languages/lua.js +1 -0
  76. package/sensor/dist/extraction/languages/lua.js.map +1 -1
  77. package/sensor/dist/extraction/parse-pool.d.ts +5 -5
  78. package/sensor/dist/extraction/parse-pool.d.ts.map +1 -1
  79. package/sensor/dist/extraction/parse-pool.js +4 -4
  80. package/sensor/dist/extraction/parse-worker.js +1 -1
  81. package/sensor/dist/extraction/parse-worker.js.map +1 -1
  82. package/sensor/dist/extraction/store-writer.d.ts +1 -1
  83. package/sensor/dist/extraction/store-writer.js +1 -1
  84. package/sensor/dist/extraction/svelte-extractor.d.ts +1 -1
  85. package/sensor/dist/extraction/svelte-extractor.js +1 -1
  86. package/sensor/dist/extraction/tree-sitter-helpers.js +1 -1
  87. package/sensor/dist/extraction/tree-sitter.d.ts +2 -2
  88. package/sensor/dist/extraction/tree-sitter.d.ts.map +1 -1
  89. package/sensor/dist/extraction/tree-sitter.js +71 -4
  90. package/sensor/dist/extraction/tree-sitter.js.map +1 -1
  91. package/sensor/dist/extraction/wasm-runtime-flags.d.ts +2 -2
  92. package/sensor/dist/extraction/wasm-runtime-flags.d.ts.map +1 -1
  93. package/sensor/dist/extraction/wasm-runtime-flags.js +5 -5
  94. package/sensor/dist/extraction/wasm-runtime-flags.js.map +1 -1
  95. package/sensor/dist/index.d.ts +36 -36
  96. package/sensor/dist/index.d.ts.map +1 -1
  97. package/sensor/dist/index.js +71 -71
  98. package/sensor/dist/index.js.map +1 -1
  99. package/sensor/dist/mcp/daemon-manager.js +1 -1
  100. package/sensor/dist/mcp/daemon-paths.d.ts +3 -3
  101. package/sensor/dist/mcp/daemon-paths.js +7 -7
  102. package/sensor/dist/mcp/daemon-paths.js.map +1 -1
  103. package/sensor/dist/mcp/daemon-registry.d.ts +2 -2
  104. package/sensor/dist/mcp/daemon-registry.js +5 -5
  105. package/sensor/dist/mcp/daemon.d.ts +7 -7
  106. package/sensor/dist/mcp/daemon.d.ts.map +1 -1
  107. package/sensor/dist/mcp/daemon.js +21 -21
  108. package/sensor/dist/mcp/daemon.js.map +1 -1
  109. package/sensor/dist/mcp/dynamic-boundaries.js +1 -1
  110. package/sensor/dist/mcp/engine.d.ts +9 -9
  111. package/sensor/dist/mcp/engine.d.ts.map +1 -1
  112. package/sensor/dist/mcp/engine.js +44 -44
  113. package/sensor/dist/mcp/engine.js.map +1 -1
  114. package/sensor/dist/mcp/index.d.ts +14 -14
  115. package/sensor/dist/mcp/index.d.ts.map +1 -1
  116. package/sensor/dist/mcp/index.js +41 -41
  117. package/sensor/dist/mcp/index.js.map +1 -1
  118. package/sensor/dist/mcp/liveness-watchdog.js +7 -7
  119. package/sensor/dist/mcp/liveness-watchdog.js.map +1 -1
  120. package/sensor/dist/mcp/ppid-watchdog.d.ts +3 -3
  121. package/sensor/dist/mcp/ppid-watchdog.js +2 -2
  122. package/sensor/dist/mcp/proxy.d.ts.map +1 -1
  123. package/sensor/dist/mcp/proxy.js +37 -37
  124. package/sensor/dist/mcp/proxy.js.map +1 -1
  125. package/sensor/dist/mcp/query-pool.d.ts +3 -3
  126. package/sensor/dist/mcp/query-pool.js +7 -7
  127. package/sensor/dist/mcp/query-pool.js.map +1 -1
  128. package/sensor/dist/mcp/query-worker.d.ts +2 -2
  129. package/sensor/dist/mcp/query-worker.js +7 -7
  130. package/sensor/dist/mcp/query-worker.js.map +1 -1
  131. package/sensor/dist/mcp/server-instructions.d.ts +10 -12
  132. package/sensor/dist/mcp/server-instructions.d.ts.map +1 -1
  133. package/sensor/dist/mcp/server-instructions.js +39 -37
  134. package/sensor/dist/mcp/server-instructions.js.map +1 -1
  135. package/sensor/dist/mcp/session.d.ts +2 -2
  136. package/sensor/dist/mcp/session.js +18 -18
  137. package/sensor/dist/mcp/session.js.map +1 -1
  138. package/sensor/dist/mcp/startup-handshake.d.ts +3 -3
  139. package/sensor/dist/mcp/startup-handshake.d.ts.map +1 -1
  140. package/sensor/dist/mcp/startup-handshake.js +3 -3
  141. package/sensor/dist/mcp/startup-handshake.js.map +1 -1
  142. package/sensor/dist/mcp/tools.d.ts +53 -53
  143. package/sensor/dist/mcp/tools.d.ts.map +1 -1
  144. package/sensor/dist/mcp/tools.js +180 -216
  145. package/sensor/dist/mcp/tools.js.map +1 -1
  146. package/sensor/dist/mcp/transport.d.ts +1 -1
  147. package/sensor/dist/mcp/transport.js +6 -6
  148. package/sensor/dist/mcp/transport.js.map +1 -1
  149. package/sensor/dist/mcp/version.d.ts +2 -2
  150. package/sensor/dist/mcp/version.d.ts.map +1 -1
  151. package/sensor/dist/mcp/version.js +3 -3
  152. package/sensor/dist/mcp/version.js.map +1 -1
  153. package/sensor/dist/project-config.d.ts +6 -6
  154. package/sensor/dist/project-config.d.ts.map +1 -1
  155. package/sensor/dist/project-config.js +10 -10
  156. package/sensor/dist/project-config.js.map +1 -1
  157. package/sensor/dist/resolution/callback-synthesizer.js +4 -4
  158. package/sensor/dist/resolution/callback-synthesizer.js.map +1 -1
  159. package/sensor/dist/resolution/frameworks/drupal.d.ts +3 -3
  160. package/sensor/dist/resolution/frameworks/drupal.js +3 -3
  161. package/sensor/dist/resolution/frameworks/fabric.js +1 -1
  162. package/sensor/dist/resolution/frameworks/fabric.js.map +1 -1
  163. package/sensor/dist/resolution/frameworks/java.js +1 -1
  164. package/sensor/dist/resolution/frameworks/java.js.map +1 -1
  165. package/sensor/dist/resolution/frameworks/svelte.js +1 -1
  166. package/sensor/dist/resolution/frameworks/svelte.js.map +1 -1
  167. package/sensor/dist/resolution/goframe-synthesizer.d.ts +1 -1
  168. package/sensor/dist/resolution/goframe-synthesizer.js +1 -1
  169. package/sensor/dist/resolution/index.d.ts +1 -1
  170. package/sensor/dist/resolution/index.js +9 -9
  171. package/sensor/dist/resolution/index.js.map +1 -1
  172. package/sensor/dist/resolution/name-matcher.js +2 -2
  173. package/sensor/dist/resolution/name-matcher.js.map +1 -1
  174. package/sensor/dist/resolution/resolver-pool.d.ts +2 -2
  175. package/sensor/dist/resolution/resolver-pool.js +4 -4
  176. package/sensor/dist/resolution/resolver-pool.js.map +1 -1
  177. package/sensor/dist/resolution/resolver-worker.js +2 -2
  178. package/sensor/dist/resolution/resolver-worker.js.map +1 -1
  179. package/sensor/dist/resolution/workspace-packages.js +1 -1
  180. package/sensor/dist/resolution/workspace-packages.js.map +1 -1
  181. package/sensor/dist/search/identifier-segments.d.ts +1 -1
  182. package/sensor/dist/search/identifier-segments.js +1 -1
  183. package/sensor/dist/search/query-utils.d.ts +1 -0
  184. package/sensor/dist/search/query-utils.d.ts.map +1 -1
  185. package/sensor/dist/search/query-utils.js +10 -3
  186. package/sensor/dist/search/query-utils.js.map +1 -1
  187. package/sensor/dist/sync/git-hooks.d.ts +9 -9
  188. package/sensor/dist/sync/git-hooks.d.ts.map +1 -1
  189. package/sensor/dist/sync/git-hooks.js +15 -15
  190. package/sensor/dist/sync/git-hooks.js.map +1 -1
  191. package/sensor/dist/sync/watch-policy.d.ts +2 -2
  192. package/sensor/dist/sync/watch-policy.js +5 -5
  193. package/sensor/dist/sync/watch-policy.js.map +1 -1
  194. package/sensor/dist/sync/watcher.d.ts +2 -2
  195. package/sensor/dist/sync/watcher.d.ts.map +1 -1
  196. package/sensor/dist/sync/watcher.js +16 -16
  197. package/sensor/dist/sync/watcher.js.map +1 -1
  198. package/sensor/dist/sync/worktree.d.ts +5 -5
  199. package/sensor/dist/sync/worktree.d.ts.map +1 -1
  200. package/sensor/dist/sync/worktree.js +9 -9
  201. package/sensor/dist/sync/worktree.js.map +1 -1
  202. package/sensor/dist/telemetry/index.d.ts +8 -8
  203. package/sensor/dist/telemetry/index.d.ts.map +1 -1
  204. package/sensor/dist/telemetry/index.js +16 -16
  205. package/sensor/dist/telemetry/index.js.map +1 -1
  206. package/sensor/dist/types.d.ts +2 -2
  207. package/sensor/dist/types.js +1 -1
  208. package/sensor/dist/ui/color.d.ts +2 -2
  209. package/sensor/dist/ui/color.js +2 -2
  210. package/sensor/dist/ui/glyphs.d.ts +3 -3
  211. package/sensor/dist/ui/glyphs.js +7 -7
  212. package/sensor/dist/ui/glyphs.js.map +1 -1
  213. package/sensor/dist/utils.d.ts +4 -4
  214. package/sensor/dist/utils.js +8 -8
  215. package/sensor/dist/utils.js.map +1 -1
  216. package/sensor/package.json +8 -13
  217. package/src/artifact-contracts.mjs +2 -2
  218. package/src/boundary-compiler.mjs +28 -28
  219. package/src/boundary-observation-compiler-v2.mjs +10 -10
  220. package/src/bounded-seam.mjs +144 -0
  221. package/src/bridge-cli.mjs +227 -0
  222. package/src/bridge-config.mjs +346 -0
  223. package/src/bridge-daemon.mjs +328 -0
  224. package/src/bridge-launch-agent.mjs +311 -0
  225. package/src/bridge-server.mjs +309 -0
  226. package/src/cli-help.mjs +163 -0
  227. package/src/control-compiler.mjs +30 -30
  228. package/src/dag-chain.mjs +261 -0
  229. package/src/factory-diagnostics.mjs +8 -7
  230. package/src/hash-chain.mjs +76 -0
  231. package/src/node-version-guard.mjs +5 -4
  232. package/src/project-cli.mjs +392 -0
  233. package/src/project-identity.mjs +71 -0
  234. package/src/rc1-evidence-bundle.mjs +16 -16
  235. package/src/rc1-v4-campaign.mjs +15 -14
  236. package/src/rc1-v5-artifact-set.mjs +2 -2
  237. package/src/rc1-v5-campaign.mjs +15 -14
  238. package/src/rc1-v6-artifact-set.mjs +18 -18
  239. package/src/rc1-v6-campaign.mjs +16 -16
  240. package/src/rc1-v6-causal-binding.mjs +16 -14
  241. package/src/rc1-v6-measurement.mjs +20 -38
  242. package/src/rc2-artifact-set.mjs +45 -40
  243. package/src/rc2-campaign.mjs +48 -66
  244. package/src/rc2-delivery-policy-front-end.mjs +30 -30
  245. package/src/rc2-rc1-transfer-front-end.mjs +5 -5
  246. package/src/rc3-actual-dogfood.mjs +6 -6
  247. package/src/rc3-dogfood-scaffold.mjs +12 -7
  248. package/src/rc3-scripted-campaign.mjs +75 -21
  249. package/src/rc4-stage1-dogfood.mjs +24 -7
  250. package/src/runtime-cli.mjs +2424 -45
  251. package/src/runtime-contracts.mjs +7 -7
  252. package/src/runtime-control-store.mjs +547 -0
  253. package/src/runtime-controller-protocol.mjs +517 -0
  254. package/src/runtime-direct-os-observer.mjs +284 -0
  255. package/src/runtime-engine.mjs +2 -2
  256. package/src/runtime-errors.mjs +1 -1
  257. package/src/runtime-event-store.mjs +15 -43
  258. package/src/runtime-front-end.mjs +26 -26
  259. package/src/runtime-gate-store.mjs +477 -0
  260. package/src/runtime-hold-recompile.mjs +214 -23
  261. package/src/runtime-lifecycle-lock.mjs +290 -0
  262. package/src/runtime-managed-supervisor.mjs +1276 -0
  263. package/src/runtime-multi-epoch-store.mjs +761 -0
  264. package/src/runtime-projection.mjs +62 -0
  265. package/src/seam-transform.mjs +38 -38
  266. package/src/{codegraph-adapter.mjs → sensor-adapter.mjs} +7 -7
  267. package/src/sensor-cli.mjs +107 -0
  268. package/src/sensor-runtime.mjs +48 -0
  269. package/src/timestamp-contract.mjs +8 -0
  270. package/src/todo-chain.mjs +178 -0
  271. package/src/todo-cli.mjs +1032 -0
  272. package/src/todo-contracts.mjs +501 -0
  273. package/src/todo-dashboard-registry.mjs +318 -0
  274. package/src/todo-gantt-html.mjs +416 -0
  275. package/src/todo-gantt-layout.mjs +603 -0
  276. package/src/todo-gantt-live.mjs +269 -0
  277. package/src/todo-gantt-presentation.mjs +217 -0
  278. package/src/todo-gantt-svg.mjs +249 -0
  279. package/src/todo-markdown-renderer.mjs +260 -0
  280. package/src/todo-migration.mjs +260 -0
  281. package/src/todo-narrative-anchor.mjs +130 -0
  282. package/src/todo-revision.mjs +425 -0
  283. package/src/todo-status.mjs +340 -0
  284. package/src/todo-store.mjs +3451 -0
  285. package/src/treatment-compiler.mjs +28 -28
  286. package/src/treatment-runner.mjs +42 -44
  287. package/sensor/dist/bin/codegraph.d.ts +0 -26
  288. package/sensor/dist/bin/codegraph.d.ts.map +0 -1
  289. package/sensor/dist/bin/codegraph.js.map +0 -1
  290. package/sensor/dist/bin/uninstall.d.ts +0 -14
  291. package/sensor/dist/bin/uninstall.d.ts.map +0 -1
  292. package/sensor/dist/bin/uninstall.js +0 -36
  293. package/sensor/dist/bin/uninstall.js.map +0 -1
  294. package/sensor/dist/installer/beta-signup.d.ts +0 -54
  295. package/sensor/dist/installer/beta-signup.d.ts.map +0 -1
  296. package/sensor/dist/installer/beta-signup.js +0 -178
  297. package/sensor/dist/installer/beta-signup.js.map +0 -1
  298. package/sensor/dist/installer/config-writer.d.ts +0 -28
  299. package/sensor/dist/installer/config-writer.d.ts.map +0 -1
  300. package/sensor/dist/installer/config-writer.js +0 -91
  301. package/sensor/dist/installer/config-writer.js.map +0 -1
  302. package/sensor/dist/installer/index.d.ts +0 -142
  303. package/sensor/dist/installer/index.d.ts.map +0 -1
  304. package/sensor/dist/installer/index.js +0 -622
  305. package/sensor/dist/installer/index.js.map +0 -1
  306. package/sensor/dist/installer/instructions-template.d.ts +0 -41
  307. package/sensor/dist/installer/instructions-template.d.ts.map +0 -1
  308. package/sensor/dist/installer/instructions-template.js +0 -53
  309. package/sensor/dist/installer/instructions-template.js.map +0 -1
  310. package/sensor/dist/installer/targets/antigravity.d.ts +0 -57
  311. package/sensor/dist/installer/targets/antigravity.d.ts.map +0 -1
  312. package/sensor/dist/installer/targets/antigravity.js +0 -308
  313. package/sensor/dist/installer/targets/antigravity.js.map +0 -1
  314. package/sensor/dist/installer/targets/claude.d.ts +0 -62
  315. package/sensor/dist/installer/targets/claude.d.ts.map +0 -1
  316. package/sensor/dist/installer/targets/claude.js +0 -454
  317. package/sensor/dist/installer/targets/claude.js.map +0 -1
  318. package/sensor/dist/installer/targets/codex.d.ts +0 -18
  319. package/sensor/dist/installer/targets/codex.d.ts.map +0 -1
  320. package/sensor/dist/installer/targets/codex.js +0 -185
  321. package/sensor/dist/installer/targets/codex.js.map +0 -1
  322. package/sensor/dist/installer/targets/cursor.d.ts +0 -35
  323. package/sensor/dist/installer/targets/cursor.d.ts.map +0 -1
  324. package/sensor/dist/installer/targets/cursor.js +0 -254
  325. package/sensor/dist/installer/targets/cursor.js.map +0 -1
  326. package/sensor/dist/installer/targets/gemini.d.ts +0 -26
  327. package/sensor/dist/installer/targets/gemini.d.ts.map +0 -1
  328. package/sensor/dist/installer/targets/gemini.js +0 -165
  329. package/sensor/dist/installer/targets/gemini.js.map +0 -1
  330. package/sensor/dist/installer/targets/hermes.d.ts +0 -18
  331. package/sensor/dist/installer/targets/hermes.d.ts.map +0 -1
  332. package/sensor/dist/installer/targets/hermes.js +0 -359
  333. package/sensor/dist/installer/targets/hermes.js.map +0 -1
  334. package/sensor/dist/installer/targets/kiro.d.ts +0 -27
  335. package/sensor/dist/installer/targets/kiro.d.ts.map +0 -1
  336. package/sensor/dist/installer/targets/kiro.js +0 -178
  337. package/sensor/dist/installer/targets/kiro.js.map +0 -1
  338. package/sensor/dist/installer/targets/opencode.d.ts +0 -38
  339. package/sensor/dist/installer/targets/opencode.d.ts.map +0 -1
  340. package/sensor/dist/installer/targets/opencode.js +0 -288
  341. package/sensor/dist/installer/targets/opencode.js.map +0 -1
  342. package/sensor/dist/installer/targets/registry.d.ts +0 -35
  343. package/sensor/dist/installer/targets/registry.d.ts.map +0 -1
  344. package/sensor/dist/installer/targets/registry.js +0 -91
  345. package/sensor/dist/installer/targets/registry.js.map +0 -1
  346. package/sensor/dist/installer/targets/shared.d.ts +0 -101
  347. package/sensor/dist/installer/targets/shared.d.ts.map +0 -1
  348. package/sensor/dist/installer/targets/shared.js +0 -264
  349. package/sensor/dist/installer/targets/shared.js.map +0 -1
  350. package/sensor/dist/installer/targets/toml.d.ts +0 -52
  351. package/sensor/dist/installer/targets/toml.d.ts.map +0 -1
  352. package/sensor/dist/installer/targets/toml.js +0 -147
  353. package/sensor/dist/installer/targets/toml.js.map +0 -1
  354. package/sensor/dist/installer/targets/types.d.ts +0 -108
  355. package/sensor/dist/installer/targets/types.d.ts.map +0 -1
  356. package/sensor/dist/installer/targets/types.js +0 -16
  357. package/sensor/dist/installer/targets/types.js.map +0 -1
  358. package/sensor/dist/upgrade/index.d.ts +0 -171
  359. package/sensor/dist/upgrade/index.d.ts.map +0 -1
  360. package/sensor/dist/upgrade/index.js +0 -659
  361. package/sensor/dist/upgrade/index.js.map +0 -1
  362. package/sensor/dist/upgrade/remove-binary.d.ts +0 -87
  363. package/sensor/dist/upgrade/remove-binary.d.ts.map +0 -1
  364. package/sensor/dist/upgrade/remove-binary.js +0 -289
  365. package/sensor/dist/upgrade/remove-binary.js.map +0 -1
  366. package/sensor/dist/upgrade/update-check.d.ts +0 -92
  367. package/sensor/dist/upgrade/update-check.d.ts.map +0 -1
  368. package/sensor/dist/upgrade/update-check.js +0 -258
  369. package/sensor/dist/upgrade/update-check.js.map +0 -1
  370. package/src/bootstrap.mjs +0 -88
@@ -2,7 +2,7 @@
2
2
  /**
3
3
  * MCP Tool Definitions
4
4
  *
5
- * Defines the tools exposed by the CodeGraph MCP server.
5
+ * Defines the tools exposed by the LatticeSensor MCP server.
6
6
  */
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
8
  exports.ToolHandler = exports.tools = exports.IndexOpenError = exports.PathRefusalError = exports.NotIndexedError = void 0;
@@ -15,12 +15,12 @@ exports.formatDegradedBanner = formatDegradedBanner;
15
15
  exports.getStaticTools = getStaticTools;
16
16
  const directory_1 = require("../directory");
17
17
  const version_1 = require("./version");
18
- // Lazy-load the heavy CodeGraph chain off the MCP startup path — see the same
18
+ // Lazy-load the heavy LatticeSensor chain off the MCP startup path — see the same
19
19
  // helper in engine.ts. ToolHandler must load to answer tools/list (static
20
20
  // schemas), but it must NOT drag in sqlite/query layers before the daemon binds;
21
- // CodeGraph is pulled in only when a tool actually opens a project. require() is
21
+ // LatticeSensor is pulled in only when a tool actually opens a project. require() is
22
22
  // sync + cached (CommonJS build).
23
- const loadCodeGraph = () => require('../index').default;
23
+ const loadLatticeSensor = () => require('../index').default;
24
24
  const worktree_1 = require("../sync/worktree");
25
25
  const query_utils_1 = require("../search/query-utils");
26
26
  const fs_1 = require("fs");
@@ -28,11 +28,11 @@ const utils_1 = require("../utils");
28
28
  const generated_detection_1 = require("../extraction/generated-detection");
29
29
  const dynamic_boundaries_1 = require("./dynamic-boundaries");
30
30
  /**
31
- * An expected, recoverable "codegraph can't serve this" condition — most
31
+ * An expected, recoverable "lattice sensor can't serve this" condition — most
32
32
  * importantly a project with no index. The dispatch catch converts these to
33
33
  * SUCCESS-shaped responses (guidance text, NO isError): an `isError: true`
34
34
  * early in a session teaches the agent the toolset is broken and it stops
35
- * calling codegraph entirely (observed repeatedly), which is exactly wrong
35
+ * calling lattice sensor entirely (observed repeatedly), which is exactly wrong
36
36
  * for conditions the agent can simply work around (use built-in tools for
37
37
  * that codebase / pass projectPath). isError is reserved for "stop trying"
38
38
  * cases: security refusals ({@link PathRefusalError}) and genuine
@@ -51,13 +51,13 @@ exports.PathRefusalError = PathRefusalError;
51
51
  /**
52
52
  * ADR 0049 Decision 5②: a genuine malfunction opening the default project's
53
53
  * index — DB open failure, schema mismatch, integrity error, or lock
54
- * contention — as OPPOSED to the project simply having no `.codegraph/` at
54
+ * contention — as OPPOSED to the project simply having no `.lattice/sensor/` at
55
55
  * all (that stays {@link NotIndexedError}, the success-shaped guidance case).
56
56
  * This is fail-closed by design: it stays `isError: true` (via `execute`'s
57
57
  * catch, same as {@link PathRefusalError}) rather than the NotIndexedError
58
58
  * success-shaped guidance, because silently degrading to "no default
59
59
  * project" here would hide a broken index behind text that reads as "just
60
- * run `codegraph init`" — actively misleading for a project that WAS
60
+ * run `lattice sensor init . --json`" — actively misleading for a project that WAS
61
61
  * indexed and IS now broken.
62
62
  */
63
63
  class IndexOpenError extends Error {
@@ -89,7 +89,7 @@ const MAX_PATH_LENGTH = 4_096;
89
89
  */
90
90
  const RUST_PATH_PREFIXES = new Set(['crate', 'super', 'self']);
91
91
  /**
92
- * Node kinds that contain other symbols. For these, `codegraph_node` with
92
+ * Node kinds that contain other symbols. For these, `lattice_sensor_node` with
93
93
  * `includeCode=true` returns a structural outline (member names + signatures
94
94
  * + line numbers) instead of the full body, which for a large class is a
95
95
  * multi-thousand-character wall of source that bloats the agent's context.
@@ -129,7 +129,7 @@ function normalizeQuerySpelling(query) {
129
129
  .replace(/(^|[\s,()[\]])(?!(?:kind|lang|language|path|name):)([a-z_][\w@]*):([A-Za-z_][\w@]*)(?=$|[\s,()[\]])/g, '$1$2.$3');
130
130
  }
131
131
  /**
132
- * Calculate the recommended number of codegraph_explore calls based on project size.
132
+ * Calculate the recommended number of lattice_sensor_explore calls based on project size.
133
133
  * Larger codebases need more exploration calls to cover their surface area,
134
134
  * but smaller ones should use fewer to avoid unnecessary overhead.
135
135
  */
@@ -244,21 +244,21 @@ function getExploreOutputBudget(fileCount) {
244
244
  };
245
245
  }
246
246
  /**
247
- * Whether `codegraph_explore` should prefix source lines with their line
247
+ * Whether `lattice_sensor_explore` should prefix source lines with their line
248
248
  * numbers (cat -n style: `<num>\t<code>`).
249
249
  *
250
250
  * Line numbers let the agent cite `file:line` straight from the explore
251
251
  * payload instead of re-Reading the file just to find a line number — the
252
252
  * dominant residual cost on precise-tracing questions (#185 follow-up).
253
253
  *
254
- * Defaults ON. Set `CODEGRAPH_EXPLORE_LINENUMS=0` to disable (used by the
254
+ * Defaults ON. Set `LATTICE_SENSOR_EXPLORE_LINENUMS=0` to disable (used by the
255
255
  * A/B harness to measure the payload-cost vs. read-savings tradeoff).
256
256
  */
257
257
  function exploreLineNumbersEnabled() {
258
- return process.env.CODEGRAPH_EXPLORE_LINENUMS !== '0';
258
+ return process.env.LATTICE_SENSOR_EXPLORE_LINENUMS !== '0';
259
259
  }
260
260
  /**
261
- * Adaptive explore sizing (default ON). `codegraph_explore` skeletonizes OFF-SPINE
261
+ * Adaptive explore sizing (default ON). `lattice_sensor_explore` skeletonizes OFF-SPINE
262
262
  * polymorphic-sibling files — a file whose class is one of ≥3 interchangeable
263
263
  * implementations of a shared interface (e.g. OkHttp's `: Interceptor` classes) —
264
264
  * to class + member signatures (bodies elided), keeping the on-spine exemplar full.
@@ -267,10 +267,10 @@ function exploreLineNumbersEnabled() {
267
267
  * search, reads flat). It is PROVABLY INERT elsewhere: distinct pipeline steps (no
268
268
  * ≥3-implementer supertype, e.g. Excalidraw's `renderStaticScene`) and on-spine
269
269
  * files keep full source — output is byte-identical to shipped on excalidraw /
270
- * tokio / django / vscode / gin. Set `CODEGRAPH_ADAPTIVE_EXPLORE=0` to disable.
270
+ * tokio / django / vscode / gin. Set `LATTICE_SENSOR_ADAPTIVE_EXPLORE=0` to disable.
271
271
  */
272
272
  function adaptiveExploreEnabled() {
273
- return process.env.CODEGRAPH_ADAPTIVE_EXPLORE !== '0' && process.env.CODEGRAPH_ADAPTIVE_EXPLORE !== 'false';
273
+ return process.env.LATTICE_SENSOR_ADAPTIVE_EXPLORE !== '0' && process.env.LATTICE_SENSOR_ADAPTIVE_EXPLORE !== 'false';
274
274
  }
275
275
  /**
276
276
  * How long the FIRST tool call waits on the post-open catch-up reconcile before
@@ -281,12 +281,12 @@ function adaptiveExploreEnabled() {
281
281
  * for a clean answer, then serve and let the reconcile finish in the background
282
282
  * (it yields to the event loop, so a concurrent read still runs).
283
283
  *
284
- * `CODEGRAPH_CATCHUP_GATE_TIMEOUT_MS` overrides the default; `0` restores the
284
+ * `LATTICE_SENSOR_CATCHUP_GATE_TIMEOUT_MS` overrides the default; `0` restores the
285
285
  * old unbounded-wait behavior (always block until the reconcile completes).
286
286
  */
287
287
  const DEFAULT_CATCHUP_GATE_TIMEOUT_MS = 3000;
288
288
  function resolveCatchUpGateTimeoutMs() {
289
- const raw = process.env.CODEGRAPH_CATCHUP_GATE_TIMEOUT_MS;
289
+ const raw = process.env.LATTICE_SENSOR_CATCHUP_GATE_TIMEOUT_MS;
290
290
  if (raw === undefined || raw === '')
291
291
  return DEFAULT_CATCHUP_GATE_TIMEOUT_MS;
292
292
  const n = Number(raw);
@@ -311,7 +311,7 @@ function numberSourceLines(slice, firstLineNumber) {
311
311
  return out.join('\n');
312
312
  }
313
313
  /**
314
- * Unique line-prefix for a per-file source section in codegraph_explore output.
314
+ * Unique line-prefix for a per-file source section in lattice_sensor_explore output.
315
315
  * Issue #778: tool results dropped ATX headings (`####`, `##`, `###`) for bold
316
316
  * labels so Markdown-rendering MCP clients (e.g. the Claude Code VSCode
317
317
  * extension) stop blowing every header up to H1–H4. The path is bold + a code
@@ -320,12 +320,12 @@ function numberSourceLines(slice, firstLineNumber) {
320
320
  * truncation boundary (`handleExplore`) keys off to cut on whole file sections.
321
321
  */
322
322
  const FILE_SECTION_PREFIX = '**`';
323
- // Placeholder for codegraph_explore's "Found N symbols across M files." line.
323
+ // Placeholder for lattice_sensor_explore's "Found N symbols across M files." line.
324
324
  // The honest N/M can only be known after the final truncation drops trailing
325
325
  // sections (#1046), so the header is emitted as this sentinel and substituted
326
326
  // at the very end. This bracketed token never occurs in rendered source or a
327
327
  // file path, so the final string-replace can't collide.
328
- const SUMMARY_SENTINEL = '[[codegraph-explore-summary]]';
328
+ const SUMMARY_SENTINEL = '[[lattice sensor-explore-summary]]';
329
329
  function fileSectionHeader(filePath, suffix) {
330
330
  return suffix
331
331
  ? `${FILE_SECTION_PREFIX}${filePath}\`** — ${suffix}`
@@ -345,7 +345,7 @@ function formatStaleBanner(stale) {
345
345
  return ` - ${p.path} (edited ${ageMs}ms ago, ${label})`;
346
346
  });
347
347
  return ('⚠️ Some files referenced below were edited since the last index sync — ' +
348
- 'their codegraph entries may be stale:\n' +
348
+ 'their lattice sensor entries may be stale:\n' +
349
349
  lines.join('\n') +
350
350
  '\nFor accurate content of those specific files, Read them directly. ' +
351
351
  'The rest of this response is fresh.');
@@ -373,10 +373,10 @@ function formatStaleFooter(stale) {
373
373
  * `getPendingFiles()` is empty, so the per-file banner above can't fire even
374
374
  * though the index is now FROZEN and silently drifting stale. Leads with the
375
375
  * agent-actionable instruction (Read directly) and carries the reason, which
376
- * already names the operator remedy (`codegraph sync` / git hooks).
376
+ * already names the operator remedy (`lattice sensor sync . --json` / git hooks).
377
377
  */
378
378
  function formatDegradedBanner(reason) {
379
- return ('⚠️ CodeGraph auto-sync is DISABLED — live file watching stopped, so the index is ' +
379
+ return ('⚠️ LatticeSensor auto-sync is DISABLED — live file watching stopped, so the index is ' +
380
380
  'frozen and any file edited since then is stale here. Read files directly to confirm ' +
381
381
  'current content before relying on it.' +
382
382
  (reason ? `\n Reason: ${reason}` : ''));
@@ -386,10 +386,10 @@ function formatDegradedBanner(reason) {
386
386
  */
387
387
  const projectPathProperty = {
388
388
  type: 'string',
389
- description: 'Absolute path to the project to query (or any directory inside it) — codegraph uses the nearest .codegraph/ index at or above that path. Omit to use this session\'s default project. Pass it to query a second codebase, or when the server root has no index of its own (e.g. a monorepo where only sub-projects are indexed, so there is no default project).',
389
+ description: 'Absolute path to the project to query (or any directory inside it) — lattice sensor uses the nearest .lattice/sensor/ index at or above that path. Omit to use this session\'s default project. Pass it to query a second codebase, or when the server root has no index of its own (e.g. a monorepo where only sub-projects are indexed, so there is no default project).',
390
390
  };
391
391
  /**
392
- * EVERY codegraph tool is query-only: it reads the pre-built index and never
392
+ * EVERY lattice sensor tool is query-only: it reads the pre-built index and never
393
393
  * mutates the workspace (indexing is the user's explicit CLI call, never the
394
394
  * agent's). Advertising this read-only contract lets clients that gate on it run
395
395
  * the tools where a possibly-mutating tool would be blocked — most concretely,
@@ -406,9 +406,9 @@ const READ_ONLY_ANNOTATIONS = {
406
406
  openWorldHint: false,
407
407
  };
408
408
  /**
409
- * All CodeGraph MCP tools
409
+ * All LatticeSensor MCP tools
410
410
  *
411
- * Designed for minimal context usage - use codegraph_explore as the primary tool
411
+ * Designed for minimal context usage - use lattice_sensor_explore as the primary tool
412
412
  * (one call usually answers the whole question), and only use other tools for
413
413
  * targeted follow-up queries.
414
414
  *
@@ -416,8 +416,8 @@ const READ_ONLY_ANNOTATIONS = {
416
416
  */
417
417
  exports.tools = [
418
418
  {
419
- name: 'codegraph_search',
420
- description: 'Quick symbol search by name. Returns locations only (no code). Use codegraph_explore instead to get the actual source / understand an area in one call.',
419
+ name: 'lattice_sensor_search',
420
+ description: 'Quick symbol search by name. Returns locations only (no code). Use lattice_sensor_explore instead to get the actual source / understand an area in one call.',
421
421
  inputSchema: {
422
422
  type: 'object',
423
423
  properties: {
@@ -442,8 +442,8 @@ exports.tools = [
442
442
  annotations: READ_ONLY_ANNOTATIONS,
443
443
  },
444
444
  {
445
- name: 'codegraph_callers',
446
- description: 'List functions that call <symbol>. For the full flow, use codegraph_explore.',
445
+ name: 'lattice_sensor_callers',
446
+ description: 'List functions that call <symbol>. For the full flow, use lattice_sensor_explore.',
447
447
  inputSchema: {
448
448
  type: 'object',
449
449
  properties: {
@@ -467,8 +467,8 @@ exports.tools = [
467
467
  annotations: READ_ONLY_ANNOTATIONS,
468
468
  },
469
469
  {
470
- name: 'codegraph_callees',
471
- description: 'List functions that <symbol> calls. For the full flow, use codegraph_explore.',
470
+ name: 'lattice_sensor_callees',
471
+ description: 'List functions that <symbol> calls. For the full flow, use lattice_sensor_explore.',
472
472
  inputSchema: {
473
473
  type: 'object',
474
474
  properties: {
@@ -492,7 +492,7 @@ exports.tools = [
492
492
  annotations: READ_ONLY_ANNOTATIONS,
493
493
  },
494
494
  {
495
- name: 'codegraph_impact',
495
+ name: 'lattice_sensor_impact',
496
496
  description: 'List symbols affected by changing <symbol>. Use before a refactor.',
497
497
  inputSchema: {
498
498
  type: 'object',
@@ -517,8 +517,8 @@ exports.tools = [
517
517
  annotations: READ_ONLY_ANNOTATIONS,
518
518
  },
519
519
  {
520
- name: 'codegraph_node',
521
- description: 'Two modes. (1) READ A FILE — use INSTEAD of the Read tool: pass `file` (a path or basename) with no `symbol` and it returns that file\'s current on-disk source with line numbers, exactly the shape Read gives you (`<n>\\t<line>`, safe to Edit from), narrowable with `offset`/`limit` just like Read — PLUS a one-line note of which files depend on it. Same bytes as Read, faster (served from the index), with the blast radius attached. Use it whenever you would Read a source file. (2) ONE SYMBOL you can name — its location, signature, verbatim source (includeCode=true) and caller/callee trail in one call, so before changing it you see what calls it and what your edit would break. For an AMBIGUOUS name it returns EVERY matching definition\'s body in one call (so you never Read a file to find the right overload); pass `file`/`line` to pin one. Use codegraph_explore for several related symbols or the full flow.',
520
+ name: 'lattice_sensor_node',
521
+ description: 'Two modes. (1) READ A FILE — use INSTEAD of the Read tool: pass `file` (a path or basename) with no `symbol` and it returns that file\'s current on-disk source with line numbers, exactly the shape Read gives you (`<n>\\t<line>`, safe to Edit from), narrowable with `offset`/`limit` just like Read — PLUS a one-line note of which files depend on it. Same bytes as Read, faster (served from the index), with the blast radius attached. Use it whenever you would Read a source file. (2) ONE SYMBOL you can name — its location, signature, verbatim source (includeCode=true) and caller/callee trail in one call, so before changing it you see what calls it and what your edit would break. For an AMBIGUOUS name it returns EVERY matching definition\'s body in one call (so you never Read a file to find the right overload); pass `file`/`line` to pin one. Use lattice_sensor_explore for several related symbols or the full flow.',
522
522
  inputSchema: {
523
523
  type: 'object',
524
524
  properties: {
@@ -559,14 +559,14 @@ exports.tools = [
559
559
  annotations: READ_ONLY_ANNOTATIONS,
560
560
  },
561
561
  {
562
- name: 'codegraph_explore',
562
+ name: 'lattice_sensor_explore',
563
563
  description: 'PRIMARY TOOL — call FIRST for almost any question OR before an edit: how does X work, architecture, a bug, where/what is X, surveying an area, or the symbols you are about to change. Returns the verbatim source of the relevant symbols grouped by file in ONE capped call (Read-equivalent — treat the shown source as already Read; do NOT re-open those files), plus the call path among them. Query can be a natural-language question OR a bag of symbol/file names. Usually the ONLY call you need — more accurate context, in far fewer tokens and round-trips than a search/Read/Grep loop.',
564
564
  inputSchema: {
565
565
  type: 'object',
566
566
  properties: {
567
567
  query: {
568
568
  type: 'string',
569
- description: 'Symbol names, file names, or short code terms to explore (e.g., "AuthService loginUser session-manager", "GraphTraverser BFS impact traversal.ts"). For a flow question, name the symbols spanning the flow (e.g. "mutateElement renderScene"). A natural-language question works too — no prior codegraph_search needed.',
569
+ description: 'Symbol names, file names, or short code terms to explore (e.g., "AuthService loginUser session-manager", "GraphTraverser BFS impact traversal.ts"). For a flow question, name the symbols spanning the flow (e.g. "mutateElement renderScene"). A natural-language question works too — no prior lattice_sensor_search needed.',
570
570
  },
571
571
  maxFiles: {
572
572
  type: 'number',
@@ -580,7 +580,7 @@ exports.tools = [
580
580
  annotations: READ_ONLY_ANNOTATIONS,
581
581
  },
582
582
  {
583
- name: 'codegraph_status',
583
+ name: 'lattice_sensor_status',
584
584
  description: 'Index health check (files / nodes / edges) AND the version/execution-mode declaration surface: reports the running Lattice sensor version, the index schema stats, and a machine-readable `mode: daemon|direct` + `reason` field describing how this session is served (see ADR 0049). Skip unless debugging.',
585
585
  inputSchema: {
586
586
  type: 'object',
@@ -591,7 +591,7 @@ exports.tools = [
591
591
  annotations: READ_ONLY_ANNOTATIONS,
592
592
  },
593
593
  {
594
- name: 'codegraph_files',
594
+ name: 'lattice_sensor_files',
595
595
  description: 'Indexed file tree with language + symbol counts. Faster than Glob for project layout.',
596
596
  inputSchema: {
597
597
  type: 'object',
@@ -630,7 +630,7 @@ exports.tools = [
630
630
  *
631
631
  * Used for the NO-DEFAULT-PROJECT tool surface (issue #993): when the MCP server
632
632
  * has no default project to fall back to — a gateway server started outside any
633
- * repo, or a monorepo root whose `.codegraph/` indexes live only in sub-projects
633
+ * repo, or a monorepo root whose `.lattice/sensor/` indexes live only in sub-projects
634
634
  * — every call MUST carry an explicit `projectPath`, so the schema should say so.
635
635
  * A `required` field is a HIGH-salience channel (MCP clients surface and often
636
636
  * validate it), unlike the instructions text the reporter found too weak to stop
@@ -659,45 +659,41 @@ function withRequiredProjectPath(defs) {
659
659
  /**
660
660
  * Allowlist-filtered tool definitions WITHOUT an engine — the static surface the
661
661
  * proxy answers `tools/list` with before any project is open. Mirrors
662
- * `ToolHandler.getTools()` in the no-CodeGraph case (the dynamic per-repo budget
662
+ * `ToolHandler.getTools()` in the no-LatticeSensor case (the dynamic per-repo budget
663
663
  * note in a description only adds once `cg` is loaded; the schemas are static).
664
664
  */
665
665
  function getStaticTools() {
666
- const raw = process.env.CODEGRAPH_MCP_TOOLS;
666
+ const raw = process.env.LATTICE_SENSOR_MCP_TOOLS;
667
667
  if (!raw || !raw.trim()) {
668
- return exports.tools.filter(t => DEFAULT_MCP_TOOLS.has(t.name.replace(/^codegraph_/, '')));
668
+ return exports.tools.filter(t => DEFAULT_MCP_TOOLS.has(t.name.replace(/^lattice_sensor_/, '')));
669
669
  }
670
- const allow = new Set(raw.split(',').map(s => s.trim().replace(/^codegraph_/, '')).filter(Boolean));
671
- return allow.size ? exports.tools.filter(t => allow.has(t.name.replace(/^codegraph_/, ''))) : exports.tools;
670
+ const allow = new Set(raw.split(',').map(s => s.trim().replace(/^lattice_sensor_/, '')).filter(Boolean));
671
+ return allow.size ? exports.tools.filter(t => allow.has(t.name.replace(/^lattice_sensor_/, ''))) : exports.tools;
672
672
  }
673
673
  /**
674
- * The MCP tools served by DEFAULT (short names). Pared to ONLY `codegraph_explore`
675
- * the single tool that reliably earns its place: one capped call returns the
676
- * verbatim source of the relevant symbols grouped by file. Every other tool is a
677
- * narrower slice of what explore already does, and presence itself steers
678
- * mis-picks, so they are no longer LISTED to agents.
679
- *
680
- * The other defined tools (`node`, `search`, `callers`, plus callees/impact/files/
681
- * status) remain fully functional — handlers stay, the library API and CLI are
682
- * untouched, and `CODEGRAPH_MCP_TOOLS=explore,node,...` re-enables any of them.
674
+ * ADR 0049 / 0059: Lattice MCP v1 publishes exactly these eight compatibility
675
+ * tool names. The provider is Lattice; narrowing the default based on repo size
676
+ * would silently remove contracted surfaces and make host acceptance ambiguous.
683
677
  */
684
- const DEFAULT_MCP_TOOLS = new Set(['explore']);
678
+ const DEFAULT_MCP_TOOLS = new Set([
679
+ 'search', 'callers', 'callees', 'impact', 'node', 'explore', 'status', 'files',
680
+ ]);
685
681
  /**
686
- * Tool handler that executes tools against a CodeGraph instance
682
+ * Tool handler that executes tools against a LatticeSensor instance
687
683
  *
688
684
  * Supports cross-project queries via the projectPath parameter.
689
685
  * Other projects are opened on-demand and cached for performance.
690
686
  */
691
687
  class ToolHandler {
692
688
  cg;
693
- // Cache of opened CodeGraph instances for cross-project queries
689
+ // Cache of opened LatticeSensor instances for cross-project queries
694
690
  projectCache = new Map();
695
691
  // The directory the server last searched for a default project. Surfaced in
696
692
  // the "not initialized" error so users can see why detection missed.
697
693
  defaultProjectHint = null;
698
694
  // Per-start-path cache of the git worktree/index mismatch (issue #155). The
699
695
  // mismatch is a fixed property of (where the request came from → which
700
- // .codegraph/ it resolves to), so the up-to-two `git rev-parse` spawns run
696
+ // .lattice/sensor/ it resolves to), so the up-to-two `git rev-parse` spawns run
701
697
  // once and every later tool call reuses the result — never shelling out to
702
698
  // git on the hot path. `undefined` = not computed yet; `null` = no mismatch.
703
699
  worktreeMismatchCache = new Map();
@@ -719,12 +715,12 @@ class ToolHandler {
719
715
  // ADR 0049 Decision 5②: the reason the DEFAULT project's index failed to
720
716
  // open (DB open failure, schema mismatch, integrity error, lock
721
717
  // contention) — set by the engine's init path, distinct from "no
722
- // .codegraph/ found" (which leaves this null and falls through to
718
+ // .lattice/sensor/ found" (which leaves this null and falls through to
723
719
  // NotIndexedError's success-shaped guidance). Cleared on a successful
724
- // {@link setDefaultCodeGraph}.
720
+ // {@link setDefaultLatticeSensor}.
725
721
  openFailure = null;
726
722
  // ADR 0049 Decision 5④: this session's execution mode, reported by
727
- // codegraph_status as a machine-readable field. Defaults to a direct/
723
+ // lattice_sensor_status as a machine-readable field. Defaults to a direct/
728
724
  // no-daemon placeholder — every real caller (MCPServer.startDirect, the
729
725
  // shared Daemon, the local-handshake proxy's fallback engine) calls
730
726
  // {@link setExecutionMode} before any tool call can reach a live engine.
@@ -742,20 +738,20 @@ class ToolHandler {
742
738
  this.queryPool = pool;
743
739
  }
744
740
  /**
745
- * Update the default CodeGraph instance (e.g. after lazy initialization).
741
+ * Update the default LatticeSensor instance (e.g. after lazy initialization).
746
742
  * A successful open supersedes any previously recorded open failure.
747
743
  */
748
- setDefaultCodeGraph(cg) {
744
+ setDefaultLatticeSensor(cg) {
749
745
  this.cg = cg;
750
746
  this.openFailure = null;
751
747
  }
752
748
  /**
753
749
  * ADR 0049 Decision 5②: record that the DEFAULT project's index failed to
754
- * open for a reason OTHER than "no .codegraph/ found" — the engine calls
755
- * this from its init catch block. `getCodeGraph()` throws it (fail closed)
750
+ * open for a reason OTHER than "no .lattice/sensor/ found" — the engine calls
751
+ * this from its init catch block. `getLatticeSensor()` throws it (fail closed)
756
752
  * instead of the NotIndexedError guidance the next time a tool call needs
757
753
  * the default project, so the failure surfaces as `isError: true` rather
758
- * than being silently absorbed into "just run codegraph init" prose.
754
+ * than being silently absorbed into "just run lattice sensor init . --json" prose.
759
755
  */
760
756
  setOpenFailure(err) {
761
757
  this.openFailure = err;
@@ -764,7 +760,7 @@ class ToolHandler {
764
760
  * ADR 0049 Decision 5④: record this session's execution mode
765
761
  * (`daemon`/`direct`) and the typed reason direct mode was chosen (or
766
762
  * `'daemon'` when routed through the shared daemon). Surfaced verbatim by
767
- * `codegraph_status`.
763
+ * `lattice_sensor_status`.
768
764
  */
769
765
  setExecutionMode(mode, reason) {
770
766
  this.executionMode = { mode, reason };
@@ -813,8 +809,8 @@ class ToolHandler {
813
809
  timedOut,
814
810
  ]);
815
811
  if (outcome === 'timeout') {
816
- process.stderr.write(`[CodeGraph MCP] Catch-up reconcile still running after ${timeoutMs}ms; serving this tool call now and finishing the reconcile in the background (#905). ` +
817
- `Set CODEGRAPH_CATCHUP_GATE_TIMEOUT_MS=0 to always wait for it.\n`);
812
+ process.stderr.write(`[LatticeSensor MCP] Catch-up reconcile still running after ${timeoutMs}ms; serving this tool call now and finishing the reconcile in the background (#905). ` +
813
+ `Set LATTICE_SENSOR_CATCHUP_GATE_TIMEOUT_MS=0 to always wait for it.\n`);
818
814
  }
819
815
  }
820
816
  finally {
@@ -830,46 +826,46 @@ class ToolHandler {
830
826
  this.defaultProjectHint = searchedPath;
831
827
  }
832
828
  /**
833
- * Whether a default CodeGraph instance is available
829
+ * Whether a default LatticeSensor instance is available
834
830
  */
835
- hasDefaultCodeGraph() {
831
+ hasDefaultLatticeSensor() {
836
832
  return this.cg !== null;
837
833
  }
838
834
  /**
839
- * Optional allowlist of exposed tools, parsed from the CODEGRAPH_MCP_TOOLS
835
+ * Optional allowlist of exposed tools, parsed from the LATTICE_SENSOR_MCP_TOOLS
840
836
  * env var (comma-separated short names, e.g. "trace,search,node,context").
841
- * Unset/empty → every tool is exposed. Lets an operator (or an A/B harness)
837
+ * Unset/empty → the contracted eight-tool surface. Lets an operator (or an A/B harness)
842
838
  * trim the tool surface without rebuilding the client config; the ablated
843
839
  * tool is then truly absent from ListTools rather than merely denied on call.
844
- * Matching is on the short form, so "node" and "codegraph_node" both work.
840
+ * Matching is on the short form, so "node" and "lattice_sensor_node" both work.
845
841
  */
846
842
  toolAllowlist() {
847
- const raw = process.env.CODEGRAPH_MCP_TOOLS;
843
+ const raw = process.env.LATTICE_SENSOR_MCP_TOOLS;
848
844
  if (!raw || !raw.trim())
849
845
  return null;
850
- const short = (s) => s.trim().replace(/^codegraph_/, '');
846
+ const short = (s) => s.trim().replace(/^lattice_sensor_/, '');
851
847
  const set = new Set(raw.split(',').map(short).filter(Boolean));
852
848
  return set.size ? set : null;
853
849
  }
854
- /** Whether a tool name passes the CODEGRAPH_MCP_TOOLS allowlist (if any). */
850
+ /** Whether a tool name passes the LATTICE_SENSOR_MCP_TOOLS allowlist (if any). */
855
851
  isToolAllowed(name) {
856
852
  const allow = this.toolAllowlist();
857
- return !allow || allow.has(name.replace(/^codegraph_/, ''));
853
+ return !allow || allow.has(name.replace(/^lattice_sensor_/, ''));
858
854
  }
859
855
  /**
860
856
  * Get tool definitions with dynamic descriptions based on project size.
861
- * The codegraph_explore tool description includes a budget recommendation
862
- * scaled to the number of indexed files. Honors the CODEGRAPH_MCP_TOOLS
857
+ * The lattice_sensor_explore tool description includes a budget recommendation
858
+ * scaled to the number of indexed files. Honors the LATTICE_SENSOR_MCP_TOOLS
863
859
  * allowlist so a trimmed surface is reflected in ListTools.
864
860
  */
865
861
  getTools() {
866
862
  const allow = this.toolAllowlist();
867
- // No explicit allowlist → the default 4-tool surface (see
863
+ // No explicit allowlist → the contracted eight-tool surface (see
868
864
  // DEFAULT_MCP_TOOLS for the evidence). An allowlist replaces the
869
865
  // default entirely, so any defined tool can be re-enabled.
870
866
  let visible = allow
871
- ? exports.tools.filter(t => allow.has(t.name.replace(/^codegraph_/, '')))
872
- : exports.tools.filter(t => DEFAULT_MCP_TOOLS.has(t.name.replace(/^codegraph_/, '')));
867
+ ? exports.tools.filter(t => allow.has(t.name.replace(/^lattice_sensor_/, '')))
868
+ : exports.tools.filter(t => DEFAULT_MCP_TOOLS.has(t.name.replace(/^lattice_sensor_/, '')));
873
869
  // No default project loaded → no-root-index case (#993): a gateway server
874
870
  // started outside any repo, or a monorepo root whose indexes live in
875
871
  // sub-projects. With nothing to fall back to, EVERY call needs an explicit
@@ -885,40 +881,8 @@ class ToolHandler {
885
881
  try {
886
882
  const stats = this.cg.getStats();
887
883
  const budget = getExploreBudget(stats.fileCount);
888
- // Tiny-repo tool gating: on projects under TINY_REPO_FILE_THRESHOLD
889
- // files, only expose the core trio (search, node, explore) — one
890
- // below even the 4-tool default: at this scale callers, too, reduces
891
- // to one grep. (Historical note: the audit below ran when context and
892
- // trace still existed; its "5 core tools" are today's trio.)
893
- //
894
- // n=2 audits ruled out cutting below 5 tools:
895
- // - 3-tool gate (search + context + trace): cost regressed on
896
- // cobra/ky/sinatra. The agent fell back to raw Reads to cover
897
- // what codegraph_node + codegraph_explore would have answered.
898
- // - 1-tool gate (search only): catastrophic regression — express
899
- // went from -43% WIN to +107% LOSS. With only search, the agent
900
- // can't navigate the call graph structurally and reads everything.
901
- //
902
- // 5 is the empirical lower bound. Tools beyond search/context/
903
- // node/explore/trace pay overhead that the agent doesn't recoup
904
- // on tiny-repo flow questions.
905
- // ITER4: raise threshold 150 → 500 so single-file frameworks
906
- // (sinatra at 159, slim_framework around 200) also get the
907
- // 5-tool surface. The empirical 5-tool floor was set on <150
908
- // probes; iter3 measurement showed sinatra is structurally the
909
- // SAME problem as cobra (single-file WITHOUT-arm Read wins),
910
- // so it deserves the same gating.
911
- const TINY_REPO_FILE_THRESHOLD = 500;
912
- const TINY_REPO_CORE_TOOLS = new Set([
913
- 'codegraph_explore',
914
- 'codegraph_search',
915
- 'codegraph_node',
916
- ]);
917
- if (stats.fileCount < TINY_REPO_FILE_THRESHOLD) {
918
- visible = visible.filter(t => TINY_REPO_CORE_TOOLS.has(t.name));
919
- }
920
884
  return visible.map(tool => {
921
- if (tool.name === 'codegraph_explore') {
885
+ if (tool.name === 'lattice_sensor_explore') {
922
886
  return {
923
887
  ...tool,
924
888
  description: `${tool.description} Budget: make at most ${budget} calls for this project (${stats.fileCount.toLocaleString()} files indexed).`,
@@ -932,15 +896,15 @@ class ToolHandler {
932
896
  }
933
897
  }
934
898
  /**
935
- * Get CodeGraph instance for a project
899
+ * Get LatticeSensor instance for a project
936
900
  *
937
- * If projectPath is provided, opens that project's CodeGraph (cached).
938
- * Otherwise returns the default CodeGraph instance.
901
+ * If projectPath is provided, opens that project's LatticeSensor (cached).
902
+ * Otherwise returns the default LatticeSensor instance.
939
903
  *
940
- * Walks up parent directories to find the nearest .codegraph/ folder,
904
+ * Walks up parent directories to find the nearest .lattice/sensor/ folder,
941
905
  * similar to how git finds .git/ directories.
942
906
  */
943
- getCodeGraph(projectPath) {
907
+ getLatticeSensor(projectPath) {
944
908
  if (!projectPath) {
945
909
  if (!this.cg) {
946
910
  // ADR 0049 Decision 5②: a recorded open failure (DB open error,
@@ -950,31 +914,31 @@ class ToolHandler {
950
914
  // NotIndexedError guidance below, which would misleadingly read as
951
915
  // "this project just isn't indexed yet".
952
916
  if (this.openFailure) {
953
- throw new IndexOpenError(`The default project's CodeGraph index failed to open: ${this.openFailure.message}\n` +
917
+ throw new IndexOpenError(`The default project's LatticeSensor index failed to open: ${this.openFailure.message}\n` +
954
918
  'This is a genuine malfunction (corrupt/locked database, schema mismatch, or ' +
955
919
  'similar) — NOT a missing index. Retry the call once; if it persists, the index ' +
956
- 'may need to be rebuilt (`codegraph init` after removing `.codegraph/`) or a ' +
920
+ 'may need to be rebuilt (`lattice sensor init . --json` after removing `.lattice/sensor/`) or a ' +
957
921
  'stale lock cleared.');
958
922
  }
959
923
  const searched = this.defaultProjectHint ?? process.cwd();
960
- throw new NotIndexedError('No CodeGraph project is loaded for this session.\n' +
961
- `Searched for a .codegraph/ directory starting from: ${searched}\n` +
924
+ throw new NotIndexedError('No LatticeSensor project is loaded for this session.\n' +
925
+ `Searched for a .lattice/sensor/ directory starting from: ${searched}\n` +
962
926
  'Either the server root has no index of its own (e.g. a monorepo where only ' +
963
927
  "sub-projects are indexed), or the MCP client launched the server outside your " +
964
928
  'project without reporting the workspace root. Either way, target the project ' +
965
929
  'explicitly:\n' +
966
930
  ' • Pass projectPath to the tool call, e.g. projectPath: "/absolute/path/to/your/project" ' +
967
- '(any project that has a .codegraph/ — including a sub-project of a monorepo)\n' +
931
+ '(any project that has a .lattice/sensor/ — including a sub-project of a monorepo)\n' +
968
932
  ' • Or add --path to the server\'s MCP config args: ["serve", "--mcp", "--path", "/absolute/path/to/your/project"]\n' +
969
933
  'If a project simply has no index, use your built-in tools (Read/Grep/Glob) for THAT ' +
970
- "project (the user can run 'codegraph init' there to enable it) — you can still query " +
934
+ "project (the user can run 'lattice sensor init . --json' there to enable it) — you can still query " +
971
935
  'other indexed projects by projectPath in the same session.');
972
936
  }
973
937
  return this.freshen(this.cg);
974
938
  }
975
939
  // Reject sensitive system directories before opening. Only validate a
976
940
  // path that actually exists — a nested or not-yet-created sub-path of a
977
- // real project must still be allowed to resolve UP to its .codegraph/
941
+ // real project must still be allowed to resolve UP to its .lattice/sensor/
978
942
  // root below (issue #238), so we don't run the existence-checking
979
943
  // validator on paths that are meant to walk up.
980
944
  if ((0, fs_1.existsSync)(projectPath)) {
@@ -983,22 +947,22 @@ class ToolHandler {
983
947
  throw new PathRefusalError(pathError);
984
948
  }
985
949
  }
986
- // Always RE-RESOLVE the nearest .codegraph/ from the input path. The walk
950
+ // Always RE-RESOLVE the nearest .lattice/sensor/ from the input path. The walk
987
951
  // is cheap (a few existsSync up the tree) and is the only thing that
988
952
  // notices a path whose index root CHANGED since it was first seen — most
989
- // importantly a git worktree that gained its own .codegraph/ after the
953
+ // importantly a git worktree that gained its own .lattice/sensor/ after the
990
954
  // (long-lived) server first resolved it up to the parent checkout. We used
991
955
  // to short-circuit on a `projectCache[projectPath]` entry before resolving,
992
956
  // which pinned that first resolution for the server's whole lifetime, so a
993
957
  // worktree kept being served the parent checkout's index until restart
994
958
  // (#926). The DB connection itself is still cached (by resolved root,
995
959
  // below), so re-resolving costs only the stat walk, never a reopen.
996
- const resolvedRoot = (0, directory_1.findNearestCodeGraphRoot)(projectPath);
960
+ const resolvedRoot = (0, directory_1.findNearestLatticeSensorRoot)(projectPath);
997
961
  if (!resolvedRoot) {
998
- throw new NotIndexedError(`The project at ${projectPath} isn't indexed with codegraph (no .codegraph/ directory found ` +
999
- 'walking up from it), so codegraph cannot query it. Use your built-in tools (Read/Grep/Glob) ' +
1000
- "for that codebase instead, and don't call codegraph for it again this session. " +
1001
- "Indexing is the user's decision — they can run 'codegraph init' in that project to enable it.");
962
+ throw new NotIndexedError(`The project at ${projectPath} isn't indexed with lattice sensor (no .lattice/sensor/ directory found ` +
963
+ 'walking up from it), so lattice sensor cannot query it. Use your built-in tools (Read/Grep/Glob) ' +
964
+ "for that codebase instead, and don't call lattice sensor for it again this session. " +
965
+ "Indexing is the user's decision — they can run 'lattice sensor init . --json' in that project to enable it.");
1002
966
  }
1003
967
  // If the path resolves to the default project, reuse the already-open
1004
968
  // default instance rather than opening a SECOND connection to the same DB.
@@ -1016,13 +980,13 @@ class ToolHandler {
1016
980
  const cached = this.projectCache.get(resolvedRoot);
1017
981
  if (cached)
1018
982
  return this.freshen(cached);
1019
- const cg = loadCodeGraph().openSync(resolvedRoot);
983
+ const cg = loadLatticeSensor().openSync(resolvedRoot);
1020
984
  this.projectCache.set(resolvedRoot, cg);
1021
985
  return cg;
1022
986
  }
1023
987
  /**
1024
- * Heal a long-lived connection whose `.codegraph/` was removed and recreated
1025
- * at the same path (a worktree recreated, or `rm -rf .codegraph` + re-init)
988
+ * Heal a long-lived connection whose `.lattice/sensor/` was removed and recreated
989
+ * at the same path (a worktree recreated, or `rm -rf .lattice/sensor` + re-init)
1026
990
  * before handing it to a tool. Otherwise the daemon keeps serving the
1027
991
  * pre-removal snapshot from its now-unlinked file handle until restart — and
1028
992
  * because the daemon registry is keyed by path, a same-path recreate routes
@@ -1033,7 +997,7 @@ class ToolHandler {
1033
997
  freshen(cg) {
1034
998
  try {
1035
999
  if (cg.reopenIfReplaced()) {
1036
- process.stderr.write('[CodeGraph MCP] The index was replaced on disk (e.g. a git worktree ' +
1000
+ process.stderr.write('[LatticeSensor MCP] The index was replaced on disk (e.g. a git worktree ' +
1037
1001
  'recreated at the same path); reopened the live database in place.\n');
1038
1002
  }
1039
1003
  }
@@ -1099,7 +1063,7 @@ class ToolHandler {
1099
1063
  const startPath = projectPath ?? this.defaultProjectHint ?? process.cwd();
1100
1064
  // The verdict depends on BOTH the start path AND the index root it resolves
1101
1065
  // to, so the cache must be keyed on the pair. Resolve the index root first
1102
- // (cheap — getCodeGraph re-walks to the nearest .codegraph/, no git), then
1066
+ // (cheap — getLatticeSensor re-walks to the nearest .lattice/sensor/, no git), then
1103
1067
  // key on `(startPath, indexRoot)`. The moment that root changes — most
1104
1068
  // importantly when a git worktree gains its own index and the walk-up stops
1105
1069
  // there instead of at the parent checkout — the key changes and the verdict
@@ -1108,7 +1072,7 @@ class ToolHandler {
1108
1072
  // that first verdict until restart (#926).
1109
1073
  let indexRoot;
1110
1074
  try {
1111
- indexRoot = this.getCodeGraph(projectPath).getProjectRoot();
1075
+ indexRoot = this.getLatticeSensor(projectPath).getProjectRoot();
1112
1076
  }
1113
1077
  catch {
1114
1078
  // No resolvable project (or any other resolution error) → nothing to warn.
@@ -1127,7 +1091,7 @@ class ToolHandler {
1127
1091
  * notice when the resolved index belongs to a different git working tree than
1128
1092
  * the caller's (issue #155). Without this, an agent in a nested worktree
1129
1093
  * silently trusts main-branch results. No-op on error results and when there
1130
- * is no mismatch. `codegraph_status` is excluded — it embeds its own verbose
1094
+ * is no mismatch. `lattice_sensor_status` is excluded — it embeds its own verbose
1131
1095
  * warning — so it stays out of this path.
1132
1096
  */
1133
1097
  withWorktreeNotice(result, projectPath) {
@@ -1161,12 +1125,12 @@ class ToolHandler {
1161
1125
  return result;
1162
1126
  let cg;
1163
1127
  try {
1164
- cg = this.getCodeGraph(projectPath);
1128
+ cg = this.getLatticeSensor(projectPath);
1165
1129
  }
1166
1130
  catch {
1167
1131
  return result; // no default project — leave as is
1168
1132
  }
1169
- // Cross-project `projectPath` calls open a cached CodeGraph WITHOUT a
1133
+ // Cross-project `projectPath` calls open a cached LatticeSensor WITHOUT a
1170
1134
  // watcher (watchers are only attached to the default session project).
1171
1135
  // When the cross-project path happens to be the same project as the
1172
1136
  // default cg, the cached instance is the wrong one — its pendingFiles is
@@ -1188,7 +1152,7 @@ class ToolHandler {
1188
1152
  // fire — but the index is now FROZEN and silently drifting stale. Surface
1189
1153
  // one global notice instead, so the agent Reads for current content rather
1190
1154
  // than trusting a response off a no-longer-updating index. (Cross-project
1191
- // calls open a watcher-less CodeGraph, so this is false there — correct: we
1155
+ // calls open a watcher-less LatticeSensor, so this is false there — correct: we
1192
1156
  // only know degraded state for the default session project.)
1193
1157
  let degraded = false;
1194
1158
  try {
@@ -1211,7 +1175,7 @@ class ToolHandler {
1211
1175
  const composed = `${formatDegradedBanner(reason)}\n\n${head.text}`;
1212
1176
  return { ...result, content: [{ type: 'text', text: composed }, ...tail] };
1213
1177
  }
1214
- // Defensive: some test fakes inject a partial CodeGraph stub without the
1178
+ // Defensive: some test fakes inject a partial LatticeSensor stub without the
1215
1179
  // newer pending-files API. Treat missing/throwing as "no pending files."
1216
1180
  let pending = [];
1217
1181
  try {
@@ -1230,7 +1194,7 @@ class ToolHandler {
1230
1194
  const elsewhere = [];
1231
1195
  for (const p of pending) {
1232
1196
  // Substring match against the project-relative POSIX path — that's
1233
- // exactly the format both the watcher and every codegraph response
1197
+ // exactly the format both the watcher and every lattice sensor response
1234
1198
  // emit, so a plain includes() is sufficient and avoids regex pitfalls.
1235
1199
  if (text.includes(p.path))
1236
1200
  inResponse.push(p);
@@ -1268,10 +1232,10 @@ class ToolHandler {
1268
1232
  this.catchUpGate = null;
1269
1233
  await this.awaitCatchUpGate(gate);
1270
1234
  }
1271
- // Honor the optional tool allowlist (CODEGRAPH_MCP_TOOLS): a trimmed
1235
+ // Honor the optional tool allowlist (LATTICE_SENSOR_MCP_TOOLS): a trimmed
1272
1236
  // surface rejects ablated tools defensively even if a client cached them.
1273
1237
  if (!this.isToolAllowed(toolName)) {
1274
- return this.errorResult(`Tool ${toolName} is disabled via CODEGRAPH_MCP_TOOLS`);
1238
+ return this.errorResult(`Tool ${toolName} is disabled via LATTICE_SENSOR_MCP_TOOLS`);
1275
1239
  }
1276
1240
  // Cross-cutting input validation. All tools accept an optional
1277
1241
  // `projectPath` and most accept either `query`, `task`, or
@@ -1281,7 +1245,7 @@ class ToolHandler {
1281
1245
  if (typeof pathCheck === 'object' && pathCheck !== undefined) {
1282
1246
  return pathCheck;
1283
1247
  }
1284
- // The `path` and `pattern` properties used by codegraph_files are
1248
+ // The `path` and `pattern` properties used by lattice_sensor_files are
1285
1249
  // also path-shaped — apply the same cap.
1286
1250
  if (args.path !== undefined) {
1287
1251
  const check = this.validateOptionalPath(args.path, 'path');
@@ -1293,12 +1257,12 @@ class ToolHandler {
1293
1257
  if (typeof check === 'object' && check !== undefined)
1294
1258
  return check;
1295
1259
  }
1296
- // codegraph_status reports watcher state (pending files, degraded mode,
1260
+ // lattice_sensor_status reports watcher state (pending files, degraded mode,
1297
1261
  // worktree warning) and embeds its own sections — it must run on the MAIN
1298
1262
  // thread against the watched default instance, so it is NEVER off-loaded to
1299
1263
  // a worker (whose read connection has no watcher). It also skips the
1300
1264
  // auto-banner wrapper to avoid duplicating its own pending-files section.
1301
- if (toolName === 'codegraph_status') {
1265
+ if (toolName === 'lattice_sensor_status') {
1302
1266
  return await this.handleStatus(args);
1303
1267
  }
1304
1268
  // Read tools: off-load the CPU-heavy dispatch to the worker pool when one
@@ -1333,8 +1297,8 @@ class ToolHandler {
1333
1297
  return this.errorResult(err.message);
1334
1298
  }
1335
1299
  return this.errorResult(`Tool execution failed: ${err instanceof Error ? err.message : String(err)}. ` +
1336
- 'This is an internal codegraph error — retry the call once; if it persists, ' +
1337
- 'continue without codegraph for this task.');
1300
+ 'This is an internal lattice sensor error — retry the call once; if it persists, ' +
1301
+ 'continue without lattice sensor for this task.');
1338
1302
  }
1339
1303
  }
1340
1304
  /**
@@ -1362,36 +1326,36 @@ class ToolHandler {
1362
1326
  return this.errorResult(err.message);
1363
1327
  }
1364
1328
  return this.errorResult(`Tool execution failed: ${err instanceof Error ? err.message : String(err)}. ` +
1365
- 'This is an internal codegraph error — retry the call once; if it persists, ' +
1366
- 'continue without codegraph for this task.');
1329
+ 'This is an internal lattice sensor error — retry the call once; if it persists, ' +
1330
+ 'continue without lattice sensor for this task.');
1367
1331
  }
1368
1332
  }
1369
1333
  /**
1370
1334
  * Pure dispatch over the read tools — the switch, with no gate, no notices, no
1371
- * allowlist/validation (the caller owns those). `codegraph_status` is handled
1335
+ * allowlist/validation (the caller owns those). `lattice_sensor_status` is handled
1372
1336
  * on the main thread in {@link execute} and never reaches here. May throw
1373
1337
  * NotIndexed/PathRefusal, which {@link executeReadTool} classifies.
1374
1338
  */
1375
1339
  async dispatchTool(toolName, args) {
1376
1340
  switch (toolName) {
1377
- case 'codegraph_search': return await this.handleSearch(args);
1378
- case 'codegraph_callers': return await this.handleCallers(args);
1379
- case 'codegraph_callees': return await this.handleCallees(args);
1380
- case 'codegraph_impact': return await this.handleImpact(args);
1381
- case 'codegraph_explore': return await this.handleExplore(args);
1382
- case 'codegraph_node': return await this.handleNode(args);
1383
- case 'codegraph_files': return await this.handleFiles(args);
1341
+ case 'lattice_sensor_search': return await this.handleSearch(args);
1342
+ case 'lattice_sensor_callers': return await this.handleCallers(args);
1343
+ case 'lattice_sensor_callees': return await this.handleCallees(args);
1344
+ case 'lattice_sensor_impact': return await this.handleImpact(args);
1345
+ case 'lattice_sensor_explore': return await this.handleExplore(args);
1346
+ case 'lattice_sensor_node': return await this.handleNode(args);
1347
+ case 'lattice_sensor_files': return await this.handleFiles(args);
1384
1348
  default: return this.errorResult(`Unknown tool: ${toolName}`);
1385
1349
  }
1386
1350
  }
1387
1351
  /**
1388
- * Handle codegraph_search
1352
+ * Handle lattice_sensor_search
1389
1353
  */
1390
1354
  async handleSearch(args) {
1391
1355
  const query = this.validateString(args.query, 'query');
1392
1356
  if (typeof query !== 'string')
1393
1357
  return query;
1394
- const cg = this.getCodeGraph(args.projectPath);
1358
+ const cg = this.getLatticeSensor(args.projectPath);
1395
1359
  const rawKind = args.kind;
1396
1360
  // The schema enum says 'type' (what agents naturally reach for); the
1397
1361
  // NodeKind is 'type_alias'. Without the mapping, kind: "type" silently
@@ -1455,13 +1419,13 @@ class ToolHandler {
1455
1419
  return `**${head.qualifiedName}** (${head.kind}) — ${head.filePath}${line}`;
1456
1420
  }
1457
1421
  /**
1458
- * Handle codegraph_callers
1422
+ * Handle lattice_sensor_callers
1459
1423
  */
1460
1424
  async handleCallers(args) {
1461
1425
  const symbol = this.validateString(args.symbol, 'symbol');
1462
1426
  if (typeof symbol !== 'string')
1463
1427
  return symbol;
1464
- const cg = this.getCodeGraph(args.projectPath);
1428
+ const cg = this.getLatticeSensor(args.projectPath);
1465
1429
  const limit = (0, utils_1.clamp)(args.limit || 20, 1, 100);
1466
1430
  const fileFilter = typeof args.file === 'string' ? args.file : undefined;
1467
1431
  const allMatches = this.findAllSymbols(cg, symbol);
@@ -1523,13 +1487,13 @@ class ToolHandler {
1523
1487
  return this.textResult(this.truncateOutput(lines.join('\n') + filterNote));
1524
1488
  }
1525
1489
  /**
1526
- * Handle codegraph_callees
1490
+ * Handle lattice_sensor_callees
1527
1491
  */
1528
1492
  async handleCallees(args) {
1529
1493
  const symbol = this.validateString(args.symbol, 'symbol');
1530
1494
  if (typeof symbol !== 'string')
1531
1495
  return symbol;
1532
- const cg = this.getCodeGraph(args.projectPath);
1496
+ const cg = this.getLatticeSensor(args.projectPath);
1533
1497
  const limit = (0, utils_1.clamp)(args.limit || 20, 1, 100);
1534
1498
  const fileFilter = typeof args.file === 'string' ? args.file : undefined;
1535
1499
  const allMatches = this.findAllSymbols(cg, symbol);
@@ -1588,13 +1552,13 @@ class ToolHandler {
1588
1552
  return this.textResult(this.truncateOutput(lines.join('\n') + filterNote));
1589
1553
  }
1590
1554
  /**
1591
- * Handle codegraph_impact
1555
+ * Handle lattice_sensor_impact
1592
1556
  */
1593
1557
  async handleImpact(args) {
1594
1558
  const symbol = this.validateString(args.symbol, 'symbol');
1595
1559
  if (typeof symbol !== 'string')
1596
1560
  return symbol;
1597
- const cg = this.getCodeGraph(args.projectPath);
1561
+ const cg = this.getLatticeSensor(args.projectPath);
1598
1562
  const depth = (0, utils_1.clamp)(args.depth || 2, 1, 10);
1599
1563
  const fileFilter = typeof args.file === 'string' ? args.file : undefined;
1600
1564
  const allMatches = this.findAllSymbols(cg, symbol);
@@ -1735,7 +1699,7 @@ class ToolHandler {
1735
1699
  return null;
1736
1700
  }
1737
1701
  /**
1738
- * Flow-from-named-symbols: an agent's codegraph_explore query is a bag of
1702
+ * Flow-from-named-symbols: an agent's lattice_sensor_explore query is a bag of
1739
1703
  * symbol names that usually spans the flow it's investigating (e.g.
1740
1704
  * "PmsProductController getList PmsProductService list PmsProductServiceImpl").
1741
1705
  * Surface the longest call chain AMONG those named symbols — scoped to what the
@@ -2115,7 +2079,7 @@ class ToolHandler {
2115
2079
  '',
2116
2080
  ...notes,
2117
2081
  '',
2118
- '> These sites choose their call target at runtime (registry / bus / reflection) — the site shown IS where the flow continues. To follow it, run codegraph_explore or codegraph_node on a candidate; source for the sites above is included below.',
2082
+ '> These sites choose their call target at runtime (registry / bus / reflection) — the site shown IS where the flow continues. To follow it, run lattice_sensor_explore or lattice_sensor_node on a candidate; source for the sites above is included below.',
2119
2083
  '',
2120
2084
  ].join('\n');
2121
2085
  }
@@ -2129,7 +2093,7 @@ class ToolHandler {
2129
2093
  * the concrete target is chosen at runtime from N implementations, so no single
2130
2094
  * static edge is "the answer" — the implementations ARE the continuations. We
2131
2095
  * announce the supertype, its TRUE implementer count, and a few concrete targets,
2132
- * then steer to codegraph_explore. Graph-only, query-time, zero mutation; the
2096
+ * then steer to lattice_sensor_explore. Graph-only, query-time, zero mutation; the
2133
2097
  * caller fires it ONLY for an UNCOVERED named token, so a connected flow is silent.
2134
2098
  *
2135
2099
  * Robust to FTS sampling bias: the same-name family is a capped FTS sample that
@@ -2222,7 +2186,7 @@ class ToolHandler {
2222
2186
  '',
2223
2187
  ...notes,
2224
2188
  '',
2225
- '> The method above is dispatched at runtime to one of the listed implementations (a registry / plugin / strategy interface) — there is no single static caller→callee edge; the implementations ARE the continuations. To follow one, run codegraph_explore on a listed target.',
2189
+ '> The method above is dispatched at runtime to one of the listed implementations (a registry / plugin / strategy interface) — there is no single static caller→callee edge; the implementations ARE the continuations. To follow one, run lattice_sensor_explore on a listed target.',
2226
2190
  '',
2227
2191
  ].join('\n');
2228
2192
  }
@@ -2375,7 +2339,7 @@ class ToolHandler {
2375
2339
  * PageRank) from the query's matched SEED nodes over the call/reference graph.
2376
2340
  *
2377
2341
  * This is the ranking signal text search (FTS/bm25) CANNOT provide, and it's
2378
- * codegraph's home turf: relevance by STRUCTURE, not words. A file whose
2342
+ * lattice sensor's home turf: relevance by STRUCTURE, not words. A file whose
2379
2343
  * symbols are call-connected to the matched cluster accrues walk mass and
2380
2344
  * ranks high; a lone TEXT match — e.g. `LensSwitcher.swift` matched the word
2381
2345
  * "switch" from `switchOrganization`, but calls none of `setUser`/`fetchUser`
@@ -2453,11 +2417,11 @@ class ToolHandler {
2453
2417
  return out;
2454
2418
  }
2455
2419
  /**
2456
- * Handle codegraph_explore — deep exploration in a single call
2420
+ * Handle lattice_sensor_explore — deep exploration in a single call
2457
2421
  *
2458
2422
  * Strategy: find relevant symbols via graph traversal, group by file,
2459
2423
  * then read contiguous file sections covering all symbols per file.
2460
- * This replaces multiple codegraph_node + Read calls.
2424
+ * This replaces multiple lattice_sensor_node + Read calls.
2461
2425
  *
2462
2426
  * Output size is adaptive to project file count via
2463
2427
  * `getExploreOutputBudget` — see #185 for why a fixed 35k cap was a
@@ -2470,7 +2434,7 @@ class ToolHandler {
2470
2434
  // One normalization point so the flow-builder, relevance search, and
2471
2435
  // ranking all see the same canonical spelling (Erlang `mod:fn/arity`).
2472
2436
  const query = normalizeQuerySpelling(rawQuery);
2473
- const cg = this.getCodeGraph(args.projectPath);
2437
+ const cg = this.getLatticeSensor(args.projectPath);
2474
2438
  const projectRoot = cg.getProjectRoot();
2475
2439
  // Resolve adaptive output budget from project size. Falls back to the
2476
2440
  // largest-tier defaults if stats aren't available, which preserves
@@ -2615,7 +2579,7 @@ class ToolHandler {
2615
2579
  // 50+-overload name (tokio `poll`) ranks the wanted def (`Harness::poll`)
2616
2580
  // below the FTS cut, so findAllSymbols would never see it and the
2617
2581
  // type-token bias below couldn't pick the harness.rs one. (Same fix as
2618
- // codegraph_node's findSymbolMatches.) Qualified tokens keep findAllSymbols.
2582
+ // lattice_sensor_node's findSymbolMatches.) Qualified tokens keep findAllSymbols.
2619
2583
  const isQual = /[.\/]|::/.test(t);
2620
2584
  const raw = isQual ? this.findAllSymbols(cg, t).nodes : cg.getNodesByName(t);
2621
2585
  let cands = raw
@@ -2661,7 +2625,7 @@ class ToolHandler {
2661
2625
  // only: the overloads whose file/class the query ALSO names (the agent
2662
2626
  // told us which one it wants — DataRequest's, not Validation.swift's),
2663
2627
  // capped; else fall back to the single most-substantive def. This is the
2664
- // explore-side mirror of codegraph_node's overload disambiguation.
2628
+ // explore-side mirror of lattice_sensor_node's overload disambiguation.
2665
2629
  let picks;
2666
2630
  let tierPicks; // subset that earns the named-first tier (#1064)
2667
2631
  if (cands.length <= 3) {
@@ -2949,9 +2913,9 @@ class ToolHandler {
2949
2913
  // neither entry nor central (a type/util file that matches "element"+x but isn't
2950
2914
  // the flow) is NOT promoted, so it can't displace the graph-central answer file
2951
2915
  // (hits=1) the way a blunt hits-only tier would. Single-layer repos with one
2952
- // cluster are unaffected (no competing mass). Set CODEGRAPH_RANK_NO_MULTITERM=1
2916
+ // cluster are unaffected (no competing mass). Set LATTICE_SENSOR_RANK_NO_MULTITERM=1
2953
2917
  // to disable.
2954
- const MULTITERM_OFF = process.env.CODEGRAPH_RANK_NO_MULTITERM === '1';
2918
+ const MULTITERM_OFF = process.env.LATTICE_SENSOR_RANK_NO_MULTITERM === '1';
2955
2919
  const isCorroborated = (fp) => !MULTITERM_OFF &&
2956
2920
  (fileTermHits.get(fp) ?? 0) >= 2 &&
2957
2921
  (entryFiles.has(fp) || centralFiles.has(fp));
@@ -3139,7 +3103,7 @@ class ToolHandler {
3139
3103
  }
3140
3104
  const fileLines = fileContent.split('\n');
3141
3105
  const lang = group.nodes[0]?.language || '';
3142
- // Adaptive sizing (CODEGRAPH_ADAPTIVE_EXPLORE, default on): collapse a file
3106
+ // Adaptive sizing (LATTICE_SENSOR_ADAPTIVE_EXPLORE, default on): collapse a file
3143
3107
  // to a per-symbol view when it's a redundant member of a polymorphic family.
3144
3108
  // Engages iff ALL hold:
3145
3109
  // 1. a flow spine exists,
@@ -3254,15 +3218,15 @@ class ToolHandler {
3254
3218
  if (skel.length > 0) {
3255
3219
  const names = [...new Set(group.nodes.filter(n => n.kind !== 'import' && n.kind !== 'export').map(n => n.name))]
3256
3220
  .slice(0, budget.maxSymbolsInFileHeader).join(', ');
3257
- // Steer the agent to codegraph_explore for an elided body — NEVER to
3221
+ // Steer the agent to lattice_sensor_explore for an elided body — NEVER to
3258
3222
  // Read. The old "Read for more" / "Read for a full body" tags invited
3259
3223
  // a Read of the very file just skeletonized; on a central, wanted file
3260
3224
  // (Session.swift, DataRequest.swift) that fired an over-investigation
3261
3225
  // spiral (the agent Read the skeletonized file, then kept digging).
3262
3226
  // CLAUDE.md: explore output must never tell the agent to Read.
3263
3227
  const tag = bodyIds.size > 0
3264
- ? 'focused (the methods you named in full, the rest as signatures — codegraph_explore a signature by name for its body; do NOT Read)'
3265
- : 'skeleton (signatures only — codegraph_explore a name for its full body; do NOT Read)';
3228
+ ? 'focused (the methods you named in full, the rest as signatures — lattice_sensor_explore a signature by name for its body; do NOT Read)'
3229
+ : 'skeleton (signatures only — lattice_sensor_explore a name for its full body; do NOT Read)';
3266
3230
  lines.push(fileSectionHeader(filePath, `${names} · ${tag}`), '', '```' + lang, skel.join('\n'), '```', '');
3267
3231
  totalChars += skel.join('\n').length + 120;
3268
3232
  renderedFilePaths.push(filePath);
@@ -3637,11 +3601,11 @@ class ToolHandler {
3637
3601
  if (budget.includeCompletenessSignal) {
3638
3602
  lines.push('');
3639
3603
  lines.push('---');
3640
- lines.push(`> **Complete source for ${filesIncluded} files is included above — do NOT re-read them.** If your question also needs files/symbols listed under "Not shown above" (or any area this call didn't cover), make ANOTHER codegraph_explore targeting those names — it returns the same source with line numbers and is cheaper and more complete than reading. Reserve Read for a single specific line range explore can't surface.`);
3604
+ lines.push(`> **Complete source for ${filesIncluded} files is included above — do NOT re-read them.** If your question also needs files/symbols listed under "Not shown above" (or any area this call didn't cover), make ANOTHER lattice_sensor_explore targeting those names — it returns the same source with line numbers and is cheaper and more complete than reading. Reserve Read for a single specific line range explore can't surface.`);
3641
3605
  }
3642
3606
  else if (anyFileTrimmed) {
3643
3607
  lines.push('');
3644
- lines.push(`> Some file sections were trimmed for size. For a specific symbol you still need, run another \`codegraph_explore\` (or \`codegraph_node\`) with its exact name — line-numbered source, cheaper and more complete than Read.`);
3608
+ lines.push(`> Some file sections were trimmed for size. For a specific symbol you still need, run another \`lattice_sensor_explore\` (or \`lattice_sensor_node\`) with its exact name — line-numbered source, cheaper and more complete than Read.`);
3645
3609
  }
3646
3610
  // Add explore budget note based on project size
3647
3611
  if (budget.includeBudgetNote) {
@@ -3676,7 +3640,7 @@ class ToolHandler {
3676
3640
  const lastSection = cut.lastIndexOf('\n' + FILE_SECTION_PREFIX);
3677
3641
  const boundary = lastSection > hardCeiling * 0.5 ? lastSection : cut.lastIndexOf('\n');
3678
3642
  const safe = boundary > 0 ? cut.slice(0, boundary) : cut;
3679
- finalText = safe + '\n\n... (output truncated to budget; the source above is complete and verbatim — treat it as already Read. For any area not covered, run another codegraph_explore with the specific names — do NOT Read these files.)';
3643
+ finalText = safe + '\n\n... (output truncated to budget; the source above is complete and verbatim — treat it as already Read. For any area not covered, run another lattice_sensor_explore with the specific names — do NOT Read these files.)';
3680
3644
  }
3681
3645
  else {
3682
3646
  finalText = output;
@@ -3702,10 +3666,10 @@ class ToolHandler {
3702
3666
  return this.textResult(finalText);
3703
3667
  }
3704
3668
  /**
3705
- * Handle codegraph_node
3669
+ * Handle lattice_sensor_node
3706
3670
  */
3707
3671
  async handleNode(args) {
3708
- const cg = this.getCodeGraph(args.projectPath);
3672
+ const cg = this.getLatticeSensor(args.projectPath);
3709
3673
  // Default to false to minimize context usage
3710
3674
  const includeCode = args.includeCode === true;
3711
3675
  const fileHint = typeof args.file === 'string' && args.file.trim() ? args.file.trim() : undefined;
@@ -3761,7 +3725,7 @@ class ToolHandler {
3761
3725
  // different types (Alamofire `didCompleteTask`/`task`/`validate`, gin
3762
3726
  // `reset`). Returning ONE forces the agent to guess, and when it guesses
3763
3727
  // wrong it READS the file to find the right overload — the dominant
3764
- // codegraph_node read cause on Swift/Go. So return them ALL: pack as many
3728
+ // lattice_sensor_node read cause on Swift/Go. So return them ALL: pack as many
3765
3729
  // FULL bodies as fit a char budget (the agent gets the one it needs in this
3766
3730
  // one call, no follow-up parameter to learn), and list any remainder by
3767
3731
  // file:line so a large overload set can't overflow the per-tool cap.
@@ -3806,7 +3770,7 @@ class ToolHandler {
3806
3770
  out.push('', '**Other definitions**', ...shownList.map((n) => `- \`${n.name}\` (${n.kind}) — ${n.filePath}:${n.startLine}`));
3807
3771
  if (listed.length > LIST_CAP)
3808
3772
  out.push(`- … +${listed.length - LIST_CAP} more`);
3809
- out.push('', `> Need one of these in full? Call codegraph_node again with \`file\` (e.g. \`"${listed[0].filePath.split('/').pop()}"\`) or \`line\` — do NOT Read it.`);
3773
+ out.push('', `> Need one of these in full? Call lattice_sensor_node again with \`file\` (e.g. \`"${listed[0].filePath.split('/').pop()}"\`) or \`line\` — do NOT Read it.`);
3810
3774
  }
3811
3775
  return this.textResult(this.truncateOutput(out.join('\n')));
3812
3776
  }
@@ -3828,7 +3792,7 @@ class ToolHandler {
3828
3792
  const wantLower = normalize(fileArg).toLowerCase();
3829
3793
  const allFiles = cg.getFiles();
3830
3794
  if (allFiles.length === 0)
3831
- return this.textResult('No files indexed. Run `codegraph index` first.');
3795
+ return this.textResult('No files indexed. Run `lattice sensor index` first.');
3832
3796
  let resolved = allFiles.find((f) => f.path.toLowerCase() === wantLower);
3833
3797
  let candidates = [];
3834
3798
  if (!resolved) {
@@ -3846,14 +3810,14 @@ class ToolHandler {
3846
3810
  ...candidates.slice(0, 25).map((f) => `- ${f.path}`)].join('\n'));
3847
3811
  }
3848
3812
  if (!resolved) {
3849
- return this.textResult(`No indexed file matches "${fileArg}". Codegraph indexes source files; configs/docs it doesn't parse won't appear — Read those directly.`);
3813
+ return this.textResult(`No indexed file matches "${fileArg}". Lattice sensor indexes source files; configs/docs it doesn't parse won't appear — Read those directly.`);
3850
3814
  }
3851
3815
  const filePath = resolved.path;
3852
3816
  const nodes = cg.getNodesInFile(filePath)
3853
3817
  .filter((n) => n.kind !== 'file' && n.kind !== 'import' && n.kind !== 'export')
3854
3818
  .sort((a, b) => a.startLine - b.startLine);
3855
3819
  const dependents = cg.getFileDependents(filePath);
3856
- // Compact, one-line blast radius (codegraph's value-add over a plain Read).
3820
+ // Compact, one-line blast radius (lattice sensor's value-add over a plain Read).
3857
3821
  const depSummary = dependents.length
3858
3822
  ? `used by ${dependents.length} file${dependents.length === 1 ? '' : 's'}: ${dependents.slice(0, 8).join(', ')}${dependents.length > 8 ? `, +${dependents.length - 8} more` : ''}`
3859
3823
  : 'no other indexed file depends on it';
@@ -3884,7 +3848,7 @@ class ToolHandler {
3884
3848
  const out = [`**${filePath}** — configuration/data file, ${depSummary}`, ''];
3885
3849
  if (nodes.length)
3886
3850
  out.push(...symbolMap('**Keys (values withheld for safety)**'));
3887
- out.push('', '> Values may be secrets, so codegraph indexes keys only. Read the file directly if you need a value.');
3851
+ out.push('', '> Values may be secrets, so lattice sensor indexes keys only. Read the file directly if you need a value.');
3888
3852
  return this.textResult(this.truncateOutput(out.join('\n')));
3889
3853
  }
3890
3854
  // Read the current bytes from disk through the security chokepoint
@@ -3939,7 +3903,7 @@ class ToolHandler {
3939
3903
  const complete = offset === 1 && shownEnd >= total;
3940
3904
  const out = [header, '', ...numbered];
3941
3905
  if (!complete) {
3942
- out.push('', `(lines ${offset}–${shownEnd} of ${total} — pass \`offset\`/\`limit\` for another range, or \`codegraph_node <symbol>\` for one symbol in full)`);
3906
+ out.push('', `(lines ${offset}–${shownEnd} of ${total} — pass \`offset\`/\`limit\` for another range, or \`lattice_sensor_node <symbol>\` for one symbol in full)`);
3943
3907
  }
3944
3908
  // Self-bounded to CHAR_BUDGET — do NOT route through truncateOutput (15k).
3945
3909
  return this.textResult(out.join('\n'));
@@ -3964,9 +3928,9 @@ class ToolHandler {
3964
3928
  }
3965
3929
  /**
3966
3930
  * Build the "trail" for a symbol: its direct callees (what it calls) and
3967
- * callers (what calls it), each with file:line — so codegraph_node doubles as
3931
+ * callers (what calls it), each with file:line — so lattice_sensor_node doubles as
3968
3932
  * the structural Grep→Read→expand primitive: a spot PLUS where to go next.
3969
- * Capped to stay cheap. Walk the graph by calling codegraph_node on a trail
3933
+ * Capped to stay cheap. Walk the graph by calling lattice_sensor_node on a trail
3970
3934
  * entry; no Read needed for covered hops. Empty edges on a non-leaf often mean
3971
3935
  * dynamic dispatch the static graph couldn't resolve — that absence is itself
3972
3936
  * a signal (read that one hop) rather than a dead end.
@@ -3993,7 +3957,7 @@ class ToolHandler {
3993
3957
  const callers = collect(cg.getCallers(node.id));
3994
3958
  if (callees.length === 0 && callers.length === 0)
3995
3959
  return '';
3996
- const lines = ['', '**Trail — codegraph_node any of these to follow it (no Read needed)**'];
3960
+ const lines = ['', '**Trail — lattice_sensor_node any of these to follow it (no Read needed)**'];
3997
3961
  if (callees.length > 0) {
3998
3962
  lines.push(`**Calls →** ${callees.slice(0, TRAIL_CAP).map(fmt).join(', ')}${callees.length > TRAIL_CAP ? `, +${callees.length - TRAIL_CAP} more` : ''}`);
3999
3963
  }
@@ -4003,10 +3967,10 @@ class ToolHandler {
4003
3967
  return lines.join('\n');
4004
3968
  }
4005
3969
  /**
4006
- * Handle codegraph_status
3970
+ * Handle lattice_sensor_status
4007
3971
  */
4008
3972
  async handleStatus(args) {
4009
- let cg = this.getCodeGraph(args.projectPath);
3973
+ let cg = this.getLatticeSensor(args.projectPath);
4010
3974
  // Same trick as withStalenessNotice — when an explicit projectPath
4011
3975
  // resolves to the same project as the default session cg, prefer the
4012
3976
  // default so getPendingFiles() (only populated by the default's watcher)
@@ -4027,7 +3991,7 @@ class ToolHandler {
4027
3991
  // one-liner via withWorktreeNotice. Both share the cached detection.
4028
3992
  const mismatch = this.worktreeMismatchFor(args.projectPath);
4029
3993
  const lines = [
4030
- '**CodeGraph Status**',
3994
+ '**Lattice Sensor Status**',
4031
3995
  '',
4032
3996
  ];
4033
3997
  if (mismatch) {
@@ -4040,7 +4004,7 @@ class ToolHandler {
4040
4004
  // as plain `key: value` lines (not buried in prose) so a caller can parse
4041
4005
  // them without depending on the surrounding Markdown.
4042
4006
  const executionMode = this.executionMode;
4043
- lines.push(`**Lattice sensor version:** ${version_1.CodeGraphPackageVersion}`, `mode: ${executionMode.mode}`, `reason: ${executionMode.reason}`, '', `**Files indexed:** ${stats.fileCount}`, `**Total nodes:** ${stats.nodeCount}`, `**Total edges:** ${stats.edgeCount}`, `**Database size:** ${(stats.dbSizeBytes / 1024 / 1024).toFixed(2)} MB`);
4007
+ lines.push('provider: lattice', 'sensor_owner: lattice', `**Lattice sensor version:** ${version_1.LatticeSensorPackageVersion}`, `mode: ${executionMode.mode}`, `reason: ${executionMode.reason}`, '', `**Files indexed:** ${stats.fileCount}`, `**Total nodes:** ${stats.nodeCount}`, `**Total edges:** ${stats.edgeCount}`, `**Database size:** ${(stats.dbSizeBytes / 1024 / 1024).toFixed(2)} MB`);
4044
4008
  // Surface the active SQLite backend (node:sqlite, Node's built-in real
4045
4009
  // SQLite — full WAL + FTS5, no native build).
4046
4010
  lines.push(`**Backend:** node:sqlite (Node built-in) — full WAL + FTS5`);
@@ -4067,7 +4031,7 @@ class ToolHandler {
4067
4031
  if (pendingRefs > 0) {
4068
4032
  lines.push(`**Pending resolution:** ⚠ ${pendingRefs} references from an interrupted ` +
4069
4033
  `index run — some caller/impact edges are missing until the next sync ` +
4070
- `(any file change triggers it, or run \`codegraph sync\`)`);
4034
+ `(any file change triggers it, or run \`lattice sensor sync . --json\`)`);
4071
4035
  }
4072
4036
  lines.push('', '**Nodes by Kind:**');
4073
4037
  for (const [kind, count] of Object.entries(stats.nodesByKind)) {
@@ -4105,10 +4069,10 @@ class ToolHandler {
4105
4069
  return this.textResult(lines.join('\n'));
4106
4070
  }
4107
4071
  /**
4108
- * Handle codegraph_files - get project file structure from the index
4072
+ * Handle lattice_sensor_files - get project file structure from the index
4109
4073
  */
4110
4074
  async handleFiles(args) {
4111
- const cg = this.getCodeGraph(args.projectPath);
4075
+ const cg = this.getLatticeSensor(args.projectPath);
4112
4076
  const pathFilter = args.path;
4113
4077
  const pattern = args.pattern;
4114
4078
  const format = args.format || 'tree';
@@ -4117,7 +4081,7 @@ class ToolHandler {
4117
4081
  // Get all files from the index
4118
4082
  const allFiles = cg.getFiles();
4119
4083
  if (allFiles.length === 0) {
4120
- return this.textResult('No files indexed. Run `codegraph index` first.');
4084
+ return this.textResult('No files indexed. Run `lattice sensor index` first.');
4121
4085
  }
4122
4086
  // Filter by path prefix. Stored paths are project-relative POSIX (e.g.
4123
4087
  // "src/foo.ts"), but agents commonly pass project-root variants like "/",
@@ -4328,7 +4292,7 @@ class ToolHandler {
4328
4292
  return containerHints.every((hint) => segments.some((seg) => seg === hint || seg.replace(/\.[^.]+$/, '') === hint));
4329
4293
  }
4330
4294
  /**
4331
- * Find ALL definitions matching a name, ranked, so codegraph_node can return
4295
+ * Find ALL definitions matching a name, ranked, so lattice_sensor_node can return
4332
4296
  * every overload instead of guessing one (the wrong guess → a Read). Keepers
4333
4297
  * rank before generated stubs (.pb.go etc.); stable within a group preserves
4334
4298
  * FTS order. Returns [] when nothing matches; a qualified lookup that finds no
@@ -4548,10 +4512,10 @@ class ToolHandler {
4548
4512
  lines.push('', node.docstring);
4549
4513
  }
4550
4514
  if (outline) {
4551
- lines.push('', outline, '', `> Structural outline only. Read \`${node.filePath}\` or call codegraph_node on a specific member for its body.`);
4515
+ lines.push('', outline, '', `> Structural outline only. Read \`${node.filePath}\` or call lattice_sensor_node on a specific member for its body.`);
4552
4516
  }
4553
4517
  else if (code) {
4554
- // Line-numbered (cat -n style, like codegraph_explore and Read) so the
4518
+ // Line-numbered (cat -n style, like lattice_sensor_explore and Read) so the
4555
4519
  // agent can cite/edit exact lines without re-Reading the file for them.
4556
4520
  const numbered = node.startLine ? numberSourceLines(code, node.startLine) : code;
4557
4521
  lines.push('', '```' + node.language, numbered, '```');