@nebulacomponents/citable 1.12.0 → 1.13.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 (397) hide show
  1. package/CHANGELOG.md +140 -0
  2. package/README.md +23 -1
  3. package/dist/universal/.agents/skills/citable/SKILL.md +12 -1
  4. package/dist/universal/.agents/skills/citable/VERSION +1 -1
  5. package/dist/universal/.agents/skills/citable/commands/README.md +2 -1
  6. package/dist/universal/.agents/skills/citable/commands/artifact-interchange.md +28 -0
  7. package/dist/universal/.agents/skills/citable/commands/field-validation.md +71 -0
  8. package/dist/universal/.agents/skills/citable/commands/observe-and-act.md +5 -0
  9. package/dist/universal/.agents/skills/citable/manifest.json +30 -10
  10. package/dist/universal/.agents/skills/citable/references/aeo-geo-validation.md +1 -1
  11. package/dist/universal/.agents/skills/citable/references/capability-boundaries.md +1 -0
  12. package/dist/universal/.agents/skills/citable/schemas/acceptance-corpus.schema.json +168 -0
  13. package/dist/universal/.agents/skills/citable/schemas/acceptance-run-context.schema.json +17 -0
  14. package/dist/universal/.agents/skills/citable/schemas/acceptance-run-receipt.schema.json +88 -0
  15. package/dist/universal/.agents/skills/citable/schemas/artifact-interchange.schema.json +58 -0
  16. package/dist/universal/.agents/skills/citable/schemas/assumption.schema.json +119 -0
  17. package/dist/universal/.agents/skills/citable/schemas/browser-evidence-plan.schema.json +76 -0
  18. package/dist/universal/.agents/skills/citable/schemas/corpus-publication-receipt.schema.json +24 -0
  19. package/dist/universal/.agents/skills/citable/schemas/customer-outcome.schema.json +119 -0
  20. package/dist/universal/.agents/skills/citable/schemas/decision.schema.json +154 -0
  21. package/dist/universal/.agents/skills/citable/schemas/deployment-receipt.schema.json +51 -0
  22. package/dist/universal/.agents/skills/citable/schemas/field-validation-metrics.schema.json +15 -0
  23. package/dist/universal/.agents/skills/citable/schemas/initiative.schema.json +185 -0
  24. package/dist/universal/.agents/skills/citable/schemas/kpi.schema.json +108 -0
  25. package/dist/universal/.agents/skills/citable/schemas/observation.schema.json +1 -1
  26. package/dist/universal/.agents/skills/citable/schemas/release-manifest.schema.json +74 -0
  27. package/dist/universal/.agents/skills/citable/schemas/release-state.schema.json +40 -0
  28. package/dist/universal/.agents/skills/citable/schemas/risk.schema.json +172 -0
  29. package/dist/universal/.agents/skills/citable/schemas/scenario.schema.json +165 -0
  30. package/dist/universal/.agents/skills/citable/schemas/variance.schema.json +112 -0
  31. package/dist/universal/.claude/skills/citable/SKILL.md +12 -1
  32. package/dist/universal/.claude/skills/citable/VERSION +1 -1
  33. package/dist/universal/.claude/skills/citable/commands/README.md +2 -1
  34. package/dist/universal/.claude/skills/citable/commands/artifact-interchange.md +28 -0
  35. package/dist/universal/.claude/skills/citable/commands/field-validation.md +71 -0
  36. package/dist/universal/.claude/skills/citable/commands/observe-and-act.md +5 -0
  37. package/dist/universal/.claude/skills/citable/manifest.json +30 -10
  38. package/dist/universal/.claude/skills/citable/references/aeo-geo-validation.md +1 -1
  39. package/dist/universal/.claude/skills/citable/references/capability-boundaries.md +1 -0
  40. package/dist/universal/.claude/skills/citable/schemas/acceptance-corpus.schema.json +168 -0
  41. package/dist/universal/.claude/skills/citable/schemas/acceptance-run-context.schema.json +17 -0
  42. package/dist/universal/.claude/skills/citable/schemas/acceptance-run-receipt.schema.json +88 -0
  43. package/dist/universal/.claude/skills/citable/schemas/artifact-interchange.schema.json +58 -0
  44. package/dist/universal/.claude/skills/citable/schemas/assumption.schema.json +119 -0
  45. package/dist/universal/.claude/skills/citable/schemas/browser-evidence-plan.schema.json +76 -0
  46. package/dist/universal/.claude/skills/citable/schemas/corpus-publication-receipt.schema.json +24 -0
  47. package/dist/universal/.claude/skills/citable/schemas/customer-outcome.schema.json +119 -0
  48. package/dist/universal/.claude/skills/citable/schemas/decision.schema.json +154 -0
  49. package/dist/universal/.claude/skills/citable/schemas/deployment-receipt.schema.json +51 -0
  50. package/dist/universal/.claude/skills/citable/schemas/field-validation-metrics.schema.json +15 -0
  51. package/dist/universal/.claude/skills/citable/schemas/initiative.schema.json +185 -0
  52. package/dist/universal/.claude/skills/citable/schemas/kpi.schema.json +108 -0
  53. package/dist/universal/.claude/skills/citable/schemas/observation.schema.json +1 -1
  54. package/dist/universal/.claude/skills/citable/schemas/release-manifest.schema.json +74 -0
  55. package/dist/universal/.claude/skills/citable/schemas/release-state.schema.json +40 -0
  56. package/dist/universal/.claude/skills/citable/schemas/risk.schema.json +172 -0
  57. package/dist/universal/.claude/skills/citable/schemas/scenario.schema.json +165 -0
  58. package/dist/universal/.claude/skills/citable/schemas/variance.schema.json +112 -0
  59. package/dist/universal/.cursor/skills/citable/SKILL.md +12 -1
  60. package/dist/universal/.cursor/skills/citable/VERSION +1 -1
  61. package/dist/universal/.cursor/skills/citable/commands/README.md +2 -1
  62. package/dist/universal/.cursor/skills/citable/commands/artifact-interchange.md +28 -0
  63. package/dist/universal/.cursor/skills/citable/commands/field-validation.md +71 -0
  64. package/dist/universal/.cursor/skills/citable/commands/observe-and-act.md +5 -0
  65. package/dist/universal/.cursor/skills/citable/manifest.json +30 -10
  66. package/dist/universal/.cursor/skills/citable/references/aeo-geo-validation.md +1 -1
  67. package/dist/universal/.cursor/skills/citable/references/capability-boundaries.md +1 -0
  68. package/dist/universal/.cursor/skills/citable/schemas/acceptance-corpus.schema.json +168 -0
  69. package/dist/universal/.cursor/skills/citable/schemas/acceptance-run-context.schema.json +17 -0
  70. package/dist/universal/.cursor/skills/citable/schemas/acceptance-run-receipt.schema.json +88 -0
  71. package/dist/universal/.cursor/skills/citable/schemas/artifact-interchange.schema.json +58 -0
  72. package/dist/universal/.cursor/skills/citable/schemas/assumption.schema.json +119 -0
  73. package/dist/universal/.cursor/skills/citable/schemas/browser-evidence-plan.schema.json +76 -0
  74. package/dist/universal/.cursor/skills/citable/schemas/corpus-publication-receipt.schema.json +24 -0
  75. package/dist/universal/.cursor/skills/citable/schemas/customer-outcome.schema.json +119 -0
  76. package/dist/universal/.cursor/skills/citable/schemas/decision.schema.json +154 -0
  77. package/dist/universal/.cursor/skills/citable/schemas/deployment-receipt.schema.json +51 -0
  78. package/dist/universal/.cursor/skills/citable/schemas/field-validation-metrics.schema.json +15 -0
  79. package/dist/universal/.cursor/skills/citable/schemas/initiative.schema.json +185 -0
  80. package/dist/universal/.cursor/skills/citable/schemas/kpi.schema.json +108 -0
  81. package/dist/universal/.cursor/skills/citable/schemas/observation.schema.json +1 -1
  82. package/dist/universal/.cursor/skills/citable/schemas/release-manifest.schema.json +74 -0
  83. package/dist/universal/.cursor/skills/citable/schemas/release-state.schema.json +40 -0
  84. package/dist/universal/.cursor/skills/citable/schemas/risk.schema.json +172 -0
  85. package/dist/universal/.cursor/skills/citable/schemas/scenario.schema.json +165 -0
  86. package/dist/universal/.cursor/skills/citable/schemas/variance.schema.json +112 -0
  87. package/dist/universal/.gemini/skills/citable/SKILL.md +12 -1
  88. package/dist/universal/.gemini/skills/citable/VERSION +1 -1
  89. package/dist/universal/.gemini/skills/citable/commands/README.md +2 -1
  90. package/dist/universal/.gemini/skills/citable/commands/artifact-interchange.md +28 -0
  91. package/dist/universal/.gemini/skills/citable/commands/field-validation.md +71 -0
  92. package/dist/universal/.gemini/skills/citable/commands/observe-and-act.md +5 -0
  93. package/dist/universal/.gemini/skills/citable/manifest.json +30 -10
  94. package/dist/universal/.gemini/skills/citable/references/aeo-geo-validation.md +1 -1
  95. package/dist/universal/.gemini/skills/citable/references/capability-boundaries.md +1 -0
  96. package/dist/universal/.gemini/skills/citable/schemas/acceptance-corpus.schema.json +168 -0
  97. package/dist/universal/.gemini/skills/citable/schemas/acceptance-run-context.schema.json +17 -0
  98. package/dist/universal/.gemini/skills/citable/schemas/acceptance-run-receipt.schema.json +88 -0
  99. package/dist/universal/.gemini/skills/citable/schemas/artifact-interchange.schema.json +58 -0
  100. package/dist/universal/.gemini/skills/citable/schemas/assumption.schema.json +119 -0
  101. package/dist/universal/.gemini/skills/citable/schemas/browser-evidence-plan.schema.json +76 -0
  102. package/dist/universal/.gemini/skills/citable/schemas/corpus-publication-receipt.schema.json +24 -0
  103. package/dist/universal/.gemini/skills/citable/schemas/customer-outcome.schema.json +119 -0
  104. package/dist/universal/.gemini/skills/citable/schemas/decision.schema.json +154 -0
  105. package/dist/universal/.gemini/skills/citable/schemas/deployment-receipt.schema.json +51 -0
  106. package/dist/universal/.gemini/skills/citable/schemas/field-validation-metrics.schema.json +15 -0
  107. package/dist/universal/.gemini/skills/citable/schemas/initiative.schema.json +185 -0
  108. package/dist/universal/.gemini/skills/citable/schemas/kpi.schema.json +108 -0
  109. package/dist/universal/.gemini/skills/citable/schemas/observation.schema.json +1 -1
  110. package/dist/universal/.gemini/skills/citable/schemas/release-manifest.schema.json +74 -0
  111. package/dist/universal/.gemini/skills/citable/schemas/release-state.schema.json +40 -0
  112. package/dist/universal/.gemini/skills/citable/schemas/risk.schema.json +172 -0
  113. package/dist/universal/.gemini/skills/citable/schemas/scenario.schema.json +165 -0
  114. package/dist/universal/.gemini/skills/citable/schemas/variance.schema.json +112 -0
  115. package/dist/universal/.github/skills/citable/SKILL.md +12 -1
  116. package/dist/universal/.github/skills/citable/VERSION +1 -1
  117. package/dist/universal/.github/skills/citable/commands/README.md +2 -1
  118. package/dist/universal/.github/skills/citable/commands/artifact-interchange.md +28 -0
  119. package/dist/universal/.github/skills/citable/commands/field-validation.md +71 -0
  120. package/dist/universal/.github/skills/citable/commands/observe-and-act.md +5 -0
  121. package/dist/universal/.github/skills/citable/manifest.json +30 -10
  122. package/dist/universal/.github/skills/citable/references/aeo-geo-validation.md +1 -1
  123. package/dist/universal/.github/skills/citable/references/capability-boundaries.md +1 -0
  124. package/dist/universal/.github/skills/citable/schemas/acceptance-corpus.schema.json +168 -0
  125. package/dist/universal/.github/skills/citable/schemas/acceptance-run-context.schema.json +17 -0
  126. package/dist/universal/.github/skills/citable/schemas/acceptance-run-receipt.schema.json +88 -0
  127. package/dist/universal/.github/skills/citable/schemas/artifact-interchange.schema.json +58 -0
  128. package/dist/universal/.github/skills/citable/schemas/assumption.schema.json +119 -0
  129. package/dist/universal/.github/skills/citable/schemas/browser-evidence-plan.schema.json +76 -0
  130. package/dist/universal/.github/skills/citable/schemas/corpus-publication-receipt.schema.json +24 -0
  131. package/dist/universal/.github/skills/citable/schemas/customer-outcome.schema.json +119 -0
  132. package/dist/universal/.github/skills/citable/schemas/decision.schema.json +154 -0
  133. package/dist/universal/.github/skills/citable/schemas/deployment-receipt.schema.json +51 -0
  134. package/dist/universal/.github/skills/citable/schemas/field-validation-metrics.schema.json +15 -0
  135. package/dist/universal/.github/skills/citable/schemas/initiative.schema.json +185 -0
  136. package/dist/universal/.github/skills/citable/schemas/kpi.schema.json +108 -0
  137. package/dist/universal/.github/skills/citable/schemas/observation.schema.json +1 -1
  138. package/dist/universal/.github/skills/citable/schemas/release-manifest.schema.json +74 -0
  139. package/dist/universal/.github/skills/citable/schemas/release-state.schema.json +40 -0
  140. package/dist/universal/.github/skills/citable/schemas/risk.schema.json +172 -0
  141. package/dist/universal/.github/skills/citable/schemas/scenario.schema.json +165 -0
  142. package/dist/universal/.github/skills/citable/schemas/variance.schema.json +112 -0
  143. package/dist/universal/.kiro/skills/citable/SKILL.md +12 -1
  144. package/dist/universal/.kiro/skills/citable/VERSION +1 -1
  145. package/dist/universal/.kiro/skills/citable/commands/README.md +2 -1
  146. package/dist/universal/.kiro/skills/citable/commands/artifact-interchange.md +28 -0
  147. package/dist/universal/.kiro/skills/citable/commands/field-validation.md +71 -0
  148. package/dist/universal/.kiro/skills/citable/commands/observe-and-act.md +5 -0
  149. package/dist/universal/.kiro/skills/citable/manifest.json +30 -10
  150. package/dist/universal/.kiro/skills/citable/references/aeo-geo-validation.md +1 -1
  151. package/dist/universal/.kiro/skills/citable/references/capability-boundaries.md +1 -0
  152. package/dist/universal/.kiro/skills/citable/schemas/acceptance-corpus.schema.json +168 -0
  153. package/dist/universal/.kiro/skills/citable/schemas/acceptance-run-context.schema.json +17 -0
  154. package/dist/universal/.kiro/skills/citable/schemas/acceptance-run-receipt.schema.json +88 -0
  155. package/dist/universal/.kiro/skills/citable/schemas/artifact-interchange.schema.json +58 -0
  156. package/dist/universal/.kiro/skills/citable/schemas/assumption.schema.json +119 -0
  157. package/dist/universal/.kiro/skills/citable/schemas/browser-evidence-plan.schema.json +76 -0
  158. package/dist/universal/.kiro/skills/citable/schemas/corpus-publication-receipt.schema.json +24 -0
  159. package/dist/universal/.kiro/skills/citable/schemas/customer-outcome.schema.json +119 -0
  160. package/dist/universal/.kiro/skills/citable/schemas/decision.schema.json +154 -0
  161. package/dist/universal/.kiro/skills/citable/schemas/deployment-receipt.schema.json +51 -0
  162. package/dist/universal/.kiro/skills/citable/schemas/field-validation-metrics.schema.json +15 -0
  163. package/dist/universal/.kiro/skills/citable/schemas/initiative.schema.json +185 -0
  164. package/dist/universal/.kiro/skills/citable/schemas/kpi.schema.json +108 -0
  165. package/dist/universal/.kiro/skills/citable/schemas/observation.schema.json +1 -1
  166. package/dist/universal/.kiro/skills/citable/schemas/release-manifest.schema.json +74 -0
  167. package/dist/universal/.kiro/skills/citable/schemas/release-state.schema.json +40 -0
  168. package/dist/universal/.kiro/skills/citable/schemas/risk.schema.json +172 -0
  169. package/dist/universal/.kiro/skills/citable/schemas/scenario.schema.json +165 -0
  170. package/dist/universal/.kiro/skills/citable/schemas/variance.schema.json +112 -0
  171. package/dist/universal/.opencode/skills/citable/SKILL.md +12 -1
  172. package/dist/universal/.opencode/skills/citable/VERSION +1 -1
  173. package/dist/universal/.opencode/skills/citable/commands/README.md +2 -1
  174. package/dist/universal/.opencode/skills/citable/commands/artifact-interchange.md +28 -0
  175. package/dist/universal/.opencode/skills/citable/commands/field-validation.md +71 -0
  176. package/dist/universal/.opencode/skills/citable/commands/observe-and-act.md +5 -0
  177. package/dist/universal/.opencode/skills/citable/manifest.json +30 -10
  178. package/dist/universal/.opencode/skills/citable/references/aeo-geo-validation.md +1 -1
  179. package/dist/universal/.opencode/skills/citable/references/capability-boundaries.md +1 -0
  180. package/dist/universal/.opencode/skills/citable/schemas/acceptance-corpus.schema.json +168 -0
  181. package/dist/universal/.opencode/skills/citable/schemas/acceptance-run-context.schema.json +17 -0
  182. package/dist/universal/.opencode/skills/citable/schemas/acceptance-run-receipt.schema.json +88 -0
  183. package/dist/universal/.opencode/skills/citable/schemas/artifact-interchange.schema.json +58 -0
  184. package/dist/universal/.opencode/skills/citable/schemas/assumption.schema.json +119 -0
  185. package/dist/universal/.opencode/skills/citable/schemas/browser-evidence-plan.schema.json +76 -0
  186. package/dist/universal/.opencode/skills/citable/schemas/corpus-publication-receipt.schema.json +24 -0
  187. package/dist/universal/.opencode/skills/citable/schemas/customer-outcome.schema.json +119 -0
  188. package/dist/universal/.opencode/skills/citable/schemas/decision.schema.json +154 -0
  189. package/dist/universal/.opencode/skills/citable/schemas/deployment-receipt.schema.json +51 -0
  190. package/dist/universal/.opencode/skills/citable/schemas/field-validation-metrics.schema.json +15 -0
  191. package/dist/universal/.opencode/skills/citable/schemas/initiative.schema.json +185 -0
  192. package/dist/universal/.opencode/skills/citable/schemas/kpi.schema.json +108 -0
  193. package/dist/universal/.opencode/skills/citable/schemas/observation.schema.json +1 -1
  194. package/dist/universal/.opencode/skills/citable/schemas/release-manifest.schema.json +74 -0
  195. package/dist/universal/.opencode/skills/citable/schemas/release-state.schema.json +40 -0
  196. package/dist/universal/.opencode/skills/citable/schemas/risk.schema.json +172 -0
  197. package/dist/universal/.opencode/skills/citable/schemas/scenario.schema.json +165 -0
  198. package/dist/universal/.opencode/skills/citable/schemas/variance.schema.json +112 -0
  199. package/dist/universal/.pi/agent/skills/citable/SKILL.md +12 -1
  200. package/dist/universal/.pi/agent/skills/citable/VERSION +1 -1
  201. package/dist/universal/.pi/agent/skills/citable/commands/README.md +2 -1
  202. package/dist/universal/.pi/agent/skills/citable/commands/artifact-interchange.md +28 -0
  203. package/dist/universal/.pi/agent/skills/citable/commands/field-validation.md +71 -0
  204. package/dist/universal/.pi/agent/skills/citable/commands/observe-and-act.md +5 -0
  205. package/dist/universal/.pi/agent/skills/citable/manifest.json +30 -10
  206. package/dist/universal/.pi/agent/skills/citable/references/aeo-geo-validation.md +1 -1
  207. package/dist/universal/.pi/agent/skills/citable/references/capability-boundaries.md +1 -0
  208. package/dist/universal/.pi/agent/skills/citable/schemas/acceptance-corpus.schema.json +168 -0
  209. package/dist/universal/.pi/agent/skills/citable/schemas/acceptance-run-context.schema.json +17 -0
  210. package/dist/universal/.pi/agent/skills/citable/schemas/acceptance-run-receipt.schema.json +88 -0
  211. package/dist/universal/.pi/agent/skills/citable/schemas/artifact-interchange.schema.json +58 -0
  212. package/dist/universal/.pi/agent/skills/citable/schemas/assumption.schema.json +119 -0
  213. package/dist/universal/.pi/agent/skills/citable/schemas/browser-evidence-plan.schema.json +76 -0
  214. package/dist/universal/.pi/agent/skills/citable/schemas/corpus-publication-receipt.schema.json +24 -0
  215. package/dist/universal/.pi/agent/skills/citable/schemas/customer-outcome.schema.json +119 -0
  216. package/dist/universal/.pi/agent/skills/citable/schemas/decision.schema.json +154 -0
  217. package/dist/universal/.pi/agent/skills/citable/schemas/deployment-receipt.schema.json +51 -0
  218. package/dist/universal/.pi/agent/skills/citable/schemas/field-validation-metrics.schema.json +15 -0
  219. package/dist/universal/.pi/agent/skills/citable/schemas/initiative.schema.json +185 -0
  220. package/dist/universal/.pi/agent/skills/citable/schemas/kpi.schema.json +108 -0
  221. package/dist/universal/.pi/agent/skills/citable/schemas/observation.schema.json +1 -1
  222. package/dist/universal/.pi/agent/skills/citable/schemas/release-manifest.schema.json +74 -0
  223. package/dist/universal/.pi/agent/skills/citable/schemas/release-state.schema.json +40 -0
  224. package/dist/universal/.pi/agent/skills/citable/schemas/risk.schema.json +172 -0
  225. package/dist/universal/.pi/agent/skills/citable/schemas/scenario.schema.json +165 -0
  226. package/dist/universal/.pi/agent/skills/citable/schemas/variance.schema.json +112 -0
  227. package/dist/universal/.qoder/skills/citable/SKILL.md +12 -1
  228. package/dist/universal/.qoder/skills/citable/VERSION +1 -1
  229. package/dist/universal/.qoder/skills/citable/commands/README.md +2 -1
  230. package/dist/universal/.qoder/skills/citable/commands/artifact-interchange.md +28 -0
  231. package/dist/universal/.qoder/skills/citable/commands/field-validation.md +71 -0
  232. package/dist/universal/.qoder/skills/citable/commands/observe-and-act.md +5 -0
  233. package/dist/universal/.qoder/skills/citable/manifest.json +30 -10
  234. package/dist/universal/.qoder/skills/citable/references/aeo-geo-validation.md +1 -1
  235. package/dist/universal/.qoder/skills/citable/references/capability-boundaries.md +1 -0
  236. package/dist/universal/.qoder/skills/citable/schemas/acceptance-corpus.schema.json +168 -0
  237. package/dist/universal/.qoder/skills/citable/schemas/acceptance-run-context.schema.json +17 -0
  238. package/dist/universal/.qoder/skills/citable/schemas/acceptance-run-receipt.schema.json +88 -0
  239. package/dist/universal/.qoder/skills/citable/schemas/artifact-interchange.schema.json +58 -0
  240. package/dist/universal/.qoder/skills/citable/schemas/assumption.schema.json +119 -0
  241. package/dist/universal/.qoder/skills/citable/schemas/browser-evidence-plan.schema.json +76 -0
  242. package/dist/universal/.qoder/skills/citable/schemas/corpus-publication-receipt.schema.json +24 -0
  243. package/dist/universal/.qoder/skills/citable/schemas/customer-outcome.schema.json +119 -0
  244. package/dist/universal/.qoder/skills/citable/schemas/decision.schema.json +154 -0
  245. package/dist/universal/.qoder/skills/citable/schemas/deployment-receipt.schema.json +51 -0
  246. package/dist/universal/.qoder/skills/citable/schemas/field-validation-metrics.schema.json +15 -0
  247. package/dist/universal/.qoder/skills/citable/schemas/initiative.schema.json +185 -0
  248. package/dist/universal/.qoder/skills/citable/schemas/kpi.schema.json +108 -0
  249. package/dist/universal/.qoder/skills/citable/schemas/observation.schema.json +1 -1
  250. package/dist/universal/.qoder/skills/citable/schemas/release-manifest.schema.json +74 -0
  251. package/dist/universal/.qoder/skills/citable/schemas/release-state.schema.json +40 -0
  252. package/dist/universal/.qoder/skills/citable/schemas/risk.schema.json +172 -0
  253. package/dist/universal/.qoder/skills/citable/schemas/scenario.schema.json +165 -0
  254. package/dist/universal/.qoder/skills/citable/schemas/variance.schema.json +112 -0
  255. package/dist/universal/.rovodev/skills/citable/SKILL.md +12 -1
  256. package/dist/universal/.rovodev/skills/citable/VERSION +1 -1
  257. package/dist/universal/.rovodev/skills/citable/commands/README.md +2 -1
  258. package/dist/universal/.rovodev/skills/citable/commands/artifact-interchange.md +28 -0
  259. package/dist/universal/.rovodev/skills/citable/commands/field-validation.md +71 -0
  260. package/dist/universal/.rovodev/skills/citable/commands/observe-and-act.md +5 -0
  261. package/dist/universal/.rovodev/skills/citable/manifest.json +30 -10
  262. package/dist/universal/.rovodev/skills/citable/references/aeo-geo-validation.md +1 -1
  263. package/dist/universal/.rovodev/skills/citable/references/capability-boundaries.md +1 -0
  264. package/dist/universal/.rovodev/skills/citable/schemas/acceptance-corpus.schema.json +168 -0
  265. package/dist/universal/.rovodev/skills/citable/schemas/acceptance-run-context.schema.json +17 -0
  266. package/dist/universal/.rovodev/skills/citable/schemas/acceptance-run-receipt.schema.json +88 -0
  267. package/dist/universal/.rovodev/skills/citable/schemas/artifact-interchange.schema.json +58 -0
  268. package/dist/universal/.rovodev/skills/citable/schemas/assumption.schema.json +119 -0
  269. package/dist/universal/.rovodev/skills/citable/schemas/browser-evidence-plan.schema.json +76 -0
  270. package/dist/universal/.rovodev/skills/citable/schemas/corpus-publication-receipt.schema.json +24 -0
  271. package/dist/universal/.rovodev/skills/citable/schemas/customer-outcome.schema.json +119 -0
  272. package/dist/universal/.rovodev/skills/citable/schemas/decision.schema.json +154 -0
  273. package/dist/universal/.rovodev/skills/citable/schemas/deployment-receipt.schema.json +51 -0
  274. package/dist/universal/.rovodev/skills/citable/schemas/field-validation-metrics.schema.json +15 -0
  275. package/dist/universal/.rovodev/skills/citable/schemas/initiative.schema.json +185 -0
  276. package/dist/universal/.rovodev/skills/citable/schemas/kpi.schema.json +108 -0
  277. package/dist/universal/.rovodev/skills/citable/schemas/observation.schema.json +1 -1
  278. package/dist/universal/.rovodev/skills/citable/schemas/release-manifest.schema.json +74 -0
  279. package/dist/universal/.rovodev/skills/citable/schemas/release-state.schema.json +40 -0
  280. package/dist/universal/.rovodev/skills/citable/schemas/risk.schema.json +172 -0
  281. package/dist/universal/.rovodev/skills/citable/schemas/scenario.schema.json +165 -0
  282. package/dist/universal/.rovodev/skills/citable/schemas/variance.schema.json +112 -0
  283. package/dist/universal/.trae/skills/citable/SKILL.md +12 -1
  284. package/dist/universal/.trae/skills/citable/VERSION +1 -1
  285. package/dist/universal/.trae/skills/citable/commands/README.md +2 -1
  286. package/dist/universal/.trae/skills/citable/commands/artifact-interchange.md +28 -0
  287. package/dist/universal/.trae/skills/citable/commands/field-validation.md +71 -0
  288. package/dist/universal/.trae/skills/citable/commands/observe-and-act.md +5 -0
  289. package/dist/universal/.trae/skills/citable/manifest.json +30 -10
  290. package/dist/universal/.trae/skills/citable/references/aeo-geo-validation.md +1 -1
  291. package/dist/universal/.trae/skills/citable/references/capability-boundaries.md +1 -0
  292. package/dist/universal/.trae/skills/citable/schemas/acceptance-corpus.schema.json +168 -0
  293. package/dist/universal/.trae/skills/citable/schemas/acceptance-run-context.schema.json +17 -0
  294. package/dist/universal/.trae/skills/citable/schemas/acceptance-run-receipt.schema.json +88 -0
  295. package/dist/universal/.trae/skills/citable/schemas/artifact-interchange.schema.json +58 -0
  296. package/dist/universal/.trae/skills/citable/schemas/assumption.schema.json +119 -0
  297. package/dist/universal/.trae/skills/citable/schemas/browser-evidence-plan.schema.json +76 -0
  298. package/dist/universal/.trae/skills/citable/schemas/corpus-publication-receipt.schema.json +24 -0
  299. package/dist/universal/.trae/skills/citable/schemas/customer-outcome.schema.json +119 -0
  300. package/dist/universal/.trae/skills/citable/schemas/decision.schema.json +154 -0
  301. package/dist/universal/.trae/skills/citable/schemas/deployment-receipt.schema.json +51 -0
  302. package/dist/universal/.trae/skills/citable/schemas/field-validation-metrics.schema.json +15 -0
  303. package/dist/universal/.trae/skills/citable/schemas/initiative.schema.json +185 -0
  304. package/dist/universal/.trae/skills/citable/schemas/kpi.schema.json +108 -0
  305. package/dist/universal/.trae/skills/citable/schemas/observation.schema.json +1 -1
  306. package/dist/universal/.trae/skills/citable/schemas/release-manifest.schema.json +74 -0
  307. package/dist/universal/.trae/skills/citable/schemas/release-state.schema.json +40 -0
  308. package/dist/universal/.trae/skills/citable/schemas/risk.schema.json +172 -0
  309. package/dist/universal/.trae/skills/citable/schemas/scenario.schema.json +165 -0
  310. package/dist/universal/.trae/skills/citable/schemas/variance.schema.json +112 -0
  311. package/dist/universal/.trae-cn/skills/citable/SKILL.md +12 -1
  312. package/dist/universal/.trae-cn/skills/citable/VERSION +1 -1
  313. package/dist/universal/.trae-cn/skills/citable/commands/README.md +2 -1
  314. package/dist/universal/.trae-cn/skills/citable/commands/artifact-interchange.md +28 -0
  315. package/dist/universal/.trae-cn/skills/citable/commands/field-validation.md +71 -0
  316. package/dist/universal/.trae-cn/skills/citable/commands/observe-and-act.md +5 -0
  317. package/dist/universal/.trae-cn/skills/citable/manifest.json +30 -10
  318. package/dist/universal/.trae-cn/skills/citable/references/aeo-geo-validation.md +1 -1
  319. package/dist/universal/.trae-cn/skills/citable/references/capability-boundaries.md +1 -0
  320. package/dist/universal/.trae-cn/skills/citable/schemas/acceptance-corpus.schema.json +168 -0
  321. package/dist/universal/.trae-cn/skills/citable/schemas/acceptance-run-context.schema.json +17 -0
  322. package/dist/universal/.trae-cn/skills/citable/schemas/acceptance-run-receipt.schema.json +88 -0
  323. package/dist/universal/.trae-cn/skills/citable/schemas/artifact-interchange.schema.json +58 -0
  324. package/dist/universal/.trae-cn/skills/citable/schemas/assumption.schema.json +119 -0
  325. package/dist/universal/.trae-cn/skills/citable/schemas/browser-evidence-plan.schema.json +76 -0
  326. package/dist/universal/.trae-cn/skills/citable/schemas/corpus-publication-receipt.schema.json +24 -0
  327. package/dist/universal/.trae-cn/skills/citable/schemas/customer-outcome.schema.json +119 -0
  328. package/dist/universal/.trae-cn/skills/citable/schemas/decision.schema.json +154 -0
  329. package/dist/universal/.trae-cn/skills/citable/schemas/deployment-receipt.schema.json +51 -0
  330. package/dist/universal/.trae-cn/skills/citable/schemas/field-validation-metrics.schema.json +15 -0
  331. package/dist/universal/.trae-cn/skills/citable/schemas/initiative.schema.json +185 -0
  332. package/dist/universal/.trae-cn/skills/citable/schemas/kpi.schema.json +108 -0
  333. package/dist/universal/.trae-cn/skills/citable/schemas/observation.schema.json +1 -1
  334. package/dist/universal/.trae-cn/skills/citable/schemas/release-manifest.schema.json +74 -0
  335. package/dist/universal/.trae-cn/skills/citable/schemas/release-state.schema.json +40 -0
  336. package/dist/universal/.trae-cn/skills/citable/schemas/risk.schema.json +172 -0
  337. package/dist/universal/.trae-cn/skills/citable/schemas/scenario.schema.json +165 -0
  338. package/dist/universal/.trae-cn/skills/citable/schemas/variance.schema.json +112 -0
  339. package/dist/universal/manifest.json +363 -123
  340. package/package.json +4 -1
  341. package/release/surfaces.json +21 -0
  342. package/schemas/acceptance-corpus.schema.json +168 -0
  343. package/schemas/acceptance-run-context.schema.json +17 -0
  344. package/schemas/acceptance-run-receipt.schema.json +88 -0
  345. package/schemas/artifact-interchange.schema.json +58 -0
  346. package/schemas/assumption.schema.json +119 -0
  347. package/schemas/browser-evidence-plan.schema.json +76 -0
  348. package/schemas/corpus-publication-receipt.schema.json +24 -0
  349. package/schemas/customer-outcome.schema.json +119 -0
  350. package/schemas/decision.schema.json +154 -0
  351. package/schemas/deployment-receipt.schema.json +51 -0
  352. package/schemas/field-validation-metrics.schema.json +15 -0
  353. package/schemas/initiative.schema.json +185 -0
  354. package/schemas/kpi.schema.json +108 -0
  355. package/schemas/observation.schema.json +1 -1
  356. package/schemas/release-manifest.schema.json +74 -0
  357. package/schemas/release-state.schema.json +40 -0
  358. package/schemas/risk.schema.json +172 -0
  359. package/schemas/scenario.schema.json +165 -0
  360. package/schemas/variance.schema.json +112 -0
  361. package/scripts/release-governance.js +123 -0
  362. package/skill/SKILL.md +12 -1
  363. package/skill/commands/README.md +2 -1
  364. package/skill/commands/artifact-interchange.md +28 -0
  365. package/skill/commands/field-validation.md +71 -0
  366. package/skill/commands/observe-and-act.md +5 -0
  367. package/skill/references/aeo-geo-validation.md +1 -1
  368. package/skill/references/capability-boundaries.md +1 -0
  369. package/src/acceptance/reproducibility.js +180 -0
  370. package/src/artifacts/interchange.js +179 -0
  371. package/src/cli/index.js +143 -4
  372. package/src/commands/assumptionAudit.js +111 -0
  373. package/src/commands/audit.js +6 -0
  374. package/src/commands/boardReport.js +251 -0
  375. package/src/commands/competitiveIntel.js +124 -0
  376. package/src/commands/corpus.js +322 -0
  377. package/src/commands/decisionMemo.js +202 -0
  378. package/src/commands/executive.js +167 -0
  379. package/src/commands/executiveReview.js +206 -0
  380. package/src/commands/init.js +14 -1
  381. package/src/commands/kpi.js +86 -0
  382. package/src/commands/monitor.js +9 -0
  383. package/src/commands/observe.js +84 -2
  384. package/src/commands/outcomes.js +113 -0
  385. package/src/commands/prioritize.js +108 -0
  386. package/src/commands/risk.js +104 -0
  387. package/src/commands/scenario.js +98 -0
  388. package/src/commands/variance.js +102 -0
  389. package/src/detectors/framework.js +37 -0
  390. package/src/detectors/page.js +10 -10
  391. package/src/detectors/tech.js +5 -3
  392. package/src/extractor/site.js +21 -6
  393. package/src/observations/browserJourney.js +167 -0
  394. package/src/observations/media.js +8 -1
  395. package/src/registries/index.js +107 -6
  396. package/src/release/governance.js +331 -0
  397. package/src/shared/asOf.js +18 -0
