@nebulacomponents/citable 1.19.0 → 1.21.0

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 (360) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +12 -1
  3. package/dist/universal/.agents/skills/citable/SKILL.md +11 -2
  4. package/dist/universal/.agents/skills/citable/VERSION +1 -1
  5. package/dist/universal/.agents/skills/citable/manifest.json +24 -12
  6. package/dist/universal/.agents/skills/citable/schemas/action-plan.schema.json +38 -1
  7. package/dist/universal/.agents/skills/citable/schemas/audit-coverage.schema.json +118 -0
  8. package/dist/universal/.agents/skills/citable/schemas/claim-evidence.schema.json +21 -0
  9. package/dist/universal/.agents/skills/citable/schemas/claim-verification.schema.json +18 -0
  10. package/dist/universal/.agents/skills/citable/schemas/collection-result.schema.json +35 -0
  11. package/dist/universal/.agents/skills/citable/schemas/config.schema.json +2 -0
  12. package/dist/universal/.agents/skills/citable/schemas/cro-report.schema.json +8 -1
  13. package/dist/universal/.agents/skills/citable/schemas/derivation.schema.json +18 -0
  14. package/dist/universal/.agents/skills/citable/schemas/external-comparison.schema.json +16 -0
  15. package/dist/universal/.agents/skills/citable/schemas/external-observation.schema.json +32 -0
  16. package/dist/universal/.agents/skills/citable/schemas/finding.schema.json +105 -2
  17. package/dist/universal/.agents/skills/citable/schemas/prompt-set.schema.json +47 -0
  18. package/dist/universal/.agents/skills/citable/schemas/remediation-verification.schema.json +12 -1
  19. package/dist/universal/.agents/skills/citable/schemas/representation-data.schema.json +21 -0
  20. package/dist/universal/.agents/skills/citable/schemas/research-dataset.schema.json +27 -0
  21. package/dist/universal/.agents/skills/citable/schemas/run.schema.json +15 -2
  22. package/dist/universal/.agents/skills/citable/schemas/search-discovery-data.schema.json +20 -0
  23. package/dist/universal/.agents/skills/citable/schemas/search-report.schema.json +8 -1
  24. package/dist/universal/.agents/skills/citable/schemas/summary.schema.json +41 -0
  25. package/dist/universal/.claude/agents/citable/manifest.json +2 -2
  26. package/dist/universal/.claude/skills/citable/SKILL.md +11 -2
  27. package/dist/universal/.claude/skills/citable/VERSION +1 -1
  28. package/dist/universal/.claude/skills/citable/manifest.json +24 -12
  29. package/dist/universal/.claude/skills/citable/schemas/action-plan.schema.json +38 -1
  30. package/dist/universal/.claude/skills/citable/schemas/audit-coverage.schema.json +118 -0
  31. package/dist/universal/.claude/skills/citable/schemas/claim-evidence.schema.json +21 -0
  32. package/dist/universal/.claude/skills/citable/schemas/claim-verification.schema.json +18 -0
  33. package/dist/universal/.claude/skills/citable/schemas/collection-result.schema.json +35 -0
  34. package/dist/universal/.claude/skills/citable/schemas/config.schema.json +2 -0
  35. package/dist/universal/.claude/skills/citable/schemas/cro-report.schema.json +8 -1
  36. package/dist/universal/.claude/skills/citable/schemas/derivation.schema.json +18 -0
  37. package/dist/universal/.claude/skills/citable/schemas/external-comparison.schema.json +16 -0
  38. package/dist/universal/.claude/skills/citable/schemas/external-observation.schema.json +32 -0
  39. package/dist/universal/.claude/skills/citable/schemas/finding.schema.json +105 -2
  40. package/dist/universal/.claude/skills/citable/schemas/prompt-set.schema.json +47 -0
  41. package/dist/universal/.claude/skills/citable/schemas/remediation-verification.schema.json +12 -1
  42. package/dist/universal/.claude/skills/citable/schemas/representation-data.schema.json +21 -0
  43. package/dist/universal/.claude/skills/citable/schemas/research-dataset.schema.json +27 -0
  44. package/dist/universal/.claude/skills/citable/schemas/run.schema.json +15 -2
  45. package/dist/universal/.claude/skills/citable/schemas/search-discovery-data.schema.json +20 -0
  46. package/dist/universal/.claude/skills/citable/schemas/search-report.schema.json +8 -1
  47. package/dist/universal/.claude/skills/citable/schemas/summary.schema.json +41 -0
  48. package/dist/universal/.cursor/skills/citable/SKILL.md +11 -2
  49. package/dist/universal/.cursor/skills/citable/VERSION +1 -1
  50. package/dist/universal/.cursor/skills/citable/manifest.json +24 -12
  51. package/dist/universal/.cursor/skills/citable/schemas/action-plan.schema.json +38 -1
  52. package/dist/universal/.cursor/skills/citable/schemas/audit-coverage.schema.json +118 -0
  53. package/dist/universal/.cursor/skills/citable/schemas/claim-evidence.schema.json +21 -0
  54. package/dist/universal/.cursor/skills/citable/schemas/claim-verification.schema.json +18 -0
  55. package/dist/universal/.cursor/skills/citable/schemas/collection-result.schema.json +35 -0
  56. package/dist/universal/.cursor/skills/citable/schemas/config.schema.json +2 -0
  57. package/dist/universal/.cursor/skills/citable/schemas/cro-report.schema.json +8 -1
  58. package/dist/universal/.cursor/skills/citable/schemas/derivation.schema.json +18 -0
  59. package/dist/universal/.cursor/skills/citable/schemas/external-comparison.schema.json +16 -0
  60. package/dist/universal/.cursor/skills/citable/schemas/external-observation.schema.json +32 -0
  61. package/dist/universal/.cursor/skills/citable/schemas/finding.schema.json +105 -2
  62. package/dist/universal/.cursor/skills/citable/schemas/prompt-set.schema.json +47 -0
  63. package/dist/universal/.cursor/skills/citable/schemas/remediation-verification.schema.json +12 -1
  64. package/dist/universal/.cursor/skills/citable/schemas/representation-data.schema.json +21 -0
  65. package/dist/universal/.cursor/skills/citable/schemas/research-dataset.schema.json +27 -0
  66. package/dist/universal/.cursor/skills/citable/schemas/run.schema.json +15 -2
  67. package/dist/universal/.cursor/skills/citable/schemas/search-discovery-data.schema.json +20 -0
  68. package/dist/universal/.cursor/skills/citable/schemas/search-report.schema.json +8 -1
  69. package/dist/universal/.cursor/skills/citable/schemas/summary.schema.json +41 -0
  70. package/dist/universal/.gemini/skills/citable/SKILL.md +11 -2
  71. package/dist/universal/.gemini/skills/citable/VERSION +1 -1
  72. package/dist/universal/.gemini/skills/citable/manifest.json +24 -12
  73. package/dist/universal/.gemini/skills/citable/schemas/action-plan.schema.json +38 -1
  74. package/dist/universal/.gemini/skills/citable/schemas/audit-coverage.schema.json +118 -0
  75. package/dist/universal/.gemini/skills/citable/schemas/claim-evidence.schema.json +21 -0
  76. package/dist/universal/.gemini/skills/citable/schemas/claim-verification.schema.json +18 -0
  77. package/dist/universal/.gemini/skills/citable/schemas/collection-result.schema.json +35 -0
  78. package/dist/universal/.gemini/skills/citable/schemas/config.schema.json +2 -0
  79. package/dist/universal/.gemini/skills/citable/schemas/cro-report.schema.json +8 -1
  80. package/dist/universal/.gemini/skills/citable/schemas/derivation.schema.json +18 -0
  81. package/dist/universal/.gemini/skills/citable/schemas/external-comparison.schema.json +16 -0
  82. package/dist/universal/.gemini/skills/citable/schemas/external-observation.schema.json +32 -0
  83. package/dist/universal/.gemini/skills/citable/schemas/finding.schema.json +105 -2
  84. package/dist/universal/.gemini/skills/citable/schemas/prompt-set.schema.json +47 -0
  85. package/dist/universal/.gemini/skills/citable/schemas/remediation-verification.schema.json +12 -1
  86. package/dist/universal/.gemini/skills/citable/schemas/representation-data.schema.json +21 -0
  87. package/dist/universal/.gemini/skills/citable/schemas/research-dataset.schema.json +27 -0
  88. package/dist/universal/.gemini/skills/citable/schemas/run.schema.json +15 -2
  89. package/dist/universal/.gemini/skills/citable/schemas/search-discovery-data.schema.json +20 -0
  90. package/dist/universal/.gemini/skills/citable/schemas/search-report.schema.json +8 -1
  91. package/dist/universal/.gemini/skills/citable/schemas/summary.schema.json +41 -0
  92. package/dist/universal/.github/skills/citable/SKILL.md +11 -2
  93. package/dist/universal/.github/skills/citable/VERSION +1 -1
  94. package/dist/universal/.github/skills/citable/manifest.json +24 -12
  95. package/dist/universal/.github/skills/citable/schemas/action-plan.schema.json +38 -1
  96. package/dist/universal/.github/skills/citable/schemas/audit-coverage.schema.json +118 -0
  97. package/dist/universal/.github/skills/citable/schemas/claim-evidence.schema.json +21 -0
  98. package/dist/universal/.github/skills/citable/schemas/claim-verification.schema.json +18 -0
  99. package/dist/universal/.github/skills/citable/schemas/collection-result.schema.json +35 -0
  100. package/dist/universal/.github/skills/citable/schemas/config.schema.json +2 -0
  101. package/dist/universal/.github/skills/citable/schemas/cro-report.schema.json +8 -1
  102. package/dist/universal/.github/skills/citable/schemas/derivation.schema.json +18 -0
  103. package/dist/universal/.github/skills/citable/schemas/external-comparison.schema.json +16 -0
  104. package/dist/universal/.github/skills/citable/schemas/external-observation.schema.json +32 -0
  105. package/dist/universal/.github/skills/citable/schemas/finding.schema.json +105 -2
  106. package/dist/universal/.github/skills/citable/schemas/prompt-set.schema.json +47 -0
  107. package/dist/universal/.github/skills/citable/schemas/remediation-verification.schema.json +12 -1
  108. package/dist/universal/.github/skills/citable/schemas/representation-data.schema.json +21 -0
  109. package/dist/universal/.github/skills/citable/schemas/research-dataset.schema.json +27 -0
  110. package/dist/universal/.github/skills/citable/schemas/run.schema.json +15 -2
  111. package/dist/universal/.github/skills/citable/schemas/search-discovery-data.schema.json +20 -0
  112. package/dist/universal/.github/skills/citable/schemas/search-report.schema.json +8 -1
  113. package/dist/universal/.github/skills/citable/schemas/summary.schema.json +41 -0
  114. package/dist/universal/.kiro/skills/citable/SKILL.md +11 -2
  115. package/dist/universal/.kiro/skills/citable/VERSION +1 -1
  116. package/dist/universal/.kiro/skills/citable/manifest.json +24 -12
  117. package/dist/universal/.kiro/skills/citable/schemas/action-plan.schema.json +38 -1
  118. package/dist/universal/.kiro/skills/citable/schemas/audit-coverage.schema.json +118 -0
  119. package/dist/universal/.kiro/skills/citable/schemas/claim-evidence.schema.json +21 -0
  120. package/dist/universal/.kiro/skills/citable/schemas/claim-verification.schema.json +18 -0
  121. package/dist/universal/.kiro/skills/citable/schemas/collection-result.schema.json +35 -0
  122. package/dist/universal/.kiro/skills/citable/schemas/config.schema.json +2 -0
  123. package/dist/universal/.kiro/skills/citable/schemas/cro-report.schema.json +8 -1
  124. package/dist/universal/.kiro/skills/citable/schemas/derivation.schema.json +18 -0
  125. package/dist/universal/.kiro/skills/citable/schemas/external-comparison.schema.json +16 -0
  126. package/dist/universal/.kiro/skills/citable/schemas/external-observation.schema.json +32 -0
  127. package/dist/universal/.kiro/skills/citable/schemas/finding.schema.json +105 -2
  128. package/dist/universal/.kiro/skills/citable/schemas/prompt-set.schema.json +47 -0
  129. package/dist/universal/.kiro/skills/citable/schemas/remediation-verification.schema.json +12 -1
  130. package/dist/universal/.kiro/skills/citable/schemas/representation-data.schema.json +21 -0
  131. package/dist/universal/.kiro/skills/citable/schemas/research-dataset.schema.json +27 -0
  132. package/dist/universal/.kiro/skills/citable/schemas/run.schema.json +15 -2
  133. package/dist/universal/.kiro/skills/citable/schemas/search-discovery-data.schema.json +20 -0
  134. package/dist/universal/.kiro/skills/citable/schemas/search-report.schema.json +8 -1
  135. package/dist/universal/.kiro/skills/citable/schemas/summary.schema.json +41 -0
  136. package/dist/universal/.opencode/skills/citable/SKILL.md +11 -2
  137. package/dist/universal/.opencode/skills/citable/VERSION +1 -1
  138. package/dist/universal/.opencode/skills/citable/manifest.json +24 -12
  139. package/dist/universal/.opencode/skills/citable/schemas/action-plan.schema.json +38 -1
  140. package/dist/universal/.opencode/skills/citable/schemas/audit-coverage.schema.json +118 -0
  141. package/dist/universal/.opencode/skills/citable/schemas/claim-evidence.schema.json +21 -0
  142. package/dist/universal/.opencode/skills/citable/schemas/claim-verification.schema.json +18 -0
  143. package/dist/universal/.opencode/skills/citable/schemas/collection-result.schema.json +35 -0
  144. package/dist/universal/.opencode/skills/citable/schemas/config.schema.json +2 -0
  145. package/dist/universal/.opencode/skills/citable/schemas/cro-report.schema.json +8 -1
  146. package/dist/universal/.opencode/skills/citable/schemas/derivation.schema.json +18 -0
  147. package/dist/universal/.opencode/skills/citable/schemas/external-comparison.schema.json +16 -0
  148. package/dist/universal/.opencode/skills/citable/schemas/external-observation.schema.json +32 -0
  149. package/dist/universal/.opencode/skills/citable/schemas/finding.schema.json +105 -2
  150. package/dist/universal/.opencode/skills/citable/schemas/prompt-set.schema.json +47 -0
  151. package/dist/universal/.opencode/skills/citable/schemas/remediation-verification.schema.json +12 -1
  152. package/dist/universal/.opencode/skills/citable/schemas/representation-data.schema.json +21 -0
  153. package/dist/universal/.opencode/skills/citable/schemas/research-dataset.schema.json +27 -0
  154. package/dist/universal/.opencode/skills/citable/schemas/run.schema.json +15 -2
  155. package/dist/universal/.opencode/skills/citable/schemas/search-discovery-data.schema.json +20 -0
  156. package/dist/universal/.opencode/skills/citable/schemas/search-report.schema.json +8 -1
  157. package/dist/universal/.opencode/skills/citable/schemas/summary.schema.json +41 -0
  158. package/dist/universal/.pi/agent/skills/citable/SKILL.md +11 -2
  159. package/dist/universal/.pi/agent/skills/citable/VERSION +1 -1
  160. package/dist/universal/.pi/agent/skills/citable/manifest.json +24 -12
  161. package/dist/universal/.pi/agent/skills/citable/schemas/action-plan.schema.json +38 -1
  162. package/dist/universal/.pi/agent/skills/citable/schemas/audit-coverage.schema.json +118 -0
  163. package/dist/universal/.pi/agent/skills/citable/schemas/claim-evidence.schema.json +21 -0
  164. package/dist/universal/.pi/agent/skills/citable/schemas/claim-verification.schema.json +18 -0
  165. package/dist/universal/.pi/agent/skills/citable/schemas/collection-result.schema.json +35 -0
  166. package/dist/universal/.pi/agent/skills/citable/schemas/config.schema.json +2 -0
  167. package/dist/universal/.pi/agent/skills/citable/schemas/cro-report.schema.json +8 -1
  168. package/dist/universal/.pi/agent/skills/citable/schemas/derivation.schema.json +18 -0
  169. package/dist/universal/.pi/agent/skills/citable/schemas/external-comparison.schema.json +16 -0
  170. package/dist/universal/.pi/agent/skills/citable/schemas/external-observation.schema.json +32 -0
  171. package/dist/universal/.pi/agent/skills/citable/schemas/finding.schema.json +105 -2
  172. package/dist/universal/.pi/agent/skills/citable/schemas/prompt-set.schema.json +47 -0
  173. package/dist/universal/.pi/agent/skills/citable/schemas/remediation-verification.schema.json +12 -1
  174. package/dist/universal/.pi/agent/skills/citable/schemas/representation-data.schema.json +21 -0
  175. package/dist/universal/.pi/agent/skills/citable/schemas/research-dataset.schema.json +27 -0
  176. package/dist/universal/.pi/agent/skills/citable/schemas/run.schema.json +15 -2
  177. package/dist/universal/.pi/agent/skills/citable/schemas/search-discovery-data.schema.json +20 -0
  178. package/dist/universal/.pi/agent/skills/citable/schemas/search-report.schema.json +8 -1
  179. package/dist/universal/.pi/agent/skills/citable/schemas/summary.schema.json +41 -0
  180. package/dist/universal/.qoder/skills/citable/SKILL.md +11 -2
  181. package/dist/universal/.qoder/skills/citable/VERSION +1 -1
  182. package/dist/universal/.qoder/skills/citable/manifest.json +24 -12
  183. package/dist/universal/.qoder/skills/citable/schemas/action-plan.schema.json +38 -1
  184. package/dist/universal/.qoder/skills/citable/schemas/audit-coverage.schema.json +118 -0
  185. package/dist/universal/.qoder/skills/citable/schemas/claim-evidence.schema.json +21 -0
  186. package/dist/universal/.qoder/skills/citable/schemas/claim-verification.schema.json +18 -0
  187. package/dist/universal/.qoder/skills/citable/schemas/collection-result.schema.json +35 -0
  188. package/dist/universal/.qoder/skills/citable/schemas/config.schema.json +2 -0
  189. package/dist/universal/.qoder/skills/citable/schemas/cro-report.schema.json +8 -1
  190. package/dist/universal/.qoder/skills/citable/schemas/derivation.schema.json +18 -0
  191. package/dist/universal/.qoder/skills/citable/schemas/external-comparison.schema.json +16 -0
  192. package/dist/universal/.qoder/skills/citable/schemas/external-observation.schema.json +32 -0
  193. package/dist/universal/.qoder/skills/citable/schemas/finding.schema.json +105 -2
  194. package/dist/universal/.qoder/skills/citable/schemas/prompt-set.schema.json +47 -0
  195. package/dist/universal/.qoder/skills/citable/schemas/remediation-verification.schema.json +12 -1
  196. package/dist/universal/.qoder/skills/citable/schemas/representation-data.schema.json +21 -0
  197. package/dist/universal/.qoder/skills/citable/schemas/research-dataset.schema.json +27 -0
  198. package/dist/universal/.qoder/skills/citable/schemas/run.schema.json +15 -2
  199. package/dist/universal/.qoder/skills/citable/schemas/search-discovery-data.schema.json +20 -0
  200. package/dist/universal/.qoder/skills/citable/schemas/search-report.schema.json +8 -1
  201. package/dist/universal/.qoder/skills/citable/schemas/summary.schema.json +41 -0
  202. package/dist/universal/.rovodev/skills/citable/SKILL.md +11 -2
  203. package/dist/universal/.rovodev/skills/citable/VERSION +1 -1
  204. package/dist/universal/.rovodev/skills/citable/manifest.json +24 -12
  205. package/dist/universal/.rovodev/skills/citable/schemas/action-plan.schema.json +38 -1
  206. package/dist/universal/.rovodev/skills/citable/schemas/audit-coverage.schema.json +118 -0
  207. package/dist/universal/.rovodev/skills/citable/schemas/claim-evidence.schema.json +21 -0
  208. package/dist/universal/.rovodev/skills/citable/schemas/claim-verification.schema.json +18 -0
  209. package/dist/universal/.rovodev/skills/citable/schemas/collection-result.schema.json +35 -0
  210. package/dist/universal/.rovodev/skills/citable/schemas/config.schema.json +2 -0
  211. package/dist/universal/.rovodev/skills/citable/schemas/cro-report.schema.json +8 -1
  212. package/dist/universal/.rovodev/skills/citable/schemas/derivation.schema.json +18 -0
  213. package/dist/universal/.rovodev/skills/citable/schemas/external-comparison.schema.json +16 -0
  214. package/dist/universal/.rovodev/skills/citable/schemas/external-observation.schema.json +32 -0
  215. package/dist/universal/.rovodev/skills/citable/schemas/finding.schema.json +105 -2
  216. package/dist/universal/.rovodev/skills/citable/schemas/prompt-set.schema.json +47 -0
  217. package/dist/universal/.rovodev/skills/citable/schemas/remediation-verification.schema.json +12 -1
  218. package/dist/universal/.rovodev/skills/citable/schemas/representation-data.schema.json +21 -0
  219. package/dist/universal/.rovodev/skills/citable/schemas/research-dataset.schema.json +27 -0
  220. package/dist/universal/.rovodev/skills/citable/schemas/run.schema.json +15 -2
  221. package/dist/universal/.rovodev/skills/citable/schemas/search-discovery-data.schema.json +20 -0
  222. package/dist/universal/.rovodev/skills/citable/schemas/search-report.schema.json +8 -1
  223. package/dist/universal/.rovodev/skills/citable/schemas/summary.schema.json +41 -0
  224. package/dist/universal/.trae/skills/citable/SKILL.md +11 -2
  225. package/dist/universal/.trae/skills/citable/VERSION +1 -1
  226. package/dist/universal/.trae/skills/citable/manifest.json +24 -12
  227. package/dist/universal/.trae/skills/citable/schemas/action-plan.schema.json +38 -1
  228. package/dist/universal/.trae/skills/citable/schemas/audit-coverage.schema.json +118 -0
  229. package/dist/universal/.trae/skills/citable/schemas/claim-evidence.schema.json +21 -0
  230. package/dist/universal/.trae/skills/citable/schemas/claim-verification.schema.json +18 -0
  231. package/dist/universal/.trae/skills/citable/schemas/collection-result.schema.json +35 -0
  232. package/dist/universal/.trae/skills/citable/schemas/config.schema.json +2 -0
  233. package/dist/universal/.trae/skills/citable/schemas/cro-report.schema.json +8 -1
  234. package/dist/universal/.trae/skills/citable/schemas/derivation.schema.json +18 -0
  235. package/dist/universal/.trae/skills/citable/schemas/external-comparison.schema.json +16 -0
  236. package/dist/universal/.trae/skills/citable/schemas/external-observation.schema.json +32 -0
  237. package/dist/universal/.trae/skills/citable/schemas/finding.schema.json +105 -2
  238. package/dist/universal/.trae/skills/citable/schemas/prompt-set.schema.json +47 -0
  239. package/dist/universal/.trae/skills/citable/schemas/remediation-verification.schema.json +12 -1
  240. package/dist/universal/.trae/skills/citable/schemas/representation-data.schema.json +21 -0
  241. package/dist/universal/.trae/skills/citable/schemas/research-dataset.schema.json +27 -0
  242. package/dist/universal/.trae/skills/citable/schemas/run.schema.json +15 -2
  243. package/dist/universal/.trae/skills/citable/schemas/search-discovery-data.schema.json +20 -0
  244. package/dist/universal/.trae/skills/citable/schemas/search-report.schema.json +8 -1
  245. package/dist/universal/.trae/skills/citable/schemas/summary.schema.json +41 -0
  246. package/dist/universal/.trae-cn/skills/citable/SKILL.md +11 -2
  247. package/dist/universal/.trae-cn/skills/citable/VERSION +1 -1
  248. package/dist/universal/.trae-cn/skills/citable/manifest.json +24 -12
  249. package/dist/universal/.trae-cn/skills/citable/schemas/action-plan.schema.json +38 -1
  250. package/dist/universal/.trae-cn/skills/citable/schemas/audit-coverage.schema.json +118 -0
  251. package/dist/universal/.trae-cn/skills/citable/schemas/claim-evidence.schema.json +21 -0
  252. package/dist/universal/.trae-cn/skills/citable/schemas/claim-verification.schema.json +18 -0
  253. package/dist/universal/.trae-cn/skills/citable/schemas/collection-result.schema.json +35 -0
  254. package/dist/universal/.trae-cn/skills/citable/schemas/config.schema.json +2 -0
  255. package/dist/universal/.trae-cn/skills/citable/schemas/cro-report.schema.json +8 -1
  256. package/dist/universal/.trae-cn/skills/citable/schemas/derivation.schema.json +18 -0
  257. package/dist/universal/.trae-cn/skills/citable/schemas/external-comparison.schema.json +16 -0
  258. package/dist/universal/.trae-cn/skills/citable/schemas/external-observation.schema.json +32 -0
  259. package/dist/universal/.trae-cn/skills/citable/schemas/finding.schema.json +105 -2
  260. package/dist/universal/.trae-cn/skills/citable/schemas/prompt-set.schema.json +47 -0
  261. package/dist/universal/.trae-cn/skills/citable/schemas/remediation-verification.schema.json +12 -1
  262. package/dist/universal/.trae-cn/skills/citable/schemas/representation-data.schema.json +21 -0
  263. package/dist/universal/.trae-cn/skills/citable/schemas/research-dataset.schema.json +27 -0
  264. package/dist/universal/.trae-cn/skills/citable/schemas/run.schema.json +15 -2
  265. package/dist/universal/.trae-cn/skills/citable/schemas/search-discovery-data.schema.json +20 -0
  266. package/dist/universal/.trae-cn/skills/citable/schemas/search-report.schema.json +8 -1
  267. package/dist/universal/.trae-cn/skills/citable/schemas/summary.schema.json +41 -0
  268. package/dist/universal/manifest.json +292 -148
  269. package/package.json +1 -1
  270. package/schemas/action-plan.schema.json +38 -1
  271. package/schemas/audit-coverage.schema.json +118 -0
  272. package/schemas/claim-evidence.schema.json +21 -0
  273. package/schemas/claim-verification.schema.json +18 -0
  274. package/schemas/collection-result.schema.json +35 -0
  275. package/schemas/config.schema.json +2 -0
  276. package/schemas/cro-report.schema.json +8 -1
  277. package/schemas/derivation.schema.json +18 -0
  278. package/schemas/external-comparison.schema.json +16 -0
  279. package/schemas/external-observation.schema.json +32 -0
  280. package/schemas/finding.schema.json +105 -2
  281. package/schemas/prompt-set.schema.json +47 -0
  282. package/schemas/remediation-verification.schema.json +12 -1
  283. package/schemas/representation-data.schema.json +21 -0
  284. package/schemas/research-dataset.schema.json +27 -0
  285. package/schemas/run.schema.json +15 -2
  286. package/schemas/search-discovery-data.schema.json +20 -0
  287. package/schemas/search-report.schema.json +8 -1
  288. package/schemas/summary.schema.json +41 -0
  289. package/skill/SKILL.md +11 -2
  290. package/src/acceptance/reproducibility.js +5 -25
  291. package/src/analysis/croRoadmap.js +3 -3
  292. package/src/analysis/strategicRoadmap.js +3 -3
  293. package/src/artifacts/interchange.js +2 -6
  294. package/src/cli/index.js +15 -3
  295. package/src/commands/actionPlan.js +46 -5
  296. package/src/commands/applyRemediation.js +5 -5
  297. package/src/commands/audit.js +75 -8
  298. package/src/commands/ciWorkflow.js +7 -2
  299. package/src/commands/compareSnapshots.js +155 -47
  300. package/src/commands/connect.js +24 -4
  301. package/src/commands/context.js +41 -2
  302. package/src/commands/croSuite.js +51 -13
  303. package/src/commands/delivery.js +7 -7
  304. package/src/commands/governance.js +9 -10
  305. package/src/commands/implementationKit.js +2 -1
  306. package/src/commands/init.js +8 -1
  307. package/src/commands/previewCro.js +1 -1
  308. package/src/commands/prioritize.js +3 -2
  309. package/src/commands/reviews.js +31 -5
  310. package/src/commands/roadmapCmd.js +7 -13
  311. package/src/commands/sweep.js +15 -2
  312. package/src/commands/verifyRemediation.js +94 -19
  313. package/src/connectors/collectionResult.js +80 -0
  314. package/src/connectors/ga4.js +46 -11
  315. package/src/connectors/gsc.js +45 -6
  316. package/src/connectors/index.js +1 -1
  317. package/src/connectors/webflow.js +140 -10
  318. package/src/connectors/wordpress.js +92 -8
  319. package/src/crawler/fetch.js +220 -24
  320. package/src/crawler/resourceValidity.js +119 -0
  321. package/src/crawler/sitemap.js +435 -16
  322. package/src/crawler/sitemapCollector.js +364 -0
  323. package/src/crawler/urlIdentity.js +97 -0
  324. package/src/detectors/agent.js +11 -0
  325. package/src/detectors/ans.js +16 -1
  326. package/src/detectors/arch.js +6 -0
  327. package/src/detectors/claim.js +9 -0
  328. package/src/detectors/crawl.js +7 -0
  329. package/src/detectors/cro.js +21 -0
  330. package/src/detectors/cwv.js +4 -0
  331. package/src/detectors/entity.js +7 -0
  332. package/src/detectors/evd.js +9 -0
  333. package/src/detectors/framework.js +28 -2
  334. package/src/detectors/geoReco.js +16 -0
  335. package/src/detectors/hreflang.js +3 -0
  336. package/src/detectors/lifeMeas.js +9 -0
  337. package/src/detectors/link.js +6 -1
  338. package/src/detectors/page.js +11 -0
  339. package/src/detectors/schemaData.js +16 -1
  340. package/src/detectors/tech.js +34 -3
  341. package/src/discovery/searchConsole.js +186 -0
  342. package/src/evidence/coverage.js +448 -0
  343. package/src/evidence/determination.js +157 -0
  344. package/src/evidence/downstream.js +110 -0
  345. package/src/evidence/external.js +251 -0
  346. package/src/evidence/hashes.js +109 -0
  347. package/src/evidence/run.js +68 -8
  348. package/src/extractor/page.js +29 -2
  349. package/src/extractor/site.js +298 -50
  350. package/src/reporting/executiveCroReport.js +36 -13
  351. package/src/reporting/executiveExport.js +45 -16
  352. package/src/reporting/executiveSearchReport.js +56 -22
  353. package/src/reporting/report.js +56 -9
  354. package/src/representation/prompts.js +117 -0
  355. package/src/representation/representation.js +186 -0
  356. package/src/shared/epistemicLanguage.js +86 -0
  357. package/src/shared/evidenceSourceResolver.js +48 -17
  358. package/src/shared/htmlEscape.js +8 -4
  359. package/src/shared/runPackageVerifier.js +99 -8
  360. package/src/shared/verifiedRunLoader.js +129 -0
