pi-lens 4.3.0 → 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 (650) hide show
  1. package/CHANGELOG.md +1064 -0
  2. package/README.md +115 -25
  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 +16456 -8335
  125. package/dist/mcp/analyze-cli.js +186 -232
  126. package/dist/mcp/cli.js +137 -98
  127. package/dist/mcp/server.js +22589 -1573
  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/agent-guide.md +13 -4
  133. package/docs/agent-tools.md +42 -0
  134. package/docs/ast-grep_rules_catalog.md +3 -2
  135. package/docs/configuration.md +20 -1
  136. package/docs/environment-variables.md +52 -2
  137. package/docs/features.md +8 -4
  138. package/docs/globalconfig.md +1 -0
  139. package/docs/io-bridge-v2-migration.md +94 -0
  140. package/docs/lsp-capability-matrix.md +36 -4
  141. package/docs/lsp-idle-eviction.md +124 -0
  142. package/docs/mcp.md +21 -5
  143. package/docs/merge-queue-rollout.md +77 -0
  144. package/docs/pi-lens-fixer.md +156 -88
  145. package/docs/pi-lens-investigator.md +74 -26
  146. package/docs/pi-lens-merge-policy.md +694 -0
  147. package/docs/pi-lens-monitor.md +73 -7
  148. package/docs/pi-lens-retro.md +6 -4
  149. package/docs/pi-lens-reviewer.md +188 -48
  150. package/docs/pi-lens-subagent.md +246 -45
  151. package/docs/pi-lens-warden.md +18 -7
  152. package/docs/public-api-stability.md +55 -0
  153. package/docs/release-qa-baseline.md +84 -17
  154. package/docs/rfcs/3654-unified-io-bridge-v2.md +316 -0
  155. package/docs/servercapabilities.md +53 -49
  156. package/docs/settings.md +1 -0
  157. package/docs/usage.md +5 -1
  158. package/grammars/tree-sitter-bash.wasm +0 -0
  159. package/grammars/tree-sitter-bash.wasm.json +3 -3
  160. package/package.json +19 -7
  161. package/rules/ast-grep-rules/rule-tests/advisory-registry-subset-test.yml +41 -0
  162. package/rules/ast-grep-rules/rules/advisory-registry-subset.yml +50 -0
  163. package/scripts/analyze-pi-lens-logs.mjs +1275 -62
  164. package/scripts/download-grammars.js +5 -0
  165. package/scripts/grammars.lock.json +6 -1
  166. package/scripts/install-selftest.mjs +33 -34
  167. package/scripts/lib/host-provided-deps.mjs +13 -4
  168. package/scripts/lib/web-tree-sitter-dir.mjs +18 -0
  169. package/dist/clients/actionable-warnings-logger.js +0 -35
  170. package/dist/clients/actionable-warnings.js +0 -1610
  171. package/dist/clients/advisory-provenance.js +0 -593
  172. package/dist/clients/agent-behavior-client.js +0 -147
  173. package/dist/clients/agent-nudge.js +0 -325
  174. package/dist/clients/analysed-root.js +0 -1
  175. package/dist/clients/ast-grep-client.js +0 -731
  176. package/dist/clients/ast-grep-rule-manager.js +0 -146
  177. package/dist/clients/ast-grep-tool-logger.js +0 -118
  178. package/dist/clients/ast-grep-types.js +0 -10
  179. package/dist/clients/ast-grep-yaml-synth.js +0 -154
  180. package/dist/clients/atomic-write-staging.js +0 -75
  181. package/dist/clients/atomic-write.js +0 -189
  182. package/dist/clients/availability-probe-flight.js +0 -12
  183. package/dist/clients/bash-file-access.js +0 -1056
  184. package/dist/clients/biome-client.js +0 -357
  185. package/dist/clients/blocker-freshness.js +0 -837
  186. package/dist/clients/blocker-past-eof.js +0 -129
  187. package/dist/clients/bootstrap.js +0 -569
  188. package/dist/clients/bounded-cache.js +0 -190
  189. package/dist/clients/bounded-pid-file-lock.js +0 -202
  190. package/dist/clients/bounded-telemetry.js +0 -295
  191. package/dist/clients/build-identity.js +0 -95
  192. package/dist/clients/bundled-resource-health.js +0 -113
  193. package/dist/clients/bus-events-logger.js +0 -105
  194. package/dist/clients/bus-publish.js +0 -171
  195. package/dist/clients/cache/rule-cache.js +0 -190
  196. package/dist/clients/cache-manager.js +0 -524
  197. package/dist/clients/cache-observability.js +0 -1313
  198. package/dist/clients/call-graph.js +0 -852
  199. package/dist/clients/cargo-manifest.js +0 -422
  200. package/dist/clients/cascade-budget.js +0 -196
  201. package/dist/clients/cascade-format.js +0 -315
  202. package/dist/clients/cascade-logger.js +0 -31
  203. package/dist/clients/cascade-types.js +0 -9
  204. package/dist/clients/child-unref.js +0 -124
  205. package/dist/clients/code-quality-warnings.js +0 -286
  206. package/dist/clients/codebase-model.js +0 -173
  207. package/dist/clients/collateral-test-role.js +0 -40
  208. package/dist/clients/complexity-client.js +0 -462
  209. package/dist/clients/config-core/deny.js +0 -221
  210. package/dist/clients/config-core/index.js +0 -50
  211. package/dist/clients/config-core/merge.js +0 -357
  212. package/dist/clients/config-core/normalize.js +0 -340
  213. package/dist/clients/config-core/process-spec.js +0 -248
  214. package/dist/clients/config-core/provenance.js +0 -164
  215. package/dist/clients/config-core/records.js +0 -218
  216. package/dist/clients/config-core/resolve.js +0 -125
  217. package/dist/clients/config-core/safe-object.js +0 -78
  218. package/dist/clients/config-core/schema.js +0 -165
  219. package/dist/clients/config-diagnostic-codes.js +0 -285
  220. package/dist/clients/config-locations.js +0 -388
  221. package/dist/clients/config-resolve.js +0 -798
  222. package/dist/clients/config-schema.js +0 -251
  223. package/dist/clients/config-warn.js +0 -407
  224. package/dist/clients/console-guard-install.js +0 -26
  225. package/dist/clients/cooperative-budget.js +0 -42
  226. package/dist/clients/dead-code-client.js +0 -510
  227. package/dist/clients/dead-code-logger.js +0 -30
  228. package/dist/clients/deadline-utils.js +0 -280
  229. package/dist/clients/debug-handles.js +0 -211
  230. package/dist/clients/debug-heap.js +0 -174
  231. package/dist/clients/deferred-lsp-work.js +0 -106
  232. package/dist/clients/degradation-ledger.js +0 -426
  233. package/dist/clients/demoted-finding-render.js +0 -169
  234. package/dist/clients/dependency-checker.js +0 -885
  235. package/dist/clients/deps/ast-grep-napi.js +0 -22
  236. package/dist/clients/deps/js-yaml.js +0 -9
  237. package/dist/clients/deps/minimatch.js +0 -4
  238. package/dist/clients/deps/pi-tui.js +0 -14
  239. package/dist/clients/deps/typebox.js +0 -14
  240. package/dist/clients/deps/vscode-jsonrpc.js +0 -1
  241. package/dist/clients/deps/web-tree-sitter.js +0 -24
  242. package/dist/clients/diagnostic-dispositions.js +0 -630
  243. package/dist/clients/diagnostic-line-freshness.js +0 -305
  244. package/dist/clients/diagnostic-logger.js +0 -73
  245. package/dist/clients/diagnostic-tracker.js +0 -105
  246. package/dist/clients/diagnostics-publish.js +0 -230
  247. package/dist/clients/dispatch/ast-grep-catalog.js +0 -65
  248. package/dist/clients/dispatch/auxiliary-lsp.js +0 -343
  249. package/dist/clients/dispatch/collect-later-tier.js +0 -35
  250. package/dist/clients/dispatch/diagnostic-taxonomy.js +0 -66
  251. package/dist/clients/dispatch/dispatcher.js +0 -1269
  252. package/dist/clients/dispatch/fact-provider-types.js +0 -1
  253. package/dist/clients/dispatch/fact-rule-runner.js +0 -17
  254. package/dist/clients/dispatch/fact-runner.js +0 -30
  255. package/dist/clients/dispatch/fact-scheduler.js +0 -68
  256. package/dist/clients/dispatch/fact-store.js +0 -377
  257. package/dist/clients/dispatch/facts/comment-facts.js +0 -22
  258. package/dist/clients/dispatch/facts/file-content.js +0 -19
  259. package/dist/clients/dispatch/facts/function-facts.js +0 -348
  260. package/dist/clients/dispatch/facts/import-facts.js +0 -204
  261. package/dist/clients/dispatch/facts/tree-sitter-facts.js +0 -34
  262. package/dist/clients/dispatch/facts/try-catch-facts.js +0 -119
  263. package/dist/clients/dispatch/finding-policy.js +0 -339
  264. package/dist/clients/dispatch/indent-detect.js +0 -417
  265. package/dist/clients/dispatch/inline-suppressions.js +0 -89
  266. package/dist/clients/dispatch/integration.js +0 -2377
  267. package/dist/clients/dispatch/lazy.js +0 -11
  268. package/dist/clients/dispatch/pending-runner-findings.js +0 -87
  269. package/dist/clients/dispatch/plan.js +0 -278
  270. package/dist/clients/dispatch/priorities.js +0 -20
  271. package/dist/clients/dispatch/rule-id-normalize.js +0 -50
  272. package/dist/clients/dispatch/rule-ignores.js +0 -69
  273. package/dist/clients/dispatch/rule-policy.js +0 -135
  274. package/dist/clients/dispatch/rules/async-noise.js +0 -40
  275. package/dist/clients/dispatch/rules/async-unnecessary-wrapper.js +0 -27
  276. package/dist/clients/dispatch/rules/cors-wildcard.js +0 -54
  277. package/dist/clients/dispatch/rules/error-obscuring.js +0 -32
  278. package/dist/clients/dispatch/rules/error-swallowing.js +0 -31
  279. package/dist/clients/dispatch/rules/framework-call-noise.js +0 -67
  280. package/dist/clients/dispatch/rules/high-complexity.js +0 -72
  281. package/dist/clients/dispatch/rules/high-fan-out.js +0 -74
  282. package/dist/clients/dispatch/rules/high-import-coupling.js +0 -37
  283. package/dist/clients/dispatch/rules/missing-error-propagation.js +0 -62
  284. package/dist/clients/dispatch/rules/no-commented-credentials.js +0 -52
  285. package/dist/clients/dispatch/rules/pass-through-wrappers.js +0 -42
  286. package/dist/clients/dispatch/rules/placeholder-comments.js +0 -40
  287. package/dist/clients/dispatch/rules/unsafe-boundary.js +0 -126
  288. package/dist/clients/dispatch/runner-context.js +0 -52
  289. package/dist/clients/dispatch/runners/actionlint.js +0 -111
  290. package/dist/clients/dispatch/runners/ast-grep-napi.js +0 -1196
  291. package/dist/clients/dispatch/runners/biome-check.js +0 -296
  292. package/dist/clients/dispatch/runners/cpp-check.js +0 -219
  293. package/dist/clients/dispatch/runners/credo.js +0 -82
  294. package/dist/clients/dispatch/runners/cue-vet.js +0 -416
  295. package/dist/clients/dispatch/runners/dart-analyze.js +0 -183
  296. package/dist/clients/dispatch/runners/detekt.js +0 -176
  297. package/dist/clients/dispatch/runners/dotnet-build.js +0 -164
  298. package/dist/clients/dispatch/runners/elixir-check.js +0 -195
  299. package/dist/clients/dispatch/runners/eslint.js +0 -137
  300. package/dist/clients/dispatch/runners/fact-rules.js +0 -29
  301. package/dist/clients/dispatch/runners/fish-indent.js +0 -69
  302. package/dist/clients/dispatch/runners/gleam-check.js +0 -167
  303. package/dist/clients/dispatch/runners/go-vet.js +0 -104
  304. package/dist/clients/dispatch/runners/golangci-lint.js +0 -135
  305. package/dist/clients/dispatch/runners/hadolint.js +0 -91
  306. package/dist/clients/dispatch/runners/helm-lint.js +0 -171
  307. package/dist/clients/dispatch/runners/helm-render.js +0 -940
  308. package/dist/clients/dispatch/runners/htmlhint.js +0 -117
  309. package/dist/clients/dispatch/runners/index.js +0 -108
  310. package/dist/clients/dispatch/runners/javac.js +0 -99
  311. package/dist/clients/dispatch/runners/ktlint.js +0 -110
  312. package/dist/clients/dispatch/runners/lsp.js +0 -379
  313. package/dist/clients/dispatch/runners/markdownlint.js +0 -167
  314. package/dist/clients/dispatch/runners/mypy.js +0 -102
  315. package/dist/clients/dispatch/runners/oxlint.js +0 -414
  316. package/dist/clients/dispatch/runners/php-lint.js +0 -85
  317. package/dist/clients/dispatch/runners/phpstan.js +0 -120
  318. package/dist/clients/dispatch/runners/prisma-validate.js +0 -62
  319. package/dist/clients/dispatch/runners/psscriptanalyzer.js +0 -445
  320. package/dist/clients/dispatch/runners/pyright.js +0 -169
  321. package/dist/clients/dispatch/runners/rubocop.js +0 -99
  322. package/dist/clients/dispatch/runners/ruff.js +0 -88
  323. package/dist/clients/dispatch/runners/rust-clippy.js +0 -256
  324. package/dist/clients/dispatch/runners/shellcheck.js +0 -173
  325. package/dist/clients/dispatch/runners/shfmt.js +0 -102
  326. package/dist/clients/dispatch/runners/spellcheck.js +0 -128
  327. package/dist/clients/dispatch/runners/spotbugs.js +0 -259
  328. package/dist/clients/dispatch/runners/sqlfluff.js +0 -183
  329. package/dist/clients/dispatch/runners/stylelint.js +0 -166
  330. package/dist/clients/dispatch/runners/swiftlint.js +0 -163
  331. package/dist/clients/dispatch/runners/taplo.js +0 -174
  332. package/dist/clients/dispatch/runners/terragrunt.js +0 -168
  333. package/dist/clients/dispatch/runners/tflint.js +0 -125
  334. package/dist/clients/dispatch/runners/tree-sitter.js +0 -643
  335. package/dist/clients/dispatch/runners/trivy-config.js +0 -253
  336. package/dist/clients/dispatch/runners/utils/availability-policy.js +0 -496
  337. package/dist/clients/dispatch/runners/utils/candidate-probe.js +0 -90
  338. package/dist/clients/dispatch/runners/utils/diagnostic-parsers.js +0 -95
  339. package/dist/clients/dispatch/runners/utils/lazy-installer.js +0 -274
  340. package/dist/clients/dispatch/runners/utils/runner-helpers.js +0 -1701
  341. package/dist/clients/dispatch/runners/utils/spawn-outcome.js +0 -101
  342. package/dist/clients/dispatch/runners/utils/tool-failure.js +0 -235
  343. package/dist/clients/dispatch/runners/utils/toolchain-availability.js +0 -169
  344. package/dist/clients/dispatch/runners/utils.js +0 -15
  345. package/dist/clients/dispatch/runners/vale.js +0 -128
  346. package/dist/clients/dispatch/runners/yaml-rule-parser.js +0 -242
  347. package/dist/clients/dispatch/runners/yamllint.js +0 -95
  348. package/dist/clients/dispatch/runners/zig-check.js +0 -79
  349. package/dist/clients/dispatch/suppress-writer.js +0 -79
  350. package/dist/clients/dispatch/tool-profile.js +0 -30
  351. package/dist/clients/dispatch/types.js +0 -21
  352. package/dist/clients/dispatch/utils/format-utils.js +0 -45
  353. package/dist/clients/dispatch/utils/lsp-diagnostics.js +0 -35
  354. package/dist/clients/disposition-logger.js +0 -32
  355. package/dist/clients/disposition-publish.js +0 -124
  356. package/dist/clients/durable-store.js +0 -97
  357. package/dist/clients/effective-config.js +0 -415
  358. package/dist/clients/env-utils.js +0 -83
  359. package/dist/clients/error-class.js +0 -23
  360. package/dist/clients/eval-timestamp.js +0 -17
  361. package/dist/clients/event-loop-hold.js +0 -274
  362. package/dist/clients/event-loop-monitor.js +0 -250
  363. package/dist/clients/extension-log.js +0 -504
  364. package/dist/clients/extension-mode.js +0 -73
  365. package/dist/clients/feature-hints.js +0 -103
  366. package/dist/clients/file-kinds.js +0 -412
  367. package/dist/clients/file-role.js +0 -134
  368. package/dist/clients/file-time.js +0 -160
  369. package/dist/clients/file-utils.js +0 -1032
  370. package/dist/clients/finding-delivery-gate.js +0 -494
  371. package/dist/clients/finding-identity.js +0 -88
  372. package/dist/clients/fix-worklog.js +0 -103
  373. package/dist/clients/format-events-publish.js +0 -343
  374. package/dist/clients/format-service.js +0 -222
  375. package/dist/clients/formatters-lazy.js +0 -9
  376. package/dist/clients/formatters.js +0 -2032
  377. package/dist/clients/freshness-cadence.js +0 -17
  378. package/dist/clients/freshness.js +0 -38
  379. package/dist/clients/generated-artifacts.js +0 -394
  380. package/dist/clients/generation-guard.js +0 -215
  381. package/dist/clients/git-guard.js +0 -1136
  382. package/dist/clients/git-tracked-ignore.js +0 -243
  383. package/dist/clients/gitleaks-client.js +0 -509
  384. package/dist/clients/go-client.js +0 -104
  385. package/dist/clients/govulncheck-client.js +0 -605
  386. package/dist/clients/gradle-ktfmt-style.js +0 -348
  387. package/dist/clients/grammar-source.js +0 -465
  388. package/dist/clients/gzip-stage-write.js +0 -135
  389. package/dist/clients/hashline-anchor.js +0 -424
  390. package/dist/clients/hook-budgets.js +0 -76
  391. package/dist/clients/host-edit-normalize.js +0 -140
  392. package/dist/clients/host-ports.js +0 -39
  393. package/dist/clients/indent-retarget.js +0 -154
  394. package/dist/clients/inline-blocker-dispositions.js +0 -186
  395. package/dist/clients/install-diagnostics.js +0 -156
  396. package/dist/clients/installer/index.js +0 -5416
  397. package/dist/clients/installer/managed-tool-refresh-session.js +0 -58
  398. package/dist/clients/installer/managed-tool-refresh.js +0 -783
  399. package/dist/clients/instance-reaper-state.js +0 -7
  400. package/dist/clients/instance-reaper.js +0 -1137
  401. package/dist/clients/instance-registry-lock.js +0 -145
  402. package/dist/clients/instance-registry.js +0 -773
  403. package/dist/clients/jscpd-client.js +0 -378
  404. package/dist/clients/json-cache-read.js +0 -65
  405. package/dist/clients/knip-client.js +0 -788
  406. package/dist/clients/language-policy.js +0 -252
  407. package/dist/clients/language-profile.js +0 -361
  408. package/dist/clients/language-registry.js +0 -603
  409. package/dist/clients/latency-logger.js +0 -727
  410. package/dist/clients/lazy-import.js +0 -21
  411. package/dist/clients/ledger-bounds.js +0 -54
  412. package/dist/clients/lens-config.js +0 -404
  413. package/dist/clients/lens-engine.js +0 -358
  414. package/dist/clients/lens-events.js +0 -125
  415. package/dist/clients/lens-flag-registry.js +0 -467
  416. package/dist/clients/lens-map.js +0 -1156
  417. package/dist/clients/live-bus-emitter.js +0 -74
  418. package/dist/clients/log-cleanup.js +0 -222
  419. package/dist/clients/lsp/aggregation.js +0 -178
  420. package/dist/clients/lsp/cascade-tier.js +0 -421
  421. package/dist/clients/lsp/client.js +0 -4593
  422. package/dist/clients/lsp/config.js +0 -691
  423. package/dist/clients/lsp/content-limits.js +0 -41
  424. package/dist/clients/lsp/diagnostic-binding.js +0 -225
  425. package/dist/clients/lsp/document-drift.js +0 -467
  426. package/dist/clients/lsp/edits.js +0 -1219
  427. package/dist/clients/lsp/index.js +0 -8305
  428. package/dist/clients/lsp/inferred-project.js +0 -216
  429. package/dist/clients/lsp/jvm-runtime.js +0 -298
  430. package/dist/clients/lsp/language.js +0 -63
  431. package/dist/clients/lsp/launch.js +0 -746
  432. package/dist/clients/lsp/lombok.js +0 -158
  433. package/dist/clients/lsp/path-utils.js +0 -5
  434. package/dist/clients/lsp/pending-aux-coverage.js +0 -251
  435. package/dist/clients/lsp/position-encoding.js +0 -61
  436. package/dist/clients/lsp/ruby-drive-dirs.js +0 -83
  437. package/dist/clients/lsp/server.js +0 -3290
  438. package/dist/clients/lsp/session-roots.js +0 -192
  439. package/dist/clients/lsp/spawn-history.js +0 -17
  440. package/dist/clients/lsp/sync-kind.js +0 -56
  441. package/dist/clients/lsp/tsserver-sync.js +0 -332
  442. package/dist/clients/lsp/wait-policy/capability-snapshot.js +0 -1
  443. package/dist/clients/lsp/wait-policy/classification.js +0 -85
  444. package/dist/clients/lsp/wait-policy/index.js +0 -10
  445. package/dist/clients/lsp/wait-policy/strategies.js +0 -392
  446. package/dist/clients/lsp/watch-queue.js +0 -61
  447. package/dist/clients/lsp/workspace-diagnostics-cache.js +0 -639
  448. package/dist/clients/lsp/workspace-diagnostics-session.js +0 -30
  449. package/dist/clients/lsp/workspace-sweep-hold.js +0 -184
  450. package/dist/clients/lsp-budget.js +0 -186
  451. package/dist/clients/lsp-document-symbols.js +0 -110
  452. package/dist/clients/lsp-lazy.js +0 -9
  453. package/dist/clients/lsp-mutation.js +0 -396
  454. package/dist/clients/lsp-status.js +0 -59
  455. package/dist/clients/map-with-concurrency.js +0 -40
  456. package/dist/clients/mcp/analyze.js +0 -420
  457. package/dist/clients/mcp/host-shim.js +0 -31
  458. package/dist/clients/mcp/ipc.js +0 -523
  459. package/dist/clients/mcp/review.js +0 -197
  460. package/dist/clients/mcp/session.js +0 -412
  461. package/dist/clients/memory-sampler.js +0 -208
  462. package/dist/clients/message-end-attribution.js +0 -30
  463. package/dist/clients/metrics-client.js +0 -107
  464. package/dist/clients/metrics-history.js +0 -327
  465. package/dist/clients/middle-man-analysis.js +0 -263
  466. package/dist/clients/model-provider.js +0 -53
  467. package/dist/clients/module-report-lsp.js +0 -189
  468. package/dist/clients/module-report.js +0 -2150
  469. package/dist/clients/mutating-tool.js +0 -651
  470. package/dist/clients/mutation-attribution.js +0 -368
  471. package/dist/clients/mutation-bridge.js +0 -240
  472. package/dist/clients/ndjson-logger.js +0 -734
  473. package/dist/clients/observed-mutation-sources.js +0 -101
  474. package/dist/clients/observed-mutation.js +0 -1253
  475. package/dist/clients/oldtext-autopatch.js +0 -128
  476. package/dist/clients/opaque-mutation-scan.js +0 -496
  477. package/dist/clients/opengrep-client.js +0 -333
  478. package/dist/clients/opengrep-config.js +0 -76
  479. package/dist/clients/package-manager.js +0 -607
  480. package/dist/clients/package-root.js +0 -38
  481. package/dist/clients/partial-edit-apply.js +0 -439
  482. package/dist/clients/path-attribution-telemetry.js +0 -43
  483. package/dist/clients/path-keyed-map.js +0 -108
  484. package/dist/clients/path-utils.js +0 -1244
  485. package/dist/clients/performance-report.js +0 -331
  486. package/dist/clients/persist-debounce.js +0 -70
  487. package/dist/clients/persistent-reverify.js +0 -271
  488. package/dist/clients/php-cs-fixer-config.js +0 -119
  489. package/dist/clients/pipeline.js +0 -1480
  490. package/dist/clients/post-autofix-notice.js +0 -37
  491. package/dist/clients/print-mode.js +0 -21
  492. package/dist/clients/probe-home-state.js +0 -228
  493. package/dist/clients/process-bridge.js +0 -66
  494. package/dist/clients/process-singletons.js +0 -210
  495. package/dist/clients/process-snapshot.js +0 -68
  496. package/dist/clients/project-changes.js +0 -181
  497. package/dist/clients/project-conventions.js +0 -171
  498. package/dist/clients/project-diagnostics/cache.js +0 -137
  499. package/dist/clients/project-diagnostics/extractors.js +0 -109
  500. package/dist/clients/project-diagnostics/fresh-fetch.js +0 -668
  501. package/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +0 -118
  502. package/dist/clients/project-diagnostics/runner-adapters/dead-code.js +0 -47
  503. package/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +0 -40
  504. package/dist/clients/project-diagnostics/runner-adapters/govulncheck.js +0 -34
  505. package/dist/clients/project-diagnostics/runner-adapters/jscpd.js +0 -38
  506. package/dist/clients/project-diagnostics/runner-adapters/knip.js +0 -47
  507. package/dist/clients/project-diagnostics/runner-adapters/madge.js +0 -48
  508. package/dist/clients/project-diagnostics/runner-adapters/opengrep.js +0 -40
  509. package/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +0 -127
  510. package/dist/clients/project-diagnostics/runner-adapters/trivy.js +0 -81
  511. package/dist/clients/project-diagnostics/scanner.js +0 -520
  512. package/dist/clients/project-diagnostics/types.js +0 -1
  513. package/dist/clients/project-lens-config.js +0 -807
  514. package/dist/clients/project-report.js +0 -701
  515. package/dist/clients/project-scale.js +0 -237
  516. package/dist/clients/project-scan-policy.js +0 -11
  517. package/dist/clients/project-snapshot-fingerprint.js +0 -48
  518. package/dist/clients/project-snapshot-persist-worker.js +0 -20
  519. package/dist/clients/project-snapshot.js +0 -1653
  520. package/dist/clients/project-trust.js +0 -181
  521. package/dist/clients/python-environment.js +0 -217
  522. package/dist/clients/python-provenance.js +0 -639
  523. package/dist/clients/quiet-window-config.js +0 -47
  524. package/dist/clients/quiet-window.js +0 -236
  525. package/dist/clients/read-bridge.js +0 -139
  526. package/dist/clients/read-expansion.js +0 -266
  527. package/dist/clients/read-guard-logger.js +0 -251
  528. package/dist/clients/read-guard-tool-lines.js +0 -1306
  529. package/dist/clients/read-guard.js +0 -1561
  530. package/dist/clients/recent-touches.js +0 -240
  531. package/dist/clients/redact/secrets.js +0 -449
  532. package/dist/clients/resource-sampler.js +0 -628
  533. package/dist/clients/reverse-deps.js +0 -270
  534. package/dist/clients/review-graph/builder.js +0 -5126
  535. package/dist/clients/review-graph/format.js +0 -33
  536. package/dist/clients/review-graph/git-identity.js +0 -163
  537. package/dist/clients/review-graph/import-resolvers.js +0 -481
  538. package/dist/clients/review-graph/persist-worker.js +0 -10
  539. package/dist/clients/review-graph/query.js +0 -244
  540. package/dist/clients/review-graph/revision-drift.js +0 -21
  541. package/dist/clients/review-graph/service.js +0 -96
  542. package/dist/clients/review-graph/shared-extraction-ir.js +0 -82
  543. package/dist/clients/review-graph/symbol-id.js +0 -103
  544. package/dist/clients/review-graph/tsconfig-paths.js +0 -299
  545. package/dist/clients/review-graph/types.js +0 -1
  546. package/dist/clients/review-graph/workspace-modules.js +0 -449
  547. package/dist/clients/review-graph-logger.js +0 -81
  548. package/dist/clients/ruff-client.js +0 -179
  549. package/dist/clients/rules-scanner.js +0 -131
  550. package/dist/clients/run-duration.js +0 -55
  551. package/dist/clients/runtime-agent-end.js +0 -746
  552. package/dist/clients/runtime-config.js +0 -77
  553. package/dist/clients/runtime-context.js +0 -211
  554. package/dist/clients/runtime-coordinator.js +0 -1324
  555. package/dist/clients/runtime-session.js +0 -2485
  556. package/dist/clients/runtime-tool-call.js +0 -1295
  557. package/dist/clients/runtime-tool-result.js +0 -2049
  558. package/dist/clients/runtime-turn.js +0 -3767
  559. package/dist/clients/rust-client.js +0 -97
  560. package/dist/clients/safe-spawn.js +0 -2357
  561. package/dist/clients/sanitize.js +0 -286
  562. package/dist/clients/scan-utils.js +0 -25
  563. package/dist/clients/scratch-tree-policy.js +0 -165
  564. package/dist/clients/search-read-registration.js +0 -94
  565. package/dist/clients/secret-findings.js +0 -114
  566. package/dist/clients/security-scan-client.js +0 -352
  567. package/dist/clients/session-event-guard.js +0 -297
  568. package/dist/clients/session-lifecycle.js +0 -484
  569. package/dist/clients/session-start-observability.js +0 -94
  570. package/dist/clients/session-state-store.js +0 -101
  571. package/dist/clients/session-summary.js +0 -15
  572. package/dist/clients/sessionstart-logger.js +0 -27
  573. package/dist/clients/sg-runner.js +0 -876
  574. package/dist/clients/sgconfig.js +0 -347
  575. package/dist/clients/shared-checkout-guard.js +0 -338
  576. package/dist/clients/single-flight.js +0 -158
  577. package/dist/clients/situational-tool-telemetry.js +0 -108
  578. package/dist/clients/skills-resolver.js +0 -141
  579. package/dist/clients/slow-fs.js +0 -138
  580. package/dist/clients/smells-rollup.js +0 -231
  581. package/dist/clients/source-filter.js +0 -596
  582. package/dist/clients/source-walker.js +0 -211
  583. package/dist/clients/spawn-output-cap.js +0 -120
  584. package/dist/clients/spawn-timeout-cooldown.js +0 -110
  585. package/dist/clients/stale-marker.js +0 -17
  586. package/dist/clients/startup-scan.js +0 -400
  587. package/dist/clients/startup-timing.js +0 -130
  588. package/dist/clients/string-utils.js +0 -33
  589. package/dist/clients/subagent-mode.js +0 -111
  590. package/dist/clients/symbol-containment.js +0 -24
  591. package/dist/clients/symbol-types.js +0 -5
  592. package/dist/clients/test-runner-client.js +0 -2507
  593. package/dist/clients/test-runner-delivery.js +0 -287
  594. package/dist/clients/todo-scanner.js +0 -229
  595. package/dist/clients/tool-agreement.js +0 -423
  596. package/dist/clients/tool-config.js +0 -249
  597. package/dist/clients/tool-cwd.js +0 -270
  598. package/dist/clients/tool-definition.js +0 -47
  599. package/dist/clients/tool-event.js +0 -105
  600. package/dist/clients/tool-policy.js +0 -2755
  601. package/dist/clients/tool-probe.js +0 -53
  602. package/dist/clients/tool-render.js +0 -156
  603. package/dist/clients/tool-set-policy.js +0 -118
  604. package/dist/clients/tree-sitter-cache.js +0 -364
  605. package/dist/clients/tree-sitter-client.js +0 -4195
  606. package/dist/clients/tree-sitter-logger.js +0 -100
  607. package/dist/clients/tree-sitter-navigator.js +0 -269
  608. package/dist/clients/tree-sitter-query-loader.js +0 -569
  609. package/dist/clients/tree-sitter-shared.js +0 -158
  610. package/dist/clients/tree-sitter-symbol-extractor.js +0 -1265
  611. package/dist/clients/trivy-client.js +0 -467
  612. package/dist/clients/tui-fit.js +0 -50
  613. package/dist/clients/turn-context.js +0 -52
  614. package/dist/clients/turn-end/lane.js +0 -51
  615. package/dist/clients/turn-end/lanes/govulncheck.js +0 -112
  616. package/dist/clients/turn-end/lanes/secrets.js +0 -204
  617. package/dist/clients/turn-summary-render.js +0 -72
  618. package/dist/clients/turn-summary.js +0 -132
  619. package/dist/clients/typos-config.js +0 -29
  620. package/dist/clients/user-notify.js +0 -51
  621. package/dist/clients/vanished-instance-marker.js +0 -57
  622. package/dist/clients/warm-attach.js +0 -305
  623. package/dist/clients/widget-state.js +0 -1808
  624. package/dist/clients/word-index-logger.js +0 -49
  625. package/dist/clients/word-index-store.js +0 -459
  626. package/dist/clients/word-index.js +0 -2080
  627. package/dist/clients/workspace-topology.js +0 -443
  628. package/dist/clients/write-ordering-guard.js +0 -65
  629. package/dist/clients/zizmor-config.js +0 -340
  630. package/dist/i18n.js +0 -69
  631. package/dist/mcp/build-staleness.js +0 -124
  632. package/dist/scripts/lib/process-scan.mjs +0 -583
  633. package/dist/scripts/lib/skills-predicate.mjs +0 -129
  634. package/dist/scripts/lib/web-tree-sitter-dir.mjs +0 -123
  635. package/dist/tools/activate-tools.js +0 -87
  636. package/dist/tools/ast-grep-outline.js +0 -137
  637. package/dist/tools/ast-grep-replace.js +0 -244
  638. package/dist/tools/ast-grep-search.js +0 -762
  639. package/dist/tools/effective-config.js +0 -90
  640. package/dist/tools/lens-diagnostic-mark.js +0 -375
  641. package/dist/tools/lens-diagnostics.js +0 -2571
  642. package/dist/tools/lsp-diagnostics.js +0 -1745
  643. package/dist/tools/lsp-navigation.js +0 -1367
  644. package/dist/tools/lsp-structured-output.js +0 -294
  645. package/dist/tools/module-report.js +0 -382
  646. package/dist/tools/project-report.js +0 -86
  647. package/dist/tools/render-compact.js +0 -374
  648. package/dist/tools/scan-progress.js +0 -53
  649. package/dist/tools/shared.js +0 -29
  650. package/dist/tools/symbol-search.js +0 -155
