@nebulacomponents/citable 0.1.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 (586) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/LICENSE +201 -0
  3. package/README.md +150 -0
  4. package/cli/bin/citable.js +5 -0
  5. package/dist/universal/.agents/skills/citable/SKILL.md +137 -0
  6. package/dist/universal/.agents/skills/citable/VERSION +1 -0
  7. package/dist/universal/.agents/skills/citable/commands/README.md +36 -0
  8. package/dist/universal/.agents/skills/citable/commands/ingest.md +44 -0
  9. package/dist/universal/.agents/skills/citable/commands/measurement.md +49 -0
  10. package/dist/universal/.agents/skills/citable/commands/optimize-page.md +53 -0
  11. package/dist/universal/.agents/skills/citable/commands/page-work.md +48 -0
  12. package/dist/universal/.agents/skills/citable/commands/validate-render.md +24 -0
  13. package/dist/universal/.agents/skills/citable/manifest.json +54 -0
  14. package/dist/universal/.agents/skills/citable/policies/crawler-policy-template.md +47 -0
  15. package/dist/universal/.agents/skills/citable/references/anti-patterns.md +61 -0
  16. package/dist/universal/.agents/skills/citable/rubrics/README.md +30 -0
  17. package/dist/universal/.agents/skills/citable/rubrics/answer-extractability.md +44 -0
  18. package/dist/universal/.agents/skills/citable/rubrics/claim-boundedness.md +36 -0
  19. package/dist/universal/.agents/skills/citable/rubrics/comparison-fairness.md +30 -0
  20. package/dist/universal/.agents/skills/citable/rubrics/conversion-alignment.md +37 -0
  21. package/dist/universal/.agents/skills/citable/rubrics/entity-clarity.md +41 -0
  22. package/dist/universal/.agents/skills/citable/rubrics/evidence-strength.md +53 -0
  23. package/dist/universal/.agents/skills/citable/rubrics/information-gain.md +33 -0
  24. package/dist/universal/.agents/skills/citable/rubrics/intent-alignment.md +41 -0
  25. package/dist/universal/.agents/skills/citable/rubrics/narrative-accuracy.md +46 -0
  26. package/dist/universal/.agents/skills/citable/rubrics/recommendation-eligibility.md +36 -0
  27. package/dist/universal/.agents/skills/citable/rubrics/semantic-clarity.md +42 -0
  28. package/dist/universal/.agents/skills/citable/rubrics/source-authority.md +37 -0
  29. package/dist/universal/.agents/skills/citable/schemas/claim.schema.json +53 -0
  30. package/dist/universal/.agents/skills/citable/schemas/common.defs.json +33 -0
  31. package/dist/universal/.agents/skills/citable/schemas/competitor.schema.json +28 -0
  32. package/dist/universal/.agents/skills/citable/schemas/config.schema.json +41 -0
  33. package/dist/universal/.agents/skills/citable/schemas/crawler.schema.json +33 -0
  34. package/dist/universal/.agents/skills/citable/schemas/detector-quality.schema.json +39 -0
  35. package/dist/universal/.agents/skills/citable/schemas/entity.schema.json +39 -0
  36. package/dist/universal/.agents/skills/citable/schemas/evidence.schema.json +41 -0
  37. package/dist/universal/.agents/skills/citable/schemas/experiment.schema.json +37 -0
  38. package/dist/universal/.agents/skills/citable/schemas/finding.schema.json +101 -0
  39. package/dist/universal/.agents/skills/citable/schemas/page.schema.json +40 -0
  40. package/dist/universal/.agents/skills/citable/schemas/project.schema.json +29 -0
  41. package/dist/universal/.agents/skills/citable/schemas/prompt-result.schema.json +37 -0
  42. package/dist/universal/.agents/skills/citable/schemas/prompt.schema.json +41 -0
  43. package/dist/universal/.agents/skills/citable/schemas/query.schema.json +43 -0
  44. package/dist/universal/.agents/skills/citable/schemas/run.schema.json +36 -0
  45. package/dist/universal/.agents/skills/citable/scripts/README.md +4 -0
  46. package/dist/universal/.agents/skills/citable/templates/finding-review.md +54 -0
  47. package/dist/universal/.claude/skills/citable/SKILL.md +137 -0
  48. package/dist/universal/.claude/skills/citable/VERSION +1 -0
  49. package/dist/universal/.claude/skills/citable/commands/README.md +36 -0
  50. package/dist/universal/.claude/skills/citable/commands/ingest.md +44 -0
  51. package/dist/universal/.claude/skills/citable/commands/measurement.md +49 -0
  52. package/dist/universal/.claude/skills/citable/commands/optimize-page.md +53 -0
  53. package/dist/universal/.claude/skills/citable/commands/page-work.md +48 -0
  54. package/dist/universal/.claude/skills/citable/commands/validate-render.md +24 -0
  55. package/dist/universal/.claude/skills/citable/manifest.json +54 -0
  56. package/dist/universal/.claude/skills/citable/policies/crawler-policy-template.md +47 -0
  57. package/dist/universal/.claude/skills/citable/references/anti-patterns.md +61 -0
  58. package/dist/universal/.claude/skills/citable/rubrics/README.md +30 -0
  59. package/dist/universal/.claude/skills/citable/rubrics/answer-extractability.md +44 -0
  60. package/dist/universal/.claude/skills/citable/rubrics/claim-boundedness.md +36 -0
  61. package/dist/universal/.claude/skills/citable/rubrics/comparison-fairness.md +30 -0
  62. package/dist/universal/.claude/skills/citable/rubrics/conversion-alignment.md +37 -0
  63. package/dist/universal/.claude/skills/citable/rubrics/entity-clarity.md +41 -0
  64. package/dist/universal/.claude/skills/citable/rubrics/evidence-strength.md +53 -0
  65. package/dist/universal/.claude/skills/citable/rubrics/information-gain.md +33 -0
  66. package/dist/universal/.claude/skills/citable/rubrics/intent-alignment.md +41 -0
  67. package/dist/universal/.claude/skills/citable/rubrics/narrative-accuracy.md +46 -0
  68. package/dist/universal/.claude/skills/citable/rubrics/recommendation-eligibility.md +36 -0
  69. package/dist/universal/.claude/skills/citable/rubrics/semantic-clarity.md +42 -0
  70. package/dist/universal/.claude/skills/citable/rubrics/source-authority.md +37 -0
  71. package/dist/universal/.claude/skills/citable/schemas/claim.schema.json +53 -0
  72. package/dist/universal/.claude/skills/citable/schemas/common.defs.json +33 -0
  73. package/dist/universal/.claude/skills/citable/schemas/competitor.schema.json +28 -0
  74. package/dist/universal/.claude/skills/citable/schemas/config.schema.json +41 -0
  75. package/dist/universal/.claude/skills/citable/schemas/crawler.schema.json +33 -0
  76. package/dist/universal/.claude/skills/citable/schemas/detector-quality.schema.json +39 -0
  77. package/dist/universal/.claude/skills/citable/schemas/entity.schema.json +39 -0
  78. package/dist/universal/.claude/skills/citable/schemas/evidence.schema.json +41 -0
  79. package/dist/universal/.claude/skills/citable/schemas/experiment.schema.json +37 -0
  80. package/dist/universal/.claude/skills/citable/schemas/finding.schema.json +101 -0
  81. package/dist/universal/.claude/skills/citable/schemas/page.schema.json +40 -0
  82. package/dist/universal/.claude/skills/citable/schemas/project.schema.json +29 -0
  83. package/dist/universal/.claude/skills/citable/schemas/prompt-result.schema.json +37 -0
  84. package/dist/universal/.claude/skills/citable/schemas/prompt.schema.json +41 -0
  85. package/dist/universal/.claude/skills/citable/schemas/query.schema.json +43 -0
  86. package/dist/universal/.claude/skills/citable/schemas/run.schema.json +36 -0
  87. package/dist/universal/.claude/skills/citable/scripts/README.md +4 -0
  88. package/dist/universal/.claude/skills/citable/templates/finding-review.md +54 -0
  89. package/dist/universal/.cursor/skills/citable/SKILL.md +137 -0
  90. package/dist/universal/.cursor/skills/citable/VERSION +1 -0
  91. package/dist/universal/.cursor/skills/citable/commands/README.md +36 -0
  92. package/dist/universal/.cursor/skills/citable/commands/ingest.md +44 -0
  93. package/dist/universal/.cursor/skills/citable/commands/measurement.md +49 -0
  94. package/dist/universal/.cursor/skills/citable/commands/optimize-page.md +53 -0
  95. package/dist/universal/.cursor/skills/citable/commands/page-work.md +48 -0
  96. package/dist/universal/.cursor/skills/citable/commands/validate-render.md +24 -0
  97. package/dist/universal/.cursor/skills/citable/manifest.json +54 -0
  98. package/dist/universal/.cursor/skills/citable/policies/crawler-policy-template.md +47 -0
  99. package/dist/universal/.cursor/skills/citable/references/anti-patterns.md +61 -0
  100. package/dist/universal/.cursor/skills/citable/rubrics/README.md +30 -0
  101. package/dist/universal/.cursor/skills/citable/rubrics/answer-extractability.md +44 -0
  102. package/dist/universal/.cursor/skills/citable/rubrics/claim-boundedness.md +36 -0
  103. package/dist/universal/.cursor/skills/citable/rubrics/comparison-fairness.md +30 -0
  104. package/dist/universal/.cursor/skills/citable/rubrics/conversion-alignment.md +37 -0
  105. package/dist/universal/.cursor/skills/citable/rubrics/entity-clarity.md +41 -0
  106. package/dist/universal/.cursor/skills/citable/rubrics/evidence-strength.md +53 -0
  107. package/dist/universal/.cursor/skills/citable/rubrics/information-gain.md +33 -0
  108. package/dist/universal/.cursor/skills/citable/rubrics/intent-alignment.md +41 -0
  109. package/dist/universal/.cursor/skills/citable/rubrics/narrative-accuracy.md +46 -0
  110. package/dist/universal/.cursor/skills/citable/rubrics/recommendation-eligibility.md +36 -0
  111. package/dist/universal/.cursor/skills/citable/rubrics/semantic-clarity.md +42 -0
  112. package/dist/universal/.cursor/skills/citable/rubrics/source-authority.md +37 -0
  113. package/dist/universal/.cursor/skills/citable/schemas/claim.schema.json +53 -0
  114. package/dist/universal/.cursor/skills/citable/schemas/common.defs.json +33 -0
  115. package/dist/universal/.cursor/skills/citable/schemas/competitor.schema.json +28 -0
  116. package/dist/universal/.cursor/skills/citable/schemas/config.schema.json +41 -0
  117. package/dist/universal/.cursor/skills/citable/schemas/crawler.schema.json +33 -0
  118. package/dist/universal/.cursor/skills/citable/schemas/detector-quality.schema.json +39 -0
  119. package/dist/universal/.cursor/skills/citable/schemas/entity.schema.json +39 -0
  120. package/dist/universal/.cursor/skills/citable/schemas/evidence.schema.json +41 -0
  121. package/dist/universal/.cursor/skills/citable/schemas/experiment.schema.json +37 -0
  122. package/dist/universal/.cursor/skills/citable/schemas/finding.schema.json +101 -0
  123. package/dist/universal/.cursor/skills/citable/schemas/page.schema.json +40 -0
  124. package/dist/universal/.cursor/skills/citable/schemas/project.schema.json +29 -0
  125. package/dist/universal/.cursor/skills/citable/schemas/prompt-result.schema.json +37 -0
  126. package/dist/universal/.cursor/skills/citable/schemas/prompt.schema.json +41 -0
  127. package/dist/universal/.cursor/skills/citable/schemas/query.schema.json +43 -0
  128. package/dist/universal/.cursor/skills/citable/schemas/run.schema.json +36 -0
  129. package/dist/universal/.cursor/skills/citable/scripts/README.md +4 -0
  130. package/dist/universal/.cursor/skills/citable/templates/finding-review.md +54 -0
  131. package/dist/universal/.gemini/skills/citable/SKILL.md +137 -0
  132. package/dist/universal/.gemini/skills/citable/VERSION +1 -0
  133. package/dist/universal/.gemini/skills/citable/commands/README.md +36 -0
  134. package/dist/universal/.gemini/skills/citable/commands/ingest.md +44 -0
  135. package/dist/universal/.gemini/skills/citable/commands/measurement.md +49 -0
  136. package/dist/universal/.gemini/skills/citable/commands/optimize-page.md +53 -0
  137. package/dist/universal/.gemini/skills/citable/commands/page-work.md +48 -0
  138. package/dist/universal/.gemini/skills/citable/commands/validate-render.md +24 -0
  139. package/dist/universal/.gemini/skills/citable/manifest.json +54 -0
  140. package/dist/universal/.gemini/skills/citable/policies/crawler-policy-template.md +47 -0
  141. package/dist/universal/.gemini/skills/citable/references/anti-patterns.md +61 -0
  142. package/dist/universal/.gemini/skills/citable/rubrics/README.md +30 -0
  143. package/dist/universal/.gemini/skills/citable/rubrics/answer-extractability.md +44 -0
  144. package/dist/universal/.gemini/skills/citable/rubrics/claim-boundedness.md +36 -0
  145. package/dist/universal/.gemini/skills/citable/rubrics/comparison-fairness.md +30 -0
  146. package/dist/universal/.gemini/skills/citable/rubrics/conversion-alignment.md +37 -0
  147. package/dist/universal/.gemini/skills/citable/rubrics/entity-clarity.md +41 -0
  148. package/dist/universal/.gemini/skills/citable/rubrics/evidence-strength.md +53 -0
  149. package/dist/universal/.gemini/skills/citable/rubrics/information-gain.md +33 -0
  150. package/dist/universal/.gemini/skills/citable/rubrics/intent-alignment.md +41 -0
  151. package/dist/universal/.gemini/skills/citable/rubrics/narrative-accuracy.md +46 -0
  152. package/dist/universal/.gemini/skills/citable/rubrics/recommendation-eligibility.md +36 -0
  153. package/dist/universal/.gemini/skills/citable/rubrics/semantic-clarity.md +42 -0
  154. package/dist/universal/.gemini/skills/citable/rubrics/source-authority.md +37 -0
  155. package/dist/universal/.gemini/skills/citable/schemas/claim.schema.json +53 -0
  156. package/dist/universal/.gemini/skills/citable/schemas/common.defs.json +33 -0
  157. package/dist/universal/.gemini/skills/citable/schemas/competitor.schema.json +28 -0
  158. package/dist/universal/.gemini/skills/citable/schemas/config.schema.json +41 -0
  159. package/dist/universal/.gemini/skills/citable/schemas/crawler.schema.json +33 -0
  160. package/dist/universal/.gemini/skills/citable/schemas/detector-quality.schema.json +39 -0
  161. package/dist/universal/.gemini/skills/citable/schemas/entity.schema.json +39 -0
  162. package/dist/universal/.gemini/skills/citable/schemas/evidence.schema.json +41 -0
  163. package/dist/universal/.gemini/skills/citable/schemas/experiment.schema.json +37 -0
  164. package/dist/universal/.gemini/skills/citable/schemas/finding.schema.json +101 -0
  165. package/dist/universal/.gemini/skills/citable/schemas/page.schema.json +40 -0
  166. package/dist/universal/.gemini/skills/citable/schemas/project.schema.json +29 -0
  167. package/dist/universal/.gemini/skills/citable/schemas/prompt-result.schema.json +37 -0
  168. package/dist/universal/.gemini/skills/citable/schemas/prompt.schema.json +41 -0
  169. package/dist/universal/.gemini/skills/citable/schemas/query.schema.json +43 -0
  170. package/dist/universal/.gemini/skills/citable/schemas/run.schema.json +36 -0
  171. package/dist/universal/.gemini/skills/citable/scripts/README.md +4 -0
  172. package/dist/universal/.gemini/skills/citable/templates/finding-review.md +54 -0
  173. package/dist/universal/.github/skills/citable/SKILL.md +137 -0
  174. package/dist/universal/.github/skills/citable/VERSION +1 -0
  175. package/dist/universal/.github/skills/citable/commands/README.md +36 -0
  176. package/dist/universal/.github/skills/citable/commands/ingest.md +44 -0
  177. package/dist/universal/.github/skills/citable/commands/measurement.md +49 -0
  178. package/dist/universal/.github/skills/citable/commands/optimize-page.md +53 -0
  179. package/dist/universal/.github/skills/citable/commands/page-work.md +48 -0
  180. package/dist/universal/.github/skills/citable/commands/validate-render.md +24 -0
  181. package/dist/universal/.github/skills/citable/manifest.json +54 -0
  182. package/dist/universal/.github/skills/citable/policies/crawler-policy-template.md +47 -0
  183. package/dist/universal/.github/skills/citable/references/anti-patterns.md +61 -0
  184. package/dist/universal/.github/skills/citable/rubrics/README.md +30 -0
  185. package/dist/universal/.github/skills/citable/rubrics/answer-extractability.md +44 -0
  186. package/dist/universal/.github/skills/citable/rubrics/claim-boundedness.md +36 -0
  187. package/dist/universal/.github/skills/citable/rubrics/comparison-fairness.md +30 -0
  188. package/dist/universal/.github/skills/citable/rubrics/conversion-alignment.md +37 -0
  189. package/dist/universal/.github/skills/citable/rubrics/entity-clarity.md +41 -0
  190. package/dist/universal/.github/skills/citable/rubrics/evidence-strength.md +53 -0
  191. package/dist/universal/.github/skills/citable/rubrics/information-gain.md +33 -0
  192. package/dist/universal/.github/skills/citable/rubrics/intent-alignment.md +41 -0
  193. package/dist/universal/.github/skills/citable/rubrics/narrative-accuracy.md +46 -0
  194. package/dist/universal/.github/skills/citable/rubrics/recommendation-eligibility.md +36 -0
  195. package/dist/universal/.github/skills/citable/rubrics/semantic-clarity.md +42 -0
  196. package/dist/universal/.github/skills/citable/rubrics/source-authority.md +37 -0
  197. package/dist/universal/.github/skills/citable/schemas/claim.schema.json +53 -0
  198. package/dist/universal/.github/skills/citable/schemas/common.defs.json +33 -0
  199. package/dist/universal/.github/skills/citable/schemas/competitor.schema.json +28 -0
  200. package/dist/universal/.github/skills/citable/schemas/config.schema.json +41 -0
  201. package/dist/universal/.github/skills/citable/schemas/crawler.schema.json +33 -0
  202. package/dist/universal/.github/skills/citable/schemas/detector-quality.schema.json +39 -0
  203. package/dist/universal/.github/skills/citable/schemas/entity.schema.json +39 -0
  204. package/dist/universal/.github/skills/citable/schemas/evidence.schema.json +41 -0
  205. package/dist/universal/.github/skills/citable/schemas/experiment.schema.json +37 -0
  206. package/dist/universal/.github/skills/citable/schemas/finding.schema.json +101 -0
  207. package/dist/universal/.github/skills/citable/schemas/page.schema.json +40 -0
  208. package/dist/universal/.github/skills/citable/schemas/project.schema.json +29 -0
  209. package/dist/universal/.github/skills/citable/schemas/prompt-result.schema.json +37 -0
  210. package/dist/universal/.github/skills/citable/schemas/prompt.schema.json +41 -0
  211. package/dist/universal/.github/skills/citable/schemas/query.schema.json +43 -0
  212. package/dist/universal/.github/skills/citable/schemas/run.schema.json +36 -0
  213. package/dist/universal/.github/skills/citable/scripts/README.md +4 -0
  214. package/dist/universal/.github/skills/citable/templates/finding-review.md +54 -0
  215. package/dist/universal/.kiro/skills/citable/SKILL.md +137 -0
  216. package/dist/universal/.kiro/skills/citable/VERSION +1 -0
  217. package/dist/universal/.kiro/skills/citable/commands/README.md +36 -0
  218. package/dist/universal/.kiro/skills/citable/commands/ingest.md +44 -0
  219. package/dist/universal/.kiro/skills/citable/commands/measurement.md +49 -0
  220. package/dist/universal/.kiro/skills/citable/commands/optimize-page.md +53 -0
  221. package/dist/universal/.kiro/skills/citable/commands/page-work.md +48 -0
  222. package/dist/universal/.kiro/skills/citable/commands/validate-render.md +24 -0
  223. package/dist/universal/.kiro/skills/citable/manifest.json +54 -0
  224. package/dist/universal/.kiro/skills/citable/policies/crawler-policy-template.md +47 -0
  225. package/dist/universal/.kiro/skills/citable/references/anti-patterns.md +61 -0
  226. package/dist/universal/.kiro/skills/citable/rubrics/README.md +30 -0
  227. package/dist/universal/.kiro/skills/citable/rubrics/answer-extractability.md +44 -0
  228. package/dist/universal/.kiro/skills/citable/rubrics/claim-boundedness.md +36 -0
  229. package/dist/universal/.kiro/skills/citable/rubrics/comparison-fairness.md +30 -0
  230. package/dist/universal/.kiro/skills/citable/rubrics/conversion-alignment.md +37 -0
  231. package/dist/universal/.kiro/skills/citable/rubrics/entity-clarity.md +41 -0
  232. package/dist/universal/.kiro/skills/citable/rubrics/evidence-strength.md +53 -0
  233. package/dist/universal/.kiro/skills/citable/rubrics/information-gain.md +33 -0
  234. package/dist/universal/.kiro/skills/citable/rubrics/intent-alignment.md +41 -0
  235. package/dist/universal/.kiro/skills/citable/rubrics/narrative-accuracy.md +46 -0
  236. package/dist/universal/.kiro/skills/citable/rubrics/recommendation-eligibility.md +36 -0
  237. package/dist/universal/.kiro/skills/citable/rubrics/semantic-clarity.md +42 -0
  238. package/dist/universal/.kiro/skills/citable/rubrics/source-authority.md +37 -0
  239. package/dist/universal/.kiro/skills/citable/schemas/claim.schema.json +53 -0
  240. package/dist/universal/.kiro/skills/citable/schemas/common.defs.json +33 -0
  241. package/dist/universal/.kiro/skills/citable/schemas/competitor.schema.json +28 -0
  242. package/dist/universal/.kiro/skills/citable/schemas/config.schema.json +41 -0
  243. package/dist/universal/.kiro/skills/citable/schemas/crawler.schema.json +33 -0
  244. package/dist/universal/.kiro/skills/citable/schemas/detector-quality.schema.json +39 -0
  245. package/dist/universal/.kiro/skills/citable/schemas/entity.schema.json +39 -0
  246. package/dist/universal/.kiro/skills/citable/schemas/evidence.schema.json +41 -0
  247. package/dist/universal/.kiro/skills/citable/schemas/experiment.schema.json +37 -0
  248. package/dist/universal/.kiro/skills/citable/schemas/finding.schema.json +101 -0
  249. package/dist/universal/.kiro/skills/citable/schemas/page.schema.json +40 -0
  250. package/dist/universal/.kiro/skills/citable/schemas/project.schema.json +29 -0
  251. package/dist/universal/.kiro/skills/citable/schemas/prompt-result.schema.json +37 -0
  252. package/dist/universal/.kiro/skills/citable/schemas/prompt.schema.json +41 -0
  253. package/dist/universal/.kiro/skills/citable/schemas/query.schema.json +43 -0
  254. package/dist/universal/.kiro/skills/citable/schemas/run.schema.json +36 -0
  255. package/dist/universal/.kiro/skills/citable/scripts/README.md +4 -0
  256. package/dist/universal/.kiro/skills/citable/templates/finding-review.md +54 -0
  257. package/dist/universal/.opencode/skills/citable/SKILL.md +137 -0
  258. package/dist/universal/.opencode/skills/citable/VERSION +1 -0
  259. package/dist/universal/.opencode/skills/citable/commands/README.md +36 -0
  260. package/dist/universal/.opencode/skills/citable/commands/ingest.md +44 -0
  261. package/dist/universal/.opencode/skills/citable/commands/measurement.md +49 -0
  262. package/dist/universal/.opencode/skills/citable/commands/optimize-page.md +53 -0
  263. package/dist/universal/.opencode/skills/citable/commands/page-work.md +48 -0
  264. package/dist/universal/.opencode/skills/citable/commands/validate-render.md +24 -0
  265. package/dist/universal/.opencode/skills/citable/manifest.json +54 -0
  266. package/dist/universal/.opencode/skills/citable/policies/crawler-policy-template.md +47 -0
  267. package/dist/universal/.opencode/skills/citable/references/anti-patterns.md +61 -0
  268. package/dist/universal/.opencode/skills/citable/rubrics/README.md +30 -0
  269. package/dist/universal/.opencode/skills/citable/rubrics/answer-extractability.md +44 -0
  270. package/dist/universal/.opencode/skills/citable/rubrics/claim-boundedness.md +36 -0
  271. package/dist/universal/.opencode/skills/citable/rubrics/comparison-fairness.md +30 -0
  272. package/dist/universal/.opencode/skills/citable/rubrics/conversion-alignment.md +37 -0
  273. package/dist/universal/.opencode/skills/citable/rubrics/entity-clarity.md +41 -0
  274. package/dist/universal/.opencode/skills/citable/rubrics/evidence-strength.md +53 -0
  275. package/dist/universal/.opencode/skills/citable/rubrics/information-gain.md +33 -0
  276. package/dist/universal/.opencode/skills/citable/rubrics/intent-alignment.md +41 -0
  277. package/dist/universal/.opencode/skills/citable/rubrics/narrative-accuracy.md +46 -0
  278. package/dist/universal/.opencode/skills/citable/rubrics/recommendation-eligibility.md +36 -0
  279. package/dist/universal/.opencode/skills/citable/rubrics/semantic-clarity.md +42 -0
  280. package/dist/universal/.opencode/skills/citable/rubrics/source-authority.md +37 -0
  281. package/dist/universal/.opencode/skills/citable/schemas/claim.schema.json +53 -0
  282. package/dist/universal/.opencode/skills/citable/schemas/common.defs.json +33 -0
  283. package/dist/universal/.opencode/skills/citable/schemas/competitor.schema.json +28 -0
  284. package/dist/universal/.opencode/skills/citable/schemas/config.schema.json +41 -0
  285. package/dist/universal/.opencode/skills/citable/schemas/crawler.schema.json +33 -0
  286. package/dist/universal/.opencode/skills/citable/schemas/detector-quality.schema.json +39 -0
  287. package/dist/universal/.opencode/skills/citable/schemas/entity.schema.json +39 -0
  288. package/dist/universal/.opencode/skills/citable/schemas/evidence.schema.json +41 -0
  289. package/dist/universal/.opencode/skills/citable/schemas/experiment.schema.json +37 -0
  290. package/dist/universal/.opencode/skills/citable/schemas/finding.schema.json +101 -0
  291. package/dist/universal/.opencode/skills/citable/schemas/page.schema.json +40 -0
  292. package/dist/universal/.opencode/skills/citable/schemas/project.schema.json +29 -0
  293. package/dist/universal/.opencode/skills/citable/schemas/prompt-result.schema.json +37 -0
  294. package/dist/universal/.opencode/skills/citable/schemas/prompt.schema.json +41 -0
  295. package/dist/universal/.opencode/skills/citable/schemas/query.schema.json +43 -0
  296. package/dist/universal/.opencode/skills/citable/schemas/run.schema.json +36 -0
  297. package/dist/universal/.opencode/skills/citable/scripts/README.md +4 -0
  298. package/dist/universal/.opencode/skills/citable/templates/finding-review.md +54 -0
  299. package/dist/universal/.pi/agent/skills/citable/SKILL.md +137 -0
  300. package/dist/universal/.pi/agent/skills/citable/VERSION +1 -0
  301. package/dist/universal/.pi/agent/skills/citable/commands/README.md +36 -0
  302. package/dist/universal/.pi/agent/skills/citable/commands/ingest.md +44 -0
  303. package/dist/universal/.pi/agent/skills/citable/commands/measurement.md +49 -0
  304. package/dist/universal/.pi/agent/skills/citable/commands/optimize-page.md +53 -0
  305. package/dist/universal/.pi/agent/skills/citable/commands/page-work.md +48 -0
  306. package/dist/universal/.pi/agent/skills/citable/commands/validate-render.md +24 -0
  307. package/dist/universal/.pi/agent/skills/citable/manifest.json +54 -0
  308. package/dist/universal/.pi/agent/skills/citable/policies/crawler-policy-template.md +47 -0
  309. package/dist/universal/.pi/agent/skills/citable/references/anti-patterns.md +61 -0
  310. package/dist/universal/.pi/agent/skills/citable/rubrics/README.md +30 -0
  311. package/dist/universal/.pi/agent/skills/citable/rubrics/answer-extractability.md +44 -0
  312. package/dist/universal/.pi/agent/skills/citable/rubrics/claim-boundedness.md +36 -0
  313. package/dist/universal/.pi/agent/skills/citable/rubrics/comparison-fairness.md +30 -0
  314. package/dist/universal/.pi/agent/skills/citable/rubrics/conversion-alignment.md +37 -0
  315. package/dist/universal/.pi/agent/skills/citable/rubrics/entity-clarity.md +41 -0
  316. package/dist/universal/.pi/agent/skills/citable/rubrics/evidence-strength.md +53 -0
  317. package/dist/universal/.pi/agent/skills/citable/rubrics/information-gain.md +33 -0
  318. package/dist/universal/.pi/agent/skills/citable/rubrics/intent-alignment.md +41 -0
  319. package/dist/universal/.pi/agent/skills/citable/rubrics/narrative-accuracy.md +46 -0
  320. package/dist/universal/.pi/agent/skills/citable/rubrics/recommendation-eligibility.md +36 -0
  321. package/dist/universal/.pi/agent/skills/citable/rubrics/semantic-clarity.md +42 -0
  322. package/dist/universal/.pi/agent/skills/citable/rubrics/source-authority.md +37 -0
  323. package/dist/universal/.pi/agent/skills/citable/schemas/claim.schema.json +53 -0
  324. package/dist/universal/.pi/agent/skills/citable/schemas/common.defs.json +33 -0
  325. package/dist/universal/.pi/agent/skills/citable/schemas/competitor.schema.json +28 -0
  326. package/dist/universal/.pi/agent/skills/citable/schemas/config.schema.json +41 -0
  327. package/dist/universal/.pi/agent/skills/citable/schemas/crawler.schema.json +33 -0
  328. package/dist/universal/.pi/agent/skills/citable/schemas/detector-quality.schema.json +39 -0
  329. package/dist/universal/.pi/agent/skills/citable/schemas/entity.schema.json +39 -0
  330. package/dist/universal/.pi/agent/skills/citable/schemas/evidence.schema.json +41 -0
  331. package/dist/universal/.pi/agent/skills/citable/schemas/experiment.schema.json +37 -0
  332. package/dist/universal/.pi/agent/skills/citable/schemas/finding.schema.json +101 -0
  333. package/dist/universal/.pi/agent/skills/citable/schemas/page.schema.json +40 -0
  334. package/dist/universal/.pi/agent/skills/citable/schemas/project.schema.json +29 -0
  335. package/dist/universal/.pi/agent/skills/citable/schemas/prompt-result.schema.json +37 -0
  336. package/dist/universal/.pi/agent/skills/citable/schemas/prompt.schema.json +41 -0
  337. package/dist/universal/.pi/agent/skills/citable/schemas/query.schema.json +43 -0
  338. package/dist/universal/.pi/agent/skills/citable/schemas/run.schema.json +36 -0
  339. package/dist/universal/.pi/agent/skills/citable/scripts/README.md +4 -0
  340. package/dist/universal/.pi/agent/skills/citable/templates/finding-review.md +54 -0
  341. package/dist/universal/.qoder/skills/citable/SKILL.md +137 -0
  342. package/dist/universal/.qoder/skills/citable/VERSION +1 -0
  343. package/dist/universal/.qoder/skills/citable/commands/README.md +36 -0
  344. package/dist/universal/.qoder/skills/citable/commands/ingest.md +44 -0
  345. package/dist/universal/.qoder/skills/citable/commands/measurement.md +49 -0
  346. package/dist/universal/.qoder/skills/citable/commands/optimize-page.md +53 -0
  347. package/dist/universal/.qoder/skills/citable/commands/page-work.md +48 -0
  348. package/dist/universal/.qoder/skills/citable/commands/validate-render.md +24 -0
  349. package/dist/universal/.qoder/skills/citable/manifest.json +54 -0
  350. package/dist/universal/.qoder/skills/citable/policies/crawler-policy-template.md +47 -0
  351. package/dist/universal/.qoder/skills/citable/references/anti-patterns.md +61 -0
  352. package/dist/universal/.qoder/skills/citable/rubrics/README.md +30 -0
  353. package/dist/universal/.qoder/skills/citable/rubrics/answer-extractability.md +44 -0
  354. package/dist/universal/.qoder/skills/citable/rubrics/claim-boundedness.md +36 -0
  355. package/dist/universal/.qoder/skills/citable/rubrics/comparison-fairness.md +30 -0
  356. package/dist/universal/.qoder/skills/citable/rubrics/conversion-alignment.md +37 -0
  357. package/dist/universal/.qoder/skills/citable/rubrics/entity-clarity.md +41 -0
  358. package/dist/universal/.qoder/skills/citable/rubrics/evidence-strength.md +53 -0
  359. package/dist/universal/.qoder/skills/citable/rubrics/information-gain.md +33 -0
  360. package/dist/universal/.qoder/skills/citable/rubrics/intent-alignment.md +41 -0
  361. package/dist/universal/.qoder/skills/citable/rubrics/narrative-accuracy.md +46 -0
  362. package/dist/universal/.qoder/skills/citable/rubrics/recommendation-eligibility.md +36 -0
  363. package/dist/universal/.qoder/skills/citable/rubrics/semantic-clarity.md +42 -0
  364. package/dist/universal/.qoder/skills/citable/rubrics/source-authority.md +37 -0
  365. package/dist/universal/.qoder/skills/citable/schemas/claim.schema.json +53 -0
  366. package/dist/universal/.qoder/skills/citable/schemas/common.defs.json +33 -0
  367. package/dist/universal/.qoder/skills/citable/schemas/competitor.schema.json +28 -0
  368. package/dist/universal/.qoder/skills/citable/schemas/config.schema.json +41 -0
  369. package/dist/universal/.qoder/skills/citable/schemas/crawler.schema.json +33 -0
  370. package/dist/universal/.qoder/skills/citable/schemas/detector-quality.schema.json +39 -0
  371. package/dist/universal/.qoder/skills/citable/schemas/entity.schema.json +39 -0
  372. package/dist/universal/.qoder/skills/citable/schemas/evidence.schema.json +41 -0
  373. package/dist/universal/.qoder/skills/citable/schemas/experiment.schema.json +37 -0
  374. package/dist/universal/.qoder/skills/citable/schemas/finding.schema.json +101 -0
  375. package/dist/universal/.qoder/skills/citable/schemas/page.schema.json +40 -0
  376. package/dist/universal/.qoder/skills/citable/schemas/project.schema.json +29 -0
  377. package/dist/universal/.qoder/skills/citable/schemas/prompt-result.schema.json +37 -0
  378. package/dist/universal/.qoder/skills/citable/schemas/prompt.schema.json +41 -0
  379. package/dist/universal/.qoder/skills/citable/schemas/query.schema.json +43 -0
  380. package/dist/universal/.qoder/skills/citable/schemas/run.schema.json +36 -0
  381. package/dist/universal/.qoder/skills/citable/scripts/README.md +4 -0
  382. package/dist/universal/.qoder/skills/citable/templates/finding-review.md +54 -0
  383. package/dist/universal/.rovodev/skills/citable/SKILL.md +137 -0
  384. package/dist/universal/.rovodev/skills/citable/VERSION +1 -0
  385. package/dist/universal/.rovodev/skills/citable/commands/README.md +36 -0
  386. package/dist/universal/.rovodev/skills/citable/commands/ingest.md +44 -0
  387. package/dist/universal/.rovodev/skills/citable/commands/measurement.md +49 -0
  388. package/dist/universal/.rovodev/skills/citable/commands/optimize-page.md +53 -0
  389. package/dist/universal/.rovodev/skills/citable/commands/page-work.md +48 -0
  390. package/dist/universal/.rovodev/skills/citable/commands/validate-render.md +24 -0
  391. package/dist/universal/.rovodev/skills/citable/manifest.json +54 -0
  392. package/dist/universal/.rovodev/skills/citable/policies/crawler-policy-template.md +47 -0
  393. package/dist/universal/.rovodev/skills/citable/references/anti-patterns.md +61 -0
  394. package/dist/universal/.rovodev/skills/citable/rubrics/README.md +30 -0
  395. package/dist/universal/.rovodev/skills/citable/rubrics/answer-extractability.md +44 -0
  396. package/dist/universal/.rovodev/skills/citable/rubrics/claim-boundedness.md +36 -0
  397. package/dist/universal/.rovodev/skills/citable/rubrics/comparison-fairness.md +30 -0
  398. package/dist/universal/.rovodev/skills/citable/rubrics/conversion-alignment.md +37 -0
  399. package/dist/universal/.rovodev/skills/citable/rubrics/entity-clarity.md +41 -0
  400. package/dist/universal/.rovodev/skills/citable/rubrics/evidence-strength.md +53 -0
  401. package/dist/universal/.rovodev/skills/citable/rubrics/information-gain.md +33 -0
  402. package/dist/universal/.rovodev/skills/citable/rubrics/intent-alignment.md +41 -0
  403. package/dist/universal/.rovodev/skills/citable/rubrics/narrative-accuracy.md +46 -0
  404. package/dist/universal/.rovodev/skills/citable/rubrics/recommendation-eligibility.md +36 -0
  405. package/dist/universal/.rovodev/skills/citable/rubrics/semantic-clarity.md +42 -0
  406. package/dist/universal/.rovodev/skills/citable/rubrics/source-authority.md +37 -0
  407. package/dist/universal/.rovodev/skills/citable/schemas/claim.schema.json +53 -0
  408. package/dist/universal/.rovodev/skills/citable/schemas/common.defs.json +33 -0
  409. package/dist/universal/.rovodev/skills/citable/schemas/competitor.schema.json +28 -0
  410. package/dist/universal/.rovodev/skills/citable/schemas/config.schema.json +41 -0
  411. package/dist/universal/.rovodev/skills/citable/schemas/crawler.schema.json +33 -0
  412. package/dist/universal/.rovodev/skills/citable/schemas/detector-quality.schema.json +39 -0
  413. package/dist/universal/.rovodev/skills/citable/schemas/entity.schema.json +39 -0
  414. package/dist/universal/.rovodev/skills/citable/schemas/evidence.schema.json +41 -0
  415. package/dist/universal/.rovodev/skills/citable/schemas/experiment.schema.json +37 -0
  416. package/dist/universal/.rovodev/skills/citable/schemas/finding.schema.json +101 -0
  417. package/dist/universal/.rovodev/skills/citable/schemas/page.schema.json +40 -0
  418. package/dist/universal/.rovodev/skills/citable/schemas/project.schema.json +29 -0
  419. package/dist/universal/.rovodev/skills/citable/schemas/prompt-result.schema.json +37 -0
  420. package/dist/universal/.rovodev/skills/citable/schemas/prompt.schema.json +41 -0
  421. package/dist/universal/.rovodev/skills/citable/schemas/query.schema.json +43 -0
  422. package/dist/universal/.rovodev/skills/citable/schemas/run.schema.json +36 -0
  423. package/dist/universal/.rovodev/skills/citable/scripts/README.md +4 -0
  424. package/dist/universal/.rovodev/skills/citable/templates/finding-review.md +54 -0
  425. package/dist/universal/.trae/skills/citable/SKILL.md +137 -0
  426. package/dist/universal/.trae/skills/citable/VERSION +1 -0
  427. package/dist/universal/.trae/skills/citable/commands/README.md +36 -0
  428. package/dist/universal/.trae/skills/citable/commands/ingest.md +44 -0
  429. package/dist/universal/.trae/skills/citable/commands/measurement.md +49 -0
  430. package/dist/universal/.trae/skills/citable/commands/optimize-page.md +53 -0
  431. package/dist/universal/.trae/skills/citable/commands/page-work.md +48 -0
  432. package/dist/universal/.trae/skills/citable/commands/validate-render.md +24 -0
  433. package/dist/universal/.trae/skills/citable/manifest.json +54 -0
  434. package/dist/universal/.trae/skills/citable/policies/crawler-policy-template.md +47 -0
  435. package/dist/universal/.trae/skills/citable/references/anti-patterns.md +61 -0
  436. package/dist/universal/.trae/skills/citable/rubrics/README.md +30 -0
  437. package/dist/universal/.trae/skills/citable/rubrics/answer-extractability.md +44 -0
  438. package/dist/universal/.trae/skills/citable/rubrics/claim-boundedness.md +36 -0
  439. package/dist/universal/.trae/skills/citable/rubrics/comparison-fairness.md +30 -0
  440. package/dist/universal/.trae/skills/citable/rubrics/conversion-alignment.md +37 -0
  441. package/dist/universal/.trae/skills/citable/rubrics/entity-clarity.md +41 -0
  442. package/dist/universal/.trae/skills/citable/rubrics/evidence-strength.md +53 -0
  443. package/dist/universal/.trae/skills/citable/rubrics/information-gain.md +33 -0
  444. package/dist/universal/.trae/skills/citable/rubrics/intent-alignment.md +41 -0
  445. package/dist/universal/.trae/skills/citable/rubrics/narrative-accuracy.md +46 -0
  446. package/dist/universal/.trae/skills/citable/rubrics/recommendation-eligibility.md +36 -0
  447. package/dist/universal/.trae/skills/citable/rubrics/semantic-clarity.md +42 -0
  448. package/dist/universal/.trae/skills/citable/rubrics/source-authority.md +37 -0
  449. package/dist/universal/.trae/skills/citable/schemas/claim.schema.json +53 -0
  450. package/dist/universal/.trae/skills/citable/schemas/common.defs.json +33 -0
  451. package/dist/universal/.trae/skills/citable/schemas/competitor.schema.json +28 -0
  452. package/dist/universal/.trae/skills/citable/schemas/config.schema.json +41 -0
  453. package/dist/universal/.trae/skills/citable/schemas/crawler.schema.json +33 -0
  454. package/dist/universal/.trae/skills/citable/schemas/detector-quality.schema.json +39 -0
  455. package/dist/universal/.trae/skills/citable/schemas/entity.schema.json +39 -0
  456. package/dist/universal/.trae/skills/citable/schemas/evidence.schema.json +41 -0
  457. package/dist/universal/.trae/skills/citable/schemas/experiment.schema.json +37 -0
  458. package/dist/universal/.trae/skills/citable/schemas/finding.schema.json +101 -0
  459. package/dist/universal/.trae/skills/citable/schemas/page.schema.json +40 -0
  460. package/dist/universal/.trae/skills/citable/schemas/project.schema.json +29 -0
  461. package/dist/universal/.trae/skills/citable/schemas/prompt-result.schema.json +37 -0
  462. package/dist/universal/.trae/skills/citable/schemas/prompt.schema.json +41 -0
  463. package/dist/universal/.trae/skills/citable/schemas/query.schema.json +43 -0
  464. package/dist/universal/.trae/skills/citable/schemas/run.schema.json +36 -0
  465. package/dist/universal/.trae/skills/citable/scripts/README.md +4 -0
  466. package/dist/universal/.trae/skills/citable/templates/finding-review.md +54 -0
  467. package/dist/universal/.trae-cn/skills/citable/SKILL.md +137 -0
  468. package/dist/universal/.trae-cn/skills/citable/VERSION +1 -0
  469. package/dist/universal/.trae-cn/skills/citable/commands/README.md +36 -0
  470. package/dist/universal/.trae-cn/skills/citable/commands/ingest.md +44 -0
  471. package/dist/universal/.trae-cn/skills/citable/commands/measurement.md +49 -0
  472. package/dist/universal/.trae-cn/skills/citable/commands/optimize-page.md +53 -0
  473. package/dist/universal/.trae-cn/skills/citable/commands/page-work.md +48 -0
  474. package/dist/universal/.trae-cn/skills/citable/commands/validate-render.md +24 -0
  475. package/dist/universal/.trae-cn/skills/citable/manifest.json +54 -0
  476. package/dist/universal/.trae-cn/skills/citable/policies/crawler-policy-template.md +47 -0
  477. package/dist/universal/.trae-cn/skills/citable/references/anti-patterns.md +61 -0
  478. package/dist/universal/.trae-cn/skills/citable/rubrics/README.md +30 -0
  479. package/dist/universal/.trae-cn/skills/citable/rubrics/answer-extractability.md +44 -0
  480. package/dist/universal/.trae-cn/skills/citable/rubrics/claim-boundedness.md +36 -0
  481. package/dist/universal/.trae-cn/skills/citable/rubrics/comparison-fairness.md +30 -0
  482. package/dist/universal/.trae-cn/skills/citable/rubrics/conversion-alignment.md +37 -0
  483. package/dist/universal/.trae-cn/skills/citable/rubrics/entity-clarity.md +41 -0
  484. package/dist/universal/.trae-cn/skills/citable/rubrics/evidence-strength.md +53 -0
  485. package/dist/universal/.trae-cn/skills/citable/rubrics/information-gain.md +33 -0
  486. package/dist/universal/.trae-cn/skills/citable/rubrics/intent-alignment.md +41 -0
  487. package/dist/universal/.trae-cn/skills/citable/rubrics/narrative-accuracy.md +46 -0
  488. package/dist/universal/.trae-cn/skills/citable/rubrics/recommendation-eligibility.md +36 -0
  489. package/dist/universal/.trae-cn/skills/citable/rubrics/semantic-clarity.md +42 -0
  490. package/dist/universal/.trae-cn/skills/citable/rubrics/source-authority.md +37 -0
  491. package/dist/universal/.trae-cn/skills/citable/schemas/claim.schema.json +53 -0
  492. package/dist/universal/.trae-cn/skills/citable/schemas/common.defs.json +33 -0
  493. package/dist/universal/.trae-cn/skills/citable/schemas/competitor.schema.json +28 -0
  494. package/dist/universal/.trae-cn/skills/citable/schemas/config.schema.json +41 -0
  495. package/dist/universal/.trae-cn/skills/citable/schemas/crawler.schema.json +33 -0
  496. package/dist/universal/.trae-cn/skills/citable/schemas/detector-quality.schema.json +39 -0
  497. package/dist/universal/.trae-cn/skills/citable/schemas/entity.schema.json +39 -0
  498. package/dist/universal/.trae-cn/skills/citable/schemas/evidence.schema.json +41 -0
  499. package/dist/universal/.trae-cn/skills/citable/schemas/experiment.schema.json +37 -0
  500. package/dist/universal/.trae-cn/skills/citable/schemas/finding.schema.json +101 -0
  501. package/dist/universal/.trae-cn/skills/citable/schemas/page.schema.json +40 -0
  502. package/dist/universal/.trae-cn/skills/citable/schemas/project.schema.json +29 -0
  503. package/dist/universal/.trae-cn/skills/citable/schemas/prompt-result.schema.json +37 -0
  504. package/dist/universal/.trae-cn/skills/citable/schemas/prompt.schema.json +41 -0
  505. package/dist/universal/.trae-cn/skills/citable/schemas/query.schema.json +43 -0
  506. package/dist/universal/.trae-cn/skills/citable/schemas/run.schema.json +36 -0
  507. package/dist/universal/.trae-cn/skills/citable/scripts/README.md +4 -0
  508. package/dist/universal/.trae-cn/skills/citable/templates/finding-review.md +54 -0
  509. package/dist/universal/manifest.json +598 -0
  510. package/package.json +89 -0
  511. package/schemas/claim.schema.json +53 -0
  512. package/schemas/common.defs.json +33 -0
  513. package/schemas/competitor.schema.json +28 -0
  514. package/schemas/config.schema.json +41 -0
  515. package/schemas/crawler.schema.json +33 -0
  516. package/schemas/detector-quality.schema.json +39 -0
  517. package/schemas/entity.schema.json +39 -0
  518. package/schemas/evidence.schema.json +41 -0
  519. package/schemas/experiment.schema.json +37 -0
  520. package/schemas/finding.schema.json +101 -0
  521. package/schemas/page.schema.json +40 -0
  522. package/schemas/project.schema.json +29 -0
  523. package/schemas/prompt-result.schema.json +37 -0
  524. package/schemas/prompt.schema.json +41 -0
  525. package/schemas/query.schema.json +43 -0
  526. package/schemas/run.schema.json +36 -0
  527. package/scripts/build-dist.js +143 -0
  528. package/skill/SKILL.md +137 -0
  529. package/skill/commands/README.md +36 -0
  530. package/skill/commands/ingest.md +44 -0
  531. package/skill/commands/measurement.md +49 -0
  532. package/skill/commands/optimize-page.md +53 -0
  533. package/skill/commands/page-work.md +48 -0
  534. package/skill/commands/validate-render.md +24 -0
  535. package/skill/policies/crawler-policy-template.md +47 -0
  536. package/skill/references/anti-patterns.md +61 -0
  537. package/skill/rubrics/README.md +30 -0
  538. package/skill/rubrics/answer-extractability.md +44 -0
  539. package/skill/rubrics/claim-boundedness.md +36 -0
  540. package/skill/rubrics/comparison-fairness.md +30 -0
  541. package/skill/rubrics/conversion-alignment.md +37 -0
  542. package/skill/rubrics/entity-clarity.md +41 -0
  543. package/skill/rubrics/evidence-strength.md +53 -0
  544. package/skill/rubrics/information-gain.md +33 -0
  545. package/skill/rubrics/intent-alignment.md +41 -0
  546. package/skill/rubrics/narrative-accuracy.md +46 -0
  547. package/skill/rubrics/recommendation-eligibility.md +36 -0
  548. package/skill/rubrics/semantic-clarity.md +42 -0
  549. package/skill/rubrics/source-authority.md +37 -0
  550. package/skill/templates/finding-review.md +54 -0
  551. package/src/cli/index.js +135 -0
  552. package/src/commands/audit.js +111 -0
  553. package/src/commands/compareSnapshots.js +48 -0
  554. package/src/commands/context.js +62 -0
  555. package/src/commands/init.js +111 -0
  556. package/src/commands/inspect.js +61 -0
  557. package/src/commands/mapClaims.js +89 -0
  558. package/src/commands/schemaCmd.js +71 -0
  559. package/src/commands/substantiate.js +121 -0
  560. package/src/commands/validate.js +27 -0
  561. package/src/crawler/fetch.js +31 -0
  562. package/src/crawler/robots.js +67 -0
  563. package/src/crawler/sitemap.js +25 -0
  564. package/src/detectors/ans.js +219 -0
  565. package/src/detectors/arch.js +154 -0
  566. package/src/detectors/claim.js +230 -0
  567. package/src/detectors/crawl.js +143 -0
  568. package/src/detectors/entity.js +202 -0
  569. package/src/detectors/evd.js +164 -0
  570. package/src/detectors/framework.js +137 -0
  571. package/src/detectors/geoReco.js +218 -0
  572. package/src/detectors/index.js +50 -0
  573. package/src/detectors/lifeMeas.js +212 -0
  574. package/src/detectors/link.js +121 -0
  575. package/src/detectors/page.js +202 -0
  576. package/src/detectors/schemaData.js +249 -0
  577. package/src/detectors/tech.js +397 -0
  578. package/src/evidence/run.js +88 -0
  579. package/src/extractor/page.js +125 -0
  580. package/src/extractor/site.js +175 -0
  581. package/src/installer/index.js +1117 -0
  582. package/src/installer/providers.js +164 -0
  583. package/src/registries/index.js +127 -0
  584. package/src/reporting/report.js +82 -0
  585. package/src/shared/io.js +56 -0
  586. package/src/shared/schemaValidator.js +29 -0
