@shrkcrft/inspector 0.1.0-alpha.30 → 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 (693) hide show
  1. package/dist/acceptance-replay.js +1 -1
  2. package/dist/agent-contract-templates.js +6 -6
  3. package/dist/agent-contract.d.ts.map +1 -1
  4. package/dist/agent-contract.js +13 -8
  5. package/dist/agent-orchestration.js +2 -2
  6. package/dist/agent-task-prep.d.ts +16 -0
  7. package/dist/agent-task-prep.d.ts.map +1 -1
  8. package/dist/agent-task-prep.js +51 -4
  9. package/dist/ai-readiness.d.ts.map +1 -1
  10. package/dist/ai-readiness.js +21 -3
  11. package/dist/architecture-map.d.ts +16 -0
  12. package/dist/architecture-map.d.ts.map +1 -1
  13. package/dist/architecture-map.js +42 -26
  14. package/dist/area-explore.d.ts +2 -2
  15. package/dist/area-explore.d.ts.map +1 -1
  16. package/dist/area-explore.js +36 -16
  17. package/dist/area-map.d.ts +56 -11
  18. package/dist/area-map.d.ts.map +1 -1
  19. package/dist/area-map.js +106 -25
  20. package/dist/asset-doctor-proposed-exit.d.ts +21 -0
  21. package/dist/asset-doctor-proposed-exit.d.ts.map +1 -0
  22. package/dist/asset-doctor-proposed-exit.js +22 -0
  23. package/dist/asset-provenance.js +1 -1
  24. package/dist/boundaries-changed-only.d.ts +24 -1
  25. package/dist/boundaries-changed-only.d.ts.map +1 -1
  26. package/dist/boundaries-changed-only.js +12 -2
  27. package/dist/boundary-check-options.model.d.ts +40 -0
  28. package/dist/boundary-check-options.model.d.ts.map +1 -0
  29. package/dist/boundary-check-options.model.js +1 -0
  30. package/dist/boundary-check-result.model.d.ts +89 -0
  31. package/dist/boundary-check-result.model.d.ts.map +1 -0
  32. package/dist/boundary-check-result.model.js +1 -0
  33. package/dist/boundary-configuration-status.d.ts +38 -0
  34. package/dist/boundary-configuration-status.d.ts.map +1 -0
  35. package/dist/boundary-configuration-status.js +118 -0
  36. package/dist/boundary-configuration-status.model.d.ts +37 -0
  37. package/dist/boundary-configuration-status.model.d.ts.map +1 -0
  38. package/dist/boundary-configuration-status.model.js +1 -0
  39. package/dist/boundary-load-issue.model.d.ts +30 -0
  40. package/dist/boundary-load-issue.model.d.ts.map +1 -0
  41. package/dist/boundary-load-issue.model.js +1 -0
  42. package/dist/boundary-rule-check.model.d.ts +44 -0
  43. package/dist/boundary-rule-check.model.d.ts.map +1 -0
  44. package/dist/boundary-rule-check.model.js +1 -0
  45. package/dist/boundary-rule-invalidation.model.d.ts +31 -0
  46. package/dist/boundary-rule-invalidation.model.d.ts.map +1 -0
  47. package/dist/boundary-rule-invalidation.model.js +1 -0
  48. package/dist/boundary-rule-set-diff.model.d.ts +75 -0
  49. package/dist/boundary-rule-set-diff.model.d.ts.map +1 -0
  50. package/dist/boundary-rule-set-diff.model.js +1 -0
  51. package/dist/boundary-rule-sources.d.ts +28 -0
  52. package/dist/boundary-rule-sources.d.ts.map +1 -0
  53. package/dist/boundary-rule-sources.js +110 -0
  54. package/dist/boundary-stale-exception-finding.model.d.ts +12 -0
  55. package/dist/boundary-stale-exception-finding.model.d.ts.map +1 -0
  56. package/dist/boundary-stale-exception-finding.model.js +1 -0
  57. package/dist/boundary-unit-liveness.d.ts +35 -0
  58. package/dist/boundary-unit-liveness.d.ts.map +1 -0
  59. package/dist/boundary-unit-liveness.js +71 -0
  60. package/dist/change-intent.d.ts +3 -0
  61. package/dist/change-intent.d.ts.map +1 -1
  62. package/dist/change-intent.js +61 -27
  63. package/dist/changes-summary.d.ts.map +1 -1
  64. package/dist/changes-summary.js +19 -9
  65. package/dist/ci-integrity-report.js +1 -1
  66. package/dist/ci-predict.d.ts.map +1 -1
  67. package/dist/ci-predict.js +38 -5
  68. package/dist/code-intelligence-doctor.d.ts +6 -0
  69. package/dist/code-intelligence-doctor.d.ts.map +1 -1
  70. package/dist/code-intelligence-doctor.js +22 -7
  71. package/dist/command-recommender.d.ts +45 -2
  72. package/dist/command-recommender.d.ts.map +1 -1
  73. package/dist/command-recommender.js +41 -263
  74. package/dist/command-resolution-status.d.ts +44 -0
  75. package/dist/command-resolution-status.d.ts.map +1 -0
  76. package/dist/command-resolution-status.js +44 -0
  77. package/dist/command-safety-level.d.ts +15 -0
  78. package/dist/command-safety-level.d.ts.map +1 -0
  79. package/dist/command-safety-level.js +43 -0
  80. package/dist/command-taxonomy.js +1 -1
  81. package/dist/compliance-evidence.js +1 -1
  82. package/dist/compliance-profiles.js +1 -1
  83. package/dist/construct-registry.d.ts +40 -0
  84. package/dist/construct-registry.d.ts.map +1 -1
  85. package/dist/construct-registry.js +186 -82
  86. package/dist/context-tuning.d.ts +4 -0
  87. package/dist/context-tuning.d.ts.map +1 -1
  88. package/dist/context-tuning.js +10 -7
  89. package/dist/contract-template-registry.d.ts +10 -0
  90. package/dist/contract-template-registry.d.ts.map +1 -1
  91. package/dist/contract-template-registry.js +59 -33
  92. package/dist/contribution-kind.d.ts +52 -0
  93. package/dist/contribution-kind.d.ts.map +1 -0
  94. package/dist/contribution-kind.js +52 -0
  95. package/dist/contribution-load-failures.d.ts +106 -0
  96. package/dist/contribution-load-failures.d.ts.map +1 -0
  97. package/dist/contribution-load-failures.js +575 -0
  98. package/dist/contributions-report.d.ts +28 -0
  99. package/dist/contributions-report.d.ts.map +1 -0
  100. package/dist/contributions-report.js +242 -0
  101. package/dist/convention-registry.d.ts +22 -0
  102. package/dist/convention-registry.d.ts.map +1 -1
  103. package/dist/convention-registry.js +79 -39
  104. package/dist/coverage-report.d.ts.map +1 -1
  105. package/dist/coverage-report.js +6 -6
  106. package/dist/custom-checks.d.ts +60 -1
  107. package/dist/custom-checks.d.ts.map +1 -1
  108. package/dist/custom-checks.js +159 -6
  109. package/dist/dashboard/dashboard-data.d.ts +6 -0
  110. package/dist/dashboard/dashboard-data.d.ts.map +1 -1
  111. package/dist/dashboard/dashboard-data.js +99 -8
  112. package/dist/dashboard/dashboard-knowledge.d.ts.map +1 -1
  113. package/dist/dashboard/dashboard-knowledge.js +14 -2
  114. package/dist/decision-records.d.ts +20 -0
  115. package/dist/decision-records.d.ts.map +1 -1
  116. package/dist/decision-records.js +68 -20
  117. package/dist/declared-cross-references.d.ts +61 -0
  118. package/dist/declared-cross-references.d.ts.map +1 -0
  119. package/dist/declared-cross-references.js +550 -0
  120. package/dist/declared-gate-plane-rules.d.ts +24 -0
  121. package/dist/declared-gate-plane-rules.d.ts.map +1 -0
  122. package/dist/declared-gate-plane-rules.js +39 -0
  123. package/dist/declared-reference-coverage.d.ts +27 -0
  124. package/dist/declared-reference-coverage.d.ts.map +1 -0
  125. package/dist/declared-reference-coverage.js +50 -0
  126. package/dist/declared-xref-status.d.ts +19 -0
  127. package/dist/declared-xref-status.d.ts.map +1 -0
  128. package/dist/declared-xref-status.js +19 -0
  129. package/dist/delegate-pack-recipes.d.ts +13 -2
  130. package/dist/delegate-pack-recipes.d.ts.map +1 -1
  131. package/dist/delegate-pack-recipes.js +45 -14
  132. package/dist/demo-package.js +2 -2
  133. package/dist/demo-script.js +2 -2
  134. package/dist/demo-workflow.js +3 -3
  135. package/dist/dev-cycle.js +1 -1
  136. package/dist/dev-session.js +1 -1
  137. package/dist/doc-references.d.ts +23 -2
  138. package/dist/doc-references.d.ts.map +1 -1
  139. package/dist/doc-references.js +96 -17
  140. package/dist/doctor-result.d.ts +8 -0
  141. package/dist/doctor-result.d.ts.map +1 -1
  142. package/dist/doctor-verdict-kind.d.ts +19 -0
  143. package/dist/doctor-verdict-kind.d.ts.map +1 -0
  144. package/dist/doctor-verdict-kind.js +19 -0
  145. package/dist/doctor-verdict.d.ts +18 -0
  146. package/dist/doctor-verdict.d.ts.map +1 -0
  147. package/dist/doctor-verdict.js +28 -0
  148. package/dist/drift.d.ts +17 -0
  149. package/dist/drift.d.ts.map +1 -1
  150. package/dist/drift.js +40 -10
  151. package/dist/entrypoint-matrix.d.ts.map +1 -1
  152. package/dist/entrypoint-matrix.js +4 -1
  153. package/dist/feedback-ingestion.d.ts +28 -2
  154. package/dist/feedback-ingestion.d.ts.map +1 -1
  155. package/dist/feedback-ingestion.js +68 -19
  156. package/dist/fix-preview.d.ts.map +1 -1
  157. package/dist/fix-preview.js +9 -5
  158. package/dist/framework-extractor-outcomes.d.ts +27 -0
  159. package/dist/framework-extractor-outcomes.d.ts.map +1 -0
  160. package/dist/framework-extractor-outcomes.js +83 -0
  161. package/dist/fuzzy-impact.js +1 -1
  162. package/dist/healing-plan.d.ts.map +1 -1
  163. package/dist/healing-plan.js +3 -4
  164. package/dist/helper-catalog.d.ts +25 -0
  165. package/dist/helper-catalog.d.ts.map +1 -0
  166. package/dist/helper-catalog.js +91 -0
  167. package/dist/helper-registry.d.ts.map +1 -1
  168. package/dist/helper-registry.js +17 -1
  169. package/dist/helper-view.d.ts +33 -0
  170. package/dist/helper-view.d.ts.map +1 -0
  171. package/dist/helper-view.js +1 -0
  172. package/dist/i-asset-doctor-flags.d.ts +16 -0
  173. package/dist/i-asset-doctor-flags.d.ts.map +1 -0
  174. package/dist/i-asset-doctor-flags.js +1 -0
  175. package/dist/i-command-resolution.d.ts +22 -0
  176. package/dist/i-command-resolution.d.ts.map +1 -0
  177. package/dist/i-command-resolution.js +1 -0
  178. package/dist/i-command-resolve-options.d.ts +24 -0
  179. package/dist/i-command-resolve-options.d.ts.map +1 -0
  180. package/dist/i-command-resolve-options.js +1 -0
  181. package/dist/i-command-safety.d.ts +13 -0
  182. package/dist/i-command-safety.d.ts.map +1 -0
  183. package/dist/i-command-safety.js +1 -0
  184. package/dist/i-contribution-accepted-entry.d.ts +18 -0
  185. package/dist/i-contribution-accepted-entry.d.ts.map +1 -0
  186. package/dist/i-contribution-accepted-entry.js +1 -0
  187. package/dist/i-contribution-entry-rejection.d.ts +21 -0
  188. package/dist/i-contribution-entry-rejection.d.ts.map +1 -0
  189. package/dist/i-contribution-entry-rejection.js +1 -0
  190. package/dist/i-contribution-file-issue.d.ts +18 -0
  191. package/dist/i-contribution-file-issue.d.ts.map +1 -0
  192. package/dist/i-contribution-file-issue.js +1 -0
  193. package/dist/i-contribution-file-report.d.ts +40 -0
  194. package/dist/i-contribution-file-report.d.ts.map +1 -0
  195. package/dist/i-contribution-file-report.js +1 -0
  196. package/dist/i-contribution-file-validation.d.ts +24 -0
  197. package/dist/i-contribution-file-validation.d.ts.map +1 -0
  198. package/dist/i-contribution-file-validation.js +1 -0
  199. package/dist/i-contributions-report.d.ts +31 -0
  200. package/dist/i-contributions-report.d.ts.map +1 -0
  201. package/dist/i-contributions-report.js +1 -0
  202. package/dist/i-declared-xref-field.d.ts +25 -0
  203. package/dist/i-declared-xref-field.d.ts.map +1 -0
  204. package/dist/i-declared-xref-field.js +1 -0
  205. package/dist/i-declared-xref-issue.d.ts +25 -0
  206. package/dist/i-declared-xref-issue.d.ts.map +1 -0
  207. package/dist/i-declared-xref-issue.js +1 -0
  208. package/dist/i-declared-xref-report.d.ts +48 -0
  209. package/dist/i-declared-xref-report.d.ts.map +1 -0
  210. package/dist/i-declared-xref-report.js +1 -0
  211. package/dist/i-declared-xref-row.d.ts +29 -0
  212. package/dist/i-declared-xref-row.d.ts.map +1 -0
  213. package/dist/i-declared-xref-row.js +1 -0
  214. package/dist/i-doctor-verdict.d.ts +10 -0
  215. package/dist/i-doctor-verdict.d.ts.map +1 -0
  216. package/dist/i-doctor-verdict.js +1 -0
  217. package/dist/i-kind-outcomes.d.ts +13 -0
  218. package/dist/i-kind-outcomes.d.ts.map +1 -0
  219. package/dist/i-kind-outcomes.js +1 -0
  220. package/dist/i-pack-doctor-verdict.d.ts +15 -0
  221. package/dist/i-pack-doctor-verdict.d.ts.map +1 -0
  222. package/dist/i-pack-doctor-verdict.js +1 -0
  223. package/dist/i-probed-id-field.d.ts +17 -0
  224. package/dist/i-probed-id-field.d.ts.map +1 -0
  225. package/dist/i-probed-id-field.js +1 -0
  226. package/dist/i-reference-kind-declaration.d.ts +38 -0
  227. package/dist/i-reference-kind-declaration.d.ts.map +1 -0
  228. package/dist/i-reference-kind-declaration.js +1 -0
  229. package/dist/i-reference-warm-options.d.ts +21 -0
  230. package/dist/i-reference-warm-options.d.ts.map +1 -0
  231. package/dist/i-reference-warm-options.js +1 -0
  232. package/dist/i-registry-outcomes.d.ts +16 -0
  233. package/dist/i-registry-outcomes.d.ts.map +1 -0
  234. package/dist/i-registry-outcomes.js +1 -0
  235. package/dist/i-scaffold-pattern-doctor-report.d.ts +35 -0
  236. package/dist/i-scaffold-pattern-doctor-report.d.ts.map +1 -0
  237. package/dist/i-scaffold-pattern-doctor-report.js +1 -0
  238. package/dist/i-search-tuning-key-probe.d.ts +30 -0
  239. package/dist/i-search-tuning-key-probe.d.ts.map +1 -0
  240. package/dist/i-search-tuning-key-probe.js +1 -0
  241. package/dist/i-search-tuning-lint-issue.d.ts +61 -0
  242. package/dist/i-search-tuning-lint-issue.d.ts.map +1 -0
  243. package/dist/i-search-tuning-lint-issue.js +1 -0
  244. package/dist/i-search-tuning-lint-report.d.ts +38 -0
  245. package/dist/i-search-tuning-lint-report.d.ts.map +1 -0
  246. package/dist/i-search-tuning-lint-report.js +1 -0
  247. package/dist/i-unresolvable-reference-scan.d.ts +14 -0
  248. package/dist/i-unresolvable-reference-scan.d.ts.map +1 -0
  249. package/dist/i-unresolvable-reference-scan.js +1 -0
  250. package/dist/i-unresolvable-reference.d.ts +29 -0
  251. package/dist/i-unresolvable-reference.d.ts.map +1 -0
  252. package/dist/i-unresolvable-reference.js +1 -0
  253. package/dist/i-workspace-profile-payload.d.ts +12 -0
  254. package/dist/i-workspace-profile-payload.d.ts.map +1 -0
  255. package/dist/i-workspace-profile-payload.js +1 -0
  256. package/dist/impact-analysis.d.ts +15 -0
  257. package/dist/impact-analysis.d.ts.map +1 -1
  258. package/dist/impact-analysis.js +58 -13
  259. package/dist/impact-render.d.ts.map +1 -1
  260. package/dist/impact-render.js +22 -0
  261. package/dist/import-hygiene.d.ts +35 -1
  262. package/dist/import-hygiene.d.ts.map +1 -1
  263. package/dist/import-hygiene.js +107 -13
  264. package/dist/index.d.ts +141 -0
  265. package/dist/index.d.ts.map +1 -1
  266. package/dist/index.js +172 -0
  267. package/dist/inspection-discovery.d.ts +45 -0
  268. package/dist/inspection-discovery.d.ts.map +1 -0
  269. package/dist/inspection-discovery.js +70 -0
  270. package/dist/knowledge-advisory-code.d.ts +17 -0
  271. package/dist/knowledge-advisory-code.d.ts.map +1 -0
  272. package/dist/knowledge-advisory-code.js +17 -0
  273. package/dist/knowledge-aged-entry.d.ts +10 -0
  274. package/dist/knowledge-aged-entry.d.ts.map +1 -0
  275. package/dist/knowledge-aged-entry.js +1 -0
  276. package/dist/knowledge-authoring.d.ts +24 -1
  277. package/dist/knowledge-authoring.d.ts.map +1 -1
  278. package/dist/knowledge-authoring.js +46 -7
  279. package/dist/knowledge-entry-verdict-record.d.ts +22 -0
  280. package/dist/knowledge-entry-verdict-record.d.ts.map +1 -0
  281. package/dist/knowledge-entry-verdict-record.js +1 -0
  282. package/dist/knowledge-entry-verdict.d.ts +17 -0
  283. package/dist/knowledge-entry-verdict.d.ts.map +1 -0
  284. package/dist/knowledge-entry-verdict.js +17 -0
  285. package/dist/knowledge-graph.d.ts +6 -0
  286. package/dist/knowledge-graph.d.ts.map +1 -1
  287. package/dist/knowledge-graph.js +18 -7
  288. package/dist/knowledge-kind-bucket.d.ts +19 -0
  289. package/dist/knowledge-kind-bucket.d.ts.map +1 -0
  290. package/dist/knowledge-kind-bucket.js +1 -0
  291. package/dist/knowledge-load-failure.d.ts +23 -0
  292. package/dist/knowledge-load-failure.d.ts.map +1 -0
  293. package/dist/knowledge-load-failure.js +1 -0
  294. package/dist/knowledge-reference-kind-bucket.d.ts +11 -0
  295. package/dist/knowledge-reference-kind-bucket.d.ts.map +1 -0
  296. package/dist/knowledge-reference-kind-bucket.js +1 -0
  297. package/dist/knowledge-stale-advisory.d.ts +14 -0
  298. package/dist/knowledge-stale-advisory.d.ts.map +1 -0
  299. package/dist/knowledge-stale-advisory.js +1 -0
  300. package/dist/knowledge-stale-coverage.d.ts +19 -0
  301. package/dist/knowledge-stale-coverage.d.ts.map +1 -0
  302. package/dist/knowledge-stale-coverage.js +1 -0
  303. package/dist/knowledge-stale-gate-flags.d.ts +33 -0
  304. package/dist/knowledge-stale-gate-flags.d.ts.map +1 -0
  305. package/dist/knowledge-stale-gate-flags.js +1 -0
  306. package/dist/knowledge-stale-gate-input.d.ts +46 -0
  307. package/dist/knowledge-stale-gate-input.d.ts.map +1 -0
  308. package/dist/knowledge-stale-gate-input.js +1 -0
  309. package/dist/knowledge-stale-gate-result.d.ts +33 -0
  310. package/dist/knowledge-stale-gate-result.d.ts.map +1 -0
  311. package/dist/knowledge-stale-gate-result.js +1 -0
  312. package/dist/knowledge-stale-gate-rule.d.ts +33 -0
  313. package/dist/knowledge-stale-gate-rule.d.ts.map +1 -0
  314. package/dist/knowledge-stale-gate-rule.js +1 -0
  315. package/dist/knowledge-stale-gate-violation.d.ts +13 -0
  316. package/dist/knowledge-stale-gate-violation.d.ts.map +1 -0
  317. package/dist/knowledge-stale-gate-violation.js +1 -0
  318. package/dist/knowledge-stale-gate.d.ts +83 -0
  319. package/dist/knowledge-stale-gate.d.ts.map +1 -0
  320. package/dist/knowledge-stale-gate.js +429 -0
  321. package/dist/knowledge-stale-quality-gate.d.ts +26 -0
  322. package/dist/knowledge-stale-quality-gate.d.ts.map +1 -0
  323. package/dist/knowledge-stale-quality-gate.js +110 -0
  324. package/dist/knowledge-stale.d.ts +122 -9
  325. package/dist/knowledge-stale.d.ts.map +1 -1
  326. package/dist/knowledge-stale.js +996 -291
  327. package/dist/knowledge-unverifiable-reason.d.ts +12 -0
  328. package/dist/knowledge-unverifiable-reason.d.ts.map +1 -0
  329. package/dist/knowledge-unverifiable-reason.js +12 -0
  330. package/dist/loader-diagnostics.d.ts +14 -2
  331. package/dist/loader-diagnostics.d.ts.map +1 -1
  332. package/dist/match-terms.d.ts +48 -0
  333. package/dist/match-terms.d.ts.map +1 -0
  334. package/dist/match-terms.js +155 -0
  335. package/dist/migration-profile-registry.d.ts +10 -0
  336. package/dist/migration-profile-registry.d.ts.map +1 -1
  337. package/dist/migration-profile-registry.js +57 -34
  338. package/dist/migration-readiness.d.ts.map +1 -1
  339. package/dist/migration-readiness.js +1 -3
  340. package/dist/nearest-id.d.ts +10 -26
  341. package/dist/nearest-id.d.ts.map +1 -1
  342. package/dist/nearest-id.js +9 -59
  343. package/dist/pack-asset-freshness.d.ts +65 -0
  344. package/dist/pack-asset-freshness.d.ts.map +1 -0
  345. package/dist/pack-asset-freshness.js +340 -0
  346. package/dist/pack-author-ux.d.ts +24 -3
  347. package/dist/pack-author-ux.d.ts.map +1 -1
  348. package/dist/pack-author-ux.js +87 -93
  349. package/dist/pack-contributions-inventory.d.ts +79 -39
  350. package/dist/pack-contributions-inventory.d.ts.map +1 -1
  351. package/dist/pack-contributions-inventory.js +443 -286
  352. package/dist/pack-doctor-verdict.d.ts +29 -0
  353. package/dist/pack-doctor-verdict.d.ts.map +1 -0
  354. package/dist/pack-doctor-verdict.js +45 -0
  355. package/dist/pack-doctor.d.ts +74 -1
  356. package/dist/pack-doctor.d.ts.map +1 -1
  357. package/dist/pack-doctor.js +281 -1
  358. package/dist/pack-helper-plan.d.ts +24 -0
  359. package/dist/pack-helper-plan.d.ts.map +1 -0
  360. package/dist/pack-helper-plan.js +77 -0
  361. package/dist/pack-helper-registry.d.ts +14 -0
  362. package/dist/pack-helper-registry.d.ts.map +1 -1
  363. package/dist/pack-helper-registry.js +76 -37
  364. package/dist/pack-manifest-reader.d.ts +8 -0
  365. package/dist/pack-manifest-reader.d.ts.map +1 -0
  366. package/dist/pack-manifest-reader.js +79 -0
  367. package/dist/pack-release-check.d.ts +14 -1
  368. package/dist/pack-release-check.d.ts.map +1 -1
  369. package/dist/pack-release-check.js +23 -1
  370. package/dist/pack-signature-status.d.ts +18 -6
  371. package/dist/pack-signature-status.d.ts.map +1 -1
  372. package/dist/pack-signature-status.js +59 -105
  373. package/dist/pack-test-runner.d.ts +27 -5
  374. package/dist/pack-test-runner.d.ts.map +1 -1
  375. package/dist/pack-test-runner.js +91 -35
  376. package/dist/pack-typecheck.d.ts +8 -0
  377. package/dist/pack-typecheck.d.ts.map +1 -0
  378. package/dist/pack-typecheck.js +76 -0
  379. package/dist/plan-review.d.ts +2 -0
  380. package/dist/plan-review.d.ts.map +1 -1
  381. package/dist/plan-review.js +17 -5
  382. package/dist/plan-simulation.d.ts.map +1 -1
  383. package/dist/plan-simulation.js +16 -5
  384. package/dist/playbook-load-issue.d.ts +16 -0
  385. package/dist/playbook-load-issue.d.ts.map +1 -0
  386. package/dist/playbook-load-issue.js +1 -0
  387. package/dist/playbook-registry.d.ts +32 -1
  388. package/dist/playbook-registry.d.ts.map +1 -1
  389. package/dist/playbook-registry.js +144 -55
  390. package/dist/policy-declaration.d.ts +18 -0
  391. package/dist/policy-declaration.d.ts.map +1 -0
  392. package/dist/policy-declaration.js +1 -0
  393. package/dist/policy-engine.d.ts +8 -0
  394. package/dist/policy-engine.d.ts.map +1 -1
  395. package/dist/policy-engine.js +26 -9
  396. package/dist/policy-overrides.d.ts.map +1 -1
  397. package/dist/policy-overrides.js +4 -4
  398. package/dist/policy-registry.d.ts +27 -0
  399. package/dist/policy-registry.d.ts.map +1 -1
  400. package/dist/policy-registry.js +87 -20
  401. package/dist/probed-id-fields.d.ts +21 -0
  402. package/dist/probed-id-fields.d.ts.map +1 -0
  403. package/dist/probed-id-fields.js +25 -0
  404. package/dist/probed-id-source.d.ts +11 -0
  405. package/dist/probed-id-source.d.ts.map +1 -0
  406. package/dist/probed-id-source.js +11 -0
  407. package/dist/profile-registry.d.ts +25 -2
  408. package/dist/profile-registry.d.ts.map +1 -1
  409. package/dist/profile-registry.js +59 -6
  410. package/dist/quality-gate-examination.d.ts +15 -0
  411. package/dist/quality-gate-examination.d.ts.map +1 -0
  412. package/dist/quality-gate-examination.js +15 -0
  413. package/dist/quality-gate-row-status.d.ts +19 -0
  414. package/dist/quality-gate-row-status.d.ts.map +1 -0
  415. package/dist/quality-gate-row-status.js +28 -0
  416. package/dist/quality-gate-status.d.ts +16 -0
  417. package/dist/quality-gate-status.d.ts.map +1 -0
  418. package/dist/quality-gate-status.js +16 -0
  419. package/dist/quality-html.d.ts.map +1 -1
  420. package/dist/quality-html.js +14 -3
  421. package/dist/quality-report-coverage.d.ts +26 -0
  422. package/dist/quality-report-coverage.d.ts.map +1 -0
  423. package/dist/quality-report-coverage.js +48 -0
  424. package/dist/quality-report.d.ts +28 -1
  425. package/dist/quality-report.d.ts.map +1 -1
  426. package/dist/quality-report.js +263 -35
  427. package/dist/query-intent-kind.d.ts +18 -0
  428. package/dist/query-intent-kind.d.ts.map +1 -0
  429. package/dist/query-intent-kind.js +18 -0
  430. package/dist/query-intent-result.d.ts +23 -0
  431. package/dist/query-intent-result.d.ts.map +1 -0
  432. package/dist/query-intent-result.js +1 -0
  433. package/dist/query-intent.d.ts +18 -0
  434. package/dist/query-intent.d.ts.map +1 -0
  435. package/dist/query-intent.js +336 -0
  436. package/dist/query-resolver.d.ts +18 -0
  437. package/dist/query-resolver.d.ts.map +1 -1
  438. package/dist/query-resolver.js +7 -4
  439. package/dist/ranked-recommendations.d.ts +36 -0
  440. package/dist/ranked-recommendations.d.ts.map +1 -0
  441. package/dist/ranked-recommendations.js +1 -0
  442. package/dist/ranker-explainability.d.ts.map +1 -1
  443. package/dist/ranker-explainability.js +38 -10
  444. package/dist/recommend-recipe.d.ts +17 -0
  445. package/dist/recommend-recipe.d.ts.map +1 -0
  446. package/dist/recommend-recipe.js +1 -0
  447. package/dist/recommend-recipes.d.ts +9 -0
  448. package/dist/recommend-recipes.d.ts.map +1 -0
  449. package/dist/recommend-recipes.js +106 -0
  450. package/dist/recommendation-candidate.d.ts +30 -0
  451. package/dist/recommendation-candidate.d.ts.map +1 -0
  452. package/dist/recommendation-candidate.js +1 -0
  453. package/dist/recommendation-confidence.d.ts +27 -0
  454. package/dist/recommendation-confidence.d.ts.map +1 -0
  455. package/dist/recommendation-confidence.js +1 -0
  456. package/dist/recommendation-ranking-options.d.ts +24 -0
  457. package/dist/recommendation-ranking-options.d.ts.map +1 -0
  458. package/dist/recommendation-ranking-options.js +1 -0
  459. package/dist/recommendation-ranking.d.ts +50 -0
  460. package/dist/recommendation-ranking.d.ts.map +1 -0
  461. package/dist/recommendation-ranking.js +527 -0
  462. package/dist/recommendation-source.d.ts +23 -0
  463. package/dist/recommendation-source.d.ts.map +1 -0
  464. package/dist/recommendation-source.js +23 -0
  465. package/dist/recommendation-suppression.d.ts +14 -0
  466. package/dist/recommendation-suppression.d.ts.map +1 -0
  467. package/dist/recommendation-suppression.js +14 -0
  468. package/dist/reference-asset-kind.d.ts +14 -0
  469. package/dist/reference-asset-kind.d.ts.map +1 -0
  470. package/dist/reference-asset-kind.js +14 -0
  471. package/dist/reference-content-check.d.ts +32 -0
  472. package/dist/reference-content-check.d.ts.map +1 -0
  473. package/dist/reference-content-check.js +143 -0
  474. package/dist/reference-failure.d.ts +31 -0
  475. package/dist/reference-failure.d.ts.map +1 -0
  476. package/dist/reference-failure.js +31 -0
  477. package/dist/reference-id-status.d.ts +15 -0
  478. package/dist/reference-id-status.d.ts.map +1 -0
  479. package/dist/reference-id-status.js +15 -0
  480. package/dist/reference-kind-declarations.d.ts +42 -0
  481. package/dist/reference-kind-declarations.d.ts.map +1 -0
  482. package/dist/reference-kind-declarations.js +142 -0
  483. package/dist/reference-lookup.d.ts +6 -0
  484. package/dist/reference-lookup.d.ts.map +1 -1
  485. package/dist/reference-lookup.js +13 -5
  486. package/dist/reference-registry.d.ts +109 -11
  487. package/dist/reference-registry.d.ts.map +1 -1
  488. package/dist/reference-registry.js +186 -30
  489. package/dist/reference-subject.d.ts +20 -0
  490. package/dist/reference-subject.d.ts.map +1 -0
  491. package/dist/reference-subject.js +1 -0
  492. package/dist/registration-hint-discovery-status.d.ts +25 -0
  493. package/dist/registration-hint-discovery-status.d.ts.map +1 -0
  494. package/dist/registration-hint-discovery-status.js +25 -0
  495. package/dist/registration-hint-registry.d.ts +80 -0
  496. package/dist/registration-hint-registry.d.ts.map +1 -1
  497. package/dist/registration-hint-registry.js +356 -138
  498. package/dist/registry-lifecycle.d.ts +200 -19
  499. package/dist/registry-lifecycle.d.ts.map +1 -1
  500. package/dist/registry-lifecycle.js +526 -136
  501. package/dist/release-readiness.d.ts.map +1 -1
  502. package/dist/release-readiness.js +10 -7
  503. package/dist/release-smoke.d.ts.map +1 -1
  504. package/dist/release-smoke.js +11 -7
  505. package/dist/report-site.d.ts.map +1 -1
  506. package/dist/report-site.js +25 -7
  507. package/dist/repository-intelligence.d.ts.map +1 -1
  508. package/dist/repository-intelligence.js +3 -2
  509. package/dist/repository-knowledge-model.d.ts.map +1 -1
  510. package/dist/repository-knowledge-model.js +18 -5
  511. package/dist/resolve-project-config.d.ts +64 -0
  512. package/dist/resolve-project-config.d.ts.map +1 -1
  513. package/dist/resolve-project-config.js +240 -32
  514. package/dist/reuse/compute-reuse-coverage.d.ts +29 -0
  515. package/dist/reuse/compute-reuse-coverage.d.ts.map +1 -0
  516. package/dist/reuse/compute-reuse-coverage.js +198 -0
  517. package/dist/reuse/rank-reuse-candidates.d.ts +38 -0
  518. package/dist/reuse/rank-reuse-candidates.d.ts.map +1 -0
  519. package/dist/reuse/rank-reuse-candidates.js +212 -0
  520. package/dist/reuse/rank-reuse-options.d.ts +20 -0
  521. package/dist/reuse/rank-reuse-options.d.ts.map +1 -0
  522. package/dist/reuse/rank-reuse-options.js +1 -0
  523. package/dist/reuse/rank-reuse-suggestions.d.ts +15 -0
  524. package/dist/reuse/rank-reuse-suggestions.d.ts.map +1 -0
  525. package/dist/reuse/rank-reuse-suggestions.js +31 -0
  526. package/dist/reuse/resolve-curated-reuse.d.ts +43 -0
  527. package/dist/reuse/resolve-curated-reuse.d.ts.map +1 -0
  528. package/dist/reuse/resolve-curated-reuse.js +115 -0
  529. package/dist/reuse/reuse-candidate.d.ts +29 -0
  530. package/dist/reuse/reuse-candidate.d.ts.map +1 -0
  531. package/dist/reuse/reuse-candidate.js +1 -0
  532. package/dist/reuse/reuse-coverage-report.d.ts +74 -0
  533. package/dist/reuse/reuse-coverage-report.d.ts.map +1 -0
  534. package/dist/reuse/reuse-coverage-report.js +1 -0
  535. package/dist/reuse/reuse-curated-coverage.d.ts +36 -0
  536. package/dist/reuse/reuse-curated-coverage.d.ts.map +1 -0
  537. package/dist/reuse/reuse-curated-coverage.js +1 -0
  538. package/dist/reuse/reuse-curated-resolution.d.ts +36 -0
  539. package/dist/reuse/reuse-curated-resolution.d.ts.map +1 -0
  540. package/dist/reuse/reuse-curated-resolution.js +1 -0
  541. package/dist/reuse/reuse-curated-status.d.ts +21 -0
  542. package/dist/reuse/reuse-curated-status.d.ts.map +1 -0
  543. package/dist/reuse/reuse-curated-status.js +21 -0
  544. package/dist/reuse/reuse-match-detail.d.ts +15 -0
  545. package/dist/reuse/reuse-match-detail.d.ts.map +1 -0
  546. package/dist/reuse/reuse-match-detail.js +1 -0
  547. package/dist/reuse/reuse-ranking.d.ts +37 -0
  548. package/dist/reuse/reuse-ranking.d.ts.map +1 -0
  549. package/dist/reuse/reuse-ranking.js +1 -0
  550. package/dist/reuse/reuse-suggestion.d.ts +19 -0
  551. package/dist/reuse/reuse-suggestion.d.ts.map +1 -0
  552. package/dist/reuse/reuse-suggestion.js +1 -0
  553. package/dist/reuse/reuse-symbol-lookup.d.ts +28 -0
  554. package/dist/reuse/reuse-symbol-lookup.d.ts.map +1 -0
  555. package/dist/reuse/reuse-symbol-lookup.js +1 -0
  556. package/dist/reuse/reuse-tokenize.d.ts +11 -0
  557. package/dist/reuse/reuse-tokenize.d.ts.map +1 -0
  558. package/dist/reuse/reuse-tokenize.js +26 -0
  559. package/dist/reuse/score-reuse-name.d.ts +16 -0
  560. package/dist/reuse/score-reuse-name.d.ts.map +1 -0
  561. package/dist/reuse/score-reuse-name.js +35 -0
  562. package/dist/reuse/score-reuse-primitive.d.ts +33 -0
  563. package/dist/reuse/score-reuse-primitive.d.ts.map +1 -0
  564. package/dist/reuse/score-reuse-primitive.js +92 -0
  565. package/dist/review-packet.d.ts +2 -0
  566. package/dist/review-packet.d.ts.map +1 -1
  567. package/dist/review-packet.js +13 -6
  568. package/dist/role-views.d.ts.map +1 -1
  569. package/dist/role-views.js +16 -16
  570. package/dist/routing-recommends-channels.d.ts +24 -0
  571. package/dist/routing-recommends-channels.d.ts.map +1 -0
  572. package/dist/routing-recommends-channels.js +19 -0
  573. package/dist/run-boundary-check.d.ts +118 -0
  574. package/dist/run-boundary-check.d.ts.map +1 -0
  575. package/dist/run-boundary-check.js +592 -0
  576. package/dist/safety-audit.js +1 -1
  577. package/dist/scaffold-coverage.js +1 -1
  578. package/dist/scaffold-pattern-doctor-report.d.ts +19 -0
  579. package/dist/scaffold-pattern-doctor-report.d.ts.map +1 -0
  580. package/dist/scaffold-pattern-doctor-report.js +54 -0
  581. package/dist/scaffold-patterns.d.ts +75 -1
  582. package/dist/scaffold-patterns.d.ts.map +1 -1
  583. package/dist/scaffold-patterns.js +375 -84
  584. package/dist/schema-inventory.d.ts.map +1 -1
  585. package/dist/schema-inventory.js +4 -3
  586. package/dist/search-document-id.d.ts +52 -0
  587. package/dist/search-document-id.d.ts.map +1 -0
  588. package/dist/search-document-id.js +72 -0
  589. package/dist/search-document-prefix.d.ts +7 -0
  590. package/dist/search-document-prefix.d.ts.map +1 -0
  591. package/dist/search-document-prefix.js +1 -0
  592. package/dist/search-index.d.ts.map +1 -1
  593. package/dist/search-index.js +20 -23
  594. package/dist/search-tuning-explain.d.ts +6 -0
  595. package/dist/search-tuning-explain.d.ts.map +1 -1
  596. package/dist/search-tuning-explain.js +19 -17
  597. package/dist/search-tuning-key-probes.d.ts +16 -0
  598. package/dist/search-tuning-key-probes.d.ts.map +1 -0
  599. package/dist/search-tuning-key-probes.js +65 -0
  600. package/dist/search-tuning-key-resolution.d.ts +25 -0
  601. package/dist/search-tuning-key-resolution.d.ts.map +1 -0
  602. package/dist/search-tuning-key-resolution.js +1 -0
  603. package/dist/search-tuning-key-resolver.d.ts +4 -0
  604. package/dist/search-tuning-key-resolver.d.ts.map +1 -0
  605. package/dist/search-tuning-key-resolver.js +107 -0
  606. package/dist/search-tuning-key-status.d.ts +24 -0
  607. package/dist/search-tuning-key-status.d.ts.map +1 -0
  608. package/dist/search-tuning-key-status.js +24 -0
  609. package/dist/search-tuning-lint.d.ts +9 -0
  610. package/dist/search-tuning-lint.d.ts.map +1 -0
  611. package/dist/search-tuning-lint.js +468 -0
  612. package/dist/search-tuning-registry.d.ts +43 -0
  613. package/dist/search-tuning-registry.d.ts.map +1 -1
  614. package/dist/search-tuning-registry.js +214 -49
  615. package/dist/self-audit.d.ts +12 -0
  616. package/dist/self-audit.d.ts.map +1 -1
  617. package/dist/self-audit.js +36 -10
  618. package/dist/self-config-doctor-v2.d.ts +145 -3
  619. package/dist/self-config-doctor-v2.d.ts.map +1 -1
  620. package/dist/self-config-doctor-v2.js +1304 -181
  621. package/dist/self-config-doctor.d.ts +20 -1
  622. package/dist/self-config-doctor.d.ts.map +1 -1
  623. package/dist/self-config-doctor.js +53 -280
  624. package/dist/settled-unit-states.d.ts +9 -0
  625. package/dist/settled-unit-states.d.ts.map +1 -0
  626. package/dist/settled-unit-states.js +14 -0
  627. package/dist/sharkcraft-inspector.d.ts +34 -0
  628. package/dist/sharkcraft-inspector.d.ts.map +1 -1
  629. package/dist/sharkcraft-inspector.js +273 -26
  630. package/dist/spec/spec-evidence.d.ts.map +1 -1
  631. package/dist/spec/spec-evidence.js +14 -20
  632. package/dist/split-identifier.d.ts +21 -0
  633. package/dist/split-identifier.d.ts.map +1 -0
  634. package/dist/split-identifier.js +27 -0
  635. package/dist/start-here.d.ts.map +1 -1
  636. package/dist/start-here.js +1 -2
  637. package/dist/substitute-placeholders.d.ts +8 -0
  638. package/dist/substitute-placeholders.d.ts.map +1 -0
  639. package/dist/substitute-placeholders.js +9 -0
  640. package/dist/symbol-index.d.ts +33 -0
  641. package/dist/symbol-index.d.ts.map +1 -1
  642. package/dist/symbol-index.js +241 -3
  643. package/dist/symbol-member-entry.d.ts +26 -0
  644. package/dist/symbol-member-entry.d.ts.map +1 -0
  645. package/dist/symbol-member-entry.js +1 -0
  646. package/dist/symbol-member-kind.d.ts +14 -0
  647. package/dist/symbol-member-kind.d.ts.map +1 -0
  648. package/dist/symbol-member-kind.js +14 -0
  649. package/dist/task-packet.d.ts.map +1 -1
  650. package/dist/task-packet.js +52 -9
  651. package/dist/task-ranker.d.ts +8 -0
  652. package/dist/task-ranker.d.ts.map +1 -1
  653. package/dist/task-ranker.js +25 -13
  654. package/dist/task-risk.js +1 -1
  655. package/dist/task-routing-hint-registry.d.ts +20 -1
  656. package/dist/task-routing-hint-registry.d.ts.map +1 -1
  657. package/dist/task-routing-hint-registry.js +186 -42
  658. package/dist/template-drift.d.ts.map +1 -1
  659. package/dist/template-drift.js +30 -9
  660. package/dist/template-lint.d.ts.map +1 -1
  661. package/dist/template-lint.js +160 -2
  662. package/dist/term-query.d.ts +10 -0
  663. package/dist/term-query.d.ts.map +1 -0
  664. package/dist/term-query.js +1 -0
  665. package/dist/test-definitions.d.ts +6 -3
  666. package/dist/test-definitions.d.ts.map +1 -1
  667. package/dist/test-runner.d.ts +95 -10
  668. package/dist/test-runner.d.ts.map +1 -1
  669. package/dist/test-runner.js +309 -308
  670. package/dist/tuning-query-tokens.d.ts +29 -0
  671. package/dist/tuning-query-tokens.d.ts.map +1 -0
  672. package/dist/tuning-query-tokens.js +51 -0
  673. package/dist/typecheck-files.d.ts +36 -0
  674. package/dist/typecheck-files.d.ts.map +1 -0
  675. package/dist/typecheck-files.js +158 -0
  676. package/dist/uncertainty.js +1 -1
  677. package/dist/universal-search.d.ts.map +1 -1
  678. package/dist/universal-search.js +5 -3
  679. package/dist/unregistered-exports.d.ts +19 -0
  680. package/dist/unregistered-exports.d.ts.map +1 -0
  681. package/dist/unregistered-exports.js +141 -0
  682. package/dist/unresolvable-reason.d.ts +11 -0
  683. package/dist/unresolvable-reason.d.ts.map +1 -0
  684. package/dist/unresolvable-reason.js +11 -0
  685. package/dist/upgrade-advisor.d.ts.map +1 -1
  686. package/dist/upgrade-advisor.js +16 -9
  687. package/dist/validate-contribution-file.d.ts +4 -0
  688. package/dist/validate-contribution-file.d.ts.map +1 -0
  689. package/dist/validate-contribution-file.js +228 -0
  690. package/dist/why-file.d.ts +3 -0
  691. package/dist/why-file.d.ts.map +1 -1
  692. package/dist/why-file.js +7 -3
  693. package/package.json +17 -17