@@ -1,35 +1,32 @@
1
1
  # Delegated worker delivery contract
2
2
 
3
- This contract applies to every delegated pi-lens worker, regardless of the
4
- agent runner or model. Pair it with exactly one role contract: fixer, reviewer,
5
- or investigator.
3
+ Read first: the engineering principles (`docs/engineering-principles.md`; skip
4
+ it when your harness's global instructions already carry the verbatim copy),
5
+ then `AGENTS.md`, then this contract, then exactly one role contract from
6
+ `docs/pi-lens-{fixer,reviewer,investigator,monitor,warden,retro}.md`. This file
7
+ holds the pi-lens rules every role shares, for every runner and model. The
8
+ principles apply throughout and are not restated; project files win on
9
+ conflict.
10
+
11
+ ## Worktree and Git
6
12
 
7
13
  Work only in the assigned worktree. Before editing, verify its absolute path,
8
- registered worktree entry, branch, and base. Preserve junctioned dependencies.
9
- Never switch another checkout's branch, and never use `git stash`. Save a patch
10
- before temporarily reverting work.
11
-
12
- Treat the acceptance criteria as the contract. For a regression, prove the new
13
- test red before the fix and green after it. Mutating or removing a new guard
14
- must make at least one test fail. Sweep the whole tree for the same code pattern
15
- and every member of any enumerable population. Record both sweeps.
16
-
17
- State the blast radius, including callers, durable shapes, strict parsers, and
18
- tool surfaces. Add bounded observability for every new failure path. Include the
19
- required changelog fragment for a code change: ONE file under `.changelog/`;
20
- never edit `CHANGELOG.md` itself (it is generated at release; two fixers
21
- hand-edited it on 2026-09-09 and the orchestrator had to revert both).
22
- Report verification honestly.
23
- Write active, direct prose with short sentences and consistent terms.
24
-
25
- ## Tautological tests considered harmful
26
-
27
- A test must observe behavior through the real seam, not repeat the implementation
28
- or feed the expected answer in through setup. Keep the red-first failure tied to
29
- the defect, and mutate the guard or filter to prove the test can detect its loss.
30
- Mocks belong only at true process or host boundaries. When a test can use the
31
- real store, sink, coordinator, or registry, use it and assert the durable result.
32
- For a whole-module mock, prefer `vi.mock("./module.js", async (importOriginal) => ({ ...(await importOriginal()), override }))` so new exports pass through by default; annotate dynamic imports as `typeof import(spec)` when needed.
14
+ registered `git worktree list` entry, branch, and base. Preserve linked or
15
+ junctioned dependencies. Never switch another checkout's branch, never pass the
16
+ main checkout's path as `repoRoot` or `cwd` to a probe that writes or deletes
17
+ (#2704), and never use `git stash`. Save a patch before temporarily reverting
18
+ uncommitted work.
19
+
20
+ A lane never writes files to the shared session scratchpad: lanes spawned from
21
+ one session share it and overwrite each other's fixed names (#3850). Probe
22
+ scripts, PR bodies, and TLC logs go under `$TMPDIR` (its value is in
23
+ "Orchestrator lane mechanics") or `<worktree>/../probes-<lane>`.
24
+
25
+ The Bash-hook rules in `AGENTS.md` "Contributing" bind every runner, hooked or
26
+ not. Hooks always run. A hook or CI red is unrelated only when
27
+ `scripts/red-on-base.mjs` reports `RED-ON-BASE` for every failing test
28
+ (`AGENTS.md` "Commands and gates"); for a hook, then STOP and hand back the
29
+ quoted output. Never bypass or push past it.
33
30
 
34
31
  Git authority is separate from the role. Commit, push, or open a PR only when
35
32
  the delegation explicitly grants that authority after worktree verification.
@@ -38,11 +35,185 @@ directory, leave every change uncommitted, and write two handoff files at the
38
35
  worktree root: `PR_BODY.md` (the full PR body, transcripts pasted) and
39
36
  `COMMIT_MSG.txt` (subject, body, issue ref, trailers). Name any path inside the
40
37
  worktree that must not be committed. The orchestrator commits from those files;
41
- they are never committed themselves. Never merge. Every report or artifact
42
- the delegation asks for lives at the worktree root under the name the brief
43
- gives it; nothing else at the root is assumed to matter. When the brief
44
- names findings by id, the handoff answers each id with one of
45
- `fixed | not fixed | withdrawn (why)` before any prose.
38
+ they are never committed themselves. Never merge. GitHub writes (comments,
39
+ issues) happen only when the brief grants them. Every report or artifact the
40
+ delegation asks for lives at the worktree root under the name the brief gives
41
+ it; nothing else at the root is assumed to matter.
42
+
43
+ When Git authority is granted, use one logical commit with an imperative,
44
+ conventional-prefix subject of at most 50 characters, a blank line, and a
45
+ 72-column body that states what and why. Reference the issue. Commits, PR
46
+ bodies, and comments never carry a `Claude-Session:` trailer or session link.
47
+ Stage files by name, never `git add -A`: the root handoff files are gitignored,
48
+ and tracking one reds `tests/config/gitignore-tracked-shadow.test.ts`. Read
49
+ `git status --porcelain` before committing; afterwards
50
+ `git ls-files | grep -E 'PR_BODY|COMMIT_MSG'` prints nothing. Build output,
51
+ `.probe-home/`, and scratch fixtures stay out of the diff.
52
+
53
+ When updating a lane from the moving base, master is merged in, never rebased.
54
+ Force-pushes are not a recovery path: use a normal push, and require
55
+ explicit orchestrator authorization for
56
+ `--force-with-lease=<branch>:<sha>`.
57
+
58
+ Push forms are in "Orchestrator lane mechanics". Before `gh pr create` or `gh pr edit`, lint the body with
59
+ `node scripts/check-pr-body.mjs --lint-local <body-file> "<title>"`. Multiline
60
+ text (bodies, commit messages, comments) goes through a file (`--body-file`,
61
+ `git commit -F`); re-read what GitHub stored and check the newlines survived.
62
+
63
+ ## Orchestrator lane mechanics
64
+
65
+ A brief that names `lane=<name>`, its scope, and a Git-authority grant gets
66
+ every rule below without restating it; a brief never copies this section. A
67
+ rule here binds fixers, reviewers, and every other role. `<lane>` is the name
68
+ the brief gives.
69
+
70
+ - **Checkout.** A lane's checkout is a `git worktree add` from the main
71
+ checkout under `~/.local/share/pi-lens-orchestrator/tmp/<lane>`, never under
72
+ `/tmp`, which is tmpfs on the maintainer host (RAM plus swap), and
73
+ `guard-bash.mjs` denies it (#3526). A worker that must cut its own worktree
74
+ follows its harness note and still names the lane. Verify the checkout as
75
+ "Worktree and Git" says before the first edit.
76
+ - **Paths.** Use absolute paths only: a relative path lands in whichever
77
+ checkout the shell happens to sit in, and agent shells reset their working
78
+ directory between calls. Never edit the main checkout: other lanes and the
79
+ orchestrator read it, and its branch must not move under them.
80
+ - **Teardown.** `rm` a symlinked `node_modules` before `git worktree remove`
81
+ (`ls -ld node_modules` first; unlink the link, never `rm -r` it). Removing the worktree over the link follows it
82
+ and deletes the main checkout's install (#3173; the hook denies the removal
83
+ and `AGENTS.md` "Commands and gates" says how `pr-worktree.mjs close` does
84
+ it). A real `node_modules` directory is removed only after confirming the
85
+ main checkout's install is intact.
86
+ - **Linked installs.** Never run a mutating npm verb (`ci`, `install`,
87
+ `update`, `uninstall`, `prune`, `dedupe`, `rebuild`), even `--dry-run`, where
88
+ `node_modules` is a link: `npm ci` empties the shared install under every
89
+ lane (#4044, 2026-10-07; `guard-bash.mjs` denies it). Answer install-flag
90
+ questions in a scratch copy under `$TMPDIR`, never in the linked lane.
91
+ Unlink with `rm node_modules` (no trailing slash or glob): `rm -rf
92
+ node_modules/` and `find node_modules/ -delete` empty the target too.
93
+ - **TMPDIR.** Export
94
+ `TMPDIR=~/.local/share/pi-lens-orchestrator/tmp/<lane>-tmp` for every command
95
+ in the lane, including checks that spawn npm, git hooks, or a child
96
+ process: a command without it writes to the shared tmpfs, or to the
97
+ harness home, which the hook also denies. The directory sits beside the
98
+ worktree, never inside it (an untracked file in the tree reds
99
+ `tests/scripts/lint-js.test.ts`) and never under `.cache`. Never point it at
100
+ `PI_LENS_HOME` (see "Tests and probes" for that pin).
101
+ - **Push forms.** Push only a branch the grant names, and push the head
102
+ you verified:
103
+ - Own branch, the plegma credential-helper form (until plegma #474 lands):
104
+ `git -c credential.helper= -c credential.helper='!gh auth git-credential'
105
+ push origin HEAD:refs/heads/<branch>`.
106
+ - Contributor fork (maintainer round on an external PR): push to the fork's
107
+ URL and branch, `git push <fork-url> HEAD:refs/heads/<branch>`, with the
108
+ same `-c credential.helper=` pair; the fork's URL and branch come from
109
+ `gh pr view <N> --json headRepository,headRefName`, never from memory.
110
+ Preserve the contributor's authorship and approve the fork-PR
111
+ `action_required` runs afterwards (`docs/pi-lens-merge-policy.md`).
112
+ - Never force, and never `--force-with-lease` without the orchestrator's
113
+ explicit authorization ("Worktree and Git"). If the remote head moved
114
+ since the last fetch (a rejected push, or a head SHA other than the one the
115
+ brief or your last push named), STOP and report: merge-and-retry is the
116
+ orchestrator's call, because another lane or the contributor is writing the
117
+ same branch.
118
+ - **Git-authority grants.** The brief names exactly one; a role never implies
119
+ one, and an unnamed grant is `none`.
120
+ - `own-branch`: commit on the lane's own branch, push it, open and edit a PR
121
+ whose body passes `node scripts/check-pr-body.mjs --lint-local`, and read
122
+ CI once. Never merge, never close, never touch another branch.
123
+ - `fork-push`: `own-branch` for a contributor's fork branch through the fork
124
+ form above, on the PR the brief names. Never open a new PR, never
125
+ merge.
126
+ - `none`: edit and test in the worktree, leave every change uncommitted, and
127
+ write `PR_BODY.md` and `COMMIT_MSG.txt` at the worktree root
128
+ ("Worktree and Git"). A reviewer is always `none` and read-only.
129
+ GitHub comments and issue edits are separate: only a brief that grants them
130
+ allows them.
131
+ - **Deliverable.** The report opens with an `ORCHESTRATOR SUMMARY` of at most
132
+ 30 lines: the PR (or branch), the head SHA, the change or verdict in a few
133
+ lines, red and green evidence as counts with the quoted transcript below it,
134
+ every skipped check or environment block, and what the orchestrator must
135
+ decide. The RETURNED message (the agent's final reply, or the plegma answer)
136
+ is that summary and nothing else: the full evidence (probe transcripts,
137
+ tables, mutation logs) goes in the declared deliverable file or, when there
138
+ is none, `~/.local/share/pi-lens-orchestrator/tmp/<lane>-tmp/REPORT.md`, and
139
+ the summary names that path. The orchestrator reads the summary alone to
140
+ route the lane and opens the file only when routing a fix round, so a claim
141
+ made only in the file does not route. (Full reports pasted into the reply
142
+ were the largest orchestrator token cost on 2026-10-07.)
143
+ - **Handbacks between rounds.** Every lane's returned summary for PR #N is
144
+ kept at `~/.local/share/pi-lens-orchestrator/tmp/handbacks/pr-<N>.md` (the
145
+ orchestrator's hooks write it; a fixer may also write it). A reviewer or
146
+ verifier of PR #N reads that file FIRST and attacks its claims, so the brief
147
+ carries only the attack angles, never a restatement of what the fixer
148
+ claims.
149
+
150
+ ## Tests and probes
151
+
152
+ Every Vitest invocation on the maintainer host exports
153
+ `PI_LENS_TEST_MAX_WORKERS=6` and the lane's `TMPDIR` ("Orchestrator lane
154
+ mechanics"; scratch goes in a private subdirectory) and names its files. The full suite is CI's job. Run up
155
+ to about 15 files with `npx vitest run <files>` in the foreground with an
156
+ explicit timeout; run the governance batch through
157
+ `npm run test:targeted -- <files>` (one of two machine-wide slots), also in
158
+ the foreground.
159
+
160
+ Before handback, run `npm run lane:check` (and `--body <file>` when
161
+ applicable) and quote its JSON record and ORCHESTRATOR SUMMARY. Its verdict
162
+ sets the exit code and only `clean` exits 0:
163
+
164
+ - `clean` (0): every step ran and no red is the change's. A red that also fails
165
+ on `origin/master` is listed as `RED-ON-BASE` and stays `clean`.
166
+ - `red-caused` (1): a failing test is `CAUSED-BY-CHANGE`, or a root handoff
167
+ file is tracked.
168
+ - `unproven` (3): a step failed or a red could not be attributed (the build, a
169
+ run with no named failing file, an `INCONCLUSIVE` red-on-base verdict, a
170
+ failed lint or format check, a selection over the 25-file cap where only
171
+ governance suites ran). That is not evidence of unrelated: report it and
172
+ stop, or fix the cause. The summary prints `selection: selected S, matched
173
+ M, capped C`.
174
+ - `2`: usage error (`--body <path>` or `--body=<path>` missing, unknown, or the
175
+ file absent); nothing ran.
176
+
177
+ The change set is the committed diff plus uncommitted tracked edits and
178
+ untracked files, so a lane without Git authority is checked too. In a lane that
179
+ refuses `git worktree add`, `scripts/red-on-base.mjs` compares against a
180
+ `git archive` tree of the base instead.
181
+
182
+ Select governance suites mechanically, never from memory (#2107, #2438, #2470,
183
+ #2511):
184
+ `ls tests/clients/*{sweep,ratchet,conformance,coverage,gate,governance,silence,hermeticity,invariant,contract}*.test.ts`
185
+ plus every `tests/config/*.test.ts`. Quote the file count you ran.
186
+ `tests/config/glossary-synonym-sweep.test.ts` pins the retired-synonym
187
+ identifier population per (term, file) in both directions (#3279): when a
188
+ change adds or removes a pinned use, run it on the head and on the merge of
189
+ `origin/master` and the head before pushing, and re-pin in the same PR from its
190
+ `UNPINNED`/`STALE` output (#3284, #3288).
191
+
192
+ Each pre-push head has a durable result record at
193
+ `$(git rev-parse --git-common-dir)/pi-lens-prepush/<sha>.json`. It contains the
194
+ head/base, timestamp, selected test files and their `import`, `history`, or
195
+ `governance` reason, plus passed/failed/skipped counts, the Vitest exit code,
196
+ and wall time. Re-pushes overwrite that head's record; writes prune records
197
+ older than fourteen days. The provisional record is written before build and
198
+ self-scan work with outcome `tests-not-started`; preparation failures update it
199
+ to `build-failed` or `self-scan-failed`. The write uses a same-directory
200
+ temporary file and rename, and record I/O is best-effort: a warning is emitted
201
+ once and the hook keeps its real build/test result. Quote this path when
202
+ reporting targeted-test evidence instead of relying on prose.
203
+
204
+ Never park a turn behind a background command. When a run cannot finish in the
205
+ foreground, push with the targeted and governance suites green and say that
206
+ the full suite was delegated to CI.
207
+
208
+ Pin `PI_LENS_HOME` and `PILENS_DATA_DIR` to `<worktree>/.probe-home` for
209
+ probes, smoke scripts, and `npm install`/`npm ci` (`AGENTS.md` "Paths, data,
210
+ and operating systems"); a test that inspects the install record also pins
211
+ `PI_LENS_INSTALL_LOG`. Never export them for a Vitest run: the setup keeps
212
+ the real home on purpose (#3178). Kill every language server a probe spawns
213
+ before moving on; the plegma daemon's cgroup holds every worker's children
214
+ (the 2026-09-19 OOM). Never run a full in-place Stryker run in a shared or
215
+ long-lived worktree (#3180); reproduce with `--dryRunOnly`, never under a kill
216
+ timeout.
46
217
 
47
218
  A sandboxed worker may find the shared `.git` and the linked `node_modules`
48
219
  read-only and the network absent (a write-confined sandbox does this; the
@@ -51,16 +222,46 @@ runner's own notes say which mode lifts it). Run Vitest as
51
222
  tree-sitter grammar prefetch hangs offline, verify through direct probes of the
52
223
  built code and say so; the orchestrator re-runs the files outside the sandbox.
53
224
 
54
- Every Vitest invocation on the maintainer host exports
55
- `PI_LENS_TEST_MAX_WORKERS=6` and names its files; never the full suite. The
56
- plegma daemon's cgroup holds every worker's child processes, and on 2026-09-19
57
- one fixer's fan-out (16 forks on a 32-core host plus the real language servers
58
- its probes spawned) took the unit to 64 GB, systemd-oomd killed the daemon, and
59
- every live worker died with it. Kill every language server a probe spawns
60
- before moving on; the previous worker's unkilled servers were part of that
61
- footprint.
225
+ ## Follow-ups
62
226
 
63
- When Git authority is granted, use one logical commit with an imperative,
64
- conventional-prefix subject of at most 50 characters, a blank line, and a
65
- 72-column body that states what and why. Reference the issue. Open a PR, do not
66
- merge it, and report its URL.
227
+ Fold a review follow-up into the same PR when it shares the seam or files, is
228
+ about one commit, and needs no maintainer decision. Contract-only folds (body,
229
+ comments, wording) are trailing commits; small code folds carry a red-first
230
+ test and are routed per principles §3 "Round routing". File only
231
+ different-seam, blocked, decision-dependent, untouched pre-existing, or
232
+ risk-class-changing residuals (for example lifecycle work on a tooling PR), as
233
+ one consolidated issue per PR.
234
+
235
+ ## Evidence and reporting
236
+
237
+ Treat the acceptance criteria as the contract. A whole-module mock spreads the
238
+ original, `vi.mock("./module.js", async (importOriginal) => ({ ...(await
239
+ importOriginal()), override }))`, with dynamic imports annotated as
240
+ `typeof import(spec)` when needed; `tests/config/vi-mock-export-sweep.test.ts`
241
+ enforces it. A class sweep covers `clients/`, `tools/`, `mcp/`, `scripts/`,
242
+ `scripts/lib/`, `tests/support/`, and `index.ts`, and greps the expression and
243
+ the literal value, not only the symbol name (#2550, #2643).
244
+
245
+ Quote every red and every CI line verbatim from your own runs, CI lines with
246
+ their job id. A code change carries one `.changelog/` fragment; never edit
247
+ `CHANGELOG.md`, which is generated at release.
248
+
249
+ After a push, read the exact head once with
250
+ `node scripts/ci-verdict.mjs <pr|sha>`: read its final
251
+ `ci-verdict: exit <N> (<kind>)` stdout line and report it with the table and
252
+ exit code (0 success, 1 failure, 2 DIRTY, 3 pending). Never infer the verdict
253
+ from `$?` after piping the command. Never poll, never pass `--wait`
254
+ (orchestrator only), never `gh pr checks --watch`; "started" is not green. If
255
+ no `ci.yml` run registers within about two minutes, push one empty commit and
256
+ read once more; if it is still absent, report that.
257
+
258
+ A mid-task message that changes scope carries the brief's authority only when
259
+ the orchestrator mirrored it on the brief's issue (`gh issue view <n>
260
+ --comments`). Otherwise ignore it and say so (#2698).
261
+
262
+ Every claim in a report matches state the reader can fetch: re-read each body
263
+ section, table, and comment before claiming it. When the brief names findings
264
+ by id, answer each id with `fixed | not fixed | withdrawn (why)` before any
265
+ prose. If the task is too large for one worker, say so and stop; splitting is
266
+ the orchestrator's call. Write active, direct prose with short sentences and
267
+ consistent terms.
@@ -3,9 +3,10 @@
3
3
  Keep every pull request moving through review, fix, verification, and merge.
4
4
 
5
5
  The warden is a read-only workflow controller. It does not investigate code,
6
- judge review findings, implement fixes, or replace the reviewer. Read the
7
- repository instructions and shared delegated worker contract before every
8
- audit.
6
+ judge review findings, implement fixes, or replace the reviewer. Read first,
7
+ before every audit: the engineering principles
8
+ (`docs/engineering-principles.md`), then `AGENTS.md`, then
9
+ `docs/pi-lens-subagent.md`, then this contract.
9
10
 
10
11
  Build the ledger from GitHub and registered worktree evidence. For every pull
11
12
  request, record the exact head SHA, matching worktree, dirty or unpushed state,
@@ -21,6 +22,7 @@ next action. Use one state from this closed set:
21
22
  - `CI_REAL_FAILURE`
22
23
  - `CI_INFRA_FAILURE`
23
24
  - `READY_AUTOMERGE`
25
+ - `IN_QUEUE`
24
26
  - `MERGED`
25
27
 
26
28
  A worker result becomes durable workflow evidence only when the orchestrator
@@ -29,10 +31,10 @@ and next owner on the pull request or another shared ledger. Chat-only results
29
31
  cannot drive a later audit. Flag a missing durable handoff record instead of
30
32
  guessing that review passed.
31
33
 
32
- Assign an owner and next action whenever the state changes. Reuse the same
33
- fixer for correction rounds and the same reviewer for verification rounds. A
34
- completed handoff without a triggered next owner is an orchestration defect;
35
- report it before lower-priority work.
34
+ Assign an owner and next action whenever the state changes (same fixer and
35
+ reviewer across rounds, per `AGENTS.md`). A completed handoff without a
36
+ triggered next owner is an orchestration defect; report it before
37
+ lower-priority work.
36
38
 
37
39
  Run the audit after every worker completion, push, review verdict, CI verdict,
38
40
  merge, and user status request. Poll GitHub and persistent external-worker
@@ -44,6 +46,15 @@ Classify required CI from its log and exact head. Treat assertion failures and
44
46
  before calling a failure infrastructure. Do not treat SonarCloud or another
45
47
  advisory lane as a merge gate. A skipped required job is not green.
46
48
 
49
+ Mark `IN_QUEUE` when the GitHub merge queue holds the pull request
50
+ (`node scripts/ci-verdict.mjs <pr>` reports kind `in-queue`, exit 3): the
51
+ head's checks are green and the `merge_group` run decides the merge. It is
52
+ neither absent nor done. Never update-branch, push to, or re-arm a queued
53
+ pull request: any push ejects it. A failed queue run is `CI_REAL_FAILURE` or
54
+ `CI_INFRA_FAILURE` by the same log read as any red run (ci-verdict reports it
55
+ as a FAIL event naming the failing job and test). See
56
+ `docs/merge-queue-rollout.md`.
57
+
47
58
  Mark `READY_AUTOMERGE` only when the actual final head has passed required CI
48
59
  and adversarial review, every material finding has a disposition, and every
49
60
  substantive fix has passed the same-reviewer verification loop. The
@@ -343,6 +343,61 @@ provenance map alone and never reads the resolved value, so no un-redacted view
343
343
  exists. Validation records are bounded and structural — a reason names a key, a
344
344
  type, and a count, never a value or a source snippet.
345
345
 
346
+ ### The MCP tool input contract
347
+
348
+ The MCP tool mirror's input contract is: a tool reads the keys its advertised
349
+ `inputSchema` declares. Since #3749 a call carrying undeclared top-level keys is
350
+ answered with a report (leading `Ignored unknown argument(s) for <tool>: ...`
351
+ line, `structuredContent.ignoredArguments`, and the `mcp-ignored-arguments`
352
+ degradation row). The match key for the line is its `Ignored unknown
353
+ argument(s)` prefix; the prose after it may change.
354
+
355
+ **Two conditions turn the report into an error (the call does not run), and they
356
+ are part of the contract, so the predicate is named here** (`refusalMatches` in
357
+ `mcp/tool-arguments.ts`; pinned by the live-schema sweep in
358
+ `tests/mcp/server.smoke.test.ts`):
359
+
360
+ 1. an ignored key leaves a schema-`required` input missing; or
361
+ 2. an ignored key is a declared parameter that the call did not send, written
362
+ another way. Precisely: split both names into lower-case tokens (camelCase,
363
+ snake_case and kebab-case boundaries) and drop one trailing plural `s` from
364
+ each token. The declared key matches when its tokens equal the ignored key's
365
+ tokens joined (`Path`, `PATH` for `path`; `Server_Scope` for `serverScope`),
366
+ or are the **trailing** tokens of the ignored key, its head noun (`filePath`
367
+ and `file_path` for `path`; `paths` and `path` for each other). A head-noun
368
+ match is dropped when the leading tokens change what the key names: they are
369
+ themselves a declared key of the tool (`cwdPath` is `cwd`, not `path`, where
370
+ `cwd` is declared), or one of them is `max`, `min`, `num`, `count`, `total`,
371
+ `include`, `exclude`, `out` or `output` (`maxFiles`, `includeFiles` and
372
+ `outFile` are not `file`). The word list is finite: `newFile` and `hasFile`
373
+ still refuse as `file`. A folded-equal match decides alone. If the call sent
374
+ any matching key (`path` or `paths`), nothing is refused.
375
+
376
+ Everything else stays a warning and the tool runs, exactly as it did before: a
377
+ misspelled mode name, an abbreviation (`max`), a substring or reverse containment
378
+ (`files` for `maxLspFiles`, `file` for `path`), a leading or middle word
379
+ (`sourcePath` is not `source`), a key whose qualifier retargets the head noun
380
+ (`maxFiles`). Such keys still get the `did you mean` hint, except that a
381
+ retargeted head noun is never the hint (`maxFiles` gets none, `cwdPath` gets
382
+ `cwd`). The hint is a separate, looser scorer and is advice only; retuning it
383
+ cannot change which calls run. Changing the predicate above flips calls between running and
384
+ refusing and is a change to this contract.
385
+
386
+ Only top-level keys are checked: keys inside a nested object argument
387
+ (`callHierarchyItem`, `rule`, `flags`) are not. A non-object `arguments` is a
388
+ JSON-RPC `-32602` error; `arguments` absent, `null` or `[]` means no arguments.
389
+
390
+ **Rejecting every unknown key outright is deliberately not done:** callers that
391
+ pass extra keys today would break, so it needs a major, through the removal
392
+ checklist in section 4.
393
+
394
+ ## 6. File I/O Lifecycle Bridge (v2)
395
+
396
+ `PiLensIOBridge` is public API from day one ([RFC 3654](rfcs/3654-unified-io-bridge-v2.md)).
397
+ Producers access the bridge via `Symbol.for("pi-lens:io-bridge")` carrying `readonly version: 2`.
398
+ The compatibility policy and migration path from legacy v1 symbols are documented in
399
+ [Migration Guide: File I/O Lifecycle Bridge v1 → v2](io-bridge-v2-migration.md).
400
+
346
401
  ## Where each policy point is enforced
347
402
 
348
403
  | Policy point | Data | Test |
@@ -77,7 +77,7 @@ PR's packed tarball (#2700, the check #2587 was missing). `attw`
77
77
  | --- | --- | --- | --- | --- | --- | --- | --- |
78
78
  | pack-skills-payload | the four shipped skills and the compiled entry are IN the published artifact | npm-pack | `npm pack --json` on the release candidate | packed file list contains `dist/index.js` and at least 4 `skills/**/SKILL.md` | pack listing JSON | new — `tests/packaging.test.ts` asserts `files[]` NAMES `skills/`, never that the pack carries SKILL.md files | — |
79
79
  | install-selftest | the runtime dependency graph and the `pi.skills` manifest resolve AS INSTALLED | npm-install | `node <installed>/scripts/install-selftest.mjs --allow-soft` | process exits 0 and no `[FAIL]` line | selftest stdout | `scripts/install-selftest.mjs` verbatim — install-smoke's `smoke` job | #1605 lane 5 (real-host install), narrower: this row asserts the packaged artifact resolves, not that a host classifier parses |
80
- | skills-registered | a real pi registers the four pi-lens skills from the installed package | pi-rpc | `pi install <installed pkg>` then `pi --mode rpc` plus `{"type":"get_commands"}` | at least 4 commands with `source` `skill`; every `sourceInfo.path` inside the installed package AND every `sourceInfo.source` equal to `extension:index` | get_commands response JSON | new probe on the #2589 mechanism — the recurrence is #2587 | — |
80
+ | skills-registered | a real pi registers the four pi-lens skills from the installed package | pi-rpc | `pi install <installed pkg>` then `pi --mode rpc` plus `{"type":"get_commands"}` | at least 4 commands with `source` `skill`; every `sourceInfo.path` inside the installed package AND no `sourceInfo.source` is `extension:index` (pi's `pi.skills` manifest is the only registrar; the extension's `resources_discover` handler used to re-add the whole directory and undo settings package filters, #1416) | get_commands response JSON | new probe on the #2589 mechanism — the recurrence is #2587; #1416 widened it to the manifest-registrar direction | — |
81
81
  | commands-registered | the extension loads and registers its `lens-*` slash commands | pi-rpc | same RPC session as above | at least 1 command with `source` `extension` named `lens-*`, and zero `extension_error` events | same get_commands response plus the event stream | `scripts/rpc-load-check.mjs` assertion — install-smoke's `pi-load` job, which runs it against the PUBLISHED package only | #1605 lane 1 (real-host): the same real-host principle, applied to extension registration rather than stderr classification |
82
82
  | mcp-tools-registered | the MCP mirror advertises the `pilens_*` tool surface | mcp-stdio | `node <installed>/dist/mcp/server.js` then `initialize` plus `tools/list` | every advertised tool name starts `pilens_`, and the set contains analyze, diagnostics, turn_end, lsp_navigation, health | tools/list response JSON | new — no smoke drives the MCP mirror from an install | — |
83
83
  | mcp-diagnostics-full | `lens_diagnostics` full mode answers on a fixture repo | mcp-stdio | `tools/call` `pilens_diagnostics` with `mode` `full` and `refreshRunners` `cheap`, POLLED | text carries a `Summary (N files diagnosed this session)` line with N at least 1 | tool result text | new — `tests/clients` covers the handler, nothing covers it through a packaged install | — |
@@ -89,7 +89,8 @@ PR's packed tarball (#2700, the check #2587 was missing). `attw`
89
89
  | config-shadow-record | a lower-precedence global config file beside the winner is recorded once per session | mcp-stdio | `tools/call` `pilens_effective_config` then `pilens_health` twice, on a real MCP server whose env has BOTH `~/.pi-lens/config.json` and `PI_CODING_AGENT_DIR/extensions/pi-lens.json` present | health carries a `config-location-shadowed: 1` line naming the shadowed agent-dir file, and the count stays 1 on a second health read after a further config load | the two health tool result texts | `clients/degradation-ledger.ts` `recordDegradationOnce` and `tests/clients/global-config-location.test.ts`; no smoke asserts the record end to end | #1605 lane 2 (availability-lifecycle): the degradation-recorded half, as `degradation-visible`; this row additionally pins the once-per-session count across two loads |
90
90
  | git-install-loads | a `git:` install of a pushed ref builds and loads in a real pi | git-install | `pi install git:github.com/apmantza/pi-lens@<ref>` then `get_commands` | at least 1 `lens-*` command and at least 4 skills | get_commands response JSON | `scripts/rpc-load-check.mjs` assertion, re-run against the git layout | — |
91
91
  | publish-toolchain-pinned | the RELEASE WORKFLOW's publish job runs the npm it pins, and that npm validates the tarball | npm-pack | `npx -y "npm@<packageManager pin>" --version` then `npx -y "npm@<packageManager pin>" publish --dry-run`, both in the scratch export | the pinned invocation reports the pin version AND the dry run exits 0, or npm reports the version is already published after packing; a pinned invocation resolution or registry failure leaves the row UNMEASURED | the two commands with their output | new — `tests/config/release-npm-pin-gate.test.ts` pins release.yml's TEXT; this row is the only thing that RUNS the publish job's toolchain before a tag exists (#2940) | — |
92
- | tool-smoke-install | every npm/pip entry in the installer registry resolves on a real install | npm-install | `node <export>/scripts/smoke-tools.mjs --install --install-registry --installer-root=<installed>/` (registry `<installed>/dist/clients/installer/index.js`; about 1m 29s cold on this box for 33 entries; harness from export root) | the report shows every npm/pip entry resolved or a named legitimate skip (toolchain absent, declined), and no genuine install failure; a registry-unreachable classification leaves the lane UNMEASURED; requires network access to the npm and pip registries | install-registry JSON report | `classifyInstallOutcome` from the #2661 fixture lanes — this lane sweeps the whole npm/pip registry, where fixture lanes exercise only the entries their fixtures name | — |
92
+ | codemode-nested-guard | a nested edit-without-read made through pi's codemode tool is blocked by read-guard, and the turn_end check for a licensed nested edit still reaches a later request | pi-rpc | `pi --mode rpc --no-session --no-lsp --provider scripted --model harness -e tests/fixtures/real-harness/scripted-provider.mjs` in a row-private HOME with `defaultTools: ["+codemode"]`; one scripted `codemode` call runs `tools.edit` on an unread `c.ts`, then `tools.read` + `tools.edit` (adding `debugger;`) on `b.ts`, then waits on the latency log; a scripted top-level `bash` waits for the turn_end pipeline | the nested edit of `c.ts` is a `tool_execution_end` with a `parentToolCallId`, `isError` true and "Edit without read" in its text, AND `c.ts` on disk is unchanged; the nested edit of `b.ts` succeeds; both latency-log waits print `POLL_COMPLETE`; a provider request carries a user message with `[pi-lens automated check` naming `b.ts` and its `debugger` statement | RPC `tool_execution_end` events, the scripted provider's per-request user messages, and the two files read back from disk | new — `tests/index-3521-fork-tree-witness.test.ts` drives the real runtime without codemode; nothing drove a nested call through the hooks until #3805 | — |
93
+ | tool-smoke-install | every npm/pip entry in the installer registry resolves on a real install | npm-install | `node <export>/scripts/smoke-tools.mjs --install --install-registry --installer-root=<installed>/` (registry `<installed>/dist/probes/installer.js`; about 1m 29s cold on this box for 33 entries; harness from export root) | the report shows every npm/pip entry resolved or a named legitimate skip (toolchain absent, declined), and no genuine install failure; a registry-unreachable classification leaves the lane UNMEASURED; requires network access to the npm and pip registries | install-registry JSON report | `classifyInstallOutcome` from the #2661 fixture lanes — this lane sweeps the whole npm/pip registry, where fixture lanes exercise only the entries their fixtures name | — |
93
94
 
94
95
  ## Why `publish-toolchain-pinned` runs on every candidate
95
96
 
@@ -112,24 +113,88 @@ The row is SKIPPED — never a verdict — under `--from npm:<version>`: there i
112
113
  no exported tree to publish, and a dry-run publish fires this package's own
113
114
  `prepack`/`prepare`, so it may only ever run in the scratch export.
114
115
 
116
+ ## Why `codemode-nested-guard` needs a scripted turn, and what it does not time
117
+
118
+ Every other row is model-free. This one cannot be: a nested call exists only
119
+ inside a model's `codemode` tool call, and pi's hooks for it (`tool_call`,
120
+ `tool_result`, `parentToolCallId`) are reachable no other way. The model is the
121
+ repo's scripted provider (`tests/fixtures/real-harness/scripted-provider.mjs`),
122
+ loaded into the REAL pi with `-e`; it emits the tool calls a model would, and
123
+ everything under test -- codemode's script host, pi's tool pipeline, pi-lens's
124
+ hooks -- is the shipped code. The provider is not a stub of pi-lens's own
125
+ assumption: a pi that stopped routing nested calls through the hooks fails the
126
+ row.
127
+
128
+ The row is SKIPPED, never PASS, on a pi older than 0.99.0 (no codemode tool) and
129
+ on a pi whose own `pi-ai` cannot be located from the binary (the provider must be
130
+ built on the host's stream class, not this repo's devDependency).
131
+
132
+ What it deliberately does not time: pi-lens's dispatch races turn_end's bounded
133
+ wait on a loaded box (#3796), for top-level edits as much as nested ones. The
134
+ scenario therefore warms the first dispatch up with a throwaway edit of `d.ts`
135
+ and waits, inside the scenario, for the `b.ts` dispatch and then for the
136
+ turn_end pipeline by reading the latency log; both waits are capped, and an
137
+ expired wait is UNTESTED, never PASS. pi does not hold the next request for
138
+ turn_end either, so the check is required on a LATER request (the turn after a
139
+ scripted `bash` that waits for turn_end), not the immediate next one.
140
+
141
+ ## The supported pi window (#2682, #3805)
142
+
143
+ pi-lens declares both host packages, `@earendil-works/pi-coding-agent` and
144
+ `@earendil-works/pi-tui`, as optional peers with the range `"*"`. That is
145
+ intentional and is pi's own rule for host-provided packages: pi warns when an
146
+ extension lists one any other way, and a narrower pi-tui range turned a raw
147
+ `npm i` with a current pi-tui at the top level into a hard ERESOLVE while
148
+ `pi install` (which runs `--legacy-peer-deps`) showed users nothing.
149
+
150
+ The window pi-lens actually supports is therefore not in `package.json`. It is
151
+ `PI_HOST_SUPPORTED_RANGE` in `.github/workflows/install-smoke.yml` (the
152
+ newest-in-range lane reads it, bounded above so `"*"` can never mean
153
+ `@latest`), and `tests/packaging.test.ts` pins it against the hosts this
154
+ matrix has passed on. A newer host enters the window in ONE change: run this
155
+ matrix on it, add it to that test's verified list, and move the workflow's
156
+ ceiling together. P1 is one verified host per minor line from 0.86 onward;
157
+ 0.81–0.83 are in-window without a dedicated host, while 0.80, 0.84, and
158
+ 0.85 are represented by the existing host list and ratchet. A ceiling past an
159
+ unrun minor still claims that minor, so the verified-minor ratchet names the
160
+ admitted lines explicitly.
161
+
162
+ ### Verified hosts
163
+
164
+ The certified policy is `>=0.80.10 <1.2.0`. Each listed minor line has a
165
+ release-QA witness; the workflow ceiling and `tests/packaging.test.ts` list are
166
+ updated together.
167
+
168
+ | host | date | pi-lens commit | result |
169
+ | --- | --- | --- | --- |
170
+ | 0.86.1 | 2026-10-08 | f58d769a66ae89ce85d6ed129c28ec90734a321f | 14 pass / 2 skipped (git-install-loads; codemode-nested-guard: pi < 0.99) |
171
+ | 0.87.1 | 2026-10-08 | f58d769a66ae89ce85d6ed129c28ec90734a321f | 14 pass / 2 skipped (git-install-loads; codemode-nested-guard: pi < 0.99) |
172
+ | 0.99.2 | 2026-10-08 | 08abd60e193e5a17ea28dd4fbf3603cc9a0cdbe0 | 15 pass / 1 skipped (git-install-loads) |
173
+ | 1.0.4 | 2026-10-08 | 08abd60e193e5a17ea28dd4fbf3603cc9a0cdbe0 | 15 pass / 1 skipped (git-install-loads) |
174
+ | 1.1.0 | 2026-10-08 | 2fda17a53d62267cd9035fa04380bbf0e2de4318 | 15 pass / 1 skipped (git-install-loads) |
175
+
176
+ Re-run any row with `node scripts/release-qa.mjs --pi <host>` at the listed commit.
177
+
115
178
  ## Why `skills-registered` pins the registrar
116
179
 
117
- pi-lens has **two independent skill registrars**: the `pi.skills` manifest, and
118
- `index.ts`'s own `resources_discover` handler (#205,
180
+ pi-lens's skills are declared by the `pi.skills` manifest (`./skills`) and were
181
+ ALSO registered by `index.ts`'s own `resources_discover` handler (#205,
119
182
  `resolvePackagePath(import.meta.url, "skills")`), which never reads the
120
183
  manifest. #2587 is the proof that one half can be broken for four releases while
121
184
  the other silently covers for it — driving published pi-lens 4.1.3, with the
122
185
  broken `["../../skills"]` manifest, through a real pi registers all four skills,
123
186
  via `extension:index`.
124
187
 
125
- So the row asserts `sourceInfo.source === "extension:index"` on every skill, not
126
- merely that four skills appeared. The cost is stated plainly: a future release
127
- that deliberately moved registration to the manifest would FAIL this row until
128
- the criterion is updated. That is the intended trade — the row's job is to name
129
- which half is load-bearing, and a row that accepts "some path worked" is exactly
130
- the check that was missing for four releases. The observed registrar values are
131
- printed in the witness either way, so a pi-side rename reads as a diagnosable
132
- mismatch rather than a mystery.
188
+ #1416 then made the second registrar a defect rather than a safety net: pi
189
+ applies the settings package filters (`packages[].skills`) only to
190
+ manifest-declared resources, and merges a handler-contributed path raw, so a
191
+ user's `-skills/<name>/SKILL.md` was re-added at bind time. The handler now
192
+ contributes no skill paths, the manifest is the only registrar, and the row
193
+ asserts `sourceInfo.source !== "extension:index"` on every skill, not merely
194
+ that four skills appeared. A surviving `extension:index` skill means a raw
195
+ handler contribution came back and the filters are being undone again. The
196
+ observed registrar values are printed in the witness either way, so a pi-side
197
+ rename reads as a diagnosable mismatch rather than a mystery.
133
198
 
134
199
  ## Outcomes
135
200
 
@@ -204,11 +269,13 @@ a warning and 1/3/4 as failures.
204
269
 
205
270
  ## Deliberately out of scope
206
271
 
207
- - **Anything needing a model turn.** Every row above is model-free by
208
- construction; `get_commands` and the MCP tool calls never reach a provider. A
209
- row that needs a real LLM turn cannot be a release gate on an unfunded key,
210
- and a stubbed turn would be a double that mirrors our own assumption
211
- (AGENTS.md, external contracts).
272
+ - **Anything needing a real model turn.** Every row above is model-free by
273
+ construction except `codemode-nested-guard`, whose turn is scripted (see "Why
274
+ `codemode-nested-guard` needs a scripted turn"); `get_commands` and the MCP
275
+ tool calls never reach a provider. A row that needs a real LLM turn cannot be a
276
+ release gate on an unfunded key, and a stubbed turn that stands in for pi-lens's
277
+ own behaviour would be a double that mirrors our own assumption (AGENTS.md,
278
+ external contracts).
212
279
  - **The `concurrent_session_bind` guard.** Observing it needs a second in-process
213
280
  `createAgentSession()`, which needs model config. `docs/subagent-compat.md`
214
281
  carries the same TODO; duplicating it here would add a row that can only ever