@@ -0,0 +1,202 @@
1
+ import { defineDetector, indexTargets, pageSubject, entrySubject } from './framework.js';
2
+ import { isPastDate } from '../shared/io.js';
3
+
4
+ const D = [];
5
+
6
+ function allJsonLdBlocks(site) {
7
+ const out = [];
8
+ for (const p of site.pages) {
9
+ for (const j of p.jsonLd) for (const b of j.blocks) out.push({ page: p, block: b });
10
+ }
11
+ return out;
12
+ }
13
+
14
+ D.push(defineDetector({
15
+ id: 'ENTITY-001', name: 'Entity missing canonical URL', namespace: 'ENTITY',
16
+ description: 'A registry entity has no canonical URL, so engines have no authoritative page to resolve it to.',
17
+ discipline: ['geo', 'aeo'], severity: 'medium', deterministic: true, requires: ['registries'],
18
+ impact: { representation: 'high' },
19
+ applicable_requirement: 'AEO §3 every entity should have one canonical URL; GEO §3 canonical entities',
20
+ remediation: 'Create or designate one canonical page for the entity and record it in the registry.',
21
+ verification: 'Registry entry has canonical_url set and resolvable.',
22
+ check(ctx) {
23
+ return (ctx.registries.entities?.entries || [])
24
+ .filter((e) => e.status !== 'retired' && !e.canonical_url)
25
+ .map((e) => ({
26
+ subject: entrySubject('entities', e.entity_id),
27
+ summary: `Entity "${e.canonical_name}" has no canonical URL`,
28
+ evidence: [`entities/${e.entity_id}: canonical_url empty`],
29
+ }));
30
+ },
31
+ }));
32
+
33
+ D.push(defineDetector({
34
+ id: 'ENTITY-002', name: 'Schema entity name conflicts with registry', namespace: 'ENTITY',
35
+ description: 'A JSON-LD Organization/Product name does not match the registry canonical name or a documented alias.',
36
+ discipline: ['geo', 'seo'], severity: 'high', deterministic: true, requires: ['site', 'registries'],
37
+ impact: { representation: 'high' },
38
+ applicable_requirement: 'GEO §3 required consistency; detector spec: schema entity differs from visible entity',
39
+ remediation: 'Emit the canonical name from the entity registry in structured data; add legitimate variants to aliases.',
40
+ verification: 'Compare schema names with registry canonical_name and aliases.',
41
+ check(ctx) {
42
+ const entities = (ctx.registries.entities?.entries || []).filter((e) => ['organization', 'product', 'product_family'].includes(e.entity_type));
43
+ if (entities.length === 0) return [];
44
+ const hits = [];
45
+ for (const { page, block } of allJsonLdBlocks(ctx.site)) {
46
+ const type = [].concat(block['@type'] || []).join(',');
47
+ if (!/Organization|Corporation|SoftwareApplication|Product/i.test(type) || !block.name) continue;
48
+ const match = entities.find(
49
+ (e) => e.canonical_name.toLowerCase() === String(block.name).toLowerCase() || (e.aliases || []).some((a) => a.toLowerCase() === String(block.name).toLowerCase())
50
+ );
51
+ if (!match) {
52
+ const nearest = entities.find((e) => String(block.name).toLowerCase().includes(e.canonical_name.toLowerCase().split(' ')[0]) || e.canonical_name.toLowerCase().includes(String(block.name).toLowerCase().split(' ')[0]));
53
+ if (nearest) {
54
+ hits.push({
55
+ subject: { type: 'schema_block', identifier: `${page.url}#${block['@id'] || block.name}`, url: page.url },
56
+ summary: `Schema ${type} name "${block.name}" is not the canonical name "${nearest.canonical_name}" nor a documented alias`,
57
+ evidence: [`schema name: ${block.name}`, `registry canonical: ${nearest.canonical_name}; aliases: ${(nearest.aliases || []).join(', ') || 'none'}`],
58
+ });
59
+ }
60
+ }
61
+ }
62
+ return hits;
63
+ },
64
+ }));
65
+
66
+ D.push(defineDetector({
67
+ id: 'ENTITY-003', name: 'Unstable @id for same entity', namespace: 'ENTITY',
68
+ description: 'The same entity name appears in JSON-LD with different @id values across pages.',
69
+ discipline: ['geo', 'seo'], severity: 'medium', deterministic: true, requires: ['site'],
70
+ impact: { representation: 'medium' },
71
+ applicable_requirement: 'SEO §7 stable @id identifiers; GEO §9 required graph consistency',
72
+ remediation: 'Emit one stable @id per entity from shared data, referenced everywhere.',
73
+ verification: 'Collect @id values per entity name; each name maps to one @id.',
74
+ check(ctx) {
75
+ const byName = new Map();
76
+ for (const { block } of allJsonLdBlocks(ctx.site)) {
77
+ if (!block.name || !block['@id']) continue;
78
+ const key = `${[].concat(block['@type'] || []).join(',')}|${String(block.name).toLowerCase()}`;
79
+ if (!byName.has(key)) byName.set(key, new Set());
80
+ byName.get(key).add(block['@id']);
81
+ }
82
+ return [...byName.entries()]
83
+ .filter(([, ids]) => ids.size > 1)
84
+ .map(([key, ids]) => ({
85
+ subject: { type: 'entity', identifier: key },
86
+ summary: `Entity "${key.split('|')[1]}" uses ${ids.size} different @id values`,
87
+ evidence: [...ids].map((i) => `@id: ${i}`),
88
+ }));
89
+ },
90
+ }));
91
+
92
+ D.push(defineDetector({
93
+ id: 'ENTITY-004', name: 'sameAs profile not in authoritative list', namespace: 'ENTITY',
94
+ description: 'JSON-LD sameAs references a profile URL not recorded as an authoritative profile in the entity registry.',
95
+ discipline: ['geo'], severity: 'low', deterministic: true, requires: ['site', 'registries'],
96
+ impact: { representation: 'medium' },
97
+ applicable_requirement: 'AEO §6 sameAs limited to authoritative profiles; detector spec: unsupported sameAs',
98
+ remediation: 'Either add the profile to authoritative_profiles after verification, or remove it from sameAs.',
99
+ verification: 'Every sameAs URL appears in the registry authoritative_profiles.',
100
+ check(ctx) {
101
+ const entities = ctx.registries.entities?.entries || [];
102
+ if (entities.length === 0) return [];
103
+ const hits = [];
104
+ for (const { page, block } of allJsonLdBlocks(ctx.site)) {
105
+ if (!block.sameAs || !block.name) continue;
106
+ const entity = entities.find((e) => e.canonical_name.toLowerCase() === String(block.name).toLowerCase() || (e.aliases || []).some((a) => a.toLowerCase() === String(block.name).toLowerCase()));
107
+ if (!entity) continue;
108
+ const approved = new Set(entity.authoritative_profiles || []);
109
+ for (const s of [].concat(block.sameAs)) {
110
+ if (!approved.has(s)) {
111
+ hits.push({
112
+ subject: { type: 'schema_block', identifier: `${page.url}#sameAs`, url: page.url },
113
+ summary: `sameAs "${s}" for "${block.name}" is not a registered authoritative profile`,
114
+ evidence: [`schema sameAs: ${s}`, `registered profiles: ${[...approved].join(', ') || 'none'}`],
115
+ });
116
+ }
117
+ }
118
+ }
119
+ return hits;
120
+ },
121
+ }));
122
+
123
+ D.push(defineDetector({
124
+ id: 'ENTITY-005', name: 'Product entity without owner relationship', namespace: 'ENTITY',
125
+ description: 'A product/product-family entity records no owning organization.',
126
+ discipline: ['geo'], severity: 'medium', deterministic: true, requires: ['registries'],
127
+ impact: { representation: 'high' },
128
+ applicable_requirement: 'GEO §3 the engine must determine which products the organization owns; detector spec: product ownership ambiguous',
129
+ remediation: 'Set owner_entity (or a relationship) linking the product to its organization.',
130
+ verification: 'Product entity has owner_entity or an ownership relationship.',
131
+ check(ctx) {
132
+ return (ctx.registries.entities?.entries || [])
133
+ .filter((e) => ['product', 'product_family', 'service'].includes(e.entity_type) && e.status !== 'retired')
134
+ .filter((e) => !e.owner_entity && !(e.relationships || []).some((r) => ['owned_by', 'organization', 'publisher'].includes(r.type)))
135
+ .map((e) => ({
136
+ subject: entrySubject('entities', e.entity_id),
137
+ summary: `Product entity "${e.canonical_name}" has no recorded owning organization`,
138
+ evidence: [`entities/${e.entity_id}: owner_entity empty; no ownership relationship`],
139
+ }));
140
+ },
141
+ }));
142
+
143
+ D.push(defineDetector({
144
+ id: 'ENTITY-006', name: 'Unregistered name variant in page text', namespace: 'ENTITY',
145
+ description: 'Page text uses a variant of an entity name that is neither the canonical name nor a documented alias.',
146
+ discipline: ['geo', 'seo'], severity: 'low', deterministic: false, requires: ['site', 'registries'],
147
+ impact: { representation: 'medium' },
148
+ applicable_requirement: 'GEO §3 category contradictions and naming drift; SEO §6 consistent names',
149
+ false_positive_conditions: ['grammatical possessives and legitimate prose inflections'],
150
+ remediation: 'Standardize on the canonical name, or register the variant as an alias if intentional.',
151
+ verification: 'Page text uses only canonical names and registered aliases.',
152
+ check(ctx) {
153
+ const hits = [];
154
+ for (const e of (ctx.registries.entities?.entries || []).filter((e) => ['organization', 'product'].includes(e.entity_type))) {
155
+ const canonical = e.canonical_name;
156
+ const parts = canonical.split(/\s+/);
157
+ if (parts.length < 2) continue; // single-word names produce too many false variants
158
+ const known = new Set([canonical.toLowerCase(), ...(e.aliases || []).map((a) => a.toLowerCase())]);
159
+ // variant: same words joined/hyphenated/reordered-case
160
+ const variantRx = new RegExp(parts.join('[\\s-]*'), 'gi');
161
+ for (const p of indexTargets(ctx)) {
162
+ for (const m of p.text.matchAll(variantRx)) {
163
+ const found = m[0];
164
+ if (!known.has(found.toLowerCase())) {
165
+ hits.push({
166
+ subject: pageSubject(p),
167
+ summary: `Name variant "${found}" used for entity "${canonical}" (not a registered alias)`,
168
+ evidence: [`found: "${found}"`, `canonical: "${canonical}"`],
169
+ confidence: 'medium',
170
+ });
171
+ break; // one hit per page per entity
172
+ }
173
+ }
174
+ }
175
+ }
176
+ return hits;
177
+ },
178
+ }));
179
+
180
+ D.push(defineDetector({
181
+ id: 'ENTITY-007', name: 'Entity verification stale', namespace: 'ENTITY',
182
+ description: 'An active entity has not been verified within the last 12 months (or last_verified missing).',
183
+ discipline: ['geo'], severity: 'low', deterministic: true, requires: ['registries'],
184
+ impact: { representation: 'medium', maintainability: 'medium' },
185
+ applicable_requirement: 'GEO §3 entity record last_verified; lifecycle premises',
186
+ remediation: 'Re-verify identity, category, relationships, and profiles; update last_verified.',
187
+ verification: 'last_verified within 12 months.',
188
+ check(ctx) {
189
+ const cutoff = new Date(ctx.refDate ?? Date.now());
190
+ cutoff.setMonth(cutoff.getMonth() - 12);
191
+ return (ctx.registries.entities?.entries || [])
192
+ .filter((e) => e.status === 'active' || e.status === 'verified')
193
+ .filter((e) => !e.last_verified || new Date(e.last_verified) < cutoff)
194
+ .map((e) => ({
195
+ subject: entrySubject('entities', e.entity_id),
196
+ summary: `Entity "${e.canonical_name}" not verified in the last 12 months (last: ${e.last_verified ?? 'never'})`,
197
+ evidence: [`last_verified: ${e.last_verified ?? 'missing'}`],
198
+ }));
199
+ },
200
+ }));
201
+
202
+ export default D;
@@ -0,0 +1,164 @@
1
+ import { defineDetector, entrySubject } from './framework.js';
2
+ import { isPastDate } from '../shared/io.js';
3
+
4
+ const D = [];
5
+
6
+ D.push(defineDetector({
7
+ id: 'EVD-001', name: 'Evidence past validity date', namespace: 'EVD',
8
+ description: 'An evidence entry has passed valid_until but its verification_status is not stale/revoked.',
9
+ discipline: ['aeo', 'geo'], severity: 'medium', deterministic: true, requires: ['registries'],
10
+ impact: { legal: 'medium', citation: 'medium' },
11
+ applicable_requirement: 'Registry §6.5 valid_until; AEO §8 source revalidation',
12
+ remediation: 'Re-validate the evidence or mark it stale and re-assess dependent claims.',
13
+ verification: 'No verified evidence past its valid_until date.',
14
+ check(ctx) {
15
+ return (ctx.registries.evidence?.entries || [])
16
+ .filter((e) => isPastDate(e.valid_until, ctx.refDate) && !['stale', 'revoked', 'inaccessible'].includes(e.verification_status))
17
+ .map((e) => ({
18
+ subject: entrySubject('evidence', e.evidence_id),
19
+ summary: `Evidence "${e.title}" passed valid_until ${e.valid_until} but is still ${e.verification_status}`,
20
+ evidence: [`valid_until: ${e.valid_until}; verification_status: ${e.verification_status}`],
21
+ }));
22
+ },
23
+ }));
24
+
25
+ D.push(defineDetector({
26
+ id: 'EVD-002', name: 'Benchmark/test evidence missing methodology', namespace: 'EVD',
27
+ description: 'Benchmark, test-result, or dataset evidence records no methodology or measurement period.',
28
+ discipline: ['aeo', 'geo'], severity: 'medium', deterministic: true, requires: ['registries'],
29
+ impact: { citation: 'medium', legal: 'medium' },
30
+ applicable_requirement: 'AEO §8 version evidence: methodology, test date; detector spec: missing methodology / measurement period',
31
+ remediation: 'Record methodology, test conditions, and measurement period, or downgrade dependent claims.',
32
+ verification: 'Benchmark/test evidence entries carry methodology and measurement_period.',
33
+ check(ctx) {
34
+ return (ctx.registries.evidence?.entries || [])
35
+ .filter((e) => ['benchmark', 'test_result', 'dataset'].includes(e.evidence_type))
36
+ .filter((e) => !e.methodology || !e.measurement_period)
37
+ .map((e) => ({
38
+ subject: entrySubject('evidence', e.evidence_id),
39
+ summary: `${e.evidence_type} evidence "${e.title}" lacks ${!e.methodology ? 'methodology' : ''}${!e.methodology && !e.measurement_period ? ' and ' : ''}${!e.measurement_period ? 'measurement period' : ''}`,
40
+ evidence: [`methodology: ${e.methodology ?? 'missing'}; measurement_period: ${e.measurement_period ?? 'missing'}`],
41
+ }));
42
+ },
43
+ }));
44
+
45
+ D.push(defineDetector({
46
+ id: 'EVD-003', name: 'Claim references dangling or unverified evidence', namespace: 'EVD',
47
+ description: 'A claim references an evidence id that does not exist or has verification_status unverified.',
48
+ discipline: ['aeo', 'geo'], severity: 'high', deterministic: true, requires: ['registries'],
49
+ impact: { legal: 'medium', maintainability: 'medium' },
50
+ applicable_requirement: 'Referential integrity between claim and evidence registries; premise 3.5',
51
+ remediation: 'Register and verify the evidence, or remove the reference and re-assess the claim.',
52
+ verification: 'All claim evidence references resolve to reviewed/verified entries.',
53
+ check(ctx) {
54
+ const ev = new Map((ctx.registries.evidence?.entries || []).map((e) => [e.evidence_id, e]));
55
+ const hits = [];
56
+ for (const c of ctx.registries.claims?.entries || []) {
57
+ for (const id of c.evidence || []) {
58
+ const e = ev.get(id);
59
+ if (!e) {
60
+ hits.push({
61
+ subject: entrySubject('claims', c.claim_id),
62
+ summary: `Claim references unknown evidence id "${id}"`,
63
+ evidence: [`claims/${c.claim_id} → evidence "${id}" not found`],
64
+ });
65
+ } else if (e.verification_status === 'unverified' && ['verified', 'verified_narrowed'].includes(c.status)) {
66
+ hits.push({
67
+ subject: entrySubject('claims', c.claim_id),
68
+ summary: `Verified claim relies on unverified evidence "${id}"`,
69
+ evidence: [`evidence/${id}: verification_status=unverified`],
70
+ });
71
+ }
72
+ }
73
+ }
74
+ return hits;
75
+ },
76
+ }));
77
+
78
+ D.push(defineDetector({
79
+ id: 'EVD-004', name: 'Secondary evidence where primary is required', namespace: 'EVD',
80
+ description: 'A performance or security claim is supported only by secondary evidence (e.g., third-party articles).',
81
+ discipline: ['aeo', 'geo'], severity: 'medium', deterministic: true, requires: ['registries'],
82
+ impact: { legal: 'medium', citation: 'medium' },
83
+ applicable_requirement: 'Detector spec: secondary evidence used where primary evidence is required; AEO §4 primary sources where available',
84
+ remediation: 'Produce primary evidence (test result, architecture spec, certification) or narrow the claim.',
85
+ verification: 'Performance/security claims have at least one primary evidence entry.',
86
+ check(ctx) {
87
+ const ev = new Map((ctx.registries.evidence?.entries || []).map((e) => [e.evidence_id, e]));
88
+ const hits = [];
89
+ for (const c of (ctx.registries.claims?.entries || []).filter((c) => ['performance', 'security'].includes(c.claim_type) && (c.evidence || []).length > 0)) {
90
+ const kinds = (c.evidence || []).map((id) => ev.get(id)).filter(Boolean);
91
+ if (kinds.length > 0 && kinds.every((e) => e.primary_or_secondary === 'secondary')) {
92
+ hits.push({
93
+ subject: entrySubject('claims', c.claim_id),
94
+ summary: `${c.claim_type} claim supported only by secondary evidence`,
95
+ evidence: kinds.map((e) => `${e.evidence_id}: ${e.evidence_type} (secondary)`),
96
+ });
97
+ }
98
+ }
99
+ return hits;
100
+ },
101
+ }));
102
+
103
+ D.push(defineDetector({
104
+ id: 'EVD-005', name: 'Customer evidence lacks attribution', namespace: 'EVD',
105
+ description: 'Customer-reference or case-study evidence has no attribution recorded.',
106
+ discipline: ['aeo', 'geo'], severity: 'low', deterministic: true, requires: ['registries'],
107
+ impact: { reputational: 'medium', legal: 'medium' },
108
+ applicable_requirement: 'Detector spec: customer evidence lacks attribution; premise 3.6 no fabricated customers',
109
+ remediation: 'Record attribution (who, role, permission status) or mark the evidence anonymous-by-consent with reviewer sign-off.',
110
+ verification: 'Customer evidence entries carry attribution or a documented consent basis.',
111
+ check(ctx) {
112
+ return (ctx.registries.evidence?.entries || [])
113
+ .filter((e) => ['customer_reference', 'case_study'].includes(e.evidence_type) && !e.attribution && !e.reviewer)
114
+ .map((e) => ({
115
+ subject: entrySubject('evidence', e.evidence_id),
116
+ summary: `Customer evidence "${e.title}" has no attribution and no reviewer`,
117
+ evidence: ['attribution: missing; reviewer: missing'],
118
+ }));
119
+ },
120
+ }));
121
+
122
+ D.push(defineDetector({
123
+ id: 'EVD-006', name: 'Evidence integrity hash absent', namespace: 'EVD',
124
+ description: 'Primary evidence (test results, benchmarks, datasets, certifications) has no integrity hash, so later tampering or drift cannot be detected.',
125
+ discipline: ['aeo', 'geo'], severity: 'low', deterministic: true, requires: ['registries'],
126
+ impact: { maintainability: 'medium', legal: 'low' },
127
+ applicable_requirement: 'Registry §6.5 integrity_hash; detector spec: evidence integrity hash absent where expected',
128
+ remediation: 'Store a sha256 of the evidence artifact at verification time.',
129
+ verification: 'Primary evidence entries carry integrity_hash.',
130
+ check(ctx) {
131
+ return (ctx.registries.evidence?.entries || [])
132
+ .filter((e) => ['test_result', 'benchmark', 'dataset', 'certification'].includes(e.evidence_type) && e.primary_or_secondary === 'primary' && !e.integrity_hash)
133
+ .map((e) => ({
134
+ subject: entrySubject('evidence', e.evidence_id),
135
+ summary: `Primary ${e.evidence_type} evidence "${e.title}" has no integrity hash`,
136
+ evidence: ['integrity_hash: missing'],
137
+ }));
138
+ },
139
+ }));
140
+
141
+ D.push(defineDetector({
142
+ id: 'EVD-007', name: 'Evidence marked inaccessible still supporting claims', namespace: 'EVD',
143
+ description: 'Evidence with access_status inaccessible (or verification_status inaccessible) is still listed as supporting active claims.',
144
+ discipline: ['aeo', 'geo'], severity: 'medium', deterministic: true, requires: ['registries'],
145
+ impact: { legal: 'medium', citation: 'medium' },
146
+ applicable_requirement: 'Detector spec: evidence source inaccessible; revoked evidence still supporting published claim',
147
+ remediation: 'Restore access to the source, replace the evidence, or downgrade dependent claims.',
148
+ verification: 'No active claim relies solely on inaccessible evidence.',
149
+ check(ctx) {
150
+ const claims = new Map((ctx.registries.claims?.entries || []).map((c) => [c.claim_id, c]));
151
+ return (ctx.registries.evidence?.entries || [])
152
+ .filter((e) => (e.access_status === 'inaccessible' || e.verification_status === 'inaccessible') && (e.supports_claims || []).some((id) => {
153
+ const c = claims.get(id);
154
+ return c && !['retired', 'expired', 'prohibited'].includes(c.status);
155
+ }))
156
+ .map((e) => ({
157
+ subject: entrySubject('evidence', e.evidence_id),
158
+ summary: `Inaccessible evidence "${e.title}" still supports active claims: ${(e.supports_claims || []).join(', ')}`,
159
+ evidence: [`access_status: ${e.access_status}; verification_status: ${e.verification_status}`],
160
+ }));
161
+ },
162
+ }));
163
+
164
+ export default D;
@@ -0,0 +1,137 @@
1
+ import { sha256 } from '../shared/io.js';
2
+
3
+ const REQUIRED = ['id', 'name', 'namespace', 'description', 'discipline', 'severity', 'deterministic', 'remediation', 'verification', 'check'];
4
+ // RENDER (browser-rendered truth / source-render divergence) is reserved for the
5
+ // rendered-truth phase; no RENDER detectors ship until a real renderer backs them.
6
+ const NAMESPACES = ['TECH', 'CRAWL', 'ARCH', 'PAGE', 'ANS', 'ENTITY', 'CLAIM', 'EVD', 'SCHEMA', 'LINK', 'EXT', 'GEO', 'RECO', 'LIFE', 'MEAS', 'RENDER'];
7
+
8
+ /**
9
+ * Detector definition contract. `check(ctx)` returns raw hits:
10
+ * { subject: {type, identifier, url?, source_file?, source_location?}, summary, evidence: [..],
11
+ * captured?, expected?, severity?, confidence? }
12
+ */
13
+ export function defineDetector(def) {
14
+ for (const k of REQUIRED) {
15
+ if (def[k] === undefined) throw new Error(`detector ${def.id ?? '?'} missing field: ${k}`);
16
+ }
17
+ if (!NAMESPACES.includes(def.namespace)) throw new Error(`detector ${def.id}: unknown namespace ${def.namespace}`);
18
+ if (!def.id.startsWith(def.namespace + '-')) throw new Error(`detector id ${def.id} must be prefixed with namespace`);
19
+ return {
20
+ confidence_model: def.deterministic ? 'binary condition; confirmed when observed' : 'heuristic; confidence reported per finding',
21
+ confidence: def.deterministic ? 'confirmed' : 'medium',
22
+ finding_type: def.deterministic ? 'deterministic_observation' : 'probabilistic_inference',
23
+ impact: {},
24
+ false_positive_conditions: [],
25
+ false_negative_conditions: [],
26
+ applicable_requirement: '',
27
+ ...def,
28
+ };
29
+ }
30
+
31
+ /** Run detectors over a context; returns { findings, detectorsRun, detectorsSkipped, errors }. */
32
+ export function runDetectors(detectors, ctx) {
33
+ const findings = [];
34
+ const detectorsRun = [];
35
+ const detectorsSkipped = [];
36
+ const errors = [];
37
+ const ts = ctx.timestamp ?? new Date().toISOString();
38
+ for (const d of detectors) {
39
+ if (d.requires && !d.requires.every((r) => ctx[r])) {
40
+ detectorsSkipped.push({ detector_id: d.id, reason: `missing context: ${d.requires.filter((r) => !ctx[r]).join(', ')}` });
41
+ continue;
42
+ }
43
+ let hits;
44
+ try {
45
+ hits = d.check(ctx) || [];
46
+ } catch (err) {
47
+ errors.push(`${d.id}: detector error: ${err.message}`);
48
+ continue;
49
+ }
50
+ detectorsRun.push(d.id);
51
+ for (const hit of hits) {
52
+ const idSeed = `${d.id}|${hit.subject?.identifier ?? ''}|${hit.summary}`;
53
+ findings.push({
54
+ finding_id: `F-${sha256(idSeed).slice(0, 12)}`,
55
+ detector_id: d.id,
56
+ run_id: ctx.runId ?? 'adhoc',
57
+ timestamp: ts,
58
+ discipline: d.discipline,
59
+ subject: hit.subject,
60
+ observation: {
61
+ summary: hit.summary,
62
+ evidence: hit.evidence,
63
+ captured_value: hit.captured ?? null,
64
+ expected_value: hit.expected ?? null,
65
+ },
66
+ classification: {
67
+ finding_type: hit.finding_type ?? d.finding_type,
68
+ severity: hit.severity ?? d.severity,
69
+ confidence: hit.confidence ?? d.confidence,
70
+ deterministic: d.deterministic,
71
+ impact: { ...d.impact, ...(hit.impact || {}) },
72
+ },
73
+ reasoning: {
74
+ applicable_requirement: d.applicable_requirement,
75
+ explanation: d.description,
76
+ assumptions: hit.assumptions ?? [],
77
+ limitations: d.deterministic ? [] : ['heuristic detection; verify manually before acting'],
78
+ },
79
+ remediation: {
80
+ preferred: d.remediation,
81
+ alternatives: d.remediation_alternatives ?? [],
82
+ unsafe_shortcuts: d.unsafe_shortcuts ?? [],
83
+ owner: hit.owner ?? null,
84
+ review_required: d.review_required ?? !d.deterministic,
85
+ },
86
+ verification: {
87
+ method: d.verification,
88
+ expected_result: 'detector no longer reports this subject',
89
+ detector_to_rerun: d.id,
90
+ },
91
+ status: { state: 'open', first_seen: ts, last_seen: ts, resolved_at: null },
92
+ });
93
+ }
94
+ }
95
+ return { findings, detectorsRun, detectorsSkipped, errors };
96
+ }
97
+
98
+ /* ---------- shared helpers for detector implementations ---------- */
99
+
100
+ /** Pages whose declared or default intent is to be indexed. */
101
+ export function indexTargets(ctx) {
102
+ return ctx.site.pages.filter((p) => {
103
+ const reg = registryPageFor(ctx, p);
104
+ if (reg?.indexing_intent === 'noindex') return false;
105
+ return true;
106
+ });
107
+ }
108
+
109
+ /** Match a live page to its registry entry by URL path. */
110
+ export function registryPageFor(ctx, page) {
111
+ const entries = ctx.registries?.pages?.entries || [];
112
+ const pPath = safePath(page.url);
113
+ return entries.find((e) => safePath(e.url, ctx.site?.baseUrl) === pPath) ?? null;
114
+ }
115
+
116
+ /** Find the live site page for a registry entry. */
117
+ export function sitePageFor(ctx, registryEntry) {
118
+ if (!ctx.site) return null;
119
+ const target = safePath(registryEntry.url, ctx.site.baseUrl);
120
+ return ctx.site.pages.find((p) => safePath(p.url) === target) ?? null;
121
+ }
122
+
123
+ export function safePath(url, base = 'https://example.test') {
124
+ try {
125
+ return new URL(url, base).pathname.replace(/\/$/, '') || '/';
126
+ } catch {
127
+ return url;
128
+ }
129
+ }
130
+
131
+ export function pageSubject(page) {
132
+ return { type: 'page', identifier: page.url, url: page.url, ...(page.sourceFile ? { source_file: page.sourceFile } : {}) };
133
+ }
134
+
135
+ export function entrySubject(type, id) {
136
+ return { type: 'registry_entry', identifier: `${type}/${id}` };
137
+ }