@@ -0,0 +1,27 @@
1
+ {
2
+ "$id": "citable://schemas/research-dataset.schema.json",
3
+ "$schema": "http://json-schema.org/draft-07/schema#",
4
+ "title": "Immutable research dataset",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["dataset_id", "dataset_version", "declared_purpose", "declared_population", "population_size", "inclusion_criteria", "exclusion_criteria", "collection", "source_references", "observation_references", "normalization", "derivation_references", "coverage", "coverage_status", "limitations", "dataset_hash"],
8
+ "properties": {
9
+ "dataset_id": { "type": "string", "minLength": 1 },
10
+ "dataset_version": { "type": "integer", "minimum": 1 },
11
+ "declared_purpose": { "type": "string", "minLength": 1 },
12
+ "declared_population": { "type": "object", "additionalProperties": false, "required": ["type", "id"], "properties": { "type": { "type": "string", "minLength": 1 }, "id": { "type": "string", "minLength": 1 }, "size": { "type": ["integer", "null"], "minimum": 0 } } },
13
+ "population_size": { "type": ["integer", "null"], "minimum": 0 },
14
+ "inclusion_criteria": { "type": "array", "items": { "type": "string" } },
15
+ "exclusion_criteria": { "type": "array", "items": { "type": "string" } },
16
+ "collection": { "type": "object", "additionalProperties": false, "required": ["started_at", "ended_at"], "properties": { "started_at": { "type": "string", "format": "date-time" }, "ended_at": { "type": "string", "format": "date-time" } } },
17
+ "source_references": { "type": "array", "items": { "type": "string" } },
18
+ "source_retrieval_timestamps": { "type": "array", "items": { "type": "string", "format": "date-time" } },
19
+ "observation_references": { "type": "array", "items": { "type": "string" } },
20
+ "normalization": { "type": "object", "additionalProperties": false, "required": ["method", "version"], "properties": { "method": { "type": "string", "minLength": 1 }, "version": { "type": "string", "minLength": 1 } } },
21
+ "derivation_references": { "type": "array", "items": { "type": "string" } },
22
+ "coverage": { "type": "object", "additionalProperties": false, "required": ["declared", "retrieved", "evaluated", "unavailable", "failed"], "properties": { "declared": { "type": "integer", "minimum": 0 }, "retrieved": { "type": "integer", "minimum": 0 }, "evaluated": { "type": "integer", "minimum": 0 }, "unavailable": { "type": "integer", "minimum": 0 }, "failed": { "type": "integer", "minimum": 0 } } },
23
+ "coverage_status": { "type": "string", "enum": ["complete_for_declared_population", "partial", "truncated", "indeterminate", "error"] },
24
+ "limitations": { "type": "array", "items": { "type": "string" } },
25
+ "dataset_hash": { "type": "string", "pattern": "^[a-f0-9]{64}$" }
26
+ }
27
+ }
@@ -5,6 +5,7 @@
5
5
  "type": "object",
