pi-lens 4.4.1 → 4.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/config/dependency-cruiser-eager-allowlist.json +3 -1
  3. package/dist/{chunk-BJF25SUG.js → chunk-23WOO7TX.js} +11 -10
  4. package/dist/{chunk-WATC3IQR.js → chunk-2B73ZPOK.js} +3 -3
  5. package/dist/{chunk-N2IRDBZI.js → chunk-2BBLFX75.js} +101 -11
  6. package/dist/{chunk-TA5L5KWQ.js → chunk-2CD5RS6M.js} +2 -2
  7. package/dist/{chunk-3TTPKMEF.js → chunk-2ZGIZPDG.js} +38 -37
  8. package/dist/{chunk-LNOMA3MP.js → chunk-34WSVGEM.js} +29 -3
  9. package/dist/chunk-3JNKMP3B.js +17 -0
  10. package/dist/{chunk-H2W2AXD3.js → chunk-3UUPUE3O.js} +41 -35
  11. package/dist/{chunk-6P54TMWL.js → chunk-3VPVG5SU.js} +6 -6
  12. package/dist/chunk-3WA4HP4I.js +55 -0
  13. package/dist/chunk-466Z26MG.js +30 -0
  14. package/dist/{chunk-PCHDGUKT.js → chunk-4UNXBNE2.js} +12 -11
  15. package/dist/{chunk-J7WJZ6W7.js → chunk-4W4VLAPJ.js} +12 -11
  16. package/dist/{chunk-F5VLZHUW.js → chunk-52FUZI6K.js} +4 -2
  17. package/dist/chunk-5JM2524W.js +84 -0
  18. package/dist/{chunk-H5EV3VMF.js → chunk-5NGR67U5.js} +2 -2
  19. package/dist/{chunk-YLN4K6WD.js → chunk-66SXUJCA.js} +6 -6
  20. package/dist/{chunk-LD7WFTRX.js → chunk-66VMUL7Q.js} +16 -16
  21. package/dist/{chunk-BHWHXMQ2.js → chunk-67WMNWEE.js} +9 -8
  22. package/dist/{chunk-USHG4DLH.js → chunk-6C7JWPCP.js} +7 -7
  23. package/dist/{chunk-VPWKF3GN.js → chunk-6GFRNVYR.js} +11 -10
  24. package/dist/{chunk-3JL6IFD7.js → chunk-6SDEP3AJ.js} +9 -8
  25. package/dist/{chunk-KJCWXUUS.js → chunk-724UL2TJ.js} +6 -4
  26. package/dist/{chunk-MQA2YBAH.js → chunk-76MWC2K6.js} +3 -3
  27. package/dist/{chunk-XHSCVSOL.js → chunk-7DYBLXYA.js} +3 -3
  28. package/dist/{chunk-AFZYMAIV.js → chunk-7ULNCDCO.js} +37 -35
  29. package/dist/{chunk-VSMJK3ZJ.js → chunk-AOHZU2BM.js} +1 -1
  30. package/dist/{chunk-ZETYB3XG.js → chunk-ARJ6PLFH.js} +44 -28
  31. package/dist/{chunk-T4QZ6FEH.js → chunk-AW7R2GWG.js} +65 -8
  32. package/dist/{chunk-GAYGGICG.js → chunk-BKE7E7TC.js} +10 -9
  33. package/dist/{chunk-EUT3B22Y.js → chunk-BRGDSBJE.js} +13 -12
  34. package/dist/{chunk-T54VJRAD.js → chunk-C34ZXZ7O.js} +55 -11
  35. package/dist/{chunk-CBD2B5CP.js → chunk-CF24OIYI.js} +21 -20
  36. package/dist/{chunk-UGSMCQ4D.js → chunk-CHOW74WE.js} +1 -1
  37. package/dist/{chunk-OZJINN4O.js → chunk-CO2G5PHH.js} +2 -2
  38. package/dist/{chunk-OC7LYAU5.js → chunk-EETY4LF7.js} +24 -10
  39. package/dist/{chunk-KJN4IOEJ.js → chunk-EJIUXPBX.js} +1 -1
  40. package/dist/{chunk-IQZXOZ7S.js → chunk-ESBQHFMJ.js} +549 -271
  41. package/dist/{chunk-CFYISHUW.js → chunk-FLKWCIZH.js} +8 -5
  42. package/dist/{chunk-IUKPRZER.js → chunk-GAEGEPOC.js} +2 -2
  43. package/dist/{chunk-6XX5HCLK.js → chunk-GBPP5P7X.js} +4 -4
  44. package/dist/{chunk-3FERWMCH.js → chunk-GHB6AYCP.js} +27 -26
  45. package/dist/{chunk-NFXP47RV.js → chunk-GOYRYZ2R.js} +26 -24
  46. package/dist/{chunk-TQFBZVCG.js → chunk-GXW6K4YJ.js} +1 -1
  47. package/dist/{chunk-N7YNJE5R.js → chunk-GZYBXISR.js} +9 -9
  48. package/dist/{chunk-3JSEWUWI.js → chunk-IBGIOBEE.js} +3 -3
  49. package/dist/{chunk-OYTMZXRF.js → chunk-IBRALRBR.js} +15 -14
  50. package/dist/{chunk-5JHXUETW.js → chunk-IXXDFY73.js} +3 -3
  51. package/dist/chunk-IZSHAIJ7.js +26 -0
  52. package/dist/{chunk-7ELY2CSM.js → chunk-JAU72XNY.js} +16 -14
  53. package/dist/chunk-JMYYOTQG.js +77 -0
  54. package/dist/{chunk-ELVWJYRV.js → chunk-JSQFTSC6.js} +12 -11
  55. package/dist/{chunk-3P4PF2BX.js → chunk-JWA5I3SR.js} +34 -20
  56. package/dist/{chunk-J6DFZDFA.js → chunk-KBG47GHP.js} +4 -4
  57. package/dist/{chunk-XGUL4SLQ.js → chunk-L3BLXZG7.js} +2 -2
  58. package/dist/chunk-LOP6GRPH.js +31 -0
  59. package/dist/chunk-MQLUAEOC.js +162 -0
  60. package/dist/{chunk-3MRXIJ6I.js → chunk-MRXKYPCS.js} +2 -2
  61. package/dist/{chunk-G3RLJYA2.js → chunk-N2H3ZPZY.js} +47 -1
  62. package/dist/{chunk-HREZQCT3.js → chunk-N3X6Q4YT.js} +3 -3
  63. package/dist/{chunk-NJF2X5XF.js → chunk-NW7BOILN.js} +19 -17
  64. package/dist/{chunk-ZZUFZUQZ.js → chunk-ODBNXWT4.js} +275 -90
  65. package/dist/{chunk-HSIRMK2D.js → chunk-OG5UUPN7.js} +13 -13
  66. package/dist/{chunk-ZOEYVXSV.js → chunk-OXXKQCSV.js} +6 -6
  67. package/dist/{chunk-S6AMWKPC.js → chunk-P7266HLM.js} +2 -2
  68. package/dist/{chunk-JONGANYH.js → chunk-PFNSLWU5.js} +31 -30
  69. package/dist/{chunk-64LU2OVH.js → chunk-PHDMFAKM.js} +12 -2
  70. package/dist/{chunk-IMSQR4WO.js → chunk-PNQDPDRC.js} +1 -1
  71. package/dist/{chunk-MTDRLSI7.js → chunk-PV6LR5P5.js} +5398 -1156
  72. package/dist/{chunk-N77WFUL7.js → chunk-Q6ZWTCLY.js} +24 -22
  73. package/dist/{chunk-IUR76K6A.js → chunk-Q7DUK4LX.js} +5 -5
  74. package/dist/{chunk-CULQYFLU.js → chunk-QGQ5CCCG.js} +2 -2
  75. package/dist/{chunk-UEAHAMEI.js → chunk-QHJ6DQ2R.js} +11 -11
  76. package/dist/{chunk-BNKLYOOO.js → chunk-QILIYSJF.js} +1 -1
  77. package/dist/{chunk-VYKKMYVT.js → chunk-QOBUHWHX.js} +11 -6
  78. package/dist/{chunk-3PNFWVHT.js → chunk-QQNQ7SJW.js} +2 -75
  79. package/dist/{chunk-OEX24ECI.js → chunk-QZVW3AAK.js} +50 -41
  80. package/dist/{chunk-7M4T5N3V.js → chunk-R3PCY3YS.js} +14 -13
  81. package/dist/{chunk-MGIWSROG.js → chunk-RPLINGVB.js} +7 -7
  82. package/dist/{chunk-CMU4RMJB.js → chunk-RWWYJ623.js} +10 -1
  83. package/dist/{chunk-7BX5DWSA.js → chunk-SAEFPSB6.js} +11 -11
  84. package/dist/{chunk-6UYA642J.js → chunk-TYM6OUIT.js} +13 -12
  85. package/dist/{chunk-ALQRYH6O.js → chunk-UXGETRP4.js} +13 -12
  86. package/dist/{chunk-FGALODG3.js → chunk-UZ3TUTRV.js} +1 -1
  87. package/dist/{chunk-J3FZR3YY.js → chunk-VCHXCQFG.js} +3 -3
  88. package/dist/{chunk-DMS52BEP.js → chunk-VITUCP5A.js} +5 -5
  89. package/dist/{chunk-O7HZX7CA.js → chunk-VRZP76YM.js} +1 -1
  90. package/dist/{chunk-VZHJS6DR.js → chunk-VSSBEUFT.js} +16 -15
  91. package/dist/{chunk-U52SAGRM.js → chunk-VWCXW2E7.js} +1 -1
  92. package/dist/{chunk-WW5BLB74.js → chunk-WOA4LN2R.js} +2 -2
  93. package/dist/{chunk-IR6XFA5P.js → chunk-WOKKRCJ5.js} +15 -14
  94. package/dist/{chunk-ZMOMPX2Z.js → chunk-WU567RSC.js} +11 -10
  95. package/dist/{chunk-WSEWKCXU.js → chunk-XCJN5IJU.js} +4 -4
  96. package/dist/{chunk-D65GOCJB.js → chunk-XKIZ2HNN.js} +15 -14
  97. package/dist/{chunk-OYOB3ZFG.js → chunk-XMSXXAHW.js} +2 -2
  98. package/dist/chunk-XPZPXCBV.js +28 -0
  99. package/dist/{chunk-34OCDWOS.js → chunk-XTMJ7XDT.js} +1 -1
  100. package/dist/{chunk-Z6BB4JLQ.js → chunk-XVF2VVXP.js} +5 -3
  101. package/dist/chunk-Z527N6YQ.js +28 -0
  102. package/dist/{chunk-D6YF5HKX.js → chunk-ZANLILYD.js} +22 -2
  103. package/dist/{chunk-2UMYMRI3.js → chunk-ZGDGW2V3.js} +2 -2
  104. package/dist/{chunk-6B5I6ICN.js → chunk-ZHFZWTZV.js} +12 -11
  105. package/dist/{chunk-AXKPQ6ZI.js → chunk-ZXYDQ3TZ.js} +5 -5
  106. package/dist/index.js +72740 -70136
  107. package/dist/mcp/analyze-cli.js +18 -8
  108. package/dist/mcp/cli.js +48 -37
  109. package/dist/mcp/server.js +564 -394
  110. package/dist/mcp/worker.js +66 -55
  111. package/dist/probes/installer.js +20 -19
  112. package/docs/astplayground.md +1 -1
  113. package/docs/configuration.md +29 -0
  114. package/docs/dependencies.md +3 -0
  115. package/docs/features.md +2 -2
  116. package/docs/globalconfig.md +2 -0
  117. package/docs/language-coverage.md +2 -1
  118. package/docs/lsp-capability-matrix.md +29 -7
  119. package/docs/lsp-idle-eviction.md +38 -47
  120. package/docs/pi-lens-fixer.md +4 -0
  121. package/docs/pi-lens-merge-policy.md +5 -0
  122. package/docs/pi-lens-retro.md +2 -1
  123. package/docs/pi-lens-reviewer.md +15 -0
  124. package/docs/pi-lens-subagent.md +2 -0
  125. package/docs/real-harness.md +17 -0
  126. package/docs/schema/pi-lens-config-v1.json +37 -2
  127. package/docs/servercapabilities.md +15 -4
  128. package/docs/settings.md +2 -1
  129. package/package.json +1 -1
  130. package/dist/chunk-2FQ62SPM.js +0 -83
  131. package/dist/chunk-7AXO3ZDF.js +0 -30
  132. package/dist/chunk-KMGPUKFD.js +0 -25
  133. package/dist/chunk-RJFED73B.js +0 -79
  134. package/dist/chunk-RTQNRM5X.js +0 -27
  135. package/dist/chunk-V5MEBST3.js +0 -4139
  136. package/dist/chunk-VGEVL5EQ.js +0 -29
  137. package/dist/chunk-WPE5FPGR.js +0 -54
  138. package/dist/chunk-Z7QQA2KT.js +0 -27