@@ -0,0 +1,167 @@
1
+ /**
2
+ * executive command — Chief-of-Staff Router
3
+ *
4
+ * Routes reporting and decision requests to the correct specialized skill.
5
+ * Built last deliberately — orchestration without strong underlying skills
6
+ * only coordinates weak outputs.
7
+ *
8
+ * Routing table:
9
+ * quarterly reporting → board-report
10
+ * monthly reporting → executive-review
11
+ * bounded decision → decision-memo
12
+ * material uncertainty → scenario
13
+ * risk request → risk
14
+ * metric dispute → kpi
15
+ * commercial premise → assumption-audit
16
+ * customer value question → outcomes
17
+ * roadmap priority → prioritize
18
+ * competitor change → competitive-intel
19
+ *
20
+ * Controls:
21
+ * - Max orchestration depth: 1 (no recursive routing)
22
+ * - Circular-call prevention: command registry checked before dispatch
23
+ * - Explicit conflict surfacing — conflicts not smoothed over
24
+ * - Decision logging to .citable/executive-log.yaml
25
+ *
26
+ * Usage:
27
+ * citable executive <request>
28
+ * citable executive --route <command> Force a specific route
29
+ * citable executive --log Show recent routing decisions
30
+ */
31
+ import { contextDir } from '../registries/index.js';
32
+ import { readYaml, writeYaml, nowIso } from '../shared/io.js';
33
+ import path from 'node:path';
34
+ import fs from 'node:fs';
35
+
36
+ const ROUTES = [
37
+ { patterns: [/quarterly|board.pack|board.report/i], command: 'board-report', reason: 'Quarterly board pack' },
38
+ { patterns: [/monthly|operating.review|exec.review/i], command: 'executive-review', reason: 'Monthly executive operating review' },
39
+ { patterns: [/decision|decide|approve|memo/i], command: 'decision-memo', reason: 'Bounded decision record' },
40
+ { patterns: [/scenario|war.room|compound.risk|cascade/i], command: 'scenario', reason: 'Compound risk scenario' },
41
+ { patterns: [/risk.register|residual.risk|risk.list/i], command: 'risk', reason: 'Risk register' },
42
+ { patterns: [/kpi|metric.definition|metric.dispute/i], command: 'kpi', reason: 'KPI architecture' },
43
+ { patterns: [/assumption|premise|still.valid/i], command: 'assumption-audit', reason: 'Assumption validity' },
44
+ { patterns: [/customer.outcome|customer.value|impact/i], command: 'outcomes', reason: 'Customer outcomes' },
45
+ { patterns: [/variance|miss|why.did.we/i], command: 'variance', reason: 'Variance analysis' },
46
+ { patterns: [/prioriti|roadmap|what.to.build|rank/i], command: 'prioritize', reason: 'Initiative prioritization' },
47
+ { patterns: [/competitor|competitive|market.change/i], command: 'competitive-intel', reason: 'Competitive intelligence' },
48
+ ];
49
+
50
+ const MAX_DEPTH = 1;
51
+ let _callDepth = 0;
52
+
53
+ export async function executiveCommand(args, root = process.cwd()) {
54
+ const forceRoute = argVal(args, '--route');
55
+ const showLog = args.includes('--log');
56
+
57
+ if (showLog) return executiveLog(root);
58
+
59
+ if (_callDepth >= MAX_DEPTH) {
60
+ return { error: 'Maximum orchestration depth reached — circular routing prevented' };
61
+ }
62
+
63
+ const request = args.filter(a => !a.startsWith('--')).join(' ');
64
+
65
+ const route = forceRoute
66
+ ? ROUTES.find(r => r.command === forceRoute)
67
+ : resolveRoute(request);
68
+
69
+ if (!route) {
70
+ return {
71
+ unresolved: true,
72
+ request,
73
+ available_commands: ROUTES.map(r => ({ command: r.command, reason: r.reason })),
74
+ message: 'Could not determine the appropriate skill. Use --route <command> to force a route, or run the specific command directly.',
75
+ };
76
+ }
77
+
78
+ // Log the routing decision
79
+ logDecision(root, { request, routed_to: route.command, reason: route.reason, at: nowIso() });
80
+
81
+ _callDepth++;
82
+ try {
83
+ // Lazy-import to avoid circular deps — commands are imported at call time
84
+ const mod = await import(`./${commandToModule(route.command)}.js`);
85
+ const fn = mod[commandToExport(route.command)];
86
+ if (!fn) {
87
+ return { error: `No handler for command: ${route.command}` };
88
+ }
89
+ const downstreamArgs = args.filter((arg, index) => arg !== '--route' && args[index - 1] !== '--route');
90
+ const result = await fn(downstreamArgs, root);
91
+ return {
92
+ routed_to: route.command,
93
+ reason: route.reason,
94
+ result,
95
+ };
96
+ } finally {
97
+ _callDepth--;
98
+ }
99
+ }
100
+
101
+ function resolveRoute(request) {
102
+ if (!request) return null;
103
+ for (const route of ROUTES) {
104
+ if (route.patterns.some(p => p.test(request))) return route;
105
+ }
106
+ return null;
107
+ }
108
+
109
+ function commandToModule(cmd) {
110
+ const MAP = {
111
+ 'board-report': 'boardReport',
112
+ 'executive-review': 'executiveReview',
113
+ 'decision-memo': 'decisionMemo',
114
+ 'scenario': 'scenario',
115
+ 'risk': 'risk',
116
+ 'kpi': 'kpi',
117
+ 'assumption-audit': 'assumptionAudit',
118
+ 'outcomes': 'outcomes',
119
+ 'variance': 'variance',
120
+ 'prioritize': 'prioritize',
121
+ 'competitive-intel': 'competitiveIntel',
122
+ };
123
+ return MAP[cmd] ?? cmd;
124
+ }
125
+
126
+ function commandToExport(cmd) {
127
+ const MAP = {
128
+ 'board-report': 'boardReportCommand',
129
+ 'executive-review': 'executiveReviewCommand',
130
+ 'decision-memo': 'decisionMemoCommand',
131
+ 'scenario': 'scenarioCommand',
132
+ 'risk': 'riskCommand',
133
+ 'kpi': 'kpiCommand',
134
+ 'assumption-audit': 'assumptionAuditCommand',
135
+ 'outcomes': 'outcomesCommand',
136
+ 'variance': 'varianceCommand',
137
+ 'prioritize': 'prioritizeCommand',
138
+ 'competitive-intel': 'competitiveIntelCommand',
139
+ };
140
+ return MAP[cmd] ?? cmd + 'Command';
141
+ }
142
+
143
+ function logDecision(root, entry) {
144
+ const dir = contextDir(root);
145
+ const logFile = path.join(dir, 'executive-log.yaml');
146
+ let log = { version: 1, kind: 'executive-log', entries: [] };
147
+ if (fs.existsSync(logFile)) {
148
+ try { log = readYaml(logFile) ?? log; } catch {}
149
+ }
150
+ log.entries.push(entry);
151
+ // Keep last 100 entries
152
+ if (log.entries.length > 100) log.entries = log.entries.slice(-100);
153
+ if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
154
+ writeYaml(logFile, { ...log, updated: nowIso() });
155
+ }
156
+
157
+ function executiveLog(root) {
158
+ const logFile = path.join(contextDir(root), 'executive-log.yaml');
159
+ if (!fs.existsSync(logFile)) return { log: [], message: 'No routing decisions logged yet.' };
160
+ const log = readYaml(logFile) ?? { entries: [] };
161
+ return { log: (log.entries ?? []).slice(-20) };
162
+ }
163
+
164
+ function argVal(args, flag) {
165
+ const i = args.indexOf(flag);
166
+ return i >= 0 ? args[i + 1] : null;
167
+ }
@@ -0,0 +1,206 @@
1
+ /**
2
+ * executive-review command — Monthly Executive Operating Review
3
+ *
4
+ * Generates an evidence-first operating review. Produces an evidence
5
+ * ledger first, then derives the narrative. Never generates a polished
6
+ * positive summary when data is absent or ungoverned.
7
+ *
8
+ * Four-act invariant (mandatory):
9
+ * 1. Where management said the company would be
10
+ * 2. Where it actually is
11
+ * 3. Why the variance exists
12
+ * 4. What management is doing about it
13
+ *
14
+ * Usage:
15
+ * citable executive-review [--period <YYYY-MM>] [--json]
16
+ */
17
+ import { checkReferentialIntegrity, loadRegistries } from '../registries/index.js';
18
+ import { nowIso } from '../shared/io.js';
19
+ import { validateAgainst } from '../shared/schemaValidator.js';
20
+ import { dateOnly, parseAsOf } from '../shared/asOf.js';
21
+
22
+
23
+ /** Filter registry entries to only those that pass schema validation. */
24
+ function validEntries(entries, schemaName) {
25
+ if (!entries?.length) return [];
26
+ return entries.filter(e => {
27
+ const { valid } = validateAgainst(schemaName, { version: 1, kind: schemaName.replace('.schema.json','s'), entries: [e] });
28
+ return valid;
29
+ });
30
+ }
31
+
32
+ function validReferences(entries, kind, idField, problems) {
33
+ return entries.filter(entry => !problems.some(problem => problem.startsWith(`${kind}/${entry[idField]}:`)));
34
+ }
35
+
36
+ export async function executiveReviewCommand(args, root = process.cwd()) {
37
+ const asOf = parseAsOf(args);
38
+ const period = argVal(args, '--period') ?? currentPeriod(asOf);
39
+ const asJson = args.includes('--json');
40
+
41
+ const { registries, problems: regProblems } = loadRegistries(root);
42
+ const refProblems = checkReferentialIntegrity(registries);
43
+
44
+ const report = buildReview(registries, period, [...regProblems, ...refProblems], refProblems);
45
+ report.generated_at = nowIso();
46
+ report.as_of = dateOnly(asOf);
47
+
48
+ return asJson ? report : formatReview(report);
49
+ }
50
+
51
+ function buildReview(registries, period, regProblems, refProblems) {
52
+ // Filter to schema-valid and referentially valid governed evidence.
53
+ const kpis = validReferences(validEntries(registries.kpis?.entries, 'kpi.schema.json'), 'kpis', 'metric_id', refProblems);
54
+ const validVariances = validReferences(validEntries(registries.variances?.entries, 'variance.schema.json'), 'variances', 'variance_id', refProblems);
55
+ const variances = validVariances.filter(v => v.period === period);
56
+ const outcomes = validReferences(validEntries(registries['customer-outcomes']?.entries, 'customer-outcome.schema.json'), 'customer-outcomes', 'outcome_id', refProblems);
57
+ const risks = validReferences(validEntries(registries.risks?.entries, 'risk.schema.json'), 'risks', 'risk_id', refProblems);
58
+ const decisions = validReferences(validEntries(registries.decisions?.entries, 'decision.schema.json'), 'decisions', 'decision_id', refProblems);
59
+
60
+ const invalidTotal =
61
+ ((registries.kpis?.entries?.length ?? 0) - kpis.length) +
62
+ ((registries.variances?.entries?.length ?? 0) - validVariances.length) +
63
+ ((registries['customer-outcomes']?.entries?.length ?? 0) - outcomes.length) +
64
+ ((registries.risks?.entries?.length ?? 0) - risks.length) +
65
+ ((registries.decisions?.entries?.length ?? 0) - decisions.length);
66
+
67
+
68
+ // Evidence ledger — raw facts before narrative
69
+ const ledger = {
70
+ period,
71
+ governed_metrics: kpis.length,
72
+ variances_this_period: variances.length,
73
+ material_variances: variances.filter(v => ['material','critical'].includes(v.materiality)).length,
74
+ customer_outcomes_total: outcomes.length,
75
+ outcomes_customer_confirmed: outcomes.filter(o => o.customer_confirmed).length,
76
+ outcomes_causal_established: outcomes.filter(o => o.outcome_stage === 'causal_relationship_established').length,
77
+ board_visible_risks: risks.filter(r => r.board_visibility).length,
78
+ critical_risks: risks.filter(r => r.residual_exposure === 'critical').length,
79
+ deteriorating_risks: risks.filter(r => r.trend === 'deteriorating').length,
80
+ };
81
+
82
+ // Commercial section
83
+ const commercial = buildSection('commercial', kpis, variances, [
84
+ 'ARR','MRR','bookings','pipeline_coverage','win_rate','sales_cycle','customer_concentration',
85
+ ]);
86
+
87
+ // Customer section
88
+ const customer = buildSection('customer', kpis, variances, [
89
+ 'active_customers','onboarding_time','renewal_risk','findings_acted_upon','unresolved_escalations',
90
+ ]);
91
+
92
+ // Product section
93
+ const product = buildSection('product', kpis, variances, [
94
+ 'active_properties','audits_run','completed_valid_audits','installation_success','feature_adoption',
95
+ ]);
96
+
97
+ // Quality section — Citable-specific
98
+ const quality = buildSection('quality', kpis, variances, [
99
+ 'detector_precision','confirmed_false_positives','known_false_negatives','expired_evidence','stale_registries',
100
+ ]);
101
+
102
+ // Operations section
103
+ const operations = buildSection('operations', kpis, variances, [
104
+ 'failed_runs','incomplete_evidence_packages','crawler_access_failures','release_regressions',
105
+ ]);
106
+
107
+ // Management section
108
+ const openDecisions = decisions.filter(d => d.status === 'open');
109
+ const management = {
110
+ open_decisions: openDecisions.length,
111
+ decisions_requiring_action: openDecisions.map(d => ({
112
+ id: d.decision_id, title: d.title, owner: d.owner, deadline: d.deadline,
113
+ })),
114
+ };
115
+
116
+ return {
117
+ report_type: 'executive-operating-review',
118
+ period,
119
+ registry_problems: regProblems,
120
+ invalid_entries_excluded: invalidTotal > 0 ? invalidTotal : undefined,
121
+ ledger,
122
+ four_act_required: buildFourActPrompt(variances),
123
+ sections: { commercial, customer, product, quality, operations, management },
124
+ ungoverned_warning: ledger.governed_metrics === 0
125
+ ? 'BLOCKED: No governed KPIs. Register metrics with `citable kpi add` before generating narrative.'
126
+ : null,
127
+ };
128
+ }
129
+
130
+ function buildSection(name, kpis, variances, relevantNames) {
131
+ const sectionKpis = kpis.filter(k =>
132
+ relevantNames.some(n => k.metric_id?.toLowerCase().includes(n.toLowerCase()) || k.name?.toLowerCase().includes(n.toLowerCase()))
133
+ );
134
+ const sectionVariances = variances.filter(v =>
135
+ sectionKpis.some(k => k.metric_id === v.metric_id)
136
+ );
137
+ return {
138
+ section: name,
139
+ governed_metrics: sectionKpis.length,
140
+ variances: sectionVariances.length,
141
+ material_variances: sectionVariances.filter(v => ['material','critical'].includes(v.materiality)).length,
142
+ ungoverned_warning: sectionKpis.length === 0
143
+ ? `No governed KPIs for ${name} — narrative cannot be generated from ungoverned data`
144
+ : null,
145
+ };
146
+ }
147
+
148
+ function buildFourActPrompt(variances) {
149
+ if (variances.length === 0) return { status: 'no_variances_this_period' };
150
+ const material = variances.filter(v => ['material','critical'].includes(v.materiality));
151
+ return {
152
+ status: 'required',
153
+ material_variances: material.length,
154
+ template: {
155
+ act_1: 'Where management said the company would be: [state targets and forecasts from KPI registry]',
156
+ act_2: 'Where it actually is: [state actuals from variance records]',
157
+ act_3: 'Why the variance exists: [state primary_driver from each material variance — vague causes rejected]',
158
+ act_4: 'What management is doing about it: [state management_response from each material variance]',
159
+ },
160
+ };
161
+ }
162
+
163
+ function formatReview(report) {
164
+ const lines = [
165
+ `# Executive Operating Review — ${report.period}`,
166
+ `Generated: ${report.generated_at}`,
167
+ '',
168
+ ];
169
+ if (report.ungoverned_warning) {
170
+ lines.push(`⛔ ${report.ungoverned_warning}`, '');
171
+ }
172
+ if (report.registry_problems?.length) {
173
+ lines.push(`⚠️ Registry problems (${report.registry_problems.length}):`);
174
+ for (const p of report.registry_problems.slice(0, 5)) lines.push(` ${p}`);
175
+ lines.push('');
176
+ }
177
+ const l = report.ledger;
178
+ lines.push(
179
+ '## Evidence Ledger',
180
+ `- Governed metrics: ${l.governed_metrics}`,
181
+ `- Variances this period: ${l.variances_this_period} (${l.material_variances} material)`,
182
+ `- Customer outcomes: ${l.customer_outcomes_total} (${l.outcomes_customer_confirmed} confirmed, ${l.outcomes_causal_established} causal)`,
183
+ `- Board-visible risks: ${l.board_visible_risks} (${l.critical_risks} critical, ${l.deteriorating_risks} deteriorating)`,
184
+ '',
185
+ '## Four-Act Reporting Requirement',
186
+ );
187
+ const fa = report.four_act_required;
188
+ if (fa.status === 'required') {
189
+ for (const [act, text] of Object.entries(fa.template)) {
190
+ lines.push(`**${act.replace('_',' ').toUpperCase()}:** ${text}`);
191
+ }
192
+ } else {
193
+ lines.push('No variances registered for this period.');
194
+ }
195
+ return lines.join('\n');
196
+ }
197
+
198
+ function currentPeriod(asOf) {
199
+ const d = asOf ?? new Date();
200
+ return `${d.getUTCFullYear()}-${String(d.getUTCMonth() + 1).padStart(2, '0')}`;
201
+ }
202
+
203
+ function argVal(args, flag) {
204
+ const i = args.indexOf(flag);
205
+ return i >= 0 ? args[i + 1] : null;
206
+ }
@@ -15,6 +15,19 @@ const DEFAULT_CRAWLERS = [
15
15
  ['CRAWLER-CLAUDEBOT', 'ClaudeBot', 'Anthropic', 'model_training'],
16
16
  ];