6
6
  "required": ["run_id", "command", "tool_version", "skill_version", "timestamp", "target", "status"],
7
7
  "properties": {
8
+ "schema_version": { "type": "integer", "enum": [1, 2] },
8
9
  "run_id": { "type": "string" },
9
10
  "command": { "type": "string" },
10
11
  "argv": { "type": "array", "items": { "type": "string" } },
@@ -31,6 +32,18 @@
31
32
  "incomplete_checks": { "type": "array", "items": { "type": "string" } },
32
33
  "errors": { "type": "array", "items": { "type": "string" } },
33
34
  "warnings": { "type": "array", "items": { "type": "string" } },
34
- "status": { "type": "string", "enum": ["completed", "completed_with_warnings", "incomplete", "failed"] }
35
- }
35
+ "status": { "type": "string", "enum": ["completed", "completed_with_warnings", "incomplete", "failed"] },
36
+ "execution_status": { "type": "string", "enum": ["completed", "completed_with_warnings", "failed"] },
37
+ "coverage_status": { "type": "string", "enum": ["complete", "truncated", "indeterminate", "not_applicable"] },
38
+ "determination_status": { "type": "string", "enum": ["supported", "qualified", "indeterminate", "not_applicable"] }
39
+ },
40
+ "allOf": [
41
+ {
42
+ "if": {
43
+ "required": ["schema_version"],
44
+ "properties": { "schema_version": { "const": 2 } }
45
+ },
46
+ "then": { "required": ["execution_status", "coverage_status", "determination_status"] }
47
+ }
48
+ ]
36
49
  }
