@unbrained/pm-cli 2026.7.1 → 2026.7.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 (563) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/cli/commander-usage.d.ts +2 -0
  3. package/dist/cli/commander-usage.js +58 -47
  4. package/dist/cli/commander-usage.js.map +1 -1
  5. package/dist/cli/commands/aggregate.js +102 -79
  6. package/dist/cli/commands/aggregate.js.map +1 -1
  7. package/dist/cli/commands/calendar.js +278 -243
  8. package/dist/cli/commands/calendar.js.map +1 -1
  9. package/dist/cli/commands/close-many.js +89 -68
  10. package/dist/cli/commands/close-many.js.map +1 -1
  11. package/dist/cli/commands/close.js +157 -129
  12. package/dist/cli/commands/close.js.map +1 -1
  13. package/dist/cli/commands/comments-audit.js +50 -42
  14. package/dist/cli/commands/comments-audit.js.map +1 -1
  15. package/dist/cli/commands/config.d.ts +2 -0
  16. package/dist/cli/commands/config.js +443 -879
  17. package/dist/cli/commands/config.js.map +1 -1
  18. package/dist/cli/commands/context.js +365 -287
  19. package/dist/cli/commands/context.js.map +1 -1
  20. package/dist/cli/commands/contracts.js +352 -238
  21. package/dist/cli/commands/contracts.js.map +1 -1
  22. package/dist/cli/commands/dedupe-audit.js +46 -39
  23. package/dist/cli/commands/dedupe-audit.js.map +1 -1
  24. package/dist/cli/commands/dedupe-merge.js +88 -69
  25. package/dist/cli/commands/dedupe-merge.js.map +1 -1
  26. package/dist/cli/commands/get.js +114 -81
  27. package/dist/cli/commands/get.js.map +1 -1
  28. package/dist/cli/commands/health.d.ts +17 -0
  29. package/dist/cli/commands/health.js +446 -307
  30. package/dist/cli/commands/health.js.map +1 -1
  31. package/dist/cli/commands/history-compact.js +209 -140
  32. package/dist/cli/commands/history-compact.js.map +1 -1
  33. package/dist/cli/commands/history-redact.js +162 -119
  34. package/dist/cli/commands/history-redact.js.map +1 -1
  35. package/dist/cli/commands/history-repair.js +120 -85
  36. package/dist/cli/commands/history-repair.js.map +1 -1
  37. package/dist/cli/commands/init.d.ts +8 -2
  38. package/dist/cli/commands/init.js +263 -162
  39. package/dist/cli/commands/init.js.map +1 -1
  40. package/dist/cli/commands/list.js +152 -102
  41. package/dist/cli/commands/list.js.map +1 -1
  42. package/dist/cli/commands/next.js +49 -32
  43. package/dist/cli/commands/next.js.map +1 -1
  44. package/dist/cli/commands/plan.js +373 -298
  45. package/dist/cli/commands/plan.js.map +1 -1
  46. package/dist/cli/commands/recurrence-parsers.js +43 -25
  47. package/dist/cli/commands/recurrence-parsers.js.map +1 -1
  48. package/dist/cli/commands/reindex.d.ts +21 -5
  49. package/dist/cli/commands/reindex.js +345 -205
  50. package/dist/cli/commands/reindex.js.map +1 -1
  51. package/dist/cli/commands/restore.d.ts +8 -7
  52. package/dist/cli/commands/restore.js +105 -69
  53. package/dist/cli/commands/restore.js.map +1 -1
  54. package/dist/cli/commands/schema.js +33 -30
  55. package/dist/cli/commands/schema.js.map +1 -1
  56. package/dist/cli/commands/search.d.ts +10 -2
  57. package/dist/cli/commands/search.js +503 -470
  58. package/dist/cli/commands/search.js.map +1 -1
  59. package/dist/cli/commands/telemetry.js +98 -87
  60. package/dist/cli/commands/telemetry.js.map +1 -1
  61. package/dist/cli/commands/test-all.js +237 -168
  62. package/dist/cli/commands/test-all.js.map +1 -1
  63. package/dist/cli/commands/test.d.ts +6 -5
  64. package/dist/cli/commands/test.js +424 -344
  65. package/dist/cli/commands/test.js.map +1 -1
  66. package/dist/cli/commands/update-many.js +57 -42
  67. package/dist/cli/commands/update-many.js.map +1 -1
  68. package/dist/cli/commands/update.d.ts +1 -1
  69. package/dist/cli/commands/update.js +738 -671
  70. package/dist/cli/commands/update.js.map +1 -1
  71. package/dist/cli/commands/validate.d.ts +18 -1
  72. package/dist/cli/commands/validate.js +466 -343
  73. package/dist/cli/commands/validate.js.map +1 -1
  74. package/dist/cli/error-guidance.js +399 -357
  75. package/dist/cli/error-guidance.js.map +1 -1
  76. package/dist/cli/main.d.ts +47 -0
  77. package/dist/cli/main.js +428 -341
  78. package/dist/cli/main.js.map +1 -1
  79. package/dist/cli/migration-gates.js +22 -45
  80. package/dist/cli/migration-gates.js.map +1 -1
  81. package/dist/cli/register-list-query.js +94 -105
  82. package/dist/cli/register-list-query.js.map +1 -1
  83. package/dist/cli/register-mutation.js +400 -416
  84. package/dist/cli/register-mutation.js.map +1 -1
  85. package/dist/cli/register-operations.js +86 -66
  86. package/dist/cli/register-operations.js.map +1 -1
  87. package/dist/cli/register-setup.js +120 -101
  88. package/dist/cli/register-setup.js.map +1 -1
  89. package/dist/cli-bundle/chunks/{activity-DBLQVIP6.js → activity-CUC4JY3U.js} +9 -9
  90. package/dist/cli-bundle/chunks/activity-WEIEMM73.js +16 -0
  91. package/dist/cli-bundle/chunks/{aggregate-JTEF4BP7.js → aggregate-DKUTRY6R.js} +108 -84
  92. package/dist/cli-bundle/chunks/aggregate-DKUTRY6R.js.map +1 -0
  93. package/dist/cli-bundle/chunks/{aggregate-SDF7DUOD.js → aggregate-SW5PNGCS.js} +107 -83
  94. package/dist/cli-bundle/chunks/{aggregate-SDF7DUOD.js.map → aggregate-SW5PNGCS.js.map} +2 -2
  95. package/dist/cli-bundle/chunks/{append-QCFJSDFL.js → append-H32VOR2Y.js} +6 -6
  96. package/dist/cli-bundle/chunks/{append-LOVPGVPT.js → append-UBM632FK.js} +6 -6
  97. package/dist/cli-bundle/chunks/{chunk-RLDHZHQS.js → chunk-2227673O.js} +158 -114
  98. package/dist/cli-bundle/chunks/chunk-2227673O.js.map +1 -0
  99. package/dist/cli-bundle/chunks/{chunk-SLMUGTK3.js → chunk-2ASNV4DH.js} +4 -4
  100. package/dist/cli-bundle/chunks/{chunk-UZIWVBE6.js → chunk-2CHRYUXL.js} +2 -2
  101. package/dist/cli-bundle/chunks/{chunk-NWMZWYYB.js → chunk-2KWL5NPW.js} +42 -27
  102. package/dist/cli-bundle/chunks/chunk-2KWL5NPW.js.map +1 -0
  103. package/dist/cli-bundle/chunks/{chunk-NFDPYAIP.js → chunk-36UGKF4O.js} +21 -29
  104. package/dist/cli-bundle/chunks/chunk-36UGKF4O.js.map +7 -0
  105. package/dist/cli-bundle/chunks/{chunk-NU2UEROZ.js → chunk-3AZUFQK6.js} +6 -6
  106. package/dist/cli-bundle/chunks/{chunk-LB6TP6MC.js → chunk-3LCUASYG.js} +2 -2
  107. package/dist/cli-bundle/chunks/{chunk-HPPFYYOV.js → chunk-3Q2HBMTI.js} +2 -2
  108. package/dist/cli-bundle/chunks/{chunk-IPYBJWTE.js → chunk-4NUOWFBT.js} +109 -72
  109. package/dist/cli-bundle/chunks/chunk-4NUOWFBT.js.map +7 -0
  110. package/dist/cli-bundle/chunks/{chunk-W4ULYO7Z.js → chunk-55XRYWEG.js} +6 -6
  111. package/dist/cli-bundle/chunks/{chunk-HXTQJXWT.js → chunk-5GVTFFTC.js} +2 -2
  112. package/dist/cli-bundle/chunks/{chunk-BDTISOSD.js → chunk-5PGBHRY3.js} +41 -26
  113. package/dist/cli-bundle/chunks/chunk-5PGBHRY3.js.map +7 -0
  114. package/dist/cli-bundle/chunks/{chunk-YITK2PJ6.js → chunk-66Z3X7ZG.js} +261 -161
  115. package/dist/cli-bundle/chunks/chunk-66Z3X7ZG.js.map +7 -0
  116. package/dist/cli-bundle/chunks/{chunk-NUHHPVVS.js → chunk-6ITZLD4T.js} +712 -612
  117. package/dist/cli-bundle/chunks/chunk-6ITZLD4T.js.map +7 -0
  118. package/dist/cli-bundle/chunks/{chunk-V3NOKJF2.js → chunk-6YCYF2AI.js} +262 -162
  119. package/dist/cli-bundle/chunks/chunk-6YCYF2AI.js.map +1 -0
  120. package/dist/cli-bundle/chunks/{chunk-BZCEN4JA.js → chunk-6ZMBJRDJ.js} +492 -403
  121. package/dist/cli-bundle/chunks/chunk-6ZMBJRDJ.js.map +7 -0
  122. package/dist/cli-bundle/chunks/{chunk-CF7RL6FR.js → chunk-7MYWF4ZX.js} +110 -73
  123. package/dist/cli-bundle/chunks/chunk-7MYWF4ZX.js.map +1 -0
  124. package/dist/cli-bundle/chunks/{chunk-RVUALSJF.js → chunk-7NSPKJUS.js} +356 -285
  125. package/dist/cli-bundle/chunks/chunk-7NSPKJUS.js.map +7 -0
  126. package/dist/cli-bundle/chunks/{chunk-4DSGXSBL.js → chunk-7TH5NMVB.js} +95 -53
  127. package/dist/cli-bundle/chunks/chunk-7TH5NMVB.js.map +7 -0
  128. package/dist/cli-bundle/chunks/{chunk-ZETXE4SE.js → chunk-7W4H4K26.js} +713 -613
  129. package/dist/cli-bundle/chunks/chunk-7W4H4K26.js.map +1 -0
  130. package/dist/cli-bundle/chunks/{chunk-64HNBBFQ.js → chunk-A6VOGKBA.js} +6 -6
  131. package/dist/cli-bundle/chunks/{chunk-WYDHYJPO.js → chunk-AIAIXG7I.js} +2 -2
  132. package/dist/cli-bundle/chunks/{chunk-CWFNTKQJ.js → chunk-AJEBCRIY.js} +5 -5
  133. package/dist/cli-bundle/chunks/{chunk-VZDBVEZR.js → chunk-B4O5S7I3.js} +79 -57
  134. package/dist/cli-bundle/chunks/{chunk-VZDBVEZR.js.map → chunk-B4O5S7I3.js.map} +2 -2
  135. package/dist/cli-bundle/chunks/{chunk-NOLPZMSV.js → chunk-BTX5MIQF.js} +2 -2
  136. package/dist/cli-bundle/chunks/{chunk-RH5ZBYFD.js → chunk-BVZZN2LH.js} +3 -3
  137. package/dist/cli-bundle/chunks/{chunk-27BXPBAY.js → chunk-CYBDUHNO.js} +3 -3
  138. package/dist/cli-bundle/chunks/{chunk-A7FPBAQS.js → chunk-CZPVDLD2.js} +4 -4
  139. package/dist/cli-bundle/chunks/{chunk-3VGN2UWE.js → chunk-EMPGXBUF.js} +22 -30
  140. package/dist/cli-bundle/chunks/chunk-EMPGXBUF.js.map +1 -0
  141. package/dist/cli-bundle/chunks/{chunk-JPECA746.js → chunk-EUKTMRN3.js} +2 -2
  142. package/dist/cli-bundle/chunks/{chunk-2466X6E4.js → chunk-FFOQHGNH.js} +6 -6
  143. package/dist/cli-bundle/chunks/{chunk-JLM7BHI7.js → chunk-GFMSLORL.js} +6 -6
  144. package/dist/cli-bundle/chunks/{chunk-SDR5J34Q.js → chunk-GRRG3MCT.js} +4 -4
  145. package/dist/cli-bundle/chunks/{chunk-GJ326ZKX.js → chunk-H4GRLYJS.js} +3 -3
  146. package/dist/cli-bundle/chunks/{chunk-OGXLACHC.js → chunk-HQTPRV4D.js} +6 -6
  147. package/dist/cli-bundle/chunks/{chunk-7R4QEMZZ.js → chunk-I66WE2HE.js} +354 -283
  148. package/dist/cli-bundle/chunks/chunk-I66WE2HE.js.map +1 -0
  149. package/dist/cli-bundle/chunks/{chunk-BHO33VBQ.js → chunk-IEEJQCZ4.js} +3 -3
  150. package/dist/cli-bundle/chunks/{chunk-JMP4E6D7.js → chunk-IG5JYZGU.js} +390 -312
  151. package/dist/cli-bundle/chunks/{chunk-JMP4E6D7.js.map → chunk-IG5JYZGU.js.map} +2 -2
  152. package/dist/cli-bundle/chunks/{chunk-4DUVCVLZ.js → chunk-JMK5GCK2.js} +2 -2
  153. package/dist/cli-bundle/chunks/{chunk-3K2M5OYU.js → chunk-JXAUVO6X.js} +258 -169
  154. package/dist/cli-bundle/chunks/{chunk-3K2M5OYU.js.map → chunk-JXAUVO6X.js.map} +2 -2
  155. package/dist/cli-bundle/chunks/{chunk-AXIDKKAT.js → chunk-K2VYLVX4.js} +2 -2
  156. package/dist/cli-bundle/chunks/{chunk-EJUDVUYZ.js → chunk-KCO2EAN5.js} +3 -3
  157. package/dist/cli-bundle/chunks/{chunk-6AQZPVHQ.js → chunk-KIYCOJ63.js} +4 -4
  158. package/dist/cli-bundle/chunks/{chunk-ZRP4VG5U.js → chunk-KLXF7NCC.js} +2 -2
  159. package/dist/cli-bundle/chunks/{chunk-QCWF6IYD.js → chunk-KN3URLKS.js} +3 -3
  160. package/dist/cli-bundle/chunks/{chunk-N74UMG5H.js → chunk-LRKMWUUV.js} +2 -2
  161. package/dist/cli-bundle/chunks/{chunk-AVEE5EHK.js → chunk-LTRAF2D7.js} +3 -3
  162. package/dist/cli-bundle/chunks/{chunk-VARHOHYV.js → chunk-MNBPX5JS.js} +55 -36
  163. package/dist/cli-bundle/chunks/chunk-MNBPX5JS.js.map +7 -0
  164. package/dist/cli-bundle/chunks/{chunk-IJYK2T43.js → chunk-MRD4T5LF.js} +2 -2
  165. package/dist/cli-bundle/chunks/{chunk-G7I7DEZA.js → chunk-N2JSWVWG.js} +4 -4
  166. package/dist/cli-bundle/chunks/{chunk-5QFDBI4F.js → chunk-N3QCJS4M.js} +6 -6
  167. package/dist/cli-bundle/chunks/{chunk-JSU5P7VS.js → chunk-NRZS637N.js} +258 -169
  168. package/dist/cli-bundle/chunks/chunk-NRZS637N.js.map +1 -0
  169. package/dist/cli-bundle/chunks/{chunk-4A3BJ675.js → chunk-OTUJZKGI.js} +3 -3
  170. package/dist/cli-bundle/chunks/{chunk-5CGRF3L5.js → chunk-Q6K2OACU.js} +153 -90
  171. package/dist/cli-bundle/chunks/chunk-Q6K2OACU.js.map +1 -0
  172. package/dist/cli-bundle/chunks/{chunk-3XZCOZ5J.js → chunk-Q6NXOHS6.js} +391 -313
  173. package/dist/cli-bundle/chunks/chunk-Q6NXOHS6.js.map +1 -0
  174. package/dist/cli-bundle/chunks/{chunk-HZZEHPRG.js → chunk-QH3FSKRJ.js} +2 -2
  175. package/dist/cli-bundle/chunks/{chunk-4XOIEKSD.js → chunk-RM37OPYK.js} +56 -37
  176. package/dist/cli-bundle/chunks/chunk-RM37OPYK.js.map +1 -0
  177. package/dist/cli-bundle/chunks/{chunk-NKZAN7BD.js → chunk-S62UANU7.js} +3 -3
  178. package/dist/cli-bundle/chunks/{chunk-RMMQ74TG.js → chunk-SPM2XLWI.js} +37 -28
  179. package/dist/cli-bundle/chunks/chunk-SPM2XLWI.js.map +7 -0
  180. package/dist/cli-bundle/chunks/{chunk-3J6JRJ3I.js → chunk-SYNKD3ZG.js} +5 -5
  181. package/dist/cli-bundle/chunks/{chunk-FFMQB7WR.js → chunk-SYVUU7EK.js} +493 -404
  182. package/dist/cli-bundle/chunks/chunk-SYVUU7EK.js.map +1 -0
  183. package/dist/cli-bundle/chunks/{chunk-UYUYDGIB.js → chunk-TPOFWBMY.js} +95 -53
  184. package/dist/cli-bundle/chunks/chunk-TPOFWBMY.js.map +1 -0
  185. package/dist/cli-bundle/chunks/{chunk-OTUHB4HS.js → chunk-TTHCEV5Q.js} +92 -77
  186. package/dist/cli-bundle/chunks/chunk-TTHCEV5Q.js.map +1 -0
  187. package/dist/cli-bundle/chunks/{chunk-L5OEFZQG.js → chunk-U2BEEM2X.js} +3 -3
  188. package/dist/cli-bundle/chunks/{chunk-KNPEF7QG.js → chunk-UGLU6Q2I.js} +91 -76
  189. package/dist/cli-bundle/chunks/chunk-UGLU6Q2I.js.map +7 -0
  190. package/dist/cli-bundle/chunks/{chunk-EVMTBV6V.js → chunk-UT73HUPC.js} +3 -3
  191. package/dist/cli-bundle/chunks/{chunk-VICZWYGZ.js → chunk-UTSH5GWX.js} +4 -4
  192. package/dist/cli-bundle/chunks/{chunk-IZBR4NRW.js → chunk-UWKEJMZU.js} +157 -113
  193. package/dist/cli-bundle/chunks/chunk-UWKEJMZU.js.map +7 -0
  194. package/dist/cli-bundle/chunks/{chunk-3S2KT7NG.js → chunk-W47SML5B.js} +152 -89
  195. package/dist/cli-bundle/chunks/chunk-W47SML5B.js.map +7 -0
  196. package/dist/cli-bundle/chunks/{chunk-RGEMWD6Q.js → chunk-WJAMWAHZ.js} +157 -118
  197. package/dist/cli-bundle/chunks/chunk-WJAMWAHZ.js.map +7 -0
  198. package/dist/cli-bundle/chunks/{chunk-JWXRETDF.js → chunk-XCHUVHKU.js} +626 -484
  199. package/dist/cli-bundle/chunks/chunk-XCHUVHKU.js.map +1 -0
  200. package/dist/cli-bundle/chunks/{chunk-55SNVXRQ.js → chunk-XEWQKDYZ.js} +626 -484
  201. package/dist/cli-bundle/chunks/chunk-XEWQKDYZ.js.map +7 -0
  202. package/dist/cli-bundle/chunks/{chunk-TP5Q5ZD3.js → chunk-XTHQWXVC.js} +158 -119
  203. package/dist/cli-bundle/chunks/chunk-XTHQWXVC.js.map +1 -0
  204. package/dist/cli-bundle/chunks/{chunk-MDPEOIGN.js → chunk-XWGEMNBR.js} +2 -2
  205. package/dist/cli-bundle/chunks/{chunk-HYTGA6GI.js → chunk-Y4NRKBFW.js} +3 -3
  206. package/dist/cli-bundle/chunks/{chunk-2D4HATP2.js → chunk-YLZZ6T54.js} +38 -29
  207. package/dist/cli-bundle/chunks/chunk-YLZZ6T54.js.map +1 -0
  208. package/dist/cli-bundle/chunks/{chunk-22WKIL3H.js → chunk-YPKFV2JR.js} +6 -6
  209. package/dist/cli-bundle/chunks/{chunk-OKQ22KTH.js → chunk-Z4DGFQDH.js} +80 -58
  210. package/dist/cli-bundle/chunks/{chunk-OKQ22KTH.js.map → chunk-Z4DGFQDH.js.map} +1 -1
  211. package/dist/cli-bundle/chunks/{chunk-DDPTYJIM.js → chunk-ZNHEYCDD.js} +2 -2
  212. package/dist/cli-bundle/chunks/{chunk-MAUKX7JC.js → chunk-ZNT7KEWE.js} +2 -2
  213. package/dist/cli-bundle/chunks/{claim-T3GCKV7C.js → claim-SENTPZBN.js} +8 -8
  214. package/dist/cli-bundle/chunks/{claim-EMQLYPRW.js → claim-Z7MEQCBT.js} +8 -8
  215. package/dist/cli-bundle/chunks/{close-TQYAAFJP.js → close-424MX4CU.js} +7 -7
  216. package/dist/cli-bundle/chunks/close-YCWQQPDS.js +14 -0
  217. package/dist/cli-bundle/chunks/{close-many-LDRVEQY2.js → close-many-2IV4J2TR.js} +102 -81
  218. package/dist/cli-bundle/chunks/close-many-2IV4J2TR.js.map +1 -0
  219. package/dist/cli-bundle/chunks/{close-many-BG5QQIDQ.js → close-many-SWY34BII.js} +101 -80
  220. package/dist/cli-bundle/chunks/close-many-SWY34BII.js.map +7 -0
  221. package/dist/cli-bundle/chunks/{comments-YUXJRZPQ.js → comments-4FGNTSNV.js} +8 -8
  222. package/dist/cli-bundle/chunks/{comments-QCKR2YY2.js → comments-7YS5MY5X.js} +8 -8
  223. package/dist/cli-bundle/chunks/config-BZJKK7FZ.js +1062 -0
  224. package/dist/cli-bundle/chunks/config-BZJKK7FZ.js.map +1 -0
  225. package/dist/cli-bundle/chunks/config-G74GISC4.js +1072 -0
  226. package/dist/cli-bundle/chunks/config-G74GISC4.js.map +7 -0
  227. package/dist/cli-bundle/chunks/{context-OCZ3FJ4Z.js → context-LHVKJSPJ.js} +12 -12
  228. package/dist/cli-bundle/chunks/{context-B6275WPX.js → context-ZQY54JNS.js} +12 -12
  229. package/dist/cli-bundle/chunks/{contracts-HN7ABKLP.js → contracts-CP2EZJC7.js} +320 -199
  230. package/dist/cli-bundle/chunks/contracts-CP2EZJC7.js.map +7 -0
  231. package/dist/cli-bundle/chunks/{contracts-W4FZVVD6.js → contracts-FIZLMP7O.js} +321 -200
  232. package/dist/cli-bundle/chunks/contracts-FIZLMP7O.js.map +1 -0
  233. package/dist/cli-bundle/chunks/{copy-DEM4DATS.js → copy-GYNQQPW2.js} +5 -5
  234. package/dist/cli-bundle/chunks/{copy-BTJOSKKT.js → copy-TLW7JTQT.js} +5 -5
  235. package/dist/cli-bundle/chunks/{create-RLRJMRTM.js → create-VSKYSOCD.js} +12 -12
  236. package/dist/cli-bundle/chunks/create-XTMAPS7I.js +28 -0
  237. package/dist/cli-bundle/chunks/{delete-LSVHAB4Y.js → delete-4W5JYCEG.js} +5 -5
  238. package/dist/cli-bundle/chunks/{delete-BHK7VB2Z.js → delete-ANTOTI2I.js} +5 -5
  239. package/dist/cli-bundle/chunks/{deps-XHYXWEPT.js → deps-HPPE6MJN.js} +5 -5
  240. package/dist/cli-bundle/chunks/{deps-4UDFJRUA.js → deps-ZQZN54EZ.js} +5 -5
  241. package/dist/cli-bundle/chunks/{docs-GYZNVS26.js → docs-RPOVFMP3.js} +7 -7
  242. package/dist/cli-bundle/chunks/{docs-26S44RXU.js → docs-XJNYBJGE.js} +7 -7
  243. package/dist/cli-bundle/chunks/{eval-PGRVIJQU.js → eval-DM6JBZTS.js} +10 -10
  244. package/dist/cli-bundle/chunks/{eval-UYF3ZPVO.js → eval-RFBI5FGS.js} +10 -10
  245. package/dist/cli-bundle/chunks/{extension-CPSLJQVE.js → extension-B3YY4WY5.js} +11 -11
  246. package/dist/cli-bundle/chunks/{extension-CXJ6RELI.js → extension-TTSEFQTS.js} +11 -11
  247. package/dist/cli-bundle/chunks/{files-NQHEXUZD.js → files-5D65CHGE.js} +7 -7
  248. package/dist/cli-bundle/chunks/{files-MBNICQFM.js → files-GPIG77EN.js} +7 -7
  249. package/dist/cli-bundle/chunks/{focus-XZW5423D.js → focus-C3PEJV2C.js} +6 -6
  250. package/dist/cli-bundle/chunks/{focus-DWYIG7GU.js → focus-ZHN7WIGX.js} +6 -6
  251. package/dist/cli-bundle/chunks/{gc-LPVMKJQJ.js → gc-D4JQ6OWN.js} +3 -3
  252. package/dist/cli-bundle/chunks/{gc-7GQYOS2G.js → gc-VZIXDL32.js} +3 -3
  253. package/dist/cli-bundle/chunks/{get-DSDEKJ3L.js → get-GIBRUUOP.js} +121 -81
  254. package/dist/cli-bundle/chunks/get-GIBRUUOP.js.map +1 -0
  255. package/dist/cli-bundle/chunks/{get-A7MAOHCU.js → get-IOVAN6RU.js} +120 -80
  256. package/dist/cli-bundle/chunks/get-IOVAN6RU.js.map +7 -0
  257. package/dist/cli-bundle/chunks/{health-3IPFLKXB.js → health-L2U3AFKV.js} +437 -265
  258. package/dist/cli-bundle/chunks/health-L2U3AFKV.js.map +1 -0
  259. package/dist/cli-bundle/chunks/{health-GZXGBZ36.js → health-MM7AWXYF.js} +436 -264
  260. package/dist/cli-bundle/chunks/health-MM7AWXYF.js.map +7 -0
  261. package/dist/cli-bundle/chunks/history-DD7L7BNL.js +18 -0
  262. package/dist/cli-bundle/chunks/{history-NERDJNUB.js → history-IL7XCEX2.js} +8 -8
  263. package/dist/cli-bundle/chunks/{history-compact-HR7BB4LR.js → history-compact-HALOTOU7.js} +214 -135
  264. package/dist/cli-bundle/chunks/history-compact-HALOTOU7.js.map +1 -0
  265. package/dist/cli-bundle/chunks/{history-compact-2WRZ2WK4.js → history-compact-MV25P7DM.js} +213 -134
  266. package/dist/cli-bundle/chunks/history-compact-MV25P7DM.js.map +7 -0
  267. package/dist/cli-bundle/chunks/history-redact-IX4YEWMY.js +19 -0
  268. package/dist/cli-bundle/chunks/{history-redact-O3NBCNWC.js → history-redact-VYCWQFK7.js} +9 -9
  269. package/dist/cli-bundle/chunks/{history-repair-XA3LC4GA.js → history-repair-44MODPQF.js} +124 -84
  270. package/dist/cli-bundle/chunks/history-repair-44MODPQF.js.map +1 -0
  271. package/dist/cli-bundle/chunks/{history-repair-LCMOS45X.js → history-repair-CPNAOCNF.js} +123 -83
  272. package/dist/cli-bundle/chunks/history-repair-CPNAOCNF.js.map +7 -0
  273. package/dist/cli-bundle/chunks/{init-64XDLQJB.js → init-F27NHENZ.js} +12 -12
  274. package/dist/cli-bundle/chunks/init-HHVQQP6C.js +22 -0
  275. package/dist/cli-bundle/chunks/{learnings-LPKCSJX7.js → learnings-HJVDQIGY.js} +8 -8
  276. package/dist/cli-bundle/chunks/{learnings-JR6MA5TI.js → learnings-XSFSUUWK.js} +8 -8
  277. package/dist/cli-bundle/chunks/{list-G5Y65VF6.js → list-HPMEKCAA.js} +8 -8
  278. package/dist/cli-bundle/chunks/{list-DNBJVO3E.js → list-VMPWTURB.js} +8 -8
  279. package/dist/cli-bundle/chunks/{next-BCERKDUR.js → next-ETXF2ZCN.js} +59 -37
  280. package/dist/cli-bundle/chunks/next-ETXF2ZCN.js.map +7 -0
  281. package/dist/cli-bundle/chunks/{next-FYTQF6HG.js → next-QM6YJIIS.js} +60 -38
  282. package/dist/cli-bundle/chunks/next-QM6YJIIS.js.map +1 -0
  283. package/dist/cli-bundle/chunks/{notes-2BMU3VVQ.js → notes-GDZIKGR6.js} +8 -8
  284. package/dist/cli-bundle/chunks/{notes-6KTGO2OJ.js → notes-WDDBPC4D.js} +8 -8
  285. package/dist/cli-bundle/chunks/{plan-RKZHQVXR.js → plan-BGDR73Z6.js} +373 -279
  286. package/dist/cli-bundle/chunks/plan-BGDR73Z6.js.map +1 -0
  287. package/dist/cli-bundle/chunks/{plan-4WXEQCTN.js → plan-C5IMM335.js} +372 -278
  288. package/dist/cli-bundle/chunks/plan-C5IMM335.js.map +7 -0
  289. package/dist/cli-bundle/chunks/{profile-QLER5ENE.js → profile-CCOKZ2IQ.js} +9 -9
  290. package/dist/cli-bundle/chunks/{profile-4OMM32CD.js → profile-HUCENIEQ.js} +9 -9
  291. package/dist/cli-bundle/chunks/{register-list-query-7LV46VAU.js → register-list-query-ROSNIL52.js} +80 -83
  292. package/dist/cli-bundle/chunks/register-list-query-ROSNIL52.js.map +1 -0
  293. package/dist/cli-bundle/chunks/{register-list-query-SNG5PGA4.js → register-list-query-XN4ZRHSV.js} +79 -82
  294. package/dist/cli-bundle/chunks/register-list-query-XN4ZRHSV.js.map +7 -0
  295. package/dist/cli-bundle/chunks/{register-mutation-ENNDUAZG.js → register-mutation-CFSB2MS3.js} +403 -382
  296. package/dist/cli-bundle/chunks/register-mutation-CFSB2MS3.js.map +1 -0
  297. package/dist/cli-bundle/chunks/{register-mutation-KK7PHYYU.js → register-mutation-KRLAHEL2.js} +402 -381
  298. package/dist/cli-bundle/chunks/register-mutation-KRLAHEL2.js.map +7 -0
  299. package/dist/cli-bundle/chunks/{register-operations-HZ6XERQG.js → register-operations-4PASGJDB.js} +112 -93
  300. package/dist/cli-bundle/chunks/register-operations-4PASGJDB.js.map +7 -0
  301. package/dist/cli-bundle/chunks/{register-operations-C6OWLDSH.js → register-operations-MBN4KGUM.js} +113 -94
  302. package/dist/cli-bundle/chunks/register-operations-MBN4KGUM.js.map +1 -0
  303. package/dist/cli-bundle/chunks/{register-setup-P67EMBDJ.js → register-setup-VIAWYFP5.js} +129 -104
  304. package/dist/cli-bundle/chunks/register-setup-VIAWYFP5.js.map +1 -0
  305. package/dist/cli-bundle/chunks/{register-setup-ZKJ53RS7.js → register-setup-ZCGKHDKL.js} +128 -103
  306. package/dist/cli-bundle/chunks/register-setup-ZCGKHDKL.js.map +7 -0
  307. package/dist/cli-bundle/chunks/{restore-4MHZFJ2E.js → restore-4CBWUMCX.js} +9 -9
  308. package/dist/cli-bundle/chunks/restore-5UEAGG3W.js +17 -0
  309. package/dist/cli-bundle/chunks/{scheduling-shortcuts-LB6DOLRL.js → scheduling-shortcuts-6VFKNKCM.js} +12 -12
  310. package/dist/cli-bundle/chunks/{scheduling-shortcuts-UTOYKLXQ.js → scheduling-shortcuts-ERHCVTEM.js} +12 -12
  311. package/dist/cli-bundle/chunks/{schema-73HR2OJW.js → schema-TDGK6N3I.js} +7 -7
  312. package/dist/cli-bundle/chunks/{schema-U6LJKSIR.js → schema-UE5KKAUX.js} +7 -7
  313. package/dist/cli-bundle/chunks/{search-KILGT37L.js → search-FP7MEU4S.js} +10 -10
  314. package/dist/cli-bundle/chunks/{search-AXPXKZER.js → search-K4CFLQ5S.js} +10 -10
  315. package/dist/cli-bundle/chunks/{stats-PSYVVTNZ.js → stats-NJJCALEZ.js} +6 -6
  316. package/dist/cli-bundle/chunks/{stats-W5KNVJWQ.js → stats-XT6QRKQY.js} +6 -6
  317. package/dist/cli-bundle/chunks/{telemetry-GAHHQTOS.js → telemetry-5SQ5UDXC.js} +84 -70
  318. package/dist/cli-bundle/chunks/telemetry-5SQ5UDXC.js.map +7 -0
  319. package/dist/cli-bundle/chunks/{telemetry-BZUF6H7G.js → telemetry-HVXFZA2U.js} +85 -71
  320. package/dist/cli-bundle/chunks/telemetry-HVXFZA2U.js.map +1 -0
  321. package/dist/cli-bundle/chunks/{test-ACD52Z3S.js → test-UFSJ5YIO.js} +15 -15
  322. package/dist/cli-bundle/chunks/{test-PWDIZ255.js → test-YCDAUBWF.js} +15 -15
  323. package/dist/cli-bundle/chunks/test-all-2BWKY3GQ.js +427 -0
  324. package/dist/cli-bundle/chunks/test-all-2BWKY3GQ.js.map +1 -0
  325. package/dist/cli-bundle/chunks/test-all-PM7UYN42.js +430 -0
  326. package/dist/cli-bundle/chunks/test-all-PM7UYN42.js.map +7 -0
  327. package/dist/cli-bundle/chunks/{test-runs-UXIXPDKU.js → test-runs-FK5E75AA.js} +185 -147
  328. package/dist/cli-bundle/chunks/test-runs-FK5E75AA.js.map +1 -0
  329. package/dist/cli-bundle/chunks/{test-runs-PLRAZEFW.js → test-runs-H4TGWGRN.js} +184 -146
  330. package/dist/cli-bundle/chunks/test-runs-H4TGWGRN.js.map +7 -0
  331. package/dist/cli-bundle/chunks/update-MTCFES6X.js +24 -0
  332. package/dist/cli-bundle/chunks/{update-KFX2SIAC.js → update-Y5WQVT5O.js} +15 -15
  333. package/dist/cli-bundle/chunks/{update-many-Z5GJS5LC.js → update-many-6YAYYRLE.js} +82 -67
  334. package/dist/cli-bundle/chunks/{update-many-Z5GJS5LC.js.map → update-many-6YAYYRLE.js.map} +2 -2
  335. package/dist/cli-bundle/chunks/{update-many-RNSBX2TA.js → update-many-JTKKSA7Y.js} +83 -68
  336. package/dist/cli-bundle/chunks/{update-many-RNSBX2TA.js.map → update-many-JTKKSA7Y.js.map} +1 -1
  337. package/dist/cli-bundle/chunks/{upgrade-HAK6JG2O.js → upgrade-DTAHZ236.js} +11 -11
  338. package/dist/cli-bundle/chunks/{upgrade-BRL6KCOJ.js → upgrade-JUDU7YL4.js} +11 -11
  339. package/dist/cli-bundle/chunks/{validate-MTUVL5VC.js → validate-732RWS5W.js} +440 -320
  340. package/dist/cli-bundle/chunks/validate-732RWS5W.js.map +7 -0
  341. package/dist/cli-bundle/chunks/{validate-X5W76YJL.js → validate-W7H5TEDC.js} +441 -321
  342. package/dist/cli-bundle/chunks/validate-W7H5TEDC.js.map +1 -0
  343. package/dist/cli-bundle/main.js +945 -812
  344. package/dist/cli-bundle/main.js.map +3 -3
  345. package/dist/core/config/nested-settings.js +89 -67
  346. package/dist/core/config/nested-settings.js.map +1 -1
  347. package/dist/core/governance/metadata-coverage.js +20 -28
  348. package/dist/core/governance/metadata-coverage.js.map +1 -1
  349. package/dist/core/history/drift-scan.js +93 -81
  350. package/dist/core/history/drift-scan.js.map +1 -1
  351. package/dist/core/item/item-type-definition.js +14 -14
  352. package/dist/core/item/item-type-definition.js.map +1 -1
  353. package/dist/core/item/type-registry.js +87 -82
  354. package/dist/core/item/type-registry.js.map +1 -1
  355. package/dist/core/output/mutation-projection.js +42 -26
  356. package/dist/core/output/mutation-projection.js.map +1 -1
  357. package/dist/core/schema/runtime-schema.js +34 -28
  358. package/dist/core/schema/runtime-schema.js.map +1 -1
  359. package/dist/core/search/semantic-defaults.js +64 -37
  360. package/dist/core/search/semantic-defaults.js.map +1 -1
  361. package/dist/core/search/vector-stores.js +32 -17
  362. package/dist/core/search/vector-stores.js.map +1 -1
  363. package/dist/core/sentry/helpers.js +31 -28
  364. package/dist/core/sentry/helpers.js.map +1 -1
  365. package/dist/core/sentry/instrument.js +54 -43
  366. package/dist/core/sentry/instrument.js.map +1 -1
  367. package/dist/core/store/front-matter-cache.js +239 -153
  368. package/dist/core/store/front-matter-cache.js.map +1 -1
  369. package/dist/core/store/item-store.js +33 -26
  370. package/dist/core/store/item-store.js.map +1 -1
  371. package/dist/core/store/settings.js +247 -203
  372. package/dist/core/store/settings.js.map +1 -1
  373. package/dist/core/test/background-runs.js +189 -160
  374. package/dist/core/test/background-runs.js.map +1 -1
  375. package/package.json +2 -2
  376. package/packages/pm-beads/extensions/beads/runtime.ts +240 -167
  377. package/packages/pm-guide-shell/extensions/guide-shell/runtime.ts +65 -58
  378. package/packages/pm-todos/extensions/todos/runtime.ts +65 -42
  379. package/dist/cli-bundle/chunks/activity-AW6XVFH6.js +0 -16
  380. package/dist/cli-bundle/chunks/aggregate-JTEF4BP7.js.map +0 -1
  381. package/dist/cli-bundle/chunks/chunk-2D4HATP2.js.map +0 -1
  382. package/dist/cli-bundle/chunks/chunk-3S2KT7NG.js.map +0 -7
  383. package/dist/cli-bundle/chunks/chunk-3VGN2UWE.js.map +0 -1
  384. package/dist/cli-bundle/chunks/chunk-3XZCOZ5J.js.map +0 -1
  385. package/dist/cli-bundle/chunks/chunk-4DSGXSBL.js.map +0 -7
  386. package/dist/cli-bundle/chunks/chunk-4XOIEKSD.js.map +0 -1
  387. package/dist/cli-bundle/chunks/chunk-55SNVXRQ.js.map +0 -7
  388. package/dist/cli-bundle/chunks/chunk-5CGRF3L5.js.map +0 -1
  389. package/dist/cli-bundle/chunks/chunk-7R4QEMZZ.js.map +0 -1
  390. package/dist/cli-bundle/chunks/chunk-BDTISOSD.js.map +0 -7
  391. package/dist/cli-bundle/chunks/chunk-BZCEN4JA.js.map +0 -7
  392. package/dist/cli-bundle/chunks/chunk-CF7RL6FR.js.map +0 -1
  393. package/dist/cli-bundle/chunks/chunk-FFMQB7WR.js.map +0 -1
  394. package/dist/cli-bundle/chunks/chunk-IPYBJWTE.js.map +0 -7
  395. package/dist/cli-bundle/chunks/chunk-IZBR4NRW.js.map +0 -7
  396. package/dist/cli-bundle/chunks/chunk-JSU5P7VS.js.map +0 -1
  397. package/dist/cli-bundle/chunks/chunk-JWXRETDF.js.map +0 -1
  398. package/dist/cli-bundle/chunks/chunk-KNPEF7QG.js.map +0 -7
  399. package/dist/cli-bundle/chunks/chunk-NFDPYAIP.js.map +0 -7
  400. package/dist/cli-bundle/chunks/chunk-NUHHPVVS.js.map +0 -7
  401. package/dist/cli-bundle/chunks/chunk-NWMZWYYB.js.map +0 -1
  402. package/dist/cli-bundle/chunks/chunk-OTUHB4HS.js.map +0 -1
  403. package/dist/cli-bundle/chunks/chunk-RGEMWD6Q.js.map +0 -7
  404. package/dist/cli-bundle/chunks/chunk-RLDHZHQS.js.map +0 -1
  405. package/dist/cli-bundle/chunks/chunk-RMMQ74TG.js.map +0 -7
  406. package/dist/cli-bundle/chunks/chunk-RVUALSJF.js.map +0 -7
  407. package/dist/cli-bundle/chunks/chunk-TP5Q5ZD3.js.map +0 -1
  408. package/dist/cli-bundle/chunks/chunk-UYUYDGIB.js.map +0 -1
  409. package/dist/cli-bundle/chunks/chunk-V3NOKJF2.js.map +0 -1
  410. package/dist/cli-bundle/chunks/chunk-VARHOHYV.js.map +0 -7
  411. package/dist/cli-bundle/chunks/chunk-YITK2PJ6.js.map +0 -7
  412. package/dist/cli-bundle/chunks/chunk-ZETXE4SE.js.map +0 -1
  413. package/dist/cli-bundle/chunks/close-E6ZZGCJY.js +0 -14
  414. package/dist/cli-bundle/chunks/close-many-BG5QQIDQ.js.map +0 -7
  415. package/dist/cli-bundle/chunks/close-many-LDRVEQY2.js.map +0 -1
  416. package/dist/cli-bundle/chunks/config-DMSU64QO.js +0 -1541
  417. package/dist/cli-bundle/chunks/config-DMSU64QO.js.map +0 -7
  418. package/dist/cli-bundle/chunks/config-QH2DICD6.js +0 -1531
  419. package/dist/cli-bundle/chunks/config-QH2DICD6.js.map +0 -1
  420. package/dist/cli-bundle/chunks/contracts-HN7ABKLP.js.map +0 -7
  421. package/dist/cli-bundle/chunks/contracts-W4FZVVD6.js.map +0 -1
  422. package/dist/cli-bundle/chunks/create-OH3BDGBB.js +0 -28
  423. package/dist/cli-bundle/chunks/get-A7MAOHCU.js.map +0 -7
  424. package/dist/cli-bundle/chunks/get-DSDEKJ3L.js.map +0 -1
  425. package/dist/cli-bundle/chunks/health-3IPFLKXB.js.map +0 -1
  426. package/dist/cli-bundle/chunks/health-GZXGBZ36.js.map +0 -7
  427. package/dist/cli-bundle/chunks/history-WSZHY3PN.js +0 -18
  428. package/dist/cli-bundle/chunks/history-compact-2WRZ2WK4.js.map +0 -7
  429. package/dist/cli-bundle/chunks/history-compact-HR7BB4LR.js.map +0 -1
  430. package/dist/cli-bundle/chunks/history-redact-MP6CH7U5.js +0 -19
  431. package/dist/cli-bundle/chunks/history-repair-LCMOS45X.js.map +0 -7
  432. package/dist/cli-bundle/chunks/history-repair-XA3LC4GA.js.map +0 -1
  433. package/dist/cli-bundle/chunks/init-PAX32BJA.js +0 -22
  434. package/dist/cli-bundle/chunks/next-BCERKDUR.js.map +0 -7
  435. package/dist/cli-bundle/chunks/next-FYTQF6HG.js.map +0 -1
  436. package/dist/cli-bundle/chunks/plan-4WXEQCTN.js.map +0 -7
  437. package/dist/cli-bundle/chunks/plan-RKZHQVXR.js.map +0 -1
  438. package/dist/cli-bundle/chunks/register-list-query-7LV46VAU.js.map +0 -1
  439. package/dist/cli-bundle/chunks/register-list-query-SNG5PGA4.js.map +0 -7
  440. package/dist/cli-bundle/chunks/register-mutation-ENNDUAZG.js.map +0 -1
  441. package/dist/cli-bundle/chunks/register-mutation-KK7PHYYU.js.map +0 -7
  442. package/dist/cli-bundle/chunks/register-operations-C6OWLDSH.js.map +0 -1
  443. package/dist/cli-bundle/chunks/register-operations-HZ6XERQG.js.map +0 -7
  444. package/dist/cli-bundle/chunks/register-setup-P67EMBDJ.js.map +0 -1
  445. package/dist/cli-bundle/chunks/register-setup-ZKJ53RS7.js.map +0 -7
  446. package/dist/cli-bundle/chunks/restore-YALDGTQR.js +0 -17
  447. package/dist/cli-bundle/chunks/telemetry-BZUF6H7G.js.map +0 -1
  448. package/dist/cli-bundle/chunks/telemetry-GAHHQTOS.js.map +0 -7
  449. package/dist/cli-bundle/chunks/test-all-L2MDDUCA.js +0 -358
  450. package/dist/cli-bundle/chunks/test-all-L2MDDUCA.js.map +0 -1
  451. package/dist/cli-bundle/chunks/test-all-RBZ6DLU2.js +0 -361
  452. package/dist/cli-bundle/chunks/test-all-RBZ6DLU2.js.map +0 -7
  453. package/dist/cli-bundle/chunks/test-runs-PLRAZEFW.js.map +0 -7
  454. package/dist/cli-bundle/chunks/test-runs-UXIXPDKU.js.map +0 -1
  455. package/dist/cli-bundle/chunks/update-AMRSOIWP.js +0 -24
  456. package/dist/cli-bundle/chunks/validate-MTUVL5VC.js.map +0 -7
  457. package/dist/cli-bundle/chunks/validate-X5W76YJL.js.map +0 -1
  458. /package/dist/cli-bundle/chunks/{activity-DBLQVIP6.js.map → activity-CUC4JY3U.js.map} +0 -0
  459. /package/dist/cli-bundle/chunks/{activity-AW6XVFH6.js.map → activity-WEIEMM73.js.map} +0 -0
  460. /package/dist/cli-bundle/chunks/{append-QCFJSDFL.js.map → append-H32VOR2Y.js.map} +0 -0
  461. /package/dist/cli-bundle/chunks/{append-LOVPGVPT.js.map → append-UBM632FK.js.map} +0 -0
  462. /package/dist/cli-bundle/chunks/{chunk-SLMUGTK3.js.map → chunk-2ASNV4DH.js.map} +0 -0
  463. /package/dist/cli-bundle/chunks/{chunk-UZIWVBE6.js.map → chunk-2CHRYUXL.js.map} +0 -0
  464. /package/dist/cli-bundle/chunks/{chunk-NU2UEROZ.js.map → chunk-3AZUFQK6.js.map} +0 -0
  465. /package/dist/cli-bundle/chunks/{chunk-LB6TP6MC.js.map → chunk-3LCUASYG.js.map} +0 -0
  466. /package/dist/cli-bundle/chunks/{chunk-HPPFYYOV.js.map → chunk-3Q2HBMTI.js.map} +0 -0
  467. /package/dist/cli-bundle/chunks/{chunk-W4ULYO7Z.js.map → chunk-55XRYWEG.js.map} +0 -0
  468. /package/dist/cli-bundle/chunks/{chunk-HXTQJXWT.js.map → chunk-5GVTFFTC.js.map} +0 -0
  469. /package/dist/cli-bundle/chunks/{chunk-64HNBBFQ.js.map → chunk-A6VOGKBA.js.map} +0 -0
  470. /package/dist/cli-bundle/chunks/{chunk-WYDHYJPO.js.map → chunk-AIAIXG7I.js.map} +0 -0
  471. /package/dist/cli-bundle/chunks/{chunk-CWFNTKQJ.js.map → chunk-AJEBCRIY.js.map} +0 -0
  472. /package/dist/cli-bundle/chunks/{chunk-NOLPZMSV.js.map → chunk-BTX5MIQF.js.map} +0 -0
  473. /package/dist/cli-bundle/chunks/{chunk-RH5ZBYFD.js.map → chunk-BVZZN2LH.js.map} +0 -0
  474. /package/dist/cli-bundle/chunks/{chunk-27BXPBAY.js.map → chunk-CYBDUHNO.js.map} +0 -0
  475. /package/dist/cli-bundle/chunks/{chunk-A7FPBAQS.js.map → chunk-CZPVDLD2.js.map} +0 -0
  476. /package/dist/cli-bundle/chunks/{chunk-JPECA746.js.map → chunk-EUKTMRN3.js.map} +0 -0
  477. /package/dist/cli-bundle/chunks/{chunk-2466X6E4.js.map → chunk-FFOQHGNH.js.map} +0 -0
  478. /package/dist/cli-bundle/chunks/{chunk-JLM7BHI7.js.map → chunk-GFMSLORL.js.map} +0 -0
  479. /package/dist/cli-bundle/chunks/{chunk-SDR5J34Q.js.map → chunk-GRRG3MCT.js.map} +0 -0
  480. /package/dist/cli-bundle/chunks/{chunk-GJ326ZKX.js.map → chunk-H4GRLYJS.js.map} +0 -0
  481. /package/dist/cli-bundle/chunks/{chunk-OGXLACHC.js.map → chunk-HQTPRV4D.js.map} +0 -0
  482. /package/dist/cli-bundle/chunks/{chunk-BHO33VBQ.js.map → chunk-IEEJQCZ4.js.map} +0 -0
  483. /package/dist/cli-bundle/chunks/{chunk-4DUVCVLZ.js.map → chunk-JMK5GCK2.js.map} +0 -0
  484. /package/dist/cli-bundle/chunks/{chunk-AXIDKKAT.js.map → chunk-K2VYLVX4.js.map} +0 -0
  485. /package/dist/cli-bundle/chunks/{chunk-EJUDVUYZ.js.map → chunk-KCO2EAN5.js.map} +0 -0
  486. /package/dist/cli-bundle/chunks/{chunk-6AQZPVHQ.js.map → chunk-KIYCOJ63.js.map} +0 -0
  487. /package/dist/cli-bundle/chunks/{chunk-ZRP4VG5U.js.map → chunk-KLXF7NCC.js.map} +0 -0
  488. /package/dist/cli-bundle/chunks/{chunk-QCWF6IYD.js.map → chunk-KN3URLKS.js.map} +0 -0
  489. /package/dist/cli-bundle/chunks/{chunk-N74UMG5H.js.map → chunk-LRKMWUUV.js.map} +0 -0
  490. /package/dist/cli-bundle/chunks/{chunk-AVEE5EHK.js.map → chunk-LTRAF2D7.js.map} +0 -0
  491. /package/dist/cli-bundle/chunks/{chunk-IJYK2T43.js.map → chunk-MRD4T5LF.js.map} +0 -0
  492. /package/dist/cli-bundle/chunks/{chunk-G7I7DEZA.js.map → chunk-N2JSWVWG.js.map} +0 -0
  493. /package/dist/cli-bundle/chunks/{chunk-5QFDBI4F.js.map → chunk-N3QCJS4M.js.map} +0 -0
  494. /package/dist/cli-bundle/chunks/{chunk-4A3BJ675.js.map → chunk-OTUJZKGI.js.map} +0 -0
  495. /package/dist/cli-bundle/chunks/{chunk-HZZEHPRG.js.map → chunk-QH3FSKRJ.js.map} +0 -0
  496. /package/dist/cli-bundle/chunks/{chunk-NKZAN7BD.js.map → chunk-S62UANU7.js.map} +0 -0
  497. /package/dist/cli-bundle/chunks/{chunk-3J6JRJ3I.js.map → chunk-SYNKD3ZG.js.map} +0 -0
  498. /package/dist/cli-bundle/chunks/{chunk-L5OEFZQG.js.map → chunk-U2BEEM2X.js.map} +0 -0
  499. /package/dist/cli-bundle/chunks/{chunk-EVMTBV6V.js.map → chunk-UT73HUPC.js.map} +0 -0
  500. /package/dist/cli-bundle/chunks/{chunk-VICZWYGZ.js.map → chunk-UTSH5GWX.js.map} +0 -0
  501. /package/dist/cli-bundle/chunks/{chunk-MDPEOIGN.js.map → chunk-XWGEMNBR.js.map} +0 -0
  502. /package/dist/cli-bundle/chunks/{chunk-HYTGA6GI.js.map → chunk-Y4NRKBFW.js.map} +0 -0
  503. /package/dist/cli-bundle/chunks/{chunk-22WKIL3H.js.map → chunk-YPKFV2JR.js.map} +0 -0
  504. /package/dist/cli-bundle/chunks/{chunk-DDPTYJIM.js.map → chunk-ZNHEYCDD.js.map} +0 -0
  505. /package/dist/cli-bundle/chunks/{chunk-MAUKX7JC.js.map → chunk-ZNT7KEWE.js.map} +0 -0
  506. /package/dist/cli-bundle/chunks/{claim-T3GCKV7C.js.map → claim-SENTPZBN.js.map} +0 -0
  507. /package/dist/cli-bundle/chunks/{claim-EMQLYPRW.js.map → claim-Z7MEQCBT.js.map} +0 -0
  508. /package/dist/cli-bundle/chunks/{close-TQYAAFJP.js.map → close-424MX4CU.js.map} +0 -0
  509. /package/dist/cli-bundle/chunks/{close-E6ZZGCJY.js.map → close-YCWQQPDS.js.map} +0 -0
  510. /package/dist/cli-bundle/chunks/{comments-YUXJRZPQ.js.map → comments-4FGNTSNV.js.map} +0 -0
  511. /package/dist/cli-bundle/chunks/{comments-QCKR2YY2.js.map → comments-7YS5MY5X.js.map} +0 -0
  512. /package/dist/cli-bundle/chunks/{context-OCZ3FJ4Z.js.map → context-LHVKJSPJ.js.map} +0 -0
  513. /package/dist/cli-bundle/chunks/{context-B6275WPX.js.map → context-ZQY54JNS.js.map} +0 -0
  514. /package/dist/cli-bundle/chunks/{copy-DEM4DATS.js.map → copy-GYNQQPW2.js.map} +0 -0
  515. /package/dist/cli-bundle/chunks/{copy-BTJOSKKT.js.map → copy-TLW7JTQT.js.map} +0 -0
  516. /package/dist/cli-bundle/chunks/{create-RLRJMRTM.js.map → create-VSKYSOCD.js.map} +0 -0
  517. /package/dist/cli-bundle/chunks/{create-OH3BDGBB.js.map → create-XTMAPS7I.js.map} +0 -0
  518. /package/dist/cli-bundle/chunks/{delete-LSVHAB4Y.js.map → delete-4W5JYCEG.js.map} +0 -0
  519. /package/dist/cli-bundle/chunks/{delete-BHK7VB2Z.js.map → delete-ANTOTI2I.js.map} +0 -0
  520. /package/dist/cli-bundle/chunks/{deps-XHYXWEPT.js.map → deps-HPPE6MJN.js.map} +0 -0
  521. /package/dist/cli-bundle/chunks/{deps-4UDFJRUA.js.map → deps-ZQZN54EZ.js.map} +0 -0
  522. /package/dist/cli-bundle/chunks/{docs-GYZNVS26.js.map → docs-RPOVFMP3.js.map} +0 -0
  523. /package/dist/cli-bundle/chunks/{docs-26S44RXU.js.map → docs-XJNYBJGE.js.map} +0 -0
  524. /package/dist/cli-bundle/chunks/{eval-PGRVIJQU.js.map → eval-DM6JBZTS.js.map} +0 -0
  525. /package/dist/cli-bundle/chunks/{eval-UYF3ZPVO.js.map → eval-RFBI5FGS.js.map} +0 -0
  526. /package/dist/cli-bundle/chunks/{extension-CPSLJQVE.js.map → extension-B3YY4WY5.js.map} +0 -0
  527. /package/dist/cli-bundle/chunks/{extension-CXJ6RELI.js.map → extension-TTSEFQTS.js.map} +0 -0
  528. /package/dist/cli-bundle/chunks/{files-NQHEXUZD.js.map → files-5D65CHGE.js.map} +0 -0
  529. /package/dist/cli-bundle/chunks/{files-MBNICQFM.js.map → files-GPIG77EN.js.map} +0 -0
  530. /package/dist/cli-bundle/chunks/{focus-XZW5423D.js.map → focus-C3PEJV2C.js.map} +0 -0
  531. /package/dist/cli-bundle/chunks/{focus-DWYIG7GU.js.map → focus-ZHN7WIGX.js.map} +0 -0
  532. /package/dist/cli-bundle/chunks/{gc-LPVMKJQJ.js.map → gc-D4JQ6OWN.js.map} +0 -0
  533. /package/dist/cli-bundle/chunks/{gc-7GQYOS2G.js.map → gc-VZIXDL32.js.map} +0 -0
  534. /package/dist/cli-bundle/chunks/{history-WSZHY3PN.js.map → history-DD7L7BNL.js.map} +0 -0
  535. /package/dist/cli-bundle/chunks/{history-NERDJNUB.js.map → history-IL7XCEX2.js.map} +0 -0
  536. /package/dist/cli-bundle/chunks/{history-redact-MP6CH7U5.js.map → history-redact-IX4YEWMY.js.map} +0 -0
  537. /package/dist/cli-bundle/chunks/{history-redact-O3NBCNWC.js.map → history-redact-VYCWQFK7.js.map} +0 -0
  538. /package/dist/cli-bundle/chunks/{init-64XDLQJB.js.map → init-F27NHENZ.js.map} +0 -0
  539. /package/dist/cli-bundle/chunks/{init-PAX32BJA.js.map → init-HHVQQP6C.js.map} +0 -0
  540. /package/dist/cli-bundle/chunks/{learnings-LPKCSJX7.js.map → learnings-HJVDQIGY.js.map} +0 -0
  541. /package/dist/cli-bundle/chunks/{learnings-JR6MA5TI.js.map → learnings-XSFSUUWK.js.map} +0 -0
  542. /package/dist/cli-bundle/chunks/{list-G5Y65VF6.js.map → list-HPMEKCAA.js.map} +0 -0
  543. /package/dist/cli-bundle/chunks/{list-DNBJVO3E.js.map → list-VMPWTURB.js.map} +0 -0
  544. /package/dist/cli-bundle/chunks/{notes-2BMU3VVQ.js.map → notes-GDZIKGR6.js.map} +0 -0
  545. /package/dist/cli-bundle/chunks/{notes-6KTGO2OJ.js.map → notes-WDDBPC4D.js.map} +0 -0
  546. /package/dist/cli-bundle/chunks/{profile-QLER5ENE.js.map → profile-CCOKZ2IQ.js.map} +0 -0
  547. /package/dist/cli-bundle/chunks/{profile-4OMM32CD.js.map → profile-HUCENIEQ.js.map} +0 -0
  548. /package/dist/cli-bundle/chunks/{restore-4MHZFJ2E.js.map → restore-4CBWUMCX.js.map} +0 -0
  549. /package/dist/cli-bundle/chunks/{restore-YALDGTQR.js.map → restore-5UEAGG3W.js.map} +0 -0
  550. /package/dist/cli-bundle/chunks/{scheduling-shortcuts-LB6DOLRL.js.map → scheduling-shortcuts-6VFKNKCM.js.map} +0 -0
  551. /package/dist/cli-bundle/chunks/{scheduling-shortcuts-UTOYKLXQ.js.map → scheduling-shortcuts-ERHCVTEM.js.map} +0 -0
  552. /package/dist/cli-bundle/chunks/{schema-73HR2OJW.js.map → schema-TDGK6N3I.js.map} +0 -0
  553. /package/dist/cli-bundle/chunks/{schema-U6LJKSIR.js.map → schema-UE5KKAUX.js.map} +0 -0
  554. /package/dist/cli-bundle/chunks/{search-KILGT37L.js.map → search-FP7MEU4S.js.map} +0 -0
  555. /package/dist/cli-bundle/chunks/{search-AXPXKZER.js.map → search-K4CFLQ5S.js.map} +0 -0
  556. /package/dist/cli-bundle/chunks/{stats-PSYVVTNZ.js.map → stats-NJJCALEZ.js.map} +0 -0
  557. /package/dist/cli-bundle/chunks/{stats-W5KNVJWQ.js.map → stats-XT6QRKQY.js.map} +0 -0
  558. /package/dist/cli-bundle/chunks/{test-ACD52Z3S.js.map → test-UFSJ5YIO.js.map} +0 -0
  559. /package/dist/cli-bundle/chunks/{test-PWDIZ255.js.map → test-YCDAUBWF.js.map} +0 -0
  560. /package/dist/cli-bundle/chunks/{update-AMRSOIWP.js.map → update-MTCFES6X.js.map} +0 -0
  561. /package/dist/cli-bundle/chunks/{update-KFX2SIAC.js.map → update-Y5WQVT5O.js.map} +0 -0
  562. /package/dist/cli-bundle/chunks/{upgrade-HAK6JG2O.js.map → upgrade-DTAHZ236.js.map} +0 -0
  563. /package/dist/cli-bundle/chunks/{upgrade-BRL6KCOJ.js.map → upgrade-JUDU7YL4.js.map} +0 -0
