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,430 @@
1
+ /**
2
+ * Console Vault projection — Manifest + VaultRuntime over `fx` (console §9.8).
3
+ *
4
+ * Secrets are write-only: fingerprints only, never cleartext. Config
5
+ * (non-sensitive) may appear in the clear. Resolution chain, readers, and
6
+ * rotation blast radius are derived — never reimplemented in the UI.
7
+ */
8
+
9
+ import { resolve } from "node:path";
10
+ import type { ConfigEnv } from "../../config/index.ts";
11
+ import { envVaultDriver, memoryVaultDriver } from "../../drivers/index.ts";
12
+ import {
13
+ createVaultRuntime,
14
+ vault as declareVault,
15
+ type VaultResolutionSource,
16
+ type VaultResolutionStep,
17
+ type VaultRuntime,
18
+ type VaultSecretDecl,
19
+ } from "../../elements/vault.ts";
20
+ import type { JournalRun, JournalStore } from "../../kernel/journal.ts";
21
+ import type { Manifest } from "../../manifest/types.ts";
22
+
23
+ /** Environment label for fingerprint columns. */
24
+ export type VaultEnvLabel = ConfigEnv | "staging" | (string & {});
25
+
26
+ /** Fingerprints keyed by environment — never values. */
27
+ export type VaultFingerprintsByEnv = Readonly<
28
+ Partial<Record<VaultEnvLabel, string>>
29
+ >;
30
+
31
+ /** Rotation blast radius from the durable journal (queried, not estimated). */
32
+ export interface ConsoleVaultBlastRadius {
33
+ /** Count of in-flight sleeping durable runs that declare this secret. */
34
+ readonly count: number;
35
+ /** Absolute epoch-ms of the furthest outstanding wake (`null` when count=0). */
36
+ readonly longestWakeAt: number | null;
37
+ /** Milliseconds until {@link longestWakeAt} from `now` (clamped ≥ 0). */
38
+ readonly longestOutstandingMs: number | null;
39
+ /** Run ids contributing to the blast radius (for Clock deep-links). */
40
+ readonly runIds: readonly string[];
41
+ }
42
+
43
+ /** One row in `console.vault.list`. */
44
+ export interface ConsoleVaultRow {
45
+ readonly name: string;
46
+ /** `"secret"` is fingerprinted; `"config"` may show cleartext. */
47
+ readonly kind: "secret" | "config";
48
+ readonly sensitive: boolean;
49
+ readonly description?: string;
50
+ readonly rotate?: string;
51
+ /**
52
+ * Per-environment fingerprints. Secrets only — config leaves this empty
53
+ * and uses {@link cleartext} instead.
54
+ */
55
+ readonly fingerprints: VaultFingerprintsByEnv;
56
+ /** Current environment's fingerprint (convenience). */
57
+ readonly fingerprint: string | null;
58
+ /** Cleartext for non-sensitive config only; always `null` for secrets. */
59
+ readonly cleartext: string | null;
60
+ /** Which layer won in the current environment. */
61
+ readonly winner: VaultResolutionSource | null;
62
+ /** Full resolution chain for the current environment. */
63
+ readonly resolution: readonly VaultResolutionStep[];
64
+ /** Flow ids that declare `fx.vault(name)` in Manifest effects. */
65
+ readonly readers: readonly string[];
66
+ /** In-flight durable runs that will wake holding a new key after rotate. */
67
+ readonly blastRadius: ConsoleVaultBlastRadius;
68
+ /** Epoch-ms of last `fx.vault` / runtime read; `null` if never read. */
69
+ readonly lastReadAt: number | null;
70
+ /**
71
+ * When the current fingerprint equals another environment's — warning,
72
+ * not error (may be deliberate).
73
+ */
74
+ readonly sharedFingerprintEnvs: readonly VaultEnvLabel[];
75
+ }
76
+
77
+ /** Options when projecting the vault list. */
78
+ export interface ProjectVaultOptions {
79
+ readonly manifest: Manifest | null;
80
+ readonly runtime: VaultRuntime | null;
81
+ /** Current process environment label. */
82
+ readonly env?: VaultEnvLabel;
83
+ /**
84
+ * Optional peer-environment fingerprints (e.g. staging from a remote
85
+ * probe). Never values — fingerprints only.
86
+ */
87
+ readonly peerFingerprints?: Readonly<
88
+ Record<string, VaultFingerprintsByEnv>
89
+ >;
90
+ /** Durable journal — blast radius is queried, not estimated. */
91
+ readonly journal?: JournalStore | null;
92
+ readonly now?: () => number;
93
+ }
94
+
95
+ /**
96
+ * Project Manifest vault contracts into operator rows.
97
+ *
98
+ * @param options - Manifest, runtime, journal
99
+ */
100
+ export async function projectVaultList(
101
+ options: ProjectVaultOptions,
102
+ ): Promise<{
103
+ readonly secrets: readonly ConsoleVaultRow[];
104
+ readonly env: VaultEnvLabel;
105
+ }> {
106
+ const env = options.env ?? "dev";
107
+ const now = options.now ?? (() => Date.now());
108
+ const names = collectNames(options.manifest, options.runtime);
109
+ const journalRuns = options.journal
110
+ ? await options.journal.list()
111
+ : ([] as readonly JournalRun[]);
112
+
113
+ const secrets: ConsoleVaultRow[] = [];
114
+ for (const name of names) {
115
+ const contract = contractOf(name, options.manifest, options.runtime);
116
+ const sensitive = contract.sensitive;
117
+ const readers = readersOf(options.manifest, name);
118
+ const blastRadius = blastRadiusOf(
119
+ journalRuns,
120
+ readers,
121
+ now(),
122
+ );
123
+ const winner = options.runtime?.resolution(name) ?? null;
124
+ const resolution = options.runtime?.resolutionChain(name) ?? [];
125
+ const lastReadAt = options.runtime?.lastReadAt(name) ?? null;
126
+
127
+ let fingerprint: string | null = null;
128
+ let cleartext: string | null = null;
129
+ const fingerprints: Record<string, string> = {};
130
+
131
+ if (sensitive) {
132
+ fingerprint = options.runtime?.fingerprint(name) ?? null;
133
+ if (fingerprint) fingerprints[env] = fingerprint;
134
+ const peers = options.peerFingerprints?.[name];
135
+ if (peers) {
136
+ for (const [e, fp] of Object.entries(peers)) {
137
+ if (typeof fp === "string" && fp.length > 0) fingerprints[e] = fp;
138
+ }
139
+ }
140
+ } else {
141
+ cleartext = options.runtime?.cleartext(name) ?? null;
142
+ }
143
+
144
+ const sharedFingerprintEnvs = sensitive
145
+ ? sharedEnvs(fingerprints, env, fingerprint)
146
+ : [];
147
+
148
+ secrets.push({
149
+ name,
150
+ kind: contract.kind,
151
+ sensitive,
152
+ ...(contract.description !== undefined
153
+ ? { description: contract.description }
154
+ : {}),
155
+ ...(contract.rotate !== undefined ? { rotate: contract.rotate } : {}),
156
+ fingerprints,
157
+ fingerprint,
158
+ cleartext,
159
+ winner,
160
+ resolution,
161
+ readers,
162
+ blastRadius,
163
+ lastReadAt,
164
+ sharedFingerprintEnvs,
165
+ });
166
+ }
167
+
168
+ return { secrets, env };
169
+ }
170
+
171
+ /** Input for set / rotate. */
172
+ export interface VaultWriteInput {
173
+ readonly name: string;
174
+ readonly value: string;
175
+ }
176
+
177
+ /**
178
+ * Set a vault value via the runtime (write-only — never returns the value).
179
+ *
180
+ * @param runtime - Vault runtime
181
+ * @param input - Name + new value
182
+ */
183
+ export function setVaultValue(
184
+ runtime: VaultRuntime,
185
+ input: VaultWriteInput,
186
+ ): { readonly name: string; readonly fingerprint: string | null } {
187
+ runtime.put(input.name, input.value);
188
+ return {
189
+ name: input.name,
190
+ fingerprint: runtime.isSensitive(input.name)
191
+ ? (runtime.fingerprint(input.name) ?? null)
192
+ : null,
193
+ };
194
+ }
195
+
196
+ /**
197
+ * Rotate = set a new value (same write path; distinct Console action + confirm).
198
+ *
199
+ * @param runtime - Vault runtime
200
+ * @param input - Name + new value
201
+ */
202
+ export function rotateVaultValue(
203
+ runtime: VaultRuntime,
204
+ input: VaultWriteInput,
205
+ ): { readonly name: string; readonly fingerprint: string | null } {
206
+ return setVaultValue(runtime, input);
207
+ }
208
+
209
+ /**
210
+ * Build a VaultRuntime from Manifest contracts when no host runtime is attached.
211
+ *
212
+ * Uses the standard resolution chain: process.env → .env.local → .env.stack
213
+ * → memory driver → (optional) dev fallback. Does not parse dotenv in the UI.
214
+ *
215
+ * @param manifest - Manifest snapshot
216
+ * @param options - cwd / env / allowDevFallbacks / seed
217
+ */
218
+ export async function createManifestVaultRuntime(
219
+ manifest: Manifest,
220
+ options: {
221
+ readonly cwd?: string;
222
+ readonly env?: ConfigEnv;
223
+ readonly allowDevFallbacks?: boolean;
224
+ readonly seed?: Readonly<Record<string, string>>;
225
+ readonly now?: () => number;
226
+ } = {},
227
+ ): Promise<VaultRuntime | null> {
228
+ const entries = Object.entries(manifest.vault ?? {});
229
+ if (entries.length === 0) return null;
230
+
231
+ const cwd = options.cwd ?? process.cwd();
232
+ const secrets: VaultSecretDecl[] = entries.map(([name, c]) => {
233
+ const sensitive = c.sensitive !== false;
234
+ if (sensitive) {
235
+ return declareVault.secret(name, {
236
+ description: c.description,
237
+ rotate: c.rotate,
238
+ schema: c.schema,
239
+ sensitive: true,
240
+ });
241
+ }
242
+ return declareVault.config(name, {
243
+ description: c.description,
244
+ rotate: c.rotate,
245
+ schema: c.schema,
246
+ sensitive: false,
247
+ });
248
+ });
249
+
250
+ const seed = options.seed ?? {};
251
+ const runtime = createVaultRuntime({
252
+ secrets,
253
+ allowDevFallbacks:
254
+ options.allowDevFallbacks ?? (options.env ?? "dev") !== "prod",
255
+ now: options.now,
256
+ chain: [
257
+ { driver: envVaultDriver, source: "process.env" },
258
+ {
259
+ driver: envVaultDriver,
260
+ source: ".env.local",
261
+ options: { path: resolve(cwd, ".env.local") },
262
+ },
263
+ {
264
+ driver: envVaultDriver,
265
+ source: ".env.stack",
266
+ options: { path: resolve(cwd, ".env.stack") },
267
+ },
268
+ {
269
+ driver: memoryVaultDriver,
270
+ source: "driver",
271
+ options: { secrets: seed },
272
+ },
273
+ ],
274
+ });
275
+ await runtime.boot();
276
+ return runtime;
277
+ }
278
+
279
+ /**
280
+ * Query journal for sleeping durable runs whose flows read `secretName`.
281
+ *
282
+ * @param runs - Journal runs
283
+ * @param readerFlowIds - Flows that declare the secret
284
+ * @param now - Clock
285
+ */
286
+ export function blastRadiusOf(
287
+ runs: readonly JournalRun[],
288
+ readerFlowIds: readonly string[],
289
+ now: number,
290
+ ): ConsoleVaultBlastRadius {
291
+ const readers = new Set(readerFlowIds);
292
+ const affected = runs.filter(
293
+ (r) =>
294
+ r.status === "sleeping" &&
295
+ r.wakeAt != null &&
296
+ readers.has(r.flow),
297
+ );
298
+ if (affected.length === 0) {
299
+ return {
300
+ count: 0,
301
+ longestWakeAt: null,
302
+ longestOutstandingMs: null,
303
+ runIds: [],
304
+ };
305
+ }
306
+ let longestWakeAt = 0;
307
+ const runIds: string[] = [];
308
+ for (const r of affected) {
309
+ runIds.push(r.id);
310
+ if ((r.wakeAt ?? 0) > longestWakeAt) longestWakeAt = r.wakeAt ?? 0;
311
+ }
312
+ return {
313
+ count: affected.length,
314
+ longestWakeAt,
315
+ longestOutstandingMs: Math.max(0, longestWakeAt - now),
316
+ runIds,
317
+ };
318
+ }
319
+
320
+ /**
321
+ * Flow ids that declare `effects.secrets` including `name`.
322
+ *
323
+ * @param manifest - Manifest
324
+ * @param name - Secret name
325
+ */
326
+ export function readersOf(
327
+ manifest: Manifest | null,
328
+ name: string,
329
+ ): readonly string[] {
330
+ if (!manifest?.flows) return [];
331
+ const out: string[] = [];
332
+ for (const [flowId, flow] of Object.entries(manifest.flows)) {
333
+ if (flow.effects?.secrets?.includes(name)) out.push(flowId);
334
+ }
335
+ return out.sort();
336
+ }
337
+
338
+ /**
339
+ * @param manifest - Manifest
340
+ * @param runtime - Runtime
341
+ */
342
+ function collectNames(
343
+ manifest: Manifest | null,
344
+ runtime: VaultRuntime | null,
345
+ ): readonly string[] {
346
+ const set = new Set<string>();
347
+ for (const name of Object.keys(manifest?.vault ?? {})) set.add(name);
348
+ if (runtime) {
349
+ for (const name of runtime.contracts.keys()) set.add(name);
350
+ for (const name of runtime.names()) set.add(name);
351
+ }
352
+ return [...set].sort();
353
+ }
354
+
355
+ /**
356
+ * @param name - Contract name
357
+ * @param manifest - Manifest
358
+ * @param runtime - Runtime
359
+ */
360
+ function contractOf(
361
+ name: string,
362
+ manifest: Manifest | null,
363
+ runtime: VaultRuntime | null,
364
+ ): {
365
+ readonly kind: "secret" | "config";
366
+ readonly sensitive: boolean;
367
+ readonly description?: string;
368
+ readonly rotate?: string;
369
+ } {
370
+ const fromRuntime = runtime?.contracts.get(name);
371
+ if (fromRuntime) {
372
+ return {
373
+ kind: fromRuntime.kind,
374
+ sensitive: fromRuntime.sensitive,
375
+ ...(fromRuntime.description !== undefined
376
+ ? { description: fromRuntime.description }
377
+ : {}),
378
+ ...(fromRuntime.rotate !== undefined
379
+ ? { rotate: fromRuntime.rotate }
380
+ : {}),
381
+ };
382
+ }
383
+ const fromManifest = manifest?.vault?.[name];
384
+ const sensitive = fromManifest?.sensitive !== false;
385
+ return {
386
+ kind: sensitive ? "secret" : "config",
387
+ sensitive,
388
+ ...(fromManifest?.description !== undefined
389
+ ? { description: fromManifest.description }
390
+ : {}),
391
+ ...(fromManifest?.rotate !== undefined
392
+ ? { rotate: fromManifest.rotate }
393
+ : {}),
394
+ };
395
+ }
396
+
397
+ /**
398
+ * Environments (other than current) that share the same fingerprint.
399
+ *
400
+ * @param fingerprints - By env
401
+ * @param env - Current env
402
+ * @param fingerprint - Current fingerprint
403
+ */
404
+ function sharedEnvs(
405
+ fingerprints: Readonly<Record<string, string>>,
406
+ env: VaultEnvLabel,
407
+ fingerprint: string | null,
408
+ ): readonly VaultEnvLabel[] {
409
+ if (!fingerprint) return [];
410
+ return Object.entries(fingerprints)
411
+ .filter(([e, fp]) => e !== env && fp === fingerprint)
412
+ .map(([e]) => e as VaultEnvLabel)
413
+ .sort();
414
+ }
415
+
416
+ /** Assert a Console row never embeds a secret value (tests / export safety). */
417
+ export function assertNoSecretLeak(
418
+ row: ConsoleVaultRow,
419
+ knownSecrets: readonly string[],
420
+ ): void {
421
+ const blob = JSON.stringify(row);
422
+ for (const secret of knownSecrets) {
423
+ if (secret.length === 0) continue;
424
+ if (blob.includes(secret)) {
425
+ throw new Error(
426
+ `vault console leak: secret value appears in row for ${row.name}`,
427
+ );
428
+ }
429
+ }
430
+ }
@@ -0,0 +1,237 @@
1
+ /**
2
+ * Static Access markup for the axe gate — same landmarks as the live panel
3
+ * (console §9.14).
4
+ */
5
+
6
+ import {
7
+ ONCE_SECRET_ACK_LABEL,
8
+ ONCE_SECRET_WARNING,
9
+ } from "./acknowledgement.ts";
10
+ import { formatAccessBlastRadius } from "./blast-radius.ts";
11
+ import {
12
+ ACCESS_BLAST_FIXTURE,
13
+ ACCESS_EFFECTIVE_FIXTURE,
14
+ ACCESS_LIST_FIXTURE,
15
+ } from "./fixture.ts";
16
+ import { hygieneLines } from "./hygiene.ts";
17
+ import { formatProvenance } from "./provenance.ts";
18
+
19
+ /** Props for {@link AccessA11yView}. */
20
+ export interface AccessA11yViewProps {
21
+ /** Focused plane. */
22
+ readonly plane?: "operator" | "user";
23
+ /** Open key id for revoke / once-secret surfaces. */
24
+ readonly openKeyId?: string;
25
+ /** Show once-secret acknowledgement surface. */
26
+ readonly showOnceSecret?: boolean;
27
+ }
28
+
29
+ /**
30
+ * Accessible Access list + detail for CI.
31
+ *
32
+ * @param props - Plane / open key
33
+ */
34
+ export function AccessA11yView(props: AccessA11yViewProps) {
35
+ const plane = props.plane ?? "user";
36
+ const section =
37
+ plane === "operator"
38
+ ? ACCESS_LIST_FIXTURE.operatorPlane
39
+ : ACCESS_LIST_FIXTURE.userPlane;
40
+ const openKeyId = props.openKeyId ?? "key_demo";
41
+ const openKey = section.keys.find((k) => k.id === openKeyId);
42
+ const blast = formatAccessBlastRadius(ACCESS_BLAST_FIXTURE);
43
+ const lines = hygieneLines(ACCESS_LIST_FIXTURE.hygiene);
44
+ const provenance = formatProvenance(ACCESS_EFFECTIVE_FIXTURE);
45
+
46
+ return (
47
+ <div className="access-a11y">
48
+ <a href="#access-main">Skip to main content</a>
49
+ <header>
50
+ <h1>Access</h1>
51
+ <p>Identities, roles, API keys — planes never merge</p>
52
+ <div role="group" aria-label="Plane">
53
+ <button type="button" aria-pressed={plane === "operator"}>
54
+ Operator plane
55
+ </button>
56
+ <button type="button" aria-pressed={plane === "user"}>
57
+ User plane
58
+ </button>
59
+ </div>
60
+ <label>
61
+ Filter access
62
+ <input aria-label="Filter access" defaultValue="" />
63
+ </label>
64
+ </header>
65
+
66
+ {lines.length > 0 ? (
67
+ <section aria-label="Access hygiene" role="status">
68
+ <h2>Hygiene</h2>
69
+ <ul>
70
+ {lines.map((line) => (
71
+ <li key={line.code}>{line.message}</li>
72
+ ))}
73
+ </ul>
74
+ </section>
75
+ ) : null}
76
+
77
+ <main id="access-main">
78
+ <section aria-label={`${plane} plane`}>
79
+ <h2>{plane === "operator" ? "Operator plane" : "User plane"}</h2>
80
+
81
+ {section.operators ? (
82
+ <section aria-label="Operators">
83
+ <h3>Operators</h3>
84
+ <ul>
85
+ {section.operators.map((op) => (
86
+ <li key={op.id}>
87
+ <button type="button" style={{ minHeight: 32, width: "100%" }}>
88
+ {op.name} ({op.email})
89
+ {op.neverSignedIn ? (
90
+ <span role="status"> never signed in</span>
91
+ ) : null}
92
+ </button>
93
+ </li>
94
+ ))}
95
+ </ul>
96
+ </section>
97
+ ) : null}
98
+
99
+ {section.users ? (
100
+ <section aria-label="Users">
101
+ <h3>Users</h3>
102
+ <ul>
103
+ {section.users.map((u) => (
104
+ <li key={u.id}>
105
+ <button type="button" style={{ minHeight: 32, width: "100%" }}>
106
+ {u.name} ({u.email})
107
+ </button>
108
+ </li>
109
+ ))}
110
+ </ul>
111
+ </section>
112
+ ) : null}
113
+
114
+ <section aria-label="Roles">
115
+ <h3>Roles</h3>
116
+ <ul>
117
+ {section.roles.map((r) => (
118
+ <li key={r.id}>
119
+ <button type="button" style={{ minHeight: 32, width: "100%" }}>
120
+ {r.name} — {r.scopes.length} scopes
121
+ </button>
122
+ </li>
123
+ ))}
124
+ </ul>
125
+ </section>
126
+
127
+ <section aria-label="API keys">
128
+ <h3>API keys</h3>
129
+ <ul>
130
+ {section.keys.map((k) => (
131
+ <li key={k.id}>
132
+ <button
133
+ type="button"
134
+ aria-pressed={k.id === openKeyId}
135
+ style={{ minHeight: 32, width: "100%" }}
136
+ >
137
+ {k.name}
138
+ {k.unused90d ? (
139
+ <span role="status"> unused 90d+</span>
140
+ ) : null}
141
+ </button>
142
+ </li>
143
+ ))}
144
+ </ul>
145
+ </section>
146
+
147
+ <section aria-label="Grantable scopes">
148
+ <h3>Grantable scopes</h3>
149
+ <p>
150
+ Only scopes you hold appear — impossibility taught by absence
151
+ </p>
152
+ <ul>
153
+ {section.grantableScopes.map((s) => (
154
+ <li key={s}>
155
+ <label>
156
+ <input type="checkbox" disabled /> {s}
157
+ </label>
158
+ </li>
159
+ ))}
160
+ </ul>
161
+ </section>
162
+ </section>
163
+
164
+ {openKey ? (
165
+ <section aria-label="Key detail" aria-live="polite">
166
+ <h2>{openKey.name}</h2>
167
+ <p className="font-mono">{openKey.id}</p>
168
+
169
+ <section aria-label="Revocation blast radius">
170
+ <h3>Revocation blast radius</h3>
171
+ <p role={blast.warn ? "alert" : "status"}>{blast.volume}</p>
172
+ <p>{blast.lastUsed}</p>
173
+ <p>{blast.sources}</p>
174
+ <p role="status">{blast.residual}</p>
175
+ </section>
176
+
177
+ <section aria-label="Revoke key">
178
+ <h3>Revoke</h3>
179
+ <label>
180
+ Type REVOKE to confirm
181
+ <input aria-label="Type REVOKE to confirm" defaultValue="" />
182
+ </label>
183
+ <label>
184
+ Reason
185
+ <input aria-label="Revoke reason" defaultValue="" />
186
+ </label>
187
+ <button type="button">Revoke key</button>
188
+ </section>
189
+ </section>
190
+ ) : null}
191
+
192
+ <section aria-label="Effective permissions">
193
+ <h2>Effective permissions</h2>
194
+ <p>Every permission with provenance — inverse of the Gates simulator</p>
195
+ <table>
196
+ <caption>Effective permissions with provenance</caption>
197
+ <thead>
198
+ <tr>
199
+ <th scope="col">Scope</th>
200
+ <th scope="col">Granted by</th>
201
+ </tr>
202
+ </thead>
203
+ <tbody>
204
+ {provenance.map((row) => (
205
+ <tr key={row.scope}>
206
+ <td>{row.scope}</td>
207
+ <td>{row.sources}</td>
208
+ </tr>
209
+ ))}
210
+ </tbody>
211
+ </table>
212
+ </section>
213
+
214
+ {props.showOnceSecret ? (
215
+ <section
216
+ aria-label="New API key secret"
217
+ role="alertdialog"
218
+ aria-modal="true"
219
+ aria-labelledby="once-secret-title"
220
+ >
221
+ <h2 id="once-secret-title">New API key secret</h2>
222
+ <p role="alert">{ONCE_SECRET_WARNING}</p>
223
+ <p>
224
+ <code>oke_fixture_secret_shown_once</code>
225
+ </p>
226
+ <label>
227
+ <input type="checkbox" /> {ONCE_SECRET_ACK_LABEL}
228
+ </label>
229
+ <button type="button" disabled>
230
+ Dismiss secret
231
+ </button>
232
+ </section>
233
+ ) : null}
234
+ </main>
235
+ </div>
236
+ );
237
+ }