@@ -0,0 +1,20 @@
1
+ {
2
+ "$id": "citable://schemas/search-discovery-data.schema.json",
3
+ "$schema": "http://json-schema.org/draft-07/schema#",
4
+ "title": "Search discovery observation data",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["query", "page", "interval", "metrics", "request", "coverage_status", "evidence_origin"],
8
+ "properties": {
9
+ "query": { "type": ["string", "null"] },
10
+ "page": { "type": ["string", "null"], "format": "uri" },
11
+ "interval": { "type": "object", "additionalProperties": false, "required": ["start_date", "end_date"], "properties": { "start_date": { "type": "string", "format": "date" }, "end_date": { "type": "string", "format": "date" } } },
12
+ "metrics": { "type": "object", "additionalProperties": false, "required": ["impressions", "clicks", "ctr", "average_position"], "properties": { "impressions": { "type": ["number", "null"], "minimum": 0 }, "clicks": { "type": ["number", "null"], "minimum": 0 }, "ctr": { "type": ["number", "null"], "minimum": 0 }, "average_position": { "type": ["number", "null"], "minimum": 0 } } },
13
+ "dimensions": { "type": "object", "additionalProperties": false, "properties": { "country": { "type": ["string", "null"] }, "device": { "type": ["string", "null"] }, "search_appearance": { "type": ["string", "null"] }, "date": { "type": ["string", "null"], "format": "date" } } },
14
+ "request": { "type": "object", "additionalProperties": false, "required": ["property_id", "dimensions", "filters", "row_limit"], "properties": { "property_id": { "type": "string", "minLength": 1 }, "dimensions": { "type": "array", "items": { "type": "string" } }, "filters": { "type": "object" }, "row_limit": { "type": "integer", "minimum": 1, "maximum": 25000 } } },
15
+ "provider_reported": { "type": "object", "additionalProperties": false, "properties": { "row_count": { "type": ["integer", "null"], "minimum": 0 }, "page_start": { "type": "integer", "minimum": 0 } } },
16
+ "response_hash": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
17
+ "coverage_status": { "type": "string", "enum": ["complete", "truncated", "indeterminate", "provider_bounded"] },
18
+ "evidence_origin": { "type": "string", "enum": ["LIVE_PROVIDER", "RECORDED_FIXTURE", "SYNTHETIC_TEST"] }
19
+ }
20
+ }
@@ -90,7 +90,14 @@
90
90
  "source_identifier": { "type": ["string", "null"] },