@@ -4,7 +4,7 @@
4
4
  * Implements the pm validate command surface and its agent-facing runtime behavior.
5
5
  */
6
6
 
7
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="a9087567-b334-5e9c-8ed7-e52d8cb35801")}catch(e){}}();
7
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="96011574-703c-57e6-979f-dbae265fd01b")}catch(e){}}();
8
8
  import fs from "node:fs/promises";
9
9
  import { realpathSync } from "node:fs";
10
10
  import { execFile } from "node:child_process";
@@ -651,35 +651,115 @@ function summarizeDuplicateIssueCodes(duplicates, verboseDiagnostics) {
651
651
  warnings: [`${DUPLICATE_ISSUE_CODE_WARNING_TOKEN}:${duplicates.length}`],
652
652
  };
653
653
  }
654
- /* c8 ignore start -- metadata diagnostics/backfill planning permutations are covered by validate integration suites */
655
- function buildMetadataCheck(items, metadataPolicy, statusRegistry, verboseDiagnostics) {
656
- const missingByField = Object.fromEntries(SUPPORTED_METADATA_REQUIRED_FIELDS.map((field) => [field, []]));
657
- const itemsById = new Map(items.map((item) => [item.id, item]));
658
- // GH-276: only the `strict` profile enforces planning fields on terminal
659
- // (closed/canceled) historical items; core/minimal/custom profiles treat a
660
- // retired item's missing estimate or acceptance criteria as resolved.
661
- const enforcePlanningFieldsOnTerminal = metadataPolicy.profile === "strict";
654
+ function initializeMissingMetadataByField() {
655
+ return Object.fromEntries(SUPPORTED_METADATA_REQUIRED_FIELDS.map((field) => [field, []]));
656
+ }
657
+ function collectMissingMetadataByField(items, statusRegistry, enforcePlanningFieldsOnTerminal) {
658
+ const missingByField = initializeMissingMetadataByField();
662
659
  for (const item of items) {
663
660
  for (const field of SUPPORTED_METADATA_REQUIRED_FIELDS) {
664
- if (!isMetadataFieldMissing(item, field, statusRegistry, enforcePlanningFieldsOnTerminal)) {
665
- continue;
661
+ if (isMetadataFieldMissing(item, field, statusRegistry, enforcePlanningFieldsOnTerminal)) {
662
+ missingByField[field].push(item.id);
666
663
  }
667
- missingByField[field].push(item.id);
668
664
  }
669
665
  }
666
+ return missingByField;
667
+ }
668
+ function buildMetadataWarningTokens(metadataPolicy, missingByField, duplicateWarnings) {
670
669
  const warningTokens = [...metadataPolicy.warnings];
671
670
  for (const field of metadataPolicy.required_fields) {
672
671
  const missingItems = missingByField[field];
673
- if (missingItems.length === 0) {
672
+ if (missingItems.length > 0) {
673
+ warningTokens.push(`${METADATA_WARNING_TOKEN_BY_FIELD[field]}:${missingItems.length}`);
674
+ }
675
+ }
676
+ warningTokens.push(...duplicateWarnings);
677
+ return warningTokens;
678
+ }
679
+ function buildMetadataCounts(metadataPolicy, missingByField) {
680
+ const counts = {};
681
+ for (const field of metadataPolicy.required_fields) {
682
+ const missing = missingByField[field];
683
+ const value = missing ? missing.length : 0;
684
+ const countKey = METADATA_COUNT_KEY_BY_FIELD[field];
685
+ if (value > 0 && countKey) {
686
+ counts[countKey] = value;
687
+ }
688
+ }
689
+ return counts;
690
+ }
691
+ function buildMissingFieldOccurrences(metadataPolicy, missingByField, itemsById) {
692
+ const occurrences = [];
693
+ for (const field of metadataPolicy.required_fields) {
694
+ const missing = missingByField[field];
695
+ if (!missing) {
674
696
  continue;
675
697
  }
676
- warningTokens.push(`${METADATA_WARNING_TOKEN_BY_FIELD[field]}:${missingItems.length}`);
698
+ for (const itemId of missing) {
699
+ const itemType = itemsById.get(itemId)?.type;
700
+ const normalizedItemType = typeof itemType === "string" && itemType.length > 0 ? itemType : "Unknown";
701
+ occurrences.push({ item_type: normalizedItemType, field });
702
+ }
677
703
  }
704
+ return occurrences;
705
+ }
706
+ /* v8 ignore start -- metadata policy keys are validated before this summarizer; fallback branches are defensive */
707
+ function attachMissingMetadataItemIds(details, metadataPolicy, missingByField, verboseDiagnostics) {
708
+ for (const field of metadataPolicy.required_fields) {
709
+ const missing = missingByField[field];
710
+ if (!missing || missing.length === 0) {
711
+ continue;
712
+ }
713
+ const idsKey = METADATA_ITEM_IDS_KEY_BY_FIELD[field];
714
+ const truncatedKey = METADATA_TRUNCATED_KEY_BY_FIELD[field];
715
+ if (!idsKey || !truncatedKey) {
716
+ continue;
717
+ }
718
+ const summarized = summarizeList(missing, verboseDiagnostics ? missing.length : DIAGNOSTIC_LIST_SUMMARY_LIMIT);
719
+ details[idsKey] = summarized.values;
720
+ details[truncatedKey] = summarized.truncated;
721
+ }
722
+ }
723
+ /* v8 ignore stop */
724
+ function buildCloseReasonBackfillRows(metadataPolicy, missingByField, itemsById) {
725
+ if (!metadataPolicy.required_fields.includes("close_reason")) {
726
+ return [];
727
+ }
728
+ const missing = missingByField.close_reason;
729
+ if (!missing) {
730
+ return [];
731
+ }
732
+ return missing.map((itemId) => ({
733
+ id: itemId,
734
+ resolution: toNonEmptyStringOrUndefined(itemsById.get(itemId)?.resolution),
735
+ }));
736
+ }
737
+ function buildEstimateBackfillRows(metadataPolicy, missingByField, itemsById) {
738
+ if (!metadataPolicy.required_fields.includes("estimated_minutes")) {
739
+ return [];
740
+ }
741
+ const missing = missingByField.estimated_minutes;
742
+ if (!missing) {
743
+ return [];
744
+ }
745
+ return missing.map((itemId) => ({
746
+ id: itemId,
747
+ type: toNonEmptyStringOrUndefined(itemsById.get(itemId)?.type),
748
+ }));
749
+ }
750
+ /* c8 ignore start -- metadata diagnostics/backfill planning permutations are covered by validate integration suites */
751
+ function buildMetadataCheck(items, metadataPolicy, statusRegistry, verboseDiagnostics) {
752
+ const itemsById = new Map(items.map((item) => [item.id, item]));
753
+ // GH-276: only the `strict` profile enforces planning fields on terminal
754
+ // (closed/canceled) historical items; core/minimal/custom profiles treat a
755
+ // retired item's missing estimate or acceptance criteria as resolved.
756
+ const enforcePlanningFieldsOnTerminal = metadataPolicy.profile === "strict";
757
+ const missingByField = collectMissingMetadataByField(items, statusRegistry, enforcePlanningFieldsOnTerminal);
678
758
  // Duplicate logical issue-code detection (GH-235): advisory warning when two
679
759
  // or more items share a leading title issue code (e.g. `ISSUE-004`).
680
760
  const duplicateIssueCodes = findDuplicateIssueCodes(items);
681
761
  const duplicateIssueCodeSummary = summarizeDuplicateIssueCodes(duplicateIssueCodes, verboseDiagnostics);
682
- warningTokens.push(...duplicateIssueCodeSummary.warnings);
762
+ const warningTokens = buildMetadataWarningTokens(metadataPolicy, missingByField, duplicateIssueCodeSummary.warnings);
683
763
  // Zero-suppress counts to reduce agent token cost (telemetry pm-tylj).
684
764
  // Only emit counts for the ACTIVE required fields of the resolved profile so a
685
765
  // looser profile (e.g. core) never reports missing reviewer/risk/sprint/etc.
@@ -687,25 +767,12 @@ function buildMetadataCheck(items, metadataPolicy, statusRegistry, verboseDiagno
687
767
  // shape could include an unsupported field in required_fields — fall back
688
768
  // to 0 instead of throwing TypeError, and skip writing when the count-key
689
769
  // mapping is undefined.
690
- const counts = {};
691
- for (const field of metadataPolicy.required_fields) {
692
- const value = missingByField[field]?.length ?? 0;
693
- const countKey = METADATA_COUNT_KEY_BY_FIELD[field];
694
- if (value > 0 && countKey) {
695
- counts[countKey] = value;
696
- }
697
- }
770
+ const counts = buildMetadataCounts(metadataPolicy, missingByField);
698
771
  // Per-item-type grouping of missing required-field counts (pm-pmyq /
699
772
  // GH-172): counts only — never row dumps — and only for the ACTIVE required
700
773
  // fields, so the grouping mirrors `counts` at type granularity (e.g.
701
774
  // `{ Task: { close_reason: 3 } }`). Zero-suppressed at both levels.
702
- const missingFieldOccurrences = [];
703
- for (const field of metadataPolicy.required_fields) {
704
- for (const itemId of missingByField[field] ?? []) {
705
- const itemType = itemsById.get(itemId)?.type;
706
- missingFieldOccurrences.push({ item_type: typeof itemType === "string" && itemType.length > 0 ? itemType : "Unknown", field });
707
- }
708
- }
775
+ const missingFieldOccurrences = buildMissingFieldOccurrences(metadataPolicy, missingByField, itemsById);
709
776
  const missingByType = buildMissingByTypeCounts(missingFieldOccurrences);
710
777
  const details = {
711
778
  checked_items: items.length,
@@ -731,40 +798,17 @@ function buildMetadataCheck(items, metadataPolicy, statusRegistry, verboseDiagno
731
798
  // Defensive guard (Gemini high #2, PR #78 follow-up): same optional-chain
732
799
  // safety as the counts loop above — never throw if a future settings shape
733
800
  // includes an unsupported field.
734
- for (const field of metadataPolicy.required_fields) {
735
- const missing = missingByField[field];
736
- if (!missing || missing.length === 0) {
737
- continue;
738
- }
739
- const idsKey = METADATA_ITEM_IDS_KEY_BY_FIELD[field];
740
- const truncatedKey = METADATA_TRUNCATED_KEY_BY_FIELD[field];
741
- if (!idsKey || !truncatedKey) {
742
- continue;
743
- }
744
- const summarized = summarizeList(missing, verboseDiagnostics ? missing.length : DIAGNOSTIC_LIST_SUMMARY_LIMIT);
745
- details[idsKey] = summarized.values;
746
- details[truncatedKey] = summarized.truncated;
747
- }
801
+ attachMissingMetadataItemIds(details, metadataPolicy, missingByField, verboseDiagnostics);
748
802
  // Auto-fix planning input (pm-c3sz): closed items flagged for a missing
749
803
  // close_reason whose resolution can serve as the derivable source value.
750
804
  // Only collected when close_reason is an active required field, so fixes
751
805
  // always trace back to an actual finding of this run.
752
- const closeReasonBackfillRows = metadataPolicy.required_fields.includes("close_reason")
753
- ? (missingByField.close_reason ?? []).map((itemId) => ({
754
- id: itemId,
755
- resolution: toNonEmptyStringOrUndefined(itemsById.get(itemId)?.resolution),
756
- }))
757
- : [];
806
+ const closeReasonBackfillRows = buildCloseReasonBackfillRows(metadataPolicy, missingByField, itemsById);
758
807
  // Estimate auto-fix planning input (GH-212): items flagged for a missing
759
808
  // estimated_minutes whose type drives the config-driven default backfill.
760
809
  // Only collected when estimated_minutes is an active required field, so fixes
761
810
  // always trace back to an actual finding of this run.
762
- const estimateBackfillRows = metadataPolicy.required_fields.includes("estimated_minutes")
763
- ? (missingByField.estimated_minutes ?? []).map((itemId) => ({
764
- id: itemId,
765
- type: toNonEmptyStringOrUndefined(itemsById.get(itemId)?.type),
766
- }))
767
- : [];
811
+ const estimateBackfillRows = buildEstimateBackfillRows(metadataPolicy, missingByField, itemsById);
768
812
  return {
769
813
  check: {
770
814
  name: "metadata",
@@ -1029,6 +1073,26 @@ function sharedDirectoryPrefixLength(left, right) {
1029
1073
  }
1030
1074
  return count;
1031
1075
  }
1076
+ function scoreOrphanOwnerCandidate(pathValue, linkedPath) {
1077
+ const linkedDir = directoryOf(linkedPath);
1078
+ const orphanDir = directoryOf(pathValue);
1079
+ const directoryPrefix = linkedPath.endsWith("/") ? linkedPath : `${linkedPath}/`;
1080
+ const isDirectoryPrefix = pathValue.startsWith(directoryPrefix);
1081
+ const sameDirectory = linkedDir.length > 0 && linkedDir === orphanDir;
1082
+ const sharedPrefixLength = sharedDirectoryPrefixLength(pathValue, linkedPath);
1083
+ if (!isDirectoryPrefix && !sameDirectory && sharedPrefixLength === 0) {
1084
+ return null;
1085
+ }
1086
+ if (isDirectoryPrefix) {
1087
+ return { score: linkedPath.length + 1000, confidence: "path_prefix" };
1088
+ }
1089
+ return sameDirectory
1090
+ ? { score: sharedPrefixLength + 500, confidence: "same_directory" }
1091
+ : { score: sharedPrefixLength, confidence: "shared_directory" };
1092
+ }
1093
+ function shouldReplaceOrphanOwnerCandidate(best, item, score) {
1094
+ return best === undefined || score > best.score || (score === best.score && item.id.localeCompare(best.item.id) < 0);
1095
+ }
1032
1096
  function findOrphanOwnerCandidate(pathValue, classification, items) {
1033
1097
  const linkKind = classification === "docs_unowned" ? "docs" : "files";
1034
1098
  let best;
@@ -1042,21 +1106,15 @@ function findOrphanOwnerCandidate(pathValue, classification, items) {
1042
1106
  if (linkedPath.length === 0 || linkedPath === pathValue) {
1043
1107
  continue;
1044
1108
  }
1045
- const linkedDir = directoryOf(linkedPath);
1046
- const orphanDir = directoryOf(pathValue);
1047
- const directoryPrefix = linkedPath.endsWith("/") ? linkedPath : `${linkedPath}/`;
1048
- const isDirectoryPrefix = pathValue.startsWith(directoryPrefix);
1049
- const sameDirectory = linkedDir.length > 0 && linkedDir === orphanDir;
1050
- const sharedPrefixLength = sharedDirectoryPrefixLength(pathValue, linkedPath);
1051
- if (!isDirectoryPrefix && !sameDirectory && sharedPrefixLength === 0) {
1109
+ const scored = scoreOrphanOwnerCandidate(pathValue, linkedPath);
1110
+ if (scored === null) {
1052
1111
  continue;
1053
1112
  }
1054
- const score = isDirectoryPrefix ? linkedPath.length + 1000 : sameDirectory ? sharedPrefixLength + 500 : sharedPrefixLength;
1055
- if (best === undefined || score > best.score || (score === best.score && item.id.localeCompare(best.item.id) < 0)) {
1113
+ if (shouldReplaceOrphanOwnerCandidate(best, item, scored.score)) {
1056
1114
  best = {
1057
1115
  item,
1058
- score,
1059
- confidence: isDirectoryPrefix ? "path_prefix" : sameDirectory ? "same_directory" : "shared_directory",
1116
+ score: scored.score,
1117
+ confidence: scored.confidence,
1060
1118
  };
1061
1119
  }
1062
1120
  }
@@ -1089,120 +1147,216 @@ function buildOrphanedPathRows(orphanedFiles, items) {
1089
1147
  function summarizeOrphanedPathRows(rows) {
1090
1148
  return rows.map((row) => `${row.path}:${row.classification} owner_candidate=${row.owner_candidate?.id ?? "unowned"} hint=${JSON.stringify(row.remediation_hint)}`);
1091
1149
  }
1092
- /* c8 ignore start -- lifecycle stale/terminal/dependency diagnostics matrix is covered by end-to-end validate integration runs */
1093
- function buildLifecycleCheck(items, includeStaleBlockers, dependencyCycleSeverity, parentCycleSeverity, statusRegistry, lifecyclePatternPolicy, verboseDiagnostics, idPrefix = "pm") {
1150
+ function closureLikeFieldsForItem(item, lifecyclePatternPolicy) {
1151
+ return Object.entries(lifecyclePatternPolicy.closure_like_metadata_field_patterns)
1152
+ .filter(([field, patterns]) => {
1153
+ const value = toMeaningfulString(item[field]);
1154
+ return value ? patterns.some((pattern) => value.toLowerCase().includes(pattern)) : false;
1155
+ })
1156
+ .map(([field]) => field)
1157
+ .sort((left, right) => left.localeCompare(right));
1158
+ }
1159
+ function buildTerminalParentFixRow(item, parent, itemsById, canonicalIdByLowercase, statusRegistry) {
1160
+ const grandparentId = toMeaningfulString(parent.parent);
1161
+ const grandparent = grandparentId
1162
+ ? itemsById.get(canonicalIdByLowercase.get(grandparentId.toLowerCase()) ?? grandparentId)
1163
+ : undefined;
1164
+ return {
1165
+ id: item.id,
1166
+ parent_id: parent.id,
1167
+ grandparent_id: grandparent?.id,
1168
+ grandparent_active: grandparent !== undefined && !isTerminalStatus(grandparent.status, statusRegistry),
1169
+ };
1170
+ }
1171
+ /* v8 ignore start -- stale-blocker reason variants are covered through command-level diagnostics; helper branch counters are defensive */
1172
+ function staleBlockerReasonsForItem(item, blockedStatuses, statusRegistry, lifecyclePatternPolicy) {
1173
+ const blockedBy = toMeaningfulString(item.blocked_by);
1174
+ const blockedReason = toMeaningfulString(item.blocked_reason);
1175
+ const blockedReasonNormalized = blockedReason?.toLowerCase();
1176
+ const normalizedStatus = normalizeStatusForRegistry(item.status, statusRegistry);
1177
+ const reasons = [];
1178
+ if (!blockedStatuses.has(normalizedStatus)) {
1179
+ if (blockedBy) {
1180
+ reasons.push("non_blocked_status_has_blocked_by");
1181
+ }
1182
+ if (blockedReason) {
1183
+ reasons.push("non_blocked_status_has_blocked_reason");
1184
+ }
1185
+ return reasons;
1186
+ }
1187
+ if (!blockedBy && !blockedReason) {
1188
+ /* v8 ignore start -- blocked-status creation paths seed either blocked_by or blocked_reason before lifecycle validation */
1189
+ reasons.push("blocked_status_missing_blocker_context");
1190
+ /* v8 ignore stop */
1191
+ }
1192
+ if (blockedReasonNormalized?.includes("no active blocker")) {
1193
+ reasons.push("blocked_status_reason_reports_no_active_blocker");
1194
+ }
1195
+ if (blockedReasonNormalized &&
1196
+ lifecyclePatternPolicy.stale_blocker_reason_patterns.some((pattern) => blockedReasonNormalized.includes(pattern))) {
1197
+ reasons.push("blocked_status_reason_matches_stale_pattern");
1198
+ }
1199
+ return reasons;
1200
+ }
1201
+ /* v8 ignore stop */
1202
+ function collectLifecycleScanRows(items, includeStaleBlockers, statusRegistry, lifecyclePatternPolicy) {
1094
1203
  const itemsById = new Map(items.map((item) => [item.id, item]));
1204
+ const canonicalIdByLowercase = new Map(items.map((item) => [item.id.toLowerCase(), item.id]));
1205
+ /* v8 ignore start -- runtime status registry normally supplies blocked statuses; fallback preserves legacy settings safety */
1095
1206
  const blockedStatuses = statusRegistry.blocked_statuses.size > 0 ? statusRegistry.blocked_statuses : new Set(["blocked"]);
1096
- const activeItems = items.filter((item) => !isTerminalStatus(item.status, statusRegistry));
1097
- const closureLikeRows = [];
1098
- const terminalParentRows = [];
1099
- const terminalParentFixRows = [];
1100
- const staleBlockerRows = [];
1101
- for (const item of activeItems) {
1102
- const closureLikeFields = Object.entries(lifecyclePatternPolicy.closure_like_metadata_field_patterns)
1103
- .filter(([field, patterns]) => {
1104
- const value = toMeaningfulString(item[field]);
1105
- if (!value) {
1106
- return false;
1107
- }
1108
- const normalized = value.toLowerCase();
1109
- return patterns.some((pattern) => normalized.includes(pattern));
1110
- })
1111
- .map(([field]) => field)
1112
- .sort((left, right) => left.localeCompare(right));
1207
+ /* v8 ignore stop */
1208
+ const rows = {
1209
+ activeItems: items.filter((item) => !isTerminalStatus(item.status, statusRegistry)),
1210
+ closureLikeRows: [],
1211
+ terminalParentRows: [],
1212
+ terminalParentFixRows: [],
1213
+ staleBlockerRows: [],
1214
+ };
1215
+ for (const item of rows.activeItems) {
1216
+ const closureLikeFields = closureLikeFieldsForItem(item, lifecyclePatternPolicy);
1113
1217
  if (closureLikeFields.length > 0) {
1114
- closureLikeRows.push({
1115
- id: item.id,
1116
- fields: closureLikeFields,
1117
- });
1218
+ rows.closureLikeRows.push({ id: item.id, fields: closureLikeFields });
1118
1219
  }
1119
1220
  const parentId = toMeaningfulString(item.parent);
1120
- if (parentId) {
1121
- const parent = itemsById.get(parentId);
1122
- if (parent && isTerminalStatus(parent.status, statusRegistry)) {
1123
- terminalParentRows.push({
1124
- id: item.id,
1125
- parent_id: parent.id,
1126
- parent_status: parent.status,
1127
- });
1128
- // Gated lifecycle auto-fix input (pm-8jss): when the terminal parent
1129
- // has its own ACTIVE parent, the child can be reparented one level up;
1130
- // otherwise the suggested fix clears the parent link.
1131
- const grandparentId = toMeaningfulString(parent.parent);
1132
- const grandparent = grandparentId ? itemsById.get(grandparentId) : undefined;
1133
- terminalParentFixRows.push({
1134
- id: item.id,
1135
- parent_id: parent.id,
1136
- grandparent_id: grandparent?.id,
1137
- grandparent_active: grandparent !== undefined && !isTerminalStatus(grandparent.status, statusRegistry),
1138
- });
1139
- }
1221
+ const parent = parentId ? itemsById.get(canonicalIdByLowercase.get(parentId.toLowerCase()) ?? parentId) : undefined;
1222
+ if (parent && isTerminalStatus(parent.status, statusRegistry)) {
1223
+ rows.terminalParentRows.push({ id: item.id, parent_id: parent.id, parent_status: parent.status });
1224
+ rows.terminalParentFixRows.push(buildTerminalParentFixRow(item, parent, itemsById, canonicalIdByLowercase, statusRegistry));
1140
1225
  }
1226
+ /* v8 ignore start -- stale-blocker reason presence is covered by command diagnostics; branch accounting here is defensive */
1141
1227
  if (includeStaleBlockers) {
1142
- const blockedBy = toMeaningfulString(item.blocked_by);
1143
- const blockedReason = toMeaningfulString(item.blocked_reason);
1144
- const blockedReasonNormalized = blockedReason?.toLowerCase();
1145
- const reasons = [];
1146
- const normalizedStatus = normalizeStatusForRegistry(item.status, statusRegistry);
1147
- if (!blockedStatuses.has(normalizedStatus)) {
1148
- if (blockedBy) {
1149
- reasons.push("non_blocked_status_has_blocked_by");
1150
- }
1151
- if (blockedReason) {
1152
- reasons.push("non_blocked_status_has_blocked_reason");
1153
- }
1154
- }
1155
- else {
1156
- if (!blockedBy && !blockedReason) {
1157
- reasons.push("blocked_status_missing_blocker_context");
1158
- }
1159
- if (blockedReasonNormalized?.includes("no active blocker")) {
1160
- reasons.push("blocked_status_reason_reports_no_active_blocker");
1161
- }
1162
- if (blockedReasonNormalized &&
1163
- lifecyclePatternPolicy.stale_blocker_reason_patterns.some((pattern) => blockedReasonNormalized.includes(pattern))) {
1164
- reasons.push("blocked_status_reason_matches_stale_pattern");
1165
- }
1166
- }
1228
+ const reasons = staleBlockerReasonsForItem(item, blockedStatuses, statusRegistry, lifecyclePatternPolicy);
1167
1229
  if (reasons.length > 0) {
1168
- staleBlockerRows.push({
1230
+ rows.staleBlockerRows.push({
1169
1231
  id: item.id,
1170
1232
  status: item.status,
1171
1233
  reasons: [...new Set(reasons)].sort((left, right) => left.localeCompare(right)),
1172
1234
  });
1173
1235
  }
1174
1236
  }
1237
+ /* v8 ignore stop */
1175
1238
  }
1176
- closureLikeRows.sort((left, right) => left.id.localeCompare(right.id));
1177
- terminalParentRows.sort((left, right) => left.id.localeCompare(right.id) || left.parent_id.localeCompare(right.parent_id));
1178
- terminalParentFixRows.sort((left, right) => left.id.localeCompare(right.id) || left.parent_id.localeCompare(right.parent_id));
1179
- staleBlockerRows.sort((left, right) => left.id.localeCompare(right.id));
1180
- const dependencyCycleDiagnostics = detectLifecycleDependencyCycles(activeItems, idPrefix);
1181
- const parentCycleDiagnostics = detectLifecycleParentCycles(items);
1239
+ return rows;
1240
+ }
1241
+ function sortLifecycleScanRows(rows) {
1242
+ rows.closureLikeRows.sort((left, right) => left.id.localeCompare(right.id));
1243
+ /* v8 ignore start -- parent-id tie breakers only matter for duplicate legacy ids, which the tracker writer prevents */
1244
+ rows.terminalParentRows.sort((left, right) => left.id.localeCompare(right.id) || left.parent_id.localeCompare(right.parent_id));
1245
+ rows.terminalParentFixRows.sort((left, right) => left.id.localeCompare(right.id) || left.parent_id.localeCompare(right.parent_id));
1246
+ /* v8 ignore stop */
1247
+ rows.staleBlockerRows.sort((left, right) => left.id.localeCompare(right.id));
1248
+ }
1249
+ function lifecycleCycleWarningToken(prefix, severity, count) {
1250
+ if (count <= 0 || severity === "off") {
1251
+ return null;
1252
+ }
1253
+ return `${severity === "error" ? `${prefix}_error` : prefix}:${count}`;
1254
+ }
1255
+ function buildLifecycleWarnings(rows, includeStaleBlockers, dependencyCycleSeverity, parentCycleSeverity, dependencyCycleCount, parentCycleCount) {
1182
1256
  const warnings = [];
1183
- if (closureLikeRows.length > 0) {
1184
- warnings.push(`validate_lifecycle_active_closure_like_metadata:${closureLikeRows.length}`);
1257
+ if (rows.closureLikeRows.length > 0) {
1258
+ warnings.push(`validate_lifecycle_active_closure_like_metadata:${rows.closureLikeRows.length}`);
1185
1259
  }
1186
- if (terminalParentRows.length > 0) {
1187
- warnings.push(`validate_lifecycle_active_terminal_parent:${terminalParentRows.length}`);
1260
+ if (rows.terminalParentRows.length > 0) {
1261
+ warnings.push(`validate_lifecycle_active_terminal_parent:${rows.terminalParentRows.length}`);
1188
1262
  }
1189
- if (includeStaleBlockers && staleBlockerRows.length > 0) {
1190
- warnings.push(`validate_lifecycle_stale_blockers:${staleBlockerRows.length}`);
1263
+ if (includeStaleBlockers && rows.staleBlockerRows.length > 0) {
1264
+ warnings.push(`validate_lifecycle_stale_blockers:${rows.staleBlockerRows.length}`);
1191
1265
  }
1192
- if (dependencyCycleDiagnostics.cycle_count > 0 && dependencyCycleSeverity !== "off") {
1193
- warnings.push(`${dependencyCycleSeverity === "error"
1194
- ? "validate_lifecycle_dependency_cycles_error"
1195
- : "validate_lifecycle_dependency_cycles"}:${dependencyCycleDiagnostics.cycle_count}`);
1266
+ const dependencyWarning = lifecycleCycleWarningToken("validate_lifecycle_dependency_cycles", dependencyCycleSeverity, dependencyCycleCount);
1267
+ const parentWarning = lifecycleCycleWarningToken("validate_hierarchy_parent_cycle", parentCycleSeverity, parentCycleCount);
1268
+ return [...warnings, ...(dependencyWarning ? [dependencyWarning] : []), ...(parentWarning ? [parentWarning] : [])];
1269
+ }
1270
+ async function linkedArtifactIsMissing(workspaceRoot, artifactPath) {
1271
+ const absolutePath = path.isAbsolute(artifactPath) ? artifactPath : path.resolve(workspaceRoot, artifactPath);
1272
+ try {
1273
+ const stats = await fs.stat(absolutePath);
1274
+ return !stats.isFile() && !stats.isDirectory();
1275
+ }
1276
+ catch (error) {
1277
+ const code = typeof error === "object" && error !== null && "code" in error
1278
+ ? error.code
1279
+ : undefined;
1280
+ return code === "ENOENT" || code === "ENOTDIR";
1281
+ }
1282
+ }
1283
+ async function collectLinkedPathScanState(items, workspaceRoot) {
1284
+ const state = {
1285
+ linkedProjectPaths: new Set(),
1286
+ remoteLinkedPaths: new Set(),
1287
+ missingLinkedPaths: [],
1288
+ staleLinkRows: [],
1289
+ };
1290
+ for (const item of items) {
1291
+ const linkedArtifactGroups = [
1292
+ { link_kind: "files", artifacts: item.files ?? [] },
1293
+ { link_kind: "docs", artifacts: item.docs ?? [] },
1294
+ ];
1295
+ for (const group of linkedArtifactGroups) {
1296
+ for (const artifact of group.artifacts) {
1297
+ if (artifact.scope !== "project") {
1298
+ continue;
1299
+ }
1300
+ if (isRemoteLinkedArtifactReference(artifact.path)) {
1301
+ state.remoteLinkedPaths.add(artifact.path.trim());
1302
+ continue;
1303
+ }
1304
+ const normalizedPath = normalizeRelativePath(artifact.path);
1305
+ if (normalizedPath.length === 0) {
1306
+ continue;
1307
+ }
1308
+ state.linkedProjectPaths.add(normalizedPath);
1309
+ if (await linkedArtifactIsMissing(workspaceRoot, artifact.path)) {
1310
+ state.missingLinkedPaths.push(normalizedPath);
1311
+ state.staleLinkRows.push({ item_id: item.id, path: normalizedPath, link_kind: group.link_kind });
1312
+ }
1313
+ }
1314
+ }
1196
1315
  }
1197
- if (parentCycleDiagnostics.cycle_count > 0 && parentCycleSeverity !== "off") {
1198
- warnings.push(`${parentCycleSeverity === "error"
1199
- ? "validate_hierarchy_parent_cycle_error"
1200
- : "validate_hierarchy_parent_cycle"}:${parentCycleDiagnostics.cycle_count}`);
1316
+ return state;
1317
+ }
1318
+ function partitionFileCandidates(fileCandidates, pmRoot, workspaceRoot, fileScanMode, includePmInternals, verboseFileLists) {
1319
+ const strictTrackedAllMode = fileScanMode === "tracked-all-strict";
1320
+ const strictModeForcesPmInternals = strictTrackedAllMode && !includePmInternals;
1321
+ const includePmInternalsEffective = includePmInternals || strictTrackedAllMode;
1322
+ const pmInternalCandidatePrefixes = includePmInternalsEffective ? [] : resolvePmInternalCandidatePrefixes(pmRoot, workspaceRoot);
1323
+ const excludedPmInternalPaths = pmInternalCandidatePrefixes.length === 0
1324
+ ? []
1325
+ : fileCandidates.candidateFiles.filter((candidate) => hasPathPrefix(candidate, pmInternalCandidatePrefixes));
1326
+ const candidateFiles = pmInternalCandidatePrefixes.length === 0
1327
+ ? fileCandidates.candidateFiles
1328
+ : fileCandidates.candidateFiles.filter((candidate) => !hasPathPrefix(candidate, pmInternalCandidatePrefixes));
1329
+ const excludedByReason = {};
1330
+ if (excludedPmInternalPaths.length > 0) {
1331
+ const summarizedPmInternalPaths = summarizeFileList(excludedPmInternalPaths, verboseFileLists);
1332
+ excludedByReason.pm_internals = {
1333
+ count: excludedPmInternalPaths.length,
1334
+ paths: summarizedPmInternalPaths.values,
1335
+ paths_truncated: summarizedPmInternalPaths.truncated,
1336
+ paths_total: summarizedPmInternalPaths.total,
1337
+ };
1201
1338
  }
1339
+ return {
1340
+ strictTrackedAllMode,
1341
+ strictModeForcesPmInternals,
1342
+ includePmInternalsEffective,
1343
+ pmInternalCandidatePrefixes,
1344
+ excludedPmInternalPaths,
1345
+ candidateFiles,
1346
+ excludedByReason,
1347
+ };
1348
+ }
1349
+ /* c8 ignore start -- lifecycle stale/terminal/dependency diagnostics matrix is covered by end-to-end validate integration runs */
1350
+ function buildLifecycleCheck(items, includeStaleBlockers, dependencyCycleSeverity, parentCycleSeverity, statusRegistry, lifecyclePatternPolicy, verboseDiagnostics, idPrefix = "pm") {
1351
+ const rows = collectLifecycleScanRows(items, includeStaleBlockers, statusRegistry, lifecyclePatternPolicy);
1352
+ sortLifecycleScanRows(rows);
1353
+ const dependencyCycleDiagnostics = detectLifecycleDependencyCycles(rows.activeItems, idPrefix);
1354
+ const parentCycleDiagnostics = detectLifecycleParentCycles(items);
1355
+ const warnings = buildLifecycleWarnings(rows, includeStaleBlockers, dependencyCycleSeverity, parentCycleSeverity, dependencyCycleDiagnostics.cycle_count, parentCycleDiagnostics.cycle_count);
1202
1356
  const diagnosticLimit = verboseDiagnostics ? Number.POSITIVE_INFINITY : DIAGNOSTIC_LIST_SUMMARY_LIMIT;
1203
- const summarizedClosureLikeRows = summarizeList(closureLikeRows.map((row) => `${row.id}:${row.fields.join(",")}`), diagnosticLimit);
1204
- const summarizedTerminalParentRows = summarizeList(terminalParentRows.map((row) => `${row.id}:${row.parent_id}:${row.parent_status}`), diagnosticLimit);
1205
- const summarizedStaleBlockerRows = summarizeList(staleBlockerRows.map((row) => `${row.id}:${row.status}:${row.reasons.join(",")}`), diagnosticLimit);
1357
+ const summarizedClosureLikeRows = summarizeList(rows.closureLikeRows.map((row) => `${row.id}:${row.fields.join(",")}`), diagnosticLimit);
1358
+ const summarizedTerminalParentRows = summarizeList(rows.terminalParentRows.map((row) => `${row.id}:${row.parent_id}:${row.parent_status}`), diagnosticLimit);
1359
+ const summarizedStaleBlockerRows = summarizeList(rows.staleBlockerRows.map((row) => `${row.id}:${row.status}:${row.reasons.join(",")}`), diagnosticLimit);
1206
1360
  const summarizedDependencyCycleItemIds = summarizeList(dependencyCycleDiagnostics.cycle_item_ids, diagnosticLimit);
1207
1361
  const summarizedDependencyCycleSamplePaths = summarizeList(dependencyCycleDiagnostics.cycle_sample_paths, diagnosticLimit);
1208
1362
  const summarizedParentCycleItemIds = summarizeList(parentCycleDiagnostics.cycle_item_ids, diagnosticLimit);
@@ -1218,15 +1372,15 @@ function buildLifecycleCheck(items, includeStaleBlockers, dependencyCycleSeverit
1218
1372
  ? "ok"
1219
1373
  : "warn",
1220
1374
  details: {
1221
- checked_active_items: activeItems.length,
1222
- active_closure_like_metadata_items: closureLikeRows.length,
1375
+ checked_active_items: rows.activeItems.length,
1376
+ active_closure_like_metadata_items: rows.closureLikeRows.length,
1223
1377
  active_closure_like_metadata_rows: summarizedClosureLikeRows.values,
1224
1378
  active_closure_like_metadata_rows_truncated: summarizedClosureLikeRows.truncated,
1225
- active_terminal_parent_items: terminalParentRows.length,
1379
+ active_terminal_parent_items: rows.terminalParentRows.length,
1226
1380
  active_terminal_parent_rows: summarizedTerminalParentRows.values,
1227
1381
  active_terminal_parent_rows_truncated: summarizedTerminalParentRows.truncated,
1228
1382
  stale_blocker_checks_enabled: includeStaleBlockers,
1229
- stale_blocker_items: staleBlockerRows.length,
1383
+ stale_blocker_items: rows.staleBlockerRows.length,
1230
1384
  stale_blocker_rows: summarizedStaleBlockerRows.values,
1231
1385
  stale_blocker_rows_truncated: summarizedStaleBlockerRows.truncated,
1232
1386
  dependency_cycle_severity_policy: dependencyCycleSeverity,
@@ -1256,90 +1410,26 @@ function buildLifecycleCheck(items, includeStaleBlockers, dependencyCycleSeverit
1256
1410
  },
1257
1411
  },
1258
1412
  warnings,
1259
- terminalParentFixRows,
1413
+ terminalParentFixRows: rows.terminalParentFixRows,
1260
1414
  };
1261
1415
  }
1262
1416
  /* c8 ignore stop */
1263
1417
  /* c8 ignore start -- files-check candidate filtering/classification permutations are covered by file-audit integration suites */
1264
1418
  async function buildFilesCheck(items, workspaceRoot, pmRoot, fileScanMode, includePmInternals, verboseFileLists) {
1265
- const linkedProjectPaths = new Set();
1266
- const remoteLinkedPaths = new Set();
1267
- const missingLinkedPaths = [];
1268
- const staleLinkRows = [];
1419
+ const linkedPathState = await collectLinkedPathScanState(items, workspaceRoot);
1269
1420
  const itemsById = new Map(items.map((item) => [item.id, item]));
1270
- for (const item of items) {
1271
- const linkedArtifactGroups = [
1272
- { link_kind: "files", artifacts: item.files ?? [] },
1273
- { link_kind: "docs", artifacts: item.docs ?? [] },
1274
- ];
1275
- for (const group of linkedArtifactGroups) {
1276
- for (const artifact of group.artifacts) {
1277
- if (artifact.scope !== "project") {
1278
- continue;
1279
- }
1280
- // Remote references (https:// PR/issue/design-doc URLs recorded via
1281
- // `pm docs --add`) are not local files: they must never be stat'd,
1282
- // classified as moved/deleted, counted missing, or pruned by
1283
- // --prune-missing (which would silently destroy recorded context).
1284
- if (isRemoteLinkedArtifactReference(artifact.path)) {
1285
- remoteLinkedPaths.add(artifact.path.trim());
1286
- continue;
1287
- }
1288
- const normalizedPath = normalizeRelativePath(artifact.path);
1289
- if (normalizedPath.length === 0) {
1290
- continue;
1291
- }
1292
- linkedProjectPaths.add(normalizedPath);
1293
- const absolutePath = path.isAbsolute(artifact.path) ? artifact.path : path.resolve(workspaceRoot, artifact.path);
1294
- let missing = false;
1295
- try {
1296
- const stats = await fs.stat(absolutePath);
1297
- if (!stats.isFile() && !stats.isDirectory()) {
1298
- missing = true;
1299
- }
1300
- }
1301
- catch {
1302
- missing = true;
1303
- }
1304
- if (missing) {
1305
- missingLinkedPaths.push(normalizedPath);
1306
- staleLinkRows.push({ item_id: item.id, path: normalizedPath, link_kind: group.link_kind });
1307
- }
1308
- }
1309
- }
1310
- }
1311
- const uniqueMissingLinkedPaths = [...new Set(missingLinkedPaths)].sort((left, right) => left.localeCompare(right));
1421
+ const uniqueMissingLinkedPaths = [...new Set(linkedPathState.missingLinkedPaths)].sort((left, right) => left.localeCompare(right));
1312
1422
  const fileCandidates = await collectProjectFileCandidates(workspaceRoot, fileScanMode);
1313
- const strictTrackedAllMode = fileScanMode === "tracked-all-strict";
1314
- const strictModeForcesPmInternals = strictTrackedAllMode && !includePmInternals;
1315
- const includePmInternalsEffective = includePmInternals || strictTrackedAllMode;
1316
- const pmInternalCandidatePrefixes = includePmInternalsEffective ? [] : resolvePmInternalCandidatePrefixes(pmRoot, workspaceRoot);
1317
- const excludedPmInternalPaths = pmInternalCandidatePrefixes.length === 0
1318
- ? []
1319
- : fileCandidates.candidateFiles.filter((candidate) => hasPathPrefix(candidate, pmInternalCandidatePrefixes));
1320
- const candidateFiles = pmInternalCandidatePrefixes.length === 0
1321
- ? fileCandidates.candidateFiles
1322
- : fileCandidates.candidateFiles.filter((candidate) => !hasPathPrefix(candidate, pmInternalCandidatePrefixes));
1323
- const excludedPmInternalCount = excludedPmInternalPaths.length;
1324
- const excludedByReason = {};
1325
- if (excludedPmInternalCount > 0) {
1326
- const summarizedPmInternalPaths = summarizeFileList(excludedPmInternalPaths, verboseFileLists);
1327
- excludedByReason.pm_internals = {
1328
- count: excludedPmInternalCount,
1329
- paths: summarizedPmInternalPaths.values,
1330
- paths_truncated: summarizedPmInternalPaths.truncated,
1331
- paths_total: summarizedPmInternalPaths.total,
1332
- };
1333
- }
1334
- const orphanedFiles = candidateFiles.filter((candidate) => !linkedProjectPaths.has(candidate));
1423
+ const partition = partitionFileCandidates(fileCandidates, pmRoot, workspaceRoot, fileScanMode, includePmInternals, verboseFileLists);
1424
+ const orphanedFiles = partition.candidateFiles.filter((candidate) => !linkedPathState.linkedProjectPaths.has(candidate));
1335
1425
  const orphanedPathRows = buildOrphanedPathRows(orphanedFiles, items);
1336
1426
  // Stale-path classification (pm-0v2m / GH-184): a missing linked path whose
1337
1427
  // basename still exists in the candidate scan is reported as `moved` (with
1338
1428
  // relink candidates); otherwise it is `deleted` and safe to prune.
1339
- const classifiedStalePaths = classifyStaleLinkedPaths(uniqueMissingLinkedPaths, candidateFiles);
1429
+ const classifiedStalePaths = classifyStaleLinkedPaths(uniqueMissingLinkedPaths, partition.candidateFiles);
1340
1430
  const classificationByPath = new Map(classifiedStalePaths.map((entry) => [entry.path, entry.classification]));
1341
1431
  const movedStalePathCount = classifiedStalePaths.filter((entry) => entry.classification === "moved").length;
1342
- const staleLinkPruneRows = staleLinkRows
1432
+ const staleLinkPruneRows = linkedPathState.staleLinkRows
1343
1433
  .map((row) => ({
1344
1434
  ...row,
1345
1435
  classification: classificationByPath.get(row.path) ?? "deleted",
@@ -1348,7 +1438,7 @@ async function buildFilesCheck(items, workspaceRoot, pmRoot, fileScanMode, inclu
1348
1438
  left.path.localeCompare(right.path) ||
1349
1439
  left.link_kind.localeCompare(right.link_kind));
1350
1440
  const warnings = [];
1351
- if (strictModeForcesPmInternals) {
1441
+ if (partition.strictModeForcesPmInternals) {
1352
1442
  warnings.push("validate_files_tracked_all_strict_forces_pm_internals");
1353
1443
  }
1354
1444
  if (uniqueMissingLinkedPaths.length > 0) {
@@ -1357,7 +1447,7 @@ async function buildFilesCheck(items, workspaceRoot, pmRoot, fileScanMode, inclu
1357
1447
  if (orphanedFiles.length > 0) {
1358
1448
  warnings.push(`validate_files_orphaned_paths:${orphanedFiles.length}`);
1359
1449
  }
1360
- const uniqueRemoteLinkedPaths = [...remoteLinkedPaths].sort((left, right) => left.localeCompare(right));
1450
+ const uniqueRemoteLinkedPaths = [...linkedPathState.remoteLinkedPaths].sort((left, right) => left.localeCompare(right));
1361
1451
  const summarizedRemote = summarizeFileList(uniqueRemoteLinkedPaths, verboseFileLists);
1362
1452
  const summarizedMissing = summarizeFileList(uniqueMissingLinkedPaths, verboseFileLists);
1363
1453
  const summarizedOrphaned = summarizeFileList(orphanedFiles, verboseFileLists);
@@ -1394,30 +1484,30 @@ async function buildFilesCheck(items, workspaceRoot, pmRoot, fileScanMode, inclu
1394
1484
  workspace_root: workspaceRoot,
1395
1485
  scan_mode_requested: fileCandidates.requestedMode,
1396
1486
  scan_mode_applied: fileCandidates.appliedMode,
1397
- strict_tracked_all_mode: strictTrackedAllMode,
1398
- strict_mode_forces_pm_internals: strictModeForcesPmInternals,
1399
- strict_mode_forces_pm_internals_notice: strictModeForcesPmInternals
1487
+ strict_tracked_all_mode: partition.strictTrackedAllMode,
1488
+ strict_mode_forces_pm_internals: partition.strictModeForcesPmInternals,
1489
+ strict_mode_forces_pm_internals_notice: partition.strictModeForcesPmInternals
1400
1490
  ? "tracked-all-strict force-enables PM internals; pass --include-pm-internals to make inclusion explicit."
1401
1491
  : null,
1402
1492
  file_list_detail_mode: verboseFileLists ? "full" : "summary",
1403
1493
  file_list_summary_limit: FILE_LIST_SUMMARY_LIMIT,
1404
1494
  candidate_scan_source: fileCandidates.source,
1405
- include_pm_internals: includePmInternalsEffective,
1495
+ include_pm_internals: partition.includePmInternalsEffective,
1406
1496
  include_pm_internals_requested: includePmInternals,
1407
- pm_internal_candidate_prefixes: pmInternalCandidatePrefixes,
1408
- pm_internal_excluded_count: excludedPmInternalCount,
1409
- excluded_total: excludedPmInternalCount,
1410
- excluded_by_reason: excludedByReason,
1411
- linked_project_paths: linkedProjectPaths.size,
1497
+ pm_internal_candidate_prefixes: partition.pmInternalCandidatePrefixes,
1498
+ pm_internal_excluded_count: partition.excludedPmInternalPaths.length,
1499
+ excluded_total: partition.excludedPmInternalPaths.length,
1500
+ excluded_by_reason: partition.excludedByReason,
1501
+ linked_project_paths: linkedPathState.linkedProjectPaths.size,
1412
1502
  remote_linked_paths_count: uniqueRemoteLinkedPaths.length,
1413
1503
  remote_linked_paths_total: summarizedRemote.total,
1414
1504
  remote_linked_paths: summarizedRemote.values,
1415
1505
  remote_linked_paths_truncated: summarizedRemote.truncated,
1416
1506
  candidate_total_raw: fileCandidates.candidateTotal,
1417
1507
  candidate_scanned_raw: fileCandidates.candidateScanned,
1418
- candidate_total: candidateFiles.length,
1419
- candidate_scanned: candidateFiles.length,
1420
- scanned_candidate_files: candidateFiles.length,
1508
+ candidate_total: partition.candidateFiles.length,
1509
+ candidate_scanned: partition.candidateFiles.length,
1510
+ scanned_candidate_files: partition.candidateFiles.length,
1421
1511
  missing_linked_paths_count: uniqueMissingLinkedPaths.length,
1422
1512
  missing_linked_paths_total: summarizedMissing.total,
1423
1513
  missing_linked_paths: summarizedMissing.values,
@@ -1692,10 +1782,14 @@ export const _testOnlyValidateCommand = {
1692
1782
  applyValidateFixes,
1693
1783
  attachValidateFixHints,
1694
1784
  buildCommandReferencesCheck,
1785
+ buildCloseReasonBackfillRows,
1695
1786
  buildFilesCheck,
1696
1787
  buildLifecycleCheck,
1697
1788
  buildLifecycleDependencyGraph,
1698
1789
  buildLifecycleParentGraph,
1790
+ buildEstimateBackfillRows,
1791
+ buildMetadataCounts,
1792
+ buildMissingFieldOccurrences,
1699
1793
  buildOrphanedPathRows,
1700
1794
  classifyOrphanedPath,
1701
1795
  collectDefaultProjectFileCandidates,
@@ -1719,6 +1813,107 @@ export const _testOnlyValidateCommand = {
1719
1813
  summarizeDuplicateIssueCodes,
1720
1814
  toMeaningfulString,
1721
1815
  };
1816
+ function recordValidateCheck(state, built, fixHintsEnabled) {
1817
+ if (fixHintsEnabled) {
1818
+ attachValidateFixHints(built.check, built.warnings);
1819
+ }
1820
+ state.checks.push(built.check);
1821
+ state.warnings.push(...built.warnings);
1822
+ }
1823
+ async function executeRequestedValidateChecks(params) {
1824
+ const state = {
1825
+ checks: [],
1826
+ warnings: [...params.initialWarnings],
1827
+ closeReasonBackfillRows: [],
1828
+ estimateBackfillRows: [],
1829
+ resolutionBackfillRows: [],
1830
+ terminalParentFixRows: [],
1831
+ staleLinkPruneRows: [],
1832
+ };
1833
+ const fixHintsEnabled = params.options.fixHints === true;
1834
+ const fullDiagnostics = params.options.verboseDiagnostics === true || params.options.allAffectedIds === true || params.global.json === true;
1835
+ if (params.requestedChecks.has("metadata")) {
1836
+ const built = buildMetadataCheck(params.items, params.metadataPolicy, params.statusRegistry, fullDiagnostics);
1837
+ state.closeReasonBackfillRows = built.closeReasonBackfillRows;
1838
+ state.estimateBackfillRows = built.estimateBackfillRows;
1839
+ recordValidateCheck(state, built, fixHintsEnabled);
1840
+ }
1841
+ if (params.requestedChecks.has("resolution")) {
1842
+ const built = buildResolutionCheck(params.items, params.statusRegistry, fullDiagnostics);
1843
+ state.resolutionBackfillRows = built.resolutionBackfillRows;
1844
+ recordValidateCheck(state, built, fixHintsEnabled);
1845
+ }
1846
+ if (params.requestedChecks.has("lifecycle")) {
1847
+ const built = buildLifecycleCheck(params.items, Boolean(params.options.checkStaleBlockers), params.dependencyCycleSeverity, params.parentCycleSeverity, params.statusRegistry, params.lifecyclePatternPolicy, fullDiagnostics, params.settings.id_prefix);
1848
+ state.terminalParentFixRows = built.terminalParentFixRows;
1849
+ recordValidateCheck(state, built, fixHintsEnabled);
1850
+ }
1851
+ if (params.requestedChecks.has("files")) {
1852
+ const built = await buildFilesCheck(params.items, params.workspaceRoot, params.pmRoot, params.fileScanMode, Boolean(params.options.includePmInternals), Boolean(params.options.verboseFileLists));
1853
+ state.staleLinkPruneRows = built.staleLinkPruneRows;
1854
+ recordValidateCheck(state, built, fixHintsEnabled);
1855
+ }
1856
+ if (params.requestedChecks.has("command_references")) {
1857
+ recordValidateCheck(state, buildCommandReferencesCheck(params.items, params.settings.id_prefix, fullDiagnostics), fixHintsEnabled);
1858
+ }
1859
+ if (params.requestedChecks.has("history_drift")) {
1860
+ recordValidateCheck(state, await buildHistoryDriftCheck(params.pmRoot, params.items, fullDiagnostics), fixHintsEnabled);
1861
+ }
1862
+ if (params.requestedChecks.has("format_version")) {
1863
+ recordValidateCheck(state, buildFormatVersionCheck(params.items, fullDiagnostics), fixHintsEnabled);
1864
+ }
1865
+ return state;
1866
+ }
1867
+ function planValidateFixes(options, state, settings) {
1868
+ const planned = [];
1869
+ if (options.autoFix === true) {
1870
+ planned.push(...planCloseReasonBackfillFixes(state.closeReasonBackfillRows));
1871
+ planned.push(...planResolutionBackfillFixes(state.resolutionBackfillRows));
1872
+ planned.push(...planEstimateBackfillFixes(state.estimateBackfillRows, settings.validation.estimate_defaults_by_type));
1873
+ planned.push(...planTerminalParentFixes(state.terminalParentFixRows));
1874
+ }
1875
+ if (options.pruneMissing === true) {
1876
+ planned.push(...planStaleLinkPruneFixes(state.staleLinkPruneRows));
1877
+ }
1878
+ return planned;
1879
+ }
1880
+ /* v8 ignore start -- validate fix-summary matrix is covered end-to-end; direct helper fallback branches are defensive */
1881
+ async function buildValidateFixesSummary(options, state, settings, grantedFixScopes, global) {
1882
+ if (options.autoFix !== true && options.pruneMissing !== true) {
1883
+ return undefined;
1884
+ }
1885
+ const planned = planValidateFixes(options, state, settings);
1886
+ const { applicable, gated } = partitionFixesByGrant(planned, grantedFixScopes);
1887
+ const dryRun = options.dryRun === true;
1888
+ const appliedFixRows = [];
1889
+ const failedFixRows = [];
1890
+ if (!dryRun) {
1891
+ const applied = await applyValidateFixes(applicable, global);
1892
+ appliedFixRows.push(...applied.applied.map(toFixOutputRow));
1893
+ failedFixRows.push(...applied.failed.map(({ fix, error }) => ({
1894
+ ...toFixOutputRow(fix),
1895
+ error: error instanceof Error ? error.message : String(error),
1896
+ })));
1897
+ }
1898
+ return {
1899
+ mode: dryRun ? "dry_run" : "apply",
1900
+ auto_fix: options.autoFix === true,
1901
+ prune_missing: options.pruneMissing === true,
1902
+ granted_fix_scopes: [...grantedFixScopes].sort((left, right) => left.localeCompare(right)),
1903
+ planned_count: planned.length,
1904
+ applied_count: appliedFixRows.length,
1905
+ gated_count: gated.length,
1906
+ failed_count: failedFixRows.length,
1907
+ planned_fixes: planned.map(toFixOutputRow),
1908
+ applied_fixes: appliedFixRows,
1909
+ gated_fixes: gated.map((fix) => ({
1910
+ ...toFixOutputRow(fix),
1911
+ gate_hint: `Withheld: re-run with --fix-scope ${fix.gate} to apply.`,
1912
+ })),
1913
+ failed_fixes: failedFixRows,
1914
+ };
1915
+ }
1916
+ /* v8 ignore stop */
1722
1917
  /* c8 ignore start -- validate orchestration + fix-application matrices are covered by end-to-end command integration runs */
1723
1918
  /**
1724
1919
  * Implements run validate for the public runtime surface of this module.
@@ -1751,108 +1946,36 @@ export async function runValidate(options, global) {
1751
1946
  const parentCycleSeverity = resolveParentCycleSeverity(options.parentCycleSeverity);
1752
1947
  const fileScanMode = resolveFileScanMode(options.scanMode);
1753
1948
  const workspaceRoot = resolveWorkspaceRoot(pmRoot);
1754
- const checks = [];
1755
- const warnings = [...new Set(itemReadWarnings)];
1756
- const fixHintsEnabled = options.fixHints === true;
1757
- // Full (un-truncated) diagnostic ID lists when the agent asks for them
1758
- // (--verbose-diagnostics/--all-affected-ids) or whenever output is JSON:
1759
- // machine consumers expect complete *_item_ids arrays, never a 5-item cap.
1760
- const fullDiagnostics = options.verboseDiagnostics === true || options.allAffectedIds === true || global.json === true;
1761
- const record = (built) => {
1762
- if (fixHintsEnabled) {
1763
- attachValidateFixHints(built.check, built.warnings);
1764
- }
1765
- checks.push(built.check);
1766
- warnings.push(...built.warnings);
1767
- };
1768
- let closeReasonBackfillRows = [];
1769
- let estimateBackfillRows = [];
1770
- let resolutionBackfillRows = [];
1771
- let terminalParentFixRows = [];
1772
- let staleLinkPruneRows = [];
1773
- if (requestedChecks.has("metadata")) {
1774
- const built = buildMetadataCheck(items, metadataPolicy, statusRegistry, fullDiagnostics);
1775
- closeReasonBackfillRows = built.closeReasonBackfillRows;
1776
- estimateBackfillRows = built.estimateBackfillRows;
1777
- record(built);
1778
- }
1779
- if (requestedChecks.has("resolution")) {
1780
- const built = buildResolutionCheck(items, statusRegistry, fullDiagnostics);
1781
- resolutionBackfillRows = built.resolutionBackfillRows;
1782
- record(built);
1783
- }
1784
- if (requestedChecks.has("lifecycle")) {
1785
- const built = buildLifecycleCheck(items, Boolean(options.checkStaleBlockers), dependencyCycleSeverity, parentCycleSeverity, statusRegistry, lifecyclePatternPolicy, fullDiagnostics, settings.id_prefix);
1786
- terminalParentFixRows = built.terminalParentFixRows;
1787
- record(built);
1788
- }
1789
- if (requestedChecks.has("files")) {
1790
- const built = await buildFilesCheck(items, workspaceRoot, pmRoot, fileScanMode, Boolean(options.includePmInternals), Boolean(options.verboseFileLists));
1791
- staleLinkPruneRows = built.staleLinkPruneRows;
1792
- record(built);
1793
- }
1794
- if (requestedChecks.has("command_references")) {
1795
- record(buildCommandReferencesCheck(items, settings.id_prefix, fullDiagnostics));
1796
- }
1797
- if (requestedChecks.has("history_drift")) {
1798
- record(await buildHistoryDriftCheck(pmRoot, items, fullDiagnostics));
1799
- }
1800
- if (requestedChecks.has("format_version")) {
1801
- record(buildFormatVersionCheck(items, fullDiagnostics));
1802
- }
1949
+ const state = await executeRequestedValidateChecks({
1950
+ requestedChecks,
1951
+ options,
1952
+ global,
1953
+ pmRoot,
1954
+ workspaceRoot,
1955
+ settings,
1956
+ items,
1957
+ statusRegistry,
1958
+ metadataPolicy,
1959
+ lifecyclePatternPolicy,
1960
+ dependencyCycleSeverity,
1961
+ parentCycleSeverity,
1962
+ fileScanMode,
1963
+ initialWarnings: [...new Set(itemReadWarnings)],
1964
+ });
1803
1965
  // Remediation phase (pm-c3sz / pm-8jss / pm-0v2m). Plans are derived from
1804
1966
  // the findings of THIS run; checks above always report the pre-fix state.
1805
1967
  // Safe field backfills apply by default under --auto-fix; gated lifecycle
1806
1968
  // fixes are planned but withheld unless --fix-scope lifecycle grants them;
1807
1969
  // --dry-run previews without mutating; failures never abort the run.
1808
- let fixes;
1809
- if (fixesRequested) {
1810
- const planned = [];
1811
- if (options.autoFix === true) {
1812
- planned.push(...planCloseReasonBackfillFixes(closeReasonBackfillRows));
1813
- planned.push(...planResolutionBackfillFixes(resolutionBackfillRows));
1814
- planned.push(...planEstimateBackfillFixes(estimateBackfillRows, settings.validation.estimate_defaults_by_type));
1815
- planned.push(...planTerminalParentFixes(terminalParentFixRows));
1816
- }
1817
- if (options.pruneMissing === true) {
1818
- planned.push(...planStaleLinkPruneFixes(staleLinkPruneRows));
1819
- }
1820
- const { applicable, gated } = partitionFixesByGrant(planned, grantedFixScopes);
1821
- const dryRun = options.dryRun === true;
1822
- const appliedFixRows = [];
1823
- const failedFixRows = [];
1824
- if (!dryRun) {
1825
- const applied = await applyValidateFixes(applicable, global);
1826
- appliedFixRows.push(...applied.applied.map(toFixOutputRow));
1827
- failedFixRows.push(...applied.failed.map(({ fix, error }) => ({
1828
- ...toFixOutputRow(fix),
1829
- error: error instanceof Error ? error.message : String(error),
1830
- })));
1831
- }
1832
- fixes = {
1833
- mode: dryRun ? "dry_run" : "apply",
1834
- auto_fix: options.autoFix === true,
1835
- prune_missing: options.pruneMissing === true,
1836
- granted_fix_scopes: [...grantedFixScopes].sort((left, right) => left.localeCompare(right)),
1837
- planned_count: planned.length,
1838
- applied_count: appliedFixRows.length,
1839
- gated_count: gated.length,
1840
- failed_count: failedFixRows.length,
1841
- planned_fixes: planned.map(toFixOutputRow),
1842
- applied_fixes: appliedFixRows,
1843
- gated_fixes: gated.map((fix) => ({
1844
- ...toFixOutputRow(fix),
1845
- gate_hint: `Withheld: re-run with --fix-scope ${fix.gate} to apply.`,
1846
- })),
1847
- failed_fixes: failedFixRows,
1848
- };
1849
- }
1850
- const normalizedWarnings = [...new Set(warnings)].sort((left, right) => left.localeCompare(right));
1851
- const hasErrors = checks.some((check) => check.status === "error");
1970
+ const fixes = fixesRequested
1971
+ ? await buildValidateFixesSummary(options, state, settings, grantedFixScopes, global)
1972
+ : undefined;
1973
+ const normalizedWarnings = [...new Set(state.warnings)].sort((left, right) => left.localeCompare(right));
1974
+ const hasErrors = state.checks.some((check) => check.status === "error");
1852
1975
  return {
1853
1976
  ok: !hasErrors,
1854
1977
  has_warnings: normalizedWarnings.length > 0,
1855
- checks,
1978
+ checks: state.checks,
1856
1979
  warnings: normalizedWarnings,
1857
1980
  ...(fixes !== undefined ? { fixes } : {}),
1858
1981
  generated_at: nowIso(),
@@ -1860,4 +1983,4 @@ export async function runValidate(options, global) {
1860
1983
  }
1861
1984
  /* c8 ignore stop */
1862
1985
  //# sourceMappingURL=validate.js.map
1863
- //# debugId=a9087567-b334-5e9c-8ed7-e52d8cb35801
1986
+ //# debugId=96011574-703c-57e6-979f-dbae265fd01b