@@ -6,18 +6,29 @@
6
6
  * - one row per detected collision — the conflicts
7
7
  *
8
8
  * Both outputs are deterministic and read-only.
9
+ *
10
+ * Honesty contract (round 11): an id the inventory could only SCRAPE is never
11
+ * reported as a healthy contribution. A file the module loader cannot import is
12
+ * a load failure — its scraped ids are `validation: 'error'` and the file is an
13
+ * `invalid-contribution` error conflict. A regex id from a kind whose loader
14
+ * returned nothing for that file is a `warning`. Every text/markdown render
15
+ * prints the extraction mode, so a fallback is never invisible.
16
+ *
17
+ * Round 12 (12.1e): EVERY loader-backed slot is a kind and is listed
18
+ * structurally (registration hints, presets, boundaries, scaffold patterns,
19
+ * constructs + facets, search tuning, decisions, policy checks, feedback rules,
20
+ * tests, delegate recipes, framework extractors and the gate planes were
21
+ * scraped by regex, or not listed at all), and an entry its loader REFUSED is
22
+ * in `rejections` — a scraped id matching one is `error` "rejected by the
23
+ * loader", never the `ok` a regex id of an unloaded kind used to get.
9
24
  */
10
- import { existsSync, readFileSync, statSync } from 'node:fs';
25
+ import { readFileSync } from 'node:fs';
11
26
  import * as nodePath from 'node:path';