91
91
  "source_findings_count": { "type": "integer", "minimum": 0 },
92
92
  "integrity_hash": { "type": ["string", "null"] },
93
- "synthetic_evidence": { "type": "boolean" }
93
+ "synthetic_evidence": { "type": "boolean" },
94
+ "package_verified": { "type": "boolean" },
95
+ "integrity_mode": { "type": "string" },
96
+ "legacy": { "type": "boolean" },
97
+ "coverage_status": { "type": "string" },
98
+ "determination_status": { "type": "string" },
99
+ "evaluated": { "type": ["integer", "null"], "minimum": 0 },
100
+ "eligible": { "type": ["integer", "null"], "minimum": 0 }
94
101
  },
95
102
  "additionalProperties": false
96
103
  }
@@ -0,0 +1,41 @@
1
+ {
2
+ "$id": "citable://schemas/summary.schema.json",
3
+ "$schema": "http://json-schema.org/draft-07/schema#",
4
+ "title": "Run summary",
5
+ "type": "object",
6
+ "required": ["coverage", "posture"],
7
+ "properties": {
8
+ "coverage": {
9
+ "type": ["object", "null"],
10
+ "required": ["status", "populations", "stop_reason"],
11
+ "properties": {
12
+ "status": { "enum": ["complete", "truncated", "indeterminate", "not_applicable"] },
13
+ "populations": { "$ref": "citable://schemas/audit-coverage.schema.json#/properties/populations" },
14
+ "stop_reason": { "type": ["string", "null"] }
15
+ },
16
+ "additionalProperties": false
17
+ },
18
+ "posture": {
19
+ "type": "object",
20
+ "required": ["retrieval_eligibility", "source_extraction_and_support", "observed_citation_behavior"],
21
+ "properties": {
22
+ "retrieval_eligibility": { "$ref": "#/definitions/posture" },
23
+ "source_extraction_and_support": { "$ref": "#/definitions/posture" },
24
+ "observed_citation_behavior": { "$ref": "#/definitions/posture" }
25
+ },
26
+ "additionalProperties": false
27
+ }
28
+ },
29
+ "additionalProperties": true,
30
+ "definitions": {
31
+ "posture": {
32
+ "type": "object",
33
+ "required": ["result"],
34
+ "properties": {
35
+ "result": { "type": "string" },
36
+ "coverage_status": { "enum": ["complete", "truncated", "indeterminate", "not_applicable"] }
37
+ },
38
+ "additionalProperties": true
39
+ }
40
+ }
41
+ }
package/skill/SKILL.md CHANGED
@@ -7,7 +7,7 @@ description: >
7
7
  generative engine optimization, structured data governance, claim substantiation,
8
8
  crawler policy, entity consistency, content discoverability, or wants a site audited
9
9
  for how search and AI systems will retrieve, understand, cite, or recommend it.
10
- version: 1.19.0
10
+ version: 1.21.0
11
11
  ---
12
12
 
13
13
  # Citable — evidence and change control for search and AI citation readiness
@@ -69,6 +69,15 @@ Every report must keep these top-level states separate:
69
69
  3. **Observed citation behavior** — only controlled, timestamped provider
70
70
  observations; absent observations are `not_evidenced`, never inferred.
71
71
 