@@ -2,74 +2,79 @@
2
2
  import { createRequire as __pilensCreateRequire } from "node:module"; const require = __pilensCreateRequire(import.meta.url);
3
3
  import {
4
4
  analyzeFile
5
- } from "../chunk-ZZUFZUQZ.js";
6
- import "../chunk-ZOEYVXSV.js";
7
- import "../chunk-KJN4IOEJ.js";
5
+ } from "../chunk-ODBNXWT4.js";
6
+ import "../chunk-OXXKQCSV.js";
7
+ import "../chunk-EJIUXPBX.js";
8
8
  import "../chunk-FC4RP4I2.js";
9
- import "../chunk-YLN4K6WD.js";
10
- import "../chunk-J3FZR3YY.js";
11
- import "../chunk-5JHXUETW.js";
12
- import "../chunk-3MRXIJ6I.js";
13
- import "../chunk-TA5L5KWQ.js";
14
- import "../chunk-FGALODG3.js";
15
- import "../chunk-OC7LYAU5.js";
16
- import "../chunk-NFXP47RV.js";
17
- import "../chunk-MGIWSROG.js";
18
- import "../chunk-WSEWKCXU.js";
19
- import "../chunk-MQA2YBAH.js";
20
- import "../chunk-TQFBZVCG.js";
21
- import "../chunk-WATC3IQR.js";
22
- import "../chunk-OYOB3ZFG.js";
23
- import "../chunk-XHSCVSOL.js";
24
- import "../chunk-V5MEBST3.js";
9
+ import "../chunk-66SXUJCA.js";
10
+ import "../chunk-VCHXCQFG.js";
11
+ import "../chunk-IXXDFY73.js";
12
+ import "../chunk-MRXKYPCS.js";
13
+ import "../chunk-2CD5RS6M.js";
14
+ import "../chunk-UZ3TUTRV.js";
15
+ import "../chunk-EETY4LF7.js";
16
+ import "../chunk-GOYRYZ2R.js";
17
+ import "../chunk-RPLINGVB.js";
18
+ import "../chunk-XCJN5IJU.js";
19
+ import "../chunk-76MWC2K6.js";
20
+ import "../chunk-GXW6K4YJ.js";
21
+ import "../chunk-2B73ZPOK.js";
22
+ import "../chunk-XMSXXAHW.js";
23
+ import "../chunk-7DYBLXYA.js";
24
+ import "../chunk-PV6LR5P5.js";
25
25
  import "../chunk-3MED75HT.js";
