@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
@@ -1,19 +1,119 @@
1
1
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
2
  import { join as nodePathJoin, resolve as nodePathResolve } from 'node:path';
3
- import { buildAnchorUpdatePlan, buildKnowledgeStaleReport, buildRenameFilePlan, buildRenameSymbolPlan, inspectSharkcraft, ReferenceCheckOutcome, resolveChangedFiles, } from '@shrkcrft/inspector';
4
- import { ALL_KNOWLEDGE_TYPES, formatEntryCompact, formatEntryFull, isKnowledgeType, projectKnowledgeEntryForJson, searchKnowledge, } from '@shrkcrft/knowledge';
5
- import { flagBool, flagNumber, flagString, flagList, resolveCwd, } from "../command-registry.js";
3
+ import { buildAnchorUpdatePlan, buildKnowledgeRefResolver, buildKnowledgeStaleReport, buildRenameFilePlan, buildRenameSymbolPlan, ContributionKind, describeInspectionDiscovery, inspectSharkcraft, KnowledgeAdvisoryCode, KnowledgeEntryVerdict, ReferenceAssetKind, ReferenceCheckOutcome, resolveChangedFiles, } from '@shrkcrft/inspector';
4
+ import { ALL_KNOWLEDGE_TYPES, formatEntryCompact, formatEntryFull, formatKnowledgeReference, isKnowledgeType, isValidVerifiedOn, parseStaleAfterDays, projectKnowledgeEntryForJson, searchKnowledge, } from '@shrkcrft/knowledge';
5
+ import { writeRejectedEntriesNote } from "../output/rejected-entries-note.js";
6
+ /** Every contribution kind the knowledge loader reads (knowledge, rules, paths, docs). */
7
+ const KNOWLEDGE_FAMILY_KINDS = [
8
+ ContributionKind.Knowledge,
9
+ ContributionKind.Rule,
10
+ ContributionKind.Path,
11
+ ContributionKind.PathConvention,
12
+ ContributionKind.Docs,
13
+ ];
14
+ import { flagBool, flagNumber, flagString, flagList, requireInputSelector, resolveCwd, } from "../command-registry.js";
6
15
  import { asJson, header } from "../output/format-output.js";
7
16
  import { maybeRunInWatchMode } from "../output/watch-loop.js";
8
17
  import { renderFailureHints, staleKnowledgeHints } from "../output/failure-hints.js";