72
+ Presentation language must preserve those boundaries. An empty finding list,
73
+ legacy package, unverified artifact, incomplete crawl, or indeterminate
74
+ determination must not be described as `clean`, `complete`, `verified`,
75
+ `resolved`, `100%`, or `site-wide`. State the evaluated population and the
76
+ limitation instead (for example, "No findings were produced for the 217
77
+ successfully evaluated resources; corpus-wide absence is not established").
78
+ Positive local observations may remain supported, but they must not be widened
79
+ to pages or resources that were not observed.
80
+
72
81
  Within retrieval, distinguish `allowed_by_policy`, `synthetic_fetch_succeeded`,
73
82
  `observed_in_production_logs`, `indexed`, and `returned_by_retrieval`. Within
74
83
  citation testing, distinguish mention, citation, material support, canonical
@@ -86,7 +95,7 @@ prefer running it over re-deriving its checks by hand:
86
95
 
87
96
  ```
88
97
  citable init # initialize .citable/ (non-destructive)
89
- citable audit [scope] --target <dir|url> [--base-url <url>] [--ref-date YYYY-MM-DD]
98
+ citable audit [scope] --target <dir|url> [--base-url <url>] [--max-pages <1..10000>] [--time-budget-seconds <1..86400>] [--ref-date YYYY-MM-DD]
90
99
  citable plan-audit --target <dir|url> [--base-url <url>]
91
100
  citable sweep technical --target <dir|url> # Technical SEO sweep + Core Web Vitals metrics
92
101
  citable inspect <page> --target <dir|url>
@@ -1,8 +1,8 @@
1
- import fs from 'node:fs';
2
1
  import path from 'node:path';
3
2
  import { canonicalJson } from '../release/governance.js';
4
- import { nowIso, readJson, sha256, sha256File, writeJson } from '../shared/io.js';
3
+ import { nowIso, readJson, sha256, writeJson } from '../shared/io.js';
5
4
  import { validateAgainst } from '../shared/schemaValidator.js';
5
+ import { loadVerifiedRun } from '../shared/verifiedRunLoader.js';
6
6
 
7
7
  const INCLUDED_FIELDS = [
8
8
  'property.target', 'property.source_commit', 'property.content_hashes',
@@ -37,25 +37,6 @@ function normalizedArguments(argv = []) {
37
37
  return normalized;
38
38
  }
39
39
 
40
- function verifyRunPackage(runDir, manifest) {
41
- const manifestCheck = validateAgainst('run.schema.json', manifest);
42
- if (!manifestCheck.valid) throw new Error(`run manifest violates contract: ${manifestCheck.errors.join('; ')}`);
43
- const checksumsFile = path.join(runDir, 'checksums.json');
44
- if (!fs.existsSync(checksumsFile)) throw new Error(`run ${manifest.run_id} has no checksums.json`);
45
- const checksums = readJson(checksumsFile);
46
- if (!checksums || Array.isArray(checksums) || typeof checksums !== 'object') throw new Error('run checksums must be an object');
47
- const failures = [];
48
- for (const [relative, expected] of Object.entries(checksums)) {
49
- const file = path.resolve(runDir, relative);
50
- if (path.isAbsolute(relative) || (!file.startsWith(`${path.resolve(runDir)}${path.sep}`))) failures.push(`${relative} escapes the run package`);
51
- else if (!/^[a-f0-9]{64}$/.test(expected)) failures.push(`${relative} has an invalid checksum`);
52
- else if (!fs.existsSync(file)) failures.push(`${relative} is missing`);
53
- else if (sha256File(file) !== expected) failures.push(`${relative} checksum differs`);
54
- }
55
- if (failures.length) throw new Error(`run package integrity failed: ${failures.join('; ')}`);
56
- return checksums;
57
- }
58
-
59
40
  function fingerprintPayload(receipt) {
60
41
  return {
61
42
  property: { target: receipt.property.target, source_commit: receipt.property.source_commit, content_hashes: receipt.property.content_hashes },
@@ -74,11 +55,10 @@ export function createAcceptanceReceipt(root, { runId, context = {}, createdAt =
74
55
  const contextCheck = validateAgainst('acceptance-run-context.schema.json', context);
75
56
  if (!contextCheck.valid) throw new Error(`acceptance context violates contract: ${contextCheck.errors.join('; ')}`);
76
57
  const runDir = path.join(root, '.citable', 'runs', runId);
77
- const manifestFile = path.join(runDir, 'manifest.json');
78
- if (!fs.existsSync(manifestFile)) throw new Error(`run ${runId} not found`);
79
- const manifest = readJson(manifestFile);
58
+ const verified = loadVerifiedRun(runDir, { requireCompletedExecution: false, allowLegacy: true, requireCoverage: false });
59
+ const manifest = verified.manifest;
80
60
  if (manifest.run_id !== runId) throw new Error(`run manifest id ${manifest.run_id} does not match requested run ${runId}`);
81
- const checksums = verifyRunPackage(runDir, manifest);
61
+ const checksums = verified.artifactHashes;
82
62
  const canonicalArtifacts = sortedObject(Object.fromEntries(
83
63
  Object.entries(checksums).filter(([name]) => name !== 'manifest.json'),
84
64
  ));
@@ -18,10 +18,10 @@ export function buildCroRoadmap({ findings = [], targetDomain = 'example.com', d
18
18
  'Mobile Tap Sizing: Expand diminutive mobile CTA touch targets to >= 48px standard (CRO-015)',
19
19
  ],
20
20
  target_outcomes: [
21
- '100% conversion funnel continuity intact across all declared paths',
21
+ 'Conversion funnel continuity observed across the declared paths in scope',
22
22
  'Keystroke Effort Index: Form completion friction reduced by >= 40%',
23
- 'Above-the-fold information scent match verified across all primary landing pages',
24
- 'Zero mobile touch target defects under 48px',
23
+ 'Above-the-fold information scent match observed on evaluated primary landing pages',
24
+ 'No mobile touch-target findings in the evaluated pages',
25
25
  ],
26
26
  measurable_conversion_kpi: 'Form Completion Rate (+8% to +15% expected relative lift)',
27
27
  experiments: backlog.experiments.filter((e) => ['CRO-007', 'CRO-005', 'CRO-015', 'CRO-017', 'CRO-018'].includes(e.detector_id) || e.ice_prioritization.effort <= 3),
@@ -24,9 +24,9 @@ export function buildStrategicRoadmap({ findings = [], initiatives = [], targetD
24
24
  ],
25
25
  exit_criteria: [
26
26
  'Zero critical-severity technical findings in citable audit technical',
27
- 'Static CLS readiness: 100% of body images have explicit dimensions',
28
- 'All major answer engine bots verified allowed in robots directives',
29
- 'Baseline Organization schema live with verified @id',
27
+ 'Static CLS readiness: every evaluated body image has explicit dimensions',
28
+ 'Major answer engine bot access observed as allowed in robots directives',
29
+ 'Baseline Organization schema live with an observed @id',
30
30
  ],
31
31
  actions: [],
32
32
  };
@@ -5,6 +5,7 @@ import { fileURLToPath } from 'node:url';
5
5
  import { canonicalJson } from '../release/governance.js';
6
6
  import { nowIso, readJson, sha256, sha256File, writeJson } from '../shared/io.js';
7
7
  import { validateAgainst } from '../shared/schemaValidator.js';
8
+ import { verifyRunPackage } from '../shared/runPackageVerifier.js';
8
9
 
9
10
  const PACKAGE = readJson(path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../package.json'));
10
11
  const ENVELOPE = 'citable-artifact.json';
@@ -37,18 +38,13 @@ function validateRunPackage(runDir) {
37
38
  const checksumsFile = path.join(runDir, 'checksums.json');
38
39
  if (!fs.existsSync(manifestFile) || !fs.existsSync(checksumsFile)) throw new Error('run package requires manifest.json and checksums.json');
39
40
  const manifest = readJson(manifestFile);
40
- const manifestCheck = validateAgainst('run.schema.json', manifest);
41
- if (!manifestCheck.valid) throw new Error(`run manifest invalid: ${manifestCheck.errors.join('; ')}`);
42
41
  const checksums = readJson(checksumsFile);
43
- if (!checksums || Array.isArray(checksums) || typeof checksums !== 'object') throw new Error('checksums.json must be an object');
42
+ verifyRunPackage(runDir, { requireFindings: false, requireCompleted: false, requireChecksums: true, ignoredFiles: [ENVELOPE] });
44
43
  const actualFiles = filesUnder(runDir).filter((name) => name !== ENVELOPE);
45
44
  const expectedFiles = [...Object.keys(checksums), 'checksums.json'].sort();
46
45
  if (new Set(expectedFiles).size !== expectedFiles.length) throw new Error('checksums.json contains duplicate package paths');
47
46
  for (const rel of Object.keys(checksums)) {
48
47
  if (!safeRelativePath(rel) || rel === ENVELOPE || rel === 'checksums.json') throw new Error(`unsafe checksum path: ${rel}`);
49
- const file = path.join(runDir, ...rel.split('/'));
50
- if (!fs.existsSync(file) || !fs.statSync(file).isFile()) throw new Error(`checksummed artifact is missing: ${rel}`);
51
- if (!/^[a-f0-9]{64}$/.test(checksums[rel]) || sha256File(file) !== checksums[rel]) throw new Error(`artifact checksum mismatch: ${rel}`);
52
48
  }
53
49
  const extras = actualFiles.filter((name) => !expectedFiles.includes(name));
54
50
  const missing = expectedFiles.filter((name) => !actualFiles.includes(name));
package/src/cli/index.js CHANGED
@@ -185,6 +185,8 @@ Commands
185
185
 
186
186
  Options
187
187
  --target <dir|url> Built output directory or deployed URL to audit
188
+ --max-pages <count> Maximum unique page URLs attempted for a URL audit (default: 500)
189
+ --time-budget-seconds <seconds> Whole-run URL collection limit (default: 1800)
188
190
  --base-url <url> Base URL for path resolution of a built output dir
189
191
  --ref-date <YYYY-MM-DD> Reference date for expiry/staleness checks (default: today)
190
192
  --input <file> Import evidence, remediation, or browser plan
@@ -233,7 +235,7 @@ Options
233
235
  No output of this tool guarantees crawling, indexing, ranking, citation,
234
236
  recommendation, inclusion, sentiment, or conversion outcomes.`;
235
237
 
236
- function parseArgs(argv) {
238
+ export function parseArgs(argv) {
237
239
  const args = { _: [] };
238
240
  for (let i = 0; i < argv.length; i++) {
239
241
  const a = argv[i];
@@ -243,6 +245,8 @@ function parseArgs(argv) {
243
245
  else if (a === '--interactions') args.interactions = true;
244
246
  else if (a === '--lighthouse') args.lighthouse = true;
245
247
  else if (a === '--target') args.target = argv[++i];
248
+ else if (a === '--max-pages') args.maxPages = Number(argv[++i]);
249
+ else if (a === '--time-budget-seconds') args.timeBudgetSeconds = Number(argv[++i]);
246
250
  else if (a === '--base-url') args.baseUrl = argv[++i];
247
251
  else if (a === '--ref-date') args.refDate = argv[++i];
248
252
  else if (a === '--viewport') args.viewport = argv[++i];
@@ -411,8 +415,16 @@ ${r.findings.map((f) => ` [${f.rule_id}] (${f.severity}) ${f.summary}\n Fix:
411
415
  break;
412
416
  }
413
417
  const scope = args._[0];
414
- const r = await audit(root, { target: args.target, scope, baseUrl: args.baseUrl, refDate: args.refDate, viewport: args.viewport });
415
- out(args, `Audit ${r.runId}: ${r.summary.total} finding(s) [${Object.entries(r.summary.by_severity).map(([k, v]) => `${k}:${v}`).join(' ')}]\nEvidence package: ${r.dir}\nReport: ${path.join(r.dir, 'report.md')}\nStatus: ${r.manifest.status}${r.manifest.incomplete_checks.length ? `\nIncomplete: ${r.manifest.incomplete_checks.join('; ')}` : ''}`, { runId: r.runId, dir: r.dir, summary: r.summary, status: r.manifest.status });
418
+ const r = await audit(root, {
419
+ target: args.target,
420
+ scope,
421
+ baseUrl: args.baseUrl,
422
+ refDate: args.refDate,
423
+ viewport: args.viewport,
424
+ maxPages: args.maxPages,
425
+ timeBudgetSeconds: args.timeBudgetSeconds,
426
+ });
427
+ out(args, `Audit ${r.runId}: ${r.summary.total} finding(s) [${Object.entries(r.summary.by_severity).map(([k, v]) => `${k}:${v}`).join(' ')}]\nEvidence package: ${r.dir}\nReport: ${path.join(r.dir, 'report.md')}\nStatus: ${r.manifest.status}\nExecution: ${r.manifest.execution_status}\nCoverage: ${r.manifest.coverage_status}\nDetermination: ${r.manifest.determination_status}${r.manifest.incomplete_checks.length ? `\nIncomplete: ${r.manifest.incomplete_checks.join('; ')}` : ''}`, { runId: r.runId, dir: r.dir, summary: r.summary, status: r.manifest.status, execution_status: r.manifest.execution_status, coverage_status: r.manifest.coverage_status, determination_status: r.manifest.determination_status });
416
428
  break;
417
429
  }
418
430
  case 'plan-audit': {
@@ -2,7 +2,10 @@ import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { readJson, writeJson, sha256, nowIso } from '../shared/io.js';
4
4
  import { validateAgainst } from '../shared/schemaValidator.js';
5
+ import { downstreamEnvelope } from '../evidence/downstream.js';
6
+ import { REQUIREMENTS, evaluateRequirement } from '../evidence/determination.js';
5
7
  import { checklistItem, toStringArray } from '../shared/checklist.js';
8
+ import { loadVerifiedRun } from '../shared/verifiedRunLoader.js';
6
9
 
7
10
  const SEVERITY = { critical: 0, high: 1, medium: 2, low: 3, informational: 3, experimental: 3 };
8
11
  const PHASE = { unblock: 0, governance: 1, content: 2, optimization: 3 };
@@ -46,6 +49,7 @@ function renderPlan(plan) {
46
49
  '# Citable action plan', '',
47
50
  `- Source audit: \`${plan.source_run_id}\``,
48
51
  `- Actions: ${plan.summary.total_actions}; ready: ${plan.summary.ready}; blocked: ${plan.summary.blocked}`,
52
+ `- Evidence coverage: ${plan.source_coverage.coverage_status}; determination: ${plan.source_coverage.determination_status}`,
49
53
  '',
50
54
  '> This plan prioritizes observed findings. It does not guarantee ranking, citation, recommendation, or conversion outcomes.',
51
55
  '',
@@ -61,6 +65,7 @@ function renderPlan(plan) {
61
65
  lines.push(`- Decision owner: ${action.decision_owner ?? 'unassigned'}`);
62
66
  lines.push(`- Dependencies: ${action.depends_on_action_ids.length ? action.depends_on_action_ids.join(', ') : 'none established'}`);
63
67
  if (action.required_input.length) lines.push(`- Required input: ${action.required_input.join(', ')}`);
68
+ if (action.limitations.length) lines.push(`- Evidence limitations: ${action.limitations.join('; ')}`);
64
69
  if (action.semantic_gates.length) lines.push(`- Semantic gates: ${action.semantic_gates.join(', ')}`);
65
70
  lines.push(`- Failure condition: ${action.failure_condition}`);
66
71
  lines.push(`- Leading indicators: ${action.leading_indicators.length ? action.leading_indicators.join(', ') : 'none established'}`);
@@ -78,13 +83,37 @@ export function actionPlan(root, { runId } = {}) {
78
83
  const sourceDir = path.join(runsDir, sourceRunId);
79
84
  const findingsFile = path.join(sourceDir, 'findings.json');
80
85
  if (!fs.existsSync(findingsFile)) throw new Error(`run ${sourceRunId} has no findings.json`);
81
- const rawFindings = fs.readFileSync(findingsFile, 'utf8');
82
- const findings = JSON.parse(rawFindings);
83
- const manifest = readJson(path.join(sourceDir, 'manifest.json'));
86
+ const loaded = loadVerifiedRun(sourceDir, { requireCompletedExecution: false, allowLegacy: true, requireCoverage: false });
87
+ const findings = loaded.findings;
88
+ const rawFindings = JSON.stringify(findings);
89
+ const manifest = loaded.manifest;
90
+ const coverage = loaded.coverage;
91
+ const sourceCoverage = downstreamEnvelope(coverage, {
92
+ artifact: coverage ? 'coverage.json' : null,
93
+ });
84
94
  const target = manifest.target?.location;
85
95
  const actions = findings.map((finding) => {
86
96
  const owner = finding.remediation.owner ?? null;
87
- const blocked = finding.remediation.review_required && !owner;
97
+ const findingScope = finding.evidence_scope || {
98
+ requirement: 'evaluated_subset',
99
+ satisfaction: sourceCoverage.determination_status,
100
+ coverage_ref: coverage ? 'coverage.json' : null,
101
+ resource_ids: [],
102
+ };
103
+ const requirement = findingScope.requirement || REQUIREMENTS.EVALUATED_SUBSET;
104
+ let requirementResult;
105
+ try {
106
+ requirementResult = evaluateRequirement(requirement, coverage, finding.subject);
107
+ } catch (error) {
108
+ requirementResult = { status: 'indeterminate', reason: `invalid_evidence_requirement: ${error.message}` };
109
+ }
110
+ const scopeSatisfied = ['supported', 'qualified'].includes(requirementResult.status);
111
+ const effectiveDetermination = sourceCoverage.determination_status === 'indeterminate'
112
+ || sourceCoverage.determination_status === 'not_applicable'
113
+ || !scopeSatisfied
114
+ ? 'indeterminate'
115
+ : (sourceCoverage.determination_status === 'qualified' || requirementResult.status === 'qualified' ? 'qualified' : 'supported');
116
+ const blocked = (finding.remediation.review_required && !owner) || !scopeSatisfied || effectiveDetermination === 'indeterminate';
88
117
  const scope = finding.discipline.length === 1 && ['aeo', 'geo', 'seo'].includes(finding.discipline[0]) ? ` ${finding.discipline[0]}` : '';
89
118
  return {
90
119
  action_id: `ACT-${finding.finding_id.replace(/^F-/, '')}`,
@@ -97,7 +126,18 @@ export function actionPlan(root, { runId } = {}) {
97
126
  owner,
98
127
  decision_owner: owner,
99
128
  status: blocked ? 'blocked' : 'ready',
100
- required_input: blocked ? toStringArray([checklistItem('owner', 'accountable owner')]) : [],
129
+ evidence_scope: { ...findingScope, satisfaction: effectiveDetermination },
130
+ coverage_status: sourceCoverage.coverage_status,
131
+ determination_status: effectiveDetermination,
132
+ limitations: [
133
+ ...sourceCoverage.limitations,
134
+ ...(finding.reasoning?.limitations || []),
135
+ ...(requirementResult.reason ? [`evidence requirement: ${requirementResult.reason}`] : []),
136
+ ].filter((item, index, all) => all.indexOf(item) === index),
137
+ required_input: blocked ? toStringArray([
138
+ ...(finding.remediation.review_required && !owner ? [checklistItem('owner', 'accountable owner')] : []),
139
+ ...(!scopeSatisfied || effectiveDetermination === 'indeterminate' ? ['sufficient comparable evidence for the declared scope'] : []),
140
+ ]) : [],
101
141
  semantic_gates: semanticGates(finding),
102
142
  unsafe_shortcuts: finding.remediation.unsafe_shortcuts || [],
103
143
  failure_condition: `${finding.verification.detector_to_rerun} still reports the exact subject, or verification cannot complete with sufficient evidence`,
@@ -120,6 +160,7 @@ export function actionPlan(root, { runId } = {}) {
120
160
  ready: actions.filter((action) => action.status === 'ready').length,
121
161
  blocked: actions.filter((action) => action.status === 'blocked').length,
122
162
  },
163
+ source_coverage: sourceCoverage,
123
164
  actions,
124
165
  };
125
166
  const validation = validateAgainst('action-plan.schema.json', plan);
@@ -3,6 +3,7 @@ import path from 'node:path';
3
3
  import { createRun } from '../evidence/run.js';
4
4
  import { readJson, sha256 } from '../shared/io.js';
5
5
  import { validateAgainst } from '../shared/schemaValidator.js';
6
+ import { loadVerifiedRun } from '../shared/verifiedRunLoader.js';
6
7
 
7
8
  function inside(root, candidate) {
8
9
  const base = path.resolve(root) + path.sep;
@@ -19,11 +20,10 @@ export function applyRemediation(root, { input, write = false } = {}) {
19
20
  const spec = readJson(input);
20
21
  const valid = validateAgainst('remediation-spec.schema.json', spec);
21
22
  if (!valid.valid) throw new Error(`remediation spec invalid: ${valid.errors.join('; ')}`);
22
- const manifestFile = path.join(root, '.citable', 'runs', spec.source_run_id, 'manifest.json');
23
- if (!fs.existsSync(manifestFile)) throw new Error(`source run not found: ${spec.source_run_id}`);
24
- const findingsFile = path.join(root, '.citable', 'runs', spec.source_run_id, 'findings.json');
25
- if (!fs.existsSync(findingsFile)) throw new Error(`source run has no findings: ${spec.source_run_id}`);
26
- const sourceFindingIds = new Set(readJson(findingsFile).map((finding) => finding.finding_id));
23
+ const sourceDir = path.join(root, '.citable', 'runs', spec.source_run_id);
24
+ if (!fs.existsSync(sourceDir)) throw new Error(`source run not found: ${spec.source_run_id}`);
25
+ const source = loadVerifiedRun(sourceDir, { requireCompletedExecution: false, allowLegacy: true, requireCoverage: false });
26
+ const sourceFindingIds = new Set(source.findings.map((finding) => finding.finding_id));
27
27
  const results = [];
28
28
  const pending = [];
29
29
  for (const operation of spec.operations) {
@@ -10,10 +10,16 @@ import { writeJson, sha256 } from '../shared/io.js';
10
10
  import { extractModified } from '../detectors/lifeMeas.js';
11
11
  import { buildEntityGraph } from '../observations/entityGraph.js';
12
12
  import { buildSourceIdentityChain } from '../observations/sourceIdentity.js';
13
+ import { pageArtifactRecord } from '../evidence/hashes.js';
13
14
 
14
15
  /** `citable audit [scope]` — run detectors and produce an evidence package. */
15
- export async function audit(root, { target, scope, baseUrl, refDate, viewport = null } = {}) {
16
- const ctx = await buildContext(root, { target, baseUrl, refDate, viewport });
16
+ export async function audit(root, {
17
+ target, scope, baseUrl, refDate, viewport = null,
18
+ maxPages, timeBudgetSeconds, fetcher, concurrency = 1,
19
+ } = {}) {
20
+ const ctx = await buildContext(root, {
21
+ target, baseUrl, refDate, viewport, maxPages, timeBudgetSeconds, fetcher, concurrency,
22
+ });
17
23
  const detectors = selectDetectors({ scope });
18
24
 
19
25
  const run = createRun(root, {
@@ -36,10 +42,32 @@ export async function audit(root, { target, scope, baseUrl, refDate, viewport =
36
42
  if (ctx.site?.fetchErrors?.length) {
37
43
  run.manifest.errors.push(...ctx.site.fetchErrors);
38
44
  }
39
- if (ctx.site?.crawl?.truncated) {
45
+ if (ctx.site?.crawl?.stopReason === 'page_budget_exhausted') {
40
46
  run.manifest.incomplete_checks.push(
41
47
  `URL collection reached the ${ctx.site.crawl.maxPages}-page limit with ${ctx.site.crawl.pendingUrlCount} discovered URL(s) pending; sitemap absence checks are incomplete.`
42
48
  );
49
+ } else if (ctx.site?.crawl?.stopReason === 'time_budget_exhausted') {
50
+ run.manifest.incomplete_checks.push(
51
+ `URL collection reached the ${ctx.site.crawl.timeBudgetSeconds}-second time budget; sitemap absence checks are incomplete.`
52
+ );
53
+ }
54
+
55
+ // Establish and persist the collection contract before detectors execute.
56
+ // Detectors receive this exact provisional evidence envelope through ctx so
57
+ // they cannot infer completeness from page-array length or legacy crawl data.
58
+ let coverage = null;
59
+ if (ctx.site?.previewCoverage) {
60
+ try {
61
+ coverage = ctx.site.previewCoverage();
62
+ run.manifest.coverage_status = coverage.coverage_status;
63
+ run.writeArtifact('coverage.json', coverage);
64
+ ctx.coverage = coverage;
65
+ } catch (error) {
66
+ run.manifest.execution_status = 'failed';
67
+ run.manifest.errors.push(`coverage: ${error.message}`);
68
+ run.finalize('failed');
69
+ throw error;
70
+ }
43
71
  }
44
72
 
45
73
  const { findings, detectorsRun, detectorsSkipped, errors } = runDetectors(detectors, ctx);
@@ -47,6 +75,27 @@ export async function audit(root, { target, scope, baseUrl, refDate, viewport =
47
75
  run.manifest.detectors_skipped = detectorsSkipped;
48
76
  run.manifest.errors.push(...errors);
49
77
 
78
+ // Seal the ledger after detector evaluation so the same artifact records
79
+ // evaluated resources while retaining the pre-detector persistence proof.
80
+ if (ctx.site?.finalizeCoverage) {
81
+ try {
82
+ coverage = ctx.site.finalizeCoverage({ evaluated: true });
83
+ run.manifest.coverage_status = coverage.coverage_status;
84
+ run.manifest.determination_status = coverage.coverage_status === 'complete' ? 'supported' : 'qualified';
85
+ run.writeArtifact('coverage.json', coverage);
86
+ if (coverage.coverage_status !== 'complete') {
87
+ run.manifest.incomplete_checks.push(
88
+ `Coverage is ${coverage.coverage_status}; conclusions are limited to the successfully observed corpus.`,
89
+ );
90
+ }
91
+ } catch (error) {
92
+ run.manifest.execution_status = 'failed';
93
+ run.manifest.errors.push(`coverage: ${error.message}`);
94
+ run.finalize('failed');
95
+ throw error;
96
+ }
97
+ }
98
+
50
99
  // Validate every finding against the data contract; a contract breach fails the run.
51
100
  const invalid = [];
52
101
  for (const f of findings) {
@@ -66,6 +115,7 @@ export async function audit(root, { target, scope, baseUrl, refDate, viewport =
66
115
  detectorsSkipped,
67
116
  promptResults: ctx.promptResults || [],
68
117
  targetOrigin: ctx.site?.baseUrl ? new URL(ctx.site.baseUrl).origin : null,
118
+ coverage,
69
119
  });
70
120
  run.writeArtifact('summary.json', summary);
71
121
  run.writeArtifact('inputs.json', {
@@ -73,6 +123,8 @@ export async function audit(root, { target, scope, baseUrl, refDate, viewport =
73
123
  registry_counts: Object.fromEntries(Object.entries(ctx.registries).map(([k, v]) => [k, v.entries.length])),
74
124
  pages_audited: ctx.site?.pages.length ?? 0,
75
125
  crawl_coverage: ctx.site?.crawl ?? null,
126
+ coverage_status: coverage?.coverage_status ?? 'not_applicable',
127
+ coverage_populations: coverage?.populations ?? null,
76
128
  });
77
129
  run.writeArtifact('environment.json', {
78
130
  node: process.version, platform: process.platform, cwd: root,
@@ -80,9 +132,8 @@ export async function audit(root, { target, scope, baseUrl, refDate, viewport =
80
132
  });
81
133
  if (ctx.site) {
82
134
  run.writeArtifact('pages/index.json', ctx.site.pages.map((p) => ({
83
- url: p.url, status: p.status, title: p.title, canonicals: p.canonicals,
84
- noindex: p.noindex, wordCount: p.wordCount, sourceFile: p.sourceFile,
85
- contentHash: ctx.hashPage(p),
135
+ ...pageArtifactRecord(p),
136
+ artifact_hash: p.artifact_hash ?? null,
86
137
  })));
87
138
  if (ctx.site.robotsText != null) run.writeArtifact('robots/robots.txt', ctx.site.robotsText);
88
139
  for (const sm of ctx.site.sitemaps) {
@@ -102,14 +153,26 @@ export async function audit(root, { target, scope, baseUrl, refDate, viewport =
102
153
  }
103
154
  }
104
155
 
105
- const report = renderMarkdownReport({ findings, manifest: run.manifest, summary, detectorsSkipped });
156
+ const report = renderMarkdownReport({ findings, manifest: run.manifest, summary, detectorsSkipped, coverage });
106
157
  run.writeArtifact('report.md', report);
107
158
 
108
159
  // Update the latest page snapshot for regression/freshness comparison
109
160
  if (ctx.site) {
110
161
  const snap = { taken_at: run.manifest.timestamp, run_id: run.runId, pages: {} };
111
162
  for (const p of ctx.site.pages) {
112
- snap.pages[p.url] = { contentHash: ctx.hashPage(p), dateModified: extractModified(p), status: p.status };
163
+ snap.pages[p.url] = {
164
+ contentHash: p.extracted_text_hash ?? ctx.hashPage(p),
165
+ hash_semantics: 'extracted_text_v1',
166
+ extracted_text_hash: p.extracted_text_hash ?? ctx.hashPage(p),
167
+ response_body_hash: p.response_body_hash ?? null,
168
+ structured_data_hash: p.structured_data_hash ?? null,
169
+ evidence_hash: p.evidence_hash ?? null,
170
+ artifact_hash: p.artifact_hash ?? null,
171
+ resource_id: p.urlIdentity?.resource_id ?? null,
172
+ url_identity: p.urlIdentity ?? null,
173
+ dateModified: extractModified(p),
174
+ status: p.status,
175
+ };
113
176
  }
114
177
  const snapDir = path.join(root, '.citable', 'snapshots');
115
178
  fs.mkdirSync(snapDir, { recursive: true });
@@ -121,6 +184,10 @@ export async function audit(root, { target, scope, baseUrl, refDate, viewport =
121
184
 
122
185
  const status = run.manifest.errors.length ? 'completed_with_warnings'
123
186
  : run.manifest.incomplete_checks.length ? 'incomplete' : 'completed';
187
+ // Successful persistence/execution is independent from collection coverage
188
+ // and legacy warning status. A run with fetch warnings can still complete as
189
+ // an execution while its coverage remains indeterminate or truncated.
190
+ run.manifest.execution_status = 'completed';
124
191
  const dir = run.finalize(status);
125
192
  return { runId: run.runId, dir, findings, summary, manifest: run.manifest, report };
126
193
  }
@@ -33,9 +33,14 @@ jobs:
33
33
  `;
34
34
  }
35
35
 
36
- export function formatPrReviewComment(findings = []) {
36
+ export function formatPrReviewComment(findings = [], determination = null) {
37
37
  if (findings.length === 0) {
38
- return '### Citable CRO Sentinel: All conversion funnels and components verified clean with zero detected friction.';
38
+ const status = determination?.determination_status || 'indeterminate';
39
+ if (status !== 'supported') {
40
+ const coverage = determination?.coverage_status ? ` (coverage: ${determination.coverage_status})` : '';
41
+ return `### ⚠️ Citable CRO Sentinel: No determination can be made from the available evidence${coverage}; insufficient evidence for a clean determination. No finding was observed in the evaluated subset; this is not a verified result.`;
42
+ }
43
+ return '### ✅ Citable CRO Sentinel: No findings were observed over the supported evidence scope.';
39
44
  }
40
45
 
41
46
  const lines = [