@shrkcrft/cli 0.1.0-alpha.29 → 0.1.0-alpha.31

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 (510) hide show
  1. package/dist/asset-preview/apply-asset-preview.js +1 -1
  2. package/dist/authoring/authoring-kit.d.ts +9 -1
  3. package/dist/authoring/authoring-kit.d.ts.map +1 -1
  4. package/dist/authoring/authoring-kit.js +26 -13
  5. package/dist/bootstrap/unlinked-workspace-dependency.d.ts +11 -0
  6. package/dist/bootstrap/unlinked-workspace-dependency.d.ts.map +1 -0
  7. package/dist/bootstrap/unlinked-workspace-dependency.js +99 -0
  8. package/dist/command-registry.d.ts +100 -1
  9. package/dist/command-registry.d.ts.map +1 -1
  10. package/dist/command-registry.js +130 -3
  11. package/dist/commands/api-diff.command.d.ts.map +1 -1
  12. package/dist/commands/api-diff.command.js +12 -0
  13. package/dist/commands/apply.command.d.ts.map +1 -1
  14. package/dist/commands/apply.command.js +3 -0
  15. package/dist/commands/arch.command.d.ts.map +1 -1
  16. package/dist/commands/arch.command.js +26 -7
  17. package/dist/commands/architecture.command.d.ts.map +1 -1
  18. package/dist/commands/architecture.command.js +8 -2
  19. package/dist/commands/baseline.command.d.ts +76 -0
  20. package/dist/commands/baseline.command.d.ts.map +1 -1
  21. package/dist/commands/baseline.command.js +599 -75
  22. package/dist/commands/biome.command.d.ts.map +1 -1
  23. package/dist/commands/biome.command.js +20 -0
  24. package/dist/commands/boundaries.command.d.ts +9 -1
  25. package/dist/commands/boundaries.command.d.ts.map +1 -1
  26. package/dist/commands/boundaries.command.js +88 -20
  27. package/dist/commands/bundle.command.d.ts.map +1 -1
  28. package/dist/commands/bundle.command.js +57 -11
  29. package/dist/commands/cache-align.command.d.ts.map +1 -1
  30. package/dist/commands/cache-align.command.js +3 -1
  31. package/dist/commands/changelog-data.d.ts.map +1 -1
  32. package/dist/commands/changelog-data.js +164 -0
  33. package/dist/commands/changes.command.d.ts.map +1 -1
  34. package/dist/commands/changes.command.js +15 -0
  35. package/dist/commands/check.command.d.ts.map +1 -1
  36. package/dist/commands/check.command.js +1260 -324
  37. package/dist/commands/checks.command.d.ts.map +1 -1
  38. package/dist/commands/checks.command.js +188 -40
  39. package/dist/commands/ci.command.d.ts.map +1 -1
  40. package/dist/commands/ci.command.js +35 -2
  41. package/dist/commands/code-intel.command.d.ts.map +1 -1
  42. package/dist/commands/code-intel.command.js +8 -1
  43. package/dist/commands/command-catalog.d.ts +23 -1
  44. package/dist/commands/command-catalog.d.ts.map +1 -1
  45. package/dist/commands/command-catalog.js +152 -35
  46. package/dist/commands/commands.command.d.ts +21 -3
  47. package/dist/commands/commands.command.d.ts.map +1 -1
  48. package/dist/commands/commands.command.js +172 -27
  49. package/dist/commands/compress.command.d.ts.map +1 -1
  50. package/dist/commands/compress.command.js +4 -0
  51. package/dist/commands/constructs.command.d.ts.map +1 -1
  52. package/dist/commands/constructs.command.js +50 -12
  53. package/dist/commands/context.command.d.ts.map +1 -1
  54. package/dist/commands/context.command.js +40 -5
  55. package/dist/commands/contract-templates.command.d.ts.map +1 -1
  56. package/dist/commands/contract-templates.command.js +9 -1
  57. package/dist/commands/contract.command.d.ts.map +1 -1
  58. package/dist/commands/contract.command.js +35 -0
  59. package/dist/commands/conventions.command.d.ts.map +1 -1
  60. package/dist/commands/conventions.command.js +189 -29
  61. package/dist/commands/coverage.command.d.ts.map +1 -1
  62. package/dist/commands/coverage.command.js +9 -0
  63. package/dist/commands/daily.commands.d.ts +0 -1
  64. package/dist/commands/daily.commands.d.ts.map +1 -1
  65. package/dist/commands/daily.commands.js +12 -76
  66. package/dist/commands/dashboard.command.d.ts.map +1 -1
  67. package/dist/commands/dashboard.command.js +10 -0
  68. package/dist/commands/dev.command.d.ts.map +1 -1
  69. package/dist/commands/dev.command.js +45 -2
  70. package/dist/commands/diagnostics.command.d.ts +0 -2
  71. package/dist/commands/diagnostics.command.d.ts.map +1 -1
  72. package/dist/commands/diagnostics.command.js +5 -78
  73. package/dist/commands/diff-check.command.d.ts +6 -4
  74. package/dist/commands/diff-check.command.d.ts.map +1 -1
  75. package/dist/commands/diff-check.command.js +190 -103
  76. package/dist/commands/docs-references.command.d.ts +20 -0
  77. package/dist/commands/docs-references.command.d.ts.map +1 -0
  78. package/dist/commands/docs-references.command.js +520 -0
  79. package/dist/commands/doctor.command.d.ts.map +1 -1
  80. package/dist/commands/doctor.command.js +60 -5
  81. package/dist/commands/drift.command.d.ts.map +1 -1
  82. package/dist/commands/drift.command.js +17 -4
  83. package/dist/commands/eslint.command.d.ts.map +1 -1
  84. package/dist/commands/eslint.command.js +20 -0
  85. package/dist/commands/export.command.d.ts.map +1 -1
  86. package/dist/commands/export.command.js +23 -1
  87. package/dist/commands/feedback-dispatch.command.d.ts.map +1 -1
  88. package/dist/commands/feedback-dispatch.command.js +29 -0
  89. package/dist/commands/feedback.command.d.ts.map +1 -1
  90. package/dist/commands/feedback.command.js +6 -1
  91. package/dist/commands/finish.command.d.ts.map +1 -1
  92. package/dist/commands/finish.command.js +32 -8
  93. package/dist/commands/fix.command.d.ts.map +1 -1
  94. package/dist/commands/fix.command.js +19 -0
  95. package/dist/commands/gate.command.d.ts +6 -1
  96. package/dist/commands/gate.command.d.ts.map +1 -1
  97. package/dist/commands/gate.command.js +50 -124
  98. package/dist/commands/gates.command.d.ts +54 -0
  99. package/dist/commands/gates.command.d.ts.map +1 -1
  100. package/dist/commands/gates.command.js +1314 -64
  101. package/dist/commands/gen.command.d.ts.map +1 -1
  102. package/dist/commands/gen.command.js +4 -0
  103. package/dist/commands/generated.command.d.ts +62 -0
  104. package/dist/commands/generated.command.d.ts.map +1 -1
  105. package/dist/commands/generated.command.js +639 -156
  106. package/dist/commands/graph-code-subverbs.d.ts +15 -0
  107. package/dist/commands/graph-code-subverbs.d.ts.map +1 -1
  108. package/dist/commands/graph-code-subverbs.js +203 -25
  109. package/dist/commands/graph.command.d.ts.map +1 -1
  110. package/dist/commands/graph.command.js +79 -37
  111. package/dist/commands/help.command.d.ts +30 -6
  112. package/dist/commands/help.command.d.ts.map +1 -1
  113. package/dist/commands/help.command.js +323 -199
  114. package/dist/commands/helper.command.d.ts +1 -0
  115. package/dist/commands/helper.command.d.ts.map +1 -1
  116. package/dist/commands/helper.command.js +195 -56
  117. package/dist/commands/impact.command.d.ts.map +1 -1
  118. package/dist/commands/impact.command.js +115 -12
  119. package/dist/commands/infer.command.d.ts.map +1 -1
  120. package/dist/commands/infer.command.js +20 -45
  121. package/dist/commands/ingest.command.d.ts +0 -1
  122. package/dist/commands/ingest.command.d.ts.map +1 -1
  123. package/dist/commands/ingest.command.js +25 -41
  124. package/dist/commands/knowledge-author.command.d.ts +0 -3
  125. package/dist/commands/knowledge-author.command.d.ts.map +1 -1
  126. package/dist/commands/knowledge-author.command.js +10 -23
  127. package/dist/commands/knowledge.command.d.ts.map +1 -1
  128. package/dist/commands/knowledge.command.js +469 -129
  129. package/dist/commands/languages.command.d.ts.map +1 -1
  130. package/dist/commands/languages.command.js +27 -0
  131. package/dist/commands/lint.command.d.ts.map +1 -1
  132. package/dist/commands/lint.command.js +3 -0
  133. package/dist/commands/mcp.command.d.ts +18 -0
  134. package/dist/commands/mcp.command.d.ts.map +1 -1
  135. package/dist/commands/mcp.command.js +33 -8
  136. package/dist/commands/onboard.command.d.ts.map +1 -1
  137. package/dist/commands/onboard.command.js +20 -0
  138. package/dist/commands/owners.command.d.ts.map +1 -1
  139. package/dist/commands/owners.command.js +14 -2
  140. package/dist/commands/packs-new.d.ts +13 -1
  141. package/dist/commands/packs-new.d.ts.map +1 -1
  142. package/dist/commands/packs-new.js +500 -335
  143. package/dist/commands/packs.command.d.ts.map +1 -1
  144. package/dist/commands/packs.command.js +378 -36
  145. package/dist/commands/paths.command.d.ts.map +1 -1
  146. package/dist/commands/paths.command.js +9 -1
  147. package/dist/commands/pipelines.command.d.ts.map +1 -1
  148. package/dist/commands/pipelines.command.js +7 -1
  149. package/dist/commands/plan-check.command.d.ts.map +1 -1
  150. package/dist/commands/plan-check.command.js +3 -0
  151. package/dist/commands/plan.command.d.ts.map +1 -1
  152. package/dist/commands/plan.command.js +3 -0
  153. package/dist/commands/playbooks.command.d.ts.map +1 -1
  154. package/dist/commands/playbooks.command.js +7 -2
  155. package/dist/commands/policy-lint.command.d.ts +19 -2
  156. package/dist/commands/policy-lint.command.d.ts.map +1 -1
  157. package/dist/commands/policy-lint.command.js +224 -65
  158. package/dist/commands/policy.command.d.ts.map +1 -1
  159. package/dist/commands/policy.command.js +6 -1
  160. package/dist/commands/pr.command.d.ts.map +1 -1
  161. package/dist/commands/pr.command.js +14 -0
  162. package/dist/commands/presets.command.d.ts.map +1 -1
  163. package/dist/commands/presets.command.js +12 -27
  164. package/dist/commands/profiles.command.d.ts.map +1 -1
  165. package/dist/commands/profiles.command.js +94 -26
  166. package/dist/commands/provenance.command.js +1 -1
  167. package/dist/commands/quality.command.d.ts.map +1 -1
  168. package/dist/commands/quality.command.js +129 -33
  169. package/dist/commands/recommend.command.d.ts +20 -4
  170. package/dist/commands/recommend.command.d.ts.map +1 -1
  171. package/dist/commands/recommend.command.js +172 -278
  172. package/dist/commands/registrations.command.d.ts.map +1 -1
  173. package/dist/commands/registrations.command.js +138 -13
  174. package/dist/commands/registry-lifecycle-run.d.ts +14 -0
  175. package/dist/commands/registry-lifecycle-run.d.ts.map +1 -0
  176. package/dist/commands/registry-lifecycle-run.js +336 -0
  177. package/dist/commands/registry.command.d.ts.map +1 -1
  178. package/dist/commands/registry.command.js +235 -62
  179. package/dist/commands/release.command.d.ts.map +1 -1
  180. package/dist/commands/release.command.js +99 -20
  181. package/dist/commands/report.command.d.ts.map +1 -1
  182. package/dist/commands/report.command.js +38 -2
  183. package/dist/commands/reuse-coverage.command.d.ts +23 -0
  184. package/dist/commands/reuse-coverage.command.d.ts.map +1 -0
  185. package/dist/commands/reuse-coverage.command.js +536 -0
  186. package/dist/commands/reuse.command.d.ts +3 -18
  187. package/dist/commands/reuse.command.d.ts.map +1 -1
  188. package/dist/commands/reuse.command.js +395 -244
  189. package/dist/commands/review.command.d.ts.map +1 -1
  190. package/dist/commands/review.command.js +33 -1
  191. package/dist/commands/rounds.command.d.ts.map +1 -1
  192. package/dist/commands/rounds.command.js +5 -0
  193. package/dist/commands/safety.command.d.ts.map +1 -1
  194. package/dist/commands/safety.command.js +9 -0
  195. package/dist/commands/scaffolds.command.d.ts.map +1 -1
  196. package/dist/commands/scaffolds.command.js +97 -25
  197. package/dist/commands/search.command.d.ts +0 -8
  198. package/dist/commands/search.command.d.ts.map +1 -1
  199. package/dist/commands/search.command.js +136 -28
  200. package/dist/commands/self-config-xrefs.command.d.ts +24 -0
  201. package/dist/commands/self-config-xrefs.command.d.ts.map +1 -0
  202. package/dist/commands/self-config-xrefs.command.js +170 -0
  203. package/dist/commands/self-config.command.d.ts.map +1 -1
  204. package/dist/commands/self-config.command.js +261 -65
  205. package/dist/commands/smart-context.command.d.ts.map +1 -1
  206. package/dist/commands/smart-context.command.js +39 -3
  207. package/dist/commands/spec.command.d.ts.map +1 -1
  208. package/dist/commands/spec.command.js +3 -0
  209. package/dist/commands/stats.command.d.ts.map +1 -1
  210. package/dist/commands/stats.command.js +3 -0
  211. package/dist/commands/surface.command.d.ts +6 -1
  212. package/dist/commands/surface.command.d.ts.map +1 -1
  213. package/dist/commands/surface.command.js +256 -54
  214. package/dist/commands/task-context.command.js +1 -1
  215. package/dist/commands/task.command.d.ts.map +1 -1
  216. package/dist/commands/task.command.js +22 -1
  217. package/dist/commands/templates.command.d.ts +4 -0
  218. package/dist/commands/templates.command.d.ts.map +1 -1
  219. package/dist/commands/templates.command.js +109 -22
  220. package/dist/commands/test.command.d.ts.map +1 -1
  221. package/dist/commands/test.command.js +161 -33
  222. package/dist/commands/tests.command.d.ts.map +1 -1
  223. package/dist/commands/tests.command.js +29 -3
  224. package/dist/commands/trace.command.d.ts.map +1 -1
  225. package/dist/commands/trace.command.js +29 -4
  226. package/dist/commands/watch.command.d.ts.map +1 -1
  227. package/dist/commands/watch.command.js +3 -0
  228. package/dist/commands/why.command.d.ts.map +1 -1
  229. package/dist/commands/why.command.js +3 -0
  230. package/dist/commands/wiring.command.d.ts +18 -4
  231. package/dist/commands/wiring.command.d.ts.map +1 -1
  232. package/dist/commands/wiring.command.js +362 -74
  233. package/dist/dashboard/code-intelligence-data.js +4 -4
  234. package/dist/diff/deleted-orphan-coverage.d.ts +32 -0
  235. package/dist/diff/deleted-orphan-coverage.d.ts.map +1 -0
  236. package/dist/diff/deleted-orphan-coverage.js +107 -0
  237. package/dist/diff/deleted-orphan-scope-notes.d.ts +23 -0
  238. package/dist/diff/deleted-orphan-scope-notes.d.ts.map +1 -0
  239. package/dist/diff/deleted-orphan-scope-notes.js +49 -0
  240. package/dist/diff/deleted-orphans.d.ts +32 -0
  241. package/dist/diff/deleted-orphans.d.ts.map +1 -1
  242. package/dist/diff/deleted-orphans.js +42 -2
  243. package/dist/dispatch/closest-match.d.ts +15 -0
  244. package/dist/dispatch/closest-match.d.ts.map +1 -0
  245. package/dist/dispatch/closest-match.js +47 -0
  246. package/dist/dispatch/global-flags.d.ts +94 -0
  247. package/dist/dispatch/global-flags.d.ts.map +1 -0
  248. package/dist/dispatch/global-flags.js +123 -0
  249. package/dist/dispatch/guard-invocation-input.d.ts +24 -0
  250. package/dist/dispatch/guard-invocation-input.d.ts.map +1 -0
  251. package/dist/dispatch/guard-invocation-input.js +1 -0
  252. package/dist/dispatch/guard-invocation.d.ts +33 -0
  253. package/dist/dispatch/guard-invocation.d.ts.map +1 -0
  254. package/dist/dispatch/guard-invocation.js +183 -0
  255. package/dist/dispatch/help-intercept.d.ts +22 -0
  256. package/dist/dispatch/help-intercept.d.ts.map +1 -0
  257. package/dist/dispatch/help-intercept.js +42 -0
  258. package/dist/dispatch/i-declared-invocation.d.ts +17 -0
  259. package/dist/dispatch/i-declared-invocation.d.ts.map +1 -0
  260. package/dist/dispatch/i-declared-invocation.js +1 -0
  261. package/dist/dispatch/i-unknown-flag-refusal-input.d.ts +28 -0
  262. package/dist/dispatch/i-unknown-flag-refusal-input.d.ts.map +1 -0
  263. package/dist/dispatch/i-unknown-flag-refusal-input.js +1 -0
  264. package/dist/dispatch/invocation-rejection-kind.d.ts +15 -0
  265. package/dist/dispatch/invocation-rejection-kind.d.ts.map +1 -0
  266. package/dist/dispatch/invocation-rejection-kind.js +15 -0
  267. package/dist/dispatch/invocation-rejection.d.ts +18 -0
  268. package/dist/dispatch/invocation-rejection.d.ts.map +1 -0
  269. package/dist/dispatch/invocation-rejection.js +1 -0
  270. package/dist/dispatch/judge-invocation.d.ts +24 -0
  271. package/dist/dispatch/judge-invocation.d.ts.map +1 -0
  272. package/dist/dispatch/judge-invocation.js +50 -0
  273. package/dist/dispatch/positional-mode.d.ts +18 -0
  274. package/dist/dispatch/positional-mode.d.ts.map +1 -0
  275. package/dist/dispatch/positional-mode.js +18 -0
  276. package/dist/dispatch/read-tracking-map.d.ts +28 -0
  277. package/dist/dispatch/read-tracking-map.d.ts.map +1 -0
  278. package/dist/dispatch/read-tracking-map.js +58 -0
  279. package/dist/dispatch/refuse-sibling-valve-flags.d.ts +30 -0
  280. package/dist/dispatch/refuse-sibling-valve-flags.d.ts.map +1 -0
  281. package/dist/dispatch/refuse-sibling-valve-flags.js +65 -0
  282. package/dist/dispatch/subverb-spec.d.ts +26 -0
  283. package/dist/dispatch/subverb-spec.d.ts.map +1 -0
  284. package/dist/dispatch/subverb-spec.js +1 -0
  285. package/dist/dispatch/undocumented-flag-reads.d.ts +22 -0
  286. package/dist/dispatch/undocumented-flag-reads.d.ts.map +1 -0
  287. package/dist/dispatch/undocumented-flag-reads.js +283 -0
  288. package/dist/dispatch/unknown-flag-refusal-mode.d.ts +13 -0
  289. package/dist/dispatch/unknown-flag-refusal-mode.d.ts.map +1 -0
  290. package/dist/dispatch/unknown-flag-refusal-mode.js +13 -0
  291. package/dist/dispatch/unknown-flag-refusal.d.ts +22 -0
  292. package/dist/dispatch/unknown-flag-refusal.d.ts.map +1 -0
  293. package/dist/dispatch/unknown-flag-refusal.js +57 -0
  294. package/dist/dispatch/unread-flags.d.ts +152 -0
  295. package/dist/dispatch/unread-flags.d.ts.map +1 -0
  296. package/dist/dispatch/unread-flags.js +295 -0
  297. package/dist/dispatch/verdict-valve-flag.d.ts +21 -0
  298. package/dist/dispatch/verdict-valve-flag.d.ts.map +1 -0
  299. package/dist/dispatch/verdict-valve-flag.js +21 -0
  300. package/dist/dispatch/walk-declared-subverbs.d.ts +14 -0
  301. package/dist/dispatch/walk-declared-subverbs.d.ts.map +1 -0
  302. package/dist/dispatch/walk-declared-subverbs.js +28 -0
  303. package/dist/exit-codes.d.ts +41 -3
  304. package/dist/exit-codes.d.ts.map +1 -1
  305. package/dist/exit-codes.js +153 -14
  306. package/dist/finish/run-finish.d.ts +72 -5
  307. package/dist/finish/run-finish.d.ts.map +1 -1
  308. package/dist/finish/run-finish.js +453 -104
  309. package/dist/gates/accepted-empty-note.d.ts +10 -0
  310. package/dist/gates/accepted-empty-note.d.ts.map +1 -0
  311. package/dist/gates/accepted-empty-note.js +11 -0
  312. package/dist/gates/allow-empty.d.ts +25 -0
  313. package/dist/gates/allow-empty.d.ts.map +1 -0
  314. package/dist/gates/allow-empty.js +27 -0
  315. package/dist/gates/asset-doctor-failing-units.d.ts +16 -0
  316. package/dist/gates/asset-doctor-failing-units.d.ts.map +1 -0
  317. package/dist/gates/asset-doctor-failing-units.js +14 -0
  318. package/dist/gates/asset-doctor-failure-line.d.ts +16 -0
  319. package/dist/gates/asset-doctor-failure-line.d.ts.map +1 -0
  320. package/dist/gates/asset-doctor-failure-line.js +28 -0
  321. package/dist/gates/empty-rule-advice-lines.d.ts +15 -0
  322. package/dist/gates/empty-rule-advice-lines.d.ts.map +1 -0
  323. package/dist/gates/empty-rule-advice-lines.js +20 -0
  324. package/dist/gates/gate-envelope.d.ts +85 -8
  325. package/dist/gates/gate-envelope.d.ts.map +1 -1
  326. package/dist/gates/gate-envelope.js +56 -7
  327. package/dist/gates/gate-rule-globs.d.ts +67 -0
  328. package/dist/gates/gate-rule-globs.d.ts.map +1 -0
  329. package/dist/gates/gate-rule-globs.js +139 -0
  330. package/dist/gates/gate-rule-view.d.ts +25 -6
  331. package/dist/gates/gate-rule-view.d.ts.map +1 -1
  332. package/dist/gates/gate-rule-view.js +105 -77
  333. package/dist/gates/i-coverage-dead-glob.d.ts +19 -0
  334. package/dist/gates/i-coverage-dead-glob.d.ts.map +1 -0
  335. package/dist/gates/i-coverage-dead-glob.js +1 -0
  336. package/dist/gates/i-coverage-negation.d.ts +13 -0
  337. package/dist/gates/i-coverage-negation.d.ts.map +1 -0
  338. package/dist/gates/i-coverage-negation.js +1 -0
  339. package/dist/gates/i-registration-query-settle-input.d.ts +18 -0
  340. package/dist/gates/i-registration-query-settle-input.d.ts.map +1 -0
  341. package/dist/gates/i-registration-query-settle-input.js +1 -0
  342. package/dist/gates/i-unit-state-note-row.d.ts +16 -0
  343. package/dist/gates/i-unit-state-note-row.d.ts.map +1 -0
  344. package/dist/gates/i-unit-state-note-row.js +1 -0
  345. package/dist/gates/i-unit-state-notes.d.ts +32 -0
  346. package/dist/gates/i-unit-state-notes.d.ts.map +1 -0
  347. package/dist/gates/i-unit-state-notes.js +1 -0
  348. package/dist/gates/incomplete-registry-inventory.d.ts +19 -0
  349. package/dist/gates/incomplete-registry-inventory.d.ts.map +1 -0
  350. package/dist/gates/incomplete-registry-inventory.js +63 -0
  351. package/dist/gates/measure-registration-roles.d.ts +10 -0
  352. package/dist/gates/measure-registration-roles.d.ts.map +1 -0
  353. package/dist/gates/measure-registration-roles.js +9 -0
  354. package/dist/gates/plane-verdict.d.ts +14 -0
  355. package/dist/gates/plane-verdict.d.ts.map +1 -0
  356. package/dist/gates/plane-verdict.js +22 -0
  357. package/dist/gates/qualify-clean-for-units.d.ts +12 -0
  358. package/dist/gates/qualify-clean-for-units.d.ts.map +1 -0
  359. package/dist/gates/qualify-clean-for-units.js +18 -0
  360. package/dist/gates/registration-graph-verdict.d.ts +34 -0
  361. package/dist/gates/registration-graph-verdict.d.ts.map +1 -0
  362. package/dist/gates/registration-graph-verdict.js +70 -0
  363. package/dist/gates/registration-roles.d.ts +9 -0
  364. package/dist/gates/registration-roles.d.ts.map +1 -0
  365. package/dist/gates/registration-roles.js +1 -0
  366. package/dist/gates/registry-liveness.d.ts +11 -0
  367. package/dist/gates/registry-liveness.d.ts.map +1 -0
  368. package/dist/gates/registry-liveness.js +13 -0
  369. package/dist/gates/rule-coverage.d.ts +225 -4
  370. package/dist/gates/rule-coverage.d.ts.map +1 -1
  371. package/dist/gates/rule-coverage.js +610 -43
  372. package/dist/gates/run-gate-planes.d.ts +58 -0
  373. package/dist/gates/run-gate-planes.d.ts.map +1 -0
  374. package/dist/gates/run-gate-planes.js +403 -0
  375. package/dist/gates/scaffold-selftest.d.ts +56 -0
  376. package/dist/gates/scaffold-selftest.d.ts.map +1 -0
  377. package/dist/gates/scaffold-selftest.js +119 -0
  378. package/dist/gates/seam-rejected-rules.d.ts +28 -0
  379. package/dist/gates/seam-rejected-rules.d.ts.map +1 -0
  380. package/dist/gates/seam-rejected-rules.js +95 -0
  381. package/dist/gates/self-test-check.d.ts +29 -0
  382. package/dist/gates/self-test-check.d.ts.map +1 -0
  383. package/dist/gates/self-test-check.js +1 -0
  384. package/dist/gates/self-test-subject.d.ts +28 -0
  385. package/dist/gates/self-test-subject.d.ts.map +1 -0
  386. package/dist/gates/self-test-subject.js +1 -0
  387. package/dist/gates/self-test.d.ts +20 -0
  388. package/dist/gates/self-test.d.ts.map +1 -0
  389. package/dist/gates/self-test.js +82 -0
  390. package/dist/gates/settle-verdict.d.ts +14 -0
  391. package/dist/gates/settle-verdict.d.ts.map +1 -0
  392. package/dist/gates/settle-verdict.js +13 -0
  393. package/dist/gates/settled-verdict.d.ts +8 -0
  394. package/dist/gates/settled-verdict.d.ts.map +1 -0
  395. package/dist/gates/settled-verdict.js +1 -0
  396. package/dist/gates/template-registry-coverage.d.ts +18 -0
  397. package/dist/gates/template-registry-coverage.d.ts.map +1 -0
  398. package/dist/gates/template-registry-coverage.js +24 -0
  399. package/dist/gates/unit-state-notes.d.ts +40 -0
  400. package/dist/gates/unit-state-notes.d.ts.map +1 -0
  401. package/dist/gates/unit-state-notes.js +71 -0
  402. package/dist/gates/verdict-line.d.ts +18 -0
  403. package/dist/gates/verdict-line.d.ts.map +1 -0
  404. package/dist/gates/verdict-line.js +40 -0
  405. package/dist/graph/graph-reuse-lookup.d.ts +10 -0
  406. package/dist/graph/graph-reuse-lookup.d.ts.map +1 -0
  407. package/dist/graph/graph-reuse-lookup.js +41 -0
  408. package/dist/graph/index-behind-hint.d.ts +11 -0
  409. package/dist/graph/index-behind-hint.d.ts.map +1 -0
  410. package/dist/graph/index-behind-hint.js +27 -0
  411. package/dist/knowledge/knowledge-stale-gate-flags.d.ts +3 -0
  412. package/dist/knowledge/knowledge-stale-gate-flags.d.ts.map +1 -0
  413. package/dist/knowledge/knowledge-stale-gate-flags.js +1 -0
  414. package/dist/knowledge/knowledge-stale-gate-input.d.ts +3 -0
  415. package/dist/knowledge/knowledge-stale-gate-input.d.ts.map +1 -0
  416. package/dist/knowledge/knowledge-stale-gate-input.js +1 -0
  417. package/dist/knowledge/knowledge-stale-gate-result.d.ts +3 -0
  418. package/dist/knowledge/knowledge-stale-gate-result.d.ts.map +1 -0
  419. package/dist/knowledge/knowledge-stale-gate-result.js +1 -0
  420. package/dist/knowledge/knowledge-stale-gate.d.ts +10 -0
  421. package/dist/knowledge/knowledge-stale-gate.d.ts.map +1 -0
  422. package/dist/knowledge/knowledge-stale-gate.js +9 -0
  423. package/dist/main.d.ts.map +1 -1
  424. package/dist/main.js +204 -83
  425. package/dist/output/failure-hints.d.ts.map +1 -1
  426. package/dist/output/failure-hints.js +11 -9
  427. package/dist/output/rejected-entries-note.d.ts +57 -0
  428. package/dist/output/rejected-entries-note.d.ts.map +1 -0
  429. package/dist/output/rejected-entries-note.js +103 -0
  430. package/dist/output/stdout-is-pipe.d.ts +13 -0
  431. package/dist/output/stdout-is-pipe.d.ts.map +1 -0
  432. package/dist/output/stdout-is-pipe.js +21 -0
  433. package/dist/packs/stale-build-warning.d.ts +11 -0
  434. package/dist/packs/stale-build-warning.d.ts.map +1 -0
  435. package/dist/packs/stale-build-warning.js +23 -0
  436. package/dist/quality/run-quality.d.ts +123 -0
  437. package/dist/quality/run-quality.d.ts.map +1 -0
  438. package/dist/quality/run-quality.js +442 -0
  439. package/dist/schemas/json-schemas.d.ts +184 -3
  440. package/dist/schemas/json-schemas.d.ts.map +1 -1
  441. package/dist/schemas/json-schemas.js +113 -2
  442. package/dist/shrk.d.ts +3 -0
  443. package/dist/shrk.d.ts.map +1 -0
  444. package/dist/shrk.js +30 -0
  445. package/dist/surface/audience-applicability.d.ts +26 -0
  446. package/dist/surface/audience-applicability.d.ts.map +1 -0
  447. package/dist/surface/audience-applicability.js +60 -0
  448. package/dist/surface/catalog-command-safety.d.ts +18 -0
  449. package/dist/surface/catalog-command-safety.d.ts.map +1 -0
  450. package/dist/surface/catalog-command-safety.js +62 -0
  451. package/dist/surface/cli-command-resolver.d.ts +21 -0
  452. package/dist/surface/cli-command-resolver.d.ts.map +1 -0
  453. package/dist/surface/cli-command-resolver.js +87 -0
  454. package/dist/surface/command-dispatch-kind.d.ts +20 -0
  455. package/dist/surface/command-dispatch-kind.d.ts.map +1 -0
  456. package/dist/surface/command-dispatch-kind.js +20 -0
  457. package/dist/surface/command-index-entry.d.ts +40 -0
  458. package/dist/surface/command-index-entry.d.ts.map +1 -0
  459. package/dist/surface/command-index-entry.js +1 -0
  460. package/dist/surface/command-index.d.ts +77 -0
  461. package/dist/surface/command-index.d.ts.map +1 -0
  462. package/dist/surface/command-index.js +323 -0
  463. package/dist/surface/i-command-index.d.ts +22 -0
  464. package/dist/surface/i-command-index.d.ts.map +1 -0
  465. package/dist/surface/i-command-index.js +1 -0
  466. package/dist/surface/i-command-string-context.d.ts +20 -0
  467. package/dist/surface/i-command-string-context.d.ts.map +1 -0
  468. package/dist/surface/i-command-string-context.js +1 -0
  469. package/dist/surface/i-surface-denial.d.ts +13 -0
  470. package/dist/surface/i-surface-denial.d.ts.map +1 -0
  471. package/dist/surface/i-surface-denial.js +1 -0
  472. package/dist/surface/load-surface-context.d.ts +17 -1
  473. package/dist/surface/load-surface-context.d.ts.map +1 -1
  474. package/dist/surface/load-surface-context.js +48 -10
  475. package/dist/surface/not-enabled-error.d.ts +38 -4
  476. package/dist/surface/not-enabled-error.d.ts.map +1 -1
  477. package/dist/surface/not-enabled-error.js +96 -6
  478. package/dist/surface/profiles.d.ts +7 -0
  479. package/dist/surface/profiles.d.ts.map +1 -1
  480. package/dist/surface/resolve-command-string.d.ts +10 -0
  481. package/dist/surface/resolve-command-string.d.ts.map +1 -0
  482. package/dist/surface/resolve-command-string.js +572 -0
  483. package/dist/surface/surface-config-writer.d.ts +7 -2
  484. package/dist/surface/surface-config-writer.d.ts.map +1 -1
  485. package/dist/surface/surface-config-writer.js +25 -6
  486. package/dist/surface/surface-layer.d.ts +11 -0
  487. package/dist/surface/surface-layer.d.ts.map +1 -0
  488. package/dist/surface/surface-layer.js +11 -0
  489. package/dist/surface/surface-refusal-reason.d.ts +16 -0
  490. package/dist/surface/surface-refusal-reason.d.ts.map +1 -0
  491. package/dist/surface/surface-refusal-reason.js +16 -0
  492. package/dist/surface/surface-selector.d.ts +26 -0
  493. package/dist/surface/surface-selector.d.ts.map +1 -0
  494. package/dist/surface/surface-selector.js +42 -0
  495. package/dist/surface/surface-summary.d.ts +61 -18
  496. package/dist/surface/surface-summary.d.ts.map +1 -1
  497. package/dist/surface/surface-summary.js +147 -60
  498. package/dist/surface/tier.d.ts +85 -22
  499. package/dist/surface/tier.d.ts.map +1 -1
  500. package/dist/surface/tier.js +132 -30
  501. package/dist/usage/usage-log.d.ts +6 -1
  502. package/dist/usage/usage-log.d.ts.map +1 -1
  503. package/dist/usage/usage-log.js +7 -2
  504. package/dist/validation/run-validation-loop.d.ts +9 -0
  505. package/dist/validation/run-validation-loop.d.ts.map +1 -1
  506. package/dist/validation/run-validation-loop.js +14 -11
  507. package/dist/validation/typecheck-emitted.d.ts +8 -9
  508. package/dist/validation/typecheck-emitted.d.ts.map +1 -1
  509. package/dist/validation/typecheck-emitted.js +17 -97
  510. package/package.json +34 -34
