@nebulacomponents/citable 1.18.2 → 1.20.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 (298) hide show
  1. package/CHANGELOG.md +64 -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 +19 -13
  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/browser-evidence-plan.schema.json +186 -3
  9. package/dist/universal/.agents/skills/citable/schemas/browser-network-events.schema.json +142 -0
  10. package/dist/universal/.agents/skills/citable/schemas/browser-runtime-events.schema.json +112 -0
  11. package/dist/universal/.agents/skills/citable/schemas/browser-state-observations.schema.json +97 -0
  12. package/dist/universal/.agents/skills/citable/schemas/collection-result.schema.json +35 -0
  13. package/dist/universal/.agents/skills/citable/schemas/config.schema.json +2 -0
  14. package/dist/universal/.agents/skills/citable/schemas/cro-report.schema.json +8 -1
  15. package/dist/universal/.agents/skills/citable/schemas/finding.schema.json +105 -2
  16. package/dist/universal/.agents/skills/citable/schemas/remediation-verification.schema.json +12 -1
  17. package/dist/universal/.agents/skills/citable/schemas/run.schema.json +15 -2
  18. package/dist/universal/.agents/skills/citable/schemas/search-report.schema.json +8 -1
  19. package/dist/universal/.agents/skills/citable/schemas/summary.schema.json +41 -0
  20. package/dist/universal/.claude/agents/citable/manifest.json +2 -2
  21. package/dist/universal/.claude/skills/citable/SKILL.md +11 -2
  22. package/dist/universal/.claude/skills/citable/VERSION +1 -1
  23. package/dist/universal/.claude/skills/citable/manifest.json +19 -13
  24. package/dist/universal/.claude/skills/citable/schemas/action-plan.schema.json +38 -1
  25. package/dist/universal/.claude/skills/citable/schemas/audit-coverage.schema.json +118 -0
  26. package/dist/universal/.claude/skills/citable/schemas/browser-evidence-plan.schema.json +186 -3
  27. package/dist/universal/.claude/skills/citable/schemas/browser-network-events.schema.json +142 -0
  28. package/dist/universal/.claude/skills/citable/schemas/browser-runtime-events.schema.json +112 -0
  29. package/dist/universal/.claude/skills/citable/schemas/browser-state-observations.schema.json +97 -0
  30. package/dist/universal/.claude/skills/citable/schemas/collection-result.schema.json +35 -0
  31. package/dist/universal/.claude/skills/citable/schemas/config.schema.json +2 -0
  32. package/dist/universal/.claude/skills/citable/schemas/cro-report.schema.json +8 -1
  33. package/dist/universal/.claude/skills/citable/schemas/finding.schema.json +105 -2
  34. package/dist/universal/.claude/skills/citable/schemas/remediation-verification.schema.json +12 -1
  35. package/dist/universal/.claude/skills/citable/schemas/run.schema.json +15 -2
  36. package/dist/universal/.claude/skills/citable/schemas/search-report.schema.json +8 -1
  37. package/dist/universal/.claude/skills/citable/schemas/summary.schema.json +41 -0
  38. package/dist/universal/.cursor/skills/citable/SKILL.md +11 -2
  39. package/dist/universal/.cursor/skills/citable/VERSION +1 -1
  40. package/dist/universal/.cursor/skills/citable/manifest.json +19 -13
  41. package/dist/universal/.cursor/skills/citable/schemas/action-plan.schema.json +38 -1
  42. package/dist/universal/.cursor/skills/citable/schemas/audit-coverage.schema.json +118 -0
  43. package/dist/universal/.cursor/skills/citable/schemas/browser-evidence-plan.schema.json +186 -3
  44. package/dist/universal/.cursor/skills/citable/schemas/browser-network-events.schema.json +142 -0
  45. package/dist/universal/.cursor/skills/citable/schemas/browser-runtime-events.schema.json +112 -0
  46. package/dist/universal/.cursor/skills/citable/schemas/browser-state-observations.schema.json +97 -0
  47. package/dist/universal/.cursor/skills/citable/schemas/collection-result.schema.json +35 -0
  48. package/dist/universal/.cursor/skills/citable/schemas/config.schema.json +2 -0
  49. package/dist/universal/.cursor/skills/citable/schemas/cro-report.schema.json +8 -1
  50. package/dist/universal/.cursor/skills/citable/schemas/finding.schema.json +105 -2
  51. package/dist/universal/.cursor/skills/citable/schemas/remediation-verification.schema.json +12 -1
  52. package/dist/universal/.cursor/skills/citable/schemas/run.schema.json +15 -2
  53. package/dist/universal/.cursor/skills/citable/schemas/search-report.schema.json +8 -1
  54. package/dist/universal/.cursor/skills/citable/schemas/summary.schema.json +41 -0
  55. package/dist/universal/.gemini/skills/citable/SKILL.md +11 -2
  56. package/dist/universal/.gemini/skills/citable/VERSION +1 -1
  57. package/dist/universal/.gemini/skills/citable/manifest.json +19 -13
  58. package/dist/universal/.gemini/skills/citable/schemas/action-plan.schema.json +38 -1
  59. package/dist/universal/.gemini/skills/citable/schemas/audit-coverage.schema.json +118 -0
  60. package/dist/universal/.gemini/skills/citable/schemas/browser-evidence-plan.schema.json +186 -3
  61. package/dist/universal/.gemini/skills/citable/schemas/browser-network-events.schema.json +142 -0
  62. package/dist/universal/.gemini/skills/citable/schemas/browser-runtime-events.schema.json +112 -0
  63. package/dist/universal/.gemini/skills/citable/schemas/browser-state-observations.schema.json +97 -0
  64. package/dist/universal/.gemini/skills/citable/schemas/collection-result.schema.json +35 -0
  65. package/dist/universal/.gemini/skills/citable/schemas/config.schema.json +2 -0
  66. package/dist/universal/.gemini/skills/citable/schemas/cro-report.schema.json +8 -1
  67. package/dist/universal/.gemini/skills/citable/schemas/finding.schema.json +105 -2
  68. package/dist/universal/.gemini/skills/citable/schemas/remediation-verification.schema.json +12 -1
  69. package/dist/universal/.gemini/skills/citable/schemas/run.schema.json +15 -2
  70. package/dist/universal/.gemini/skills/citable/schemas/search-report.schema.json +8 -1
  71. package/dist/universal/.gemini/skills/citable/schemas/summary.schema.json +41 -0
  72. package/dist/universal/.github/skills/citable/SKILL.md +11 -2
  73. package/dist/universal/.github/skills/citable/VERSION +1 -1
  74. package/dist/universal/.github/skills/citable/manifest.json +19 -13
  75. package/dist/universal/.github/skills/citable/schemas/action-plan.schema.json +38 -1
  76. package/dist/universal/.github/skills/citable/schemas/audit-coverage.schema.json +118 -0
  77. package/dist/universal/.github/skills/citable/schemas/browser-evidence-plan.schema.json +186 -3
  78. package/dist/universal/.github/skills/citable/schemas/browser-network-events.schema.json +142 -0
  79. package/dist/universal/.github/skills/citable/schemas/browser-runtime-events.schema.json +112 -0
  80. package/dist/universal/.github/skills/citable/schemas/browser-state-observations.schema.json +97 -0
  81. package/dist/universal/.github/skills/citable/schemas/collection-result.schema.json +35 -0
  82. package/dist/universal/.github/skills/citable/schemas/config.schema.json +2 -0
  83. package/dist/universal/.github/skills/citable/schemas/cro-report.schema.json +8 -1
  84. package/dist/universal/.github/skills/citable/schemas/finding.schema.json +105 -2
  85. package/dist/universal/.github/skills/citable/schemas/remediation-verification.schema.json +12 -1
  86. package/dist/universal/.github/skills/citable/schemas/run.schema.json +15 -2
  87. package/dist/universal/.github/skills/citable/schemas/search-report.schema.json +8 -1
  88. package/dist/universal/.github/skills/citable/schemas/summary.schema.json +41 -0
  89. package/dist/universal/.kiro/skills/citable/SKILL.md +11 -2
  90. package/dist/universal/.kiro/skills/citable/VERSION +1 -1
  91. package/dist/universal/.kiro/skills/citable/manifest.json +19 -13
  92. package/dist/universal/.kiro/skills/citable/schemas/action-plan.schema.json +38 -1
  93. package/dist/universal/.kiro/skills/citable/schemas/audit-coverage.schema.json +118 -0
  94. package/dist/universal/.kiro/skills/citable/schemas/browser-evidence-plan.schema.json +186 -3
  95. package/dist/universal/.kiro/skills/citable/schemas/browser-network-events.schema.json +142 -0
  96. package/dist/universal/.kiro/skills/citable/schemas/browser-runtime-events.schema.json +112 -0
  97. package/dist/universal/.kiro/skills/citable/schemas/browser-state-observations.schema.json +97 -0
  98. package/dist/universal/.kiro/skills/citable/schemas/collection-result.schema.json +35 -0
  99. package/dist/universal/.kiro/skills/citable/schemas/config.schema.json +2 -0
  100. package/dist/universal/.kiro/skills/citable/schemas/cro-report.schema.json +8 -1
  101. package/dist/universal/.kiro/skills/citable/schemas/finding.schema.json +105 -2
  102. package/dist/universal/.kiro/skills/citable/schemas/remediation-verification.schema.json +12 -1
  103. package/dist/universal/.kiro/skills/citable/schemas/run.schema.json +15 -2
  104. package/dist/universal/.kiro/skills/citable/schemas/search-report.schema.json +8 -1
  105. package/dist/universal/.kiro/skills/citable/schemas/summary.schema.json +41 -0
  106. package/dist/universal/.opencode/skills/citable/SKILL.md +11 -2
  107. package/dist/universal/.opencode/skills/citable/VERSION +1 -1
  108. package/dist/universal/.opencode/skills/citable/manifest.json +19 -13
  109. package/dist/universal/.opencode/skills/citable/schemas/action-plan.schema.json +38 -1
  110. package/dist/universal/.opencode/skills/citable/schemas/audit-coverage.schema.json +118 -0
  111. package/dist/universal/.opencode/skills/citable/schemas/browser-evidence-plan.schema.json +186 -3
  112. package/dist/universal/.opencode/skills/citable/schemas/browser-network-events.schema.json +142 -0
  113. package/dist/universal/.opencode/skills/citable/schemas/browser-runtime-events.schema.json +112 -0
  114. package/dist/universal/.opencode/skills/citable/schemas/browser-state-observations.schema.json +97 -0
  115. package/dist/universal/.opencode/skills/citable/schemas/collection-result.schema.json +35 -0
  116. package/dist/universal/.opencode/skills/citable/schemas/config.schema.json +2 -0
  117. package/dist/universal/.opencode/skills/citable/schemas/cro-report.schema.json +8 -1
  118. package/dist/universal/.opencode/skills/citable/schemas/finding.schema.json +105 -2
  119. package/dist/universal/.opencode/skills/citable/schemas/remediation-verification.schema.json +12 -1
  120. package/dist/universal/.opencode/skills/citable/schemas/run.schema.json +15 -2
  121. package/dist/universal/.opencode/skills/citable/schemas/search-report.schema.json +8 -1
  122. package/dist/universal/.opencode/skills/citable/schemas/summary.schema.json +41 -0
  123. package/dist/universal/.pi/agent/skills/citable/SKILL.md +11 -2
  124. package/dist/universal/.pi/agent/skills/citable/VERSION +1 -1
  125. package/dist/universal/.pi/agent/skills/citable/manifest.json +19 -13
  126. package/dist/universal/.pi/agent/skills/citable/schemas/action-plan.schema.json +38 -1
  127. package/dist/universal/.pi/agent/skills/citable/schemas/audit-coverage.schema.json +118 -0
  128. package/dist/universal/.pi/agent/skills/citable/schemas/browser-evidence-plan.schema.json +186 -3
  129. package/dist/universal/.pi/agent/skills/citable/schemas/browser-network-events.schema.json +142 -0
  130. package/dist/universal/.pi/agent/skills/citable/schemas/browser-runtime-events.schema.json +112 -0
  131. package/dist/universal/.pi/agent/skills/citable/schemas/browser-state-observations.schema.json +97 -0
  132. package/dist/universal/.pi/agent/skills/citable/schemas/collection-result.schema.json +35 -0
  133. package/dist/universal/.pi/agent/skills/citable/schemas/config.schema.json +2 -0
  134. package/dist/universal/.pi/agent/skills/citable/schemas/cro-report.schema.json +8 -1
  135. package/dist/universal/.pi/agent/skills/citable/schemas/finding.schema.json +105 -2
  136. package/dist/universal/.pi/agent/skills/citable/schemas/remediation-verification.schema.json +12 -1
  137. package/dist/universal/.pi/agent/skills/citable/schemas/run.schema.json +15 -2
  138. package/dist/universal/.pi/agent/skills/citable/schemas/search-report.schema.json +8 -1
  139. package/dist/universal/.pi/agent/skills/citable/schemas/summary.schema.json +41 -0
  140. package/dist/universal/.qoder/skills/citable/SKILL.md +11 -2
  141. package/dist/universal/.qoder/skills/citable/VERSION +1 -1
  142. package/dist/universal/.qoder/skills/citable/manifest.json +19 -13
  143. package/dist/universal/.qoder/skills/citable/schemas/action-plan.schema.json +38 -1
  144. package/dist/universal/.qoder/skills/citable/schemas/audit-coverage.schema.json +118 -0
  145. package/dist/universal/.qoder/skills/citable/schemas/browser-evidence-plan.schema.json +186 -3
  146. package/dist/universal/.qoder/skills/citable/schemas/browser-network-events.schema.json +142 -0
  147. package/dist/universal/.qoder/skills/citable/schemas/browser-runtime-events.schema.json +112 -0
  148. package/dist/universal/.qoder/skills/citable/schemas/browser-state-observations.schema.json +97 -0
  149. package/dist/universal/.qoder/skills/citable/schemas/collection-result.schema.json +35 -0
  150. package/dist/universal/.qoder/skills/citable/schemas/config.schema.json +2 -0
  151. package/dist/universal/.qoder/skills/citable/schemas/cro-report.schema.json +8 -1
  152. package/dist/universal/.qoder/skills/citable/schemas/finding.schema.json +105 -2
  153. package/dist/universal/.qoder/skills/citable/schemas/remediation-verification.schema.json +12 -1
  154. package/dist/universal/.qoder/skills/citable/schemas/run.schema.json +15 -2
  155. package/dist/universal/.qoder/skills/citable/schemas/search-report.schema.json +8 -1
  156. package/dist/universal/.qoder/skills/citable/schemas/summary.schema.json +41 -0
  157. package/dist/universal/.rovodev/skills/citable/SKILL.md +11 -2
  158. package/dist/universal/.rovodev/skills/citable/VERSION +1 -1
  159. package/dist/universal/.rovodev/skills/citable/manifest.json +19 -13
  160. package/dist/universal/.rovodev/skills/citable/schemas/action-plan.schema.json +38 -1
  161. package/dist/universal/.rovodev/skills/citable/schemas/audit-coverage.schema.json +118 -0
  162. package/dist/universal/.rovodev/skills/citable/schemas/browser-evidence-plan.schema.json +186 -3
  163. package/dist/universal/.rovodev/skills/citable/schemas/browser-network-events.schema.json +142 -0
  164. package/dist/universal/.rovodev/skills/citable/schemas/browser-runtime-events.schema.json +112 -0
  165. package/dist/universal/.rovodev/skills/citable/schemas/browser-state-observations.schema.json +97 -0
  166. package/dist/universal/.rovodev/skills/citable/schemas/collection-result.schema.json +35 -0
  167. package/dist/universal/.rovodev/skills/citable/schemas/config.schema.json +2 -0
  168. package/dist/universal/.rovodev/skills/citable/schemas/cro-report.schema.json +8 -1
  169. package/dist/universal/.rovodev/skills/citable/schemas/finding.schema.json +105 -2
  170. package/dist/universal/.rovodev/skills/citable/schemas/remediation-verification.schema.json +12 -1
  171. package/dist/universal/.rovodev/skills/citable/schemas/run.schema.json +15 -2
  172. package/dist/universal/.rovodev/skills/citable/schemas/search-report.schema.json +8 -1
  173. package/dist/universal/.rovodev/skills/citable/schemas/summary.schema.json +41 -0
  174. package/dist/universal/.trae/skills/citable/SKILL.md +11 -2
  175. package/dist/universal/.trae/skills/citable/VERSION +1 -1
  176. package/dist/universal/.trae/skills/citable/manifest.json +19 -13
  177. package/dist/universal/.trae/skills/citable/schemas/action-plan.schema.json +38 -1
  178. package/dist/universal/.trae/skills/citable/schemas/audit-coverage.schema.json +118 -0
  179. package/dist/universal/.trae/skills/citable/schemas/browser-evidence-plan.schema.json +186 -3
  180. package/dist/universal/.trae/skills/citable/schemas/browser-network-events.schema.json +142 -0
  181. package/dist/universal/.trae/skills/citable/schemas/browser-runtime-events.schema.json +112 -0
  182. package/dist/universal/.trae/skills/citable/schemas/browser-state-observations.schema.json +97 -0
  183. package/dist/universal/.trae/skills/citable/schemas/collection-result.schema.json +35 -0
  184. package/dist/universal/.trae/skills/citable/schemas/config.schema.json +2 -0
  185. package/dist/universal/.trae/skills/citable/schemas/cro-report.schema.json +8 -1
  186. package/dist/universal/.trae/skills/citable/schemas/finding.schema.json +105 -2
  187. package/dist/universal/.trae/skills/citable/schemas/remediation-verification.schema.json +12 -1
  188. package/dist/universal/.trae/skills/citable/schemas/run.schema.json +15 -2
  189. package/dist/universal/.trae/skills/citable/schemas/search-report.schema.json +8 -1
  190. package/dist/universal/.trae/skills/citable/schemas/summary.schema.json +41 -0
  191. package/dist/universal/.trae-cn/skills/citable/SKILL.md +11 -2
  192. package/dist/universal/.trae-cn/skills/citable/VERSION +1 -1
  193. package/dist/universal/.trae-cn/skills/citable/manifest.json +19 -13
  194. package/dist/universal/.trae-cn/skills/citable/schemas/action-plan.schema.json +38 -1
  195. package/dist/universal/.trae-cn/skills/citable/schemas/audit-coverage.schema.json +118 -0
  196. package/dist/universal/.trae-cn/skills/citable/schemas/browser-evidence-plan.schema.json +186 -3
  197. package/dist/universal/.trae-cn/skills/citable/schemas/browser-network-events.schema.json +142 -0
  198. package/dist/universal/.trae-cn/skills/citable/schemas/browser-runtime-events.schema.json +112 -0
  199. package/dist/universal/.trae-cn/skills/citable/schemas/browser-state-observations.schema.json +97 -0
  200. package/dist/universal/.trae-cn/skills/citable/schemas/collection-result.schema.json +35 -0
  201. package/dist/universal/.trae-cn/skills/citable/schemas/config.schema.json +2 -0
  202. package/dist/universal/.trae-cn/skills/citable/schemas/cro-report.schema.json +8 -1
  203. package/dist/universal/.trae-cn/skills/citable/schemas/finding.schema.json +105 -2
  204. package/dist/universal/.trae-cn/skills/citable/schemas/remediation-verification.schema.json +12 -1
  205. package/dist/universal/.trae-cn/skills/citable/schemas/run.schema.json +15 -2
  206. package/dist/universal/.trae-cn/skills/citable/schemas/search-report.schema.json +8 -1
  207. package/dist/universal/.trae-cn/skills/citable/schemas/summary.schema.json +41 -0
  208. package/dist/universal/manifest.json +232 -160
  209. package/package.json +1 -1
  210. package/schemas/action-plan.schema.json +38 -1
  211. package/schemas/audit-coverage.schema.json +118 -0
  212. package/schemas/browser-evidence-plan.schema.json +186 -3
  213. package/schemas/browser-network-events.schema.json +142 -0
  214. package/schemas/browser-runtime-events.schema.json +112 -0
  215. package/schemas/browser-state-observations.schema.json +97 -0
  216. package/schemas/collection-result.schema.json +35 -0
  217. package/schemas/config.schema.json +2 -0
  218. package/schemas/cro-report.schema.json +8 -1
  219. package/schemas/finding.schema.json +105 -2
  220. package/schemas/remediation-verification.schema.json +12 -1
  221. package/schemas/run.schema.json +15 -2
  222. package/schemas/search-report.schema.json +8 -1
  223. package/schemas/summary.schema.json +41 -0
  224. package/skill/SKILL.md +11 -2
  225. package/src/acceptance/reproducibility.js +5 -25
  226. package/src/analysis/croRoadmap.js +3 -3
  227. package/src/analysis/strategicRoadmap.js +3 -3
  228. package/src/artifacts/interchange.js +2 -6
  229. package/src/cli/index.js +15 -3
  230. package/src/commands/actionPlan.js +46 -5
  231. package/src/commands/applyRemediation.js +5 -5
  232. package/src/commands/audit.js +75 -8
  233. package/src/commands/ciWorkflow.js +7 -2
  234. package/src/commands/compareSnapshots.js +155 -47
  235. package/src/commands/connect.js +24 -4
  236. package/src/commands/context.js +41 -2
  237. package/src/commands/croSuite.js +51 -13
  238. package/src/commands/delivery.js +7 -7
  239. package/src/commands/governance.js +9 -10
  240. package/src/commands/implementationKit.js +2 -1
  241. package/src/commands/init.js +8 -1
  242. package/src/commands/previewCro.js +1 -1
  243. package/src/commands/prioritize.js +3 -2
  244. package/src/commands/reviews.js +31 -5
  245. package/src/commands/roadmapCmd.js +7 -13
  246. package/src/commands/sweep.js +15 -2
  247. package/src/commands/verifyRemediation.js +94 -19
  248. package/src/connectors/collectionResult.js +80 -0
  249. package/src/connectors/ga4.js +46 -11
  250. package/src/connectors/gsc.js +41 -6
  251. package/src/connectors/index.js +1 -1
  252. package/src/connectors/webflow.js +140 -10
  253. package/src/connectors/wordpress.js +92 -8
  254. package/src/crawler/fetch.js +220 -24
  255. package/src/crawler/resourceValidity.js +119 -0
  256. package/src/crawler/sitemap.js +435 -16
  257. package/src/crawler/sitemapCollector.js +364 -0
  258. package/src/crawler/urlIdentity.js +97 -0
  259. package/src/detectors/agent.js +11 -0
  260. package/src/detectors/ans.js +16 -1
  261. package/src/detectors/arch.js +6 -0
  262. package/src/detectors/claim.js +9 -0
  263. package/src/detectors/crawl.js +7 -0
  264. package/src/detectors/cro.js +21 -0
  265. package/src/detectors/cwv.js +4 -0
  266. package/src/detectors/entity.js +7 -0
  267. package/src/detectors/evd.js +9 -0
  268. package/src/detectors/framework.js +28 -2
  269. package/src/detectors/geoReco.js +16 -0
  270. package/src/detectors/hreflang.js +3 -0
  271. package/src/detectors/lifeMeas.js +9 -0
  272. package/src/detectors/link.js +6 -1
  273. package/src/detectors/page.js +11 -0
  274. package/src/detectors/schemaData.js +16 -1
  275. package/src/detectors/tech.js +34 -3
  276. package/src/evidence/coverage.js +448 -0
  277. package/src/evidence/determination.js +157 -0
  278. package/src/evidence/downstream.js +110 -0
  279. package/src/evidence/hashes.js +109 -0
  280. package/src/evidence/run.js +68 -8
  281. package/src/extractor/page.js +29 -2
  282. package/src/extractor/site.js +298 -50
  283. package/src/observations/browser/correlation.js +83 -0
  284. package/src/observations/browser/networkCollector.js +413 -0
  285. package/src/observations/browser/runtimeEventCollector.js +337 -0
  286. package/src/observations/browser/sanitizer.js +322 -0
  287. package/src/observations/browser/stateCollector.js +386 -0
  288. package/src/observations/browserJourney.js +131 -3
  289. package/src/reporting/executiveCroReport.js +37 -14
  290. package/src/reporting/executiveExport.js +45 -16
  291. package/src/reporting/executiveSearchReport.js +57 -23
  292. package/src/reporting/report.js +56 -9
  293. package/src/shared/epistemicLanguage.js +86 -0
  294. package/src/shared/evidenceSourceResolver.js +48 -17
  295. package/src/shared/htmlEscape.js +8 -4
  296. package/src/shared/runPackageVerifier.js +99 -8
  297. package/src/shared/verifiedRunLoader.js +129 -0
  298. package/src/sow/generateSow.js +1 -1