12
- // Structural loaders used to replace regex-fallback noise per kind.
13
- import { HELPERS } from "./helper-registry.js";
14
- import { listConventions } from "./convention-registry.js";
15
- import { listPackHelpers } from "./pack-helper-registry.js";
16
- import { listTaskRoutingHints } from "./task-routing-hint-registry.js";
17
- import { listRegistrationHints } from "./registration-hint-registry.js";
18
- import { listPlaybooks } from "./playbook-registry.js";
19
- import { loadAllContractTemplates } from "./contract-template-registry.js";
20
- import { listMigrationProfilesFromPacks } from "./migration-profile-registry.js";
27
+ import { CONTRIBUTION_FILE_KEYS } from '@shrkcrft/plugin-api';
28
+ import { collectContributionLoadFailures, collectContributionRejections, collectRegistryOutcomes, formatEntryRejection, } from "./contribution-load-failures.js";
29
+ import { ContributionKind } from "./contribution-kind.js";
30
+ import { describePackAssetFreshness, detectPackAssetFreshness } from "./pack-asset-freshness.js";
31
+ export { ContributionKind } from "./contribution-kind.js";
21
32
  export const PACK_CONTRIBUTIONS_INVENTORY_SCHEMA = 'sharkcraft.pack-contributions-inventory/v1';