@@ -0,0 +1,520 @@
1
+ import { formatEmptyRuleAdvice } from '@shrkcrft/core';
2
+ import { planeScanExcludeDirs, readScopeCoverage } from '@shrkcrft/boundaries';
3
+ import { warmCliReferenceRegistries } from "../surface/cli-command-resolver.js";
4
+ import { checkDocReferences, inspectSharkcraft, resolveProjectConfig, } from '@shrkcrft/inspector';
5
+ import { flagBool, flagString, resolveCwd, } from "../command-registry.js";
6
+ import { PositionalMode } from "../dispatch/positional-mode.js";
7
+ import { ExitCode } from "../exit-codes.js";
8
+ import { asJson, header, kv } from "../output/format-output.js";
9
+ import { buildGateEnvelope } from "../gates/gate-envelope.js";
10
+ import { verdictLine } from "../gates/verdict-line.js";
11
+ import { acceptedEmptyNote } from "../gates/accepted-empty-note.js";
12
+ import { emptyRuleAdviceLines } from "../gates/empty-rule-advice-lines.js";
13
+ import { qualifyCleanForUnits } from "../gates/qualify-clean-for-units.js";
14
+ import { unitStateNotes } from "../gates/unit-state-notes.js";
15
+ import { planeVerdictForExit } from "../gates/plane-verdict.js";
16
+ import { seamRejectedRules } from "../gates/seam-rejected-rules.js";
17
+ const SCHEMA = 'sharkcraft.doc-references/v1';
18
+ /**
19
+ * What one doc-reference rule examined — shared by `docs references check` and
20
+ * the aggregate (`gates check`, `quality`), so both report the same scope.
21
+ *
22
+ * The unit is the id-shaped tokens the rule matched. Tokens it did NOT check
23
+ * were skipped by the rule's own config — an `exempt` id, an in-file
24
+ * `exemptMarker`, the `requireContext` gate — which is a deliberate narrowing,
25
+ * so it is accepted by that config and printed as such rather than silently
26
+ * shrinking the denominator.
27
+ */
28
+ export function docReferenceCoverage(r) {
29
+ // An intended-empty rule (round 13: every `files` inclusion glob marked
30
+ // `expectEmpty`, no document matched) is covered by its acceptance — the
31
+ // settle's own record, printed at exit 0.
32
+ if (r.emptyCoverage !== undefined)
33
+ return r.emptyCoverage;
34
+ // A document the reader could not read (over the read cap) folds in through
35
+ // the one rule every plane uses: `examined N of M files`, named.
36
+ return readScopeCoverage(planeDocReferenceCoverage(r), r.readScope);
37
+ }
38
+ function planeDocReferenceCoverage(r) {
39
+ if (r.error !== undefined) {
40
+ return { unit: 'references', expected: 0, examined: 0, reason: 'the rule could not run' };
41
+ }
42
+ const expected = r.tokensChecked + r.tokensSkipped;
43
+ return {
44
+ unit: 'references',
45
+ expected,
46
+ examined: r.tokensChecked,
47
+ ...(r.skipReason !== undefined
48
+ ? { reason: r.skipReason }
49
+ : r.tokensSkipped > 0
50
+ ? { reason: "skipped by the rule's own exempt / exemptMarker / requireContext config" }
51
+ : {}),
52
+ ...(r.tokensSkipped > 0 && r.tokensChecked > 0
53
+ ? { acceptedBy: 'the rule config (exempt / exemptMarker / requireContext)' }
54
+ : {}),
55
+ };
56
+ }
57
+ async function prepare(args,
58
+ /** `rejectedKnown`: the verdict verb may select a rejected rule by `--id` (its errored row). */
59
+ opts = {}) {
60
+ const cwd = resolveCwd(args);
61
+ const json = flagBool(args, 'json');
62
+ const loaded = await resolveProjectConfig(cwd);
63
+ if (!loaded.ok) {
64
+ const msg = loaded.error.message;
65
+ if (json)
66
+ process.stdout.write(asJson({ schema: SCHEMA, error: msg }) + '\n');
67
+ else
68
+ process.stderr.write(`Could not load config: ${msg}\n Run \`shrk doctor\` for details.\n`);
69
+ return { ok: false, code: ExitCode.UsageError };
70
+ }
71
+ const all = loaded.value.config.docReferences ?? [];
72
+ // A pack doc-reference rule the merge seam REJECTED is a configured rule
73
+ // that never ran — an ERRORED row on this verb exactly as on `gates check`
74
+ // (round 13, P3 review). It was one `! … invalid docReference element … —
75
+ // skipped` line under a ✓ at exit 0 (or "No doc-reference rules declared"
76
+ // at 2 when it was the only rule) while `gates check` exited 1 on the tree.
77
+ const rejectedAll = seamRejectedRules(loaded.value, ['doc-reference']);
78
+ let rules = all;
79
+ let rejected = rejectedAll;
80
+ const id = flagString(args, 'id');
81
+ if (id) {
82
+ const wanted = id.split(',').map((s) => s.trim()).filter(Boolean);
83
+ const known = new Set([
84
+ ...all.map((r) => r.id),
85
+ ...(opts.rejectedKnown === true ? rejectedAll.map((r) => r.id) : []),
86
+ ]);
87
+ const unknown = wanted.filter((w) => !known.has(w));
88
+ if (unknown.length > 0) {
89
+ process.stderr.write(`Unknown doc-reference rule id(s): ${unknown.join(', ')}. Declared: ${[...known].join(', ') || '(none)'}\n`);
90
+ return { ok: false, code: ExitCode.UsageError };
91
+ }
92
+ rules = all.filter((r) => wanted.includes(r.id));
93
+ rejected = rejectedAll.filter((r) => wanted.includes(r.id));
94
+ }
95
+ return {
96
+ ok: true,
97
+ value: {
98
+ cwd,
99
+ rules,
100
+ all,
101
+ rejected,
102
+ // THE plane scan scope — the same authority `gates check` reads.
103
+ excludeDirs: planeScanExcludeDirs(cwd, loaded.value.sharkcraftDir),
104
+ planeDiagnostics: loaded.value.planeDiagnostics,
105
+ },
106
+ };
107
+ }
108
+ /**
109
+ * Build the inspection the resolver needs.
110
+ *
111
+ * Deliberately lazy — it is only paid for when a `docReferences` rule exists,
112
+ * so a repo without the plane never loads the registries just to be told it has
113
+ * no rules.
114
+ */
115
+ async function inspectionFor(cwd) {
116
+ // Playbook / construct ids come from a cache an ASYNC load populates; the
117
+ // resolver is sync. Warming here is what makes a correct pack playbook cited
118
+ // in prose actually resolve.
119
+ const inspection = await inspectSharkcraft({ cwd });
120
+ // WITH the command resolver: a `resolvesAs: ['command']` rule resolves
121
+ // against the live command index (without it, `command` is unverifiable
122
+ // and the rule refuses loudly).
123
+ await warmCliReferenceRegistries(inspection);
124
+ return inspection;
125
+ }
126
+ /**
127
+ * The "no rules declared" landing. A VERDICT verb passes its name so its JSON
128
+ * still carries the settled `gate` envelope — nothing declared is `2`.
129
+ */
130
+ function writeNoRules(json, verb) {
131
+ // A VERDICT verb settles first and renders second, in text AND JSON: nothing
132
+ // declared proposes 0 and the run coverage (expected 0) settles it to 2. The
133
+ // exit comes from the envelope — never a hard-coded code — so text, JSON and
134
+ // gate.exit cannot disagree. List / explain subverbs stay informational.
135
+ const gate = verb !== undefined
136
+ ? buildGateEnvelope(verb, ExitCode.VerifiedPass, [], {
137
+ unit: 'doc-reference rules',
138
+ expected: 0,
139
+ examined: 0,
140
+ reason: 'no docReferences[] declared',
141
+ })
142
+ : undefined;
143
+ const exit = gate?.exit ?? ExitCode.NotVerified;
144
+ if (json) {
145
+ process.stdout.write(asJson({
146
+ schema: SCHEMA,
147
+ results: [],
148
+ evaluated: 0,
149
+ verdict: gate ? planeVerdictForExit(gate.exit) : 'not-verified',
150
+ ...(gate ? { exitCode: gate.exit, gate } : {}),
151
+ }) + '\n');
152
+ return exit;
153
+ }
154
+ process.stdout.write(header('Doc references'));
155
+ process.stdout.write(' No doc-reference rules declared. Add `docReferences[]` to sharkcraft.config.ts to\n' +
156
+ ' catch ids cited in prose (READMEs, docs, agent skill files) that no longer resolve\n' +
157
+ ' (see docs/doc-references.md).\n');
158
+ if (gate) {
159
+ const line = verdictLine(gate, 'Nothing declared — accepted.');
160
+ if (line)
161
+ process.stdout.write(`\n${line}\n`);
162
+ }
163
+ return exit;
164
+ }
165
+ function resultJson(r) {
166
+ return {
167
+ id: r.ruleId,
168
+ ...(r.description ? { description: r.description } : {}),
169
+ status: r.status,
170
+ severity: r.severity,
171
+ filesScanned: r.filesScanned,
172
+ tokensChecked: r.tokensChecked,
173
+ tokensSkipped: r.tokensSkipped,
174
+ findings: r.findings,
175
+ ...(r.skipReason ? { skipReason: r.skipReason } : {}),
176
+ ...(r.error ? { error: r.error } : {}),
177
+ };
178
+ }
179
+ /**
180
+ * The round-12 list-verb rejection note (K10): one line per pack doc-reference
181
+ * rule the merge seam REJECTED — the rows `baseline list` / `gates list` print.
182
+ */
183
+ function writeRejectedDocRules(rejected) {
184
+ if (rejected.length === 0)
185
+ return;
186
+ process.stdout.write(`\n rejected at the pack-plane merge seam — never checked (${rejected.length}):\n`);
187
+ for (const r of rejected)
188
+ process.stdout.write(` ✗ ${r.id} REJECTED — ${r.error ?? 'failed validation'}\n`);
189
+ process.stdout.write(' `shrk packs contributions` names every rejected entry.\n');
190
+ }
191
+ export const docsReferencesCheckCommand = {
192
+ name: 'check',
193
+ description: 'Scan configured docs for id-shaped tokens and assert each resolves to a registered id. Catches a README or skill file citing a template that no longer exists.',
194
+ usage: 'shrk docs references check [--id <ids>] [--json]',
195
+ booleanFlags: new Set(['json']),
196
+ async run(args) {
197
+ const prep = await prepare(args, { rejectedKnown: true });
198
+ if (!prep.ok)
199
+ return prep.code;
200
+ const json = flagBool(args, 'json');
201
+ const rejected = prep.value.rejected;
202
+ if (prep.value.rules.length === 0 && rejected.length === 0)
203
+ return writeNoRules(json, 'docs references check');
204
+ // The resolver's inspection is paid for only when a rule will run.
205
+ const inspection = prep.value.rules.length > 0 ? await inspectionFor(prep.value.cwd) : undefined;
206
+ const results = inspection
207
+ ? prep.value.rules.map((r) => checkDocReferences(prep.value.cwd, r, inspection, prep.value.excludeDirs))
208
+ : [];
209
+ // A rule that ERRORED proved nothing — it never got as far as checking an
210
+ // id. So it is not `evaluated`, whatever its severity: a warning-severity
211
+ // rule that could not run must not leave the banner saying "not blocking"
212
+ // over an exit code of 0, which is the same half-truth as a green banner
213
+ // above a list of findings.
214
+ const errored = results.filter((r) => r.status === 'error');
215
+ const failed = results.filter((r) => r.status === 'failed');
216
+ const blocking = [...failed, ...errored].filter((r) => r.severity === 'error');
217
+ const evaluated = results.filter((r) => r.status !== 'skipped' && r.status !== 'error').length;
218
+ const skipped = results.length - evaluated;
219
+ // A rejected pack rule is a configured rule that never ran: 1, as on
220
+ // `gates check` (its ERRORED row, `failed validation — NOT evaluated`).
221
+ const proposed = blocking.length > 0 || rejected.length > 0
222
+ ? ExitCode.Failure
223
+ : evaluated === 0 || skipped > 0
224
+ ? ExitCode.NotVerified
225
+ : ExitCode.VerifiedPass;
226
+ // Settle first, render second: the envelope is built for text AND JSON, so
227
+ // both return the same settled exit and the ✓ line is printed only from it.
228
+ const unexamined = [
229
+ ...results.filter((r) => r.status === 'skipped' || r.status === 'error').map((r) => r.ruleId),
230
+ ...rejected.map((r) => r.id),
231
+ ];
232
+ const env = buildGateEnvelope('docs references check', proposed, [...results.map((r) => ({
233
+ id: r.ruleId,
234
+ type: 'doc-reference',
235
+ status: r.status,
236
+ severity: r.severity,
237
+ counts: { files: r.filesScanned, tokens: r.tokensChecked, skipped: r.tokensSkipped },
238
+ violations: r.findings.map((f) => ({
239
+ id: f.token,
240
+ file: f.file,
241
+ line: f.line,
242
+ message: f.message,
243
+ ...(f.didYouMean.length > 0 ? { hint: `did you mean: ${f.didYouMean.join(', ')}` } : {}),
244
+ })),
245
+ ...(r.skipReason ? { skipReason: r.skipReason } : {}),
246
+ ...(r.error ? { error: r.error } : {}),
247
+ coverage: docReferenceCoverage(r),
248
+ // The rule's `expectEmpty` acceptance and unit lines (round 13),
249
+ // folded into the envelope's one settle — the accepted line comes from it.
250
+ ...(r.unitAcceptance !== undefined ? { unitAcceptance: r.unitAcceptance } : {}),
251
+ ...(r.units !== undefined ? { units: r.units } : {}),
252
+ })), ...rejected], {
253
+ unit: 'doc-reference rules',
254
+ expected: results.length + rejected.length,
255
+ examined: results.length + rejected.length - unexamined.length,
256
+ ...(unexamined.length > 0 ? { unexamined, reason: 'checked nothing or could not run' } : {}),
257
+ });
258
+ const exit = env.exit;
259
+ if (json) {
260
+ process.stdout.write(asJson({
261
+ schema: SCHEMA,
262
+ results: results.map(resultJson),
263
+ evaluated,
264
+ skipped,
265
+ verdict: exit === ExitCode.Failure ? 'errors' : exit === ExitCode.VerifiedPass ? 'pass' : 'not-verified',
266
+ rejected: rejected.map((r) => ({ id: r.id, error: r.error ?? null })),
267
+ diagnostics: prep.value.planeDiagnostics,
268
+ exitCode: exit,
269
+ gate: env,
270
+ }) + '\n');
271
+ return exit;
272
+ }
273
+ process.stdout.write(header('Doc references'));
274
+ // Round 13 (K6): the printed count is the envelope's (`gate.evaluated`), which
275
+ // never counts a rule accepted as intended-empty — it is named apart. The
276
+ // local `evaluated` keeps counting it for the "nothing ran" proposal above.
277
+ process.stdout.write(kv('evaluated', `${env.evaluated} of ${prep.value.rules.length + rejected.length}${acceptedEmptyNote(env.acceptedEmpty)}`) +
278
+ '\n');
279
+ // THE shared unit-state block (round 13, K2): a dead `files` glob of a rule
280
+ // that still matched, and a LOCAL expectEmpty marker whose target appeared,
281
+ // withhold the ✓ (exit unchanged); a pack marker is INFO.
282
+ const unitNotes = unitStateNotes(results.map((r) => ({
283
+ id: r.ruleId,
284
+ ...(r.unitLiveness !== undefined ? { unitLiveness: r.unitLiveness } : {}),
285
+ reportedEmpty: r.status === 'skipped' || r.skipReason !== undefined,
286
+ })));
287
+ for (const r of results) {
288
+ if (r.status === 'skipped') {
289
+ process.stdout.write(` – ${r.ruleId} SKIPPED — ${r.skipReason}\n`);
290
+ continue;
291
+ }
292
+ if (r.status === 'error') {
293
+ process.stdout.write(` ! ${r.ruleId} ${r.error}\n`);
294
+ continue;
295
+ }
296
+ if (r.status === 'passed') {
297
+ // Rendered from the SETTLED rule: a pass over part of its scope is
298
+ // `partial`, never a ✓ (the keystone emitter pattern, step 5).
299
+ const settledRule = env.rules.find((x) => x.id === r.ruleId);
300
+ process.stdout.write(settledRule?.status === 'partial'
301
+ ? ` ~ ${r.ruleId} PARTIAL — ${settledRule.shortfall ?? 'part of its scope was not examined'}\n`
302
+ : ` ✓ ${r.ruleId} (${r.tokensChecked} reference(s) across ${r.filesScanned} doc(s) all resolve)\n`);
303
+ continue;
304
+ }
305
+ // A rule that CHECKED nothing failed for a different reason than one with
306
+ // findings, and the loud-skip contract is worthless if it does not say
307
+ // which. `0 unresolved of 0 checked` would send the reader hunting for a
308
+ // bad id when the real problem is a moved directory.
309
+ if (r.skipReason) {
310
+ process.stdout.write(` ✗ ${r.ruleId} FAILED — ${r.skipReason}\n`);
311
+ process.stdout.write(' Nothing was checked, so nothing was enforced.\n' +
312
+ ` → ${formatEmptyRuleAdvice({ fails: true })}\n`);
313
+ continue;
314
+ }
315
+ process.stdout.write(` ✗ ${r.ruleId} ${r.findings.length} unresolved reference(s) of ${r.tokensChecked} checked\n`);
316
+ for (const f of r.findings.slice(0, 25)) {
317
+ process.stdout.write(` • ${f.token} (${f.file}:${f.line})\n`);
318
+ if (f.didYouMean.length > 0) {
319
+ process.stdout.write(` did you mean: ${f.didYouMean.join(', ')}\n`);
320
+ }
321
+ }
322
+ if (r.findings.length > 25) {
323
+ process.stdout.write(` … (${r.findings.length - 25} more)\n`);
324
+ }
325
+ const hint = r.findings.find((f) => f.hint)?.hint;
326
+ if (hint)
327
+ process.stdout.write(` → ${hint}\n`);
328
+ }
329
+ for (const r of rejected)
330
+ process.stdout.write(` ✗ ${r.id} REJECTED — ${r.error ?? 'failed validation'}\n`);
331
+ for (const d of prep.value.planeDiagnostics)
332
+ process.stdout.write(` ! ${d}\n`);
333
+ // THE empty-rule advice (round 13, K8) for a rule that matched nothing and
334
+ // does not fail on it: only a FAILING empty rule was advised (inline,
335
+ // above), so a soft skip was never told how to make it fail or to mark a
336
+ // planned unit.
337
+ for (const a of emptyRuleAdviceLines(results.filter((r) => r.status === 'skipped').map(() => ({ fails: false })))) {
338
+ process.stdout.write(` ${a}.\n`);
339
+ }
340
+ process.stdout.write(unitNotes.text);
341
+ // A warning-severity rule reports without blocking, but the banner must
342
+ // still say it FIRED. "Every id resolves ✓" printed under a list of
343
+ // unresolved ids is the kind of half-truth that trains people to stop
344
+ // reading the output.
345
+ const warned = failed.filter((r) => r.severity !== 'error');
346
+ const warnedCount = warned.reduce((n, r) => n + r.findings.length, 0);
347
+ const line = verdictLine(env, warned.length > 0
348
+ ? `${warnedCount} unresolved reference(s) reported by ${warned.length} warning rule(s) — not blocking.`
349
+ : qualifyCleanForUnits('Every id cited in prose resolves. ✓', unitNotes), proposed === ExitCode.NotVerified
350
+ ? errored.length > 0
351
+ ? `${errored.length} rule(s) could not run — nothing was proved. This is NOT a pass.`
352
+ : 'Nothing was checked — this is NOT a pass.'
353
+ : undefined);
354
+ if (line)
355
+ process.stdout.write(`\n${line}\n`);
356
+ return exit;
357
+ },
358
+ };
359
+ export const docsReferencesExplainCommand = {
360
+ name: 'explain',
361
+ description: 'Show every id-shaped token ONE rule considered: where it was found, whether it resolved, and why a token was skipped.',
362
+ usage: 'shrk docs references explain --id <id> [--json]',
363
+ booleanFlags: new Set(['json']),
364
+ async run(args) {
365
+ const id = flagString(args, 'id') ?? args.positional[0];
366
+ if (!id) {
367
+ process.stderr.write('Usage: shrk docs references explain --id <id>\n');
368
+ return ExitCode.UsageError;
369
+ }
370
+ const forwarded = { ...args, flags: new Map(args.flags) };
371
+ forwarded.flags.set('id', id);
372
+ // A rejected pack rule's id is a DECLARED one (K10): `explain` names its
373
+ // rejection — it called the id unknown (a usage error, 3).
374
+ const prep = await prepare(forwarded, { rejectedKnown: true });
375
+ if (!prep.ok)
376
+ return prep.code;
377
+ const rule = prep.value.rules[0];
378
+ if (!rule) {
379
+ const rejectedRule = prep.value.rejected[0];
380
+ if (rejectedRule === undefined)
381
+ return writeNoRules(flagBool(args, 'json'));
382
+ if (flagBool(args, 'json')) {
383
+ process.stdout.write(asJson({
384
+ schema: 'sharkcraft.doc-references-explain/v1',
385
+ id: rejectedRule.id,
386
+ rejected: true,
387
+ error: rejectedRule.error ?? null,
388
+ }) + '\n');
389
+ }
390
+ else {
391
+ process.stdout.write(header(`Doc references: ${rejectedRule.id}`));
392
+ writeRejectedDocRules([rejectedRule]);
393
+ }
394
+ // A rule that never loaded cannot be explained: a failure, as every
395
+ // registry verb answers a rejected pack registry.
396
+ return ExitCode.Failure;
397
+ }
398
+ const inspection = await inspectionFor(prep.value.cwd);
399
+ const result = checkDocReferences(prep.value.cwd, rule, inspection, prep.value.excludeDirs);
400
+ if (flagBool(args, 'json')) {
401
+ process.stdout.write(asJson({
402
+ schema: 'sharkcraft.doc-references-explain/v1',
403
+ ...resultJson(result),
404
+ tokens: result.tokens,
405
+ resolvesAs: rule.resolvesAs,
406
+ requireContext: rule.requireContext ?? 'backtick',
407
+ }) + '\n');
408
+ return ExitCode.VerifiedPass;
409
+ }
410
+ process.stdout.write(header(`Doc references: ${rule.id}`));
411
+ if (rule.description)
412
+ process.stdout.write(` ${rule.description}\n`);
413
+ process.stdout.write(kv('files', rule.files.join(', ')) + '\n');
414
+ process.stdout.write(kv('token pattern', `/${rule.tokenPattern}/`) + '\n');
415
+ process.stdout.write(kv('resolves as', rule.resolvesAs.join(', ')) + '\n');
416
+ process.stdout.write(kv('context gate', rule.requireContext ?? 'backtick') + '\n');
417
+ process.stdout.write(kv('docs scanned', String(result.filesScanned)) + '\n');
418
+ process.stdout.write(kv('tokens', `${result.tokensChecked} checked, ${result.tokensSkipped} skipped`) + '\n');
419
+ if (result.error)
420
+ process.stdout.write(` ! ${result.error}\n`);
421
+ process.stdout.write('\n');
422
+ for (const t of result.tokens.slice(0, 100)) {
423
+ const verdict = t.skipped
424
+ ? `skipped (${t.skipped})`
425
+ : t.resolvedAs
426
+ ? `✓ ${t.resolvedAs}`
427
+ : '✗ UNRESOLVED';
428
+ process.stdout.write(` ${t.token} (${t.file}:${t.line}) — ${verdict}\n`);
429
+ }
430
+ if (result.tokens.length > 100) {
431
+ process.stdout.write(` … (${result.tokens.length - 100} more)\n`);
432
+ }
433
+ return ExitCode.VerifiedPass;
434
+ },
435
+ };
436
+ export const docsReferencesListCommand = {
437
+ name: 'list',
438
+ description: 'List every declared doc-reference rule: its globs, token shape, and target registries.',
439
+ usage: 'shrk docs references list [--json]',
440
+ booleanFlags: new Set(['json']),
441
+ async run(args) {
442
+ const prep = await prepare(args);
443
+ if (!prep.ok)
444
+ return prep.code;
445
+ const json = flagBool(args, 'json');
446
+ // Round 13 (K10): a pack doc-reference rule the merge seam REJECTED is a
447
+ // declared rule that never runs — listed, as `baseline list` / `gates
448
+ // list` list theirs (it was absent from `list` and unknown to `explain`).
449
+ const rejected = prep.value.rejected;
450
+ if (prep.value.all.length === 0 && rejected.length === 0)
451
+ return writeNoRules(json);
452
+ if (json) {
453
+ process.stdout.write(asJson({
454
+ schema: SCHEMA,
455
+ rules: prep.value.all,
456
+ rejected: rejected.map((r) => ({ id: r.id, error: r.error ?? null })),
457
+ }) + '\n');
458
+ return ExitCode.VerifiedPass;
459
+ }
460
+ process.stdout.write(header(`Doc-reference rules (${prep.value.all.length})`));
461
+ for (const r of prep.value.all) {
462
+ process.stdout.write(` • ${r.id}\n`);
463
+ process.stdout.write(` files ${r.files.join(', ')}\n`);
464
+ process.stdout.write(` token /${r.tokenPattern}/\n`);
465
+ process.stdout.write(` resolves ${r.resolvesAs.join(', ')}\n`);
466
+ process.stdout.write(` context ${r.requireContext ?? 'backtick'}\n`);
467
+ if (r.description)
468
+ process.stdout.write(` ${r.description}\n`);
469
+ }
470
+ writeRejectedDocRules(rejected);
471
+ return ExitCode.VerifiedPass;
472
+ },
473
+ };
474
+ /** `shrk docs references <verb>` — dispatches to check / explain / list. */
475
+ export const docsReferencesCommand = {
476
+ name: 'references',
477
+ description: 'Prose-reference linter: assert every id cited in free text (READMEs, docs, agent skill files) still resolves to a registered id.',
478
+ usage: 'shrk docs references check | explain --id <id> | list',
479
+ // Declared (round 11 review): the dispatcher guard refuses any other token
480
+ // with the closest subverb, `help` and the index see the three verbs, and
481
+ // the declared walk reaches the verdict path — so a bad flag on `docs
482
+ // references check` is a usage error of `docs references check` (3), never
483
+ // one of `docs references` (2).
484
+ positionals: PositionalMode.None,
485
+ subverbs: [
486
+ {
487
+ name: docsReferencesCheckCommand.name,
488
+ description: docsReferencesCheckCommand.description,
489
+ usage: docsReferencesCheckCommand.usage,
490
+ positionals: PositionalMode.None,
491
+ },
492
+ {
493
+ name: docsReferencesExplainCommand.name,
494
+ description: docsReferencesExplainCommand.description,
495
+ usage: docsReferencesExplainCommand.usage,
496
+ positionals: PositionalMode.Free,
497
+ },
498
+ {
499
+ name: docsReferencesListCommand.name,
500
+ description: docsReferencesListCommand.description,
501
+ usage: docsReferencesListCommand.usage,
502
+ positionals: PositionalMode.None,
503
+ },
504
+ ],
505
+ booleanFlags: new Set(['json']),
506
+ async run(args) {
507
+ const sub = args.positional[0];
508
+ const rest = { ...args, positional: args.positional.slice(1) };
509
+ if (sub === 'check')
510
+ return docsReferencesCheckCommand.run(rest);
511
+ if (sub === 'explain')
512
+ return docsReferencesExplainCommand.run(rest);
513
+ if (sub === 'list')
514
+ return docsReferencesListCommand.run(rest);
515
+ // Only a bare `shrk docs references` lands here: the guard refused any
516
+ // other token before this body ran.
517
+ process.stderr.write('Usage: shrk docs references check | explain --id <id> | list\n');
518
+ return ExitCode.UsageError;
519
+ },
520
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.command.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.command.ts"],"names":[],"mappings":"AAqBA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AA6PhC,eAAO,MAAM,aAAa,EAAE,eAW3B,CAAC;AAwfF,eAAO,MAAM,qBAAqB,EAAE,eAmCnC,CAAC;AAuDF,eAAO,MAAM,yBAAyB,EAAE,eAavC,CAAC;AAIF,eAAO,MAAM,wBAAwB,EAAE,eA2CtC,CAAC;AAgCF,eAAO,MAAM,6BAA6B,EAAE,eAa3C,CAAC"}
1
+ {"version":3,"file":"doctor.command.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.command.ts"],"names":[],"mappings":"AAwBA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAmShC,eAAO,MAAM,aAAa,EAAE,eAc3B,CAAC;AA4gBF,eAAO,MAAM,qBAAqB,EAAE,eAmCnC,CAAC;AAuDF,eAAO,MAAM,yBAAyB,EAAE,eAavC,CAAC;AAIF,eAAO,MAAM,wBAAwB,EAAE,eA2CtC,CAAC;AAgCF,eAAO,MAAM,6BAA6B,EAAE,eAa3C,CAAC"}
@@ -1,14 +1,18 @@
1
- import { buildAcknowledgement, buildAiReadinessReport, buildSuppressionEntry, doctorSuppressionsFile, DoctorSeverity, filterDoctorResult, inspectSharkcraft, loadDoctorSuppressions, renderAcknowledgementsText, runDoctor, saveDoctorSuppressions, summarizeAcknowledgements, } from '@shrkcrft/inspector';
1
+ import { detectGraphFreshness } from '@shrkcrft/graph';
2
+ import { buildAcknowledgement, buildAiReadinessReport, buildSuppressionEntry, detectUnregisteredExports, doctorSuppressionsFile, DoctorSeverity, filterDoctorResult, inspectSharkcraft, loadDoctorSuppressions, renderAcknowledgementsText, doctorVerdict, runDoctor, saveDoctorSuppressions, summarizeAcknowledgements, } from '@shrkcrft/inspector';
2
3
  import { detectProjectShape } from '@shrkcrft/workspace';
