okengine 0.1.4

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 (674) hide show
  1. package/AGENTS.md +91 -0
  2. package/README.md +327 -0
  3. package/docs/spec/complete-example.md +1188 -0
  4. package/docs/spec/console.md +739 -0
  5. package/docs/spec/four-applications.md +1188 -0
  6. package/docs/spec/unified-theory.md +489 -0
  7. package/package.json +152 -0
  8. package/spec/manifest.v1.schema.json +624 -0
  9. package/src/auth/api-keys.ts +168 -0
  10. package/src/auth/attenuation.ts +116 -0
  11. package/src/auth/auth.test.ts +273 -0
  12. package/src/auth/cross-plane.ts +98 -0
  13. package/src/auth/index.ts +112 -0
  14. package/src/auth/invites.ts +66 -0
  15. package/src/auth/invoke-as.ts +49 -0
  16. package/src/auth/operator.ts +178 -0
  17. package/src/auth/planes.ts +102 -0
  18. package/src/auth/plugin.ts +44 -0
  19. package/src/auth/roles.ts +84 -0
  20. package/src/auth/sessions.ts +418 -0
  21. package/src/auth/tables.ts +131 -0
  22. package/src/cli/args.ts +50 -0
  23. package/src/cli/branch.ts +75 -0
  24. package/src/cli/build.ts +86 -0
  25. package/src/cli/client-add.test.ts +140 -0
  26. package/src/cli/client-add.ts +164 -0
  27. package/src/cli/completion.test.ts +58 -0
  28. package/src/cli/completion.ts +296 -0
  29. package/src/cli/dev-app-runner.ts +77 -0
  30. package/src/cli/dev.test.ts +435 -0
  31. package/src/cli/dev.ts +594 -0
  32. package/src/cli/doc-drift.test.ts +146 -0
  33. package/src/cli/doc-drift.ts +397 -0
  34. package/src/cli/docker-cli.test.ts +221 -0
  35. package/src/cli/docker.ts +127 -0
  36. package/src/cli/doctor-diff-examples.ts +92 -0
  37. package/src/cli/doctor-diff.test.ts +91 -0
  38. package/src/cli/doctor-diff.ts +274 -0
  39. package/src/cli/doctor-pii.test.ts +98 -0
  40. package/src/cli/doctor-pii.ts +151 -0
  41. package/src/cli/doctor.test.ts +150 -0
  42. package/src/cli/doctor.ts +223 -0
  43. package/src/cli/eval.ts +122 -0
  44. package/src/cli/exit.ts +19 -0
  45. package/src/cli/gates-list.test.ts +47 -0
  46. package/src/cli/gates-list.ts +84 -0
  47. package/src/cli/images.ts +277 -0
  48. package/src/cli/index.ts +99 -0
  49. package/src/cli/json-out.test.ts +129 -0
  50. package/src/cli/load-config.ts +71 -0
  51. package/src/cli/mcp-from-console.ts +50 -0
  52. package/src/cli/privacy-erase.ts +73 -0
  53. package/src/cli/registry.ts +455 -0
  54. package/src/cli/safe-defaults.test.ts +92 -0
  55. package/src/cli/schema.ts +196 -0
  56. package/src/cli/stack.ts +82 -0
  57. package/src/cli/start.ts +106 -0
  58. package/src/cli/upgrade.ts +105 -0
  59. package/src/cli/vault-cmd.ts +140 -0
  60. package/src/client/budget-entry.ts +34 -0
  61. package/src/client/budget.test.ts +17 -0
  62. package/src/client/create.test.ts +159 -0
  63. package/src/client/create.ts +152 -0
  64. package/src/client/errors.ts +60 -0
  65. package/src/client/index.ts +35 -0
  66. package/src/client/notes-contract.test.ts +289 -0
  67. package/src/client/transport.test.ts +123 -0
  68. package/src/client/transport.ts +254 -0
  69. package/src/client/types.ts +282 -0
  70. package/src/compiler/aot.test.ts +248 -0
  71. package/src/compiler/aot.ts +182 -0
  72. package/src/compiler/differential.test.ts +241 -0
  73. package/src/compiler/dynamic.ts +54 -0
  74. package/src/compiler/effects-infer.ts +541 -0
  75. package/src/compiler/emit.ts +40 -0
  76. package/src/compiler/extract.test.ts +177 -0
  77. package/src/compiler/extract.ts +1368 -0
  78. package/src/compiler/fixtures/raw/raw-unannotated.ts +28 -0
  79. package/src/compiler/fixtures/skyport/oke.config.ts +24 -0
  80. package/src/compiler/fixtures/skyport/src/ai.ts +15 -0
  81. package/src/compiler/fixtures/skyport/src/app.ts +10 -0
  82. package/src/compiler/fixtures/skyport/src/channels.ts +6 -0
  83. package/src/compiler/fixtures/skyport/src/core.ts +3 -0
  84. package/src/compiler/fixtures/skyport/src/flows/bookings/index.ts +57 -0
  85. package/src/compiler/fixtures/skyport/src/flows/bookings/signals.ts +11 -0
  86. package/src/compiler/fixtures/skyport/src/flows/payments/index.ts +14 -0
  87. package/src/compiler/fixtures/skyport/src/flows/support/index.ts +20 -0
  88. package/src/compiler/fixtures/skyport/src/gates.ts +14 -0
  89. package/src/compiler/fixtures/skyport/src/journeys.ts +9 -0
  90. package/src/compiler/fixtures/skyport/src/schema.ts +3 -0
  91. package/src/compiler/fixtures/skyport/src/vault.ts +6 -0
  92. package/src/compiler/fixtures/skyport.expected.json +241 -0
  93. package/src/compiler/fixtures/triggers/five-triggers.ts +69 -0
  94. package/src/compiler/http-parse.ts +214 -0
  95. package/src/compiler/index.ts +67 -0
  96. package/src/compiler/response.ts +89 -0
  97. package/src/compiler/sucrose.ts +238 -0
  98. package/src/config/index.ts +167 -0
  99. package/src/console/budget.test.ts +73 -0
  100. package/src/console/index.ts +30 -0
  101. package/src/console/server/access.test.ts +370 -0
  102. package/src/console/server/access.ts +777 -0
  103. package/src/console/server/ai.test.ts +172 -0
  104. package/src/console/server/ai.ts +632 -0
  105. package/src/console/server/app.ts +294 -0
  106. package/src/console/server/auth-rate.test.ts +81 -0
  107. package/src/console/server/auth-rate.ts +72 -0
  108. package/src/console/server/bind.ts +25 -0
  109. package/src/console/server/channels.test.ts +179 -0
  110. package/src/console/server/channels.ts +469 -0
  111. package/src/console/server/claim.test.ts +66 -0
  112. package/src/console/server/claim.ts +134 -0
  113. package/src/console/server/clock.test.ts +239 -0
  114. package/src/console/server/clock.ts +390 -0
  115. package/src/console/server/console.test.ts +338 -0
  116. package/src/console/server/diff.test.ts +299 -0
  117. package/src/console/server/diff.ts +352 -0
  118. package/src/console/server/dry-run.audit.test.ts +118 -0
  119. package/src/console/server/flows-invoke.test.ts +148 -0
  120. package/src/console/server/flows.ts +3633 -0
  121. package/src/console/server/gates.test.ts +360 -0
  122. package/src/console/server/gates.ts +869 -0
  123. package/src/console/server/index.ts +141 -0
  124. package/src/console/server/live.test.ts +30 -0
  125. package/src/console/server/live.ts +109 -0
  126. package/src/console/server/plugin.ts +50 -0
  127. package/src/console/server/plugins.test.ts +131 -0
  128. package/src/console/server/plugins.ts +429 -0
  129. package/src/console/server/runs-pii.ts +98 -0
  130. package/src/console/server/security-headers.ts +97 -0
  131. package/src/console/server/security.gate.test.ts +286 -0
  132. package/src/console/server/serve.ts +319 -0
  133. package/src/console/server/signals.test.ts +88 -0
  134. package/src/console/server/signals.ts +282 -0
  135. package/src/console/server/state.ts +982 -0
  136. package/src/console/server/store.test.ts +233 -0
  137. package/src/console/server/store.ts +861 -0
  138. package/src/console/server/structural.ts +95 -0
  139. package/src/console/server/vault.test.ts +251 -0
  140. package/src/console/server/vault.ts +430 -0
  141. package/src/console/ui/access/AccessA11yView.tsx +237 -0
  142. package/src/console/ui/access/a11y.test.tsx +122 -0
  143. package/src/console/ui/access/acknowledgement.test.ts +13 -0
  144. package/src/console/ui/access/acknowledgement.ts +35 -0
  145. package/src/console/ui/access/blast-radius.test.ts +26 -0
  146. package/src/console/ui/access/blast-radius.ts +40 -0
  147. package/src/console/ui/access/confirmation.test.ts +38 -0
  148. package/src/console/ui/access/confirmation.ts +36 -0
  149. package/src/console/ui/access/fixture.ts +203 -0
  150. package/src/console/ui/access/grantable.test.ts +17 -0
  151. package/src/console/ui/access/grantable.ts +36 -0
  152. package/src/console/ui/access/hygiene.test.ts +12 -0
  153. package/src/console/ui/access/hygiene.ts +39 -0
  154. package/src/console/ui/access/index.ts +54 -0
  155. package/src/console/ui/access/provenance.test.ts +12 -0
  156. package/src/console/ui/access/provenance.ts +29 -0
  157. package/src/console/ui/access/search.test.ts +17 -0
  158. package/src/console/ui/access/search.ts +72 -0
  159. package/src/console/ui/access/types.ts +111 -0
  160. package/src/console/ui/ai/AiA11yView.tsx +265 -0
  161. package/src/console/ui/ai/a11y.test.tsx +99 -0
  162. package/src/console/ui/ai/findings.ts +41 -0
  163. package/src/console/ui/ai/fixture.ts +182 -0
  164. package/src/console/ui/ai/format.ts +90 -0
  165. package/src/console/ui/ai/group.test.ts +37 -0
  166. package/src/console/ui/ai/group.ts +88 -0
  167. package/src/console/ui/ai/index.ts +66 -0
  168. package/src/console/ui/ai/promotion.test.ts +77 -0
  169. package/src/console/ui/ai/promotion.ts +150 -0
  170. package/src/console/ui/ai/search.test.ts +40 -0
  171. package/src/console/ui/ai/search.ts +89 -0
  172. package/src/console/ui/ai/types.ts +139 -0
  173. package/src/console/ui/architecture/ArchitectureA11yView.tsx +163 -0
  174. package/src/console/ui/architecture/a11y.test.tsx +97 -0
  175. package/src/console/ui/architecture/boundary.ts +42 -0
  176. package/src/console/ui/architecture/declared.ts +165 -0
  177. package/src/console/ui/architecture/fixture.ts +74 -0
  178. package/src/console/ui/architecture/index.ts +84 -0
  179. package/src/console/ui/architecture/layers.ts +64 -0
  180. package/src/console/ui/architecture/layout.ts +68 -0
  181. package/src/console/ui/architecture/pathologies.ts +260 -0
  182. package/src/console/ui/architecture/search.ts +145 -0
  183. package/src/console/ui/architecture/traffic.ts +102 -0
  184. package/src/console/ui/architecture/types.ts +144 -0
  185. package/src/console/ui/architecture/view.test.ts +165 -0
  186. package/src/console/ui/architecture/view.ts +516 -0
  187. package/src/console/ui/channels/ChannelsA11yView.tsx +180 -0
  188. package/src/console/ui/channels/a11y.test.tsx +96 -0
  189. package/src/console/ui/channels/confirmation.test.ts +37 -0
  190. package/src/console/ui/channels/confirmation.ts +27 -0
  191. package/src/console/ui/channels/fallback.test.ts +15 -0
  192. package/src/console/ui/channels/fallback.ts +20 -0
  193. package/src/console/ui/channels/findings.ts +38 -0
  194. package/src/console/ui/channels/fixture.ts +134 -0
  195. package/src/console/ui/channels/group.ts +25 -0
  196. package/src/console/ui/channels/index.ts +57 -0
  197. package/src/console/ui/channels/locale.test.ts +17 -0
  198. package/src/console/ui/channels/locale.ts +31 -0
  199. package/src/console/ui/channels/mask.test.ts +14 -0
  200. package/src/console/ui/channels/mask.ts +12 -0
  201. package/src/console/ui/channels/search.ts +58 -0
  202. package/src/console/ui/channels/taxonomy.test.ts +17 -0
  203. package/src/console/ui/channels/taxonomy.ts +49 -0
  204. package/src/console/ui/channels/types.ts +117 -0
  205. package/src/console/ui/clock/ClockA11yView.tsx +182 -0
  206. package/src/console/ui/clock/a11y.test.tsx +99 -0
  207. package/src/console/ui/clock/confirmation.test.ts +32 -0
  208. package/src/console/ui/clock/confirmation.ts +34 -0
  209. package/src/console/ui/clock/findings.ts +40 -0
  210. package/src/console/ui/clock/fixture.ts +111 -0
  211. package/src/console/ui/clock/health.test.ts +25 -0
  212. package/src/console/ui/clock/health.ts +61 -0
  213. package/src/console/ui/clock/index.ts +49 -0
  214. package/src/console/ui/clock/search.test.ts +39 -0
  215. package/src/console/ui/clock/search.ts +76 -0
  216. package/src/console/ui/clock/timeline.test.ts +44 -0
  217. package/src/console/ui/clock/timeline.ts +41 -0
  218. package/src/console/ui/clock/types.ts +78 -0
  219. package/src/console/ui/clock/waiting-on.test.ts +34 -0
  220. package/src/console/ui/clock/waiting-on.ts +83 -0
  221. package/src/console/ui/confirmation.unify.test.ts +92 -0
  222. package/src/console/ui/diff/DiffA11yView.tsx +85 -0
  223. package/src/console/ui/diff/a11y.test.tsx +99 -0
  224. package/src/console/ui/diff/fixture.ts +85 -0
  225. package/src/console/ui/diff/group.test.ts +58 -0
  226. package/src/console/ui/diff/group.ts +97 -0
  227. package/src/console/ui/diff/index.ts +38 -0
  228. package/src/console/ui/diff/search.test.ts +32 -0
  229. package/src/console/ui/diff/search.ts +75 -0
  230. package/src/console/ui/diff/summary.ts +74 -0
  231. package/src/console/ui/diff/types.ts +48 -0
  232. package/src/console/ui/dist/assets/index-B71Yl_SS.js +10 -0
  233. package/src/console/ui/dist/assets/panel-access-Dd37LU2c.js +64 -0
  234. package/src/console/ui/dist/assets/panel-ai-CC7LR6-J.js +1 -0
  235. package/src/console/ui/dist/assets/panel-architecture-B5b3iKCz.js +1 -0
  236. package/src/console/ui/dist/assets/panel-channels-CeNjTKXp.js +1 -0
  237. package/src/console/ui/dist/assets/panel-clock-DgFTLoHV.js +1 -0
  238. package/src/console/ui/dist/assets/panel-diff-DxehccqB.js +1 -0
  239. package/src/console/ui/dist/assets/panel-flows-BtrVn-Eg.js +45 -0
  240. package/src/console/ui/dist/assets/panel-gates-Z9MKRGdH.js +1 -0
  241. package/src/console/ui/dist/assets/panel-overview-Bd48d9km.js +1 -0
  242. package/src/console/ui/dist/assets/panel-plugins-DWd0TowH.js +1 -0
  243. package/src/console/ui/dist/assets/panel-runs-BwsWqKeB.js +1 -0
  244. package/src/console/ui/dist/assets/panel-signals-9najbZY2.js +1 -0
  245. package/src/console/ui/dist/assets/panel-store-OHkP2pDp.js +1 -0
  246. package/src/console/ui/dist/assets/panel-traces-tn2JoY8U.js +1 -0
  247. package/src/console/ui/dist/assets/panel-vault-BbfWdox0.js +1 -0
  248. package/src/console/ui/dist/assets/rolldown-runtime-CNC7AqOf.js +1 -0
  249. package/src/console/ui/dist/assets/style-Cnl7WLya.css +3 -0
  250. package/src/console/ui/dist/index.html +14 -0
  251. package/src/console/ui/flows/FlowsA11yView.tsx +155 -0
  252. package/src/console/ui/flows/a11y.test.tsx +105 -0
  253. package/src/console/ui/flows/buffer.test.ts +91 -0
  254. package/src/console/ui/flows/buffer.ts +118 -0
  255. package/src/console/ui/flows/confirmation.ts +131 -0
  256. package/src/console/ui/flows/contract.test.ts +89 -0
  257. package/src/console/ui/flows/contract.ts +353 -0
  258. package/src/console/ui/flows/fixture.ts +81 -0
  259. package/src/console/ui/flows/graph.test.ts +101 -0
  260. package/src/console/ui/flows/graph.ts +549 -0
  261. package/src/console/ui/flows/index.ts +87 -0
  262. package/src/console/ui/flows/save-as-test.test.ts +47 -0
  263. package/src/console/ui/flows/save-as-test.ts +99 -0
  264. package/src/console/ui/flows/search.ts +255 -0
  265. package/src/console/ui/flows/tiers.ts +140 -0
  266. package/src/console/ui/gates/GatesA11yView.tsx +192 -0
  267. package/src/console/ui/gates/a11y.test.tsx +116 -0
  268. package/src/console/ui/gates/audit.test.ts +40 -0
  269. package/src/console/ui/gates/audit.ts +63 -0
  270. package/src/console/ui/gates/denial.test.ts +36 -0
  271. package/src/console/ui/gates/denial.ts +51 -0
  272. package/src/console/ui/gates/findings.ts +19 -0
  273. package/src/console/ui/gates/fixture.ts +189 -0
  274. package/src/console/ui/gates/group.test.ts +30 -0
  275. package/src/console/ui/gates/group.ts +102 -0
  276. package/src/console/ui/gates/index.ts +47 -0
  277. package/src/console/ui/gates/search.test.ts +49 -0
  278. package/src/console/ui/gates/search.ts +115 -0
  279. package/src/console/ui/gates/types.ts +121 -0
  280. package/src/console/ui/overview/OverviewA11yView.tsx +152 -0
  281. package/src/console/ui/overview/a11y.test.tsx +113 -0
  282. package/src/console/ui/overview/busiest.ts +26 -0
  283. package/src/console/ui/overview/compose.ts +133 -0
  284. package/src/console/ui/overview/cost.test.ts +39 -0
  285. package/src/console/ui/overview/cost.ts +138 -0
  286. package/src/console/ui/overview/fixture.ts +161 -0
  287. package/src/console/ui/overview/golden.ts +57 -0
  288. package/src/console/ui/overview/index.ts +59 -0
  289. package/src/console/ui/overview/rank.test.ts +136 -0
  290. package/src/console/ui/overview/rank.ts +210 -0
  291. package/src/console/ui/overview/slo.test.ts +73 -0
  292. package/src/console/ui/overview/slo.ts +229 -0
  293. package/src/console/ui/overview/types.ts +121 -0
  294. package/src/console/ui/overview/verdict.ts +131 -0
  295. package/src/console/ui/plugins/PluginsA11yView.tsx +227 -0
  296. package/src/console/ui/plugins/a11y.test.tsx +97 -0
  297. package/src/console/ui/plugins/command.test.ts +22 -0
  298. package/src/console/ui/plugins/command.ts +27 -0
  299. package/src/console/ui/plugins/findings.ts +39 -0
  300. package/src/console/ui/plugins/fixture.ts +233 -0
  301. package/src/console/ui/plugins/group.test.ts +38 -0
  302. package/src/console/ui/plugins/group.ts +67 -0
  303. package/src/console/ui/plugins/index.ts +40 -0
  304. package/src/console/ui/plugins/search.ts +67 -0
  305. package/src/console/ui/plugins/types.ts +115 -0
  306. package/src/console/ui/runs/RunsA11yView.tsx +267 -0
  307. package/src/console/ui/runs/a11y.test.tsx +99 -0
  308. package/src/console/ui/runs/explain.test.ts +23 -0
  309. package/src/console/ui/runs/explain.ts +32 -0
  310. package/src/console/ui/runs/fixture.ts +189 -0
  311. package/src/console/ui/runs/group.test.ts +24 -0
  312. package/src/console/ui/runs/group.ts +85 -0
  313. package/src/console/ui/runs/histogram.test.ts +31 -0
  314. package/src/console/ui/runs/histogram.ts +85 -0
  315. package/src/console/ui/runs/index.ts +75 -0
  316. package/src/console/ui/runs/project.ts +122 -0
  317. package/src/console/ui/runs/query.test.ts +50 -0
  318. package/src/console/ui/runs/query.ts +283 -0
  319. package/src/console/ui/runs/search.test.ts +45 -0
  320. package/src/console/ui/runs/search.ts +141 -0
  321. package/src/console/ui/runs/trace-link.test.ts +30 -0
  322. package/src/console/ui/runs/trace-link.ts +99 -0
  323. package/src/console/ui/runs/types.ts +137 -0
  324. package/src/console/ui/shell/App.tsx +56 -0
  325. package/src/console/ui/shell/client.ts +1715 -0
  326. package/src/console/ui/shell/components/ui.tsx +110 -0
  327. package/src/console/ui/shell/index.html +12 -0
  328. package/src/console/ui/shell/layout/Shell.tsx +95 -0
  329. package/src/console/ui/shell/main.tsx +281 -0
  330. package/src/console/ui/shell/panels/Access.tsx +5 -0
  331. package/src/console/ui/shell/panels/Ai.tsx +5 -0
  332. package/src/console/ui/shell/panels/Architecture.tsx +5 -0
  333. package/src/console/ui/shell/panels/Channels.tsx +5 -0
  334. package/src/console/ui/shell/panels/Clock.tsx +5 -0
  335. package/src/console/ui/shell/panels/Diff.tsx +5 -0
  336. package/src/console/ui/shell/panels/Flows.tsx +5 -0
  337. package/src/console/ui/shell/panels/Gates.tsx +5 -0
  338. package/src/console/ui/shell/panels/Overview.tsx +6 -0
  339. package/src/console/ui/shell/panels/Plugins.tsx +5 -0
  340. package/src/console/ui/shell/panels/Runs.tsx +5 -0
  341. package/src/console/ui/shell/panels/Signals.tsx +5 -0
  342. package/src/console/ui/shell/panels/Store.tsx +5 -0
  343. package/src/console/ui/shell/panels/Traces.tsx +5 -0
  344. package/src/console/ui/shell/panels/Vault.tsx +5 -0
  345. package/src/console/ui/shell/panels/access/AccessPanel.tsx +813 -0
  346. package/src/console/ui/shell/panels/ai/AiPanel.tsx +563 -0
  347. package/src/console/ui/shell/panels/architecture/ArchitecturePanel.tsx +377 -0
  348. package/src/console/ui/shell/panels/channels/ChannelsPanel.tsx +454 -0
  349. package/src/console/ui/shell/panels/clock/ClockPanel.tsx +479 -0
  350. package/src/console/ui/shell/panels/diff/DiffPanel.tsx +275 -0
  351. package/src/console/ui/shell/panels/flows/ContractEditor.tsx +301 -0
  352. package/src/console/ui/shell/panels/flows/FlowDrawer.tsx +350 -0
  353. package/src/console/ui/shell/panels/flows/FlowsPanel.tsx +502 -0
  354. package/src/console/ui/shell/panels/gates/GatesPanel.tsx +482 -0
  355. package/src/console/ui/shell/panels/overview/OverviewPanel.tsx +428 -0
  356. package/src/console/ui/shell/panels/plugins/PluginsPanel.tsx +413 -0
  357. package/src/console/ui/shell/panels/runs/RunsPanel.tsx +649 -0
  358. package/src/console/ui/shell/panels/signals/SignalsPanel.tsx +840 -0
  359. package/src/console/ui/shell/panels/store/StorePanel.tsx +787 -0
  360. package/src/console/ui/shell/panels/traces/TracesPanel.tsx +539 -0
  361. package/src/console/ui/shell/panels/vault/VaultPanel.tsx +449 -0
  362. package/src/console/ui/shell/plugin/Sandbox.tsx +29 -0
  363. package/src/console/ui/shell/setup/Wizard.tsx +189 -0
  364. package/src/console/ui/shell/styles.css +75 -0
  365. package/src/console/ui/signals/SignalsA11yView.tsx +276 -0
  366. package/src/console/ui/signals/a11y.test.tsx +99 -0
  367. package/src/console/ui/signals/confirmation.test.ts +39 -0
  368. package/src/console/ui/signals/confirmation.ts +63 -0
  369. package/src/console/ui/signals/dry-run.test.ts +18 -0
  370. package/src/console/ui/signals/dry-run.ts +36 -0
  371. package/src/console/ui/signals/durable.test.ts +22 -0
  372. package/src/console/ui/signals/durable.ts +41 -0
  373. package/src/console/ui/signals/findings.ts +33 -0
  374. package/src/console/ui/signals/fixture.ts +242 -0
  375. package/src/console/ui/signals/group.test.ts +32 -0
  376. package/src/console/ui/signals/group.ts +49 -0
  377. package/src/console/ui/signals/index.ts +52 -0
  378. package/src/console/ui/signals/monitor.test.ts +30 -0
  379. package/src/console/ui/signals/monitor.ts +79 -0
  380. package/src/console/ui/signals/schema-form.test.ts +34 -0
  381. package/src/console/ui/signals/schema-form.ts +112 -0
  382. package/src/console/ui/signals/search.ts +102 -0
  383. package/src/console/ui/signals/types.ts +71 -0
  384. package/src/console/ui/store/StoreA11yView.tsx +199 -0
  385. package/src/console/ui/store/a11y.test.tsx +99 -0
  386. package/src/console/ui/store/cache-view.test.ts +13 -0
  387. package/src/console/ui/store/cache-view.ts +36 -0
  388. package/src/console/ui/store/confirmation.test.ts +38 -0
  389. package/src/console/ui/store/confirmation.ts +55 -0
  390. package/src/console/ui/store/dry-run.test.ts +15 -0
  391. package/src/console/ui/store/dry-run.ts +29 -0
  392. package/src/console/ui/store/fixture.ts +163 -0
  393. package/src/console/ui/store/group.test.ts +21 -0
  394. package/src/console/ui/store/group.ts +41 -0
  395. package/src/console/ui/store/index.ts +40 -0
  396. package/src/console/ui/store/search.ts +78 -0
  397. package/src/console/ui/store/types.ts +65 -0
  398. package/src/console/ui/store/will-not-fire.test.ts +19 -0
  399. package/src/console/ui/store/will-not-fire.ts +40 -0
  400. package/src/console/ui/traces/TracesA11yView.tsx +200 -0
  401. package/src/console/ui/traces/a11y.test.tsx +97 -0
  402. package/src/console/ui/traces/chain.test.ts +61 -0
  403. package/src/console/ui/traces/chain.ts +144 -0
  404. package/src/console/ui/traces/critical-path.test.ts +24 -0
  405. package/src/console/ui/traces/critical-path.ts +59 -0
  406. package/src/console/ui/traces/filter.test.ts +78 -0
  407. package/src/console/ui/traces/filter.ts +112 -0
  408. package/src/console/ui/traces/fixture.ts +126 -0
  409. package/src/console/ui/traces/fold.test.ts +67 -0
  410. package/src/console/ui/traces/fold.ts +170 -0
  411. package/src/console/ui/traces/index.ts +64 -0
  412. package/src/console/ui/traces/mini.ts +65 -0
  413. package/src/console/ui/traces/replay.test.ts +24 -0
  414. package/src/console/ui/traces/replay.ts +35 -0
  415. package/src/console/ui/traces/sampling.test.ts +26 -0
  416. package/src/console/ui/traces/sampling.ts +66 -0
  417. package/src/console/ui/traces/search.ts +148 -0
  418. package/src/console/ui/traces/tier.ts +72 -0
  419. package/src/console/ui/traces/types.ts +125 -0
  420. package/src/console/ui/tsconfig.json +20 -0
  421. package/src/console/ui/vault/VaultA11yView.tsx +177 -0
  422. package/src/console/ui/vault/a11y.test.tsx +97 -0
  423. package/src/console/ui/vault/blast-radius.test.ts +35 -0
  424. package/src/console/ui/vault/blast-radius.ts +55 -0
  425. package/src/console/ui/vault/confirmation.test.ts +41 -0
  426. package/src/console/ui/vault/confirmation.ts +39 -0
  427. package/src/console/ui/vault/dormant.test.ts +37 -0
  428. package/src/console/ui/vault/dormant.ts +28 -0
  429. package/src/console/ui/vault/export-safe.test.ts +30 -0
  430. package/src/console/ui/vault/export-safe.ts +65 -0
  431. package/src/console/ui/vault/fixture.ts +75 -0
  432. package/src/console/ui/vault/group.test.ts +25 -0
  433. package/src/console/ui/vault/group.ts +50 -0
  434. package/src/console/ui/vault/index.ts +45 -0
  435. package/src/console/ui/vault/search.ts +62 -0
  436. package/src/console/ui/vault/types.ts +57 -0
  437. package/src/console/ui/vite.config.ts +84 -0
  438. package/src/console/xss.gate.test.ts +118 -0
  439. package/src/docker/compose.ts +226 -0
  440. package/src/docker/credentials.ts +25 -0
  441. package/src/docker/derive.ts +83 -0
  442. package/src/docker/docker.test.ts +185 -0
  443. package/src/docker/dockerfile.integration.test.ts +170 -0
  444. package/src/docker/dockerfile.ts +39 -0
  445. package/src/docker/helpers.ts +103 -0
  446. package/src/docker/index.ts +52 -0
  447. package/src/docker/pin.ts +90 -0
  448. package/src/docker/recipes/index.ts +33 -0
  449. package/src/docker/recipes/postgres.ts +18 -0
  450. package/src/docker/recipes/redis.ts +18 -0
  451. package/src/docker/stack.integration.test.ts +140 -0
  452. package/src/docker/stack.ts +62 -0
  453. package/src/docker/types.ts +134 -0
  454. package/src/drivers/ai-anthropic.ts +128 -0
  455. package/src/drivers/ai-mock.ts +82 -0
  456. package/src/drivers/ai-openai-compatible.ts +139 -0
  457. package/src/drivers/ai-providers.test.ts +163 -0
  458. package/src/drivers/ai-types.ts +83 -0
  459. package/src/drivers/bun-native-completeness.test.ts +155 -0
  460. package/src/drivers/channel-console.ts +118 -0
  461. package/src/drivers/channel-fcm.ts +96 -0
  462. package/src/drivers/channel-resend.ts +27 -0
  463. package/src/drivers/channel-smtp.ts +33 -0
  464. package/src/drivers/channel-types.ts +160 -0
  465. package/src/drivers/channel-unifonic.ts +79 -0
  466. package/src/drivers/channel-wa-cloud.ts +84 -0
  467. package/src/drivers/channel-webpush.ts +317 -0
  468. package/src/drivers/conformance.test.ts +89 -0
  469. package/src/drivers/conformance.ts +162 -0
  470. package/src/drivers/fs.ts +73 -0
  471. package/src/drivers/index.ts +194 -0
  472. package/src/drivers/kv-lua.ts +222 -0
  473. package/src/drivers/memory.ts +472 -0
  474. package/src/drivers/pgvector.ts +130 -0
  475. package/src/drivers/postgres.ts +221 -0
  476. package/src/drivers/redis.ts +254 -0
  477. package/src/drivers/s3.ts +129 -0
  478. package/src/drivers/signal-engine.ts +690 -0
  479. package/src/drivers/signal-memory.ts +27 -0
  480. package/src/drivers/signal-nats.ts +131 -0
  481. package/src/drivers/signal-postgres.ts +1089 -0
  482. package/src/drivers/signal-redis.ts +275 -0
  483. package/src/drivers/signal-types.ts +328 -0
  484. package/src/drivers/sqlite.ts +53 -0
  485. package/src/drivers/types.ts +334 -0
  486. package/src/drivers/vault-dotenv-parse.ts +56 -0
  487. package/src/drivers/vault-env.ts +101 -0
  488. package/src/drivers/vault-infisical.ts +61 -0
  489. package/src/drivers/vault-managed.ts +42 -0
  490. package/src/drivers/vault-memory.ts +38 -0
  491. package/src/drivers/vault-openbao.ts +80 -0
  492. package/src/drivers/vault-sops.ts +252 -0
  493. package/src/drivers/vault-types.ts +84 -0
  494. package/src/elements/ai/declare.ts +206 -0
  495. package/src/elements/ai/eval.ts +113 -0
  496. package/src/elements/ai/pii.ts +108 -0
  497. package/src/elements/ai/runtime.ts +540 -0
  498. package/src/elements/ai/schema.ts +194 -0
  499. package/src/elements/ai.test.ts +393 -0
  500. package/src/elements/ai.ts +56 -0
  501. package/src/elements/channel/consent.ts +81 -0
  502. package/src/elements/channel/costs.test.ts +62 -0
  503. package/src/elements/channel/costs.ts +130 -0
  504. package/src/elements/channel/declare.ts +141 -0
  505. package/src/elements/channel/email-auth.test.ts +47 -0
  506. package/src/elements/channel/email-auth.ts +109 -0
  507. package/src/elements/channel/locale.ts +97 -0
  508. package/src/elements/channel/mask.test.ts +19 -0
  509. package/src/elements/channel/mask.ts +60 -0
  510. package/src/elements/channel/mime.ts +23 -0
  511. package/src/elements/channel/outcomes.test.ts +40 -0
  512. package/src/elements/channel/outcomes.ts +126 -0
  513. package/src/elements/channel/receipts.ts +121 -0
  514. package/src/elements/channel/runtime.ts +500 -0
  515. package/src/elements/channel/suppression.ts +136 -0
  516. package/src/elements/channel.test.ts +232 -0
  517. package/src/elements/channel.ts +109 -0
  518. package/src/elements/clock/actions.ts +170 -0
  519. package/src/elements/clock/declare.ts +58 -0
  520. package/src/elements/clock/dst.ts +197 -0
  521. package/src/elements/clock/durable.ts +140 -0
  522. package/src/elements/clock/duration.ts +29 -0
  523. package/src/elements/clock/health.test.ts +103 -0
  524. package/src/elements/clock/health.ts +112 -0
  525. package/src/elements/clock/leader.ts +127 -0
  526. package/src/elements/clock/reconcile.ts +241 -0
  527. package/src/elements/clock/runtime.ts +243 -0
  528. package/src/elements/clock/schedule.ts +262 -0
  529. package/src/elements/clock/time-travel.ts +53 -0
  530. package/src/elements/clock.test.ts +365 -0
  531. package/src/elements/clock.ts +80 -0
  532. package/src/elements/gate/declare.ts +134 -0
  533. package/src/elements/gate/permissions.ts +104 -0
  534. package/src/elements/gate/runtime.ts +177 -0
  535. package/src/elements/gate/strategies.ts +388 -0
  536. package/src/elements/gate.test.ts +145 -0
  537. package/src/elements/gate.ts +41 -0
  538. package/src/elements/index.ts +169 -0
  539. package/src/elements/signal/chaos-child.ts +47 -0
  540. package/src/elements/signal/declare.ts +77 -0
  541. package/src/elements/signal/dry-run-replay.test.ts +95 -0
  542. package/src/elements/signal/dry-run-write-isolation.test.ts +94 -0
  543. package/src/elements/signal/reconcile.test.ts +23 -0
  544. package/src/elements/signal/reconcile.ts +122 -0
  545. package/src/elements/signal/runtime.ts +94 -0
  546. package/src/elements/signal.test.ts +457 -0
  547. package/src/elements/signal.ts +26 -0
  548. package/src/elements/store/cache.ts +197 -0
  549. package/src/elements/store/classify.ts +125 -0
  550. package/src/elements/store/declare.ts +200 -0
  551. package/src/elements/store/files-policy.test.ts +31 -0
  552. package/src/elements/store/files-policy.ts +70 -0
  553. package/src/elements/store/replica.ts +68 -0
  554. package/src/elements/store/runtime.ts +393 -0
  555. package/src/elements/store/sql-condition.ts +205 -0
  556. package/src/elements/store/sql-session.ts +579 -0
  557. package/src/elements/store/table.ts +282 -0
  558. package/src/elements/store.test.ts +370 -0
  559. package/src/elements/store.ts +99 -0
  560. package/src/elements/vault/declare.ts +143 -0
  561. package/src/elements/vault/fingerprint.ts +30 -0
  562. package/src/elements/vault/redact.ts +52 -0
  563. package/src/elements/vault/runtime.ts +461 -0
  564. package/src/elements/vault.test.ts +296 -0
  565. package/src/elements/vault.ts +44 -0
  566. package/src/index.ts +183 -0
  567. package/src/kernel/adopt-routes.ts +194 -0
  568. package/src/kernel/app.ts +1068 -0
  569. package/src/kernel/auth-resolve.ts +93 -0
  570. package/src/kernel/boot.test.ts +173 -0
  571. package/src/kernel/boot.ts +439 -0
  572. package/src/kernel/budget-entry.ts +55 -0
  573. package/src/kernel/budget.test.ts +19 -0
  574. package/src/kernel/call.test.ts +83 -0
  575. package/src/kernel/capability.ts +113 -0
  576. package/src/kernel/dry-run.test.ts +64 -0
  577. package/src/kernel/dry-run.ts +171 -0
  578. package/src/kernel/effects.test.ts +89 -0
  579. package/src/kernel/effects.ts +140 -0
  580. package/src/kernel/errors.registry.test.ts +39 -0
  581. package/src/kernel/errors.ts +225 -0
  582. package/src/kernel/flow.test.ts +154 -0
  583. package/src/kernel/flow.ts +290 -0
  584. package/src/kernel/fx.test.ts +245 -0
  585. package/src/kernel/fx.ts +996 -0
  586. package/src/kernel/hook-timing.test.ts +72 -0
  587. package/src/kernel/hook-timing.ts +190 -0
  588. package/src/kernel/hooks.test.ts +181 -0
  589. package/src/kernel/hooks.ts +275 -0
  590. package/src/kernel/index.ts +278 -0
  591. package/src/kernel/journal.ts +405 -0
  592. package/src/kernel/journey.ts +75 -0
  593. package/src/kernel/on.ts +74 -0
  594. package/src/kernel/pipeline.test.ts +349 -0
  595. package/src/kernel/pipeline.ts +245 -0
  596. package/src/kernel/plug.ts +82 -0
  597. package/src/kernel/plugin/capabilities.test.ts +84 -0
  598. package/src/kernel/plugin/conflicts.test.ts +106 -0
  599. package/src/kernel/plugin/decorate.test.ts +111 -0
  600. package/src/kernel/plugin/scoping.test.ts +138 -0
  601. package/src/kernel/plugin.ts +485 -0
  602. package/src/kernel/rate-limit.ts +25 -0
  603. package/src/kernel/registry.ts +398 -0
  604. package/src/kernel/router.test.ts +114 -0
  605. package/src/kernel/router.ts +556 -0
  606. package/src/kernel/routing-budget.test.ts +19 -0
  607. package/src/kernel/run-telemetry.ts +70 -0
  608. package/src/kernel/triggers.ts +324 -0
  609. package/src/kernel/unit.ts +88 -0
  610. package/src/manifest/diff.test.ts +866 -0
  611. package/src/manifest/diff.ts +1670 -0
  612. package/src/manifest/fixtures/base.manifest.json +112 -0
  613. package/src/manifest/fixtures/skyport.excerpt.json +51 -0
  614. package/src/manifest/fixtures/skyport.manifest.json +153 -0
  615. package/src/manifest/index.ts +27 -0
  616. package/src/manifest/types.ts +358 -0
  617. package/src/manifest/undeclared.test.ts +82 -0
  618. package/src/manifest/undeclared.ts +65 -0
  619. package/src/manifest/validate.test.ts +105 -0
  620. package/src/manifest/validate.ts +174 -0
  621. package/src/mcp/authorization.ts +340 -0
  622. package/src/mcp/confirmation.ts +174 -0
  623. package/src/mcp/data.ts +90 -0
  624. package/src/mcp/index.ts +80 -0
  625. package/src/mcp/injection.gate.test.ts +176 -0
  626. package/src/mcp/mcp.test.ts +348 -0
  627. package/src/mcp/protocol.ts +172 -0
  628. package/src/mcp/server.ts +283 -0
  629. package/src/mcp/session.ts +139 -0
  630. package/src/mcp/tools.ts +391 -0
  631. package/src/plugins/catalogue.test.ts +48 -0
  632. package/src/plugins/catalogue.ts +113 -0
  633. package/src/plugins/node-import-scan.test.ts +28 -0
  634. package/src/plugins/node-import-scan.ts +98 -0
  635. package/src/plugins/supply-chain.test.ts +48 -0
  636. package/src/plugins/supply-chain.ts +460 -0
  637. package/src/release/index.ts +30 -0
  638. package/src/release/limits.ts +20 -0
  639. package/src/release/measure.ts +443 -0
  640. package/src/release/publish.ts +56 -0
  641. package/src/runs/bench.test.ts +93 -0
  642. package/src/runs/collect.ts +144 -0
  643. package/src/runs/drivers/clickhouse.ts +108 -0
  644. package/src/runs/drivers/files.ts +201 -0
  645. package/src/runs/drivers/memory.ts +94 -0
  646. package/src/runs/drivers/postgres.ts +110 -0
  647. package/src/runs/duckdb.ts +99 -0
  648. package/src/runs/index.ts +82 -0
  649. package/src/runs/outlier.ts +180 -0
  650. package/src/runs/parquet.ts +210 -0
  651. package/src/runs/privacy.ts +49 -0
  652. package/src/runs/runs.test.ts +324 -0
  653. package/src/runs/runtime.ts +229 -0
  654. package/src/runs/shred.ts +243 -0
  655. package/src/runs/telemetry.ts +10 -0
  656. package/src/runs/types.ts +179 -0
  657. package/src/runtime/bun.ts +140 -0
  658. package/src/runtime/cold-start.bench.ts +20 -0
  659. package/src/runtime/index.ts +46 -0
  660. package/src/runtime/primitives.ts +242 -0
  661. package/src/runtime/security.test.ts +170 -0
  662. package/src/runtime/security.ts +168 -0
  663. package/src/runtime/serve.test.ts +223 -0
  664. package/src/runtime/types.ts +217 -0
  665. package/src/runtime/web-standard.ts +77 -0
  666. package/src/test/create-test-app.test.ts +161 -0
  667. package/src/test/create-test-app.ts +533 -0
  668. package/src/test/index.ts +21 -0
  669. package/src/test/provisions.integration.test.ts +174 -0
  670. package/src/upgrade/codemods.test.ts +58 -0
  671. package/src/upgrade/codemods.ts +83 -0
  672. package/src/validation/index.ts +23 -0
  673. package/src/validation/standard-schema.test.ts +96 -0
  674. package/src/validation/standard-schema.ts +316 -0
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Thin DuckDB adapter — adopted via `@duckdb/node-api`, not reinvented.
3
+ */
4
+
5
+ import {
6
+ DuckDBInstance,
7
+ type DuckDBConnection,
8
+ } from "@duckdb/node-api";
9
+
10
+ import type { RunsRow } from "./types.ts";
11
+
12
+ /** DuckDB session — instance kept alive with the connection. */
13
+ export interface DuckSession {
14
+ /** DuckDB instance (must outlive the connection). */
15
+ readonly instance: DuckDBInstance;
16
+ /** Active connection. */
17
+ readonly conn: DuckDBConnection;
18
+ /** Close connection + instance. */
19
+ close(): void;
20
+ }
21
+
22
+ /** Open an in-memory DuckDB session. */
23
+ export async function openDuckDB(): Promise<DuckSession> {
24
+ const instance = await DuckDBInstance.create(":memory:");
25
+ const conn = await instance.connect();
26
+ return {
27
+ instance,
28
+ conn,
29
+ close() {
30
+ try {
31
+ (conn as { closeSync?: () => void }).closeSync?.();
32
+ } catch {
33
+ /* ignore */
34
+ }
35
+ try {
36
+ (instance as { closeSync?: () => void }).closeSync?.();
37
+ } catch {
38
+ /* ignore */
39
+ }
40
+ },
41
+ };
42
+ }
43
+
44
+ /**
45
+ * Run a query and return plain JSON-friendly row objects.
46
+ *
47
+ * @param conn - DuckDB connection
48
+ * @param sql - SQL text
49
+ */
50
+ export async function duckQuery(
51
+ conn: DuckDBConnection,
52
+ sql: string,
53
+ ): Promise<RunsRow[]> {
54
+ const reader = await conn.runAndReadAll(sql);
55
+ const rows = reader.getRowObjectsJson() as RunsRow[];
56
+ return rows.map(normalizeRow);
57
+ }
58
+
59
+ /**
60
+ * Escape a filesystem path for use inside a DuckDB string literal.
61
+ *
62
+ * @param path - Absolute path
63
+ */
64
+ export function duckPath(path: string): string {
65
+ return path.replaceAll("'", "''");
66
+ }
67
+
68
+ /**
69
+ * Quote an identifier.
70
+ *
71
+ * @param id - Column / table name
72
+ */
73
+ export function duckIdent(id: string): string {
74
+ return `"${id.replaceAll('"', '""')}"`;
75
+ }
76
+
77
+ /**
78
+ * SQL literal for a JS value.
79
+ *
80
+ * @param value - Value to embed
81
+ */
82
+ export function duckLiteral(value: unknown): string {
83
+ if (value === null || value === undefined) return "NULL";
84
+ if (typeof value === "number") {
85
+ return Number.isFinite(value) ? String(value) : "NULL";
86
+ }
87
+ if (typeof value === "boolean") return value ? "TRUE" : "FALSE";
88
+ if (typeof value === "bigint") return `${value}`;
89
+ const s = String(value).replaceAll("'", "''");
90
+ return `'${s}'`;
91
+ }
92
+
93
+ function normalizeRow(row: RunsRow): RunsRow {
94
+ const out: RunsRow = {};
95
+ for (const [k, v] of Object.entries(row)) {
96
+ out[k] = typeof v === "bigint" ? Number(v) : v;
97
+ }
98
+ return out;
99
+ }
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Runs store — wide events, Parquet + DuckDB, outlier explanation, crypto-shred.
3
+ *
4
+ * Not a ninth element: observability derived from the effect system.
5
+ * Subpath: planned as part of the Console / runtime surface.
6
+ */
7
+
8
+ export type {
9
+ RunsDriverId,
10
+ RunLogLine,
11
+ RunError,
12
+ RunDimensions,
13
+ WideEvent,
14
+ RunsRetention,
15
+ RunsRow,
16
+ RunsStore,
17
+ RunsDriver,
18
+ RunsOpenOptions,
19
+ } from "./types.ts";
20
+
21
+ export {
22
+ createRunTelemetry,
23
+ cacheDimensionOf,
24
+ type RunTelemetry,
25
+ } from "./telemetry.ts";
26
+
27
+ export {
28
+ collectWideEvent,
29
+ type CollectWideEventInput,
30
+ } from "./collect.ts";
31
+
32
+ export {
33
+ explainOutliers,
34
+ seedOutlierDataset,
35
+ type OutlierFinding,
36
+ type ExplainOutliersOptions,
37
+ } from "./outlier.ts";
38
+
39
+ export {
40
+ SUBJECT_KEY_PREFIX,
41
+ SHREDDED,
42
+ subjectKeyName,
43
+ subjectKeysFromVault,
44
+ createMemorySubjectKeys,
45
+ ensureSubjectKey,
46
+ archiveFields,
47
+ revealArchived,
48
+ eraseSubject,
49
+ type SubjectKeyVault,
50
+ } from "./shred.ts";
51
+
52
+ export {
53
+ wideEventToRow,
54
+ rowToWideEvent,
55
+ writeParquet,
56
+ readParquet,
57
+ partitionKey,
58
+ partitionObjectKey,
59
+ type ParquetRow,
60
+ } from "./parquet.ts";
61
+
62
+ export { openDuckDB, duckQuery, duckPath, duckLiteral } from "./duckdb.ts";
63
+
64
+ export {
65
+ createRunsRuntime,
66
+ resolveRunsDriver,
67
+ filesRunsDriver,
68
+ memoryRunsDriver,
69
+ postgresRunsDriver,
70
+ clickhouseRunsDriver,
71
+ type CreateRunsRuntimeOptions,
72
+ type RunsRuntime,
73
+ } from "./runtime.ts";
74
+
75
+ export {
76
+ privacyErase,
77
+ type PrivacyEraseOptions,
78
+ type PrivacyEraseResult,
79
+ } from "./privacy.ts";
80
+
81
+ export { createRunsPostgresFake } from "./drivers/postgres.ts";
82
+ export { createRunsClickHouseFake } from "./drivers/clickhouse.ts";
@@ -0,0 +1,180 @@
1
+ /**
2
+ * Automatic outlier explanation — compare every dimension between a selected
3
+ * population and the rest (console §9.11).
4
+ *
5
+ * "94% cache=miss vs 6%" — the system surfaces separating dimensions nobody
6
+ * asked about, because all dimensions are declared and typed.
7
+ */
8
+
9
+ import type { RunDimensions, WideEvent } from "./types.ts";
10
+
11
+ /** One dimension that separates outliers from the baseline. */
12
+ export interface OutlierFinding {
13
+ /** Dimension name. */
14
+ readonly dimension: string;
15
+ /** Value enriched in the outlier population. */
16
+ readonly value: string;
17
+ /** Share of outliers carrying this value (0–1). */
18
+ readonly outlierShare: number;
19
+ /** Share of baseline carrying this value (0–1). */
20
+ readonly baselineShare: number;
21
+ /** Absolute lift (`outlierShare - baselineShare`). */
22
+ readonly lift: number;
23
+ /** Human-readable line matching the Console voice. */
24
+ readonly explanation: string;
25
+ }
26
+
27
+ /** Options for {@link explainOutliers}. */
28
+ export interface ExplainOutliersOptions {
29
+ /**
30
+ * Predicate selecting the outlier population (e.g. slow runs).
31
+ *
32
+ * @param event - Wide event
33
+ */
34
+ readonly select: (event: WideEvent) => boolean;
35
+ /** Max findings to return (default 10). */
36
+ readonly limit?: number;
37
+ /** Minimum absolute lift to report (default 0.15). */
38
+ readonly minLift?: number;
39
+ /** Dimensions to ignore. */
40
+ readonly ignore?: readonly string[];
41
+ }
42
+
43
+ /**
44
+ * Explain what separates a selected population from the rest.
45
+ *
46
+ * @param events - Seeded or queried wide events
47
+ * @param options - Selection + thresholds
48
+ */
49
+ export function explainOutliers(
50
+ events: readonly WideEvent[],
51
+ options: ExplainOutliersOptions,
52
+ ): OutlierFinding[] {
53
+ const outliers = events.filter(options.select);
54
+ const baseline = events.filter((e) => !options.select(e));
55
+ if (outliers.length === 0 || baseline.length === 0) return [];
56
+
57
+ const ignore = new Set(options.ignore ?? ["duration_ms", "flow"]);
58
+ const minLift = options.minLift ?? 0.15;
59
+ const limit = options.limit ?? 10;
60
+
61
+ const dimNames = new Set<string>();
62
+ for (const e of events) {
63
+ for (const k of Object.keys(e.dimensions)) {
64
+ if (!ignore.has(k)) dimNames.add(k);
65
+ }
66
+ }
67
+
68
+ const findings: OutlierFinding[] = [];
69
+ for (const dim of dimNames) {
70
+ const outlierCounts = valueCounts(outliers, dim);
71
+ const baselineCounts = valueCounts(baseline, dim);
72
+ const values = new Set([
73
+ ...outlierCounts.keys(),
74
+ ...baselineCounts.keys(),
75
+ ]);
76
+ for (const value of values) {
77
+ const outlierShare = (outlierCounts.get(value) ?? 0) / outliers.length;
78
+ const baselineShare =
79
+ (baselineCounts.get(value) ?? 0) / baseline.length;
80
+ const lift = outlierShare - baselineShare;
81
+ if (lift < minLift) continue;
82
+ findings.push({
83
+ dimension: dim,
84
+ value,
85
+ outlierShare,
86
+ baselineShare,
87
+ lift,
88
+ explanation: formatExplanation(dim, value, outlierShare, baselineShare),
89
+ });
90
+ }
91
+ }
92
+
93
+ findings.sort((a, b) => b.lift - a.lift);
94
+ return findings.slice(0, limit);
95
+ }
96
+
97
+ /**
98
+ * Seed a dataset where one dimension cleanly separates slow runs.
99
+ *
100
+ * @param opts - Size + separating dimension
101
+ */
102
+ export function seedOutlierDataset(opts?: {
103
+ readonly n?: number;
104
+ readonly slowShare?: number;
105
+ readonly separatingDimension?: string;
106
+ readonly separatingValue?: string;
107
+ readonly slowDurationMs?: number;
108
+ readonly fastDurationMs?: number;
109
+ }): WideEvent[] {
110
+ const n = opts?.n ?? 1000;
111
+ const slowShare = opts?.slowShare ?? 0.1;
112
+ const dim = opts?.separatingDimension ?? "cache";
113
+ const sepValue = opts?.separatingValue ?? "miss";
114
+ const slowMs = opts?.slowDurationMs ?? 2000;
115
+ const fastMs = opts?.fastDurationMs ?? 50;
116
+ const slowCount = Math.floor(n * slowShare);
117
+
118
+ const events: WideEvent[] = [];
119
+ for (let i = 0; i < n; i++) {
120
+ const slow = i < slowCount;
121
+ // 90% of slow runs carry the separating value; 5% of fast runs do.
122
+ const carriesSep = slow ? i % 10 !== 0 : i % 20 === 0;
123
+ const dimValue = carriesSep ? sepValue : dim === "cache" ? "hit" : "other";
124
+ const durationMs = slow ? slowMs : fastMs;
125
+ const startedAt = 1_700_000_000_000 + i;
126
+ const dimensions: RunDimensions = {
127
+ flow: "book",
128
+ trigger: "http",
129
+ plane: "user",
130
+ tenant: i % 7 === 0 ? "org_a41" : `org_${i % 50}`,
131
+ cache: dim === "cache" ? dimValue : i % 3 === 0 ? "miss" : "hit",
132
+ [dim]: dimValue,
133
+ duration_ms: durationMs,
134
+ };
135
+ events.push({
136
+ id: `run_${i}`,
137
+ flow: "book",
138
+ trigger: "http",
139
+ plane: "user",
140
+ tenant: String(dimensions.tenant),
141
+ principal: `user_${i % 100}`,
142
+ subjectId: `user_${i % 100}`,
143
+ gates: ["member"],
144
+ cache: (dimensions.cache as "hit" | "miss") ?? "none",
145
+ effects: [],
146
+ logs: [],
147
+ durationMs,
148
+ startedAt,
149
+ endedAt: startedAt + durationMs,
150
+ dimensions,
151
+ error: null,
152
+ });
153
+ }
154
+ return events;
155
+ }
156
+
157
+ function valueCounts(
158
+ events: readonly WideEvent[],
159
+ dim: string,
160
+ ): Map<string, number> {
161
+ const m = new Map<string, number>();
162
+ for (const e of events) {
163
+ const raw = e.dimensions[dim];
164
+ if (raw === undefined || raw === null) continue;
165
+ const key = String(raw);
166
+ m.set(key, (m.get(key) ?? 0) + 1);
167
+ }
168
+ return m;
169
+ }
170
+
171
+ function formatExplanation(
172
+ dim: string,
173
+ value: string,
174
+ outlierShare: number,
175
+ baselineShare: number,
176
+ ): string {
177
+ const o = Math.round(outlierShare * 100);
178
+ const b = Math.round(baselineShare * 100);
179
+ return `${o}% ${dim}=${value} vs ${b}%`;
180
+ }
@@ -0,0 +1,210 @@
1
+ /**
2
+ * Parquet partition writer — DuckDB `COPY … (FORMAT PARQUET)`.
3
+ *
4
+ * Locality (local vs object storage) is decided by the files driver; this
5
+ * module only serialises wide events into columnar files.
6
+ */
7
+
8
+ import { mkdir, unlink, writeFile } from "node:fs/promises";
9
+ import { dirname, join } from "node:path";
10
+
11
+ import { duckPath, duckQuery, openDuckDB } from "./duckdb.ts";
12
+ import type { WideEvent } from "./types.ts";
13
+
14
+ /** Flattened Parquet / SQL row. */
15
+ export type ParquetRow = Record<string, string | number | boolean | null>;
16
+
17
+ /**
18
+ * Flatten a wide event into a columnar row.
19
+ *
20
+ * Structured fields become JSON strings; scalar dimensions are promoted to
21
+ * top-level columns for outlier / filter queries.
22
+ *
23
+ * @param event - Wide event
24
+ */
25
+ export function wideEventToRow(event: WideEvent): ParquetRow {
26
+ const row: ParquetRow = {
27
+ id: event.id,
28
+ parent_id: event.parentId ?? null,
29
+ flow: event.flow,
30
+ unit: event.unit ?? null,
31
+ trigger: event.trigger,
32
+ plane: event.plane,
33
+ tenant: event.tenant ?? null,
34
+ principal: event.principal ?? null,
35
+ subject_id: event.subjectId ?? null,
36
+ gates: JSON.stringify(event.gates),
37
+ cache: event.cache,
38
+ replica: event.replica ?? null,
39
+ replica_lag_ms: event.replicaLagMs ?? null,
40
+ cost: event.cost ?? null,
41
+ prompt_version: event.promptVersion ?? null,
42
+ build_version: event.buildVersion ?? null,
43
+ error_code: event.error?.code ?? null,
44
+ error_message: event.error?.message ?? null,
45
+ effects: JSON.stringify(event.effects),
46
+ logs: JSON.stringify(event.logs),
47
+ duration_ms: event.durationMs,
48
+ started_at: event.startedAt,
49
+ ended_at: event.endedAt,
50
+ archived: JSON.stringify(event.archived ?? {}),
51
+ dimensions: JSON.stringify(event.dimensions),
52
+ };
53
+ for (const [k, v] of Object.entries(event.dimensions)) {
54
+ const col = `dim_${k}`;
55
+ if (row[col] !== undefined) continue;
56
+ if (v === undefined) continue;
57
+ row[col] =
58
+ typeof v === "string" || typeof v === "number" || typeof v === "boolean"
59
+ ? v
60
+ : v === null
61
+ ? null
62
+ : String(v);
63
+ }
64
+ return row;
65
+ }
66
+
67
+ /**
68
+ * Reconstruct a {@link WideEvent} from a Parquet / SQL row.
69
+ *
70
+ * @param row - Flat row
71
+ */
72
+ export function rowToWideEvent(row: Record<string, unknown>): WideEvent {
73
+ const dimensions =
74
+ typeof row.dimensions === "string"
75
+ ? (JSON.parse(row.dimensions) as WideEvent["dimensions"])
76
+ : ((row.dimensions as WideEvent["dimensions"]) ?? {});
77
+ const archivedRaw =
78
+ typeof row.archived === "string"
79
+ ? (JSON.parse(row.archived) as Record<string, string>)
80
+ : ((row.archived as Record<string, string>) ?? {});
81
+ const errorCode = row.error_code;
82
+ return {
83
+ id: String(row.id),
84
+ ...(row.parent_id != null ? { parentId: String(row.parent_id) } : {}),
85
+ flow: String(row.flow),
86
+ ...(row.unit != null ? { unit: String(row.unit) } : {}),
87
+ trigger: String(row.trigger),
88
+ plane: (row.plane as WideEvent["plane"]) ?? "user",
89
+ tenant: row.tenant != null ? String(row.tenant) : null,
90
+ principal: row.principal != null ? String(row.principal) : null,
91
+ subjectId: row.subject_id != null ? String(row.subject_id) : null,
92
+ gates: parseJsonArray(row.gates) as string[],
93
+ cache: (row.cache as WideEvent["cache"]) ?? "none",
94
+ ...(row.replica != null
95
+ ? { replica: row.replica as "primary" | "replica" }
96
+ : {}),
97
+ ...(row.replica_lag_ms != null
98
+ ? { replicaLagMs: Number(row.replica_lag_ms) }
99
+ : {}),
100
+ ...(row.cost != null ? { cost: Number(row.cost) } : {}),
101
+ ...(row.prompt_version != null
102
+ ? { promptVersion: Number(row.prompt_version) }
103
+ : {}),
104
+ ...(row.build_version != null
105
+ ? { buildVersion: String(row.build_version) }
106
+ : {}),
107
+ error:
108
+ errorCode != null
109
+ ? {
110
+ code: String(errorCode),
111
+ ...(row.error_message != null
112
+ ? { message: String(row.error_message) }
113
+ : {}),
114
+ }
115
+ : null,
116
+ effects: parseJsonArray(row.effects) as WideEvent["effects"],
117
+ logs: parseJsonArray(row.logs) as WideEvent["logs"],
118
+ durationMs: Number(row.duration_ms ?? 0),
119
+ startedAt: Number(row.started_at ?? 0),
120
+ endedAt: Number(row.ended_at ?? 0),
121
+ ...(Object.keys(archivedRaw).length > 0 ? { archived: archivedRaw } : {}),
122
+ dimensions,
123
+ };
124
+ }
125
+
126
+ /**
127
+ * Write rows to a Parquet file via DuckDB (JSONL → COPY).
128
+ *
129
+ * @param path - Absolute output path
130
+ * @param rows - Flattened rows
131
+ */
132
+ export async function writeParquet(
133
+ path: string,
134
+ rows: readonly ParquetRow[],
135
+ ): Promise<void> {
136
+ if (rows.length === 0) return;
137
+ await mkdir(dirname(path), { recursive: true });
138
+ const jsonl = `${path}.jsonl`;
139
+ await writeFile(
140
+ jsonl,
141
+ rows.map((r) => JSON.stringify(r)).join("\n"),
142
+ );
143
+ const session = await openDuckDB();
144
+ try {
145
+ await session.conn.run(
146
+ `COPY (SELECT * FROM read_json_auto('${duckPath(jsonl)}')) TO '${duckPath(path)}' (FORMAT PARQUET, COMPRESSION ZSTD)`,
147
+ );
148
+ } finally {
149
+ session.close();
150
+ await unlink(jsonl).catch(() => undefined);
151
+ }
152
+ }
153
+
154
+ /**
155
+ * Read all rows from one or more Parquet files.
156
+ *
157
+ * @param paths - Absolute Parquet paths
158
+ */
159
+ export async function readParquet(
160
+ paths: readonly string[],
161
+ ): Promise<ParquetRow[]> {
162
+ if (paths.length === 0) return [];
163
+ const session = await openDuckDB();
164
+ try {
165
+ const list = paths.map((p) => `'${duckPath(p)}'`).join(", ");
166
+ const rows = await duckQuery(
167
+ session.conn,
168
+ `SELECT * FROM read_parquet([${list}], union_by_name = true)`,
169
+ );
170
+ return rows as ParquetRow[];
171
+ } finally {
172
+ session.close();
173
+ }
174
+ }
175
+
176
+ /**
177
+ * Partition key from an event timestamp (day UTC).
178
+ *
179
+ * @param startedAt - Epoch-ms
180
+ */
181
+ export function partitionKey(startedAt: number): string {
182
+ const d = new Date(startedAt);
183
+ const y = d.getUTCFullYear();
184
+ const m = String(d.getUTCMonth() + 1).padStart(2, "0");
185
+ const day = String(d.getUTCDate()).padStart(2, "0");
186
+ return `${y}-${m}-${day}`;
187
+ }
188
+
189
+ /**
190
+ * Build a partition object key.
191
+ *
192
+ * @param day - Partition day
193
+ * @param id - Unique file id
194
+ */
195
+ export function partitionObjectKey(day: string, id: string): string {
196
+ return join("runs", `day=${day}`, `${id}.parquet`);
197
+ }
198
+
199
+ function parseJsonArray(value: unknown): unknown[] {
200
+ if (Array.isArray(value)) return value;
201
+ if (typeof value === "string" && value.length > 0) {
202
+ try {
203
+ const parsed: unknown = JSON.parse(value);
204
+ return Array.isArray(parsed) ? parsed : [];
205
+ } catch {
206
+ return [];
207
+ }
208
+ }
209
+ return [];
210
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Privacy erase — crypto-shred a subject across the runs store (and later
3
+ * journal / channel receipts). Deletes the Vault key, not the terabytes.
4
+ */
5
+
6
+ import {
7
+ eraseSubject,
8
+ subjectKeyName,
9
+ type SubjectKeyVault,
10
+ } from "./shred.ts";
11
+
12
+ /** Options for {@link privacyErase}. */
13
+ export interface PrivacyEraseOptions {
14
+ /** Subject to erase. */
15
+ readonly subjectId: string;
16
+ /** Subject-key vault (required). */
17
+ readonly subjectKeys: SubjectKeyVault;
18
+ /** Write stdout. */
19
+ readonly write?: (text: string) => void;
20
+ }
21
+
22
+ /** Result of a privacy erase. */
23
+ export interface PrivacyEraseResult {
24
+ /** Subject id. */
25
+ readonly subjectId: string;
26
+ /** Vault key that was targeted. */
27
+ readonly key: string;
28
+ /** Whether the key existed and was deleted. */
29
+ readonly deleted: boolean;
30
+ }
31
+
32
+ /**
33
+ * Crypto-shred a subject by deleting their per-subject Vault key.
34
+ *
35
+ * @param options - Subject + vault
36
+ */
37
+ export function privacyErase(
38
+ options: PrivacyEraseOptions,
39
+ ): PrivacyEraseResult {
40
+ const key = subjectKeyName(options.subjectId);
41
+ const deleted = eraseSubject(options.subjectKeys, options.subjectId);
42
+ const write = options.write ?? ((t) => process.stdout.write(t));
43
+ write(
44
+ deleted
45
+ ? `oke privacy erase: shredded subject ${options.subjectId} (deleted ${key})\n`
46
+ : `oke privacy erase: no key for subject ${options.subjectId} (${key})\n`,
47
+ );
48
+ return { subjectId: options.subjectId, key, deleted };
49
+ }