9
- function renderStaleCheckMarkdown(p) {
18
+ import { ExitCode } from "../exit-codes.js";
19
+ import { ALLOW_EMPTY_FLAG, allowEmptyValve } from "../gates/allow-empty.js";
20
+ import { buildGateEnvelope } from "../gates/gate-envelope.js";
21
+ import { verdictLine } from "../gates/verdict-line.js";
22
+ import { evaluateKnowledgeStaleGate, formatPct, KNOWLEDGE_FAIL_ON_CATEGORIES, knowledgeStaleGateInput, knowledgeStaleWindowProblem, parseMinReferenced, } from "../knowledge/knowledge-stale-gate.js";
23
+ /** Unverifiable ids shown in text / markdown before the rest are summarised. */
24
+ const UNVERIFIABLE_SHOWN = 50;
25
+ /**
26
+ * The three buckets, with the unverifiable share — on the line where a bare
27
+ * `0 stale` used to sit, so a corpus checked a quarter of the way can never
28
+ * summarise as healthy.
29
+ */
30
+ function bucketLine(r) {
31
+ const c = r.coverage;
32
+ const pct = c.entriesInScope > 0 ? formatPct(c.unverifiable / c.entriesInScope) : '0%';
33
+ return `entries in scope: ${c.entriesInScope} · verified: ${c.verified} · stale: ${c.stale} · unverifiable: ${c.unverifiable} (${pct})`;
34
+ }
35
+ /** Unverifiable entry ids grouped by the file that declares them — the file to edit. */
36
+ function unverifiableGroups(r) {
37
+ const by = new Map();
38
+ for (const v of r.entryVerdicts) {
39
+ if (v.verdict !== KnowledgeEntryVerdict.Unverifiable)
40
+ continue;
41
+ const list = by.get(v.source) ?? [];
42
+ list.push(v.entryId);
43
+ by.set(v.source, list);
44
+ }
45
+ return [...by.entries()].map(([source, ids]) => ({ source, ids }));
46
+ }
47
+ /** `sharkcraft/rules.ts (7): a, b, …` lines, capped across groups. */
48
+ function unverifiableLines(r, indent) {
49
+ const out = [];
50
+ let shown = 0;
51
+ for (const g of unverifiableGroups(r)) {
52
+ const room = UNVERIFIABLE_SHOWN - shown;
53
+ if (room <= 0)
54
+ break;
55
+ const ids = g.ids.slice(0, room);
56
+ shown += ids.length;
57
+ out.push(`${indent}${g.source} (${g.ids.length}): ${ids.join(', ')}${ids.length < g.ids.length ? ', …' : ''}`);
58
+ }
59
+ const rest = r.unverifiableIds.length - shown;
60
+ if (rest > 0)
61
+ out.push(`${indent}… ${rest} more (--json for all)`);
62
+ return out;
63
+ }
64
+ /** Load failures listed in text / markdown before the rest are summarised. */
65
+ const LOAD_FAILURES_SHOWN = 50;
66
+ /**
67
+ * `LOAD FAILED (N)` — the knowledge-bearing files whose entries never reached
68
+ * the corpus. Printed at ANY corpus size: a clean sweep of the rest is not a
69
+ * verdict over these.
70
+ */
71
+ function loadFailureLines(d, indent) {
72
+ const failed = d.knowledgeLoadFailures;
73
+ if (failed.length === 0)
74
+ return [];
75
+ const out = [
76
+ `LOAD FAILED (${failed.length} of ${Math.max(d.knowledgeFilesAttempted, failed.length)} knowledge files) — their entries were never checked:`,
77
+ ];
78
+ for (const f of failed.slice(0, LOAD_FAILURES_SHOWN)) {
79
+ out.push(`${indent}${f.status.toUpperCase().padEnd(14)}${f.kind.padEnd(10)}${f.file}${f.packName ? ` (pack ${f.packName})` : ''} — ${f.message}`);
80
+ }
81
+ if (failed.length > LOAD_FAILURES_SHOWN)
82
+ out.push(`${indent}… ${failed.length - LOAD_FAILURES_SHOWN} more (--json for all)`);
83
+ out.push('');
84
+ return out;
85
+ }
86
+ /**
87
+ * The per-kind table. A kind the sweep never visited says so in words — a row
88
+ * of zeros cannot tell "clean" from "never looked".
89
+ */
90
+ function kindTableLines(r) {
91
+ const cols = (b) => [b.scanned, b.zeroReferences, b.referencesChecked, b.verified, b.stale, b.unverifiable]
92
+ .map((n, i) => String(n).padStart(i === 0 ? 7 : i === 1 ? 10 : i === 2 ? 5 : i === 3 ? 9 : i === 4 ? 6 : 13))
93
+ .join('');
94
+ const row = (label, b, empty) => b.scanned === 0 ? ` ${label.padEnd(22)}${empty}` : ` ${label.padEnd(22)}${cols(b)}`;
95
+ const lines = [` ${'kind'.padEnd(22)}scanned zero-refs refs verified stale unverifiable`];
96
+ lines.push(row('knowledge', r.byAssetKind[ReferenceAssetKind.Knowledge], 'none in scope'));
97
+ for (const type of Object.keys(r.byEntryType).sort()) {
98
+ lines.push(row(` type:${type}`, r.byEntryType[type], 'none in scope'));
99
+ }
100
+ lines.push(row('boundary-rule', r.byAssetKind[ReferenceAssetKind.BoundaryRule], 'none declared'));
101
+ lines.push(r.policySweep.loaded
102
+ ? row('policy', r.byAssetKind[ReferenceAssetKind.Policy], 'none declared')
103
+ : ` ${'policy'.padEnd(22)}not in sweep (policy registry not loaded)`);
104
+ return lines;
105
+ }
106
+ function refLabel(c) {
107
+ return formatKnowledgeReference(c.reference);
108
+ }
109
+ function renderStaleCheckMarkdown(p, verdict) {
10
110
  const out = [];
11
111
  out.push(`# Knowledge stale-check`);
12
112
  out.push('');
13
- out.push(`- entries: ${p.entries}`);
113
+ out.push(`- ${bucketLine(p)}`);
14
114
  out.push(`- references: ${p.totalReferences}`);
15
115
  out.push(`- anchors: ${p.totalAnchors}`);
16
- out.push(`- counts: ok=${p.counts.ok}, stale=${p.counts.stale}, missing=${p.counts.missing}, unknown=${p.counts.unknown}`);
116
+ out.push(`- counts: ok=${p.counts.ok}, stale=${p.counts.stale}, missing=${p.counts.missing}, unknown=${p.counts.unknown}, invalid=${p.counts.invalid}`);
17
117
  if (p.ci.ci || p.ci.strict || p.ci.failOn.length > 0) {
18
118
  out.push(`- required failing: ${p.ci.totalRequiredFailing} (stale=${p.ci.requiredStale}, missing=${p.ci.requiredMissing})`);
19
119
  }
@@ -21,34 +121,64 @@ function renderStaleCheckMarkdown(p) {
21
121
  out.push(`- baseline (${p.baselineComparison.baseline}): new-stale=${p.baselineComparison.newStale}, new-missing=${p.baselineComparison.newMissing}, resolved=${p.baselineComparison.resolved}`);
22
122
  }
23
123
  out.push('');
124
+ out.push('```');
125
+ for (const line of kindTableLines(p))
126
+ out.push(line);
127
+ out.push('```');
128
+ const loadFailed = loadFailureLines(p.discovery, '- ').filter((l) => l !== '');
129
+ if (loadFailed.length > 0) {
130
+ out.push('');
131
+ out.push(`## ${loadFailed[0]}`);
132
+ for (const line of loadFailed.slice(1))
133
+ out.push(line);
134
+ }
135
+ if (p.coverage.unverifiable > 0) {
136
+ out.push('');
137
+ out.push(`## Unverifiable entries (${p.coverage.unverifiable}) — declare references[]`);
138
+ for (const line of unverifiableLines(p, '- '))
139
+ out.push(line);
140
+ }
141
+ out.push('');
24
142
  out.push(`## Reference issues`);
25
- for (const c of p.referenceChecks) {
143
+ for (const c of [...p.referenceChecks, ...p.assetReferenceChecks]) {
26
144
  if (c.outcome === 'ok')
27
145
  continue;
28
146
  const req = c.reference.required ? ' **(required)**' : '';
29
- out.push(`- **${c.outcome.toUpperCase()}**${req} \`${c.entryId}\` \`${c.reference.kind}:${c.reference.id ?? c.reference.path ?? c.reference.symbol ?? '?'}\` — ${c.message}`);
30
- }
31
- if (p.ci.exitNonZero && p.ci.exitReason) {
32
- out.push('');
33
- out.push(`> FAIL: ${p.ci.exitReason}`);
147
+ const kind = c.assetKind ? ` [${c.implicit ? 'implicit ' : ''}${c.assetKind}]` : '';
148
+ out.push(`- **${c.outcome.toUpperCase()}**${req}${kind} \`${c.entryId}\` → \`${refLabel(c)}\` — ${c.message}`);
34
149
  }
35
150
  out.push('');
151
+ for (const line of verdict.split('\n'))
152
+ out.push(`> ${line}`);
153
+ out.push('');
36
154
  return out.join('\n');
37
155
  }
38
- function renderStaleCheckHtml(p) {
156
+ function renderStaleCheckHtml(p, verdict) {
39
157
  const esc = (s) => s.replace(/[&<>"']/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c]));
40
158
  const rows = [];
41
- for (const c of p.referenceChecks) {
159
+ for (const c of [...p.referenceChecks, ...p.assetReferenceChecks]) {
42
160
  if (c.outcome === 'ok')
43
161
  continue;
44
- rows.push(`<tr><td>${esc(c.outcome.toUpperCase())}</td><td>${c.reference.required ? '✓' : ''}</td><td>${esc(c.entryId)}</td><td>${esc(c.reference.kind)}:${esc(c.reference.id ?? c.reference.path ?? c.reference.symbol ?? '?')}</td><td>${esc(c.message)}</td></tr>`);
162
+ rows.push(`<tr><td>${esc(c.outcome.toUpperCase())}</td><td>${c.reference.required ? '✓' : ''}</td><td>${esc(c.entryId)}</td><td>${esc(refLabel(c))}</td><td>${esc(c.message)}</td></tr>`);
45
163
  }
164
+ const unverifiable = unverifiableLines(p, '').map((l) => `<li>${esc(l)}</li>`).join('');
165
+ const loadFailedLines = loadFailureLines(p.discovery, '').filter((l) => l !== '');
166
+ const loadFailed = loadFailedLines.length > 0
167
+ ? `<h2>${esc(loadFailedLines[0])}</h2><ul>${loadFailedLines
168
+ .slice(1)
169
+ .map((l) => `<li>${esc(l)}</li>`)
170
+ .join('')}</ul>`
171
+ : '';
46
172
  return `<!doctype html><meta charset="utf-8"><title>Knowledge stale-check</title>
47
173
  <style>body{font:14px/1.4 sans-serif;margin:1rem}table{border-collapse:collapse;width:100%}td,th{border:1px solid #ccc;padding:.25rem .5rem;text-align:left}h1{margin-top:0}</style>
48
174
  <h1>Knowledge stale-check</h1>
49
- <p>entries=${p.entries}, references=${p.totalReferences}, anchors=${p.totalAnchors}, ok=${p.counts.ok}, stale=${p.counts.stale}, missing=${p.counts.missing}, unknown=${p.counts.unknown}</p>
175
+ <p>${esc(bucketLine(p))}</p>
176
+ <p>references=${p.totalReferences}, anchors=${p.totalAnchors}, ok=${p.counts.ok}, stale=${p.counts.stale}, missing=${p.counts.missing}, unknown=${p.counts.unknown}, invalid=${p.counts.invalid}</p>
177
+ <pre>${esc(kindTableLines(p).join('\n'))}</pre>
178
+ ${loadFailed}
179
+ ${unverifiable ? `<h2>Unverifiable entries (${p.coverage.unverifiable})</h2><ul>${unverifiable}</ul>` : ''}
50
180
  <table><thead><tr><th>Outcome</th><th>Required</th><th>Entry</th><th>Reference</th><th>Message</th></tr></thead><tbody>${rows.join('')}</tbody></table>
51
- ${p.ci.exitNonZero ? `<p style="color:#a40000;font-weight:bold">FAIL: ${esc(p.ci.exitReason ?? '')}</p>` : ''}
181
+ <p style="font-weight:bold${p.exitCode === 0 ? '' : ';color:#a40000'}">${esc(verdict).replace(/\n/g, '<br>')}</p>
52
182
  `;
53
183
  }
54
184
  /**
@@ -106,22 +236,43 @@ export const knowledgeListCommand = {
106
236
  // and would strip pack entries whose fields are getters/non-enumerable.
107
237
  entries.map(projectKnowledgeEntryForJson);
108
238
  process.stdout.write(asJson(payload) + '\n');
239
+ await writeRejectedEntriesNote(inspection, KNOWLEDGE_FAMILY_KINDS, { json: true, next: 'shrk doctor' });
109
240
  return 0;
110
241
  }
242
+ if (inspection.knowledgeEntries.length === 0) {
243
+ // A query, not a gate — the exit stays 0 — but an empty corpus is almost
244
+ // always a wrong root, so say where discovery landed (as `knowledge lint`).
245
+ const d = describeInspectionDiscovery(inspection, resolveCwd(args));
246
+ process.stderr.write(`WARN loaded 0 knowledge entries from ${d.resolvedRoot} (sharkcraft/ folder: ${d.sharkcraftDir ?? 'missing'}` +
247
+ `${d.configError !== undefined ? `; config failed to load — ${d.configError}` : ''}).` +
248
+ `${d.configuredAncestor ? ` A configured ancestor exists: rerun with --cwd ${d.configuredAncestor}.` : ''}\n`);
249
+ }
250
+ // A knowledge file that never loaded makes the list PARTIAL — say which.
251
+ const failedLoads = describeInspectionDiscovery(inspection, resolveCwd(args)).knowledgeLoadFailures;
252
+ if (failedLoads.length > 0) {
253
+ process.stderr.write(`WARN ${failedLoads.length} knowledge file(s) never loaded — this list is partial: ${failedLoads
254
+ .map((f) => `${f.file} (${f.status})`)
255
+ .join(', ')}. Run \`shrk doctor\` for the error.\n`);
256
+ }
111
257
  process.stdout.write(header(`Knowledge (${entries.length})`));
112
258
  for (const e of entries)
113
259
  process.stdout.write(formatEntryCompact(e) + '\n');
260
+ // An array member meant as an entry that the loader refused (no `content`,
261
+ // a reused id) is named (round 12, 12.1) — it used to vanish silently.
262
+ // Load failures are the partial-list WARN above — never said twice.
263
+ await writeRejectedEntriesNote(inspection, KNOWLEDGE_FAMILY_KINDS, { next: 'shrk doctor', loadFailures: false });
114
264
  return 0;
115
265
  },
116
266
  };
117
267
  export const knowledgeGetCommand = {
118
268
  name: 'get',
119
- description: 'Show full content of one knowledge entry.',
120
- usage: 'shrk knowledge get <id> [--json]',
269
+ description: 'Show full content of one knowledge entry. A superseded entry opens with a banner naming its successor (resolved, with its title); `--follow` renders the current entry after it. Cross-reference ids print with the namespace they resolve into.',
270
+ usage: 'shrk knowledge get <id> [--follow] [--json]',
271
+ booleanFlags: new Set(['follow', 'json']),
121
272
  async run(args) {
122
273
  const id = args.positional[0];
123
274
  if (!id) {
124
- process.stderr.write('Usage: shrk knowledge get <id>\n');
275
+ process.stderr.write('Usage: shrk knowledge get <id> [--follow] [--json]\n');
125
276
  return 2;
126
277
  }
127
278
  const inspection = await inspectSharkcraft({ cwd: resolveCwd(args) });
@@ -134,15 +285,69 @@ export const knowledgeGetCommand = {
134
285
  process.stdout.write(asJson(entry) + '\n');
135
286
  return 0;
136
287
  }
137
- process.stdout.write(formatEntryFull(entry) + '\n');
288
+ // Warm first: a construct / playbook id is otherwise NOT VERIFIED, and a
289
+ // successor must be named with the registry that actually holds it.
290
+ await (await import("../surface/cli-command-resolver.js")).warmCliReferenceRegistries(inspection);
291
+ const resolveRef = buildKnowledgeRefResolver(inspection);
292
+ process.stdout.write(formatEntryFull(entry, { resolveRef }) + '\n');
293
+ if (flagBool(args, 'follow')) {
294
+ const followed = followSupersession(inspection.index, entry, inspection.knowledgeEntries.length);
295
+ if (followed.terminal) {
296
+ process.stdout.write(`\n--- following supersededBy: ${followed.path.join(' → ')} ---\n\n`);
297
+ process.stdout.write(formatEntryFull(followed.terminal, { resolveRef }) + '\n');
298
+ }
299
+ else {
300
+ process.stderr.write(`--follow: ${followed.reason}\n`);
301
+ }
302
+ }
138
303
  return 0;
139
304
  },
140
305
  };
306
+ /**
307
+ * Walk `supersededBy` from `entry` to the ONE current entry, cycle-safe and
308
+ * bounded by the corpus size. Refuses (with the reason) on a fork, a successor
309
+ * that is not a knowledge entry, or a cycle — never guesses which branch.
310
+ */
311
+ function followSupersession(index, entry, bound) {
312
+ const path = [entry.id];
313
+ const seen = new Set(path);
314
+ let cur = entry;
315
+ for (let step = 0; step <= bound; step += 1) {
316
+ const next = (cur.supersededBy ?? []).filter((s) => typeof s === 'string' && s.length > 0);
317
+ if (next.length === 0) {
318
+ return path.length > 1
319
+ ? { terminal: cur, path }
320
+ : { path, reason: `"${entry.id}" is not superseded — nothing to follow.` };
321
+ }
322
+ if (next.length > 1) {
323
+ return { path, reason: `"${cur.id}" names ${next.length} successors (${next.join(', ')}) — pick one: shrk knowledge get <id>` };
324
+ }
325
+ const successor = index.get(next[0] ?? '');
326
+ if (!successor)
327
+ return { path, reason: `successor "${next[0]}" of "${cur.id}" is not a knowledge entry.` };
328
+ if (seen.has(successor.id)) {
329
+ return { path: [...path, successor.id], reason: `supersededBy forms a cycle (${[...path, successor.id].join(' → ')}) — no entry in it is current.` };
330
+ }
331
+ seen.add(successor.id);
332
+ path.push(successor.id);
333
+ cur = successor;
334
+ }
335
+ return { path, reason: 'the supersededBy chain is longer than the corpus.' };
336
+ }
141
337
  export const knowledgeSearchCommand = {
142
338
  name: 'search',
143
339
  description: 'Search knowledge by query.',
144
340
  usage: 'shrk knowledge search <query> [--type x,y] [--scope x,y] [--limit 10] [--json]',
145
341
  async run(args) {
342
+ // No query and no filter is "you gave me nothing to search" — a usage
343
+ // error (3), never `Results (0)` at exit 0 (round 11 §1.2#5).
344
+ const noSelector = requireInputSelector(args, {
345
+ flags: ['type', 'scope', 'tag', 'appliesWhen'],
346
+ positional: true,
347
+ usage: 'shrk knowledge search <query> [--type x,y] [--scope x,y] [--limit 10] [--json]',
348
+ });
349
+ if (noSelector !== null)
350
+ return noSelector;
146
351
  const query = args.positional.join(' ').trim();
147
352
  const inspection = await inspectSharkcraft({ cwd: resolveCwd(args) });
148
353
  const types = flagList(args, 'type');
@@ -191,33 +396,126 @@ function readChangedScopeOptionsForKnowledge(args, projectRoot) {
191
396
  includeWorktree: changedOnly || !since,
192
397
  };
193
398
  }
399
+ /** Boolean flags of the stale-check — none of them may swallow a following token. */
400
+ const STALE_CHECK_BOOLEAN_FLAGS = new Set([
401
+ 'json',
402
+ 'ci',
403
+ 'strict',
404
+ 'report',
405
+ 'changed-only',
406
+ 'staged',
407
+ 'watch',
408
+ 'once',
409
+ 'require-references',
410
+ ALLOW_EMPTY_FLAG,
411
+ ]);
412
+ const STALE_CHECK_USAGE = 'shrk knowledge stale-check [--changed-only|--since <ref>|--staged|--files a,b,c] [--ci] [--strict] [--fail-on <category,...>] [--min-referenced <ratio|NN%>] [--require-references] [--allow-empty] [--stale-after <Nd|Nw|Nm|Ny> [--as-of YYYY-MM-DD]] [--baseline <file>] [--report] [--format text|markdown|html|json] [--output <path>] [--json] [--watch [--once] [--debounce N]]';
194
413
  export const knowledgeStaleCheckCommand = {
195
414
  name: 'stale-check',
196
- description: 'Validate `references[]` + `anchors[]` on each knowledge entry against the workspace. CI flags and `--watch [--once] [--debounce N]` supported. Read-only.',
197
- usage: 'shrk knowledge stale-check [--changed-only|--since <ref>|--staged|--files a,b,c] [--ci] [--strict] [--fail-on required|stale|missing|all] [--baseline <file>] [--report] [--format text|markdown|html|json] [--output <path>] [--json] [--watch [--once] [--debounce N]]',
415
+ description: 'Verify every knowledge entry against the workspace in three buckets — verified / stale / UNVERIFIABLE (no checkable reference). Strict by default: any unverifiable entry keeps the run at exit 2 unless accepted (--min-referenced). CI flags and `--watch [--once] [--debounce N]` supported. Read-only.',
416
+ usage: STALE_CHECK_USAGE,
417
+ booleanFlags: STALE_CHECK_BOOLEAN_FLAGS,
198
418
  async run(args) {
199
- const watchExit = await maybeRunInWatchMode(args, knowledgeStaleCheckImpl);
200
- if (watchExit !== null)
201
- return watchExit;
202
- return knowledgeStaleCheckImpl(args);
419
+ return runStaleCheck(args, 'knowledge stale-check');
203
420
  },
204
421
  };
205
- async function knowledgeStaleCheckImpl(args) {
422
+ async function runStaleCheck(args, verb) {
423
+ const impl = (a) => knowledgeStaleCheckImpl(a, verb);
424
+ const watchExit = await maybeRunInWatchMode(args, impl);
425
+ if (watchExit !== null)
426
+ return watchExit;
427
+ return impl(args);
428
+ }
429
+ /** A malformed invocation: `3` (the gate never started) with the usage line. */
430
+ function staleCheckUsageError(message) {
431
+ process.stderr.write(`${message}\nUsage: ${STALE_CHECK_USAGE}\n`);
432
+ return ExitCode.UsageError;
433
+ }
434
+ async function knowledgeStaleCheckImpl(args, verb) {
206
435
  const cwd = resolveCwd(args);
436
+ // ── Validate the request first: a bad flag value is `3`, never a verdict. ──
437
+ const failOnFlag = args.flags.get('fail-on');
438
+ if (failOnFlag === true) {
439
+ return staleCheckUsageError(`--fail-on needs a value: ${KNOWLEDGE_FAIL_ON_CATEGORIES.join(', ')}.`);
440
+ }
441
+ const failOnList = (typeof failOnFlag === 'string' ? failOnFlag : '')
442
+ .toLowerCase()
443
+ .split(',')
444
+ .map((s) => s.trim())
445
+ .filter(Boolean);
446
+ const unknownFailOn = failOnList.filter((c) => !KNOWLEDGE_FAIL_ON_CATEGORIES.includes(c));
447
+ if (unknownFailOn.length > 0) {
448
+ return staleCheckUsageError(`Unknown --fail-on value(s): ${unknownFailOn.join(', ')}. Valid: ${KNOWLEDGE_FAIL_ON_CATEGORIES.join(', ')}.`);
449
+ }
450
+ const minFlag = args.flags.get('min-referenced');
451
+ let minReferenced;
452
+ if (minFlag !== undefined) {
453
+ const ratio = typeof minFlag === 'string' ? parseMinReferenced(minFlag) : null;
454
+ if (ratio === null) {
455
+ return staleCheckUsageError(`--min-referenced takes a ratio 0..1 or a percentage (0.8, 80%) — got ${JSON.stringify(minFlag)}.`);
456
+ }
457
+ minReferenced = { ratio, acceptedBy: `--min-referenced ${minFlag}` };
458
+ }
459
+ const staleAfterFlag = args.flags.get('stale-after');
460
+ let staleAfterDays;
461
+ if (staleAfterFlag !== undefined) {
462
+ const days = typeof staleAfterFlag === 'string' ? parseStaleAfterDays(staleAfterFlag) : null;
463
+ if (days === null) {
464
+ return staleCheckUsageError(`--stale-after takes a duration such as 90d, 12w, 6m or 1y — got ${JSON.stringify(staleAfterFlag)}.`);
465
+ }
466
+ staleAfterDays = days;
467
+ }
468
+ const asOfFlag = args.flags.get('as-of');
469
+ if (asOfFlag !== undefined && (typeof asOfFlag !== 'string' || !isValidVerifiedOn(asOfFlag))) {
470
+ return staleCheckUsageError(`--as-of takes a date written YYYY-MM-DD — got ${JSON.stringify(asOfFlag)}.`);
471
+ }
472
+ const asOf = typeof asOfFlag === 'string' ? asOfFlag : undefined;
473
+ // A category that can never fire is a malformed request (the `--fail-on
474
+ // bogus` class): `aged` / `--as-of` measure against a --stale-after window.
475
+ // (The same check runs again below over `knowledgeCheck.failOn`.)
476
+ const windowProblem = knowledgeStaleWindowProblem(new Set(failOnList), false, staleAfterDays, asOf);
477
+ if (windowProblem)
478
+ return staleCheckUsageError(windowProblem);
207
479
  const inspection = await inspectSharkcraft({ cwd });
480
+ // `command` references resolve against the live command index — injected
481
+ // here; without it they are NOT VERIFIED (never "Command available").
482
+ // The same call warms every async-filled registry (playbook / policy /
483
+ // construct / helper) before anything resolves.
484
+ await (await import("../surface/cli-command-resolver.js")).warmCliReferenceRegistries(inspection);
208
485
  const scopeOpts = readChangedScopeOptionsForKnowledge(args, cwd);
209
486
  const changedFiles = scopeOpts ? resolveChangedFiles(scopeOpts).files : undefined;
210
487
  const report = buildKnowledgeStaleReport(inspection, {
211
488
  ...(changedFiles ? { changedFiles } : {}),
489
+ ...(staleAfterDays !== undefined ? { staleAfterDays } : {}),
490
+ ...(asOf ? { asOf } : {}),
212
491
  });
213
- // CI/preflight flags.
214
- const ci = flagBool(args, 'ci');
215
- const strict = flagBool(args, 'strict');
216
- const failOnRaw = (flagString(args, 'fail-on') ?? '').toLowerCase();
217
- const failOn = new Set(failOnRaw
218
- .split(',')
219
- .map((s) => s.trim())
220
- .filter(Boolean));
492
+ // CI/preflight flags, folded over the config's `knowledgeCheck` block by
493
+ // THE input builder — `shrk quality` and release readiness build theirs
494
+ // there too, so a config-only request is one verdict on all three.
495
+ const discovery = describeInspectionDiscovery(inspection, cwd);
496
+ const gateInput = knowledgeStaleGateInput({
497
+ flags: {
498
+ ci: flagBool(args, 'ci'),
499
+ strict: flagBool(args, 'strict'),
500
+ failOn: failOnList,
501
+ ...(minReferenced ? { minReferenced } : {}),
502
+ requireReferences: flagBool(args, 'require-references'),
503
+ emptyAcceptance: allowEmptyValve(args, report.coverage.entriesInScope),
504
+ ...(staleAfterDays !== undefined ? { staleAfterDays } : {}),
505
+ ...(asOf ? { asOf } : {}),
506
+ },
507
+ knowledgeCheck: inspection.config?.knowledgeCheck,
508
+ discovery,
509
+ scoped: changedFiles !== undefined,
510
+ });
511
+ // `knowledgeCheck.failOn: ['aged']` with no --stale-after window: a
512
+ // category that can never fire is a malformed request, never a verdict.
513
+ if (gateInput.usageProblem)
514
+ return staleCheckUsageError(gateInput.usageProblem);
515
+ const ci = gateInput.ci;
516
+ const strict = gateInput.strict;
517
+ const effectiveFailOn = [...gateInput.failOn];
518
+ const requireReferences = gateInput.requireReferences;
221
519
  const baselineFile = flagString(args, 'baseline');
222
520
  const wantReport = flagBool(args, 'report');
223
521
  const formatRaw = (flagString(args, 'format') ?? '').toLowerCase();
@@ -225,58 +523,26 @@ async function knowledgeStaleCheckImpl(args) {
225
523
  const wantMarkdown = formatRaw === 'markdown' || formatRaw === 'md';
226
524
  const wantHtml = formatRaw === 'html';
227
525
  const output = flagString(args, 'output');
228
- // Required-reference computation. A reference is "required" when its
229
- // `required: true` (default false). Stale + missing are the same outcome
230
- // family.
231
- let requiredStale = 0;
232
- let requiredMissing = 0;
233
- for (const c of report.referenceChecks) {
234
- const isRequired = c.reference.required === true;
235
- if (isRequired && c.outcome === ReferenceCheckOutcome.Stale)
236
- requiredStale++;
237
- if (isRequired && c.outcome === ReferenceCheckOutcome.Missing)
238
- requiredMissing++;
239
- }
526
+ // ── Settle first, render second. ──
527
+ const gate = evaluateKnowledgeStaleGate(report, gateInput);
528
+ const env = buildGateEnvelope(verb, gate.proposed, gate.rules, gate.runCoverage);
529
+ const exit = env.exit;
530
+ const { verified, entriesInScope } = report.coverage;
531
+ // Round 13: the line never contradicts a STALE row printed above it — a
532
+ // failing reference this mode waives (`required: false` under --ci, …) is
533
+ // named here and printed as an acceptance below it.
534
+ const entriesVerified = `${verified} of ${entriesInScope} knowledge ${entriesInScope === 1 ? 'entry' : 'entries'} verified`;
535
+ const verdict = verdictLine(env, gate.waived > 0
536
+ ? `${entriesVerified} — ${gate.waived} failing reference(s) listed above do not block this mode (accepted below). ✓`
537
+ : `${entriesVerified} — no stale or missing references. ✓`, exit === ExitCode.NotVerified ? gate.notVerifiedLead : undefined);
538
+ const requiredStale = gate.requiredStale;
539
+ const requiredMissing = gate.requiredMissing;
240
540
  const totalRequiredFailing = requiredStale + requiredMissing;
241
- // Decide exit code.
242
- let exitNonZero = false;
243
- let exitReason;
244
- const considerFailOn = (cat) => failOn.has(cat) || failOn.has('all');
245
- if (ci) {
246
- // CI mode — required failing refs are blocking. Optional refs warn only.
247
- if (totalRequiredFailing > 0) {
248
- exitNonZero = true;
249
- exitReason = `${totalRequiredFailing} required references failing in --ci mode`;
250
- }
251
- }
252
- else if (strict) {
253
- // Strict — any stale/missing required ref fails. Same as CI essentially.
254
- if (totalRequiredFailing > 0) {
255
- exitNonZero = true;
256
- exitReason = `${totalRequiredFailing} required references failing in --strict mode`;
257
- }
258
- }
259
- else if (failOn.size > 0) {
260
- if (considerFailOn('required') && totalRequiredFailing > 0) {
261
- exitNonZero = true;
262
- exitReason = `${totalRequiredFailing} required reference issues (--fail-on=required)`;
263
- }
264
- if (considerFailOn('stale') && report.counts.stale > 0) {
265
- exitNonZero = true;
266
- exitReason = `${report.counts.stale} stale references (--fail-on=stale)`;
267
- }
268
- if (considerFailOn('missing') && report.counts.missing > 0) {
269
- exitNonZero = true;
270
- exitReason = `${report.counts.missing} missing references (--fail-on=missing)`;
271
- }
272
- }
273
- else {
274
- // Default — non-CI: only the legacy "any missing or stale" condition fails.
275
- if (report.counts.missing + report.counts.stale > 0) {
276
- exitNonZero = true;
277
- exitReason = `${report.counts.missing + report.counts.stale} stale or missing references (legacy default)`;
278
- }
279
- }
541
+ const exitReason = gate.reasons.length > 0
542
+ ? gate.reasons.join('; ')
543
+ : exit === ExitCode.NotVerified
544
+ ? `not verified ${env.shortfalls[0] ?? 'nothing was proved'}`
545
+ : undefined;
280
546
  // Baseline comparison (informational).
281
547
  let baselineComparison;
282
548
  if (baselineFile) {
@@ -335,14 +601,20 @@ async function knowledgeStaleCheckImpl(args) {
335
601
  ci: {
336
602
  ci,
337
603
  strict,
338
- failOn: [...failOn],
604
+ // The EFFECTIVE categories (a --fail-on flag, else knowledgeCheck.failOn).
605
+ failOn: effectiveFailOn,
339
606
  requiredStale,
340
607
  requiredMissing,
341
608
  totalRequiredFailing,
342
- exitNonZero,
343
- exitReason,
609
+ exitNonZero: exit !== ExitCode.VerifiedPass,
610
+ ...(exitReason ? { exitReason } : {}),
611
+ ...(gateInput.minReferenced ? { minReferenced: gateInput.minReferenced.ratio } : {}),
612
+ requireReferences,
344
613
  },
345
- baselineComparison,
614
+ ...(baselineComparison ? { baselineComparison } : {}),
615
+ discovery,
616
+ exitCode: exit,
617
+ gate: env,
346
618
  };
347
619
  // Optional report file.
348
620
  if (wantReport || output) {
@@ -358,59 +630,125 @@ async function knowledgeStaleCheckImpl(args) {
358
630
  process.stdout.write(`Wrote report → ${outPath}\n`);
359
631
  }
360
632
  }
361
- // Format-specific output.
633
+ // Format-specific output — every format returns the SETTLED exit.
362
634
  if (wantJson) {
363
635
  process.stdout.write(asJson(ciPayload) + '\n');
364
- return exitNonZero ? 1 : 0;
636
+ return exit;
365
637
  }
366
638
  if (wantMarkdown) {
367
- process.stdout.write(renderStaleCheckMarkdown(ciPayload));
368
- return exitNonZero ? 1 : 0;
639
+ process.stdout.write(renderStaleCheckMarkdown(ciPayload, verdict));
640
+ return exit;
369
641
  }
370
642
  if (wantHtml) {
371
- process.stdout.write(renderStaleCheckHtml(ciPayload));
372
- return exitNonZero ? 1 : 0;
373
- }
374
- // Default text output.
375
- process.stdout.write(header('Knowledge stale-check'));
376
- process.stdout.write(`entries=${report.entries} references=${report.totalReferences} anchors=${report.totalAnchors}\n`);
377
- process.stdout.write(`ok=${report.counts.ok} stale=${report.counts.stale} missing=${report.counts.missing} unknown=${report.counts.unknown}\n`);
378
- if (ci || strict || failOn.size > 0) {
379
- process.stdout.write(`required: stale=${requiredStale} missing=${requiredMissing} (total failing: ${totalRequiredFailing})\n`);
380
- }
381
- if (baselineComparison) {
382
- process.stdout.write(`baseline: new-stale=${baselineComparison.newStale} new-missing=${baselineComparison.newMissing} resolved=${baselineComparison.resolved}\n`);
383
- }
384
- process.stdout.write('\n');
385
- for (const c of report.referenceChecks) {
386
- if (c.outcome === ReferenceCheckOutcome.Ok)
387
- continue;
388
- const tag = c.outcome.toUpperCase().padEnd(7);
643
+ process.stdout.write(renderStaleCheckHtml(ciPayload, verdict));
644
+ return exit;
645
+ }
646
+ writeStaleCheckText(ciPayload, {
647
+ verdict,
648
+ reasons: gate.reasons,
649
+ showRequired: ci || strict || effectiveFailOn.length > 0,
650
+ allowEmptyHint: exit === ExitCode.NotVerified && entriesInScope === 0 && !gate.discoveryFailed,
651
+ });
652
+ return exit;
653
+ }
654
+ /** Advisories printed in text before the rest are summarised. */
655
+ const ADVISORIES_SHOWN = 20;
656
+ /** Aged entries printed in text before the rest are summarised. */
657
+ const AGED_SHOWN = 50;
658
+ function writeStaleCheckText(p, o) {
659
+ const w = (s) => void process.stdout.write(s);
660
+ w(header('Knowledge stale-check'));
661
+ const d = p.discovery;
662
+ if (d.entriesLoaded === 0) {
663
+ // Name where discovery landed, so a wrong root is visible on the screen
664
+ // that refuses to pass.
665
+ w('Loaded 0 knowledge entries.\n');
666
+ w(` resolved root: ${d.resolvedRoot}${d.rootMarkers.length > 0 ? ` (${d.rootMarkers.join(', ')})` : ' (no root marker)'}\n`);
667
+ w(` sharkcraft/ folder: ${d.sharkcraftDir ?? 'missing'}\n`);
668
+ w(` config: ${d.configError !== undefined ? `failed to load — ${d.configError}` : (d.configFile ?? '(none)')}\n`);
669
+ if (d.configuredAncestor) {
670
+ w(` configured ancestor: ${d.configuredAncestor} — rerun with --cwd ${d.configuredAncestor}\n`);
671
+ }
672
+ w('\n');
673
+ }
674
+ for (const line of loadFailureLines(d, ' '))
675
+ w(`${line}\n`);
676
+ w(`${bucketLine(p)}\n`);
677
+ w(`references: ${p.totalReferences} · anchors: ${p.totalAnchors} · ok=${p.counts.ok} stale=${p.counts.stale} missing=${p.counts.missing} unknown=${p.counts.unknown} invalid=${p.counts.invalid}\n`);
678
+ const failures = Object.entries(p.failureCounts).filter(([, n]) => n > 0);
679
+ if (failures.length > 0)
680
+ w(`failures: ${failures.map(([k, n]) => `${k}=${n}`).join(' ')}\n`);
681
+ if (p.entriesInScope !== p.entries) {
682
+ w(`scope: ${p.entriesInScope} of ${p.entries} entries reference the changed files\n`);
683
+ }
684
+ if (o.showRequired) {
685
+ w(`required: stale=${p.ci.requiredStale} missing=${p.ci.requiredMissing} (total failing: ${p.ci.totalRequiredFailing})\n`);
686
+ }
687
+ if (p.baselineComparison) {
688
+ w(`baseline: new-stale=${p.baselineComparison.newStale} new-missing=${p.baselineComparison.newMissing} resolved=${p.baselineComparison.resolved}\n`);
689
+ }
690
+ if (p.age) {
691
+ w(`verifiedOn: ${p.age.aged.length} older than ${p.age.staleAfterDays}d, ${p.age.neverVerified.length} never verified (as of ${p.age.asOf})\n`);
692
+ }
693
+ w('\n');
694
+ for (const line of kindTableLines(p))
695
+ w(`${line}\n`);
696
+ if (p.coverage.unverifiable > 0) {
697
+ w(`\nUNVERIFIABLE (${p.coverage.unverifiable}) — never checked; declare references[] (or anchors[]):\n`);
698
+ for (const line of unverifiableLines(p, ' '))
699
+ w(`${line}\n`);
700
+ }
701
+ const issues = [...p.referenceChecks, ...p.assetReferenceChecks].filter((c) => c.outcome !== ReferenceCheckOutcome.Ok);
702
+ const badAnchors = p.anchorChecks.filter((c) => c.outcome !== ReferenceCheckOutcome.Ok);
703
+ if (issues.length + badAnchors.length > 0)
704
+ w('\n');
705
+ for (const c of issues) {
706
+ const tag = (c.implicit ? 'IMPLICIT' : c.outcome.toUpperCase()).padEnd(8);
389
707
  const req = c.reference.required === true ? '[REQ] ' : ' ';
390
- process.stdout.write(` ${tag} ${req}${c.entryId} ${c.reference.kind}:${c.reference.id ?? c.reference.path ?? c.reference.symbol ?? '?'} — ${c.message}\n`);
708
+ const kind = c.assetKind ? `[${c.assetKind}] ` : '';
709
+ w(` ${tag}${req}${kind}${c.entryId} → ${formatKnowledgeReference(c.reference)} — ${c.message}\n`);
710
+ if (c.expected !== undefined || c.actual !== undefined) {
711
+ w(` expected: ${String(c.expected ?? '?')} · actual: ${String(c.actual ?? '?')}\n`);
712
+ }
391
713
  if (c.suggestion)
392
- process.stdout.write(` ↳ ${c.suggestion}\n`);
714
+ w(` ↳ ${c.suggestion}\n`);
393
715
  }
394
- for (const c of report.anchorChecks) {
395
- if (c.outcome === ReferenceCheckOutcome.Ok)
396
- continue;
397
- const tag = c.outcome.toUpperCase().padEnd(7);
398
- process.stdout.write(` ${tag} ${c.entryId} anchor[${c.anchor.id}] (${c.anchor.kind}) ${c.message}\n`);
716
+ for (const c of badAnchors) {
717
+ w(` ${c.outcome.toUpperCase().padEnd(8)}${c.entryId} anchor[${c.anchor.id}] (${c.anchor.kind}) — ${c.message}\n`);
718
+ }
719
+ // Implicit boundary references were listed with the issues above.
720
+ const advisories = p.advisories.filter((a) => a.code !== KnowledgeAdvisoryCode.ImplicitPathMissing);
721
+ if (advisories.length > 0) {
722
+ w(`\nAdvisories (${advisories.length}) — reported, never gating:\n`);
723
+ for (const a of advisories.slice(0, ADVISORIES_SHOWN))
724
+ w(` ${a.code} ${a.subjectId} — ${a.message}\n`);
725
+ if (advisories.length > ADVISORIES_SHOWN) {
726
+ w(` … ${advisories.length - ADVISORIES_SHOWN} more (--json for all)\n`);
727
+ }
399
728
  }
400
- if (exitNonZero && exitReason) {
401
- process.stdout.write(`\nFAIL: ${exitReason}\n`);
729
+ if (p.age && p.age.aged.length > 0) {
730
+ w(`\nAged — not verified within ${p.age.staleAfterDays}d (oldest first):\n`);
731
+ for (const a of p.age.aged.slice(0, AGED_SHOWN)) {
732
+ w(` ${a.entryId} verifiedOn ${a.verifiedOn} (${a.ageDays}d) ${a.source}\n`);
733
+ }
734
+ if (p.age.aged.length > AGED_SHOWN)
735
+ w(` … ${p.age.aged.length - AGED_SHOWN} more (--json for all)\n`);
402
736
  }
403
- if (exitNonZero) {
404
- process.stdout.write(renderFailureHints(staleKnowledgeHints()));
737
+ if (o.reasons.length > 0) {
738
+ w(`\nFAIL: ${o.reasons.join('; ')}\n`);
739
+ w(renderFailureHints(staleKnowledgeHints()));
405
740
  }
406
- return exitNonZero ? 1 : 0;
741
+ if (o.allowEmptyHint)
742
+ w('\nPass --allow-empty to accept an empty scope explicitly.\n');
743
+ w(`\n${o.verdict}\n`);
407
744
  }
408
745
  export const knowledgeVerifyCommand = {
409
746
  name: 'verify',
410
- description: 'Alias for `knowledge stale-check`. Read-only.',
411
- usage: 'shrk knowledge verify [--changed-only|--since|--staged|--files] [--json]',
747
+ description: 'Alias for `knowledge stale-check` — the same three-bucket verdict, flags and exit codes. Read-only.',
748
+ usage: STALE_CHECK_USAGE.replace('knowledge stale-check', 'knowledge verify'),
749
+ booleanFlags: STALE_CHECK_BOOLEAN_FLAGS,
412
750
  run(args) {
413
- return knowledgeStaleCheckCommand.run(args);
751
+ return runStaleCheck(args, 'knowledge verify');
414
752
  },
415
753
  };
416
754
  export const knowledgeReferencesCommand = {
@@ -447,7 +785,9 @@ export const knowledgeReferencesCommand = {
447
785
  if (data.references.length > 0) {
448
786
  process.stdout.write(`References (${data.references.length}):\n`);
449
787
  for (const r of data.references) {
450
- const target = r.id ?? r.path ?? r.symbol ?? r.command ?? '?';
788
+ // One grammar: a pinned symbol renders `Name@path` (it used to render
789
+ // as its path, hiding the symbol it pins).
790
+ const target = formatKnowledgeReference(r).slice(r.kind.length + 1);
451
791
  process.stdout.write(` • ${r.kind}: ${target}${r.required ? ' [required]' : ''}\n`);
452
792
  }
453
793
  }