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,632 @@
1
+ /**
2
+ * Console AI projection — AiRuntime journal / denial ledger + Manifest
3
+ * + wide events (console §9.10).
4
+ *
5
+ * The UI must not recompute cost or re-derive denials.
6
+ */
7
+
8
+ import { mockAiDriver } from "../../drivers/ai-mock.ts";
9
+ import {
10
+ ai,
11
+ createAiRuntime,
12
+ type AgentDenial,
13
+ type AgentRunRecord,
14
+ type AgentToolEffect,
15
+ type AiAskOutcome,
16
+ type AiFallbackAttempt,
17
+ type AiJournalEntry,
18
+ type AiRuntime,
19
+ type EvalSuiteResult,
20
+ } from "../../elements/ai.ts";
21
+ import type { Manifest } from "../../manifest/types.ts";
22
+ import type { WideEvent } from "../../runs/types.ts";
23
+
24
+ /** One numeric sample in a distribution. */
25
+ export interface AiSample {
26
+ readonly value: number;
27
+ readonly at: number;
28
+ readonly version?: number;
29
+ }
30
+
31
+ /** Histogram bucket for a metric distribution. */
32
+ export interface AiDistributionBucket {
33
+ readonly min: number;
34
+ readonly max: number;
35
+ readonly count: number;
36
+ }
37
+
38
+ /** Per-prompt-version quality / cost metrics (real numbers). */
39
+ export interface PromptVersionMetrics {
40
+ readonly prompt: string;
41
+ readonly version: number;
42
+ readonly sampleCount: number;
43
+ readonly cost: {
44
+ readonly samples: readonly number[];
45
+ readonly mean: number;
46
+ readonly p50: number;
47
+ readonly p95: number;
48
+ readonly buckets: readonly AiDistributionBucket[];
49
+ };
50
+ readonly latencyMs: {
51
+ readonly samples: readonly number[];
52
+ readonly mean: number;
53
+ readonly p50: number;
54
+ readonly p95: number;
55
+ readonly buckets: readonly AiDistributionBucket[];
56
+ };
57
+ readonly evalScore: {
58
+ readonly samples: readonly number[];
59
+ readonly mean: number;
60
+ readonly buckets: readonly AiDistributionBucket[];
61
+ };
62
+ /** Schema-invalid rate — distinct from provider errors. */
63
+ readonly schemaInvalidRate: number;
64
+ readonly providerErrorRate: number;
65
+ readonly okRate: number;
66
+ readonly overBudgetRate: number;
67
+ readonly budgetMaxCostPerCall: number | null;
68
+ readonly outcomeCounts: Readonly<Record<AiAskOutcome, number>>;
69
+ }
70
+
71
+ /** Standing security-review row for `allowPii`. */
72
+ export interface AllowPiiRow {
73
+ readonly flowId: string;
74
+ readonly asks: readonly string[];
75
+ readonly pii: "masked" | "allow" | "denied" | null;
76
+ readonly allowPii: boolean;
77
+ readonly source: string | null;
78
+ }
79
+
80
+ /** Fallback chain with cost consequence vs primary-only. */
81
+ export interface FallbackChainRow {
82
+ readonly prompt: string;
83
+ readonly version: number | undefined;
84
+ readonly attempts: readonly AiFallbackAttempt[];
85
+ readonly actualCost: number;
86
+ readonly primaryOnlyCost: number | null;
87
+ readonly costConsequence: number | null;
88
+ readonly at: number;
89
+ }
90
+
91
+ /** Agent run projection — trail from the denial ledger. */
92
+ export interface AgentRunRow {
93
+ readonly id: string;
94
+ readonly agent: string;
95
+ readonly message: string;
96
+ readonly ok: boolean;
97
+ readonly steps: number;
98
+ readonly cost: number;
99
+ readonly at: number;
100
+ readonly trail: ReadonlyArray<{
101
+ readonly tool: string;
102
+ readonly status: "ok" | "denied";
103
+ readonly effects: readonly AgentToolEffect[];
104
+ readonly denial: AgentDenial | null;
105
+ readonly at: number;
106
+ }>;
107
+ readonly denials: readonly AgentDenial[];
108
+ }
109
+
110
+ /** Catalogue prompt row. */
111
+ export interface PromptCatalogueRow {
112
+ readonly name: string;
113
+ readonly version: number | undefined;
114
+ readonly model: string | undefined;
115
+ readonly evals: string | undefined;
116
+ readonly budgetMaxCostPerCall: number | null;
117
+ /** Manifest Diff deep-link path for a version bump. */
118
+ readonly manifestDiffPath: string;
119
+ }
120
+
121
+ /** Catalogue agent row. */
122
+ export interface AgentCatalogueRow {
123
+ readonly name: string;
124
+ readonly tools: readonly string[];
125
+ readonly maxSteps: number | undefined;
126
+ readonly model: string | undefined;
127
+ readonly budgetMaxCostPerRun: number | null;
128
+ }
129
+
130
+ /** Full AI panel projection. */
131
+ export interface ConsoleAiProjection {
132
+ readonly prompts: readonly PromptCatalogueRow[];
133
+ readonly agents: readonly AgentCatalogueRow[];
134
+ readonly versions: readonly PromptVersionMetrics[];
135
+ readonly allowPii: readonly AllowPiiRow[];
136
+ readonly fallbackChains: readonly FallbackChainRow[];
137
+ readonly agentRuns: readonly AgentRunRow[];
138
+ readonly denials: readonly AgentDenial[];
139
+ readonly journal: readonly AiJournalEntry[];
140
+ }
141
+
142
+ /** Options for {@link projectAiPanel}. */
143
+ export interface ProjectAiOptions {
144
+ readonly manifest: Manifest | null;
145
+ readonly aiRuntime: AiRuntime | null;
146
+ readonly runs?: readonly WideEvent[];
147
+ readonly evalResults?: readonly EvalSuiteResult[];
148
+ readonly bucketCount?: number;
149
+ }
150
+
151
+ /**
152
+ * Build an {@link AiRuntime} from Manifest AI catalogue (mock driver default).
153
+ * Agent tool effects come from Manifest flow declarations — the denial ledger
154
+ * records them; the UI must not re-derive.
155
+ *
156
+ * @param manifest - Manifest
157
+ * @param options - Clock
158
+ */
159
+ export function createManifestAiRuntime(
160
+ manifest: Manifest | null,
161
+ options: { readonly now?: () => number } = {},
162
+ ): AiRuntime {
163
+ const models = Object.entries(manifest?.ai?.models ?? {}).map(([name, m]) =>
164
+ ai.model(name, {
165
+ ...(m.provider !== undefined ? { provider: m.provider } : {}),
166
+ ...(m.tier !== undefined ? { tier: m.tier } : {}),
167
+ ...(m.model !== undefined ? { model: m.model } : {}),
168
+ }),
169
+ );
170
+ const modelByName = new Map(models.map((m) => [m.name, m]));
171
+ const prompts = Object.entries(manifest?.ai?.prompts ?? {}).map(
172
+ ([name, p]) => {
173
+ const modelName = p.model ?? models[0]?.name ?? "mock";
174
+ const handle = modelByName.get(modelName) ?? ai.model(modelName);
175
+ return handle.prompt(name, {
176
+ ...(p.version !== undefined ? { version: p.version } : {}),
177
+ ...(p.evals !== undefined ? { evals: p.evals } : {}),
178
+ ...(p.budget !== undefined ? { budget: p.budget } : {}),
179
+ ...(p.in !== undefined ? { in: p.in } : {}),
180
+ ...(p.out !== undefined ? { out: p.out } : {}),
181
+ });
182
+ },
183
+ );
184
+ const agents = Object.entries(manifest?.ai?.agents ?? {}).map(([name, a]) =>
185
+ ai.agent(name, {
186
+ tools: a.tools ?? [],
187
+ ...(a.maxSteps !== undefined ? { maxSteps: a.maxSteps } : {}),
188
+ ...(a.budget !== undefined ? { budget: a.budget } : {}),
189
+ ...(a.model !== undefined ? { model: a.model } : {}),
190
+ }),
191
+ );
192
+
193
+ return createAiRuntime({
194
+ models:
195
+ models.length > 0
196
+ ? models
197
+ : prompts.length > 0
198
+ ? [ai.model("mock", { provider: "mock" })]
199
+ : [],
200
+ prompts,
201
+ agents,
202
+ defaultDriver: mockAiDriver,
203
+ effectsForFlow: (flowName) =>
204
+ effectsForFlowFromManifest(manifest, flowName),
205
+ now: options.now,
206
+ });
207
+ }
208
+
209
+ /**
210
+ * Project AI panel data from Manifest + AiRuntime + runs + eval history.
211
+ *
212
+ * @param options - Sources
213
+ */
214
+ export function projectAiPanel(options: ProjectAiOptions): ConsoleAiProjection {
215
+ const manifest = options.manifest;
216
+ const runtime = options.aiRuntime;
217
+ const bucketCount = options.bucketCount ?? 10;
218
+
219
+ const prompts: PromptCatalogueRow[] = [];
220
+ const promptMeta = new Map<
221
+ string,
222
+ { version?: number; budget?: number | null; model?: string }
223
+ >();
224
+
225
+ for (const [name, p] of Object.entries(manifest?.ai?.prompts ?? {})) {
226
+ const budget = p.budget?.maxCostPerCall ?? null;
227
+ prompts.push({
228
+ name,
229
+ version: p.version,
230
+ model: p.model,
231
+ evals: p.evals,
232
+ budgetMaxCostPerCall: budget,
233
+ manifestDiffPath: `/ai/prompts/${name}/version`,
234
+ });
235
+ promptMeta.set(name, {
236
+ version: p.version,
237
+ budget,
238
+ model: p.model,
239
+ });
240
+ }
241
+ if (runtime) {
242
+ for (const [name, p] of runtime.prompts) {
243
+ if (promptMeta.has(name)) continue;
244
+ const budget = p.budget?.maxCostPerCall ?? null;
245
+ prompts.push({
246
+ name,
247
+ version: p.version,
248
+ model: p.model,
249
+ evals: p.evals,
250
+ budgetMaxCostPerCall: budget,
251
+ manifestDiffPath: `/ai/prompts/${name}/version`,
252
+ });
253
+ promptMeta.set(name, {
254
+ version: p.version,
255
+ budget,
256
+ model: p.model,
257
+ });
258
+ }
259
+ }
260
+ prompts.sort((a, b) => a.name.localeCompare(b.name));
261
+
262
+ const agents: AgentCatalogueRow[] = [];
263
+ for (const [name, a] of Object.entries(manifest?.ai?.agents ?? {})) {
264
+ agents.push({
265
+ name,
266
+ tools: a.tools ?? [],
267
+ maxSteps: a.maxSteps,
268
+ model: a.model,
269
+ budgetMaxCostPerRun: a.budget?.maxCostPerRun ?? null,
270
+ });
271
+ }
272
+ if (runtime) {
273
+ for (const [name, a] of runtime.agents) {
274
+ if (agents.some((x) => x.name === name)) continue;
275
+ agents.push({
276
+ name,
277
+ tools: a.tools,
278
+ maxSteps: a.maxSteps,
279
+ model: a.model,
280
+ budgetMaxCostPerRun: a.budget?.maxCostPerRun ?? null,
281
+ });
282
+ }
283
+ }
284
+ agents.sort((a, b) => a.name.localeCompare(b.name));
285
+
286
+ const journal = runtime?.journal ?? [];
287
+ const versions = buildVersionMetrics({
288
+ journal,
289
+ runs: options.runs ?? [],
290
+ evalResults: options.evalResults ?? [],
291
+ promptMeta,
292
+ bucketCount,
293
+ });
294
+
295
+ const allowPii = projectAllowPii(manifest);
296
+ const fallbackChains = projectFallbackChains(journal);
297
+ const agentRuns = projectAgentRuns(runtime?.agentRuns ?? []);
298
+ const denials = runtime?.denials ?? [];
299
+
300
+ return {
301
+ prompts,
302
+ agents,
303
+ versions,
304
+ allowPii,
305
+ fallbackChains,
306
+ agentRuns,
307
+ denials,
308
+ journal,
309
+ };
310
+ }
311
+
312
+ /**
313
+ * Resolve Manifest effects for a tool flow into the agent trail vocabulary.
314
+ *
315
+ * @param manifest - Manifest
316
+ * @param flowName - Tool / flow name
317
+ */
318
+ export function effectsForFlowFromManifest(
319
+ manifest: Manifest | null,
320
+ flowName: string,
321
+ ): readonly AgentToolEffect[] {
322
+ const flow = manifest?.flows?.[flowName];
323
+ if (!flow?.effects) return [];
324
+ const out: AgentToolEffect[] = [];
325
+ for (const r of flow.effects.reads ?? []) {
326
+ out.push({ kind: "read", resource: r });
327
+ }
328
+ for (const r of flow.effects.writes ?? []) {
329
+ out.push({ kind: "write", resource: r });
330
+ }
331
+ for (const r of flow.effects.emits ?? []) {
332
+ out.push({ kind: "emit", resource: r });
333
+ }
334
+ for (const r of flow.effects.sends ?? []) {
335
+ out.push({ kind: "send", resource: r });
336
+ }
337
+ for (const r of flow.effects.asks ?? []) {
338
+ out.push({ kind: "ask", resource: r });
339
+ }
340
+ for (const r of flow.effects.secrets ?? []) {
341
+ out.push({ kind: "secret", resource: r });
342
+ }
343
+ for (const r of flow.effects.calls ?? []) {
344
+ out.push({ kind: "call", resource: r });
345
+ }
346
+ return out;
347
+ }
348
+
349
+ /**
350
+ * Standing `allowPii` security-review table from Manifest flows.
351
+ *
352
+ * @param manifest - Manifest
353
+ */
354
+ export function projectAllowPii(manifest: Manifest | null): readonly AllowPiiRow[] {
355
+ if (!manifest?.flows) return [];
356
+ const rows: AllowPiiRow[] = [];
357
+ for (const [flowId, flow] of Object.entries(manifest.flows)) {
358
+ const allow =
359
+ flow.allowPii === true || flow.pii === "allow";
360
+ const asks = flow.effects?.asks ?? [];
361
+ if (!allow && asks.length === 0) continue;
362
+ if (!allow && flow.pii === undefined) continue;
363
+ rows.push({
364
+ flowId,
365
+ asks: [...asks],
366
+ pii: flow.pii ?? null,
367
+ allowPii: allow,
368
+ source: flow.source ?? null,
369
+ });
370
+ }
371
+ // Prefer rows that actually acknowledge PII egress
372
+ return rows
373
+ .filter((r) => r.allowPii || r.asks.length > 0)
374
+ .sort((a, b) => {
375
+ if (a.allowPii !== b.allowPii) return a.allowPii ? -1 : 1;
376
+ return a.flowId.localeCompare(b.flowId);
377
+ });
378
+ }
379
+
380
+ function projectFallbackChains(
381
+ journal: readonly AiJournalEntry[],
382
+ ): readonly FallbackChainRow[] {
383
+ const rows: FallbackChainRow[] = [];
384
+ for (const entry of journal) {
385
+ if (entry.attempts.length < 2) continue;
386
+ const primary = entry.attempts[0];
387
+ const primaryOnlyCost =
388
+ primary?.ok && primary.cost !== undefined
389
+ ? primary.cost
390
+ : primary && !primary.ok
391
+ ? null
392
+ : (primary?.cost ?? null);
393
+ // Cost consequence: actual chain cost minus what primary-only would have been
394
+ // when primary succeeded; when primary failed, consequence is the full chain cost.
395
+ let costConsequence: number | null = null;
396
+ if (primary && !primary.ok) {
397
+ costConsequence = entry.cost;
398
+ } else if (primaryOnlyCost !== null) {
399
+ costConsequence = entry.cost - primaryOnlyCost;
400
+ }
401
+ rows.push({
402
+ prompt: entry.prompt,
403
+ version: entry.version,
404
+ attempts: entry.attempts,
405
+ actualCost: entry.cost,
406
+ primaryOnlyCost,
407
+ costConsequence,
408
+ at: entry.at,
409
+ });
410
+ }
411
+ return rows.sort((a, b) => b.at - a.at);
412
+ }
413
+
414
+ function projectAgentRuns(
415
+ runs: readonly AgentRunRecord[],
416
+ ): readonly AgentRunRow[] {
417
+ return [...runs]
418
+ .sort((a, b) => b.at - a.at)
419
+ .map((r) => ({
420
+ id: r.id,
421
+ agent: r.agent,
422
+ message: r.message,
423
+ ok: r.ok,
424
+ steps: r.steps,
425
+ cost: r.cost,
426
+ at: r.at,
427
+ trail: r.trail.map((step) => ({
428
+ tool: step.tool,
429
+ status: step.status,
430
+ effects: step.effects,
431
+ denial: step.denial ?? null,
432
+ at: step.at,
433
+ })),
434
+ denials: r.denials,
435
+ }));
436
+ }
437
+
438
+ function buildVersionMetrics(input: {
439
+ readonly journal: readonly AiJournalEntry[];
440
+ readonly runs: readonly WideEvent[];
441
+ readonly evalResults: readonly EvalSuiteResult[];
442
+ readonly promptMeta: Map<
443
+ string,
444
+ { version?: number; budget?: number | null; model?: string }
445
+ >;
446
+ readonly bucketCount: number;
447
+ }): readonly PromptVersionMetrics[] {
448
+ type Acc = {
449
+ prompt: string;
450
+ version: number;
451
+ costs: number[];
452
+ latencies: number[];
453
+ evals: number[];
454
+ outcomes: Record<AiAskOutcome, number>;
455
+ overBudget: number;
456
+ budget: number | null;
457
+ };
458
+ const map = new Map<string, Acc>();
459
+
460
+ const keyOf = (prompt: string, version: number) => `${prompt}@${version}`;
461
+
462
+ const ensure = (prompt: string, version: number): Acc => {
463
+ const k = keyOf(prompt, version);
464
+ let acc = map.get(k);
465
+ if (!acc) {
466
+ const meta = input.promptMeta.get(prompt);
467
+ acc = {
468
+ prompt,
469
+ version,
470
+ costs: [],
471
+ latencies: [],
472
+ evals: [],
473
+ outcomes: { ok: 0, provider_error: 0, schema_invalid: 0 },
474
+ overBudget: 0,
475
+ budget: meta?.budget ?? null,
476
+ };
477
+ map.set(k, acc);
478
+ }
479
+ return acc;
480
+ };
481
+
482
+ for (const entry of input.journal) {
483
+ const version =
484
+ entry.version ??
485
+ input.promptMeta.get(entry.prompt)?.version ??
486
+ 0;
487
+ const acc = ensure(entry.prompt, version);
488
+ acc.costs.push(entry.cost);
489
+ acc.latencies.push(entry.latencyMs);
490
+ acc.outcomes[entry.outcome] += 1;
491
+ if (acc.budget !== null && entry.cost > acc.budget) {
492
+ acc.overBudget += 1;
493
+ }
494
+ }
495
+
496
+ // Wide events contribute cost / latency when promptVersion is present
497
+ for (const run of input.runs) {
498
+ const ask = run.effects.find((e) => e.kind === "ask");
499
+ if (!ask) continue;
500
+ const prompt = ask.resource.replace(/^ask:/, "");
501
+ const version = run.promptVersion;
502
+ if (version === undefined) continue;
503
+ const acc = ensure(prompt, version);
504
+ if (run.cost !== undefined) acc.costs.push(run.cost);
505
+ acc.latencies.push(run.durationMs);
506
+ if (run.error?.code === "AiSchemaInvalid") {
507
+ acc.outcomes.schema_invalid += 1;
508
+ } else if (run.error) {
509
+ acc.outcomes.provider_error += 1;
510
+ } else {
511
+ acc.outcomes.ok += 1;
512
+ }
513
+ const budget = acc.budget;
514
+ if (budget !== null && (run.cost ?? 0) > budget) {
515
+ acc.overBudget += 1;
516
+ }
517
+ }
518
+
519
+ for (const suite of input.evalResults) {
520
+ const version = suite.version ?? input.promptMeta.get(suite.prompt)?.version;
521
+ if (version === undefined) continue;
522
+ const total = suite.passed + suite.failed;
523
+ if (total === 0) continue;
524
+ const score = suite.passed / total;
525
+ ensure(suite.prompt, version).evals.push(score);
526
+ }
527
+
528
+ const out: PromptVersionMetrics[] = [];
529
+ for (const acc of map.values()) {
530
+ const totalOutcomes =
531
+ acc.outcomes.ok +
532
+ acc.outcomes.provider_error +
533
+ acc.outcomes.schema_invalid;
534
+ out.push({
535
+ prompt: acc.prompt,
536
+ version: acc.version,
537
+ sampleCount: Math.max(acc.costs.length, totalOutcomes),
538
+ cost: metricBlock(acc.costs, input.bucketCount),
539
+ latencyMs: metricBlock(acc.latencies, input.bucketCount),
540
+ evalScore: metricBlock(acc.evals, input.bucketCount),
541
+ schemaInvalidRate:
542
+ totalOutcomes === 0 ? 0 : acc.outcomes.schema_invalid / totalOutcomes,
543
+ providerErrorRate:
544
+ totalOutcomes === 0 ? 0 : acc.outcomes.provider_error / totalOutcomes,
545
+ okRate: totalOutcomes === 0 ? 0 : acc.outcomes.ok / totalOutcomes,
546
+ overBudgetRate:
547
+ acc.costs.length === 0 ? 0 : acc.overBudget / acc.costs.length,
548
+ budgetMaxCostPerCall: acc.budget,
549
+ outcomeCounts: acc.outcomes,
550
+ });
551
+ }
552
+
553
+ return out.sort((a, b) => {
554
+ const byPrompt = a.prompt.localeCompare(b.prompt);
555
+ if (byPrompt !== 0) return byPrompt;
556
+ return a.version - b.version;
557
+ });
558
+ }
559
+
560
+ function metricBlock(
561
+ samples: readonly number[],
562
+ bucketCount: number,
563
+ ): PromptVersionMetrics["cost"] {
564
+ const sorted = [...samples].sort((a, b) => a - b);
565
+ return {
566
+ samples: sorted,
567
+ mean: mean(sorted),
568
+ p50: percentile(sorted, 0.5),
569
+ p95: percentile(sorted, 0.95),
570
+ buckets: histogram(sorted, bucketCount),
571
+ };
572
+ }
573
+
574
+ /**
575
+ * Arithmetic mean (0 when empty).
576
+ *
577
+ * @param values - Samples
578
+ */
579
+ export function mean(values: readonly number[]): number {
580
+ if (values.length === 0) return 0;
581
+ return values.reduce((a, b) => a + b, 0) / values.length;
582
+ }
583
+
584
+ /**
585
+ * Nearest-rank percentile (0 when empty).
586
+ *
587
+ * @param sorted - Ascending samples
588
+ * @param p - Percentile in [0, 1]
589
+ */
590
+ export function percentile(sorted: readonly number[], p: number): number {
591
+ if (sorted.length === 0) return 0;
592
+ if (sorted.length === 1) return sorted[0]!;
593
+ const idx = Math.min(
594
+ sorted.length - 1,
595
+ Math.max(0, Math.ceil(p * sorted.length) - 1),
596
+ );
597
+ return sorted[idx]!;
598
+ }
599
+
600
+ /**
601
+ * Equal-width histogram over samples.
602
+ *
603
+ * @param sorted - Ascending samples
604
+ * @param bucketCount - Buckets
605
+ */
606
+ export function histogram(
607
+ sorted: readonly number[],
608
+ bucketCount: number,
609
+ ): readonly AiDistributionBucket[] {
610
+ if (sorted.length === 0 || bucketCount < 1) return [];
611
+ const min = sorted[0]!;
612
+ const max = sorted[sorted.length - 1]!;
613
+ if (min === max) {
614
+ return [{ min, max: max + Number.EPSILON, count: sorted.length }];
615
+ }
616
+ const width = (max - min) / bucketCount;
617
+ const buckets: AiDistributionBucket[] = [];
618
+ for (let i = 0; i < bucketCount; i++) {
619
+ const lo = min + i * width;
620
+ const hi =
621
+ i === bucketCount - 1 ? max + Number.EPSILON : min + (i + 1) * width;
622
+ buckets.push({ min: lo, max: hi, count: 0 });
623
+ }
624
+ for (const v of sorted) {
625
+ let idx = Math.floor((v - min) / width);
626
+ if (idx < 0) idx = 0;
627
+ if (idx >= bucketCount) idx = bucketCount - 1;
628
+ const b = buckets[idx]!;
629
+ buckets[idx] = { ...b, count: b.count + 1 };
630
+ }
631
+ return buckets;
632
+ }