3
4
  import { loadSurfaceContext } from "../surface/load-surface-context.js";
4
5
  import { buildSurfaceSummary } from "../surface/surface-summary.js";
5
6
  import { renderShapeLine } from "../surface/shape-defaults.js";
6
7
  import { existsSync } from 'node:fs';
7
8
  import { flagBool, flagNumber, flagString, flagList, resolveCwd, } from "../command-registry.js";
9
+ import { PositionalMode } from "../dispatch/positional-mode.js";
8
10
  import { SemanticIndex, listIndexableFiles } from '@shrkcrft/embeddings';
9
11
  import { asJson, header, kv } from "../output/format-output.js";
10
12
  import { maybeRunInWatchMode } from "../output/watch-loop.js";
11
13
  import { doctorHints, renderFailureHints } from "../output/failure-hints.js";
14
+ import { settleVerdict } from "../gates/settle-verdict.js";
15
+ import { verdictLine } from "../gates/verdict-line.js";
12
16
  import { foldDoctorChecks, renderFoldedSummary, DoctorState, } from "../doctor/doctor-tags.js";
13
17
  import { enrichWithLlmRecommendations, renderRecommendationsMarkdown, } from '@shrkcrft/ai';
14
18
  const SEVERITY_LABEL = {
@@ -157,6 +161,39 @@ function augmentWithSemanticIndexCheck(result, cwd) {
157
161
  summary.errors = (summary.errors ?? 0) + 1;
158
162
  return { ...result, checks, summary };
159
163
  }
164
+ /**
165
+ * "Unregistered entry exports" (round 11 §3.1): an entry a group module exports
166
+ * that the aggregator registering it never lists is silently invisible. Added
167
+ * only when something is found (an error → exit 1); a clean repo sees no new
168
+ * line. The check lives in the inspector (`detectUnregisteredExports`) and is
169
+ * async (it imports the group modules), so it is appended here.
170
+ */
171
+ async function augmentWithUnregisteredExports(result, inspection) {
172
+ let found = [];
173
+ try {
174
+ found = await detectUnregisteredExports(inspection);
175
+ }
176
+ catch {
177
+ return result;
178
+ }
179
+ if (found.length === 0)
180
+ return result;
181
+ const shown = found.slice(0, 10).map((u) => `${u.group}${u.line > 0 ? `:${u.line}` : ''} — ${u.message}`);
182
+ const more = found.length > shown.length ? ` (+${found.length - shown.length} more)` : '';
183
+ const check = {
184
+ id: 'unregistered-entry-exports',
185
+ title: 'Unregistered entry exports',
186
+ severity: DoctorSeverity.Error,
187
+ category: 'unregistered-entry-exports',
188
+ code: 'unregistered-export',
189
+ message: `${found.length} exported entr${found.length === 1 ? 'y is' : 'ies are'} never registered, so no lookup can see ${found.length === 1 ? 'it' : 'them'}: ${shown.join('; ')}${more}`,
190
+ fix: "Add each export to its aggregator's array, or re-export the group module with `export * from './<group>'`.",
191
+ };
192
+ const summary = { ...result.summary, errors: (result.summary.errors ?? 0) + 1 };
193
+ // An error check is a failed doctor: `passed` is what the exit code, the
194
+ // JSON `ready` and the Verdict line all read, so it must flip with it.
195
+ return { ...result, passed: false, checks: [...result.checks, check], summary };
196
+ }
160
197
  function renderSemanticIndexCheck(report) {
161
198
  if (!report.hasIndex) {
162
199
  return {
@@ -214,6 +251,9 @@ function renderSemanticIndexCheck(report) {
214
251
  }
215
252
  export const doctorCommand = {
216
253
  name: 'doctor',
254
+ // Mixed-mode: suppress / suppressions / acknowledge / acknowledgements are
255
+ // trie children; a bare token reaching this handler used to run the doctor.
256
+ positionals: PositionalMode.None,
217
257
  description: 'Validate the local SharkCraft setup (config, knowledge, templates, project). `--focus errors|warnings-new|info`, `--hide <category,...>`, `--quiet-known` filter the headline view using `sharkcraft/doctor.suppressions.json`. `--watch`/`--once`/`--debounce` for live mode. `--explain-quality` shows the per-warning "why this matters" line so warnings stop being permanent yellow noise. `--blockers` shows only must-fix findings (errors + warning-category in {config-invalid, pack-signature-invalid, plan-signature-divergent, asset-load-failed}); exit code is non-zero iff a blocker remains. `--llm-recommendations` layers a local-LLM-derived list of concrete next-steps onto the deterministic output (no-op when no provider is reachable). Subcommands: `suppress`, `suppressions list|check`, `watch`.',
218
258
  usage: 'shrk [--cwd <dir>] doctor [--no-config] [--json] [--strict[=errors|warnings|all]] [--blockers] [--show-advisory] [--min-score <0-100>] [--focus errors,warnings-new,info] [--hide action-hint-quality,...] [--quiet-known] [--explain-quality] [--llm-recommendations] [--provider auto|ollama|llamacpp] [--watch [--once] [--debounce N]]',
219
259
  async run(args) {
@@ -236,7 +276,7 @@ async function doctorCommandImpl(args) {
236
276
  inspectOpts.loaderTimeoutMs = loaderTimeout;
237
277
  }
238
278
  const inspection = await inspectSharkcraft(inspectOpts);
239
- const result = augmentWithSemanticIndexCheck(runDoctor(inspection), cwd);
279
+ const result = await augmentWithUnregisteredExports(augmentWithSemanticIndexCheck(runDoctor(inspection, { graphDivergence: detectGraphFreshness(cwd) }), cwd), inspection);
240
280
  const report = buildAiReadinessReport(inspection);
241
281
  if (debug) {
242
282
  process.stderr.write(`[debug] inspection elapsed ${inspection.inspectionElapsedMs}ms cache=${inspection.cacheEnabled ? 'on' : 'off'} loaders=${inspection.loaderDiagnostics.length}\n`);
@@ -330,7 +370,7 @@ async function doctorCommandImpl(args) {
330
370
  // When --blockers is set, the exit code reflects ONLY the
331
371
  // remaining blocker set. This is the agent-friendly contract: 0 means
332
372
  // "nothing must-fix", 1 means "at least one blocker remains".
333
- const overallExitCode = noConfigLenient
373
+ const proposedExitCode = noConfigLenient
334
374
  ? 0
335
375
  : blockersOnly
336
376
  ? blockerCount > 0
@@ -339,6 +379,13 @@ async function doctorCommandImpl(args) {
339
379
  : (result.passed && !strictEval.failed && !minScoreFailed && !ackExpired)
340
380
  ? 0
341
381
  : 1;
382
+ // A scope the doctor could not verify (a compiled pack build with no build
383
+ // record, never compared with its source) settles a clean run to NOT
384
+ // VERIFIED (2), as `packs doctor` does. It never reads "Ready ✓". The
385
+ // advisory `--no-config` run and the filtered `--blockers` view keep
386
+ // their own contracts.
387
+ const doctorSettled = noConfigLenient || blockersOnly ? undefined : settleVerdict(proposedExitCode, result.coverage ?? []);
388
+ const overallExitCode = doctorSettled?.exit ?? proposedExitCode;
342
389
  if (flagBool(args, 'json')) {
343
390
  // Also compute the folded view for machine consumers so JSON
344
391
  // callers see source/state tags + folded counts.
@@ -366,7 +413,9 @@ async function doctorCommandImpl(args) {
366
413
  }
367
414
  process.stdout.write(asJson({
368
415
  targetRoot: inspection.projectRoot,
369
- ready: result.passed && inspection.knowledgeEntries.length > 0,
416
+ // THE doctor settlement (`doctorVerdict`), shared with `shrk check`,
417
+ // the dashboard and MCP: never ready over an unverified scope.
418
+ ready: doctorVerdict(result).ready && inspection.knowledgeEntries.length > 0,
370
419
  strict: strictMode,
371
420
  strictCountedWarnings: strictEval.countedWarnings,
372
421
  strictExcludedWarnings: strictEval.excludedWarnings,
@@ -374,6 +423,7 @@ async function doctorCommandImpl(args) {
374
423
  strictFailed: strictEval.failed,
375
424
  minScoreFailed,
376
425
  exitCode: overallExitCode,
426
+ ...(doctorSettled && doctorSettled.shortfalls.length > 0 ? { shortfalls: doctorSettled.shortfalls } : {}),
377
427
  // Blockers preset state. Shape stays stable when --blockers is off.
378
428
  blockers: blockersOnly
379
429
  ? {
@@ -541,6 +591,11 @@ async function doctorCommandImpl(args) {
541
591
  if (noConfigLenient) {
542
592
  process.stdout.write('\nVerdict: --no-config mode — repo has no sharkcraft/ yet (advisory). Detection works regardless.\n');
543
593
  }
594
+ else if (doctorSettled?.verdict === 'not-verified') {
595
+ const line = verdictLine(doctorSettled, '', 'Verdict: NOT VERIFIED — part of the setup could not be checked.');
596
+ if (line)
597
+ process.stdout.write(`\n${line}\n`);
598
+ }
544
599
  else if (result.passed && hasContent) {
545
600
  process.stdout.write('\nVerdict: Ready for AI-agent use. ✓\n');
546
601
  }
@@ -707,7 +762,7 @@ async function suppressionsListRun(args) {
707
762
  async function suppressionsCheckRun(args) {
708
763
  const cwd = resolveCwd(args);
709
764
  const inspection = await inspectSharkcraft({ cwd });
710
- const result = runDoctor(inspection);
765
+ const result = runDoctor(inspection, { graphDivergence: detectGraphFreshness(cwd) });
711
766
  const cfg = loadDoctorSuppressions(cwd);
712
767
  const filtered = filterDoctorResult(result, { suppressions: cfg.doctorSuppressions });
713
768
  const unused = filtered.appliedSuppressions.filter((a) => a.matched === 0);