26
- import "../chunk-IMSQR4WO.js";
27
- import "../chunk-MTDRLSI7.js";
28
- import "../chunk-OZJINN4O.js";
29
- import "../chunk-3JSEWUWI.js";
26
+ import "../chunk-CO2G5PHH.js";
27
+ import "../chunk-IBGIOBEE.js";
28
+ import "../chunk-PNQDPDRC.js";
30
29
  import "../chunk-XIMYZ3JA.js";
31
- import "../chunk-IQZXOZ7S.js";
32
- import "../chunk-LNOMA3MP.js";
33
- import "../chunk-U52SAGRM.js";
30
+ import "../chunk-ESBQHFMJ.js";
31
+ import "../chunk-34WSVGEM.js";
32
+ import "../chunk-VWCXW2E7.js";
33
+ import "../chunk-ZXYDQ3TZ.js";
34
34
  import "../chunk-5W3R6LFT.js";
35
- import "../chunk-UEAHAMEI.js";
35
+ import "../chunk-QHJ6DQ2R.js";
36
36
  import "../chunk-Z54ZSOBZ.js";
37
- import "../chunk-KJCWXUUS.js";
37
+ import "../chunk-724UL2TJ.js";
38
38
  import "../chunk-QOZXJ4NA.js";
39
- import "../chunk-6XX5HCLK.js";
40
- import "../chunk-S6AMWKPC.js";
41
- import "../chunk-F5VLZHUW.js";
42
- import "../chunk-AXKPQ6ZI.js";
43
- import "../chunk-7BX5DWSA.js";
44
- import "../chunk-IUKPRZER.js";
39
+ import "../chunk-GBPP5P7X.js";
40
+ import "../chunk-P7266HLM.js";
41
+ import "../chunk-MQLUAEOC.js";
42
+ import "../chunk-52FUZI6K.js";
43
+ import "../chunk-SAEFPSB6.js";
44
+ import "../chunk-GAEGEPOC.js";
45
45
  import "../chunk-Z3CCVDUB.js";
46
- import "../chunk-XGUL4SLQ.js";
46
+ import "../chunk-L3BLXZG7.js";
47
47
  import "../chunk-2BEMIWEW.js";
48
- import "../chunk-LD7WFTRX.js";
49
- import "../chunk-IUR76K6A.js";
50
- import "../chunk-T4QZ6FEH.js";
51
- import "../chunk-D6YF5HKX.js";
52
- import "../chunk-CMU4RMJB.js";
53
- import "../chunk-O7HZX7CA.js";
54
- import "../chunk-VYKKMYVT.js";
55
- import "../chunk-BNKLYOOO.js";
56
- import "../chunk-USHG4DLH.js";
57
- import "../chunk-H5EV3VMF.js";
58
- import "../chunk-T54VJRAD.js";
48
+ import "../chunk-66VMUL7Q.js";
49
+ import "../chunk-Q7DUK4LX.js";
50
+ import "../chunk-AW7R2GWG.js";
51
+ import "../chunk-RWWYJ623.js";
52
+ import "../chunk-VRZP76YM.js";
53
+ import "../chunk-QOBUHWHX.js";
54
+ import "../chunk-QILIYSJF.js";
55
+ import "../chunk-6C7JWPCP.js";
56
+ import "../chunk-5NGR67U5.js";
57
+ import "../chunk-C34ZXZ7O.js";
59
58
  import "../chunk-BW5KFIQC.js";
60
59
  import "../chunk-QYF5S6P6.js";
61
- import "../chunk-64LU2OVH.js";
62
- import "../chunk-N2IRDBZI.js";
63
- import "../chunk-Z6BB4JLQ.js";
60
+ import "../chunk-PHDMFAKM.js";
61
+ import "../chunk-2BBLFX75.js";
62
+ import "../chunk-XVF2VVXP.js";
63
+ import {
64
+ setProjectTrustState
65
+ } from "../chunk-ZANLILYD.js";
64
66
  import "../chunk-2EECBNC5.js";
65
- import "../chunk-7ELY2CSM.js";
66
- import "../chunk-34OCDWOS.js";
67
- import "../chunk-3PNFWVHT.js";
68
- import "../chunk-VSMJK3ZJ.js";
67
+ import "../chunk-JAU72XNY.js";
68
+ import {
69
+ logExtension
70
+ } from "../chunk-XTMJ7XDT.js";
71
+ import "../chunk-JMYYOTQG.js";
72
+ import "../chunk-QQNQ7SJW.js";
73
+ import "../chunk-AOHZU2BM.js";
69
74
  import "../chunk-LJDODBBZ.js";
70
- import "../chunk-UGSMCQ4D.js";
75
+ import "../chunk-CHOW74WE.js";
71
76
  import "../chunk-ABBOA7UD.js";
72
- import "../chunk-G3RLJYA2.js";
77
+ import "../chunk-N2H3ZPZY.js";
73
78
  import "../chunk-NXL4FFQQ.js";
74
79
 
75
80
  // dist/mcp/worker.js
@@ -79,6 +84,12 @@ function arg(name) {
79
84
  return found ? found.slice(prefix.length) : void 0;
80
85
  }