17
17
 
18
+ function hasSchemaSignal(text) {
19
+ if (/application\/ld\+json/i.test(text)) return true;
20
+ for (const match of text.matchAll(/https?:\/\/[^\s"'<>]+/gi)) {
21
+ try {
22
+ const hostname = new URL(match[0]).hostname.toLowerCase();
23
+ if (hostname === 'schema.org' || hostname === 'www.schema.org') return true;
24
+ } catch {
25
+ // Ignore malformed URL-like source text during best-effort project discovery.
26
+ }
27
+ }
28
+ return false;
29
+ }
30
+
18
31
  function detectFramework(root) {
19
32
  const detected = {
20
33
  framework: null, rendering_model: null, package_manager: null,
@@ -47,7 +60,7 @@ function detectFramework(root) {
47
60
  for (const f of listFiles(root, (p) => /sitemap.*\.(xml|ts|js|mjs)$/.test(p))) detected.sitemap_sources.push(path.relative(root, f));
48
61
  for (const f of listFiles(root, (p) => /\.(html|jsx?|tsx?|astro|vue|svelte)$/.test(p)).slice(0, 400)) {
49
62
  const text = fs.readFileSync(f, 'utf8');
50
- if (text.includes('application/ld+json') || text.includes('schema.org')) detected.schema_sources.push(path.relative(root, f));
63
+ if (hasSchemaSignal(text)) detected.schema_sources.push(path.relative(root, f));
51
64
  if (/gtag\(|googletagmanager|plausible|posthog|umami|matomo/i.test(text)) detected.analytics.push(path.relative(root, f));
52
65
  }
53
66
  if (detected.rendering_model === null) unresolved.push('Rendering model could not be determined from manifests.');
@@ -0,0 +1,86 @@
1
+ /**
2
+ * kpi command — KPI Architecture registry management
3
+ *
4
+ * Usage:
5
+ * citable kpi list List all governed metrics
6
+ * citable kpi show <id> Show a single KPI
7
+ * citable kpi validate Validate all KPI records
8
+ */
9
+ import { loadRegistries, contextDir } from '../registries/index.js';
10
+ import { readYaml, writeYaml, nowIso } from '../shared/io.js';
11
+ import { validateAgainst } from '../shared/schemaValidator.js';
12
+ import path from 'node:path';
13
+ import fs from 'node:fs';
14
+
15
+ const REQUIRED_COMPARISON = true; // every KPI must have a comparison basis
16
+
17
+ export async function kpiCommand(args, root = process.cwd()) {
18
+ const [subcommand, ...rest] = args;
19
+ const dir = contextDir(root);
20
+ const file = path.join(dir, 'kpis.yaml');
21
+
22
+ switch (subcommand) {
23
+ case 'list': return kpiList(file);
24
+ case 'show': return kpiShow(file, rest[0]);
25
+ case 'validate': return kpiValidate(file);
26
+ case 'add': return { error: '`citable kpi add` is not yet implemented; edit kpis.yaml directly and run `citable kpi validate`' };
27
+ default:
28
+ return kpiList(file);
29
+ }
30
+ }
31
+
32
+ function loadKpis(file) {
33
+ if (!fs.existsSync(file)) return { version: 1, kind: 'kpis', entries: [] };
34
+ return readYaml(file) ?? { version: 1, kind: 'kpis', entries: [] };
35
+ }
36
+
37
+ function kpiList(file) {
38
+ const data = loadKpis(file);
39
+ if (!data.entries.length) return { kpis: [], message: 'No KPIs registered. Edit .citable/kpis.yaml, then run `citable kpi validate`.' };
40
+ return {
41
+ kpis: data.entries.map(k => ({
42
+ metric_id: k.metric_id,
43
+ name: k.name,
44
+ owner: k.owner,
45
+ cadence: k.reporting_cadence,
46
+ target: k.target ?? 'NOT SET',
47
+ comparison_required: k.comparison_required ?? REQUIRED_COMPARISON,
48
+ limitations: (k.known_limitations ?? []).length,
49
+ })),
50
+ total: data.entries.length,
51
+ };
52
+ }
53
+
54
+ function kpiShow(file, id) {
55
+ if (!id) return { error: 'metric_id required' };
56
+ const data = loadKpis(file);
57
+ const kpi = data.entries.find(k => k.metric_id === id);
58
+ if (!kpi) return { error: `KPI not found: ${id}` };
59
+ return { kpi };
60
+ }
61
+
62
+ function kpiValidate(file) {
63
+ const data = loadKpis(file);
64
+ const problems = [];
65
+ const { valid, errors } = validateAgainst('kpi.schema.json', data);
66
+ if (!valid) problems.push(...errors);
67
+ // Citable-specific checks
68
+ for (const k of data.entries) {
69
+ if (!k.known_limitations || k.known_limitations.length === 0)
70
+ problems.push(`${k.metric_id}: known_limitations is empty — every metric must document its measurement constraints`);
71
+ if (k.comparison_required !== false && !k.comparison_basis)
72
+ problems.push(`${k.metric_id}: comparison_basis required when comparison_required is true`);
73
+ if (!k.restatement_policy)
74
+ problems.push(`${k.metric_id}: restatement_policy missing — how will historical data be corrected?`);
75
+ // Citable metric distinction checks
76
+ if (/installs?/i.test(k.name) && !/active/i.test(k.name))
77
+ problems.push(`${k.metric_id}: "installs" vs "active_installations" must be distinct metrics`);
78
+ if (/audit/i.test(k.name) && !/valid|complete/i.test(k.executive_definition ?? ''))
79
+ problems.push(`${k.metric_id}: audits_run vs completed_valid_audits must be distinguished in executive_definition`);
80
+ }
81
+ return {
82
+ valid: problems.length === 0,
83
+ problems,
84
+ checked: data.entries.length,
85
+ };
86
+ }
@@ -11,6 +11,7 @@ function observations(dir) {
11
11
  function key(item) {
12
12
  const d = item.data || {};
13
13
  if (item.kind === 'citation') return [item.kind, d.provider, d.product_mode, d.prompt_id, d.run_index].join(':');
14
+ if (item.kind === 'representation_drift') return [item.kind, d.manifest_hash, d.surface_id, d.retrieval_path, d.region, d.request_identity].join(':');
14
15
  return [item.kind, d.url || d.citation_url || d.prompt_id || d.timestamp || item.observation_id].join(':');
15
16
  }
16
17
 
@@ -30,6 +31,14 @@ export function monitor(root, { runA, runB } = {}) {
30
31
  if (current.kind === 'index' && previous?.data?.indexed === true && current.data.indexed === false) alerts.push({ severity: 'high', type: 'index_loss', key: k });
31
32
  if (current.kind === 'canonical_freshness' && previous?.data?.canonical_consensus === true && current.data.canonical_consensus === false) alerts.push({ severity: 'high', type: 'canonical_regression', key: k });
32
33
  if (current.kind === 'citation' && previous?.data?.property_cited === true && current.data.property_cited === false) alerts.push({ severity: 'medium', type: 'citation_presence_change', key: k });
34
+ if (current.kind === 'representation_drift' && previous) {
35
+ const from = previous.data.representation_state, to = current.data.representation_state;
36
+ if (from !== 'divergent' && to === 'divergent') alerts.push({ severity: 'high', type: 'representation_divergence_observed', key: k, previous_state: from, current_state: to, authority: 'external_unverified', gates_release_finalization: false });
37
+ if (from === 'divergent' && to === 'consistent') {
38
+ const duration = new Date(current.collected_at) - new Date(previous.collected_at);
39
+ alerts.push({ severity: 'informational', type: 'representation_convergence_observed', key: k, previous_state: from, current_state: to, observed_interval_ms: Number.isFinite(duration) && duration >= 0 ? duration : null, authority: 'external_unverified', gates_release_finalization: false });
40
+ }
41
+ }
33
42
  }
34
43
  for (const k of before.keys()) if (!after.has(k)) alerts.push({ severity: 'medium', type: 'observation_missing', key: k });
35
44
  const result = { generated_at: nowIso(), run_a: a, run_b: b, summary: { alerts: alerts.length, critical_or_high: alerts.filter((x) => ['critical', 'high'].includes(x.severity)).length }, alerts };
@@ -8,11 +8,20 @@ import { parse as parseCsv } from 'csv-parse/sync';
8
8
  import { crawlerIdentity } from '../observations/crawlerIdentity.js';
9
9
  import { validateAgainst } from '../shared/schemaValidator.js';
10
10
  import { observeMedia } from '../observations/media.js';
11
+ import { parse as parseHtml } from 'node-html-parser';
12
+ import { verifyManifestIntegrity } from '../release/governance.js';
13
+ import { observeBrowserPlan } from '../observations/browserJourney.js';
11
14
 
12
15
  const originOf = (value) => { try { return new URL(value).origin; } catch { return null; } };
13
16
  const words = (text) => String(text || '').trim().split(/\s+/).filter(Boolean);
14
17
  const strictDate = (value) => /^\d{4}-\d{2}-\d{2}$/.test(value || '') && new Date(`${value}T00:00:00Z`).toISOString().slice(0, 10) === value;
15
18
 
19
+ function visibleHtmlText(html) {
20
+ const document = parseHtml(String(html || ''));
21
+ for (const node of document.querySelectorAll('script,style')) node.remove();
22
+ return document.textContent.replace(/\s+/g, ' ').trim();
23
+ }
24
+
16
25
  function canonicalReview(raw, targetOrigin) {
17
26
  const citations = raw.citations || [];
18
27
  return citations.map((citation, index) => {
@@ -31,6 +40,7 @@ function canonicalReview(raw, targetOrigin) {
31
40
  }
32
41
 
33
42
  async function observeRender(root, options) {
43
+ if (options.input) return observeBrowserPlan(root, options);
34
44
  if (!options.target || !/^https?:\/\//.test(options.target)) throw new Error('render requires --target <http(s) URL>');
35
45
  const profileNames = ['desktop', 'mobile', 'javascript_disabled'];
36
46
  let reused = [], previousRaw = null;
@@ -74,7 +84,7 @@ async function observeRender(root, options) {
74
84
  };
75
85
  }
76
86
  const initial = await (options.fetchUrl || fetchUrl)(options.target, { timeoutMs: options.timeout || 30000, maxRetries: 1 });
77
- const initialText = initial.body.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gi, ' ').replace(/<style\b[^>]*>[\s\S]*?<\/style>/gi, ' ').replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim();
87
+ const initialText = visibleHtmlText(initial.body);
78
88
  const observations = [...reused], artifacts = { 'initial/response.html': initial.body }, incomplete = [];
79
89
  const profiles = [{ name: 'desktop', viewport: { width: 1280, height: 900 } }, { name: 'mobile', viewport: { width: 390, height: 844 }, settings: { isMobile: true } }, { name: 'javascript_disabled', viewport: { width: 1280, height: 900 }, settings: { javaScriptEnabled: false } }];
80
90
  for (const profile of profiles.filter((item) => !reused.some((old) => old.data.profile === item.name))) {
@@ -369,6 +379,77 @@ function observeCorroboration(root, options) {
369
379
  return observationRun(root, 'observe corroboration', input.file, observations, { rawInputs: { corroboration_export: input.raw } });
370
380
  }
371
381
 
382
+ async function observeRepresentation(root, options) {
383
+ const input = readInput(options.input);
384
+ const manifest = input.value;
385
+ const integrity = verifyManifestIntegrity(manifest);
386
+ if (!integrity.ok) throw new Error(`release manifest is invalid: ${integrity.failures.join('; ')}`);
387
+ if (!options.target) throw new Error('representation observation requires --target <controlled surface URL>');
388
+ const surface = manifest.controlled_surfaces.find((item) => item.url === options.target || item.surface_id === options.surfaceId);
389
+ if (!surface) throw new Error('target is not a controlled surface in the release manifest');
390
+ const expected = manifest.projections.find((item) => item.projection_id === surface.projection_id);
391
+ if (!expected) throw new Error(`expected projection ${surface.projection_id} is missing`);
392
+ const collector = options.fetchUrl || fetchUrl;
393
+ const paths = [
394
+ { path: 'direct', url: surface.url },
395
+ { path: 'cache_busted', url: `${surface.url}${surface.url.includes('?') ? '&' : '?'}citable_manifest=${manifest.manifest_hash.slice(0, 16)}` },
396
+ ];
397
+ const observations = [];
398
+ const artifacts = {};
399
+ const incomplete = [];
400
+ for (const item of paths) {
401
+ try {
402
+ const response = await collector(item.url, { userAgent: options.userAgent || 'CitableRepresentationProbe/1.0', maxRetries: 1 });
403
+ const responseHash = sha256(response.body);
404
+ const observedProjectionHash = surface.verification_method === 'exact_response_body'
405
+ ? responseHash
406
+ : response.headers?.[surface.verification_header] || null;
407
+ const representationState = response.status >= 200 && response.status < 300
408
+ ? !observedProjectionHash ? 'insufficient_evidence' : observedProjectionHash === expected.sha256 ? 'consistent' : 'divergent'
409
+ : response.status === 403 || response.status === 429 ? 'challenged' : 'failed';
410
+ const data = {
411
+ release_id: manifest.release_id,
412
+ manifest_hash: manifest.manifest_hash,
413
+ surface_id: surface.surface_id,
414
+ projection_id: expected.projection_id,
415
+ retrieval_path: item.path,
416
+ requested_url: item.url,
417
+ final_url: response.url,
418
+ status: response.status,
419
+ redirect_chain: response.redirectChain || [],
420
+ headers: response.headers || {},
421
+ verification_method: surface.verification_method,
422
+ verification_header: surface.verification_header,
423
+ expected_projection_hash: expected.sha256,
424
+ observed_projection_hash: observedProjectionHash,
425
+ observed_response_hash: responseHash,
426
+ representation_state: representationState,
427
+ authority_label: 'external_unverified',
428
+ gates_release_finalization: false,
429
+ request_identity: options.userAgent || 'CitableRepresentationProbe/1.0',
430
+ region: options.region || 'local_unspecified',
431
+ };
432
+ observations.push(envelope('representation_drift', data, {
433
+ method: 'synthetic_fetch', source: item.url, raw: response.body,
434
+ confidence: 'confirmed',
435
+ limitations: ['One synthetic retrieval does not represent all caches, indexes, products, accounts, geographies, or users.'],
436
+ authority: { source_authority: 'unknown', collection_authority: 'synthetic_probe', authenticity_status: 'unverified', representativeness: 'single_observation' },
437
+ }));
438
+ artifacts[`representation/${item.path}-response.txt`] = response.body;
439
+ artifacts[`representation/${item.path}-headers.json`] = response.headers || {};
440
+ } catch (error) {
441
+ incomplete.push(`${item.path} representation retrieval failed: ${error.message}`);
442
+ observations.push(envelope('representation_drift', {
443
+ release_id: manifest.release_id, manifest_hash: manifest.manifest_hash, surface_id: surface.surface_id,
444
+ projection_id: expected.projection_id, retrieval_path: item.path, requested_url: item.url,
445
+ representation_state: 'failed', authority_label: 'external_unverified', gates_release_finalization: false,
446
+ request_identity: options.userAgent || 'CitableRepresentationProbe/1.0', region: options.region || 'local_unspecified',
447
+ }, { method: 'synthetic_fetch', source: item.url, state: 'failed', confidence: 'confirmed', raw: error.message, limitations: [error.message], authority: { source_authority: 'unknown', collection_authority: 'synthetic_probe', authenticity_status: 'unverified', representativeness: 'single_observation' } }));
448
+ }
449
+ }
450
+ return observationRun(root, 'observe representation', surface.url, observations, { rawInputs: { release_manifest: input.raw }, incomplete, artifacts });
451
+ }
452
+
372
453
  export async function observe(root, mode, options = {}) {
373
454
  switch (mode) {
374
455
  case 'render': return observeRender(root, options);
@@ -381,6 +462,7 @@ export async function observe(root, mode, options = {}) {
381
462
  case 'performance': return observePerformance(root, options);
382
463
  case 'corroboration': return observeCorroboration(root, options);
383
464
  case 'media': return observeMedia(root, options);
384
- default: throw new Error('observe mode must be render, index, citations, logs, bing, passages, consensus, performance, corroboration, or media');
465
+ case 'representation': return observeRepresentation(root, options);
466
+ default: throw new Error('observe mode must be render, index, citations, logs, bing, passages, consensus, performance, corroboration, media, or representation');
385
467
  }
386
468
  }