pi-lens 4.2.1 → 4.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (671) hide show
  1. package/CHANGELOG.md +1562 -0
  2. package/README.md +157 -24
  3. package/config/dependency-cruiser-eager-allowlist.json +6 -2
  4. package/dist/chunk-22AVIGXS.js +560 -0
  5. package/dist/chunk-27BBHSZC.js +106 -0
  6. package/dist/chunk-2BEMIWEW.js +51 -0
  7. package/dist/chunk-2EECBNC5.js +89 -0
  8. package/dist/chunk-34U7PLGE.js +23 -0
  9. package/dist/chunk-3I5QFT3N.js +181 -0
  10. package/dist/chunk-3MED75HT.js +37 -0
  11. package/dist/chunk-47D2BO4S.js +87 -0
  12. package/dist/chunk-4RERDEXR.js +348 -0
  13. package/dist/chunk-4W2PLC4J.js +27 -0
  14. package/dist/chunk-52H5B5TC.js +202 -0
  15. package/dist/chunk-54B42YRX.js +27 -0
  16. package/dist/chunk-5RXBNSW2.js +266 -0
  17. package/dist/chunk-5THXD6X5.js +201 -0
  18. package/dist/chunk-5W3R6LFT.js +24 -0
  19. package/dist/chunk-5ZEJHV35.js +341 -0
  20. package/dist/chunk-6P62QVEA.js +118 -0
  21. package/dist/chunk-6QIUX4EP.js +459 -0
  22. package/dist/chunk-6VCD4VKZ.js +78 -0
  23. package/dist/chunk-7F72PXY2.js +326 -0
  24. package/dist/chunk-7FBF7NPR.js +998 -0
  25. package/dist/chunk-7U2IDNXN.js +37 -0
  26. package/dist/chunk-ABBOA7UD.js +157 -0
  27. package/dist/chunk-AHDW3GPE.js +50 -0
  28. package/dist/chunk-AJ3QXTRQ.js +756 -0
  29. package/dist/chunk-AJVLWNFN.js +1610 -0
  30. package/dist/chunk-AJXODZY6.js +112 -0
  31. package/dist/chunk-ARFCXG7S.js +84 -0
  32. package/dist/chunk-AS44CFQ4.js +708 -0
  33. package/dist/chunk-AWE5TMPO.js +38 -0
  34. package/dist/chunk-B3I2UUT4.js +4692 -0
  35. package/dist/chunk-BRJKOBZP.js +331 -0
  36. package/dist/chunk-BW5KFIQC.js +59 -0
  37. package/dist/chunk-C2AUYXQH.js +149 -0
  38. package/dist/chunk-CGGAIP7J.js +29 -0
  39. package/dist/chunk-D6QS3U6M.js +30 -0
  40. package/dist/chunk-DFVMIKMQ.js +349 -0
  41. package/dist/chunk-DIULIWKU.js +169 -0
  42. package/dist/chunk-DQ2NZ7C4.js +2317 -0
  43. package/dist/chunk-E2WFBRHM.js +213 -0
  44. package/dist/chunk-E4MAEDPM.js +50 -0
  45. package/dist/chunk-EOKRQ3SA.js +30 -0
  46. package/dist/chunk-F3AU2TMM.js +2626 -0
  47. package/dist/chunk-F3P7VQ7H.js +170 -0
  48. package/dist/chunk-FC4RP4I2.js +12 -0
  49. package/dist/chunk-FJNKANOS.js +32 -0
  50. package/dist/chunk-GUOGVTCQ.js +146 -0
  51. package/dist/chunk-GVXA6CCE.js +18 -0
  52. package/dist/chunk-HHYAELLJ.js +2334 -0
  53. package/dist/chunk-HMFXILPV.js +83 -0
  54. package/dist/chunk-HVUZXSWK.js +421 -0
  55. package/dist/chunk-HWBZIGMJ.js +62 -0
  56. package/dist/chunk-I3R7GKDR.js +17 -0
  57. package/dist/chunk-I7SPGOWI.js +55 -0
  58. package/dist/chunk-IIXOAGHR.js +38 -0
  59. package/dist/chunk-IVP5KAB7.js +2250 -0
  60. package/dist/chunk-IXEBJSUE.js +22 -0
  61. package/dist/chunk-JOLITGCC.js +27 -0
  62. package/dist/chunk-K6VYLB2U.js +145 -0
  63. package/dist/chunk-LJDODBBZ.js +78 -0
  64. package/dist/chunk-LNAKEO63.js +78 -0
  65. package/dist/chunk-LSMJ6KBE.js +4139 -0
  66. package/dist/chunk-LW6XKDZQ.js +5565 -0
  67. package/dist/chunk-N3YQJI6O.js +899 -0
  68. package/dist/chunk-NABLC7W3.js +148 -0
  69. package/dist/chunk-NKOUFPQF.js +659 -0
  70. package/dist/chunk-NL5GLMFI.js +211 -0
  71. package/dist/chunk-NMABWBZN.js +327 -0
  72. package/dist/chunk-NTHH2J74.js +27 -0
  73. package/dist/chunk-NTUJEGDZ.js +59 -0
  74. package/dist/chunk-NXL4FFQQ.js +47 -0
  75. package/dist/chunk-NXPS2L6U.js +466 -0
  76. package/dist/chunk-O5WILGMI.js +42 -0
  77. package/dist/chunk-O6TQT6RI.js +48 -0
  78. package/dist/chunk-OAXNDZJ7.js +323 -0
  79. package/dist/chunk-ODEEOXPH.js +44 -0
  80. package/dist/chunk-OQGFCZJ4.js +4533 -0
  81. package/dist/chunk-ORTMY4Q4.js +282 -0
  82. package/dist/chunk-OS32RNR2.js +442 -0
  83. package/dist/chunk-PAK6IDME.js +189 -0
  84. package/dist/chunk-PWFHBTSF.js +406 -0
  85. package/dist/chunk-Q5U6FMDI.js +2352 -0
  86. package/dist/chunk-QOZXJ4NA.js +3364 -0
  87. package/dist/chunk-QYF5S6P6.js +45 -0
  88. package/dist/chunk-RIISMHKN.js +36 -0
  89. package/dist/chunk-RPD4ZSB7.js +25 -0
  90. package/dist/chunk-RPD5K5NC.js +79 -0
  91. package/dist/chunk-RUOG5D2C.js +262 -0
  92. package/dist/chunk-T4ERT73Y.js +599 -0
  93. package/dist/chunk-T6D4Q4AQ.js +54 -0
  94. package/dist/chunk-TGPXLY2J.js +391 -0
  95. package/dist/chunk-TLGFBM3F.js +12116 -0
  96. package/dist/chunk-TO6WL3GM.js +88 -0
  97. package/dist/chunk-TT22N74J.js +517 -0
  98. package/dist/chunk-TVN5N6GY.js +21216 -0
  99. package/dist/chunk-U3VGR4VU.js +308 -0
  100. package/dist/chunk-UK3CMEAL.js +1250 -0
  101. package/dist/chunk-UOPVJQ4N.js +103 -0
  102. package/dist/chunk-UXVNL3D7.js +23 -0
  103. package/dist/chunk-UY752QSN.js +45 -0
  104. package/dist/chunk-V5PXFSZK.js +188 -0
  105. package/dist/chunk-V7R425XG.js +398 -0
  106. package/dist/chunk-VCSRSYLF.js +81 -0
  107. package/dist/chunk-VD4JQCQC.js +162 -0
  108. package/dist/chunk-VDBPVIKD.js +62 -0
  109. package/dist/chunk-VHQLPIRJ.js +114 -0
  110. package/dist/chunk-VN2AXLEX.js +5414 -0
  111. package/dist/chunk-VNMT7C64.js +478 -0
  112. package/dist/chunk-WONERJTP.js +309 -0
  113. package/dist/chunk-XECLWQZN.js +85 -0
  114. package/dist/chunk-XIMYZ3JA.js +27 -0
  115. package/dist/chunk-XK4CIILI.js +144 -0
  116. package/dist/chunk-Y4T27COV.js +562 -0
  117. package/dist/chunk-YGVYKNSN.js +1860 -0
  118. package/dist/chunk-YLF3PPT5.js +308 -0
  119. package/dist/chunk-YSNFMJKN.js +14 -0
  120. package/dist/chunk-Z3CCVDUB.js +76 -0
  121. package/dist/chunk-Z54ZSOBZ.js +61 -0
  122. package/dist/chunk-ZAWW3AF6.js +97 -0
  123. package/dist/chunk-ZMOL6RQC.js +167 -0
  124. package/dist/index.js +19039 -8956
  125. package/dist/mcp/analyze-cli.js +186 -228
  126. package/dist/mcp/cli.js +137 -98
  127. package/dist/mcp/server.js +22592 -1564
  128. package/dist/mcp/worker.js +97 -38
  129. package/dist/probes/installer.js +135 -0
  130. package/dist/workers/project-snapshot-persist-worker.js +22 -0
  131. package/dist/workers/review-graph-persist-worker.js +15 -0
  132. package/docs/adr/0001-stale-advisory-live-arm.md +29 -0
  133. package/docs/adr/0002-workspace-hash-rendezvous.md +30 -0
  134. package/docs/adr/0003-git-guard-latch-writer.md +203 -0
  135. package/docs/adr/0004-disposition-policy-seam.md +38 -0
  136. package/docs/adr/0005-tool-availability-enforcement-seam.md +29 -0
  137. package/docs/adr/0006-derived-state-benchmark-first.md +31 -0
  138. package/docs/adr/0007-end-to-end-witness-per-seam-slice.md +38 -0
  139. package/docs/adr/0008-turn-end-lane-interface.md +165 -0
  140. package/docs/adr/0009-reported-path-attribution.md +114 -0
  141. package/docs/adr/README.md +26 -0
  142. package/docs/agent-guide.md +13 -4
  143. package/docs/agent-tools.md +60 -1
  144. package/docs/ast-grep_rules_catalog.md +6 -4
  145. package/docs/configuration.md +75 -2
  146. package/docs/engineering-principles.md +202 -0
  147. package/docs/environment-variables.md +113 -6
  148. package/docs/features.md +10 -6
  149. package/docs/globalconfig.md +7 -1
  150. package/docs/io-bridge-v2-migration.md +94 -0
  151. package/docs/language-coverage.md +17 -0
  152. package/docs/lsp-capability-matrix.md +131 -32
  153. package/docs/lsp-idle-eviction.md +124 -0
  154. package/docs/mcp.md +21 -5
  155. package/docs/merge-queue-rollout.md +77 -0
  156. package/docs/pi-lens-fixer.md +161 -39
  157. package/docs/pi-lens-investigator.md +77 -20
  158. package/docs/pi-lens-merge-policy.md +694 -0
  159. package/docs/pi-lens-monitor.md +73 -7
  160. package/docs/pi-lens-retro.md +6 -4
  161. package/docs/pi-lens-reviewer.md +190 -34
  162. package/docs/pi-lens-subagent.md +247 -37
  163. package/docs/pi-lens-warden.md +18 -7
  164. package/docs/public-api-stability.md +56 -0
  165. package/docs/release-qa-baseline.md +86 -17
  166. package/docs/rfcs/3654-unified-io-bridge-v2.md +316 -0
  167. package/docs/servercapabilities.md +66 -52
  168. package/docs/settings.md +13 -3
  169. package/docs/subagent-compat.md +1 -1
  170. package/docs/usage.md +5 -1
  171. package/grammars/tree-sitter-bash.wasm +0 -0
  172. package/grammars/tree-sitter-bash.wasm.json +3 -3
  173. package/package.json +23 -9
  174. package/rules/ast-grep-rules/rule-tests/advisory-registry-subset-test.yml +41 -0
  175. package/rules/ast-grep-rules/rule-tests/no-assert-tuple-test.yml +13 -0
  176. package/rules/ast-grep-rules/rule-tests/no-boolean-in-except-test.yml +26 -0
  177. package/rules/ast-grep-rules/rule-tests/no-http-headers-bracket-access-test.yml +10 -0
  178. package/rules/ast-grep-rules/rule-tests/unchecked-numeric-parse-python-test.yml +18 -0
  179. package/rules/ast-grep-rules/rule-tests/unchecked-throwing-call-python-test.yml +4 -3
  180. package/rules/ast-grep-rules/rules/advisory-registry-subset.yml +50 -0
  181. package/rules/ast-grep-rules/rules/go-no-fmt-println.yml +2 -2
  182. package/rules/ast-grep-rules/rules/no-assert-tuple.yml +23 -13
  183. package/rules/ast-grep-rules/rules/no-boolean-in-except.yml +7 -3
  184. package/rules/ast-grep-rules/rules/no-console-except-error-js.yml +2 -2
  185. package/rules/ast-grep-rules/rules/no-console-except-error.yml +2 -2
  186. package/rules/ast-grep-rules/rules/no-http-headers-bracket-access.yml +12 -7
  187. package/rules/ast-grep-rules/rules/unchecked-numeric-parse-python.yml +44 -0
  188. package/rules/ast-grep-rules/rules/unchecked-throwing-call-python.yml +5 -3
  189. package/rules/tree-sitter-queries/typescript/console-statement.yml +2 -2
  190. package/scripts/analyze-pi-lens-logs.mjs +1275 -62
  191. package/scripts/download-grammars.js +5 -0
  192. package/scripts/grammars.lock.json +6 -1
  193. package/scripts/install-selftest.mjs +38 -35
  194. package/scripts/lib/host-provided-deps.mjs +13 -4
  195. package/scripts/lib/web-tree-sitter-dir.mjs +141 -0
  196. package/dist/clients/actionable-warnings-logger.js +0 -35
  197. package/dist/clients/actionable-warnings.js +0 -1594
  198. package/dist/clients/advisory-provenance.js +0 -457
  199. package/dist/clients/agent-behavior-client.js +0 -147
  200. package/dist/clients/agent-nudge.js +0 -325
  201. package/dist/clients/analysed-root.js +0 -1
  202. package/dist/clients/ast-grep-client.js +0 -731
  203. package/dist/clients/ast-grep-rule-manager.js +0 -146
  204. package/dist/clients/ast-grep-tool-logger.js +0 -118
  205. package/dist/clients/ast-grep-types.js +0 -10
  206. package/dist/clients/ast-grep-yaml-synth.js +0 -154
  207. package/dist/clients/atomic-write-staging.js +0 -75
  208. package/dist/clients/atomic-write.js +0 -189
  209. package/dist/clients/availability-probe-flight.js +0 -12
  210. package/dist/clients/bash-file-access.js +0 -1056
  211. package/dist/clients/biome-client.js +0 -357
  212. package/dist/clients/blocker-freshness.js +0 -837
  213. package/dist/clients/blocker-past-eof.js +0 -129
  214. package/dist/clients/bootstrap.js +0 -569
  215. package/dist/clients/bounded-cache.js +0 -190
  216. package/dist/clients/bounded-pid-file-lock.js +0 -202
  217. package/dist/clients/bounded-telemetry.js +0 -295
  218. package/dist/clients/build-identity.js +0 -95
  219. package/dist/clients/bundled-resource-health.js +0 -113
  220. package/dist/clients/bus-events-logger.js +0 -105
  221. package/dist/clients/bus-publish.js +0 -171
  222. package/dist/clients/cache/rule-cache.js +0 -190
  223. package/dist/clients/cache-manager.js +0 -465
  224. package/dist/clients/cache-observability.js +0 -1313
  225. package/dist/clients/call-graph.js +0 -852
  226. package/dist/clients/cargo-manifest.js +0 -422
  227. package/dist/clients/cascade-budget.js +0 -196
  228. package/dist/clients/cascade-format.js +0 -315
  229. package/dist/clients/cascade-logger.js +0 -31
  230. package/dist/clients/cascade-types.js +0 -9
  231. package/dist/clients/child-unref.js +0 -115
  232. package/dist/clients/code-quality-warnings.js +0 -286
  233. package/dist/clients/codebase-model.js +0 -173
  234. package/dist/clients/collateral-test-role.js +0 -40
  235. package/dist/clients/complexity-client.js +0 -462
  236. package/dist/clients/config-core/deny.js +0 -221
  237. package/dist/clients/config-core/index.js +0 -50
  238. package/dist/clients/config-core/merge.js +0 -357
  239. package/dist/clients/config-core/normalize.js +0 -340
  240. package/dist/clients/config-core/process-spec.js +0 -248
  241. package/dist/clients/config-core/provenance.js +0 -164
  242. package/dist/clients/config-core/records.js +0 -218
  243. package/dist/clients/config-core/resolve.js +0 -125
  244. package/dist/clients/config-core/safe-object.js +0 -78
  245. package/dist/clients/config-core/schema.js +0 -165
  246. package/dist/clients/config-diagnostic-codes.js +0 -283
  247. package/dist/clients/config-locations.js +0 -160
  248. package/dist/clients/config-resolve.js +0 -792
  249. package/dist/clients/config-schema.js +0 -251
  250. package/dist/clients/config-warn.js +0 -407
  251. package/dist/clients/console-guard-install.js +0 -26
  252. package/dist/clients/cooperative-budget.js +0 -42
  253. package/dist/clients/dead-code-client.js +0 -510
  254. package/dist/clients/dead-code-logger.js +0 -30
  255. package/dist/clients/deadline-utils.js +0 -280
  256. package/dist/clients/debug-handles.js +0 -211
  257. package/dist/clients/debug-heap.js +0 -174
  258. package/dist/clients/deferred-lsp-work.js +0 -106
  259. package/dist/clients/degradation-ledger.js +0 -396
  260. package/dist/clients/demoted-finding-render.js +0 -169
  261. package/dist/clients/dependency-checker.js +0 -862
  262. package/dist/clients/deps/ast-grep-napi.js +0 -22
  263. package/dist/clients/deps/js-yaml.js +0 -9
  264. package/dist/clients/deps/minimatch.js +0 -4
  265. package/dist/clients/deps/pi-tui.js +0 -14
  266. package/dist/clients/deps/typebox.js +0 -14
  267. package/dist/clients/deps/vscode-jsonrpc.js +0 -1
  268. package/dist/clients/deps/web-tree-sitter.js +0 -24
  269. package/dist/clients/diagnostic-dispositions.js +0 -594
  270. package/dist/clients/diagnostic-line-freshness.js +0 -305
  271. package/dist/clients/diagnostic-logger.js +0 -73
  272. package/dist/clients/diagnostic-tracker.js +0 -105
  273. package/dist/clients/diagnostics-publish.js +0 -230
  274. package/dist/clients/dispatch/ast-grep-catalog.js +0 -65
  275. package/dist/clients/dispatch/auxiliary-lsp.js +0 -343
  276. package/dist/clients/dispatch/collect-later-tier.js +0 -35
  277. package/dist/clients/dispatch/diagnostic-taxonomy.js +0 -66
  278. package/dist/clients/dispatch/dispatcher.js +0 -1269
  279. package/dist/clients/dispatch/fact-provider-types.js +0 -1
  280. package/dist/clients/dispatch/fact-rule-runner.js +0 -17
  281. package/dist/clients/dispatch/fact-runner.js +0 -30
  282. package/dist/clients/dispatch/fact-scheduler.js +0 -68
  283. package/dist/clients/dispatch/fact-store.js +0 -377
  284. package/dist/clients/dispatch/facts/comment-facts.js +0 -22
  285. package/dist/clients/dispatch/facts/file-content.js +0 -19
  286. package/dist/clients/dispatch/facts/function-facts.js +0 -348
  287. package/dist/clients/dispatch/facts/import-facts.js +0 -204
  288. package/dist/clients/dispatch/facts/tree-sitter-facts.js +0 -34
  289. package/dist/clients/dispatch/facts/try-catch-facts.js +0 -119
  290. package/dist/clients/dispatch/finding-policy.js +0 -222
  291. package/dist/clients/dispatch/indent-detect.js +0 -411
  292. package/dist/clients/dispatch/inline-suppressions.js +0 -70
  293. package/dist/clients/dispatch/integration.js +0 -2377
  294. package/dist/clients/dispatch/lazy.js +0 -11
  295. package/dist/clients/dispatch/pending-runner-findings.js +0 -87
  296. package/dist/clients/dispatch/plan.js +0 -278
  297. package/dist/clients/dispatch/priorities.js +0 -20
  298. package/dist/clients/dispatch/rule-id-normalize.js +0 -50
  299. package/dist/clients/dispatch/rule-ignores.js +0 -62
  300. package/dist/clients/dispatch/rule-policy.js +0 -135
  301. package/dist/clients/dispatch/rules/async-noise.js +0 -40
  302. package/dist/clients/dispatch/rules/async-unnecessary-wrapper.js +0 -27
  303. package/dist/clients/dispatch/rules/cors-wildcard.js +0 -54
  304. package/dist/clients/dispatch/rules/error-obscuring.js +0 -32
  305. package/dist/clients/dispatch/rules/error-swallowing.js +0 -31
  306. package/dist/clients/dispatch/rules/framework-call-noise.js +0 -67
  307. package/dist/clients/dispatch/rules/high-complexity.js +0 -72
  308. package/dist/clients/dispatch/rules/high-fan-out.js +0 -74
  309. package/dist/clients/dispatch/rules/high-import-coupling.js +0 -37
  310. package/dist/clients/dispatch/rules/missing-error-propagation.js +0 -62
  311. package/dist/clients/dispatch/rules/no-commented-credentials.js +0 -52
  312. package/dist/clients/dispatch/rules/pass-through-wrappers.js +0 -42
  313. package/dist/clients/dispatch/rules/placeholder-comments.js +0 -40
  314. package/dist/clients/dispatch/rules/unsafe-boundary.js +0 -126
  315. package/dist/clients/dispatch/runner-context.js +0 -52
  316. package/dist/clients/dispatch/runners/actionlint.js +0 -113
  317. package/dist/clients/dispatch/runners/ast-grep-napi.js +0 -1196
  318. package/dist/clients/dispatch/runners/biome-check.js +0 -283
  319. package/dist/clients/dispatch/runners/cpp-check.js +0 -236
  320. package/dist/clients/dispatch/runners/credo.js +0 -80
  321. package/dist/clients/dispatch/runners/cue-vet.js +0 -398
  322. package/dist/clients/dispatch/runners/dart-analyze.js +0 -202
  323. package/dist/clients/dispatch/runners/detekt.js +0 -169
  324. package/dist/clients/dispatch/runners/dotnet-build.js +0 -159
  325. package/dist/clients/dispatch/runners/elixir-check.js +0 -210
  326. package/dist/clients/dispatch/runners/eslint.js +0 -154
  327. package/dist/clients/dispatch/runners/fact-rules.js +0 -29
  328. package/dist/clients/dispatch/runners/fish-indent.js +0 -69
  329. package/dist/clients/dispatch/runners/gleam-check.js +0 -87
  330. package/dist/clients/dispatch/runners/go-vet.js +0 -90
  331. package/dist/clients/dispatch/runners/golangci-lint.js +0 -120
  332. package/dist/clients/dispatch/runners/hadolint.js +0 -79
  333. package/dist/clients/dispatch/runners/helm-lint.js +0 -171
  334. package/dist/clients/dispatch/runners/helm-render.js +0 -940
  335. package/dist/clients/dispatch/runners/htmlhint.js +0 -108
  336. package/dist/clients/dispatch/runners/index.js +0 -108
  337. package/dist/clients/dispatch/runners/javac.js +0 -89
  338. package/dist/clients/dispatch/runners/ktlint.js +0 -136
  339. package/dist/clients/dispatch/runners/lsp.js +0 -378
  340. package/dist/clients/dispatch/runners/markdownlint.js +0 -160
  341. package/dist/clients/dispatch/runners/mypy.js +0 -101
  342. package/dist/clients/dispatch/runners/oxlint.js +0 -398
  343. package/dist/clients/dispatch/runners/php-lint.js +0 -62
  344. package/dist/clients/dispatch/runners/phpstan.js +0 -120
  345. package/dist/clients/dispatch/runners/prisma-validate.js +0 -62
  346. package/dist/clients/dispatch/runners/psscriptanalyzer.js +0 -445
  347. package/dist/clients/dispatch/runners/pyright.js +0 -169
  348. package/dist/clients/dispatch/runners/rubocop.js +0 -90
  349. package/dist/clients/dispatch/runners/ruff.js +0 -89
  350. package/dist/clients/dispatch/runners/rust-clippy.js +0 -251
  351. package/dist/clients/dispatch/runners/shellcheck.js +0 -169
  352. package/dist/clients/dispatch/runners/shfmt.js +0 -102
  353. package/dist/clients/dispatch/runners/spellcheck.js +0 -121
  354. package/dist/clients/dispatch/runners/spotbugs.js +0 -259
  355. package/dist/clients/dispatch/runners/sqlfluff.js +0 -174
  356. package/dist/clients/dispatch/runners/stylelint.js +0 -158
  357. package/dist/clients/dispatch/runners/swiftlint.js +0 -154
  358. package/dist/clients/dispatch/runners/taplo.js +0 -168
  359. package/dist/clients/dispatch/runners/terragrunt.js +0 -168
  360. package/dist/clients/dispatch/runners/tflint.js +0 -110
  361. package/dist/clients/dispatch/runners/tree-sitter.js +0 -620
  362. package/dist/clients/dispatch/runners/trivy-config.js +0 -247
  363. package/dist/clients/dispatch/runners/utils/availability-policy.js +0 -496
  364. package/dist/clients/dispatch/runners/utils/candidate-probe.js +0 -90
  365. package/dist/clients/dispatch/runners/utils/diagnostic-parsers.js +0 -85
  366. package/dist/clients/dispatch/runners/utils/lazy-installer.js +0 -274
  367. package/dist/clients/dispatch/runners/utils/runner-helpers.js +0 -1701
  368. package/dist/clients/dispatch/runners/utils/spawn-outcome.js +0 -101
  369. package/dist/clients/dispatch/runners/utils/tool-failure.js +0 -235
  370. package/dist/clients/dispatch/runners/utils/toolchain-availability.js +0 -169
  371. package/dist/clients/dispatch/runners/utils.js +0 -15
  372. package/dist/clients/dispatch/runners/vale.js +0 -116
  373. package/dist/clients/dispatch/runners/yaml-rule-parser.js +0 -242
  374. package/dist/clients/dispatch/runners/yamllint.js +0 -85
  375. package/dist/clients/dispatch/runners/zig-check.js +0 -91
  376. package/dist/clients/dispatch/suppress-writer.js +0 -69
  377. package/dist/clients/dispatch/tool-profile.js +0 -30
  378. package/dist/clients/dispatch/types.js +0 -21
  379. package/dist/clients/dispatch/utils/format-utils.js +0 -45
  380. package/dist/clients/dispatch/utils/lsp-diagnostics.js +0 -35
  381. package/dist/clients/disposition-logger.js +0 -32
  382. package/dist/clients/disposition-publish.js +0 -124
  383. package/dist/clients/durable-store.js +0 -97
  384. package/dist/clients/effective-config.js +0 -413
  385. package/dist/clients/env-utils.js +0 -83
  386. package/dist/clients/error-class.js +0 -23
  387. package/dist/clients/eval-timestamp.js +0 -17
  388. package/dist/clients/event-loop-hold.js +0 -274
  389. package/dist/clients/event-loop-monitor.js +0 -250
  390. package/dist/clients/extension-log.js +0 -504
  391. package/dist/clients/extension-mode.js +0 -73
  392. package/dist/clients/feature-hints.js +0 -103
  393. package/dist/clients/file-kinds.js +0 -412
  394. package/dist/clients/file-role.js +0 -134
  395. package/dist/clients/file-time.js +0 -160
  396. package/dist/clients/file-utils.js +0 -1032
  397. package/dist/clients/finding-delivery-gate.js +0 -463
  398. package/dist/clients/finding-identity.js +0 -88
  399. package/dist/clients/fix-worklog.js +0 -103
  400. package/dist/clients/format-events-publish.js +0 -343
  401. package/dist/clients/format-service.js +0 -222
  402. package/dist/clients/formatters-lazy.js +0 -9
  403. package/dist/clients/formatters.js +0 -1994
  404. package/dist/clients/freshness-cadence.js +0 -17
  405. package/dist/clients/freshness.js +0 -38
  406. package/dist/clients/generated-artifacts.js +0 -394
  407. package/dist/clients/generation-guard.js +0 -215
  408. package/dist/clients/git-guard.js +0 -923
  409. package/dist/clients/git-tracked-ignore.js +0 -243
  410. package/dist/clients/gitleaks-client.js +0 -509
  411. package/dist/clients/go-client.js +0 -104
  412. package/dist/clients/govulncheck-client.js +0 -605
  413. package/dist/clients/gradle-ktfmt-style.js +0 -252
  414. package/dist/clients/grammar-source.js +0 -465
  415. package/dist/clients/gzip-stage-write.js +0 -135
  416. package/dist/clients/hashline-anchor.js +0 -424
  417. package/dist/clients/hook-budgets.js +0 -76
  418. package/dist/clients/host-edit-normalize.js +0 -140
  419. package/dist/clients/host-ports.js +0 -39
  420. package/dist/clients/indent-retarget.js +0 -154
  421. package/dist/clients/install-diagnostics.js +0 -143
  422. package/dist/clients/installer/index.js +0 -5167
  423. package/dist/clients/installer/managed-tool-refresh-session.js +0 -58
  424. package/dist/clients/installer/managed-tool-refresh.js +0 -783
  425. package/dist/clients/instance-reaper-state.js +0 -7
  426. package/dist/clients/instance-reaper.js +0 -1137
  427. package/dist/clients/instance-registry-lock.js +0 -145
  428. package/dist/clients/instance-registry.js +0 -773
  429. package/dist/clients/jscpd-client.js +0 -370
  430. package/dist/clients/json-cache-read.js +0 -65
  431. package/dist/clients/knip-client.js +0 -788
  432. package/dist/clients/language-policy.js +0 -252
  433. package/dist/clients/language-profile.js +0 -361
  434. package/dist/clients/language-registry.js +0 -603
  435. package/dist/clients/latency-logger.js +0 -719
  436. package/dist/clients/lazy-import.js +0 -21
  437. package/dist/clients/ledger-bounds.js +0 -54
  438. package/dist/clients/lens-config.js +0 -346
  439. package/dist/clients/lens-engine.js +0 -358
  440. package/dist/clients/lens-events.js +0 -125
  441. package/dist/clients/lens-flag-registry.js +0 -467
  442. package/dist/clients/lens-map.js +0 -1156
  443. package/dist/clients/live-bus-emitter.js +0 -74
  444. package/dist/clients/log-cleanup.js +0 -222
  445. package/dist/clients/lsp/aggregation.js +0 -178
  446. package/dist/clients/lsp/cascade-tier.js +0 -421
  447. package/dist/clients/lsp/client.js +0 -4465
  448. package/dist/clients/lsp/config.js +0 -689
  449. package/dist/clients/lsp/diagnostic-binding.js +0 -225
  450. package/dist/clients/lsp/document-drift.js +0 -467
  451. package/dist/clients/lsp/edits.js +0 -1219
  452. package/dist/clients/lsp/index.js +0 -8305
  453. package/dist/clients/lsp/inferred-project.js +0 -216
  454. package/dist/clients/lsp/jvm-runtime.js +0 -298
  455. package/dist/clients/lsp/language.js +0 -63
  456. package/dist/clients/lsp/launch.js +0 -725
  457. package/dist/clients/lsp/lombok.js +0 -158
  458. package/dist/clients/lsp/path-utils.js +0 -5
  459. package/dist/clients/lsp/pending-aux-coverage.js +0 -251
  460. package/dist/clients/lsp/position-encoding.js +0 -61
  461. package/dist/clients/lsp/ruby-drive-dirs.js +0 -83
  462. package/dist/clients/lsp/server.js +0 -3209
  463. package/dist/clients/lsp/session-roots.js +0 -192
  464. package/dist/clients/lsp/spawn-history.js +0 -17
  465. package/dist/clients/lsp/sync-kind.js +0 -42
  466. package/dist/clients/lsp/tsserver-sync.js +0 -332
  467. package/dist/clients/lsp/wait-policy/capability-snapshot.js +0 -1
  468. package/dist/clients/lsp/wait-policy/classification.js +0 -85
  469. package/dist/clients/lsp/wait-policy/index.js +0 -10
  470. package/dist/clients/lsp/wait-policy/strategies.js +0 -303
  471. package/dist/clients/lsp/watch-queue.js +0 -61
  472. package/dist/clients/lsp/workspace-diagnostics-cache.js +0 -639
  473. package/dist/clients/lsp/workspace-diagnostics-session.js +0 -30
  474. package/dist/clients/lsp/workspace-sweep-hold.js +0 -184
  475. package/dist/clients/lsp-budget.js +0 -186
  476. package/dist/clients/lsp-document-symbols.js +0 -110
  477. package/dist/clients/lsp-lazy.js +0 -9
  478. package/dist/clients/lsp-mutation.js +0 -396
  479. package/dist/clients/lsp-status.js +0 -59
  480. package/dist/clients/map-with-concurrency.js +0 -40
  481. package/dist/clients/mcp/analyze.js +0 -420
  482. package/dist/clients/mcp/host-shim.js +0 -31
  483. package/dist/clients/mcp/ipc.js +0 -335
  484. package/dist/clients/mcp/review.js +0 -151
  485. package/dist/clients/mcp/session.js +0 -412
  486. package/dist/clients/memory-sampler.js +0 -208
  487. package/dist/clients/message-end-attribution.js +0 -30
  488. package/dist/clients/metrics-client.js +0 -107
  489. package/dist/clients/metrics-history.js +0 -327
  490. package/dist/clients/middle-man-analysis.js +0 -263
  491. package/dist/clients/model-provider.js +0 -53
  492. package/dist/clients/module-report-lsp.js +0 -189
  493. package/dist/clients/module-report.js +0 -2150
  494. package/dist/clients/mutating-tool.js +0 -651
  495. package/dist/clients/mutation-attribution.js +0 -368
  496. package/dist/clients/mutation-bridge.js +0 -240
  497. package/dist/clients/ndjson-logger.js +0 -734
  498. package/dist/clients/observed-mutation-sources.js +0 -101
  499. package/dist/clients/observed-mutation.js +0 -1253
  500. package/dist/clients/oldtext-autopatch.js +0 -128
  501. package/dist/clients/opaque-mutation-scan.js +0 -496
  502. package/dist/clients/opengrep-client.js +0 -328
  503. package/dist/clients/opengrep-config.js +0 -76
  504. package/dist/clients/package-manager.js +0 -607
  505. package/dist/clients/package-root.js +0 -38
  506. package/dist/clients/partial-edit-apply.js +0 -439
  507. package/dist/clients/path-attribution-telemetry.js +0 -43
  508. package/dist/clients/path-keyed-map.js +0 -108
  509. package/dist/clients/path-utils.js +0 -1244
  510. package/dist/clients/performance-report.js +0 -331
  511. package/dist/clients/persist-debounce.js +0 -70
  512. package/dist/clients/persistent-reverify.js +0 -271
  513. package/dist/clients/php-cs-fixer-config.js +0 -119
  514. package/dist/clients/pipeline.js +0 -1425
  515. package/dist/clients/post-autofix-notice.js +0 -37
  516. package/dist/clients/print-mode.js +0 -21
  517. package/dist/clients/probe-home-state.js +0 -228
  518. package/dist/clients/process-bridge.js +0 -66
  519. package/dist/clients/process-singletons.js +0 -210
  520. package/dist/clients/process-snapshot.js +0 -68
  521. package/dist/clients/project-changes.js +0 -181
  522. package/dist/clients/project-conventions.js +0 -171
  523. package/dist/clients/project-diagnostics/cache.js +0 -137
  524. package/dist/clients/project-diagnostics/extractors.js +0 -109
  525. package/dist/clients/project-diagnostics/fresh-fetch.js +0 -650
  526. package/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +0 -118
  527. package/dist/clients/project-diagnostics/runner-adapters/dead-code.js +0 -47
  528. package/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +0 -40
  529. package/dist/clients/project-diagnostics/runner-adapters/govulncheck.js +0 -34
  530. package/dist/clients/project-diagnostics/runner-adapters/jscpd.js +0 -38
  531. package/dist/clients/project-diagnostics/runner-adapters/knip.js +0 -47
  532. package/dist/clients/project-diagnostics/runner-adapters/madge.js +0 -48
  533. package/dist/clients/project-diagnostics/runner-adapters/opengrep.js +0 -40
  534. package/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +0 -127
  535. package/dist/clients/project-diagnostics/runner-adapters/trivy.js +0 -81
  536. package/dist/clients/project-diagnostics/scanner.js +0 -520
  537. package/dist/clients/project-diagnostics/types.js +0 -1
  538. package/dist/clients/project-lens-config.js +0 -799
  539. package/dist/clients/project-report.js +0 -701
  540. package/dist/clients/project-scale.js +0 -237
  541. package/dist/clients/project-scan-policy.js +0 -11
  542. package/dist/clients/project-snapshot-fingerprint.js +0 -48
  543. package/dist/clients/project-snapshot-persist-worker.js +0 -20
  544. package/dist/clients/project-snapshot.js +0 -1653
  545. package/dist/clients/project-trust.js +0 -181
  546. package/dist/clients/python-environment.js +0 -217
  547. package/dist/clients/python-provenance.js +0 -639
  548. package/dist/clients/quiet-window-config.js +0 -47
  549. package/dist/clients/quiet-window.js +0 -236
  550. package/dist/clients/read-bridge.js +0 -139
  551. package/dist/clients/read-expansion.js +0 -266
  552. package/dist/clients/read-guard-logger.js +0 -251
  553. package/dist/clients/read-guard-tool-lines.js +0 -1306
  554. package/dist/clients/read-guard.js +0 -1561
  555. package/dist/clients/recent-touches.js +0 -240
  556. package/dist/clients/redact/secrets.js +0 -449
  557. package/dist/clients/resource-sampler.js +0 -628
  558. package/dist/clients/reverse-deps.js +0 -270
  559. package/dist/clients/review-graph/builder.js +0 -5118
  560. package/dist/clients/review-graph/format.js +0 -33
  561. package/dist/clients/review-graph/git-identity.js +0 -157
  562. package/dist/clients/review-graph/import-resolvers.js +0 -481
  563. package/dist/clients/review-graph/persist-worker.js +0 -10
  564. package/dist/clients/review-graph/query.js +0 -244
  565. package/dist/clients/review-graph/revision-drift.js +0 -21
  566. package/dist/clients/review-graph/service.js +0 -96
  567. package/dist/clients/review-graph/shared-extraction-ir.js +0 -82
  568. package/dist/clients/review-graph/symbol-id.js +0 -103
  569. package/dist/clients/review-graph/tsconfig-paths.js +0 -299
  570. package/dist/clients/review-graph/types.js +0 -1
  571. package/dist/clients/review-graph/workspace-modules.js +0 -449
  572. package/dist/clients/review-graph-logger.js +0 -81
  573. package/dist/clients/ruff-client.js +0 -152
  574. package/dist/clients/rules-scanner.js +0 -131
  575. package/dist/clients/run-duration.js +0 -55
  576. package/dist/clients/runtime-agent-end.js +0 -746
  577. package/dist/clients/runtime-config.js +0 -77
  578. package/dist/clients/runtime-context.js +0 -211
  579. package/dist/clients/runtime-coordinator.js +0 -1290
  580. package/dist/clients/runtime-session.js +0 -2485
  581. package/dist/clients/runtime-tool-call.js +0 -1284
  582. package/dist/clients/runtime-tool-result.js +0 -2034
  583. package/dist/clients/runtime-turn.js +0 -3600
  584. package/dist/clients/rust-client.js +0 -97
  585. package/dist/clients/safe-spawn.js +0 -2166
  586. package/dist/clients/sanitize.js +0 -286
  587. package/dist/clients/scan-utils.js +0 -25
  588. package/dist/clients/scratch-tree-policy.js +0 -165
  589. package/dist/clients/search-read-registration.js +0 -94
  590. package/dist/clients/secret-findings.js +0 -114
  591. package/dist/clients/security-scan-client.js +0 -352
  592. package/dist/clients/session-event-guard.js +0 -297
  593. package/dist/clients/session-lifecycle.js +0 -484
  594. package/dist/clients/session-start-observability.js +0 -94
  595. package/dist/clients/session-state-store.js +0 -101
  596. package/dist/clients/session-summary.js +0 -15
  597. package/dist/clients/sessionstart-logger.js +0 -27
  598. package/dist/clients/sg-runner.js +0 -876
  599. package/dist/clients/sgconfig.js +0 -347
  600. package/dist/clients/shared-checkout-guard.js +0 -338
  601. package/dist/clients/single-flight.js +0 -158
  602. package/dist/clients/situational-tool-telemetry.js +0 -108
  603. package/dist/clients/skills-resolver.js +0 -141
  604. package/dist/clients/slow-fs.js +0 -138
  605. package/dist/clients/smells-rollup.js +0 -231
  606. package/dist/clients/source-filter.js +0 -596
  607. package/dist/clients/source-walker.js +0 -211
  608. package/dist/clients/spawn-output-cap.js +0 -37
  609. package/dist/clients/spawn-timeout-cooldown.js +0 -110
  610. package/dist/clients/stale-marker.js +0 -17
  611. package/dist/clients/startup-scan.js +0 -400
  612. package/dist/clients/startup-timing.js +0 -130
  613. package/dist/clients/string-utils.js +0 -33
  614. package/dist/clients/subagent-mode.js +0 -111
  615. package/dist/clients/symbol-containment.js +0 -24
  616. package/dist/clients/symbol-types.js +0 -5
  617. package/dist/clients/test-runner-client.js +0 -2507
  618. package/dist/clients/test-runner-delivery.js +0 -287
  619. package/dist/clients/todo-scanner.js +0 -229
  620. package/dist/clients/tool-agreement.js +0 -423
  621. package/dist/clients/tool-config.js +0 -249
  622. package/dist/clients/tool-cwd.js +0 -270
  623. package/dist/clients/tool-definition.js +0 -47
  624. package/dist/clients/tool-event.js +0 -105
  625. package/dist/clients/tool-policy.js +0 -2755
  626. package/dist/clients/tool-probe.js +0 -53
  627. package/dist/clients/tool-render.js +0 -156
  628. package/dist/clients/tool-set-policy.js +0 -118
  629. package/dist/clients/tree-sitter-cache.js +0 -364
  630. package/dist/clients/tree-sitter-client.js +0 -4134
  631. package/dist/clients/tree-sitter-logger.js +0 -100
  632. package/dist/clients/tree-sitter-navigator.js +0 -269
  633. package/dist/clients/tree-sitter-query-loader.js +0 -569
  634. package/dist/clients/tree-sitter-shared.js +0 -158
  635. package/dist/clients/tree-sitter-symbol-extractor.js +0 -1265
  636. package/dist/clients/trivy-client.js +0 -467
  637. package/dist/clients/tui-fit.js +0 -50
  638. package/dist/clients/turn-context.js +0 -52
  639. package/dist/clients/turn-summary-render.js +0 -72
  640. package/dist/clients/turn-summary.js +0 -132
  641. package/dist/clients/typos-config.js +0 -29
  642. package/dist/clients/user-notify.js +0 -51
  643. package/dist/clients/vanished-instance-marker.js +0 -57
  644. package/dist/clients/warm-attach.js +0 -246
  645. package/dist/clients/widget-state.js +0 -1677
  646. package/dist/clients/word-index-logger.js +0 -49
  647. package/dist/clients/word-index-store.js +0 -459
  648. package/dist/clients/word-index.js +0 -2080
  649. package/dist/clients/workspace-topology.js +0 -389
  650. package/dist/clients/write-ordering-guard.js +0 -65
  651. package/dist/clients/zizmor-config.js +0 -327
  652. package/dist/i18n.js +0 -69
  653. package/dist/mcp/build-staleness.js +0 -124
  654. package/dist/scripts/lib/process-scan.mjs +0 -583
  655. package/dist/scripts/lib/skills-predicate.mjs +0 -129
  656. package/dist/tools/activate-tools.js +0 -87
  657. package/dist/tools/ast-grep-outline.js +0 -137
  658. package/dist/tools/ast-grep-replace.js +0 -244
  659. package/dist/tools/ast-grep-search.js +0 -762
  660. package/dist/tools/effective-config.js +0 -90
  661. package/dist/tools/lens-diagnostic-mark.js +0 -375
  662. package/dist/tools/lens-diagnostics.js +0 -2544
  663. package/dist/tools/lsp-diagnostics.js +0 -1634
  664. package/dist/tools/lsp-navigation.js +0 -1367
  665. package/dist/tools/lsp-structured-output.js +0 -294
  666. package/dist/tools/module-report.js +0 -382
  667. package/dist/tools/project-report.js +0 -86
  668. package/dist/tools/render-compact.js +0 -374
  669. package/dist/tools/scan-progress.js +0 -53
  670. package/dist/tools/shared.js +0 -29
  671. package/dist/tools/symbol-search.js +0 -155