81
86
  async function main() {
87
+ setProjectTrustState("trusted");
88
+ logExtension({
89
+ subsystem: "project-trust",
90
+ level: "debug",
91
+ message: "mcp-worker: workspace trust belongs to the MCP client; pi trust not consulted"
92
+ });
82
93
  const file = arg("file");
83
94
  const cwd = arg("cwd") ?? process.cwd();
84
95
  if (!file) {
@@ -53,30 +53,31 @@ import {
53
53
  verifyNpmPackageEntry,
54
54
  verifyToolBinary,
55
55
  wasLastResolveTransient
56
- } from "../chunk-LD7WFTRX.js";
57
- import "../chunk-IUR76K6A.js";
58
- import "../chunk-T4QZ6FEH.js";
59
- import "../chunk-D6YF5HKX.js";
60
- import "../chunk-CMU4RMJB.js";
61
- import "../chunk-O7HZX7CA.js";
62
- import "../chunk-VYKKMYVT.js";
63
- import "../chunk-BNKLYOOO.js";
64
- import "../chunk-USHG4DLH.js";
65
- import "../chunk-H5EV3VMF.js";
66
- import "../chunk-T54VJRAD.js";
56
+ } from "../chunk-66VMUL7Q.js";
57
+ import "../chunk-Q7DUK4LX.js";
58
+ import "../chunk-AW7R2GWG.js";
59
+ import "../chunk-RWWYJ623.js";
60
+ import "../chunk-VRZP76YM.js";
61
+ import "../chunk-QOBUHWHX.js";
62
+ import "../chunk-QILIYSJF.js";
63
+ import "../chunk-6C7JWPCP.js";
64
+ import "../chunk-5NGR67U5.js";
65
+ import "../chunk-C34ZXZ7O.js";
67
66
  import "../chunk-BW5KFIQC.js";
68
67
  import "../chunk-QYF5S6P6.js";
69
- import "../chunk-64LU2OVH.js";
70
- import "../chunk-N2IRDBZI.js";
71
- import "../chunk-Z6BB4JLQ.js";
68
+ import "../chunk-PHDMFAKM.js";
69
+ import "../chunk-2BBLFX75.js";
70
+ import "../chunk-XVF2VVXP.js";
71
+ import "../chunk-ZANLILYD.js";
72
72
  import "../chunk-2EECBNC5.js";
73
- import "../chunk-7ELY2CSM.js";
74
- import "../chunk-34OCDWOS.js";
75
- import "../chunk-3PNFWVHT.js";
76
- import "../chunk-VSMJK3ZJ.js";
73
+ import "../chunk-JAU72XNY.js";
74
+ import "../chunk-XTMJ7XDT.js";
75
+ import "../chunk-JMYYOTQG.js";
76
+ import "../chunk-QQNQ7SJW.js";
77
+ import "../chunk-AOHZU2BM.js";
77
78
  import "../chunk-LJDODBBZ.js";
78
79
  import "../chunk-ABBOA7UD.js";
79
- import "../chunk-G3RLJYA2.js";
80
+ import "../chunk-N2H3ZPZY.js";
80
81
  import "../chunk-NXL4FFQQ.js";
81
82
  export {
82
83
  GITHUB_TOOLS,
@@ -17,7 +17,7 @@ The shipped rule set runs in two engines:
17
17
 
18
18
  | Path | Engine | Source |
19
19
  |------|--------|--------|
20
- | ast-grep LSP (the live path) | upstream binary, auto-installed by `ensureTool` | the binary's `ast-grep` version may be ahead of `npx ast-grep@x` |
20
+ | ast-grep LSP (the live path) | upstream binary, auto-installed by `ensureTool` | the binary's `ast-grep` version may be ahead of the npm `@ast-grep/cli` version |
21
21
  | ast-grep napi runner (fallback) | `@ast-grep/napi` npm package, version-pinned in `package.json` | can lag the binary by a release |
22
22
 
23
23
  The CLI test in `tests/clients/dispatch/runners/ast-grep-catalog-rules.test.ts`
@@ -10,6 +10,13 @@ There are **two** pi-lens config files:
10
10
  Both files have the same shape, with one exception noted below the example:
11
11
  everything LSP-related lives under an `lsp` namespace inside them.
12
12
 
13
+ Executable LSP fields from a project config are admitted only when pi has
14
+ marked the project trusted. This includes custom `command` values, command
15
+ overrides, `env`, and `initializationOptions`; an untrusted or older host is
16
+ fail-closed and emits one bounded notice telling you to mark the project
17
+ trusted in pi or upgrade pi. Global config remains trusted, and a project can
18
+ always disable a server. pi-lens does not maintain a second trust setting.
19
+
13
20
  The editor-facing JSON Schema is published at
14
21
  [`docs/schema/pi-lens-config-v1.json`](schema/pi-lens-config-v1.json). LSP
15
22
  server entries also accept canonical argv arrays, optional `name` (defaulting
@@ -44,6 +51,10 @@ schema slice does not change server launch behavior.
44
51
  }
45
52
  ```
46
53
 
54
+ An override may also provide an experimental launcher `command` and `env`.
55
+ The built-in server ID and strategy remain in force; only the launcher is
56
+ replaced, and project-sourced launcher fields follow the same pi trust gate.
57
+
47
58
  Each model-facing tool accepts `tools.<name>.enabled` in the config file. Valid
48
59
  names include `ast_grep_search`, `ast_grep_replace`, `ast_grep_outline`,
49
60
  `lsp_navigation`, `lens_diagnostics`,
@@ -53,6 +64,24 @@ names include `ast_grep_search`, `ast_grep_replace`, `ast_grep_outline`,
53
64
  lifecycle tools `session_start`, `turn_end`, and `session_end` remain enabled
54
65
  because their host protocols require them.
55
66
 
67
+ To see the resolved tool surface, use `/lens-health`; the `effective_config`
68
+ tool provides the full configuration provenance. Bundled skills are managed by
69
+ pi's package-manifest filters.
70
+
71
+ ### Session-start orientation
72
+
73
+ The session-start orientation names only the tools pi-lens actually registered.
74
+ A tool disabled with `tools.<name>.enabled: false` is never advertised, so the
75
+ orientation cannot direct the agent to a tool it cannot call. The tool roster is
76
+ the same registry that drives registration; there is no second list.
77
+
78
+ `contextInjection.requirePreExistingFixes` (default `true`) controls one
79
+ sentence in that orientation: whether pre-existing blocking errors must be
80
+ fixed. Set it to `false` when the task's scope excludes pre-existing debt. The
81
+ orientation then requires fixes only for blocking errors the agent's own edits
82
+ introduce; pre-existing ones are reported, not demanded. It is a global setting,
83
+ like every `contextInjection` key.
84
+
56
85
  ### `lsp.servers.<id>.covers` — declaring which runners a custom server subsumes
57
86
 
58
87
  A custom server entry accepts an optional `covers` array naming dispatch
@@ -28,6 +28,7 @@ Auto-install behavior depends on gate type:
28
28
  | `shellcheck` | Shell script linting | Yes | GitHub release |
29
29
  | `shfmt` | Shell script formatting | Yes | GitHub release |
30
30
  | `rust-analyzer` | Rust LSP | Yes | GitHub release |
31
+ | `lake serve` | Lean 4 LSP | No | `lake` must be on PATH; uses the project's Lean toolchain |
31
32
  | `golangci-lint` | Go linting | Yes | GitHub release |
32
33
  | `hadolint` | Dockerfile linting | Yes | GitHub release |
33
34
  | `ktlint` | Kotlin linting | Yes | GitHub release |
@@ -51,6 +52,8 @@ Auto-install behavior depends on gate type:
51
52
  | `trivy` | Dependency-CVE session scan | Auto-install | Explicit opt-in (`trivy.enabled`) |
52
53
  | `psscriptanalyzer` | PowerShell linting | Manual | — |
53
54
 
55
+ Lean LSP is launched as `lake serve` from the detected Lake project root, so elan selects the toolchain from that project's `lean-toolchain` file and Lake supplies its project environment. pi-lens does not install or manage Lean/elan; install Lean and Lake separately and ensure `lake` is on `PATH`.
56
+
54
57
  Additional language servers (gopls, ruby-lsp, solargraph, etc.) are auto-detected from PATH or installed via native package managers (`go install`, `gem install`) when their language is detected.
55
58
 
56
59
  ## Pip tool installation order
package/docs/features.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  ### LSP Support
4
4
 
5
- pi-lens includes **48 language server definitions** (including four cross-cutting *auxiliary* scanners that attach alongside the file's language server — Opengrep, ast-grep, zizmor, and typos — see below). LSP is **enabled by default**; use `--no-lsp` to disable it for a session. Servers are auto-discovered from PATH, project `node_modules`, and managed installs. When a server is not installed, pi-lens offers an interactive install prompt.
5
+ pi-lens includes **49 language server definitions** (including four cross-cutting *auxiliary* scanners that attach alongside the file's language server — Opengrep, ast-grep, zizmor, and typos — see below). LSP is **enabled by default**; use `--no-lsp` to disable it for a session. Servers are auto-discovered from PATH, project `node_modules`, and managed installs. When a server with a managed installer is not installed, pi-lens offers an interactive install prompt; toolchain-bundled servers, such as Lean's `lake`, are PATH-only, and pi-lens never installs or manages them.
6
6
 
7
7
  **LSP Idle Management:** LSP servers shut down after 240 seconds of inactivity (no files modified) to free resources. The timer resets when you resume editing, preventing cold-start penalties during active development.
8
8
 
@@ -19,7 +19,7 @@ pi-lens includes **48 language server definitions** (including four cross-cuttin
19
19
  - **`capabilities`** — shows which operations are supported by the active LSP server(s) for a file, read directly from the cached `initialize` response (no round-trip).
20
20
  - **Symbol column resolution** — passing `symbol: "myFunc"` instead of an exact `character` position resolves the correct column automatically. Use `symbol: "foo#2"` for the second occurrence of `foo` on the line.
21
21
 
22
- LSP servers for: TypeScript, Deno, Python (pyright/basedpyright + jedi), Go, Rust, Ruby (ruby-lsp + solargraph), PHP, PowerShell, C# (omnisharp), F#, Java (JDT LS, with Lombok javaagent support when a Lombok jar is available), Kotlin, Swift, Dart, Lua, C/C++, Zig, Haskell, Elixir, Gleam, Typst (tinymist), Markdown (marksman), OCaml, Clojure, CUE (syntax and parse diagnostics; evaluation errors via the cue-vet auxiliary runner), Terraform, Nix, Bash, Shuck (zsh-aware shell language server), Fish, CMake, Docker, YAML, JSON, HTML, TOML, Prisma, Vue, Svelte, CSS.
22
+ LSP servers for: TypeScript, Deno, Python (pyright/basedpyright + jedi), Go, Rust, Ruby (ruby-lsp + solargraph), PHP, PowerShell, C# (omnisharp), F#, Java (JDT LS, with Lombok javaagent support when a Lombok jar is available), Kotlin, Lean, Swift, Dart, Lua, C/C++, Zig, Haskell, Elixir, Gleam, Typst (tinymist), Markdown (marksman), OCaml, Clojure, CUE (syntax and parse diagnostics; evaluation errors via the cue-vet auxiliary runner), Terraform, Nix, Bash, Shuck (zsh-aware shell language server), Fish, CMake, Docker, YAML, JSON, HTML, TOML, Prisma, Vue, Svelte, CSS.
23
23
 
24
24
  ### Formatters
25
25
 
@@ -112,6 +112,8 @@ Hide the diagnostics widget by default, run formatting immediately after write/e
112
112
 
113
113
  `contextInjection.enabled` (default `true`) controls whether pi-lens prepends automatic findings — session-start guidance, turn-end findings, and test findings — into the next model turn. Set it to `false` (or use `--no-lens-context` / `PI_LENS_NO_CONTEXT_INJECTION=1` / `/lens-context-toggle`) to keep tools, LSP, read-guard, and formatting running while avoiding the prompt-cache invalidation that injected messages cause in long, cache-sensitive sessions. Findings are still cached, so `lens_diagnostics` and `/lens-health` keep working.
114
114
 
115
+ `contextInjection.requirePreExistingFixes` (default `true`) controls whether the session-start orientation tells the agent to fix pre-existing blocking errors; set `false` to scope that demand to errors its own edits introduce.
116
+
115
117
  `actionableWarnings.enabled` gates the turn_end report. `includeLspCodeActions` fetches LSP code actions for each warning (requires an active language server). `deltaOnly` (default `true`) limits the report to lines touched in the current turn. `autoFix.enabled` applies conservative LSP quickfixes at `agent_end`; `autoFix.maxFixes` caps the number applied per turn (default `5`, must be a non-negative whole number). `maxFixes: 0` keeps the report and applies nothing, which is a useful halfway step before enabling `autoFix` for real. Unlike the toggles in the table above there is no CLI counterpart, since it takes a number rather than being on or off.
116
118
 
117
119
  `turnEnd.madge.enabled` (default `false`) runs the per-turn-end madge circular-dependency check on import-changed files. It is off by default because that pass only writes debug output — user-facing madge diagnostics come from the session-start scan cache and the `lens_diagnostics` extractor — and its subprocess spawns dominated the turn-end latency tail (#766). Enable it with `--lens-turn-end-madge` or `turnEnd.madge.enabled: true` if you want the per-edit circular-dependency note.
@@ -1,6 +1,6 @@
1
1
  # Language Coverage
2
2
 
3
- pi-lens supports **36+ languages** through dispatch runners and LSP integration.
3
+ pi-lens supports **37+ languages** through dispatch runners and LSP integration.
4
4
 
5
5
  Formatting uses a single selected formatter per file: explicit project config wins, otherwise pi-lens uses a smart default where supported, and config-first ecosystems do not autoformat without config.
6
6
 
@@ -33,6 +33,7 @@ Dispatch is diagnostics-oriented: automatic formatting and safe autofix happen i
33
33
  | Java | ✓ | lsp, javac | google-java-format |
34
34
  | Java + Lombok | ✓ | JDT LS launched with `-javaagent:<lombok.jar>` when Lombok is detected and a jar is found (`PI_LENS_LOMBOK_JAR` / `LOMBOK_JAR`, project `.lombok/lombok.jar`, or Maven/Gradle cache) | google-java-format |
35
35
  | Kotlin | ✓ | lsp, ktlint, detekt | ktlint |
36
+ | Lean 4 | ✓ (Lake `serve`) | lsp; uses each project's Lake toolchain and environment | — |
36
37
  | Swift | ✓ | lsp, swiftlint | swiftformat |
37
38
  | Dart | ✓ | lsp, dart-analyze | dart format |
38
39
  | Lua | ✓ | lsp | stylua |
@@ -1,5 +1,22 @@
1
1
  # LSP capability matrix — affirmative-clean-signal strategy
2
2
 
3
+ ## Project-code trust class (#4269)
4
+
5
+ Some global language-server binaries execute repository-owned build, plugin, or
6
+ macro code while starting or indexing. The built-in registry marks these with
7
+ `executesProjectCode`; the launch gate refuses them unless pi reports the
8
+ project as trusted. Unknown trust is a `spawn-failed` refusal, not
9
+ `tool-not-found`, and does not install or retry the server. The class currently
10
+ includes rust-analyzer (Cargo `build.rs` and proc macros), Ruby LSP
11
+ (Bundler/Gemfile composed-bundle setup), PowerShell Editor Services (workspace
12
+ modules), C# / F# servers (MSBuild targets), JDT LS and Kotlin (Gradle/Maven),
13
+ SourceKit-LSP (SwiftPM plugins), Haskell Language Server (Cabal/Stack and
14
+ Template Haskell), ElixirLS / Expert (`mix compile`), and the project-configured
15
+ analysis servers whose startup evaluates workspace configuration: Dart, ZLS,
16
+ OCaml, Clojure, Terraform, Nix, CMake, Vue, and Svelte. Lean is tracked by
17
+ #4122 and will declare itself when that change lands. gopls is excluded: its
18
+ startup/index discovery uses `go list`; cgo is not compiled by gopls startup.
19
+
3
20
  How pi-lens knows a just-edited file is **clean** (no diagnostics) vs the server
4
21
  simply **hasn't answered yet** (cold/crashed/silent). pi-lens waits *synchronously*
5
22
  for a verdict, so — unlike an editor, which renders asynchronously and never needs
@@ -68,8 +85,10 @@ discriminator either.
68
85
 
69
86
  `tests/config/lsp-first-publish-census.test.ts` compares this column against the
70
87
  `emptyFirstPublish` markers and reds in BOTH directions, which is the expiry
71
- check: when the nightly re-measures a server into a different class, the docs
72
- refresh cannot merge until the marker is updated with it.
88
+ check: when two consecutive nights re-measure a server into a different class,
89
+ the docs refresh commits the confirmed class and the marker must move with it.
90
+ A single-night flip remains in the refresh-state JSON below and does not change
91
+ the census's confirmed population.
73
92
 
74
93
  ## The strategies
75
94
 
@@ -148,7 +167,7 @@ carries the named admission until then.
148
167
  | deno | deno (alt of typescript) | pull | — | n/a (pull) | 1 | dev+ci |
149
168
  | ruby | ruby-lsp | pull | — | n/a (pull) | 1 | ci |
150
169
  | csharp | csharp-ls | pull | — | n/a (pull) | 1 | ci |
151
- | typescript | typescript-language-server | push-only | silent | direct | 3 | dev+ci |
170
+ | typescript | typescript-language-server | push-only | silent | empty-first | 3 | dev+ci |
152
171
  | markdown | marksman | push-only | silent | direct | 3 | ci |
153
172
  | lua | lua-language-server | push-only | silent | direct | 3 | dev+ci |
154
173
  | python | pyright | push-only | publishes-versioned | direct | 2 | dev+ci |
@@ -156,7 +175,7 @@ carries the named admission until then.
156
175
  | yaml | yaml-language-server | push-only | publishes-unversioned | direct | 2* | dev+ci |
157
176
  | shell | bash-language-server | push-only | publishes-versioned | direct | 2 | dev+ci |
158
177
  | dockerfile | docker-langserver | push-only | publishes-unversioned | direct | 2* | dev+ci |
159
- | dockerfile-official | docker-language-server (official) | push-only | unknown | empty-only | ? | dev+ci |
178
+ | dockerfile-official | docker-language-server (official) | push-only | publishes-versioned | direct | 2 | dev+ci |
160
179
  | toml | taplo | push-only | publishes-unversioned | direct | 2* | dev+ci |
161
180
  | terraform | terraform-ls | push-only | publishes-unversioned | empty-first | 2* | dev+ci |
162
181
  | prisma | @prisma/language-server | push-only | publishes-unversioned | direct | 2* | dev+ci |
@@ -211,6 +230,9 @@ and were characterized `push-only` in the run above).
211
230
  `first-publish` measurements on the dev box, 2026-09-23: php `empty-first`,
212
231
  typescript / opengrep / ast-grep / marksman `direct` (so the class does not
213
232
  extend to them on the measurement, whatever their comments suggest).
233
+ - The official Docker row's clean-gate witness requires the BuildKit-backed
234
+ `JSONArgsRecommended` rule and skips when `docker buildx` is unavailable;
235
+ its first-publish class is the nightly's measured `direct`.
214
236
  - **#458's learned-deadline target set = the tier-3 rows only.** 2\* rows resolve
215
237
  the wait at runtime and must NOT be given learned deadlines.
216
238
  - **Tier 3 is budget-bound by necessity**, not laziness: a silent server's silence is
@@ -256,10 +278,10 @@ _None observed as of the last probe run._
256
278
 
257
279
  ## Capability matrix refresh state (nightly-generated)
258
280
 
259
- Bookkeeping for the date-based `direct` `first-publish` expiry (#3401), the
260
- two-run `clean-behavior` hysteresis and the consecutive-night `idle-eviction`
281
+ Bookkeeping for the two-run `first-publish`/`clean-behavior` hysteresis, the
282
+ date-based `direct` expiry (#3401) and consecutive-night `idle-eviction`
261
283
  counts (#3989). Regenerated every run; never a measurement.
262
284
 
263
285
  ```json
264
- {"clean-behavior":{"dockerfile-official":{"pendingBehavior":"publishes-versioned","pendingTier":"2","runs":1}},"idle-eviction":{"docker":{"nights":[{"day":"2026-10-07","rssMb":64,"coldMs":566}]},"json":{"nights":[{"day":"2026-10-07","rssMb":67,"coldMs":1116}]},"powershell":{"nights":[{"day":"2026-10-07","rssMb":155,"coldMs":2601}]},"python-jedi":{"nights":[{"day":"2026-10-07","rssMb":51,"coldMs":1796}]},"zizmor":{"nights":[{"day":"2026-10-07","rssMb":58,"coldMs":608}]}}}
286
+ {"first-publish":{"dockerfile":{"firstMissed":"2026-10-10"},"prisma":{"firstMissed":"2026-10-10"},"python":{"firstMissed":"2026-10-10"},"shell":{"firstMissed":"2026-10-10"},"terraform":{"pendingFirstPublish":"direct","runs":1},"yaml":{"firstMissed":"2026-10-10"}}}
265
287
  ```
@@ -15,7 +15,7 @@ respawned server reports every finding it reported before eviction; the
15
15
  content-bound coverage check the auxiliary freeze depends on. A server that
16
16
  cannot demonstrate it is never proposed for eviction on perf grounds alone.
17
17
 
18
- _Last generated: 2026-10-07 on linux; 48 registry servers: 32 eligible, 0 vetoed, 2 inconclusive, 14 unavailable (0 not reached: budget)._
18
+ _Last generated: 2026-10-10 on linux; 48 registry servers: 8 eligible, 0 vetoed, 16 inconclusive, 24 unavailable (0 not reached: budget)._
19
19
 
20
20
  ## Per-server rows
21
21
 
@@ -35,54 +35,54 @@ step log only, because it flaps.
35
35
 
36
36
  | server | role | declared | result | reason | respawn | coverage |
37
37
  |---|---|---|---|---|---|---|
38
- | ast-grep | auxiliary | unmeasured | eligible | · | ok | preserved |
39
- | bash | primary | transparent | eligible | · | ok | preserved |
38
+ | ast-grep | auxiliary | unmeasured | inconclusive | not-evicted | not-evicted | n/a |
39
+ | bash | primary | transparent | unavailable | server-not-started | n/a | n/a |
40
40
  | clojure | primary | transparent | eligible | · | ok | preserved |
41
41
  | cmake | primary | unmeasured | inconclusive | no-baseline | n/a | unproven |
42
42
  | cpp | primary | transparent | eligible | · | ok | preserved |
43
43
  | csharp | primary | unmeasured | unavailable | tool-unavailable | n/a | n/a |
44
- | css | primary | transparent | eligible | · | ok | preserved |
45
- | cue | primary | unmeasured | eligible | · | ok | preserved |
44
+ | css | primary | transparent | unavailable | server-not-started | n/a | n/a |
45
+ | cue | primary | unmeasured | inconclusive | not-evicted | not-evicted | n/a |
46
46
  | dart | primary | unmeasured | unavailable | tool-unavailable | n/a | n/a |
47
47
  | deno | primary | transparent | eligible | · | ok | preserved |
48
- | docker | primary | unmeasured | eligible | · | ok | preserved |
49
- | docker-official | primary | unmeasured | eligible | · | ok | preserved |
48
+ | docker | primary | transparent | unavailable | server-not-started | n/a | n/a |
49
+ | docker-official | primary | unmeasured | inconclusive | not-evicted | not-evicted | n/a |
50
50
  | elixir | primary | unmeasured | unavailable | tool-unavailable | n/a | n/a |
51
- | expert | primary | unmeasured | eligible | · | ok | preserved |
52
- | fish | primary | transparent | eligible | · | ok | preserved |
51
+ | expert | primary | unmeasured | inconclusive | not-evicted | not-evicted | n/a |
52
+ | fish | primary | transparent | unavailable | server-not-started | n/a | n/a |
53
53
  | fsharp | primary | unmeasured | unavailable | tool-unavailable | n/a | n/a |
54
- | gleam | primary | unmeasured | eligible | · | ok | preserved |
54
+ | gleam | primary | unmeasured | inconclusive | not-evicted | not-evicted | n/a |
55
55
  | go | primary | unmeasured | unavailable | tool-unavailable | n/a | n/a |
56
56
  | haskell | primary | unmeasured | unavailable | tool-unavailable | n/a | n/a |
57
- | html | primary | transparent | eligible | · | ok | preserved |
57
+ | html | primary | transparent | unavailable | server-not-started | n/a | n/a |
58
58
  | java | primary | unmeasured | unavailable | tool-unavailable | n/a | n/a |
59
- | json | primary | unmeasured | eligible | · | ok | preserved |
60
- | kotlin | primary | unmeasured | eligible | · | ok | preserved |
61
- | lua | primary | unmeasured | eligible | · | ok | preserved |
59
+ | json | primary | transparent | eligible | · | ok | preserved |
60
+ | kotlin | primary | unmeasured | inconclusive | not-evicted | not-evicted | n/a |
61
+ | lua | primary | unmeasured | inconclusive | not-evicted | not-evicted | n/a |
62
62
  | marksman | primary | transparent | eligible | · | ok | preserved |
63
63
  | nix | primary | unmeasured | unavailable | tool-unavailable | n/a | n/a |
64
64
  | ocaml | primary | unmeasured | unavailable | tool-unavailable | n/a | n/a |
65
65
  | omnisharp | primary | unmeasured | unavailable | no-fixture | n/a | n/a |
66
66
  | opengrep | auxiliary | transparent | eligible | · | ok | preserved |
67
- | php | primary | transparent | eligible | · | ok | preserved |
68
- | powershell | primary | unmeasured | eligible | · | ok | preserved |
69
- | prisma | primary | transparent | eligible | · | ok | preserved |
70
- | python | primary | transparent | eligible | · | ok | preserved |
71
- | python-jedi | primary | unmeasured | eligible | · | ok | preserved |
67
+ | php | primary | transparent | unavailable | server-not-started | n/a | n/a |
68
+ | powershell | primary | unmeasured | inconclusive | not-evicted | not-evicted | n/a |
69
+ | prisma | primary | transparent | unavailable | server-not-started | n/a | n/a |
70
+ | python | primary | transparent | unavailable | server-not-started | n/a | n/a |
71
+ | python-jedi | primary | transparent | eligible | · | ok | preserved |
72
72
  | ruby | primary | unmeasured | unavailable | tool-unavailable | n/a | n/a |
73
- | rust | primary | unmeasured | eligible | · | ok | preserved |
73
+ | rust | primary | unmeasured | inconclusive | not-evicted | not-evicted | n/a |
74
74
  | shuck | primary | unmeasured | unavailable | server-not-started | n/a | n/a |
75
- | svelte | primary | unmeasured | eligible | · | ok | preserved |
75
+ | svelte | primary | unmeasured | unavailable | server-not-started | n/a | n/a |
76
76
  | swift | primary | unmeasured | unavailable | tool-unavailable | n/a | n/a |
77
- | terraform | primary | unmeasured | eligible | · | ok | preserved |
78
- | tinymist | primary | unmeasured | eligible | · | ok | preserved |
79
- | toml | primary | unmeasured | eligible | · | ok | preserved |
77
+ | terraform | primary | unmeasured | inconclusive | not-evicted | not-evicted | n/a |
78
+ | tinymist | primary | unmeasured | inconclusive | not-evicted | not-evicted | n/a |
79
+ | toml | primary | unmeasured | inconclusive | not-evicted | not-evicted | n/a |
80
80
  | typescript | primary | transparent | eligible | · | ok | preserved |
81
- | typos | auxiliary | unmeasured | eligible | · | ok | preserved |
82
- | vue | primary | unmeasured | inconclusive | no-baseline | n/a | unproven |
83
- | yaml | primary | transparent | eligible | · | ok | preserved |
84
- | zig | primary | unmeasured | eligible | · | ok | preserved |
85
- | zizmor | auxiliary | unmeasured | eligible | · | ok | preserved |
81
+ | typos | auxiliary | unmeasured | inconclusive | not-evicted | not-evicted | n/a |
82
+ | vue | primary | unmeasured | unavailable | server-not-started | n/a | n/a |
83
+ | yaml | primary | transparent | unavailable | server-not-started | n/a | n/a |
84
+ | zig | primary | unmeasured | inconclusive | not-evicted | not-evicted | n/a |
85
+ | zizmor | auxiliary | unmeasured | inconclusive | not-evicted | not-evicted | n/a |
86
86
 
87
87
  ## Declared versus measured
88
88
 
@@ -90,24 +90,15 @@ step log only, because it flaps.
90
90
  or `info` line is for a maintainer to act on in a follow-up; this run changed
91
91
  nothing.
92
92
 
93
- - **ast-grep** [proposal] declared unmeasured but eviction and respawn preserved its findings
94
- - **cue** [proposal] declared unmeasured but eviction and respawn preserved its findings
95
- - **docker** [proposal] declared unmeasured but eviction and respawn preserved its findings
96
- - **expert** [proposal] declared unmeasured but eviction and respawn preserved its findings
97
- - **gleam** [proposal] declared unmeasured but eviction and respawn preserved its findings
98
- - **json** [proposal] declared unmeasured but eviction and respawn preserved its findings
99
- - **kotlin** [proposal] declared unmeasured but eviction and respawn preserved its findings
100
- - **lua** [proposal] declared unmeasured but eviction and respawn preserved its findings
101
- - **powershell** [proposal] declared unmeasured but eviction and respawn preserved its findings
102
- - **python-jedi** [proposal] declared unmeasured but eviction and respawn preserved its findings
103
- - **rust** [proposal] declared unmeasured but eviction and respawn preserved its findings
104
- - **svelte** [proposal] declared unmeasured but eviction and respawn preserved its findings
105
- - **terraform** [proposal] declared unmeasured but eviction and respawn preserved its findings
106
- - **tinymist** [proposal] declared unmeasured but eviction and respawn preserved its findings
107
- - **toml** [proposal] declared unmeasured but eviction and respawn preserved its findings
108
- - **typos** [proposal] declared unmeasured but eviction and respawn preserved its findings
109
- - **zig** [proposal] declared unmeasured but eviction and respawn preserved its findings
110
- - **zizmor** [proposal] declared unmeasured but eviction and respawn preserved its findings
93
+ - **bash** [info] declared transparent with no evidence this run: unavailable (server-not-started)
94
+ - **css** [info] declared transparent with no evidence this run: unavailable (server-not-started)
95
+ - **docker** [info] declared transparent with no evidence this run: unavailable (server-not-started)
96
+ - **fish** [info] declared transparent with no evidence this run: unavailable (server-not-started)
97
+ - **html** [info] declared transparent with no evidence this run: unavailable (server-not-started)
98
+ - **php** [info] declared transparent with no evidence this run: unavailable (server-not-started)
99
+ - **prisma** [info] declared transparent with no evidence this run: unavailable (server-not-started)
100
+ - **python** [info] declared transparent with no evidence this run: unavailable (server-not-started)
101
+ - **yaml** [info] declared transparent with no evidence this run: unavailable (server-not-started)
111
102
 
112
103
  ## Reasons
113
104
 
@@ -10,6 +10,10 @@ mechanics"; a brief supplies only `lane=<name>`, scope, and the grant.
10
10
 
11
11
  ## Before code
12
12
 
13
+ Before mocking a `clients/` module, look for its test seam (`set*`, `adopt*`, or
14
+ `reset*`). The pre-flight must list the mock dependents of any module whose
15
+ exports change.
16
+
13
17
  - Trace the production entry point and reproduce the defect through it
14
18
  (principles §1, "Premise first"). Name no seam before the reproduction; the
15
19
  red reproduction is your feedback loop, built before any theory of the fix.
@@ -611,6 +611,11 @@ Each row cost a lane at least once; the prose above carries the record.
611
611
 
612
612
  | Mistake | Fix |
613
613
  |---------|-----|
614
+ | Writing incident numbers and examples into an `AGENTS.md` rule | AGENTS.md stays lean; issues, PRs and examples go to `HISTORY.md` (maintainer, 2026-10-10). `tests/config/agents-governance.test.ts` ratchets the reference count down only |
615
+ | Routing a review finding as one PR's bug when it is a member of a class | Name the shape, grep for members, and record the verdict before the fix round; `plegma-delegate-guard` refuses a fix brief with a HIGH/MEDIUM finding and no `Shape:` line |
616
+ | Taking a causal premise ("a later merge dropped X") from a hand-back into a PR body or brief | Bisect before writing it: `git show <sha>:<file>` along the path from the fix commit to master. A lane round can revert its own earlier round, and that is not a merge drop |
617
+ | Trusting a wrapper script's exit status when it echoes a check's result | `pr-body.sh lint` printed `lint-exit=1` and exited 0, so a failing body went live; the wrapper now exits with the check's status. Read the check's own result line |
618
+ | Hand-rolling the governance suite in a fresh worktree | `npm run build` alone left `dist/` missing and three census suites red; use the orchestrator's `gov-check.sh <tree>`, which builds both outputs and keeps the `node_modules` link for the commit hook |
614
619
  | Reading a CI verdict without checking the SHA it judged | `ci-verdict --wait` returned exit 0 for the PREVIOUS head seconds after a push (#2878 trailing, 2026-09-10); compare the verdict's SHA with `gh pr view --json headRefOid` before merging |
615
620
  | Reporting "pushed" before `git log -1` shows the commit | Two trailing commits failed the pre-commit hook (changelog one-entry rule, unused vars) and the ledger/body already said pushed; verify the head, then write the row |
616
621
  | Folding a worker's extra changelog fragment into an existing one | One fragment = one top-level entry (`rollup-changelog --check`); keep a second fragment separate or drop it |
@@ -61,7 +61,8 @@ is involved. Every finding cites the source it came from.
61
61
  exactly as a regression test would; a check without a red is a proposal and
62
62
  is filed as an issue naming the incident as its recurrence, not merged.
63
63
  4. **Judgement candidates become one line in the right place.** A defect shape
64
- goes into the `AGENTS.md` catalog with the reference; a reviewer duty goes
64
+ goes into the `AGENTS.md` catalog as a lean screen, and its issues, PRs and
65
+ examples go to `HISTORY.md`; a reviewer duty goes
65
66
  into `docs/pi-lens-reviewer.md`; a fixer duty goes into `docs/pi-lens-fixer.md`
66
67
  only when the fixer is the sole actor who can honour it. Standards are
67
68
  enforced by the reviewer, whose context pressure is lowest; fixers get
@@ -52,6 +52,11 @@ a brief supplies only `lane=<name>`, scope, and the grant.
52
52
 
53
53
  ## Verification
54
54
 
55
+ For each new or changed `vi.mock` or hand-built double of a `clients/` module,
56
+ check whether a real test seam exists (`set*`, `adopt*`, or `reset*`). If it
57
+ does, treat the double as a finding and require the behavior to run through the
58
+ real seam. Check that every gate the diff adds is exercised through that path.
59
+
55
60
  - **Name the behaviour population.** When a change replaces, moves, or widens
56
61
  a lifecycle, dispatch, or ownership seam, run EVERY suite that exercises the
57
62
  behaviour the seam governs and name the list; a curated file set cannot
@@ -73,6 +78,8 @@ a brief supplies only `lane=<name>`, scope, and the grant.
73
78
  a review input.
74
79
  - Repeat the pattern and population sweeps. Check blast radius, bounded
75
80
  observability, changelog, commit, and PR-body requirements.
81
+ - Re-run the PR's `## Class sweep` search yourself and widen it when the
82
+ named shape is broader than the touched seam (#4273, #4268).
76
83
  - For LSP, dispatch, cache, runner, or tool changes, test one non-TypeScript
77
84
  registry entry through the same seam.
78
85
  - On a net-count fold, mutate every predicate the deleted sibling used to
@@ -210,3 +217,11 @@ merge-order interactions with other open PRs, plus:
210
217
  - Cleared categories (one compact list) and exact-head identity.
211
218
 
212
219
  Use short, active, plain prose.
220
+
221
+ ## Documentation and prose standard
222
+
223
+ Apply this standard to PR and issue bodies, review comments, commit messages, documentation, and changelog entries. Lead with the outcome. Remove words that do no work. Use active voice and present tense. Use second person for instructions, and use the imperative for steps. Keep one idea per sentence, with about 20–25 words and no more than 30 words. Use consistent terminology and sentence-case headings. Define acronyms on first use. Prefer plain words over jargon. Avoid `please`, filler, noun piles, nested parentheticals, and em-dash chains. Use the Oxford comma.
224
+
225
+ The mechanical rules are checked by `scripts/check-prose.mjs`. The checker ignores fenced code, inline code, URLs, quoted log lines, blockquotes, and tables. It blocks long sentences, filler, and title-case headings. It warns on passive voice. The CLI accepts a body file or standard input and supports `--json`.
226
+
227
+ Reviewers judge clarity, terminology, active voice, sentence structure, and whether each list uses parallel grammar. Treat a mechanically clean result as necessary, not sufficient. Report prose that obscures the outcome or makes a user infer the action.
@@ -8,6 +8,8 @@ holds the pi-lens rules every role shares, for every runner and model. The
8
8
  principles apply throughout and are not restated; project files win on
9
9
  conflict.
10
10
 
11
+ User-facing prose follows the live standard in `docs/pi-lens-reviewer.md`.
12
+
11
13
  ## Worktree and Git
12
14
 
13
15
  Work only in the assigned worktree. Before editing, verify its absolute path,