22
33
  export var ContributionSource;
23
34
  (function (ContributionSource) {
@@ -26,32 +37,6 @@ export var ContributionSource;
26
37
  ContributionSource["Pack"] = "pack";
27
38
  ContributionSource["Fixture"] = "fixture";
28
39
  })(ContributionSource || (ContributionSource = {}));
29
- export var ContributionKind;
30
- (function (ContributionKind) {
31
- ContributionKind["Knowledge"] = "knowledge";
32
- ContributionKind["Rule"] = "rule";
33
- ContributionKind["Path"] = "path";
34
- ContributionKind["PathConvention"] = "path-convention";
35
- ContributionKind["Template"] = "template";
36
- ContributionKind["Pipeline"] = "pipeline";
37
- ContributionKind["Preset"] = "preset";
38
- ContributionKind["Boundary"] = "boundary";
39
- ContributionKind["ScaffoldPattern"] = "scaffold-pattern";
40
- ContributionKind["Policy"] = "policy";
41
- ContributionKind["Construct"] = "construct";
42
- ContributionKind["Playbook"] = "playbook";
43
- ContributionKind["SearchTuning"] = "search-tuning";
44
- ContributionKind["FeedbackRule"] = "feedback-rule";
45
- ContributionKind["Decision"] = "decision";
46
- ContributionKind["ContractTemplate"] = "contract-template";
47
- ContributionKind["MigrationProfile"] = "migration-profile";
48
- ContributionKind["ContextTest"] = "context-test";
49
- ContributionKind["AgentTest"] = "agent-test";
50
- ContributionKind["Helper"] = "helper";
51
- ContributionKind["TaskRoutingHint"] = "task-routing-hint";
52
- ContributionKind["Convention"] = "convention";
53
- ContributionKind["Docs"] = "docs";
54
- })(ContributionKind || (ContributionKind = {}));
55
40
  export var ConflictKind;