@@ -0,0 +1,31 @@
1
+ # ADR 0006: benchmark before a derived-state cache
2
+
3
+ ## Status
4
+
5
+ Accepted — 2026-09-23
6
+
7
+ ## Context
8
+
9
+ The staleness arc fixed caches whose invalidation keys could not express the
10
+ truth. For signatures, line counts, hashes, and import graphs, a bounded
11
+ request-local recompute can remove that invalidation surface. Tool-run caches
12
+ are a separate class because the expensive operation is the tool run.
13
+
14
+ ## Decision
15
+
16
+ Do not add a cross-request derived-state cache until a fresh-process benchmark
17
+ shows that request-local recomputation is the cost. A justified cache carries
18
+ the generation from which it was derived.
19
+
20
+ ## Consequences
21
+
22
+ Cheap derived state has no stale cache to invalidate. Any future cache needs a
23
+ benchmark with a control row, explicit freshness axes, and a measured reason
24
+ that the request-local pass is insufficient.
25
+
26
+ ## Links
27
+
28
+ - Catalog shape: `AGENTS.md` shape 51.
29
+ - Issue: #1644 closure decision, 2026-09-22.
30
+ - PR: #3253.
31
+
@@ -0,0 +1,38 @@
1
+ # ADR 0007: end-to-end witness per seam slice
2
+
3
+ ## Status
4
+
5
+ Accepted — 2026-09-23
6
+
7
+ ## Context
8
+
9
+ Seam umbrellas #1892, #1816, #1193, #1894, and #1844 need evidence that
10
+ survives adapter wiring and records both what the model receives and what the
11
+ degradation ledger recorded. The #3247 round-2 adapter tests establish the
12
+ shape through the pi and MCP turn-end surfaces.
13
+
14
+ ## Decision
15
+
16
+ Every slice under those seam umbrellas adds one witness test through the real
17
+ host entry: pi `index.ts` `turn_end` to the runtime-context message, or the MCP
18
+ turn-end entry in `clients/mcp/session.ts`. The test commits the rendered
19
+ context message and degradation-ledger rows as a golden fixture under
20
+ `tests/fixtures/witness/<slice>/` and diffs it on every run. The witness is
21
+ owned by the #1605 lane umbrella. Process boundaries, including LSP servers
22
+ and tool binaries, use the real-wire fake server rather than a module mock.
23
+
24
+ ## Consequences
25
+
26
+ Witnesses are the verifiable, repeatable artifact for each seam slice and
27
+ expose adapter drift at the host boundary. A witness is not the sole mechanism
28
+ at a process boundary: a module mock cannot prove argv, wire framing, process
29
+ lifecycle, or tool output, so those boundaries require the real-wire fake
30
+ server. In-process stores, sinks, coordinators, and dispatchers remain real.
31
+
32
+ ## Links
33
+
34
+ - Umbrella: #1605.
35
+ - Seam slices: #1892, #1816, #1193, #1894, #1844.
36
+ - Shape: `tests/index-3246-turn-end-delivery.test.ts` and
37
+ `tests/clients/mcp/session-inline-blocker-dispositions.test.ts`.
38
+ - Adapter evidence: #3247 round 2.
@@ -0,0 +1,165 @@
1
+ # ADR 0008: one `TurnEndLane` interface, and what stays in the composer
2
+
3
+ ## Status
4
+
5
+ Accepted — 2026-09-23
6
+
7
+ ## Context
8
+
9
+ `clients/runtime-turn.ts` was 4,654 lines with fourteen delivery lanes written
10
+ inline in `handleTurnEnd`. Each lane read its own store, applied its own
11
+ freshness/disposition policy, and formatted its own section into
12
+ `blockerParts`/`advisoryParts`, so the composer stated every lane's rules and no
13
+ lane could be read, tested or changed on its own. #1892's third slice deepens
14
+ the composer into a thin orchestrator over lane modules that share ONE
15
+ interface, one lane per round, with no agent-facing change.
16
+
17
+ The constraint that shapes the interface is #3264's fold: the turn-end scanner
18
+ stores share ONE `gateFindingsByPathFreshness` call, so a path two stores cite
19
+ is `stat`'d once, spends one stat budget, and writes one bounded decision
20
+ record per delivery instead of up to six. A lane that gated itself would
21
+ re-split that pass the moment a second lane existed.
22
+
23
+ The second constraint is the delivery-surface registry
24
+ (`clients/finding-delivery-gate.ts`): its `@delivery-surface:` seam scan reads
25
+ exactly `clients/runtime-turn.ts` and `tools/lens-diagnostics.ts`. Code that
26
+ renders an agent-facing section from a file that scan does not read would be an
27
+ unregistered surface, invisible to the mechanism built to enumerate them.
28
+
29
+ ## Decision
30
+
31
+ **The interface** (`clients/turn-end/lane.ts`) is three stages, and nothing else — no lane id, because nothing would read one:
32
+
33
+ | Stage | Signature | Owns |
34
+ |---|---|---|
35
+ | collect | `collect(ctx) → Promise<S>` where `S` maps STORE name → `FindingFreshnessSource` | which caches to read, classification, the per-store `citedPath`/`scannedAt`/`onMissing` policy. Structured rows with source identity, never a rendered string. Calls no gate. |
36
+ | gate | `gate(gates: TurnEndLaneGates<S>, ctx) → Kept` | the policy the shared pass cannot apply: dispositions through `filterFindingsByDisposition` (the seam in `clients/dispatch/finding-policy.ts`, ADR 0004), plus any per-store existence/lifecycle contract. `Kept` is lane-private. |
37
+ | render | `render(kept, ctx) → TurnEndLaneParts` | the sections, the display cap, the tier each section belongs to, the per-store suppressed counts, and the location keys it delivered. Returns sections; never pushes. `TurnEndLaneParts` carries a field per tier the composer actually pushes and no others — an unread field is a side channel that drops a lane's output, so the advisory tier joins the type with the lane that renders one. |
38
+
39
+ `TurnEndLaneContext` is the whole window a lane gets onto the turn: `cwd`, the
40
+ hook's `signal`, `readScannerCache` (memoized per turn by the composer) and
41
+ `peekActionableWarnings`.
42
+
43
+ **Writers by axis** — what the composer keeps, and why it cannot be a lane's:
44
+
45
+ | Axis | Owner | Why |
46
+ |---|---|---|
47
+ | Path-freshness pass (stat memo, stat budget, `finding_dead_path_drop` / `finding_stale_line_demote` rows) | composer | A cross-lane resource. Per-lane gating is #3264 undone: N stat passes, N budgets, N records for one filesystem fact. A lane only DECLARES sources. |
48
+ | One read per scanner store per turn | composer (`readScannerCache` memo) | The trivy store is read by the secrets lane and by the CVE/license tiers. Two envelopes of one store in one delivery is the parallel-store shape, and the TTL boundary can fall between the reads. |
49
+ | Disposition application | lane | Per-store anchor identity; only the lane knows which `ProjectDiagnostic` adapter anchors its rows. |
50
+ | Tier order, `blockerParts`/`staleSecretParts`/`advisoryParts` accumulation, the `@delivery-surface:` tags | composer | The tags are what enumerates the surfaces; the scan reads the composer. |
51
+ | Suppressed-by-disposition notice | composer, fed per lane | One bounded notice per turn (#1616), with per-lane attribution. |
52
+ | Turn signature dedupe, `turn-end-findings` cache write, git-guard record, message cap, turn telemetry | composer | Delivery-event properties of the whole turn, not of one lane. |
53
+ | Delivered location keys | lane produces, composer consumes | One secret is reported once across tiers (#131 Mode 3). |
54
+
55
+ **Registry evidence.** A surface whose render moved into a lane keeps its
56
+ registry `file` as `clients/runtime-turn.ts`, because that is where its tagged
57
+ push seam and its gate call live. Its evidence literal is repinned from the
58
+ partition it used to read (`gitleaksGate.live,`) to the gated store object the
59
+ composer hands the lane (`gitleaksGate,`). That is a weaker pin — it no longer
60
+ states which partition feeds which tier — and the loss is recorded rather than
61
+ hidden: the live/stale split is a lane rule now, pinned behaviourally by
62
+ `tests/clients/runtime-turn-finding-freshness.test.ts` and the witness goldens.
63
+ What the pin still proves is what the registry exists for: the rows came out of
64
+ a real gate call, not a hand-built object.
65
+
66
+ **Lanes that do not fit, and are not being made to.** Test-runner findings
67
+ (generation/retirement state, a verdict rather than diagnostics, its own
68
+ provenance validation at read), the git-guard latch (a durable second
69
+ writer/consumer with a commit-gate audience) and the agent nudge (session
70
+ read/edit relevance, no findings and no freshness axis at all) stay outside
71
+ this interface. So do the package-pinned trivy CVE/license tiers: they have no
72
+ cited path, so their `collect` would declare no freshness source and their
73
+ honesty mechanism is the age label, not the gate.
74
+
75
+ **One lane is one delivery contract, not one store.** The secrets lane
76
+ (`clients/turn-end/lanes/secrets.ts`) owns BOTH secret stores, because #131
77
+ Mode 3 collapses gitleaks, trivy-secrets and ast-grep by LOCATION into one
78
+ blocker section with combined provenance, and the demoted tier merges the same
79
+ two stores. A "gitleaks-only" lane would leave every rendering rule in the
80
+ composer and move only a cache read.
81
+
82
+ ## Amendment — 2026-09-23: the advisory tier joins `TurnEndLaneParts`
83
+
84
+ `TurnEndLaneParts` gains ONE field, `advisoryParts?: readonly string[]`, with
85
+ the govulncheck lane (`clients/turn-end/lanes/govulncheck.ts`). This is the
86
+ amendment the Decision above anticipated ("the advisory tier joins the type
87
+ with the lane that renders one"), not a widening of the rule.
88
+
89
+ **Why it was withheld until now.** The rule is "a field per tier the composer
90
+ PUSHES, and no others", because a field the composer does not read is a side
91
+ channel that silently drops a lane's whole output (AGENTS.md shape 5). The
92
+ secrets lane renders no advisory, so an `advisoryParts` shipped with the
93
+ interface would have been exactly that: a slot a later lane could fill and lose.
94
+ The field, the composer's push and the surface's registry id therefore move
95
+ together, in one round, as one claim.
96
+
97
+ **What the composer pushes it into.** `handleTurnEnd`'s `advisoryParts` array
98
+ (`clients/runtime-turn.ts`), under the existing tag
99
+ `// @delivery-surface: runtime-turn:govulncheck-advisory`, at the same position
100
+ in the tier order the inline block occupied. The tag is what makes the tier a
101
+ registered delivery surface rather than a string, and
102
+ `tests/config/turn-end-lane-boundaries.test.ts` already listed `advisoryParts`
103
+ in the tier-push rule it reds on — so a lane that pushes its own advisory was
104
+ forbidden before the field existed, and still is.
105
+
106
+ **What did NOT change.** Still three stages; still no lane id; still no fourth
107
+ method. The `runtime-turn:govulncheck-advisory` registry entry keeps its `file`,
108
+ its `gated` mode and its evidence literal `scannerGates.govulncheck` unchanged
109
+ — the composer still binds that gate arm itself and hands it to the lane, so
110
+ unlike the secrets repin nothing was weakened here.
111
+
112
+ **The interface question this lane was asked and did not need to answer.** The
113
+ brief asked how a lane declares "no freshness source" honestly, since a
114
+ package-pinned row (trivy CVE/license) has no path to stat. The state table is:
115
+
116
+ | Lane's store | has a cited path | honesty mechanism | fits the interface today |
117
+ |---|---|---|---|
118
+ | govulncheck | yes (first trace frame with a filename) | the shared gate, `onMissing: "demote"` | yes — this round |
119
+ | gitleaks / trivy-secrets | yes (`finding.file`) | the shared gate, `onMissing: "drop"` | yes — #3269 |
120
+ | trivy CVE / license | no — pinned by package, not by file | `formatCacheAgeLabel`, the registry's `labeled` mode | NO |
121
+ | a finding whose `citedPath` returns `undefined` for SOME rows | mixed | the gate leaves the uncited row live and gates the rest | yes — already handled per row |
122
+
123
+ The last row is the one that matters for "no freshness source": the gate already
124
+ takes `citedPath` returning `undefined` as "leave live", per FINDING, so a lane
125
+ with a partially-uncited store needs nothing new (the govulncheck witness pins
126
+ it: `GO-2026-0103` has an empty trace and renders by module). A store where
127
+ EVERY row is uncited is a different animal — it is not a gated lane at all, it
128
+ is a `labeled` one, and giving it a `sources: {}` `collect` would let it pass
129
+ the composer's gate with an empty declaration and look gated in the registry
130
+ while nothing checked anything. That is the second exception the brief said not
131
+ to bend the lane around, so it is not added: the labeled lanes need a `label`
132
+ stage (an age string the composer renders into the header) before they can be
133
+ extracted, and that is the design decision of the round that extracts one.
134
+
135
+ ## Consequences
136
+
137
+ - The composer no longer states a govulncheck rule (2026-09-23): 4,438 →
138
+ 4,403 lines, and the six rules the block held (the `demote`/first-frame
139
+ freshness declaration, the both-arm disposition anchor, the stale-line
140
+ withholding and marker, the module/package fallback, the fix hint and the
141
+ display cap) are stated once, in the lane.
142
+ - The composer no longer states a secrets rule: 4,654 → 4,438 lines, and the
143
+ ten rules the block used to hold (cache key, classification budget and
144
+ fail-open, blocking filter, freshness declaration, two disposition anchors
145
+ over both arms, location dedupe, ast-grep enrichment, display cap, both
146
+ preambles, demoted-row identity) are stated once, in the lane.
147
+ - Extracting a lane moves code out from under two mechanisms that read only
148
+ `clients/runtime-turn.ts`, so `tests/config/turn-end-lane-boundaries.test.ts`
149
+ walks `clients/turn-end/` and reds if a lane pushes into a tier or calls the
150
+ freshness gate itself. Both rules name the recurrence they prevent.
151
+ - Registrations move with the code: the `bounded()` call-site registry entry,
152
+ the one-hop unbounded-await pin, and the delivery-surface marker exemption
153
+ all name the lane file now. A lane is a new file every directory-scanning
154
+ governance suite sees.
155
+ - The next lanes are extracted one per round against this interface. A lane
156
+ that needs a stage this interface does not have is a finding to report, not a
157
+ fourth method to add quietly.
158
+
159
+ ## Links
160
+
161
+ - Umbrella: #1892. Previous slices: #3264 (the shared freshness pass), #3269
162
+ (this interface and the secrets lane).
163
+ - Witness convention: docs/adr/0007-end-to-end-witness-per-seam-slice.md.
164
+ - Disposition seam: docs/adr/0004-disposition-policy-seam.md.
165
+ - Registry and evidence rules: `clients/finding-delivery-gate.ts`.
@@ -0,0 +1,114 @@
1
+ # ADR 0009: reported-path attribution is one seam, based on the runner cwd
2
+
3
+ ## Status
4
+
5
+ Accepted — 2026-09-23
6
+
7
+ ## Context
8
+
9
+ Every runner that parses a tool's textual or JSON output has to answer one
10
+ question per reported line: *is this diagnostic about the file the dispatcher
11
+ ran me for?* Twelve sites answered it with their own predicate — a bare `===` or
12
+ `!==` over two `path.resolve` results, a `path.resolve` with NO base argument, a
13
+ `path.posix.basename` compare, and two `endsWith` compares. #209 and #3277 are
14
+ the shipped defects of the first two shapes: a spelling that differs only in
15
+ case is the SAME file on Windows and on a case-folding POSIX mount, so the
16
+ compare dropped every finding for the edited file and the run reported clean.
17
+ #3278 measured the population at ~11 and #1193 recorded the fold verdict.
18
+
19
+ The state space, written before the first edit. Left = the path the tool
20
+ printed. Right = `path.resolve(ctx.filePath)`, which is
21
+ `normalizeMapKey`-canonical and absolute by the #2016 invariant.
22
+
23
+ | axis | value | consequence |
24
+ |---|---|---|
25
+ | host folds case | win32 always; POSIX only on a case-folding mount (APFS, `nocase` vfat/ntfs3/cifs) | a `process.platform === "win32"` test is wrong in both directions on APFS. Only the filesystem knows, so the predicate must ask it. |
26
+ | reported spelling | absolute (the tool echoes our argv), relative to the tool's own cwd, relative to a package/base directory it chose, or basename-only | only the tool's OWN cwd is a base the caller can supply; `process.cwd()` is the extension's and is a different directory whenever `resolveRunnerCwd` returns a nested language root. |
27
+ | separators after `path.resolve` | host-native on both sides; a foreign separator survives only embedded in the reported string | separator folding can only MERGE, never split. |
28
+ | symlinked project dir | `pathsEqual` does NOT resolve symlinks on POSIX (`clients/path-utils.ts:181`, deliberate) | a project entered through a directory symlink can still mis-match; that is a property of the shared seam, unchanged by this decision (#3276's recorded output). |
29
+ | purpose | identity test of ONE file, per reported line — not a stored key, not set membership | asks for an equality predicate, not a key derivation. |
30
+
31
+ Candidate seams: `normalizeEphemeralMapKey` is rejected by its own contract
32
+ (`clients/path-utils.ts:488-490` — "never … compared against externally-supplied
33
+ paths where symlink / real-casing resolution actually matters"; the left side is
34
+ literally an external process's output, and it folds case on
35
+ `process.platform === "win32"` only). `normalizeFilePath`/`normalizeMapKey` are
36
+ the right rule in the wrong shape: the caller would still hold the comparison
37
+ and re-derive both keys. A NEW `reportedPathMatchesTarget(reported, { cwd,
38
+ target })` helper fails the deletion test — removing it would put back the same
39
+ single expression at each call site rather than concentrating anything — and it
40
+ would hide the comparison from the #1193 sweep's call-site walk while raising
41
+ the helper count.
42
+
43
+ ## Decision
44
+
45
+ The predicate is `pathsEqual(path.resolve(<the cwd the tool ran in>, reported),
46
+ absTarget)`, written INLINE at each call site. It is not a new helper: it is the
47
+ call shape `clients/dispatch/runners/terragrunt.ts:90`,
48
+ `elixir-check.ts:63` (#3276) and `go-vet.ts:107` (#3277) already use, so this
49
+ decision migrates the remaining members onto an existing seam and adds nothing.
50
+ A parse function that does not receive the runner cwd takes it as a parameter;
51
+ no parse function resolves a reported path against `process.cwd()`.
52
+
53
+ Absence is enforced by `tests/config/reported-path-attribution-sweep.test.ts`, a
54
+ shrink-only census of runner sites that still hold their own predicate.
55
+ `tests/config/path-key-fold-sweep.test.ts` counts folds that EXIST and therefore
56
+ structurally cannot see a member with no fold at all — measured on #3277, where
57
+ mutating `go-vet.ts` to a hand-rolled case fold left that sweep green.
58
+
59
+ A member's fold is admitted only with its premise established: what spelling
60
+ does this tool really emit under OUR invocation? Where the tool echoes the
61
+ absolute path we hand it as argv, the fold is behaviour-preserving and its tests
62
+ say so, rather than feeding a spelling the tool never emits.
63
+
64
+ ## Consequences
65
+
66
+ The path-case rule exists once, in `clients/path-utils.ts`; no runner holds a
67
+ `process.platform` test or a `toLowerCase` for this question. `pathsEqual` costs
68
+ a `realpathSync.native`/`existsSync` per reported line, which is bounded by the
69
+ tool's own output size on a parse path that already allocates per line.
70
+
71
+ Two directions are now pinned per member: the tool's real spelling attaches, and
72
+ a different file's finding does not. On a case-folding host the case-variant
73
+ spelling attaches too, and on a case-sensitive host it must not — asserted from
74
+ the filesystem's own answer, never from `process.platform`.
75
+
76
+ The predicate still cannot see through a directory symlink on POSIX, and a
77
+ runner that needs that must say so at its own call site rather than re-deriving
78
+ a local rule. It also cannot SPLIT a separator: `pathsEqual` folds `\` to `/` on
79
+ every platform (`clients/path-utils.ts:231`), so a POSIX file literally named
80
+ `a\b.gleam` stays merged with `a/b.gleam` after a member's own hand-rolled fold
81
+ is deleted. Deleting the local fold removes a second, divergent copy of the rule;
82
+ it does not change that answer.
83
+
84
+ Two amendments from #3285 / #3286, the two remainders:
85
+
86
+ 1. The CAPTURE is part of this decision, not a detail before it. A tool renders
87
+ its location line however it likes, and `gleam` renders through
88
+ `codespan_reporting`, whose locus line wraps the path in a `┌─` gutter. A
89
+ suffix compare tolerates that decoration and an equality predicate cannot, so
90
+ a member whose reported path arrives decorated moves the decoration out of the
91
+ captured group in the same change — and its premise is a vector generated by
92
+ the upstream RENDERER (`tests/fixtures/gleam-codespan/`), not a transcription
93
+ of it. The same rule covers colour: a tool that may emit SGR codes goes
94
+ through `stripAnsi` before an anchored capture.
95
+ 2. The population is runners AND tool clients (`clients/*-client.ts`). The autofix
96
+ half of a tool lives in its client, `ruff-client.ts` held the same bare `!==`,
97
+ and a detector scoped to `clients/dispatch/runners/**` structurally could not
98
+ see it. Widening cost exactly one non-member registration
99
+ (`clients/test-runner-client.ts`, two self-derived directories).
100
+
101
+ ## Links
102
+
103
+ - Umbrella: #1193 (P3 fold), #3278 (the population).
104
+ - Precedents: #3276 (`elixir-check`), #3277 / PR #3281 (`go-vet`).
105
+ - Shipped defects: #209, #3277.
106
+ - Detector: `tests/config/reported-path-attribution-sweep.test.ts`.
107
+ - Cells: `tests/clients/dispatch/runners/reported-path-attribution.test.ts`.
108
+ - Witness (ADR 0007): `tests/fixtures/witness/runner-outcome-eslint-golangci/golangci-lint-relative-path.txt`.
109
+ - Remainders, both now closed: `gleam-check.ts` (#3285 — its `endsWith` was
110
+ load-bearing for `codespan_reporting`'s gutter) and `clients/ruff-client.ts`
111
+ (#3286 — outside the runner population).
112
+ - Upstream vectors: `tests/fixtures/gleam-codespan/` (gleam v1.18.1 +
113
+ codespan-reporting 0.13.1), `tests/fixtures/ruff-json/` (ruff 0.16.8).
114
+ - Cells for the client half: `tests/clients/ruff-client-reported-path.test.ts`.
@@ -0,0 +1,26 @@
1
+ # Architecture decision records
2
+
3
+ Each record is `NNNN-title.md` and uses the same short shape: number/title,
4
+ status, date, Context, Decision, Consequences, and Links. Records capture a
5
+ settled design decision; observations without a decision remain in the defect
6
+ catalog or issue history.
7
+
8
+ The catalog is the index for defect shapes. A shape that records a decision
9
+ links its ADR in `AGENTS.md`; ADR links point to the catalog shape, the issue
10
+ that supplied the question, and the PR or brief that settled it. Use `refs`
11
+ for work that remains open and `closes` only when its acceptance criteria are
12
+ complete.
13
+
14
+ ## Seed catalog
15
+
16
+ | ADR | Decision | Catalog shape | Status |
17
+ |---|---|---:|---|
18
+ | [0001](0001-stale-advisory-live-arm.md) | Stale advisory arm skips disposition policy; live arm applies it. | 10 | Accepted |
19
+ | [0002](0002-workspace-hash-rendezvous.md) | `workspaceHash` is pure cross-process rendezvous derivation. | 1, 2 | Accepted |
20
+ | [0003](0003-git-guard-latch-writer.md) | Git-guard latch is a separate writer on the durable record. | 24 | Accepted |
21
+ | [0004](0004-disposition-policy-seam.md) | Dispositions fold onto `applyFindingPolicy`; no new store before measured #1892 work. | 10, 26 | Accepted |
22
+ | [0005](0005-tool-availability-enforcement-seam.md) | Tool availability is one seam by enforcement, with migrate-on-touch. | 52 | Accepted |
23
+ | [0006](0006-derived-state-benchmark-first.md) | No cross-request derived-state cache without a fresh-process benchmark. | 51 | Accepted |
24
+ | [0007](0007-end-to-end-witness-per-seam-slice.md) | Every seam slice commits an end-to-end host witness and degradation ledger artifact. | #1605 umbrella; #1892, #1816, #1193, #1894, #1844 | Accepted |
25
+ | [0009](0009-reported-path-attribution.md) | Reported-path attribution is `pathsEqual` against the runner cwd, inline at each call site. | 2, 34, 38; #1193, #3278 | Accepted |
26
+ | [0008](0008-turn-end-lane-interface.md) | One `TurnEndLane` interface; `handleTurnEnd` stays a thin orchestrator over lane modules. | #1892 umbrella; #3264, #3269 | Accepted |
@@ -102,7 +102,7 @@ not clean**:
102
102
 
103
103
  | Label you may see | What it means | What you must NOT do |
104
104
  |---|---|---|
105
- | **`unconfirmed`** | A push-only/silent-on-clean LSP server returned empty; emptiness could not be *proven* clean. | Don't report the file as clean. |
105
+ | **`unconfirmed`** | An LSP result that could not be *proven* clean: a push-only/silent-on-clean server returned empty; an auxiliary scanner did not answer in time; or the file has no project root for a server that needs one (rust-analyzer, csharp-ls/OmniSharp, FSAutocomplete) and the line names the missing marker. | Don't report the file as clean. |
106
106
  | **`cold` (not applicable / unavailable this run)** | A heavyweight analyzer (knip/jscpd/madge/gitleaks/govulncheck/trivy/dead-code) didn't contribute. | Don't fold its silence into "no issues." |
107
107
  | **`partial` / `truncated` / file-cap** | A walk/scan hit a file cap or coverage limit; results are a partial view. | Don't treat as whole-project coverage. |
108
108
  | **`stale`** | A cached diagnostic's file changed on disk since the scan. Secrets findings demote to `🔑 ACTION NEEDED` advisory with the line number withheld, never silently dropped; govulncheck keeps the CVE and drops only the cached line. | Don't trust the stale value or its line number. Re-scan to confirm. |
@@ -128,6 +128,10 @@ is blocking when `semantic === "blocking"`, else it falls back to severity):
128
128
  a blocker does, but it is not "no action required" like an advisory either —
129
129
  the finding is unverified, not dismissed. Re-run a secrets scan to confirm
130
130
  or clear it.
131
+ - **⏱️ Late runner diagnostics** — a slow (collect-later) runner's findings arrive at
132
+ turn end on the advisory channel, so they never gate `git commit`/`git push`;
133
+ when one is blocking it reads "blocking: fix before continuing" instead of
134
+ "no action required", and a runner that timed out or errored says so separately.
131
135
  - **Advisory** — informational (🟡 warnings, 📜 license notes, style/hygiene).
132
136
  Address when relevant; they do not gate completion.
133
137
 
@@ -147,7 +151,9 @@ Don't try to route around it — clear the blockers, then commit. The guard is s
147
151
  pi-lens monitors that you **read a file before editing it** (`clients/read-guard.ts`).
148
152
  Edits fail or warn when:
149
153
 
150
- 1. **Zero-read** — you never read the file this conversation.
154
+ 1. **Zero-read** — you never read the file this conversation, or your write
155
+ record of it expired after 30 idle minutes (the block says "the earlier
156
+ write record ... expired"). Read it again.
151
157
  2. **Stale** — the file changed on disk since you read it (content-hash checked).
152
158
  3. **Out-of-range** — your edit target wasn't covered by any read.
153
159
 
@@ -163,8 +169,11 @@ Helpful mechanics you can rely on:
163
169
 
164
170
  - **Coverage accumulates** across reads — two reads (lines 1–100 and 101–200) together
165
171
  cover a full-file write.
166
- - **Symbol expansion** — small reads (≤ ~60 lines) are silently widened to the
167
- enclosing function/method/class, and coverage is recorded at symbol level.
172
+ - **Symbol expansion** — small reads (≤ 100 lines) are widened to the enclosing
173
+ function/method/class (or Markdown section), and coverage is recorded at
174
+ symbol level. The result starts with a `[pi-lens: read widened ...]` note
175
+ naming the requested and the returned lines; ask for `limit` above 100 for
176
+ the exact range. It is off with the read guard (`--no-read-guard`).
168
177
  - `read_symbol` / `read_enclosing` reads count as edit coverage for that symbol range.
169
178
  - Markdown warns instead of blocking; `.txt`/`.log` are exempt.
170
179
  - Escape hatch (human): `/lens-allow-edit <path>` arms one exemption.
@@ -39,6 +39,48 @@ actually sent: `usage tokens=<n> elapsed-ms=<n> bytes=<n> truncated=<true|false>
39
39
  A rejected call (e.g. MCP's "Unknown or disabled tool") is rendered through the
40
40
  same gate rather than bypassing it.
41
41
 
42
+ **MCP argument handling (#3749).** The MCP `tools/call` dispatcher compares the
43
+ call's argument keys with the `inputSchema` the tool advertises in `tools/list`
44
+ (`findIgnoredArguments`, `mcp/tool-arguments.ts`), once, for every tool. An
45
+ undeclared top-level key is never silently dropped (keys inside a nested
46
+ object argument such as `callHierarchyItem`, `rule` or `flags` are not checked):
47
+
48
+ - the result's first line is ``Ignored unknown argument(s) for <tool>: `key`
49
+ (did you mean `nearest`?). They had no effect on this call.`` (the suggestion
50
+ appears only when a declared key is near), followed by the tool's own result;
51
+ - the result carries `structuredContent: { ignoredArguments: [...],
52
+ ignoredArgumentCount: N }` (at most 8 keys, each cut at 64 characters; the
53
+ count is exact);
54
+ - when an ignored key leaves the call without something it needed, the tool
55
+ does not run and the result is an error whose first line is the same
56
+ sentence, followed by `Not run: ...`. That is the case when a
57
+ schema-`required` input is missing (``Not run: required argument(s) `file`
58
+ missing.``), or when the ignored key is a declared parameter the call did not
59
+ send, written another way: a case or punctuation variant, a plural, or a key
60
+ whose last word is the parameter (`filePath`, `file_path` and `Path` for the
61
+ optional `path` of `pilens_diagnostics`: ``Not run: `filePath` looks like a
62
+ mistyped `path`, which was not sent.``). The exact predicate is named in
63
+ [public-api-stability.md](public-api-stability.md). Anything looser (a typo,
64
+ an abbreviation, `files` for `maxLspFiles`, or a count, flag or output key
65
+ such as `maxFiles`, `includeFiles`, `outFile` or `cwdPath` where `cwd` is
66
+ declared) stays a warning;
67
+ - each such call adds one count to the `mcp-ignored-arguments` degradation
68
+ group (subject: the tool name), visible in `pilens_health`.
69
+
70
+ Unknown keys are still not rejected outright: a caller that passes an extra key
71
+ that is not a declared parameter written another way (or that comes with the
72
+ parameter it resembles) keeps getting its answer, with the report above. Hard rejection is a change to the
73
+ public MCP input contract and is owned by the stability policy
74
+ ([public-api-stability.md](public-api-stability.md)). A schema declares only
75
+ what the tool reads, so `cwd` on a tool whose handler never reads it
76
+ (`pilens_health`, `pilens_latency`, `pilens_session_end`, `pilens_rebuild`;
77
+ the dispatcher uses it only to decide whether the tool is enabled) is reported
78
+ as an ignored key, a warning, because nothing it resembles is missing. The
79
+ retired `pilens_lsp_diagnostics` name is checked against `pilens_diagnostics`'s
80
+ schema; the retired `pilens_ast_grep_dump` name has no schema and is not
81
+ checked. A non-object `arguments` is a JSON-RPC `-32602` error; absent, `null`
82
+ and `[]` mean no arguments.
83
+
42
84
  ## Per-edit
43
85
 
44
86
  - **`lens_diagnostics`** — Session-cache or LSP-probe diagnostic state, selected
@@ -46,7 +88,24 @@ same gate rather than bypassing it.
46
88
  `workspace`; explicit `paths` always win over `scope`). `severity` is a
47
89
  threshold, not an exact filter: `error` shows only errors; `warning` adds
48
90
  warnings; `information` adds information; `hint`/`all` (default) show every
49
- tier. Legacy `mode`: `delta` (current turn), `all` (resurfaces stale
91
+ tier. `source=lsp` reads a file's on-disk content and will not sync it to a
92
+ language server past **2 MiB or 5000 lines** (`clients/runtime-config.ts`
93
+ `pipeline.lspMaxFileBytes`/`lspMaxFileLines`, checked in
94
+ `clients/lsp/content-limits.ts`) — not env-tunable today. A file over that
95
+ bound gets an explicit `file too large for LSP diagnostics (<N> bytes/lines
96
+ > <limit>)` result instead of stale or partial diagnostics. This is a
97
+ *different* 2 MiB from the auto-fix full-content attachment cap described in
98
+ [agent-guide.md](agent-guide.md), section 6 ("Auto-format / auto-fix
99
+ timing") — the two caps currently share one constant
100
+ (`RUNTIME_CONFIG.pipeline.lspMaxFileBytes`) but gate unrelated behaviors
101
+ (LSP sync vs. tool-result content attachment) and can diverge independently
102
+ in the future. Separately, every save-triggered edit now sends the server a
103
+ `textDocument/didSave` when it declared `textDocumentSync.save` — with the
104
+ file text when the server asked for it (`includeText`) and the file is
105
+ within the same bound, otherwise the save is still sent but without `text`
106
+ (never dropped outright); this is what makes save-triggered servers like
107
+ Expert (Elixir) re-diagnose an edit made through pi-lens (refs #3405,
108
+ #3408). Legacy `mode`: `delta` (current turn), `all` (resurfaces stale
50
109
  blockers dropped from turn context), `full` (project-wide scan).
51
110
  - **`lens_diagnostic_mark`** — Triage a diagnostic: `false-positive` /
52
111
  `suppress` (writes an inline `pi-lens-ignore` comment) / `defer`
@@ -2,7 +2,7 @@
2
2
 
3
3
  <!-- GENERATED by scripts/gen-rule-catalogs.mjs — do not edit by hand. Run `npm run docs:rule-catalogs` after changing rules. -->
4
4
 
5
- pi-lens bundles **481 enabled** ast-grep rules (297 pi-lens-authored + 184 vendored from CodeRabbit) across **17 languages**, plus 16 disabled.
5
+ pi-lens bundles **483 enabled** ast-grep rules (299 pi-lens-authored + 184 vendored from CodeRabbit) across **17 languages**, plus 16 disabled.
6
6
 
7
7
  See [`docs/custom-rules.md`](custom-rules.md) to add your own. Rule sources: `rules/ast-grep-rules/rules/` (pi-lens), `rules/ast-grep-rules/coderabbit/rules/` (vendored).
8
8
 
@@ -260,7 +260,7 @@ See [`docs/custom-rules.md`](custom-rules.md) to add your own. Rule sources: `ru
260
260
  | `openssl-cbc-static-iv-php` | warning | no | CodeRabbit | Static IV used with AES in CBC mode. Static IVs enable chosen-plaintext attacks against encrypted data. |
261
261
  | `search-active-debug-php` | warning | no | CodeRabbit | Debug logging is explicitly enabled. This can potentially disclose sensitive information and should never be active on production systems. |
262
262
 
263
- ### Python (98)
263
+ ### Python (99)
264
264
 
265
265
  | Rule | Severity | Fixable | Source | Description |
266
266
  |---|---|---|---|---|
@@ -271,7 +271,7 @@ See [`docs/custom-rules.md`](custom-rules.md) to add your own. Rule sources: `ru
271
271
  | `hashids-with-flask-secret-python` | warning | no | CodeRabbit | The Flask secret key is used as salt in HashIDs. The HashID mechanism is not secure. By observing sufficient HashIDs, the salt used to cons… |
272
272
  | `insecure-cipher-algorithm-rc4-python` | warning | no | CodeRabbit | Detected ARC4 cipher algorithm which is considered insecure. This algorithm is not cryptographically secure and can be reversed easily. Use… |
273
273
  | `jwt-python-hardcoded-secret-python` | warning | no | CodeRabbit | Hardcoded JWT secret or private key is used. This is a Insufficiently Protected Credentials weakness: https://cwe.mitre.org/data/definition… |
274
- | `no-assert-tuple` | error | no | pi-lens | Assert should not be called on a tuple literal |
274
+ | `no-assert-tuple` | warning | no | pi-lens | Assert should not be called on a tuple literal |
275
275
  | `no-aws-access-key-literal` | error | no | pi-lens | AWS access keys should not be hardcoded — use IAM roles, environment variables, or AWS Secrets Manager |
276
276
  | `no-aws-apigateway-no-auth` | error | no | pi-lens | AWS API Gateway should require authentication |
277
277
  | `no-aws-s3-public-access` | error | no | pi-lens | S3 buckets should not grant access to all users or authenticated users |
@@ -361,6 +361,7 @@ See [`docs/custom-rules.md`](custom-rules.md) to add your own. Rule sources: `ru
361
361
  | `python-webrepl-empty-password-python` | warning | no | CodeRabbit | The application creates a database connection with an empty password. This can lead to unauthorized access by either an internal or externa… |
362
362
  | `python-webrepl-hardcoded-secret-python` | warning | no | CodeRabbit | A secret is hard-coded in the application. Secrets stored in source code, such as credentials, identifiers, and other types of sensitive da… |
363
363
  | `reducible-list-comprehension` | warning | yes | pi-lens | A list comprehension is unnecessary here; use a generator expression |
364
+ | `unchecked-numeric-parse-python` | warning | no | pi-lens | int()/float() without try/except — raises ValueError on non-numeric input |
364
365
  | `unchecked-throwing-call-python` | error | no | pi-lens | Call without try/except — throws on invalid input or missing file |
365
366
 
366
367
  ### Ruby (20)
@@ -435,10 +436,11 @@ See [`docs/custom-rules.md`](custom-rules.md) to add your own. Rule sources: `ru
435
436
  | `redundant-usestate-type` | info | yes | pi-lens | `useState<TYPE>(...)` where TYPE is a primitive redundant — TS can infer it from the initial value |
436
437
  | `unnecessary-react-hook` | warning | no | pi-lens | Function with a `use*` name does not call any other React hook — rename to a plain function |
437
438
 
438
- ### TypeScript (134)
439
+ ### TypeScript (135)
439
440
 
440
441
  | Rule | Severity | Fixable | Source | Description |
441
442
  |---|---|---|---|---|
443
+ | `advisory-registry-subset` | info | no | pi-lens | Hand-enumerated registry subset — explain the excluded ids or use the registry |
442
444
  | `array-callback-return` | error | no | pi-lens | return statements must be enforced in callbacks of array methods |
443
445
  | `consistent-existence-index-check` | warning | no | pi-lens | Use .includes() instead of .indexOf() for existence checks |
444
446
  | `detect-angular-sce-disabled-typescript` | warning | no | CodeRabbit | $sceProvider is set to false. Disabling Strict Contextual escaping (SCE) in an AngularJS application could provide additional attack surfac… |