@@ -7,6 +7,7 @@ const D = [];
7
7
  /* ---------------- EXT: external corroboration ---------------- */
8
8
 
9
9
  D.push(defineDetector({
10
+ coverage_requirement: 'evaluated_subset',
10
11
  id: 'EXT-001', name: 'Corroboration claimed from owned surface', namespace: 'EXT',
11
12
  description: 'A claim lists "external corroboration" whose source is the organization’s own domain — self-corroboration.',
12
13
  discipline: ['aeo', 'geo'], severity: 'medium', deterministic: true, requires: ['registries'],
@@ -40,6 +41,7 @@ D.push(defineDetector({
40
41
  }));
41
42
 
42
43
  D.push(defineDetector({
44
+ coverage_requirement: 'evaluated_subset',
43
45
  id: 'EXT-002', name: 'Comparative claim lacking independent corroboration', namespace: 'EXT',
44
46
  description: 'A verified comparative claim has no external corroboration recorded at all.',
45
47
  discipline: ['geo'], severity: 'low', deterministic: true, requires: ['registries'],
@@ -62,6 +64,7 @@ D.push(defineDetector({
62
64
  /* ---------------- GEO: generative representation ---------------- */
63
65
 
64
66
  D.push(defineDetector({
67
+ coverage_requirement: 'evaluated_subset',
65
68
  id: 'GEO-001', name: 'Hidden instructions targeting language models', namespace: 'GEO',
66
69
  description: 'Hidden page text or HTML comments contain instruction-like phrasing aimed at AI systems (crawler prompt injection).',
67
70
  discipline: ['geo'], severity: 'critical', deterministic: true, requires: ['site'],
@@ -99,6 +102,7 @@ D.push(defineDetector({
99
102
  }));
100
103
 
101
104
  D.push(defineDetector({
105
+ coverage_requirement: 'evaluated_subset',
102
106
  id: 'GEO-002', name: 'Proprietary concept without stable definition', namespace: 'GEO',
103
107
  description: 'A proprietary-concept entity has no definition recorded and/or no canonical page.',
104
108
  discipline: ['geo', 'aeo'], severity: 'medium', deterministic: true, requires: ['registries'],
@@ -119,6 +123,7 @@ D.push(defineDetector({
119
123
  }));
120
124
 
121
125
  D.push(defineDetector({
126
+ coverage_requirement: 'evaluated_subset',
122
127
  id: 'GEO-003', name: 'Entity absent from its category page', namespace: 'GEO',
123
128
  description: 'A product entity declares a category for which a category page exists, but the page never mentions the entity.',
124
129
  discipline: ['geo'], severity: 'medium', deterministic: true, requires: ['site', 'registries'],
@@ -153,6 +158,7 @@ D.push(defineDetector({
153
158
  }));
154
159
 
155
160
  D.push(defineDetector({
161
+ coverage_requirement: 'evaluated_subset',
156
162
  id: 'GEO-004', name: 'llms.txt treated as authority mechanism', namespace: 'GEO',
157
163
  description: 'llms.txt exists and contains directive/authority language, which no engine honors as an authorization mechanism.',
158
164
  discipline: ['geo'], severity: 'low', deterministic: false, requires: ['site'],
@@ -178,6 +184,7 @@ D.push(defineDetector({
178
184
  }));
179
185
 
180
186
  D.push(defineDetector({
187
+ coverage_requirement: 'evaluated_subset',
181
188
  id: 'GEO-005', name: 'Generative target lacks primary entity mapping', namespace: 'GEO',
182
189
  description: 'A page intended to define, compare, categorize, or recommend entities does not declare its primary entities.',
183
190
  discipline: ['geo', 'aeo'], severity: 'high', deterministic: true, requires: ['site', 'registries'],
@@ -200,6 +207,7 @@ D.push(defineDetector({
200
207
  }));
201
208
 
202
209
  D.push(defineDetector({
210
+ coverage_requirement: 'evaluated_subset',
203
211
  id: 'GEO-006', name: 'Active prompt lacks evaluation brief', namespace: 'GEO',
204
212
  description: 'An active prompt lacks the expected answer components, desired outcome, risk classification, or accountable owner needed for reproducible GEO evaluation.',
205
213
  discipline: ['geo', 'aeo'], severity: 'medium', deterministic: true, requires: ['registries'],
@@ -226,6 +234,7 @@ D.push(defineDetector({
226
234
  }));
227
235
 
228
236
  D.push(defineDetector({
237
+ coverage_requirement: 'evaluated_subset',
229
238
  id: 'GEO-007', name: 'Unfavorable or distorted entity stance in recorded generative answers', namespace: 'GEO',
230
239
  description: 'Recorded generative engine answers express an unfavorable, negative, or critically distorted stance toward a registered entity.',
231
240
  discipline: ['geo', 'aeo'], severity: 'high', deterministic: false, requires: ['registries'],
@@ -326,6 +335,7 @@ D.push(defineDetector({
326
335
  }));
327
336
 
328
337
  D.push(defineDetector({
338
+ coverage_requirement: 'evaluated_subset',
329
339
  id: 'GEO-008', name: 'Generative citation attributes unverified or distorted claim to brand', namespace: 'GEO',
330
340
  description: 'Recorded generative engine answers attribute contradicted, distorted, or unverified factual claims to a registered entity or brand.',
331
341
  discipline: ['geo', 'aeo'], severity: 'high', deterministic: false, requires: ['registries'],
@@ -430,6 +440,7 @@ D.push(defineDetector({
430
440
  }));
431
441
 
432
442
  D.push(defineDetector({
443
+ coverage_requirement: 'evaluated_subset',
433
444
  id: 'GEO-009', name: 'Unstable citation presence across repeated probes', namespace: 'GEO',
434
445
  description: 'Brand citation status exhibits high volatility or flapping (alternating between cited and unmentioned) across repeated probe runs for the same prompt and engine.',
435
446
  discipline: ['geo', 'aeo'], severity: 'medium', deterministic: false, requires: ['registries'],
@@ -508,6 +519,7 @@ D.push(defineDetector({
508
519
  }));
509
520
 
510
521
  D.push(defineDetector({
522
+ coverage_requirement: 'evaluated_subset',
511
523
  id: 'GEO-010', name: 'Brand erasure in multi-competitor category prompt', namespace: 'GEO',
512
524
  description: 'A generative engine observation for a relevant category or comparison prompt cites multiple registered competitors but completely omits the first-party entity or brand.',
513
525
  discipline: ['geo', 'aeo'], severity: 'high', deterministic: false, requires: ['registries'],
@@ -568,6 +580,7 @@ D.push(defineDetector({
568
580
  }));
569
581
 
570
582
  D.push(defineDetector({
583
+ coverage_requirement: 'evaluated_subset',
571
584
  id: 'GEO-011', name: 'RAG chunk fracture: claim separated from citation across oversized section', namespace: 'GEO',
572
585
  description: 'A section under a single heading exceeds 450 words without structural sub-headings or lists, separating claims from qualifying citations and causing retrieval fracture in RAG chunking pipelines.',
573
586
  discipline: ['geo', 'aeo'], severity: 'medium', deterministic: true, requires: ['site'],
@@ -616,6 +629,7 @@ D.push(defineDetector({
616
629
  }));
617
630
 
618
631
  D.push(defineDetector({
632
+ coverage_requirement: 'evaluated_subset',
619
633
  id: 'GEO-012', name: 'Repetitive phrase stuffing in section headings degrading dense retrieval', namespace: 'GEO',
620
634
  description: 'Multiple headings repeat the identical multi-word phrase or entity prefix, degrading dense vector discriminability and triggering keyword stuffing penalties in neural search rankers.',
621
635
  discipline: ['geo', 'seo'], severity: 'low', deterministic: true, requires: ['site'],
@@ -670,6 +684,7 @@ D.push(defineDetector({
670
684
  }));
671
685
 
672
686
  D.push(defineDetector({
687
+ coverage_requirement: 'evaluated_subset',
673
688
  id: 'GEO-013', name: 'AI engine assertion contradicts verified publisher claim registry', namespace: 'GEO',
674
689
  description: 'An external AI search engine or generative model assertion directly contradicts or negates a verified publisher claim registered in claims.yaml.',
675
690
  discipline: ['geo', 'aeo'], severity: 'high', deterministic: true, requires: ['observations', 'registries'],
@@ -745,6 +760,7 @@ const RECO_CHECKS = [
745
760
 
746
761
  for (const [id, label, rx, desc, req] of RECO_CHECKS) {
747
762
  D.push(defineDetector({
763
+ coverage_requirement: 'evaluated_subset',
748
764
  id, name: `Recommendation data missing: ${label}`, namespace: 'RECO',
749
765
  description: desc,
750
766
  discipline: ['geo'], severity: 'medium', deterministic: false, requires: ['site', 'registries'],
@@ -10,6 +10,7 @@ import { defineDetector } from './framework.js';
10
10
  * HREFLANG-001: hreflang link present and valid
11
11
  */
12
12
  export const HREFLANG_001 = defineDetector({
13
+ coverage_requirement: 'evaluated_subset',
13
14
  id: 'HREFLANG-001',
14
15
  name: 'hreflang link valid',
15
16
  namespace: 'HREFLANG',
@@ -79,6 +80,7 @@ export const HREFLANG_001 = defineDetector({
79
80
  * HREFLANG-002: Self-referencing hreflang exists
80
81
  */
81
82
  export const HREFLANG_002 = defineDetector({
83
+ coverage_requirement: 'evaluated_subset',
82
84
  id: 'HREFLANG-002',
83
85
  name: 'hreflang self-reference',
84
86
  namespace: 'HREFLANG',
@@ -121,6 +123,7 @@ export const HREFLANG_002 = defineDetector({
121
123
  * HREFLANG-003: x-default present for international pages
122
124
  */
123
125
  export const HREFLANG_003 = defineDetector({
126
+ coverage_requirement: 'evaluated_subset',
124
127
  id: 'HREFLANG-003',
125
128
  name: 'hreflang x-default',
126
129
  namespace: 'HREFLANG',
@@ -6,6 +6,7 @@ const D = [];
6
6
  /* ---------------- LIFE: lifecycle and ownership ---------------- */
7
7
 
8
8
  D.push(defineDetector({
9
+ coverage_requirement: 'evaluated_subset',
9
10
  id: 'LIFE-001', name: 'Page without content owner', namespace: 'LIFE',
10
11
  description: 'An active page registry entry has no accountable content owner.',
11
12
  discipline: ['seo', 'aeo', 'geo'], severity: 'medium', deterministic: true, requires: ['registries'],
@@ -23,6 +24,7 @@ D.push(defineDetector({
23
24
  }));
24
25
 
25
26
  D.push(defineDetector({
27
+ coverage_requirement: 'evaluated_subset',
26
28
  id: 'LIFE-002', name: 'Claim-bearing page without factual reviewer', namespace: 'LIFE',
27
29
  description: 'A page that publishes registered claims has no factual reviewer.',
28
30
  discipline: ['aeo', 'geo'], severity: 'medium', deterministic: true, requires: ['registries'],
@@ -42,6 +44,7 @@ D.push(defineDetector({
42
44
  }));
43
45
 
44
46
  D.push(defineDetector({
47
+ coverage_requirement: 'evaluated_subset',
45
48
  id: 'LIFE-003', name: 'Review overdue', namespace: 'LIFE',
46
49
  description: 'A page has passed its next review date.',
47
50
  discipline: ['seo', 'aeo', 'geo'], severity: 'medium', deterministic: true, requires: ['registries'],
@@ -61,6 +64,7 @@ D.push(defineDetector({
61
64
  }));
62
65
 
63
66
  D.push(defineDetector({
67
+ coverage_requirement: 'evaluated_subset',
64
68
  id: 'LIFE-004', name: 'Page without lifecycle classification', namespace: 'LIFE',
65
69
  description: 'An active page has no lifecycle class, so no review model can apply.',
66
70
  discipline: ['seo', 'aeo', 'geo'], severity: 'low', deterministic: true, requires: ['registries'],
@@ -80,6 +84,7 @@ D.push(defineDetector({
80
84
  }));
81
85
 
82
86
  D.push(defineDetector({
87
+ coverage_requirement: 'evaluated_subset',
83
88
  id: 'LIFE-005', name: 'Regulatory content without jurisdiction', namespace: 'LIFE',
84
89
  description: 'A page classified regulatory (or carrying legal claims) records no jurisdiction.',
85
90
  discipline: ['aeo', 'geo'], severity: 'medium', deterministic: true, requires: ['registries'],
@@ -100,6 +105,7 @@ D.push(defineDetector({
100
105
  }));
101
106
 
102
107
  D.push(defineDetector({
108
+ coverage_requirement: 'evaluated_subset',
103
109
  id: 'LIFE-006', name: 'Freshness theater (date bumped, content unchanged)', namespace: 'LIFE',
104
110
  description: 'Between snapshots, a page’s dateModified advanced while its content hash stayed identical.',
105
111
  discipline: ['seo', 'aeo'], severity: 'medium', deterministic: true, requires: ['site', 'snapshots'],
@@ -139,6 +145,7 @@ export function extractModified(page) {
139
145
  /* ---------------- MEAS: measurement integrity ---------------- */
140
146
 
141
147
  D.push(defineDetector({
148
+ coverage_requirement: 'evaluated_subset',
142
149
  id: 'MEAS-001', name: 'Prompt observation missing required metadata', namespace: 'MEAS',
143
150
  description: 'A recorded prompt-test observation lacks engine, model/interface, locale, or timestamp context.',
144
151
  discipline: ['geo', 'aeo'], severity: 'medium', deterministic: true, requires: ['promptResults'],
@@ -163,6 +170,7 @@ D.push(defineDetector({
163
170
  }));
164
171
 
165
172
  D.push(defineDetector({
173
+ coverage_requirement: 'evaluated_subset',
166
174
  id: 'MEAS-002', name: 'Single observation treated as stable outcome', namespace: 'MEAS',
167
175
  description: 'A prompt has exactly one recorded observation but its registry accuracy_status asserts a definitive outcome.',
168
176
  discipline: ['geo'], severity: 'medium', deterministic: true, requires: ['registries'],
@@ -186,6 +194,7 @@ D.push(defineDetector({
186
194
  }));
187
195
 
188
196
  D.push(defineDetector({
197
+ coverage_requirement: 'evaluated_subset',
189
198
  id: 'MEAS-003', name: 'Causal experiment conclusion without controls', namespace: 'MEAS',
190
199
  description: 'A concluded experiment asserts a result but records no control group, baseline window, or confounders.',
191
200
  discipline: ['seo', 'geo'], severity: 'medium', deterministic: true, requires: ['registries'],
@@ -3,6 +3,7 @@ import { defineDetector, indexTargets, pageSubject } from './framework.js';
3
3
  const D = [];
4
4
 
5
5
  D.push(defineDetector({
6
+ coverage_requirement: 'evaluated_subset',
6
7
  id: 'LINK-001', name: 'Broken internal link', namespace: 'LINK',
7
8
  description: 'An internal link targets a URL that is missing from the audited output or returns 4xx/5xx.',
8
9
  discipline: ['seo', 'aeo'], severity: 'medium', deterministic: true, requires: ['site'],
@@ -38,6 +39,7 @@ D.push(defineDetector({
38
39
  }));
39
40
 
40
41
  D.push(defineDetector({
42
+ coverage_requirement: 'evaluated_subset',
41
43
  id: 'LINK-002', name: 'Internal link to redirect', namespace: 'LINK',
42
44
  description: 'An internal link targets a URL that redirects instead of the final destination.',
43
45
  discipline: ['seo'], severity: 'low', deterministic: true, requires: ['site'],
@@ -64,6 +66,7 @@ D.push(defineDetector({
64
66
  }));
65
67
 
66
68
  D.push(defineDetector({
69
+ coverage_requirement: 'evaluated_subset',
67
70
  id: 'LINK-003', name: 'Generic anchor text', namespace: 'LINK',
68
71
  description: 'Internal links use non-descriptive anchors ("click here", "read more", "learn more").',
69
72
  discipline: ['seo', 'aeo'], severity: 'low', deterministic: true, requires: ['site'],
@@ -89,6 +92,7 @@ D.push(defineDetector({
89
92
  }));
90
93
 
91
94
  D.push(defineDetector({
95
+ coverage_requirement: 'evaluated_subset',
92
96
  id: 'LINK-004', name: 'Sitewide repeated exact-match anchor', namespace: 'LINK',
93
97
  description: 'The same exact anchor text points at the same URL from a large share of pages — a pattern of mechanical link insertion.',
94
98
  discipline: ['seo'], severity: 'low', deterministic: false, requires: ['site'],
@@ -119,6 +123,7 @@ D.push(defineDetector({
119
123
  }));
120
124
 
121
125
  D.push(defineDetector({
126
+ coverage_requirement: 'evaluated_subset',
122
127
  id: 'LINK-005', name: 'Internal redirect hop chain or circular redirect loop', namespace: 'LINK',
123
128
  description: 'An internal link targets a URL that initiates a multi-hop redirect chain (>=2 hops) or a circular redirect loop, dissipating link equity and wasting crawler budget.',
124
129
  discipline: ['seo', 'tech'], severity: 'medium', deterministic: true, requires: ['site'],
@@ -186,6 +191,7 @@ D.push(defineDetector({
186
191
  }));
187
192
 
188
193
  D.push(defineDetector({
194
+ coverage_requirement: 'evaluated_subset',
189
195
  id: 'LINK-006', name: 'Excessive naked URL or uninformative internal anchor text ratio', namespace: 'LINK',
190
196
  description: 'Over 25% of internal links on a page use naked URLs or uninformative anchors, diluting semantic topic graph signals for search engines and generative models.',
191
197
  discipline: ['seo', 'aeo'], severity: 'low', deterministic: true, requires: ['site'],
@@ -229,4 +235,3 @@ D.push(defineDetector({
229
235
  }));
230
236
 
231
237
  export default D;
232
-
@@ -4,6 +4,7 @@ import { parse } from 'node-html-parser';
4
4
  const D = [];
5
5
 
6
6
  D.push(defineDetector({
7
+ coverage_requirement: 'page_resource',
7
8
  id: 'PAGE-001', name: 'Missing title element', namespace: 'PAGE',
8
9
  description: 'Index-target page has no <title>.',
9
10
  discipline: ['seo', 'aeo'], severity: 'high', deterministic: true, requires: ['site'],
@@ -19,6 +20,7 @@ D.push(defineDetector({
19
20
  }));
20
21
 
21
22
  D.push(defineDetector({
23
+ coverage_requirement: 'page_resource',
22
24
  id: 'PAGE-002', name: 'Duplicate title across pages', namespace: 'PAGE',
23
25
  description: 'Two or more index-target pages share an identical title.',
24
26
  discipline: ['seo'], severity: 'medium', deterministic: true, requires: ['site'],
@@ -42,6 +44,7 @@ D.push(defineDetector({
42
44
  }));
43
45
 
44
46
  D.push(defineDetector({
47
+ coverage_requirement: 'page_resource',
45
48
  id: 'PAGE-003', name: 'Missing meta description', namespace: 'PAGE',
46
49
  description: 'Index-target page lacks a meta description (search-result copy).',
47
50
  discipline: ['seo'], severity: 'low', deterministic: true, requires: ['site'],
@@ -57,6 +60,7 @@ D.push(defineDetector({
57
60
  }));
58
61
 
59
62
  D.push(defineDetector({
63
+ coverage_requirement: 'page_resource',
60
64
  id: 'PAGE-004', name: 'Duplicate meta description', namespace: 'PAGE',
61
65
  description: 'Multiple pages share an identical meta description.',
62
66
  discipline: ['seo'], severity: 'low', deterministic: true, requires: ['site'],
@@ -80,6 +84,7 @@ D.push(defineDetector({
80
84
  }));
81
85
 
82
86
  D.push(defineDetector({
87
+ coverage_requirement: 'page_resource',
83
88
  id: 'PAGE-005', name: 'Missing or multiple H1', namespace: 'PAGE',
84
89
  description: 'Page does not have exactly one primary heading.',
85
90
  discipline: ['seo', 'aeo'], severity: 'medium', deterministic: true, requires: ['site'],
@@ -98,6 +103,7 @@ D.push(defineDetector({
98
103
  }));
99
104
 
100
105
  D.push(defineDetector({
106
+ coverage_requirement: 'page_resource',
101
107
  id: 'PAGE-006', name: 'Heading hierarchy skip', namespace: 'PAGE',
102
108
  description: 'Heading levels skip (e.g., H1 → H3), indicating headings used for visual size rather than document structure.',
103
109
  discipline: ['seo', 'aeo'], severity: 'low', deterministic: true, requires: ['site'],
@@ -127,6 +133,7 @@ D.push(defineDetector({
127
133
  }));
128
134
 
129
135
  D.push(defineDetector({
136
+ coverage_requirement: 'page_resource',
130
137
  id: 'PAGE-007', name: 'Image missing alt text', namespace: 'PAGE',
131
138
  description: 'Content images lack alt attributes.',
132
139
  discipline: ['seo'], severity: 'low', deterministic: true, requires: ['site'],
@@ -147,6 +154,7 @@ D.push(defineDetector({
147
154
  }));
148
155
 
149
156
  D.push(defineDetector({
157
+ coverage_requirement: 'page_resource',
150
158
  id: 'PAGE-008', name: 'Thin index-target content', namespace: 'PAGE',
151
159
  description: 'An index-target page has very little primary text.',
152
160
  discipline: ['seo', 'aeo'], severity: 'medium', deterministic: false, requires: ['site'],
@@ -169,6 +177,7 @@ D.push(defineDetector({
169
177
  }));
170
178
 
171
179
  D.push(defineDetector({
180
+ coverage_requirement: 'page_resource',
172
181
  id: 'PAGE-009', name: 'Keyword stuffing', namespace: 'PAGE',
173
182
  description: 'A single non-trivial term dominates the page text at a frequency inconsistent with natural prose.',
174
183
  discipline: ['seo'], severity: 'medium', deterministic: false, requires: ['site'],
@@ -201,6 +210,7 @@ D.push(defineDetector({
201
210
  }));
202
211
 
203
212
  D.push(defineDetector({
213
+ coverage_requirement: 'page_resource',
204
214
  id: 'PAGE-010', name: 'High boilerplate-to-content ratio in extracted answer passages', namespace: 'PAGE',
205
215
  description: 'An index-target page has a high ratio of boilerplate (navigation, header, footer, chrome) relative to substantive primary content, diluting extracted answer passages.',
206
216
  discipline: ['aeo', 'seo'], severity: 'medium', deterministic: true, requires: ['site'],
@@ -235,6 +245,7 @@ D.push(defineDetector({
235
245
  }));
236
246
 
237
247
  D.push(defineDetector({
248
+ coverage_requirement: 'page_resource',
238
249
  id: 'PAGE-011', name: 'Critical entity claims rendered inside transient/collapsible UI containers without fallback', namespace: 'PAGE',
239
250
  description: 'Registered claim or critical entity statement is rendered exclusively inside a collapsible or transient UI container (<details>, accordion, hidden tab) without an uncollapsed fallback or crawlable representation.',
240
251
  discipline: ['aeo', 'geo'], severity: 'medium', deterministic: true, requires: ['site', 'registries'],
@@ -4,6 +4,7 @@ import { isPastDate } from '../shared/io.js';
4
4
  const D = [];
5
5
 
6
6
  D.push(defineDetector({
7
+ coverage_requirement: 'evaluated_subset',
7
8
  id: 'SCHEMA-001', name: 'JSON-LD parse failure', namespace: 'SCHEMA',
8
9
  description: 'A JSON-LD script block does not parse as JSON.',
9
10
  discipline: ['seo', 'aeo', 'geo'], severity: 'high', deterministic: true, requires: ['site'],
@@ -29,6 +30,7 @@ D.push(defineDetector({
29
30
  }));
30
31
 
31
32
  D.push(defineDetector({
33
+ coverage_requirement: 'evaluated_subset',
32
34
  id: 'SCHEMA-002', name: 'Schema headline/name mismatch with visible content', namespace: 'SCHEMA',
33
35
  description: 'Article/WebPage headline in JSON-LD does not match the visible title or H1.',
34
36
  discipline: ['seo', 'aeo'], severity: 'medium', deterministic: true, requires: ['site'],
@@ -61,6 +63,7 @@ D.push(defineDetector({
61
63
  }));
62
64
 
63
65
  D.push(defineDetector({
66
+ coverage_requirement: 'evaluated_subset',
64
67
  id: 'SCHEMA-003', name: 'Schema URL conflicts with canonical', namespace: 'SCHEMA',
65
68
  description: 'JSON-LD url/mainEntityOfPage disagrees with the page canonical.',
66
69
  discipline: ['seo'], severity: 'medium', deterministic: true, requires: ['site'],
@@ -91,6 +94,7 @@ D.push(defineDetector({
91
94
  }));
92
95
 
93
96
  D.push(defineDetector({
97
+ coverage_requirement: 'evaluated_subset',
94
98
  id: 'SCHEMA-004', name: 'Inaccurate schema dates', namespace: 'SCHEMA',
95
99
  description: 'datePublished is in the future, or dateModified precedes datePublished.',
96
100
  discipline: ['seo', 'aeo'], severity: 'medium', deterministic: true, requires: ['site'],
@@ -128,6 +132,7 @@ D.push(defineDetector({
128
132
  }));
129
133
 
130
134
  D.push(defineDetector({
135
+ coverage_requirement: 'evaluated_subset',
131
136
  id: 'SCHEMA-005', name: 'Rating/review markup without visible reviews', namespace: 'SCHEMA',
132
137
  description: 'aggregateRating or review markup exists but the visible page contains no review content.',
133
138
  discipline: ['seo'], severity: 'critical', deterministic: true, requires: ['site'],
@@ -157,6 +162,7 @@ D.push(defineDetector({
157
162
  }));
158
163
 
159
164
  D.push(defineDetector({
165
+ coverage_requirement: 'evaluated_subset',
160
166
  id: 'SCHEMA-006', name: 'Stale offer price validity', namespace: 'SCHEMA',
161
167
  description: 'Offer markup carries a priceValidUntil in the past.',
162
168
  discipline: ['seo', 'geo'], severity: 'medium', deterministic: true, requires: ['site'],
@@ -187,6 +193,7 @@ D.push(defineDetector({
187
193
  }));
188
194
 
189
195
  D.push(defineDetector({
196
+ coverage_requirement: 'evaluated_subset',
190
197
  id: 'SCHEMA-007', name: 'FAQPage markup without matching visible questions', namespace: 'SCHEMA',
191
198
  description: 'FAQPage JSON-LD questions do not appear in the visible page text.',
192
199
  discipline: ['seo', 'aeo'], severity: 'high', deterministic: true, requires: ['site'],
@@ -217,6 +224,7 @@ D.push(defineDetector({
217
224
  }));
218
225
 
219
226
  D.push(defineDetector({
227
+ coverage_requirement: 'evaluated_subset',
220
228
  id: 'SCHEMA-008', name: 'Contradictory Organization graphs', namespace: 'SCHEMA',
221
229
  description: 'Multiple Organization blocks exist with the same @id but different names, or different @id values with the same name (split identity).',
222
230
  discipline: ['geo', 'seo'], severity: 'high', deterministic: true, requires: ['site'],
@@ -247,6 +255,7 @@ D.push(defineDetector({
247
255
  }));
248
256
 
249
257
  D.push(defineDetector({
258
+ coverage_requirement: 'evaluated_subset',
250
259
  id: 'SCHEMA-009', name: 'Structured data entity facts unsupported by visible content', namespace: 'SCHEMA',
251
260
  description: 'Material entity facts in JSON-LD (such as contact phone, address, pricing, or founding year) are absent from visible page content.',
252
261
  discipline: ['seo', 'aeo', 'geo'], severity: 'high', deterministic: true, requires: ['site'],
@@ -330,6 +339,7 @@ D.push(defineDetector({
330
339
  }));
331
340
 
332
341
  D.push(defineDetector({
342
+ coverage_requirement: 'evaluated_subset',
333
343
  id: 'SCHEMA-010', name: 'Dangling or circular @id reference in entity graph', namespace: 'SCHEMA',
334
344
  description: 'A JSON-LD node references an @id URI that is not defined on the site or creates a circular self-reference.',
335
345
  discipline: ['geo', 'seo'], severity: 'high', deterministic: true, requires: ['site'],
@@ -417,6 +427,7 @@ D.push(defineDetector({
417
427
  }));
418
428
 
419
429
  D.push(defineDetector({
430
+ coverage_requirement: 'evaluated_subset',
420
431
  id: 'SCHEMA-011', name: 'BreadcrumbList schema broken or unanchored', namespace: 'SCHEMA',
421
432
  description: 'BreadcrumbList structured data has invalid sequential positions, missing or empty item URLs/names, or broken hierarchical continuity.',
422
433
  discipline: ['seo', 'aeo'], severity: 'medium', deterministic: true, requires: ['site'],
@@ -503,6 +514,7 @@ D.push(defineDetector({
503
514
  }));
504
515
 
505
516
  D.push(defineDetector({
517
+ coverage_requirement: 'evaluated_subset',
506
518
  id: 'SCHEMA-012', name: 'Temporal contradiction between schema dates, visible text, and HTTP headers', namespace: 'SCHEMA',
507
519
  description: 'Structured data dates contradict visible page text timestamps or HTTP Last-Modified headers, undermining search engine freshness consensus.',
508
520
  discipline: ['seo', 'aeo', 'geo'], severity: 'medium', deterministic: true, requires: ['site'],
@@ -592,6 +604,7 @@ D.push(defineDetector({
592
604
  }));
593
605
 
594
606
  D.push(defineDetector({
607
+ coverage_requirement: 'evaluated_subset',
595
608
  id: 'SCHEMA-013', name: 'VideoObject schema missing critical SERP playback prerequisites', namespace: 'SCHEMA',
596
609
  description: 'A VideoObject JSON-LD block is missing required attributes for Google SERP rich video display (name, description, uploadDate, thumbnailUrl, contentUrl or embedUrl).',
597
610
  discipline: ['seo', 'aeo'], severity: 'medium', deterministic: true, requires: ['site'],
@@ -635,6 +648,7 @@ D.push(defineDetector({
635
648
  }));
636
649
 
637
650
  D.push(defineDetector({
651
+ coverage_requirement: 'evaluated_subset',
638
652
  id: 'SCHEMA-014', name: 'Organization or LocalBusiness schema missing authoritative identity attributes', namespace: 'SCHEMA',
639
653
  description: 'An Organization or LocalBusiness JSON-LD block lacks essential identity signals for Google Knowledge Graph or SERP inclusion (name, url, logo, or contactPoint/address).',
640
654
  discipline: ['seo', 'aeo', 'geo'], severity: 'low', deterministic: true, requires: ['site'],
@@ -679,6 +693,7 @@ D.push(defineDetector({
679
693
  }));
680
694
 
681
695
  D.push(defineDetector({
696
+ coverage_requirement: 'evaluated_subset',
682
697
  id: 'SCHEMA-015', name: 'Circular or self-referential JSON-LD @id node reference', namespace: 'SCHEMA',
683
698
  description: 'A JSON-LD structured data graph contains an @id node that points to itself or forms a direct circular reference cycle, breaking search engine graph crawlers and parsers.',
684
699
  discipline: ['seo', 'aeo'], severity: 'high', deterministic: true, requires: ['site'],
@@ -728,6 +743,7 @@ D.push(defineDetector({
728
743
  }));
729
744
 
730
745
  D.push(defineDetector({
746
+ coverage_requirement: 'evaluated_subset',
731
747
  id: 'SCHEMA-016', name: 'Author Person entity lacks external disambiguation URL or sameAs', namespace: 'SCHEMA',
732
748
  description: 'An Article, BlogPosting, NewsArticle, or Review defines an author Person entity without an external profile URL or sameAs link, preventing search engine Knowledge Graph author disambiguation and weakening E-E-A-T trust signals.',
733
749
  discipline: ['seo', 'aeo', 'geo'], severity: 'medium', deterministic: true, requires: ['site'],
@@ -775,4 +791,3 @@ D.push(defineDetector({
775
791
 
776
792
  export default D;
777
793
 
778
-