56
41
  (function (ConflictKind) {
57
42
  ConflictKind["DuplicateIdSameKind"] = "duplicate-id-same-kind";
@@ -64,7 +49,12 @@ export var ConflictKind;
64
49
  ConflictKind["IncompatibleSchema"] = "incompatible-schema";
65
50
  ConflictKind["MissingLoader"] = "missing-loader";
66
51
  })(ConflictKind || (ConflictKind = {}));
67
- const KIND_TO_SLOT = {
52
+ /**
53
+ * THE contribution kind → manifest slot table. A `Record` over the enum: a kind
54
+ * without a slot is a compile error, and the r76 census holds every
55
+ * loader-backed `CONTRIBUTION_FILE_KEYS` slot to exactly one kind here.
56
+ */
57
+ export const CONTRIBUTION_KIND_SLOT = Object.freeze({
68
58
  [ContributionKind.Knowledge]: 'knowledgeFiles',
69
59
  [ContributionKind.Rule]: 'ruleFiles',
70
60
  [ContributionKind.Path]: 'pathFiles',
@@ -76,6 +66,7 @@ const KIND_TO_SLOT = {
76
66
  [ContributionKind.ScaffoldPattern]: 'scaffoldPatternFiles',
77
67
  [ContributionKind.Policy]: 'policyCheckFiles',
78
68
  [ContributionKind.Construct]: 'constructFiles',
69
+ [ContributionKind.ConstructFacet]: 'constructFacetFiles',
79
70
  [ContributionKind.Playbook]: 'playbookFiles',
80
71
  [ContributionKind.SearchTuning]: 'searchTuningFiles',
81
72
  [ContributionKind.FeedbackRule]: 'feedbackRuleFiles',
@@ -86,8 +77,35 @@ const KIND_TO_SLOT = {
86
77
  [ContributionKind.AgentTest]: 'agentTestFiles',
87
78
  [ContributionKind.Helper]: 'helperFiles',
88
79
  [ContributionKind.TaskRoutingHint]: 'taskRoutingHintFiles',
80
+ [ContributionKind.RegistrationHint]: 'registrationHintFiles',
89
81
  [ContributionKind.Convention]: 'conventionFiles',
90
82
  [ContributionKind.Docs]: 'docsFiles',
83
+ [ContributionKind.DelegateRecipe]: 'delegateRecipeFiles',
84
+ [ContributionKind.FrameworkExtractor]: 'frameworkExtractorFiles',
85
+ [ContributionKind.WiringRule]: 'wiringRuleFiles',
86
+ [ContributionKind.Registry]: 'registryFiles',
87
+ [ContributionKind.RegistrationIdiom]: 'registrationGraphFiles',
88
+ [ContributionKind.PolicyRule]: 'policyRuleFiles',
89
+ [ContributionKind.ReusePrimitive]: 'reusePrimitiveFiles',
90
+ [ContributionKind.Baseline]: 'baselineFiles',
91
+ [ContributionKind.GeneratedArtifact]: 'generatedArtifactFiles',
92
+ [ContributionKind.DocReference]: 'docReferenceFiles',
93
+ });
94
+ /** The contribution kind a manifest slot's files are loaded as, or `undefined` for a slot no loader reads. */
95
+ export function contributionKindForSlot(slot) {
96
+ for (const [kind, s] of Object.entries(CONTRIBUTION_KIND_SLOT))
97
+ if (s === slot)
98
+ return kind;
99
+ return undefined;
100
+ }
101
+ /**
102
+ * A slot whose files are loaded under a DIFFERENT kind: `pathConventionFiles`
103
+ * feed the path loader, `docsFiles` the markdown knowledge loader. A file the
104
+ * other kind handled structurally is handled for this slot too.
105
+ */
106
+ const ALSO_HANDLED_BY = {
107
+ [ContributionKind.PathConvention]: [ContributionKind.Path],
108
+ [ContributionKind.Docs]: [ContributionKind.Knowledge],
91
109
  };
92
110
  function safeRead(file) {
93
111
  try {
@@ -99,9 +117,9 @@ function safeRead(file) {
99
117
  }
100
118
  /**
101
119
  * Lightweight static extractor — looks for `id: '...'` and `title: '...'`
102
- * occurrences inside a contribution file. This works without importing the
103
- * file (the engine already has dedicated loaders that do this; the inventory
104
- * is intentionally a fast surface-level reporter that doesn't re-run them).
120
+ * occurrences inside a contribution file. Used ONLY where no loader answered
121
+ * for a file; its ids are tagged `regex-fallback` and never reported as a
122
+ * verified contribution.
105
123
  */
106
124
  function extractIdsFromFile(content) {
107
125
  const entries = [];
@@ -135,21 +153,25 @@ function buildContribFileEntries(inspection) {
135
153
  { kind: ContributionKind.Pipeline, relCandidates: ['pipelines.ts'] },
136
154
  { kind: ContributionKind.ScaffoldPattern, relCandidates: ['scaffold-patterns.ts'] },
137
155
  { kind: ContributionKind.Policy, relCandidates: ['policies.ts'] },
156
+ { kind: ContributionKind.Construct, relCandidates: ['constructs.ts'] },
157
+ { kind: ContributionKind.ConstructFacet, relCandidates: ['construct-facets.ts'] },
138
158
  { kind: ContributionKind.Playbook, relCandidates: ['playbooks.ts'] },
139
159
  { kind: ContributionKind.SearchTuning, relCandidates: ['search-tuning.ts'] },
140
160
  { kind: ContributionKind.FeedbackRule, relCandidates: ['feedback-rules.ts'] },
141
161
  { kind: ContributionKind.Decision, relCandidates: ['decisions.ts'] },
162
+ { kind: ContributionKind.ContextTest, relCandidates: ['context-tests.ts'] },
142
163
  { kind: ContributionKind.AgentTest, relCandidates: ['agent-tests.ts'] },
143
164
  { kind: ContributionKind.ContractTemplate, relCandidates: ['contract-templates.ts'] },
144
165
  { kind: ContributionKind.MigrationProfile, relCandidates: ['migration-profiles.ts'] },
145
166
  { kind: ContributionKind.Helper, relCandidates: ['helpers.ts'] },
146
167
  { kind: ContributionKind.TaskRoutingHint, relCandidates: ['task-routing-hints.ts'] },
168
+ { kind: ContributionKind.RegistrationHint, relCandidates: ['registration-hints.ts'] },
147
169
  { kind: ContributionKind.Convention, relCandidates: ['conventions.ts'] },
148
170
  ];
149
171
  for (const c of localConventions) {
150
172
  const files = c.relCandidates
151
173
  .map((rel) => nodePath.join(dir, rel))
152
- .filter((abs) => existsSync(abs));
174
+ .filter((abs) => safeRead(abs) !== null);
153
175
  if (files.length > 0) {
154
176
  out.push({ kind: c.kind, files, source: ContributionSource.Local });
155
177
  }
@@ -159,11 +181,11 @@ function buildContribFileEntries(inspection) {
159
181
  for (const pack of inspection.packs.validPacks ?? []) {
160
182
  const contributions = (pack.manifest?.contributions ?? {});
161
183
  for (const kind of Object.values(ContributionKind)) {
162
- const slot = KIND_TO_SLOT[kind];
184
+ const slot = CONTRIBUTION_KIND_SLOT[kind];
163
185
  const rels = contributions[slot];
164
186
  if (!rels || rels.length === 0)
165
187
  continue;
166
- const abs = rels.map((rel) => nodePath.resolve(pack.packageRoot, rel)).filter((f) => existsSync(f));
188
+ const abs = rels.map((rel) => nodePath.resolve(pack.packageRoot, rel)).filter((f) => safeRead(f) !== null);
167
189
  out.push({
168
190
  kind,
169
191
  packageName: pack.packageName,
@@ -175,16 +197,33 @@ function buildContribFileEntries(inspection) {
175
197
  }
176
198
  return out;
177
199
  }
200
+ /**
201
+ * Where a registry `sourceFile` lives, as a project-relative path. Registries
202
+ * report a PACK-relative path for pack entries and a PROJECT-relative one for
203
+ * local entries; resolving either against `process.cwd()` (as this used to)
204
+ * made the inventory cwd-dependent and broke nested-id suppression.
205
+ */
206
+ function sourceFileResolver(inspection) {
207
+ const projectRoot = inspection.projectRoot;
208
+ const packRoots = new Map();
209
+ for (const p of inspection.packs.validPacks ?? [])
210
+ packRoots.set(p.packageName, p.packageRoot);
211
+ return (file, packageName) => {
212
+ const abs = nodePath.isAbsolute(file)
213
+ ? file
214
+ : nodePath.resolve((packageName && packRoots.get(packageName)) || projectRoot, file);
215
+ return nodePath.relative(projectRoot, abs) || abs;
216
+ };
217
+ }
178
218
  async function loadStructuralEntries(inspection) {
179
219
  const byKindAndFile = new Map();
180
220
  const structuralFiles = new Map();
181
221
  const structuralIds = new Map();
182
- const projectRoot = inspection.projectRoot;
183
- const rel = (abs) => abs ? nodePath.relative(projectRoot, abs) || abs : undefined;
222
+ const toRel = sourceFileResolver(inspection);
184
223
  const record = (kind, file, entry) => {
185
224
  if (!file)
186
225
  return;
187
- const relPath = rel(file);
226
+ const relPath = toRel(file, entry.packageName);
188
227
  const kindKey = kind;
189
228
  let m = byKindAndFile.get(kindKey);
190
229
  if (!m) {
@@ -213,12 +252,16 @@ async function loadStructuralEntries(inspection) {
213
252
  const pkg = entry.packageName ?? '__local__';
214
253
  idSet.add(`${pkg}:${entry.id}`);
215
254
  };
255
+ /** Source attribution for an inspection-backed id (knowledge/rule/path/template/pipeline/preset/boundary). */
256
+ const attribution = (src) => src?.type === 'pack'
257
+ ? { source: ContributionSource.Pack, ...(src.packageName ? { packageName: src.packageName } : {}) }
258
+ : { source: ContributionSource.Local };
216
259
  // Knowledge / rules / paths / templates / pipelines come from inspection.
217
260
  for (const k of inspection.knowledgeEntries) {
218
261
  record(ContributionKind.Knowledge, k.source?.origin, {
219
262
  id: k.id,
220
263
  ...(k.title ? { title: k.title } : {}),
221
- source: ContributionSource.Local,
264
+ ...attribution(inspection.entrySources.get(k.id)),
222
265
  });
223
266
  }
224
267
  try {
@@ -227,7 +270,7 @@ async function loadStructuralEntries(inspection) {
227
270
  record(ContributionKind.Rule, r.source?.origin, {
228
271
  id: r.id,
229
272
  ...(r.title ? { title: r.title } : {}),
230
- source: ContributionSource.Local,
273
+ ...attribution(inspection.entrySources.get(r.id)),
231
274
  });
232
275
  }
233
276
  }
@@ -240,7 +283,7 @@ async function loadStructuralEntries(inspection) {
240
283
  record(ContributionKind.Path, p.source?.origin, {
241
284
  id: p.id,
242
285
  ...(p.title ? { title: p.title } : {}),
243
- source: ContributionSource.Local,
286
+ ...attribution(inspection.entrySources.get(p.id)),
244
287
  });
245
288
  }
246
289
  }
@@ -250,10 +293,11 @@ async function loadStructuralEntries(inspection) {
250
293
  try {
251
294
  const templates = inspection.templateRegistry?.list?.() ?? [];
252
295
  for (const t of templates) {
253
- record(ContributionKind.Template, t.source?.origin, {
296
+ const src = inspection.templateSources.get(t.id);
297
+ record(ContributionKind.Template, src?.file, {
254
298
  id: t.id,
255
299
  ...(t.description ? { title: t.description } : {}),
256
- source: ContributionSource.Local,
300
+ ...attribution(src),
257
301
  });
258
302
  }
259
303
  }
@@ -263,151 +307,77 @@ async function loadStructuralEntries(inspection) {
263
307
  try {
264
308
  const pipelines = inspection.pipelineRegistry?.list?.() ?? [];
265
309
  for (const p of pipelines) {
266
- record(ContributionKind.Pipeline, p.source?.origin, {
267
- id: p.id,
268
- ...(p.title ? { title: p.title } : {}),
269
- source: ContributionSource.Local,
270
- });
271
- }
272
- }
273
- catch {
274
- // ignore
275
- }
276
- // Playbooks — these were a major source of nested step.id false positives.
277
- try {
278
- const playbooks = await listPlaybooks(inspection);
279
- for (const p of playbooks) {
280
- record(ContributionKind.Playbook, p.sourceFile, {
310
+ const src = inspection.pipelineSources.get(p.id);
311
+ record(ContributionKind.Pipeline, src?.file ?? p.source?.origin, {
281
312
  id: p.id,
282
313
  ...(p.title ? { title: p.title } : {}),
283
- source: p.source === 'pack' ? ContributionSource.Pack : ContributionSource.Local,
284
- ...(p.packageName ? { packageName: p.packageName } : {}),
285
- });
286
- }
287
- }
288
- catch {
289
- // ignore
290
- }
291
- // Conventions, helpers, routing hints, registration hints, contract templates,
292
- // migration profiles — all loader-backed today.
293
- try {
294
- const entries = await listConventions(inspection);
295
- for (const e of entries) {
296
- record(ContributionKind.Convention, e.sourceFile, {
297
- id: e.convention.id,
298
- ...(e.convention.title
299
- ? { title: e.convention.title }
300
- : {}),
301
- source: e.source === 'pack'
302
- ? ContributionSource.Pack
303
- : ContributionSource.Local,
304
- ...(e.packageName ? { packageName: e.packageName } : {}),
314
+ ...attribution(src),
305
315
  });
306
316
  }
307
317
  }
308
318
  catch {
309
319
  // ignore
310
320
  }
321
+ // Presets and boundary rules: inspection-time registries with a source map.
322
+ // A built-in preset is not a contribution (its source file reads `builtin`).
311
323
  try {
312
- const builtIns = HELPERS;
313
- for (const h of builtIns) {
314
- // Built-in helpers don't have a file; skip the structural mapping.
315
- void h;
316
- }
317
- const packHelpers = await listPackHelpers(inspection);
318
- for (const e of packHelpers) {
319
- record(ContributionKind.Helper, e.sourceFile, {
320
- id: e.helper.id,
321
- ...(e.helper.description
322
- ? { title: e.helper.description }
323
- : {}),
324
- source: ContributionSource.Pack,
325
- ...(e.packageName ? { packageName: e.packageName } : {}),
326
- });
327
- }
328
- }
329
- catch {
330
- // ignore
331
- }
332
- try {
333
- const entries = await listTaskRoutingHints(inspection);
334
- for (const e of entries) {
335
- record(ContributionKind.TaskRoutingHint, e.sourceFile, {
336
- id: e.hint.id,
337
- ...(e.hint.title ? { title: e.hint.title } : {}),
338
- source: e.source === 'pack'
339
- ? ContributionSource.Pack
340
- : ContributionSource.Local,
341
- ...(e.packageName ? { packageName: e.packageName } : {}),
342
- });
324
+ for (const p of inspection.presetRegistry?.list?.() ?? []) {
325
+ const src = inspection.presetSources.get(p.id);
326
+ if (!src?.file || src.file === 'builtin')
327
+ continue;
328
+ record(ContributionKind.Preset, src.file, { id: p.id, ...(p.title ? { title: p.title } : {}), ...attribution(src) });
343
329
  }
344
330
  }
345
331
  catch {
346
332
  // ignore
347
333
  }
348
- // Registration hints don't have a dedicated `ContributionKind` today — they
349
- // ship through templates' metadata + the registration-hint registry — so
350
- // we deliberately skip them in the structural map. The self-config doctor
351
- // surfaces broken registration-hint refs via its own check.
352
- await Promise.resolve();
353
- void listRegistrationHints;
354
334
  try {
355
- const pair = await loadAllContractTemplates(inspection);
356
- for (const e of pair.entries) {
357
- record(ContributionKind.ContractTemplate, e.sourceFile, {
358
- id: e.template.id,
359
- ...(e.template.title
360
- ? { title: e.template.title }
361
- : {}),
362
- source: e.source === 'pack'
363
- ? ContributionSource.Pack
364
- : ContributionSource.Local,
365
- ...(e.packageName ? { packageName: e.packageName } : {}),
366
- });
335
+ for (const r of inspection.boundaryRegistry?.list?.() ?? []) {
336
+ const src = inspection.boundarySources.get(r.id);
337
+ if (!src?.file)
338
+ continue;
339
+ record(ContributionKind.Boundary, src.file, { id: r.id, ...(r.title ? { title: r.title } : {}), ...attribution(src) });
367
340
  }
368
341
  }
369
342
  catch {
370
343
  // ignore
371
344
  }
372
- try {
373
- const profiles = await listMigrationProfilesFromPacks(inspection);
374
- for (const p of profiles) {
375
- record(ContributionKind.MigrationProfile, p.sourceFile, {
376
- id: p.id,
377
- ...(p.title ? { title: p.title } : {}),
378
- source: ContributionSource.Pack,
379
- ...(p.packageName ? { packageName: p.packageName } : {}),
380
- });
381
- }
382
- }
383
- catch {
384
- // ignore
345
+ // Every REGISTRY kind — helpers, conventions, routing / registration hints,
346
+ // contract templates, migration profiles, scaffold patterns, playbooks,
347
+ // constructs + facets, search tuning, decisions, policy checks, feedback
348
+ // rules, tests, delegate recipes, framework extractors, the gate planes — in
349
+ // ONE run of THE registry-outcome table, which also reports what each loader
350
+ // refused and which files failed to load.
351
+ const outcomes = await collectRegistryOutcomes(inspection);
352
+ for (const a of outcomes.accepted) {
353
+ record(a.kind, a.file, {
354
+ id: a.id,
355
+ ...(a.title ? { title: a.title } : {}),
356
+ source: a.packageName ? ContributionSource.Pack : ContributionSource.Local,
357
+ ...(a.packageName ? { packageName: a.packageName } : {}),
358
+ });
385
359
  }
386
360
  return {
387
361
  byKindAndFile: byKindAndFile,
388
362
  structuralFiles: structuralFiles,
389
363
  structuralIds: structuralIds,
364
+ loadFailures: outcomes.loadFailures,
365
+ rejections: outcomes.rejections,
390
366
  };
391
367
  }
392
368
  /**
393
- * Build the inventory. Read-only. Never imports pack code beyond the
394
- * registry loaders that already do.
395
- *
396
- * Structural-first extraction. For kinds with a dedicated loader, the
397
- * inventory uses the loader's authoritative ids and **suppresses the
398
- * regex fallback** for those same source files. This eliminates the
399
- * nested-step-id false positives that previously produced duplicate /
400
- * conflict noise.
369
+ * Build the inventory WITHOUT consulting the structural loaders — a regex-only
370
+ * compatibility wrapper. Every regex id is marked `warning`
371
+ * ("unverified: loader not consulted") unless the inspection-time loader
372
+ * already imported that file cleanly; known load failures are still `error`.
373
+ * Prefer {@link buildPackContributionsInventoryAsync}.
401
374
  */
402
375
  export function buildPackContributionsInventory(inspection) {
403
376
  return buildPackContributionsInventorySync(inspection, null);
404
377
  }
405
378
  /**
406
- * Async variant that loads structural per-kind entries first.
407
- *
408
- * Production callers should prefer this over the sync wrapper since it
409
- * provides the noise-free output. The sync wrapper exists for backward
410
- * compatibility with callers that haven't been awaited yet.
379
+ * The inventory with structural per-kind entries loaded first — the
380
+ * noise-free, honest variant every surface should use.
411
381
  */
412
382
  export async function buildPackContributionsInventoryAsync(inspection) {
413
383
  const structural = await loadStructuralEntries(inspection);
@@ -416,13 +386,53 @@ export async function buildPackContributionsInventoryAsync(inspection) {
416
386
  function buildPackContributionsInventorySync(inspection, structural) {
417
387
  const entriesByKind = {};
418
388
  const entries = [];
389
+ const conflicts = [];
419
390
  const fileGroups = buildContribFileEntries(inspection);
391
+ const failures = collectContributionLoadFailures(inspection, structural?.loadFailures ?? []);
392
+ // THE rejection channel: inspection-time loaders ∪ registry loaders.
393
+ const rejections = collectContributionRejections(inspection, structural?.rejections ?? []);
394
+ const rejectedIdsByFile = new Map();
395
+ for (const r of rejections) {
396
+ if (r.entryId === undefined)
397
+ continue;
398
+ const m = rejectedIdsByFile.get(r.file) ?? new Map();
399
+ if (!m.has(r.entryId))
400
+ m.set(r.entryId, r);
401
+ rejectedIdsByFile.set(r.file, m);
402
+ }
403
+ // THE files a loader READ, per kind (async only): every file it accepted an
404
+ // entry from AND every file it refused an entry of. The regex never runs on
405
+ // a file its loader already judged — a file whose every entry was rejected
406
+ // used to be scraped, its refused ids counted as contributions (`By kind`,
407
+ // `totals`, the header) and grouped across packs into a false error-level
408
+ // duplicate (round 12 review, A-2).
409
+ const judgedFiles = new Map();
410
+ if (structural) {
411
+ for (const [kindKey, files] of structural.structuralFiles)
412
+ judgedFiles.set(kindKey, new Set(files));
413
+ for (const r of rejections) {
414
+ const rel = nodePath.relative(inspection.projectRoot, r.file) || r.file;
415
+ const set = judgedFiles.get(r.kind) ?? new Set();
416
+ set.add(rel);
417
+ judgedFiles.set(r.kind, set);
418
+ }
419
+ }
420
+ const scrapedByFile = new Map();
421
+ const failedFilesReported = new Set();
422
+ // Files the inspection-time loaders imported cleanly (used by the sync wrapper).
423
+ const loadedOk = new Set((inspection.loaderDiagnostics ?? [])
424
+ .filter((d) => d.status === 'ok')
425
+ .map((d) => nodePath.resolve(d.filePath)));
426
+ const push = (entry) => {
427
+ (entriesByKind[entry.kind] ??= []).push(entry);
428
+ entries.push(entry);
429
+ };
420
430
  // First, emit structural entries (authoritative ids).
421
431
  if (structural) {
422
432
  for (const [kindKey, files] of structural.byKindAndFile) {
423
433
  for (const [relPath, list] of files) {
424
434
  for (const s of list) {
425
- const entry = {
435
+ push({
426
436
  kind: kindKey,
427
437
  id: s.id,
428
438
  ...(s.title ? { title: s.title } : {}),
@@ -432,51 +442,68 @@ function buildPackContributionsInventorySync(inspection, structural) {
432
442
  validation: 'ok',
433
443
  extractionMode: 'structural',
434
444
  confidence: 'high',
435
- };
436
- (entriesByKind[kindKey] ??= []).push(entry);
437
- entries.push(entry);
445
+ });
438
446
  }
439
447
  }
440
448
  }
441
449
  }
442
450
  const ingestFile = (group, file) => {
443
- const rel = nodePath.relative(inspection.projectRoot, file) || file;
444
- // Skip regex extraction when the structural loader already covered
445
- // this (kind, file) pair. Otherwise nested step.id / anchor.id / sub-object
446
- // ids re-appear as top-level contribution ids, producing duplicate noise.
447
- const handled = structural?.structuralFiles.get(group.kind)?.has(rel);
448
- if (handled)
451
+ const abs = nodePath.resolve(file);
452
+ const rel = nodePath.relative(inspection.projectRoot, abs) || abs;
453
+ // Skip regex extraction when a loader already READ this (kind, file) pair
454
+ // — accepted or refused an entry of it. Otherwise nested step.id /
455
+ // anchor.id / sub-object ids re-appear as top-level contribution ids, and a
456
+ // fully-rejected file's refused ids read as contributions.
457
+ const handledKinds = [group.kind, ...(ALSO_HANDLED_BY[group.kind] ?? [])];
458
+ if (handledKinds.some((k) => judgedFiles.get(k)?.has(rel)))
449
459
  return;
460
+ const failure = failures.get(abs);
461
+ const src = {
462
+ source: group.source,
463
+ ...(group.packageName ? { packageName: group.packageName } : {}),
464
+ sourceFile: rel,
465
+ };
466
+ if (failure && !failedFilesReported.has(abs)) {
467
+ failedFilesReported.add(abs);
468
+ conflicts.push({
469
+ kind: ConflictKind.InvalidContribution,
470
+ contributionKind: group.kind,
471
+ id: rel,
472
+ sources: [src],
473
+ severity: 'error',
474
+ message: `${rel} failed to load (${failure.message}) — nothing in it takes effect; any id listed for it was scraped by regex.`,
475
+ nextCommand: group.packageRoot
476
+ ? `shrk packs release-check ${nodePath.relative(inspection.projectRoot, group.packageRoot) || '.'}`
477
+ : 'shrk doctor',
478
+ });
479
+ }
450
480
  const content = safeRead(file);
451
481
  if (content === null) {
452
- const entry = {
482
+ push({
453
483
  kind: group.kind,
454
484
  id: rel,
455
- source: group.source,
456
- ...(group.packageName ? { packageName: group.packageName } : {}),
457
- sourceFile: rel,
485
+ ...src,
458
486
  validation: 'error',
459
487
  validationMessage: 'file unreadable',
460
- };
461
- (entriesByKind[group.kind] ??= []).push(entry);
462
- entries.push(entry);
488
+ });
463
489
  return;
464
490
  }
465
491
  const extracted = extractIdsFromFile(content);
492
+ const rejectedHere = rejectedIdsByFile.get(abs);
466
493
  if (extracted.length === 0) {
467
- const entry = {
494
+ push({
468
495
  kind: group.kind,
469
496
  id: rel,
470
- source: group.source,
471
- ...(group.packageName ? { packageName: group.packageName } : {}),
472
- sourceFile: rel,
473
- validation: 'warning',
474
- validationMessage: 'no `id:` extracted; loader may still see entries',
497
+ ...src,
498
+ validation: failure || rejectedHere ? 'error' : 'warning',
499
+ validationMessage: failure
500
+ ? `file failed to load (${failure.message})`
501
+ : rejectedHere
502
+ ? 'every entry the file declares was rejected by its loader (see rejections)'
503
+ : 'no `id:` extracted; loader may still see entries',
475
504
  extractionMode: 'file-only',
476
505
  confidence: 'low',
477
- };
478
- (entriesByKind[group.kind] ??= []).push(entry);
479
- entries.push(entry);
506
+ });
480
507
  return;
481
508
  }
482
509
  // Skip regex entries whose (kind, packageName||local, id) triple
@@ -488,24 +515,48 @@ function buildPackContributionsInventorySync(inspection, structural) {
488
515
  for (const ex of extracted) {
489
516
  if (idsHandled && idsHandled.has(`${groupPkg}:${ex.id}`))
490
517
  continue;
491
- const entry = {
518
+ const rejection = rejectedHere?.get(ex.id);
519
+ let validation;
520
+ let validationMessage;
521
+ if (failure) {
522
+ validation = 'error';
523
+ validationMessage = `file failed to load (${failure.message}); id scraped by regex — this contribution does NOT take effect`;
524
+ (scrapedByFile.get(abs) ?? scrapedByFile.set(abs, []).get(abs)).push(ex.id);
525
+ }
526
+ else if (rejection) {
527
+ // The loader read this entry and REFUSED it — never `ok`, never merely
528
+ // unverified. With the loaders consulted it is in `rejections`, and a
529
+ // refused id is no contribution row at all (round 12 review, A-2).
530
+ if (structural)
531
+ continue;
532
+ validation = 'error';
533
+ validationMessage = `rejected by the ${rejection.kind} loader — ${rejection.reasons.join('; ')}; this contribution does NOT take effect`;
534
+ }
535
+ else if (!structural) {
536
+ validation = loadedOk.has(abs) ? 'ok' : 'warning';
537
+ validationMessage = loadedOk.has(abs)
538
+ ? undefined
539
+ : 'unverified: loader not consulted (use the async inventory)';
540
+ }
541
+ else {
542
+ // Every kind is loader-backed (round 12): a regex id means the loader
543
+ // returned no entry for it — unverified, never `ok`.
544
+ validation = 'warning';
545
+ validationMessage = 'regex-derived; the loader returned no entries for this file';
546
+ }
547
+ push({
492
548
  kind: group.kind,
493
549
  id: ex.id,
494
550
  ...(ex.title ? { title: ex.title } : {}),
495
- source: group.source,
496
- ...(group.packageName ? { packageName: group.packageName } : {}),
497
- sourceFile: rel,
498
- validation: 'ok',
551
+ ...src,
552
+ validation,
553
+ ...(validationMessage ? { validationMessage } : {}),
499
554
  // Regex-based id extraction can pick up nested step.id / anchor.id /
500
555
  // ref.id values. Tag these entries clearly so the conflict detector
501
- // downgrades same-file collisions to info. The structural loader is
502
- // preferred where available; this fallback fires only for kinds
503
- // without a dedicated registry.
556
+ // downgrades same-file collisions to info.
504
557
  extractionMode: 'regex-fallback',
505
- confidence: 'medium',
506
- };
507
- (entriesByKind[group.kind] ??= []).push(entry);
508
- entries.push(entry);
558
+ confidence: failure ? 'low' : 'medium',
559
+ });
509
560
  }
510
561
  };
511
562
  for (const group of fileGroups) {
@@ -515,10 +566,14 @@ function buildPackContributionsInventorySync(inspection, structural) {
515
566
  const totals = {};
516
567
  for (const [kind, list] of Object.entries(entriesByKind))
517
568
  totals[kind] = list.length;
518
- const conflicts = [];
519
569
  for (const [kind, list] of Object.entries(entriesByKind)) {
520
570
  const byId = new Map();
521
571
  for (const e of list) {
572
+ // An id that does not take effect — scraped from a file that failed to
573
+ // load, or refused by its loader — cannot collide at runtime: its own
574
+ // load failure / rejection is already the error (round 12 review, A-2).
575
+ if (e.validation === 'error')
576
+ continue;
522
577
  const arr = byId.get(e.id) ?? [];
523
578
  arr.push(e);
524
579
  byId.set(e.id, arr);
@@ -534,34 +589,27 @@ function buildPackContributionsInventorySync(inspection, structural) {
534
589
  // (informational; the loader behavior is documented per-kind).
535
590
  const hasLocal = arr.some((e) => e.source === ContributionSource.Local);
536
591
  const hasPack = arr.some((e) => e.source === ContributionSource.Pack);
592
+ const sources = arr.map((e) => {
593
+ const s = {
594
+ source: e.source,
595
+ };
596
+ if (e.packageName)
597
+ s.packageName = e.packageName;
598
+ if (e.sourceFile)
599
+ s.sourceFile = e.sourceFile;
600
+ return s;
601
+ });
537
602
  if (hasLocal && hasPack) {
538
603
  conflicts.push({
539
604
  kind: ConflictKind.ShadowedPackConfig,
540
605
  contributionKind: kind,
541
606
  id,
542
- sources: arr.map((e) => {
543
- const src = {
544
- source: e.source,
545
- };
546
- if (e.packageName)
547
- src.packageName = e.packageName;
548
- if (e.sourceFile)
549
- src.sourceFile = e.sourceFile;
550
- return src;
551
- }),
607
+ sources,
552
608
  severity: 'info',
553
609
  message: `Local "${kind}" "${id}" shadows pack contribution. Local entries win on duplicate ids.`,
554
610
  });
555
611
  }
556
612
  else {
557
- // Downgrade conflicts that come from a single source file
558
- // when ALL participating entries are regex-fallback extractions.
559
- // These are almost certainly nested `id:` fields (e.g.
560
- // playbook.steps[].id, pipeline.steps[].id) masquerading as
561
- // separate top-level contribution ids.
562
- const allRegexFallback = arr.every((e) => e.extractionMode === 'regex-fallback');
563
- const sourceFiles = new Set(arr.map((e) => e.sourceFile).filter((s) => Boolean(s)));
564
- const singleSourceFile = sourceFiles.size === 1;
565
613
  // Self-acknowledged false positive: when ALL participating entries come
566
614
  // from a SINGLE source file via regex fallback, the "duplicate" is
567
615
  // almost certainly nested `id:` fields (playbook.steps[].id /
@@ -569,22 +617,15 @@ function buildPackContributionsInventorySync(inspection, structural) {
569
617
  // contribution ids. Don't emit noise for it — a genuine duplicate would
570
618
  // span multiple files or include a non-regex-fallback entry and still
571
619
  // surface as an error below.
572
- if (allRegexFallback && singleSourceFile)
620
+ const allRegexFallback = arr.every((e) => e.extractionMode === 'regex-fallback');
621
+ const sourceFiles = new Set(arr.map((e) => e.sourceFile).filter((s) => Boolean(s)));
622
+ if (allRegexFallback && sourceFiles.size === 1)
573
623
  continue;
574
624
  conflicts.push({
575
625
  kind: conflictKind,
576
626
  contributionKind: kind,
577
627
  id,
578
- sources: arr.map((e) => {
579
- const src = {
580
- source: e.source,
581
- };
582
- if (e.packageName)
583
- src.packageName = e.packageName;
584
- if (e.sourceFile)
585
- src.sourceFile = e.sourceFile;
586
- return src;
587
- }),
628
+ sources,
588
629
  severity: 'error',
589
630
  message: `Duplicate "${kind}" id "${id}" loaded from ${arr.length} sources.`,
590
631
  nextCommand: `shrk packs contributions --json | jq '.entries[] | select(.id=="${id}" and .kind=="${kind}")'`,
@@ -592,59 +633,41 @@ function buildPackContributionsInventorySync(inspection, structural) {
592
633
  }
593
634
  }
594
635
  }
595
- // Stale-signature warning: surfaced as a conflict so a single doctor view
596
- // can highlight unsigned-by-secret manifests.
636
+ // Stale-signature: read from THE pack-asset freshness authority (content
637
+ // digests recorded at sign time), never from mtimes. Dev-signed packs are
638
+ // re-staled by every local build and load fine locally, so their divergence
639
+ // is not a conflict (mirrors pack-signature-status's dev downgrade).
597
640
  for (const pack of inspection.packs.validPacks ?? []) {
598
- const sig = pack.manifest?.signature;
599
- if (!sig)
641
+ if (!pack.manifest?.signature)
600
642
  continue;
601
- // Dev-signed packs are re-staled by every local build and load fine
602
- // locally, so suppress the stale-signature conflict for them (mirrors the
603
- // dev-aware downgrade in pack-signature-status.ts). Production signed packs
604
- // still surface as stale.
605
- if (sig.dev === true)
643
+ const freshness = detectPackAssetFreshness(pack);
644
+ if (freshness.signature.state !== 'diverged' || freshness.signature.dev)
606
645
  continue;
607
- // The loader already validates HMAC strictly; we only surface stale
608
- // when the manifest content has obviously been edited without re-signing.
609
- // Heuristic: signature timestamp older than any contribution file mtime.
610
- let staleSummary = null;
611
- try {
612
- const sigMs = new Date(sig.signedAt).getTime();
613
- const contributions = pack.manifest?.contributions ?? {};
614
- for (const slot of Object.values(KIND_TO_SLOT)) {
615
- const rels = contributions[slot] ?? [];
616
- for (const rel of rels) {
617
- const abs = nodePath.resolve(pack.packageRoot, rel);
618
- try {
619
- const stat = statSync(abs);
620
- if (stat.mtimeMs > sigMs + 1000) {
621
- staleSummary = `${rel} (mtime ${new Date(stat.mtimeMs).toISOString()}) is newer than signature (${sig.signedAt})`;
622
- break;
623
- }
624
- }
625
- catch {
626
- continue;
627
- }
628
- }
629
- if (staleSummary)
630
- break;
631
- }
632
- }
633
- catch {
634
- // ignore
635
- }
636
- if (staleSummary) {
637
- conflicts.push({
638
- kind: ConflictKind.StaleSignature,
639
- contributionKind: ContributionKind.Docs,
640
- id: pack.packageName,
641
- sources: [{ source: ContributionSource.Pack, packageName: pack.packageName, sourceFile: pack.packageRoot }],
642
- severity: 'warning',
643
- message: `Pack ${pack.packageName} signature is stale: ${staleSummary}`,
644
- nextCommand: `SHARKCRAFT_PACK_SECRET=<secret> shrk packs sign ${nodePath.relative(inspection.projectRoot, pack.packageRoot)}`,
645
- });
646
- }
646
+ conflicts.push({
647
+ kind: ConflictKind.StaleSignature,
648
+ contributionKind: ContributionKind.Docs,
649
+ id: pack.packageName,
650
+ sources: [{ source: ContributionSource.Pack, packageName: pack.packageName, sourceFile: pack.packageRoot }],
651
+ severity: 'warning',
652
+ message: describePackAssetFreshness(freshness).signature ?? `Pack ${pack.packageName} signature is stale.`,
653
+ nextCommand: `SHARKCRAFT_PACK_SECRET=<secret> shrk packs sign ${nodePath.relative(inspection.projectRoot, pack.packageRoot)}`,
654
+ });
647
655
  }
656
+ const extractionTotals = {
657
+ structural: entries.filter((e) => e.extractionMode === 'structural').length,
658
+ regexFallback: entries.filter((e) => e.extractionMode === 'regex-fallback').length,
659
+ fileOnly: entries.filter((e) => e.extractionMode === 'file-only').length,
660
+ rejected: rejections.length,
661
+ };
662
+ const loadFailures = [...failures.values()]
663
+ .map((f) => ({
664
+ file: nodePath.relative(inspection.projectRoot, f.file) || f.file,
665
+ kind: f.kind,
666
+ ...(f.packageName ? { packageName: f.packageName } : {}),
667
+ message: f.message,
668
+ scrapedIds: [...(scrapedByFile.get(f.file) ?? [])],
669
+ }))
670
+ .sort((a, b) => a.file.localeCompare(b.file));
648
671
  return {
649
672
  schema: PACK_CONTRIBUTIONS_INVENTORY_SCHEMA,
650
673
  generatedAt: new Date().toISOString(),
@@ -659,20 +682,93 @@ function buildPackContributionsInventorySync(inspection, structural) {
659
682
  root: p.packageRoot,
660
683
  signaturePresent: Boolean(p.manifest?.signature),
661
684
  })),
685
+ extractionTotals,
686
+ loadFailures,
687
+ rejections: rejections.map((r) => ({
688
+ file: nodePath.relative(inspection.projectRoot, r.file) || r.file,
689
+ kind: r.kind,
690
+ ...(r.packageName ? { packageName: r.packageName } : {}),
691
+ index: r.index,
692
+ ...(r.exportName ? { exportName: r.exportName } : {}),
693
+ ...(r.entryId !== undefined ? { entryId: r.entryId } : {}),
694
+ reasons: r.reasons,
695
+ cause: r.cause,
696
+ })),
697
+ mode: structural ? 'async' : 'sync',
662
698
  };
663
699
  }
700
+ /** Per-kind extraction-mode counts over `entries` (so a filtered view renders its own numbers). */
701
+ function modeCountsByKind(entries) {
702
+ const out = new Map();
703
+ for (const e of entries) {
704
+ const c = out.get(e.kind) ?? { total: 0, structural: 0, regexFallback: 0, fileOnly: 0 };
705
+ c.total += 1;
706
+ if (e.extractionMode === 'structural')
707
+ c.structural += 1;
708
+ else if (e.extractionMode === 'regex-fallback')
709
+ c.regexFallback += 1;
710
+ else if (e.extractionMode === 'file-only')
711
+ c.fileOnly += 1;
712
+ out.set(e.kind, c);
713
+ }
714
+ return out;
715
+ }
716
+ function modeClause(c) {
717
+ const parts = [];
718
+ if (c.structural > 0)
719
+ parts.push(`structural ${c.structural}`);
720
+ if (c.regexFallback > 0)
721
+ parts.push(`regex-fallback ${c.regexFallback}`);
722
+ if (c.fileOnly > 0)
723
+ parts.push(`file-only ${c.fileOnly}`);
724
+ return parts.length > 0 ? `(${parts.join(' · ')})` : '';
725
+ }
726
+ function extractionLine(entries, rejected) {
727
+ const s = entries.filter((e) => e.extractionMode === 'structural').length;
728
+ const r = entries.filter((e) => e.extractionMode === 'regex-fallback').length;
729
+ const f = entries.filter((e) => e.extractionMode === 'file-only').length;
730
+ return `${s} structural · ${r} regex-fallback (unverified) · ${f} file-only${rejected > 0 ? ` · ${rejected} REJECTED` : ''}`;
731
+ }
664
732
  export function renderInventoryText(inv) {
665
733
  const lines = [];
734
+ const rejections = inv.rejections ?? [];
666
735
  lines.push(`=== Pack contributions inventory (${inv.entries.length} entries) ===`);
667
736
  lines.push(` generatedAt ${inv.generatedAt}`);
668
737
  lines.push(` packs ${inv.packs.length}`);
669
738
  for (const p of inv.packs)
670
739
  lines.push(` • ${p.name}@${p.version} (sig: ${p.signaturePresent ? 'present' : 'absent'})`);
740
+ lines.push(` extraction ${extractionLine(inv.entries, rejections.length)}`);
741
+ if (inv.mode === 'sync')
742
+ lines.push(' mode sync — loaders NOT consulted; regex ids are unverified');
671
743
  lines.push('');
672
744
  lines.push(`By kind:`);
673
- for (const [k, n] of Object.entries(inv.totals).sort())
674
- lines.push(` ${k.padEnd(28)} ${n}`);
745
+ const byKind = modeCountsByKind(inv.entries);
746
+ for (const k of [...byKind.keys()].sort()) {
747
+ const c = byKind.get(k);
748
+ lines.push(` ${k.padEnd(28)} ${String(c.total).padStart(4)} ${modeClause(c)}`.trimEnd());
749
+ }
675
750
  lines.push('');
751
+ const failures = inv.loadFailures ?? [];
752
+ if (failures.length > 0) {
753
+ lines.push(`Load failures (${failures.length}):`);
754
+ for (const f of failures) {
755
+ lines.push(` ✗ ${f.file} [${f.kind}${f.packageName ? `, ${f.packageName}` : ''}] — ${f.message}`);
756
+ lines.push(` regex-scraped ids NOT loaded: ${f.scrapedIds.length > 0 ? f.scrapedIds.join(', ') : '(none)'}`);
757
+ }
758
+ lines.push('');
759
+ }
760
+ if (rejections.length > 0) {
761
+ lines.push(`Rejected entries (${rejections.length}) — refused by their loader, NOT in effect:`);
762
+ let lastFile = '';
763
+ for (const r of rejections) {
764
+ if (r.file !== lastFile) {
765
+ lines.push(` ✗ ${r.file} [${r.kind}${r.packageName ? `, ${r.packageName}` : ''}]`);
766
+ lastFile = r.file;
767
+ }
768
+ lines.push(` ${formatEntryRejection(r)}`);
769
+ }
770
+ lines.push('');
771
+ }
676
772
  if (inv.conflicts.length > 0) {
677
773
  lines.push(`Conflicts (${inv.conflicts.length}):`);
678
774
  for (const c of inv.conflicts.slice(0, 50)) {
@@ -688,6 +784,7 @@ export function renderInventoryText(inv) {
688
784
  }
689
785
  export function renderInventoryMarkdown(inv) {
690
786
  const lines = [];
787
+ const rejections = inv.rejections ?? [];
691
788
  lines.push('# Pack contributions inventory');
692
789
  lines.push('');
693
790
  lines.push(`- generatedAt: ${inv.generatedAt}`);
@@ -695,12 +792,43 @@ export function renderInventoryMarkdown(inv) {
695
792
  for (const p of inv.packs) {
696
793
  lines.push(` - **${p.name}** \`${p.version}\` (signature ${p.signaturePresent ? 'present' : 'absent'})`);
697
794
  }
795
+ lines.push(`- extraction: ${extractionLine(inv.entries, rejections.length)}`);
796
+ if (inv.mode === 'sync')
797
+ lines.push('- mode: sync — loaders NOT consulted; regex ids are unverified');
698
798
  lines.push('');
699
799
  lines.push('## By kind');
700
- lines.push('| Kind | Count |');
701
- lines.push('| --- | --- |');
702
- for (const [k, n] of Object.entries(inv.totals).sort())
703
- lines.push(`| \`${k}\` | ${n} |`);
800
+ lines.push('| Kind | Count | Structural | Regex-fallback | File-only |');
801
+ lines.push('| --- | --- | --- | --- | --- |');
802
+ const byKind = modeCountsByKind(inv.entries);
803
+ for (const k of [...byKind.keys()].sort()) {
804
+ const c = byKind.get(k);
805
+ lines.push(`| \`${k}\` | ${c.total} | ${c.structural} | ${c.regexFallback} | ${c.fileOnly} |`);
806
+ }
807
+ lines.push('');
808
+ lines.push('## Load failures');
809
+ const failures = inv.loadFailures ?? [];
810
+ if (failures.length === 0) {
811
+ lines.push('None.');
812
+ }
813
+ else {
814
+ lines.push('| File | Kind | Pack | Error | Regex-scraped ids NOT loaded |');
815
+ lines.push('| --- | --- | --- | --- | --- |');
816
+ for (const f of failures) {
817
+ lines.push(`| \`${f.file}\` | ${f.kind} | ${f.packageName ?? ''} | ${f.message} | ${f.scrapedIds.join(', ')} |`);
818
+ }
819
+ }
820
+ lines.push('');
821
+ lines.push('## Rejected entries');
822
+ if (rejections.length === 0) {
823
+ lines.push('None.');
824
+ }
825
+ else {
826
+ lines.push('| File | Kind | Pack | Entry | Reasons |');
827
+ lines.push('| --- | --- | --- | --- | --- |');
828
+ for (const r of rejections) {
829
+ lines.push(`| \`${r.file}\` | ${r.kind} | ${r.packageName ?? ''} | ${r.entryId !== undefined ? `\`${r.entryId}\`` : '(no id)'} ${r.exportName ?? ''}[${r.index}] | ${r.reasons.join('; ')} |`);
830
+ }
831
+ }
704
832
  lines.push('');
705
833
  lines.push('## Conflicts');
706
834
  if (inv.conflicts.length === 0) {
@@ -718,3 +846,32 @@ export function renderInventoryMarkdown(inv) {
718
846
  export function selectConflicts(inv) {
719
847
  return inv.conflicts;
720
848
  }
849
+ /**
850
+ * Per contribution kind, a pack's declared FILES, ACCEPTED entries and
851
+ * REJECTED entries — THE projection of this inventory that `packs list`,
852
+ * `packs get` and MCP `list_packs` / `get_pack` print (round 12, 12.1b), so
853
+ * a partially-loaded file never looks like a fully-loaded one and every
854
+ * surface counts what `packs contributions` counts. A kind with nothing
855
+ * declared, accepted or rejected is absent.
856
+ */
857
+ export function packEntryCounts(inv, pack) {
858
+ const out = {};
859
+ const row = (kind) => (out[kind] ??= { files: 0, accepted: 0, rejected: 0 });
860
+ for (const slot of CONTRIBUTION_FILE_KEYS) {
861
+ const n = pack.contributionCounts[slot] ?? 0;
862
+ if (n === 0)
863
+ continue;
864
+ row(contributionKindForSlot(slot) ?? slot).files += n;
865
+ }
866
+ for (const e of inv?.entries ?? []) {
867
+ if (e.packageName !== pack.packageName || e.extractionMode !== 'structural')
868
+ continue;
869
+ row(e.kind).accepted += 1;
870
+ }
871
+ for (const r of inv?.rejections ?? []) {
872
+ if (r.packageName !== pack.packageName)
873
+ continue;
874
+ row(r.kind).rejected += 1;
875
+ }
876
+ return out;
877
+ }