@nebulacomponents/citable 1.12.0 → 1.13.1

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 +163 -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,322 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { createRun } from '../evidence/run.js';
4
+ import { canonicalJson } from '../release/governance.js';
5
+ import { nowIso, readJson, sha256, writeJson } from '../shared/io.js';
6
+ import { validateAgainst } from '../shared/schemaValidator.js';
7
+
8
+ const PUBLICATION_LEVELS = new Set(['sanitized_artifacts', 'public_artifacts']);
9
+ const SECRET_PATTERNS = [
10
+ /-----BEGIN [A-Z ]*PRIVATE KEY-----/,
11
+ /\bBearer\s+[A-Za-z0-9._~+/-]{16,}={0,2}\b/i,
12
+ /\b(?:ghp|github_pat|npm)_[A-Za-z0-9_]{16,}\b/,
13
+ /\bAIza[0-9A-Za-z_-]{20,}\b/,
14
+ /\b(?:api[_-]?key|access[_-]?token|client[_-]?secret|password)\s*[:=]\s*[^\s,}]{8,}/i,
15
+ /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/i,
16
+ ];
17
+
18
+ function ratio(numerator, denominator) {
19
+ return denominator ? numerator / denominator : null;
20
+ }
21
+
22
+ function percentile(values, percentileValue) {
23
+ if (!values.length) return null;
24
+ const ordered = [...values].sort((a, b) => a - b);
25
+ return ordered[Math.ceil((percentileValue / 100) * ordered.length) - 1];
26
+ }
27
+
28
+ function confusion(cases) {
29
+ const result = { true_positive: 0, false_positive: 0, true_negative: 0, false_negative: 0, incomplete: 0 };
30
+ for (const item of cases) {
31
+ if (item.observed === 'incomplete') result.incomplete += 1;
32
+ else if (item.expected === 'detection' && item.observed === 'detected') result.true_positive += 1;
33
+ else if (item.expected === 'detection') result.false_negative += 1;
34
+ else if (item.observed === 'detected') result.false_positive += 1;
35
+ else result.true_negative += 1;
36
+ }
37
+ const evaluated = result.true_positive + result.false_positive + result.true_negative + result.false_negative;
38
+ return {
39
+ ...result,
40
+ evaluated,
41
+ precision: ratio(result.true_positive, result.true_positive + result.false_positive),
42
+ recall: ratio(result.true_positive, result.true_positive + result.false_negative),
43
+ false_positive_rate: ratio(result.false_positive, result.false_positive + result.true_negative),
44
+ discovered_false_negative_rate: ratio(result.false_negative, result.true_positive + result.false_negative),
45
+ incomplete_rate: ratio(result.incomplete, cases.length),
46
+ };
47
+ }
48
+
49
+ function metric(value, numerator, denominator, population, exclusions, confidenceLimitations) {
50
+ return { value, numerator, denominator, population, exclusions, confidence_limitations: confidenceLimitations };
51
+ }
52
+
53
+ function pct(value) {
54
+ return value == null ? 'not established' : `${(value * 100).toFixed(1)}%`;
55
+ }
56
+
57
+ export function renderCorpusMetrics(metrics) {
58
+ const lines = [
59
+ `# Field validation metrics: ${metrics.corpus_id}`,
60
+ '',
61
+ `- Corpus version: ${metrics.version}`,
62
+ `- Corpus hash: ${metrics.provenance.corpus_hash}`,
63
+ `- Collection window: ${metrics.provenance.collection_started_at} to ${metrics.provenance.collection_ended_at}`,
64
+ `- Evaluation design: ${metrics.evaluation_design.mode}`,
65
+ `- Properties: ${metrics.population.properties}; detector cases: ${metrics.population.detector_cases}`,
66
+ `- Detector versions: ${metrics.detector_versions.versions.join(', ') || 'none'}${metrics.detector_versions.mixed_versions ? ' (mixed)' : ''}`,
67
+ '',
68
+ '## Results',
69
+ '',
70
+ `- Detector precision: ${pct(metrics.metric_definitions.detector_precision.value)} (${metrics.metric_definitions.detector_precision.numerator}/${metrics.metric_definitions.detector_precision.denominator})`,
71
+ `- Discovered false-negative rate: ${pct(metrics.metric_definitions.discovered_false_negative_rate.value)} (${metrics.metric_definitions.discovered_false_negative_rate.numerator}/${metrics.metric_definitions.discovered_false_negative_rate.denominator})`,
72
+ `- Reviewer exact agreement: ${pct(metrics.metric_definitions.reviewer_exact_agreement.value)}`,
73
+ `- Run reproducibility: ${pct(metrics.metric_definitions.run_reproducibility.value)}`,
74
+ `- Incomplete-evidence rate: ${pct(metrics.metric_definitions.incomplete_evidence_rate.value)}`,
75
+ `- Remediation verification success: ${pct(metrics.metric_definitions.remediation_verification_success.value)}`,
76
+ '',
77
+ '## Boundaries',
78
+ '',
79
+ `- Unknown false negatives: ${metrics.unknown_false_negatives.status}. ${metrics.unknown_false_negatives.reason}`,
80
+ ...metrics.evaluation_design.extrapolation_limits.map((item) => `- ${item}`),
81
+ ...metrics.false_negative_discovery_limitations.map((item) => `- ${item}`),
82
+ ...metrics.causal_limitations.map((item) => `- ${item}`),
83
+ ...metrics.limitations.map((item) => `- ${item}`),
84
+ '',
85
+ `Metrics hash: ${metrics.metrics_hash}`,
86
+ '',
87
+ ];
88
+ return lines.join('\n');
89
+ }
90
+
91
+ export function verifyFieldValidationMetrics(metrics) {
92
+ const check = validateAgainst('field-validation-metrics.schema.json', metrics);
93
+ const failures = check.valid ? [] : [...check.errors];
94
+ const expected = sha256(canonicalJson({ ...metrics, metrics_hash: '' }));
95
+ if (metrics.metrics_hash !== expected) failures.push('field-validation metrics hash is inconsistent');
96
+ return { valid: failures.length === 0, failures };
97
+ }
98
+
99
+ function propertyRefs(corpus, propertyId) {
100
+ const property = corpus.properties.find((item) => item.property_id === propertyId);
101
+ const refs = [
102
+ ...property.evidence_package_refs,
103
+ property.authorization.evidence_ref,
104
+ property.sanitization.evidence_ref,
105
+ ];
106
+ for (const item of corpus.detector_cases.filter((entry) => entry.property_id === propertyId)) refs.push(...item.evidence_refs);
107
+ for (const item of corpus.semantic_reviews.filter((entry) => entry.property_id === propertyId)) refs.push(...item.evidence_refs, ...item.reviewer_assignment_refs, ...item.disagreement_refs);
108
+ for (const item of corpus.executions.filter((entry) => entry.property_id === propertyId)) {
109
+ refs.push(...item.raw_artifact_refs, ...item.deterministic_finding_refs, ...item.heuristic_finding_refs, ...item.reviewer_assignment_refs, ...item.disagreement_refs, ...item.exception_refs, ...item.intervention_refs, ...item.verification_refs, item.reproducibility_receipt_ref);
110
+ }
111
+ for (const item of corpus.remediation_verifications.filter((entry) => entry.property_id === propertyId)) refs.push(...item.evidence_refs);
112
+ return [...new Set(refs.filter(Boolean))].sort();
113
+ }
114
+
115
+ function safeArtifactRef(ref) {
116
+ return typeof ref === 'string' && ref.length > 0 && !path.isAbsolute(ref) && !ref.includes('\\') && !ref.split('/').includes('..') && !/^[a-z][a-z0-9+.-]*:/i.test(ref);
117
+ }
118
+
119
+ export function validateCorpusData(corpus, { forPublication = false, at = new Date() } = {}) {
120
+ const check = validateAgainst('acceptance-corpus.schema.json', corpus);
121
+ if (!check.valid) throw new Error(`acceptance corpus violates contract: ${check.errors.join('; ')}`);
122
+ const propertyIds = new Set(corpus.properties.map((item) => item.property_id));
123
+ if (propertyIds.size !== corpus.properties.length) throw new Error('acceptance corpus contains duplicate property ids');
124
+ const unknown = [
125
+ ...corpus.detector_cases.map((item) => item.property_id),
126
+ ...corpus.semantic_reviews.map((item) => item.property_id),
127
+ ...corpus.executions.map((item) => item.property_id),
128
+ ...corpus.remediation_verifications.map((item) => item.property_id),
129
+ ].filter((id) => !propertyIds.has(id));
130
+ if (unknown.length) throw new Error(`acceptance corpus references unknown properties: ${[...new Set(unknown)].join(', ')}`);
131
+ if (!corpus.properties.some((item) => item.intentionally_incomplete || ['observed', 'unresolved'].includes(item.contradiction_status))) {
132
+ throw new Error('acceptance corpus requires at least one intentionally incomplete or contradictory property');
133
+ }
134
+ const design = corpus.evaluation_design;
135
+ if (new Date(design.collection_ended_at) < new Date(design.collection_started_at)) throw new Error('acceptance corpus collection window ends before it starts');
136
+ if (design.mode === 'sample' && !design.sampling_plan_ref) throw new Error('sample evaluation requires a sampling plan reference');
137
+ if (design.mode === 'census' && design.sampling_plan_ref) throw new Error('census evaluation cannot claim a sampling plan reference');
138
+ if (forPublication) {
139
+ if (SECRET_PATTERNS.some((pattern) => pattern.test(JSON.stringify(corpus)))) throw new Error('public corpus contains credential or personal-data patterns');
140
+ if (new Date(corpus.created_at) > at) throw new Error('public corpus creation timestamp is in the future');
141
+ if (new Date(design.collection_ended_at) > at) throw new Error('public corpus collection window ends in the future');
142
+ for (const property of corpus.properties) {
143
+ if (!PUBLICATION_LEVELS.has(property.publication.level)) throw new Error(`${property.property_id} publication level ${property.publication.level} cannot enter a public corpus`);
144
+ const requiredScopes = ['collect', 'retain', 'review', 'publish_artifacts'];
145
+ const missingScopes = requiredScopes.filter((scope) => !property.authorization.scope.includes(scope));
146
+ if (missingScopes.length) throw new Error(`${property.property_id} authorization lacks required scopes: ${missingScopes.join(', ')}`);
147
+ if (property.authorization.expires_at && new Date(property.authorization.expires_at) <= at) throw new Error(`${property.property_id} owner authorization is expired`);
148
+ if (!property.publication.approved_by || !property.publication.approved_at) throw new Error(`${property.property_id} lacks publication approval`);
149
+ const sanitization = property.sanitization;
150
+ if (!sanitization.reviewed_by || !sanitization.reviewed_at || !sanitization.evidence_ref || sanitization.pii_status === 'not_reviewed' || sanitization.credential_status === 'not_reviewed' || sanitization.source_identifiers === 'not_reviewed') throw new Error(`${property.property_id} lacks completed sanitization review`);
151
+ const futureEvents = [property.authorization.authorized_at, property.publication.approved_at, sanitization.reviewed_at, ...property.collection_methods.map((item) => item.collected_at)].filter((timestamp) => new Date(timestamp) > at);
152
+ if (futureEvents.length) throw new Error(`${property.property_id} contains future-dated authorization, collection, sanitization, or approval evidence`);
153
+ const refs = propertyRefs(corpus, property.property_id);
154
+ const unsafe = [...new Set([...refs, ...property.publication.allowed_artifact_refs].filter((ref) => !safeArtifactRef(ref)))];
155
+ if (unsafe.length) throw new Error(`${property.property_id} contains unsafe artifact references: ${unsafe.join(', ')}`);
156
+ const allowed = new Set(property.publication.allowed_artifact_refs);
157
+ const unapproved = refs.filter((ref) => !allowed.has(ref));
158
+ if (unapproved.length) throw new Error(`${property.property_id} contains artifact references not approved for publication: ${unapproved.join(', ')}`);
159
+ }
160
+ }
161
+ return { valid: true, property_ids: [...propertyIds], publishable: forPublication };
162
+ }
163
+
164
+ export function evaluateCorpusData(corpus) {
165
+ validateCorpusData(corpus);
166
+ const namespaces = {};
167
+ for (const namespace of [...new Set(corpus.detector_cases.map((item) => item.namespace))].sort()) {
168
+ namespaces[namespace] = confusion(corpus.detector_cases.filter((item) => item.namespace === namespace));
169
+ }
170
+ const reviewable = corpus.semantic_reviews.filter((item) => item.reviewer_verdicts.length >= 2);
171
+ const agreeing = reviewable.filter((item) => new Set(item.reviewer_verdicts).size === 1).length;
172
+ const executions = corpus.executions;
173
+ const remediationComplete = corpus.remediation_verifications.filter((item) => item.status !== 'incomplete');
174
+ const overall = confusion(corpus.detector_cases);
175
+ const versions = [...new Set(corpus.detector_cases.map((item) => item.detector_version))].sort();
176
+ const casesByVersion = Object.fromEntries(versions.map((version) => [version, confusion(corpus.detector_cases.filter((item) => item.detector_version === version))]));
177
+ const exactAgreementRate = ratio(agreeing, reviewable.length);
178
+ const adjudicated = reviewable.filter((item) => item.adjudicated).length;
179
+ const reproducible = executions.filter((item) => item.reproducible).length;
180
+ const incompleteExecutions = executions.filter((item) => item.incomplete).length;
181
+ const verifiedRemediations = remediationComplete.filter((item) => item.status === 'verified').length;
182
+ const metrics = {
183
+ schema_version: 1,
184
+ corpus_id: corpus.corpus_id,
185
+ version: corpus.version,
186
+ provenance: { corpus_hash: sha256(canonicalJson(corpus)), corpus_created_at: corpus.created_at, collection_started_at: corpus.evaluation_design.collection_started_at, collection_ended_at: corpus.evaluation_design.collection_ended_at },
187
+ evaluation_design: corpus.evaluation_design,
188
+ population: {
189
+ properties: corpus.properties.length,
190
+ detector_cases: corpus.detector_cases.length,
191
+ semantic_reviews: corpus.semantic_reviews.length,
192
+ executions: executions.length,
193
+ remediation_verifications: corpus.remediation_verifications.length,
194
+ },
195
+ detector_versions: { versions, mixed_versions: versions.length > 1, cases_by_version: casesByVersion },
196
+ detector_accuracy: { overall, by_namespace: namespaces },
197
+ reviewer_metrics: {
198
+ reviewable_items: reviewable.length,
199
+ exact_agreement_items: agreeing,
200
+ exact_agreement_rate: exactAgreementRate,
201
+ adjudicated_items: adjudicated,
202
+ adjudication_rate: ratio(adjudicated, reviewable.length),
203
+ },
204
+ execution_metrics: {
205
+ average_runtime_ms: ratio(executions.reduce((sum, item) => sum + item.runtime_ms, 0), executions.length),
206
+ p95_runtime_ms: percentile(executions.map((item) => item.runtime_ms), 95),
207
+ peak_memory_bytes: executions.length ? Math.max(...executions.map((item) => item.peak_memory_bytes)) : null,
208
+ evidence_storage_bytes: executions.reduce((sum, item) => sum + item.evidence_bytes, 0),
209
+ reproducibility_rate: ratio(reproducible, executions.length),
210
+ incomplete_evidence_rate: ratio(incompleteExecutions, executions.length),
211
+ },
212
+ remediation_metrics: {
213
+ evaluated: remediationComplete.length,
214
+ verified: verifiedRemediations,
215
+ verification_success_rate: ratio(verifiedRemediations, remediationComplete.length),
216
+ incomplete: corpus.remediation_verifications.filter((item) => item.status === 'incomplete').length,
217
+ },
218
+ metric_definitions: {
219
+ detector_precision: metric(overall.precision, overall.true_positive, overall.true_positive + overall.false_positive, 'Adjudicated detector cases with detected outcomes.', ['Incomplete cases and non-detected outcomes.'], ['Precision applies only to the disclosed expected-case population.']),
220
+ discovered_false_negative_rate: metric(overall.discovered_false_negative_rate, overall.false_negative, overall.true_positive + overall.false_negative, 'Adjudicated cases expected to produce a detection.', ['Unknown and incomplete expected detections.'], corpus.false_negative_discovery_limitations),
221
+ false_positive_rate: metric(overall.false_positive_rate, overall.false_positive, overall.false_positive + overall.true_negative, 'Adjudicated cases expected not to produce a detection.', ['Incomplete cases and expected detections.'], ['Rate applies only to represented non-detection cases.']),
222
+ reviewer_exact_agreement: metric(exactAgreementRate, agreeing, reviewable.length, 'Semantic reviews with at least two verdicts.', ['Reviews with fewer than two verdicts.'], ['Exact agreement does not establish reviewer correctness.']),
223
+ adjudication_rate: metric(ratio(adjudicated, reviewable.length), adjudicated, reviewable.length, 'Semantic reviews with at least two verdicts.', ['Reviews with fewer than two verdicts.'], ['Adjudication rate describes workflow, not semantic accuracy.']),
224
+ average_runtime_ms: metric(ratio(executions.reduce((sum, item) => sum + item.runtime_ms, 0), executions.length), executions.reduce((sum, item) => sum + item.runtime_ms, 0), executions.length, 'Recorded corpus executions.', [], ['Runtime depends on disclosed execution environments.']),
225
+ p95_runtime_ms: metric(percentile(executions.map((item) => item.runtime_ms), 95), null, executions.length, 'Recorded corpus executions.', [], ['Nearest-rank p95 is unstable for small populations.']),
226
+ peak_memory_bytes: metric(executions.length ? Math.max(...executions.map((item) => item.peak_memory_bytes)) : null, null, executions.length, 'Recorded corpus executions.', [], ['Peak memory is the maximum owner-reported execution value.']),
227
+ evidence_storage_bytes: metric(executions.reduce((sum, item) => sum + item.evidence_bytes, 0), executions.reduce((sum, item) => sum + item.evidence_bytes, 0), executions.length, 'Recorded corpus executions.', [], ['Storage excludes unavailable or undisclosed evidence.']),
228
+ run_reproducibility: metric(ratio(reproducible, executions.length), reproducible, executions.length, 'Recorded corpus executions.', [], ['Reproducibility is bounded by each run receipt and declared exclusions.']),
229
+ incomplete_evidence_rate: metric(ratio(incompleteExecutions, executions.length), incompleteExecutions, executions.length, 'Recorded corpus executions.', [], ['Incomplete status depends on declared unavailable evidence.']),
230
+ remediation_verification_success: metric(ratio(verifiedRemediations, remediationComplete.length), verifiedRemediations, remediationComplete.length, 'Remediation verifications with a completed verdict.', ['Incomplete verifications.'], ['Verification does not establish external outcome causation.']),
231
+ },
232
+ unknown_false_negatives: { status: 'not_quantified', reason: 'Cases absent from the disclosed and adjudicated expected-detection population cannot be counted.' },
233
+ false_negative_discovery_limitations: corpus.false_negative_discovery_limitations,
234
+ causal_limitations: corpus.causal_limitations,
235
+ limitations: corpus.limitations,
236
+ metrics_hash: '',
237
+ };
238
+ metrics.metrics_hash = sha256(canonicalJson(metrics));
239
+ const check = validateAgainst('field-validation-metrics.schema.json', metrics);
240
+ if (!check.valid) throw new Error(`field-validation metrics violate contract: ${check.errors.join('; ')}`);
241
+ return metrics;
242
+ }
243
+
244
+ export function publishCorpus(root, { input, output, at = nowIso() }) {
245
+ if (!input || !fs.existsSync(input)) throw new Error('corpus publish requires --input <json>');
246
+ if (!output) throw new Error('corpus publish requires --output <json>');
247
+ const plannedOutputs = [output, `${output}.metrics.json`, `${output}.metrics.md`, `${output}.receipt.json`];
248
+ const existingOutput = plannedOutputs.find((file) => fs.existsSync(file));
249
+ if (existingOutput) throw new Error(`corpus publish refuses to overwrite ${existingOutput}`);
250
+ const raw = fs.readFileSync(input, 'utf8');
251
+ const corpus = readJson(input);
252
+ validateCorpusData(corpus, { forPublication: true, at: new Date(at) });
253
+ const published = `${JSON.stringify(corpus, null, 2)}\n`;
254
+ const metrics = evaluateCorpusData(corpus);
255
+ const metricsJson = `${JSON.stringify(metrics, null, 2)}\n`;
256
+ const metricsMarkdown = renderCorpusMetrics(metrics);
257
+ const receipt = {
258
+ schema_version: 1,
259
+ receipt_id: `CORPUS-PUBLICATION-${sha256(`${corpus.corpus_id}:${sha256(published)}:${at}`).slice(0, 20).toUpperCase()}`,
260
+ corpus_id: corpus.corpus_id,
261
+ corpus_version: corpus.version,
262
+ source_hash: sha256(raw),
263
+ published_hash: sha256(published),
264
+ metrics_json_hash: sha256(metricsJson),
265
+ metrics_markdown_hash: sha256(metricsMarkdown),
266
+ property_ids: corpus.properties.map((item) => item.property_id).sort(),
267
+ publication_levels: [...new Set(corpus.properties.map((item) => item.publication.level))].sort(),
268
+ generated_at: at,
269
+ authority: 'owner_authorized_publication_projection',
270
+ limitations: [
271
+ 'Publication receipt records publisher-controlled approval and projection integrity, not independent validation.',
272
+ 'Automated pattern checks supplement but do not replace the recorded human sanitization review.',
273
+ ],
274
+ };
275
+ receipt.receipt_hash = sha256(canonicalJson(receipt));
276
+ const receiptCheck = validateAgainst('corpus-publication-receipt.schema.json', receipt);
277
+ if (!receiptCheck.valid) throw new Error(`corpus publication receipt violates contract: ${receiptCheck.errors.join('; ')}`);
278
+ const receiptFile = `${output}.receipt.json`;
279
+ const metricsFile = `${output}.metrics.json`;
280
+ const reportFile = `${output}.metrics.md`;
281
+ writeJson(output, corpus);
282
+ writeJson(metricsFile, metrics);
283
+ fs.writeFileSync(reportFile, metricsMarkdown);
284
+ writeJson(receiptFile, receipt);
285
+ const run = createRun(root, { command: 'corpus publish', argv: process.argv.slice(2), target: { kind: 'source', location: path.resolve(input), environment: 'local' } });
286
+ run.addInput('acceptance_corpus', raw);
287
+ run.writeArtifact('published-corpus.json', corpus);
288
+ run.writeArtifact('accuracy-metrics.json', metrics);
289
+ run.writeArtifact('accuracy-metrics.md', metricsMarkdown);
290
+ run.writeArtifact('publication-receipt.json', receipt);
291
+ run.manifest.warnings.push('Publication is owner-authorized and sanitization-reviewed but is not independently attested.');
292
+ return { runId: run.runId, dir: run.finalize('completed'), output, metricsFile, reportFile, receiptFile, receipt, metrics };
293
+ }
294
+
295
+ export function verifyCorpusPublicationReceipt(receipt, publishedCorpus, { metrics = null, report = null } = {}) {
296
+ const check = validateAgainst('corpus-publication-receipt.schema.json', receipt);
297
+ const failures = check.valid ? [] : [...check.errors];
298
+ const { receipt_hash: ignored, ...unsigned } = receipt;
299
+ if (receipt.receipt_hash !== sha256(canonicalJson(unsigned))) failures.push('publication receipt hash is inconsistent');
300
+ const published = typeof publishedCorpus === 'string' ? publishedCorpus : `${JSON.stringify(publishedCorpus, null, 2)}\n`;
301
+ if (receipt.published_hash !== sha256(published)) failures.push('published corpus hash is inconsistent');
302
+ if (metrics != null) {
303
+ const metricsJson = typeof metrics === 'string' ? metrics : `${JSON.stringify(metrics, null, 2)}\n`;
304
+ if (receipt.metrics_json_hash !== sha256(metricsJson)) failures.push('published metrics JSON hash is inconsistent');
305
+ }
306
+ if (report != null && receipt.metrics_markdown_hash !== sha256(report)) failures.push('published metrics Markdown hash is inconsistent');
307
+ return { valid: failures.length === 0, failures };
308
+ }
309
+
310
+ export function evaluateCorpus(root, { input }) {
311
+ if (!input || !fs.existsSync(input)) throw new Error('corpus evaluate requires --input <json>');
312
+ const raw = fs.readFileSync(input, 'utf8');
313
+ const corpus = readJson(input);
314
+ const metrics = evaluateCorpusData(corpus);
315
+ const run = createRun(root, { command: 'corpus evaluate', argv: process.argv.slice(2), target: { kind: 'source', location: path.resolve(input), environment: 'local' } });
316
+ run.addInput('acceptance_corpus', raw);
317
+ run.writeArtifact('corpus.json', corpus);
318
+ run.writeArtifact('accuracy-metrics.json', metrics);
319
+ run.writeArtifact('accuracy-metrics.md', renderCorpusMetrics(metrics));
320
+ run.manifest.warnings.push('Metrics describe only the disclosed corpus population and do not establish performance on untested properties.');
321
+ return { runId: run.runId, dir: run.finalize('completed'), metrics };
322
+ }
@@ -0,0 +1,202 @@
1
+ /**
2
+ * decision-memo command — Bounded Executive Decision Record
3
+ *
4
+ * Treats decision-making as a controlled process, not document formatting.
5
+ * Enforces:
6
+ * - One decision per memo
7
+ * - Named decider + named consulted parties
8
+ * - Deadline required
9
+ * - Reversibility classification
10
+ * - Real trade-offs (no strawman options)
11
+ * - "What would change my mind" is a required high-trust section
12
+ * - Specific evidence required — no performative uncertainty
13
+ *
14
+ * Usage:
15
+ * citable decision-memo list [--status open|decided|deferred]
16
+ * citable decision-memo show <decision_id>
17
+ * citable decision-memo validate
18
+ * citable decision-memo new --title "..." [--from-json <file>]
19
+ */
20
+ import { contextDir, loadRegistryFile, registryLoadProblems, saveRegistry } from '../registries/index.js';
21
+ import { validateAgainst } from '../shared/schemaValidator.js';
22
+ import path from 'node:path';
23
+ import fs from 'node:fs';
24
+ import { dateOnly, parseAsOf } from '../shared/asOf.js';
25
+
26
+ export async function decisionMemoCommand(args, root = process.cwd()) {
27
+ const [subcommand, ...rest] = args;
28
+ const file = path.join(contextDir(root), 'decisions.yaml');
29
+
30
+ switch (subcommand) {
31
+ case 'show': return decisionShow(file, rest[0]);
32
+ case 'validate': return decisionValidate(file, rest);
33
+ case 'new': return decisionNew(file, rest, root);
34
+ case 'list':
35
+ default: {
36
+ const statusFilter = rest[rest.indexOf('--status') + 1] ?? null;
37
+ return decisionList(file, statusFilter);
38
+ }
39
+ }
40
+ }
41
+
42
+ function load(file) {
43
+ return loadRegistryFile(file, 'decisions');
44
+ }
45
+
46
+ function decisionList(file, statusFilter) {
47
+ const data = load(file);
48
+ let entries = statusFilter ? data.entries.filter(d => d.status === statusFilter) : data.entries;
49
+ return {
50
+ decisions: entries.map(d => ({
51
+ decision_id: d.decision_id,
52
+ title: d.title,
53
+ owner: d.owner,
54
+ deadline: d.deadline,
55
+ reversibility: d.reversibility,
56
+ status: d.status,
57
+ options_count: (d.options ?? []).length,
58
+ })),
59
+ total: entries.length,
60
+ };
61
+ }
62
+
63
+ function decisionShow(file, id) {
64
+ if (!id) return { error: 'decision_id required' };
65
+ const data = load(file);
66
+ const d = data.entries.find(e => e.decision_id === id);
67
+ if (!d) return { error: `Decision not found: ${id}` };
68
+ // Format as memo
69
+ return {
70
+ memo: {
71
+ id: d.decision_id,
72
+ title: d.title,
73
+ decision_needed: d.title,
74
+ recommendation: d.recommendation ?? 'NOT SET',
75
+ owner: d.owner,
76
+ consulted: d.consulted ?? [],
77
+ deadline: d.deadline,
78
+ reversibility: d.reversibility,
79
+ options: d.options ?? [],
80
+ what_would_change_recommendation: d.what_would_change_recommendation ?? [],
81
+ cost_of_delay: d.cost_of_delay ?? 'NOT SET',
82
+ supporting_evidence: d.supporting_evidence ?? [],
83
+ contradicting_evidence: d.contradicting_evidence ?? [],
84
+ assumptions: d.assumptions ?? [],
85
+ reopen_conditions: d.reopen_conditions ?? [],
86
+ legal_review: d.legal_review,
87
+ security_review: d.security_review,
88
+ financial_model: d.financial_model,
89
+ status: d.status,
90
+ },
91
+ };
92
+ }
93
+
94
+ function decisionValidate(file, args = []) {
95
+ const data = load(file);
96
+ const problems = [...registryLoadProblems(data)];
97
+ const { valid, errors } = validateAgainst('decision.schema.json', data);
98
+ if (!valid) problems.push(...errors);
99
+
100
+ // Reference date for deadline staleness — deterministic when --as-of provided
101
+ const refDate = parseAsOf(args);
102
+
103
+ for (const d of data.entries) {
104
+ // Named consulted parties required
105
+ if (!d.consulted || d.consulted.length === 0)
106
+ problems.push(`${d.decision_id}: consulted parties must be named — autonomous decisions without consultation are not accepted`);
107
+
108
+ // What would change recommendation is required (high-trust section)
109
+ if (!d.what_would_change_recommendation || d.what_would_change_recommendation.length === 0)
110
+ problems.push(`${d.decision_id}: what_would_change_recommendation is required — state specific evidence that would change the recommendation`);
111
+
112
+ // Options must have real trade-offs (not strawmen)
113
+ for (const opt of d.options ?? []) {
114
+ if (!opt.trade_offs || opt.trade_offs.length === 0)
115
+ problems.push(`${d.decision_id} option "${opt.label}": trade_offs required — no strawman options`);
116
+ }
117
+
118
+ // Supporting evidence must be specific
119
+ if (!d.supporting_evidence || d.supporting_evidence.length === 0)
120
+ problems.push(`${d.decision_id}: supporting_evidence required — performative uncertainty is not accepted`);
121
+
122
+ // Deadline validation against reference date (not wall clock)
123
+ if (d.deadline && new Date(d.deadline) < refDate && d.status === 'open')
124
+ problems.push(`${d.decision_id}: deadline ${d.deadline} is past (as-of ${refDate.toISOString().slice(0,10)}) but status is still "open"`);
125
+
126
+ // One-way decisions need reopen conditions
127
+ if (d.reversibility === 'effectively_one_way' && (!d.reopen_conditions || d.reopen_conditions.length === 0))
128
+ problems.push(`${d.decision_id}: effectively_one_way decision requires reopen_conditions`);
129
+ }
130
+
131
+ return { valid: problems.length === 0, problems, checked: data.entries.length, as_of: dateOnly(refDate) };
132
+ }
133
+
134
+ async function decisionNew(file, args, root) {
135
+ const titleIndex = args.indexOf('--title');
136
+ const title = titleIndex >= 0 ? args[titleIndex + 1] : undefined;
137
+ if (!title) return { error: '--title required' };
138
+ const write = args.includes('--write');
139
+
140
+ const data = load(file);
141
+ const maxSequence = data.entries.reduce((max, entry) => {
142
+ const match = /^DEC-(\d+)$/.exec(entry.decision_id ?? '');
143
+ return match ? Math.max(max, Number(match[1])) : max;
144
+ }, 0);
145
+ const id = `DEC-${String(maxSequence + 1).padStart(3, '0')}`;
146
+
147
+ // Use schema-valid placeholder values only — never persist enum-violating strings.
148
+ // reversibility enum: reversible | effectively_one_way | one_way
149
+ const stub = {
150
+ decision_id: id,
151
+ title,
152
+ owner: '',
153
+ consulted: [],
154
+ deadline: '',
155
+ reversibility: 'reversible', // valid enum — change to match actual decision
156
+ options: [],
157
+ recommendation: '',
158
+ supporting_evidence: [],
159
+ contradicting_evidence: [],
160
+ assumptions: [],
161
+ what_would_change_recommendation: [],
162
+ cost_of_delay: '',
163
+ reopen_conditions: [],
164
+ status: 'open',
165
+ };
166
+
167
+ // Validate the stub against the schema before any persistence
168
+ const { valid, errors } = validateAgainst('decision.schema.json', {
169
+ version: 1, kind: 'decisions', entries: [stub],
170
+ });
171
+ if (!valid) {
172
+ return { error: 'Stub failed schema validation — this is a bug', schema_errors: errors };
173
+ }
174
+
175
+ if (!write) {
176
+ return {
177
+ preview: true,
178
+ id,
179
+ stub,
180
+ message: 'Dry-run — pass --write to persist. Complete all empty fields before use.',
181
+ required_fields: ['owner','consulted','deadline','recommendation',
182
+ 'supporting_evidence','what_would_change_recommendation','cost_of_delay'],
183
+ reversibility_options: ['reversible','costly_to_reverse','effectively_one_way'],
184
+ };
185
+ }
186
+
187
+ // Persist only when explicitly requested and schema-valid
188
+ data.entries.push(stub);
189
+ const dir = contextDir(root);
190
+ if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
191
+ // Await persistence so success is reported only after a confirmed write.
192
+ saveRegistry(root, 'decisions', data);
193
+
194
+ return {
195
+ created: id,
196
+ file,
197
+ message: 'Decision stub written. Complete all empty fields before use.',
198
+ required_fields: ['owner','consulted','deadline','recommendation',
199
+ 'supporting_evidence','what_would_change_recommendation','cost_of_delay'],
200
+ reversibility_options: ['reversible','costly_to_reverse','effectively_one_way'],
201
+ };
202
+ }