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,165 @@
1
+ /**
2
+ * Declared architecture edges derived from the Flows causality graph (§9.1 / §9.13).
3
+ *
4
+ * Reuses {@link buildCausalityGraph} output — does not recompute causality.
5
+ */
6
+
7
+ import type { CausalityGraph, FlowNode } from "../flows/graph.ts";
8
+ import {
9
+ isBoundaryExternal,
10
+ layerOfCause,
11
+ layerOfEffectRef,
12
+ } from "./layers.ts";
13
+ import type { ElementLayer } from "./types.ts";
14
+
15
+ /** One fine-grained declared relationship before aggregation / focus. */
16
+ export interface DeclaredEdge {
17
+ /** Source node id (flow: / unit: / cause:). */
18
+ readonly from: string;
19
+ /** Target node id. */
20
+ readonly to: string;
21
+ /** Owning flow that declares the relationship (for traffic lookup). */
22
+ readonly flowId: string;
23
+ /** Effect ref when the target is a resource. */
24
+ readonly ref?: string;
25
+ /** Typed layer, or structural call. */
26
+ readonly layer: ElementLayer | "call";
27
+ /** Source unit. */
28
+ readonly fromUnit: string;
29
+ /** Target unit (`external` for boundary-crossing resources). */
30
+ readonly toUnit: string;
31
+ }
32
+
33
+ /**
34
+ * Extract every declared typed edge from the causality graph.
35
+ *
36
+ * @param graph - Flows causality graph
37
+ */
38
+ export function declaredEdgesOf(graph: CausalityGraph): DeclaredEdge[] {
39
+ const edges: DeclaredEdge[] = [];
40
+ const consumersOf = signalConsumers(graph);
41
+
42
+ for (const flow of graph.flows) {
43
+ // Cause → flow (time / messaging triggers)
44
+ for (const causeId of flow.causeIds) {
45
+ const cause = graph.causeById.get(causeId);
46
+ if (!cause) continue;
47
+ const layer = layerOfCause(cause);
48
+ if (!layer) continue;
49
+ edges.push({
50
+ from: `cause:${cause.id}`,
51
+ to: `flow:${flow.id}`,
52
+ flowId: flow.id,
53
+ layer,
54
+ fromUnit: flow.unit,
55
+ toUnit: flow.unit,
56
+ });
57
+ }
58
+
59
+ // Flow → resources / callees
60
+ for (const ref of flow.effectRefs) {
61
+ if (ref.startsWith("flow:")) {
62
+ const callee = ref.slice("flow:".length);
63
+ const calleeUnit = unitOfFlowId(callee);
64
+ edges.push({
65
+ from: `flow:${flow.id}`,
66
+ to: `flow:${callee}`,
67
+ flowId: flow.id,
68
+ ref,
69
+ layer: "call",
70
+ fromUnit: flow.unit,
71
+ toUnit: calleeUnit,
72
+ });
73
+ continue;
74
+ }
75
+
76
+ const layer = layerOfEffectRef(ref);
77
+ if (!layer) continue;
78
+
79
+ const toUnit = isBoundaryExternal(ref) ? "external" : ownerUnitOf(ref, graph);
80
+ edges.push({
81
+ from: `flow:${flow.id}`,
82
+ to: ref,
83
+ flowId: flow.id,
84
+ ref,
85
+ layer,
86
+ fromUnit: flow.unit,
87
+ toUnit,
88
+ });
89
+
90
+ // Messaging fan-out: emitter unit → consumer units
91
+ if (layer === "messaging" && ref.startsWith("signal:")) {
92
+ const sig = ref.slice("signal:".length);
93
+ for (const consumerId of consumersOf.get(sig) ?? []) {
94
+ const consumer = graph.flowById.get(consumerId);
95
+ if (!consumer || consumer.id === flow.id) continue;
96
+ edges.push({
97
+ from: `flow:${flow.id}`,
98
+ to: `flow:${consumer.id}`,
99
+ flowId: flow.id,
100
+ ref,
101
+ layer: "messaging",
102
+ fromUnit: flow.unit,
103
+ toUnit: consumer.unit,
104
+ });
105
+ }
106
+ }
107
+ }
108
+ }
109
+
110
+ return edges;
111
+ }
112
+
113
+ /**
114
+ * Unit that "owns" a resource for clustering (first writing/emitting flow's unit,
115
+ * else first touching unit, else `shared`).
116
+ *
117
+ * @param ref - Effect ref
118
+ * @param graph - Causality graph
119
+ */
120
+ export function ownerUnitOf(ref: string, graph: CausalityGraph): string {
121
+ const effect = graph.effectByRef.get(ref);
122
+ if (!effect || effect.flowIds.length === 0) return "shared";
123
+
124
+ const writers = effect.flowIds.filter((id) => {
125
+ const flow = graph.flowById.get(id);
126
+ if (!flow) return false;
127
+ return flowWritesOrEmits(flow, ref);
128
+ });
129
+ const pick = writers[0] ?? effect.flowIds[0];
130
+ if (!pick) return "shared";
131
+ return unitOfFlowId(pick);
132
+ }
133
+
134
+ function flowWritesOrEmits(flow: FlowNode, ref: string): boolean {
135
+ const effects = flow.raw.effects;
136
+ if (!effects) return false;
137
+ if (ref.startsWith("signal:")) {
138
+ const name = ref.slice("signal:".length);
139
+ return (effects.emits ?? []).includes(name);
140
+ }
141
+ if ((effects.writes ?? []).includes(ref)) return true;
142
+ return false;
143
+ }
144
+
145
+ function signalConsumers(graph: CausalityGraph): Map<string, string[]> {
146
+ const map = new Map<string, string[]>();
147
+ for (const flow of graph.flows) {
148
+ const sig = flow.raw.trigger?.signal;
149
+ if (!sig) continue;
150
+ const list = map.get(sig) ?? [];
151
+ list.push(flow.id);
152
+ map.set(sig, list);
153
+ }
154
+ return map;
155
+ }
156
+
157
+ /**
158
+ * Unit prefix of a flow id.
159
+ *
160
+ * @param flowId - Flow id
161
+ */
162
+ export function unitOfFlowId(flowId: string): string {
163
+ const i = flowId.indexOf(".");
164
+ return i === -1 ? flowId : flowId.slice(0, i);
165
+ }
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Manifest + Runs fixtures for Architecture panel tests (console §9.13).
3
+ */
4
+
5
+ import type { Manifest } from "../../../manifest/types.ts";
6
+ import { FLOWS_TEST_MANIFEST } from "../flows/fixture.ts";
7
+ import { RUNS_CHAIN_FIXTURE } from "../runs/fixture.ts";
8
+ import type { RunRecord } from "../runs/types.ts";
9
+
10
+ /**
11
+ * Architecture fixture — extends the Flows causality slice with a cycle,
12
+ * an orphan signal, a cron (time layer), and a cross-unit call.
13
+ */
14
+ export const ARCHITECTURE_TEST_MANIFEST: Manifest = {
15
+ ...FLOWS_TEST_MANIFEST,
16
+ app: "skyport-architecture-test",
17
+ flows: {
18
+ ...FLOWS_TEST_MANIFEST.flows,
19
+ "ops.nightlyReconcile": {
20
+ trigger: { cron: "0 3 * * *" },
21
+ effects: {
22
+ reads: ["sql:bookings"],
23
+ writes: ["sql:bookings"],
24
+ },
25
+ source: "src/flows/ops/index.ts:8",
26
+ },
27
+ "ops.pingPayments": {
28
+ effects: {
29
+ calls: ["payments.reportToOps"],
30
+ },
31
+ source: "src/flows/ops/index.ts:20",
32
+ },
33
+ "payments.reportToOps": {
34
+ effects: {
35
+ calls: ["ops.pingPayments"],
36
+ emits: ["payment-reported"],
37
+ },
38
+ source: "src/flows/payments/index.ts:40",
39
+ },
40
+ "reports.onPayment": {
41
+ trigger: { signal: "payment-reported" },
42
+ effects: {
43
+ writes: ["sql:reports"],
44
+ },
45
+ source: "src/flows/reports/index.ts:4",
46
+ },
47
+ "reports.list": {
48
+ trigger: { http: { method: "GET", path: "/reports" } },
49
+ effects: {
50
+ reads: ["sql:reports"],
51
+ },
52
+ source: "src/flows/reports/index.ts:18",
53
+ },
54
+ },
55
+ signals: {
56
+ ...FLOWS_TEST_MANIFEST.signals,
57
+ "payment-reported": { delivery: "once", retries: 3, deadLetter: true },
58
+ /** Declared, never emitted, never consumed. */
59
+ "legacy-unused": { delivery: "once", retries: 1, deadLetter: false },
60
+ },
61
+ stores: {
62
+ db: {
63
+ facet: "sql",
64
+ tables: {
65
+ bookings: {},
66
+ shipments: {},
67
+ reports: {},
68
+ },
69
+ },
70
+ },
71
+ };
72
+
73
+ /** Runs fixture reused for traffic thickness / dashed edges. */
74
+ export const ARCHITECTURE_RUNS_FIXTURE: readonly RunRecord[] = RUNS_CHAIN_FIXTURE;
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Architecture panel pure modules (console §9.13).
3
+ */
4
+
5
+ export type {
6
+ ArchitectureEdge,
7
+ ArchitectureFinding,
8
+ ArchitectureNode,
9
+ ArchitectureNodeKind,
10
+ ArchitectureView,
11
+ ElementLayer,
12
+ FocusDepth,
13
+ LayerFlags,
14
+ PathologyKind,
15
+ } from "./types.ts";
16
+
17
+ export {
18
+ DEFAULT_LAYERS,
19
+ ELEMENT_LAYERS,
20
+ LAYER_LABEL,
21
+ } from "./types.ts";
22
+
23
+ export {
24
+ isBoundaryExternal,
25
+ labelOfRef,
26
+ layerOfCause,
27
+ layerOfEffectRef,
28
+ } from "./layers.ts";
29
+
30
+ export {
31
+ boundaryCrossingCount,
32
+ boundaryCrossingRefs,
33
+ } from "./boundary.ts";
34
+
35
+ export {
36
+ normalizeTrafficRef,
37
+ observeTraffic,
38
+ thicknessOf,
39
+ trafficEdgeKey,
40
+ traversalsOf,
41
+ } from "./traffic.ts";
42
+
43
+ export {
44
+ declaredEdgesOf,
45
+ ownerUnitOf,
46
+ unitOfFlowId,
47
+ } from "./declared.ts";
48
+
49
+ export {
50
+ computePathologies,
51
+ findCycles,
52
+ findGodNodes,
53
+ findOrphanSignals,
54
+ findSinglePointsOfFailure,
55
+ } from "./pathologies.ts";
56
+
57
+ export {
58
+ buildArchitectureView,
59
+ setLayer,
60
+ type ArchitectureViewOptions,
61
+ } from "./view.ts";
62
+
63
+ export {
64
+ clearFocus,
65
+ focusNode,
66
+ layersOf,
67
+ parseArchitectureSearch,
68
+ serializeArchitectureSearch,
69
+ setDepth,
70
+ setLayerSearch,
71
+ type ArchitectureSearch,
72
+ } from "./search.ts";
73
+
74
+ export {
75
+ ARCHITECTURE_RUNS_FIXTURE,
76
+ ARCHITECTURE_TEST_MANIFEST,
77
+ } from "./fixture.ts";
78
+
79
+ export {
80
+ layoutNodes,
81
+ SYSTEM_BOUNDARY,
82
+ type BoundaryRect,
83
+ type NodePosition,
84
+ } from "./layout.ts";
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Typed element-layer classification for architecture edges (console §9.13).
3
+ *
4
+ * Layers toggle real edge kinds — Store / Signal / Clock / Channel+AI —
5
+ * not visual grouping of an undifferentiated graph.
6
+ */
7
+
8
+ import type { CauseNode } from "../flows/graph.ts";
9
+ import type { ElementLayer } from "./types.ts";
10
+
11
+ /**
12
+ * Classify a causality effect ref into a toggleable element layer.
13
+ *
14
+ * Returns `null` for secrets and flow portals (not among the four layers).
15
+ *
16
+ * @param ref - Effect ref (`sql:bookings`, `signal:order-placed`, …)
17
+ */
18
+ export function layerOfEffectRef(ref: string): ElementLayer | null {
19
+ if (
20
+ ref.startsWith("sql:") ||
21
+ ref.startsWith("kv:") ||
22
+ ref.startsWith("files:") ||
23
+ ref.startsWith("index:")
24
+ ) {
25
+ return "data";
26
+ }
27
+ if (ref.startsWith("signal:")) return "messaging";
28
+ if (ref.startsWith("channel:") || ref.startsWith("ai:")) return "external";
29
+ return null;
30
+ }
31
+
32
+ /**
33
+ * Classify a cause into a toggleable element layer.
34
+ *
35
+ * HTTP / CDC / caller causes are structural (always shown when relevant);
36
+ * signal → messaging; cron / every → time.
37
+ *
38
+ * @param cause - Cause node from the causality graph
39
+ */
40
+ export function layerOfCause(cause: CauseNode): ElementLayer | null {
41
+ if (cause.kind === "signal") return "messaging";
42
+ if (cause.kind === "cron" || cause.kind === "every") return "time";
43
+ return null;
44
+ }
45
+
46
+ /**
47
+ * Whether a resource ref sits outside the system boundary
48
+ * (Channel / AI — irreversible tier).
49
+ *
50
+ * @param ref - Effect ref
51
+ */
52
+ export function isBoundaryExternal(ref: string): boolean {
53
+ return ref.startsWith("channel:") || ref.startsWith("ai:");
54
+ }
55
+
56
+ /**
57
+ * Strip a kind prefix for display (`channel:booking-confirmed` → `booking-confirmed`).
58
+ *
59
+ * @param ref - Effect ref
60
+ */
61
+ export function labelOfRef(ref: string): string {
62
+ const i = ref.indexOf(":");
63
+ return i === -1 ? ref : ref.slice(i + 1);
64
+ }
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Deterministic layout for the architecture SVG (console §9.13).
3
+ *
4
+ * Units sit inside the system boundary; external nodes sit outside.
5
+ */
6
+
7
+ import type { ArchitectureNode } from "./types.ts";
8
+
9
+ /** Pixel position for a diagram node. */
10
+ export interface NodePosition {
11
+ readonly id: string;
12
+ readonly x: number;
13
+ readonly y: number;
14
+ }
15
+
16
+ /** Boundary rectangle in SVG user units. */
17
+ export interface BoundaryRect {
18
+ readonly x: number;
19
+ readonly y: number;
20
+ readonly width: number;
21
+ readonly height: number;
22
+ }
23
+
24
+ /** Fixed boundary geometry. */
25
+ export const SYSTEM_BOUNDARY: BoundaryRect = {
26
+ x: 32,
27
+ y: 40,
28
+ width: 440,
29
+ height: 300,
30
+ };
31
+
32
+ /**
33
+ * Place nodes: units / flows / resources inside the boundary; externals outside.
34
+ *
35
+ * @param nodes - Visible nodes
36
+ */
37
+ export function layoutNodes(
38
+ nodes: readonly ArchitectureNode[],
39
+ ): ReadonlyMap<string, NodePosition> {
40
+ const inside = nodes.filter((n) => n.insideBoundary);
41
+ const outside = nodes.filter((n) => !n.insideBoundary);
42
+ const map = new Map<string, NodePosition>();
43
+
44
+ const cols = Math.max(1, Math.ceil(Math.sqrt(inside.length)));
45
+ const cellW = SYSTEM_BOUNDARY.width / (cols + 1);
46
+ const rows = Math.max(1, Math.ceil(inside.length / cols));
47
+ const cellH = SYSTEM_BOUNDARY.height / (rows + 1);
48
+
49
+ inside.forEach((n, i) => {
50
+ const col = i % cols;
51
+ const row = Math.floor(i / cols);
52
+ map.set(n.id, {
53
+ id: n.id,
54
+ x: SYSTEM_BOUNDARY.x + cellW * (col + 1),
55
+ y: SYSTEM_BOUNDARY.y + cellH * (row + 1),
56
+ });
57
+ });
58
+
59
+ outside.forEach((n, i) => {
60
+ map.set(n.id, {
61
+ id: n.id,
62
+ x: SYSTEM_BOUNDARY.x + SYSTEM_BOUNDARY.width + 96,
63
+ y: SYSTEM_BOUNDARY.y + 48 + i * 56,
64
+ });
65
+ });
66
+
67
+ return map;
68
+ }
@@ -0,0 +1,260 @@
1
+ /**
2
+ * Architecture pathologies computed from the causality graph as data (§9.13).
3
+ *
4
+ * Cycles, god nodes, orphan signals, single points of failure —
5
+ * surfaced as a findings list, not decoration on the diagram.
6
+ */
7
+
8
+ import type { CausalityGraph } from "../flows/graph.ts";
9
+ import { declaredEdgesOf } from "./declared.ts";
10
+ import type { ArchitectureFinding } from "./types.ts";
11
+
12
+ /**
13
+ * Compute all architecture findings for a causality graph.
14
+ *
15
+ * @param graph - Flows causality graph
16
+ */
17
+ export function computePathologies(
18
+ graph: CausalityGraph,
19
+ ): ArchitectureFinding[] {
20
+ const findings: ArchitectureFinding[] = [];
21
+ findings.push(...findCycles(graph));
22
+ findings.push(...findGodNodes(graph));
23
+ findings.push(...findOrphanSignals(graph));
24
+ findings.push(...findSinglePointsOfFailure(graph));
25
+ return findings;
26
+ }
27
+
28
+ /**
29
+ * Directed cycles among flows (calls + signal producer→consumer).
30
+ *
31
+ * @param graph - Causality graph
32
+ */
33
+ export function findCycles(graph: CausalityGraph): ArchitectureFinding[] {
34
+ const adj = new Map<string, Set<string>>();
35
+ const ensure = (id: string): Set<string> => {
36
+ let set = adj.get(id);
37
+ if (!set) {
38
+ set = new Set();
39
+ adj.set(id, set);
40
+ }
41
+ return set;
42
+ };
43
+
44
+ for (const edge of declaredEdgesOf(graph)) {
45
+ if (!edge.from.startsWith("flow:") || !edge.to.startsWith("flow:")) {
46
+ continue;
47
+ }
48
+ const from = edge.from.slice("flow:".length);
49
+ const to = edge.to.slice("flow:".length);
50
+ ensure(from).add(to);
51
+ }
52
+
53
+ const cycles: string[][] = [];
54
+ const visited = new Set<string>();
55
+ const stack: string[] = [];
56
+ const onStack = new Set<string>();
57
+
58
+ const dfs = (node: string): void => {
59
+ visited.add(node);
60
+ stack.push(node);
61
+ onStack.add(node);
62
+ for (const next of adj.get(node) ?? []) {
63
+ if (!visited.has(next)) {
64
+ dfs(next);
65
+ } else if (onStack.has(next)) {
66
+ const idx = stack.indexOf(next);
67
+ if (idx !== -1) {
68
+ cycles.push([...stack.slice(idx), next]);
69
+ }
70
+ }
71
+ }
72
+ stack.pop();
73
+ onStack.delete(node);
74
+ };
75
+
76
+ for (const id of graph.flows.map((f) => f.id)) {
77
+ if (!visited.has(id)) dfs(id);
78
+ }
79
+
80
+ // Deduplicate by normalised cycle signature
81
+ const seen = new Set<string>();
82
+ const findings: ArchitectureFinding[] = [];
83
+ for (const cycle of cycles) {
84
+ const body = cycle.slice(0, -1);
85
+ const rotated = rotateMin(body);
86
+ const sig = rotated.join("→");
87
+ if (seen.has(sig)) continue;
88
+ seen.add(sig);
89
+ findings.push({
90
+ kind: "cycle",
91
+ severity: "critical",
92
+ title: "Cycle",
93
+ detail: `Causal cycle: ${rotated.join(" → ")}`,
94
+ nodeIds: rotated.map((id) => `flow:${id}`),
95
+ });
96
+ }
97
+ return findings;
98
+ }
99
+
100
+ /**
101
+ * Resources touched by the most flows ("god nodes").
102
+ *
103
+ * @param graph - Causality graph
104
+ */
105
+ export function findGodNodes(graph: CausalityGraph): ArchitectureFinding[] {
106
+ if (graph.effects.length === 0) return [];
107
+ const ranked = [...graph.effects]
108
+ .filter((e) => e.touchCount > 0)
109
+ .sort(
110
+ (a, b) => b.touchCount - a.touchCount || a.ref.localeCompare(b.ref),
111
+ );
112
+ const top = ranked[0];
113
+ if (!top || top.touchCount < 2) return [];
114
+
115
+ // Only flag when clearly dominant (strictly more than the runner-up, or sole)
116
+ const second = ranked[1]?.touchCount ?? 0;
117
+ if (top.touchCount === second && ranked.filter((e) => e.touchCount === top.touchCount).length > 1) {
118
+ // Tie for first — report all tied gods
119
+ return ranked
120
+ .filter((e) => e.touchCount === top.touchCount)
121
+ .map((e) => ({
122
+ kind: "god-node" as const,
123
+ severity: "warning" as const,
124
+ title: "God node",
125
+ detail: `${e.ref} is touched by ${e.touchCount} flows — the most in the system`,
126
+ nodeIds: [e.ref],
127
+ }));
128
+ }
129
+
130
+ return [
131
+ {
132
+ kind: "god-node",
133
+ severity: "warning",
134
+ title: "God node",
135
+ detail: `${top.ref} is touched by ${top.touchCount} flows — the most in the system`,
136
+ nodeIds: [top.ref],
137
+ },
138
+ ];
139
+ }
140
+
141
+ /**
142
+ * Orphan signals: declared but never emitted, never consumed, or both sides missing.
143
+ *
144
+ * @param graph - Causality graph
145
+ */
146
+ export function findOrphanSignals(
147
+ graph: CausalityGraph,
148
+ ): ArchitectureFinding[] {
149
+ const findings: ArchitectureFinding[] = [];
150
+ const signalNames = new Set<string>();
151
+
152
+ for (const effect of graph.effects) {
153
+ if (effect.ref.startsWith("signal:")) {
154
+ signalNames.add(effect.ref.slice("signal:".length));
155
+ }
156
+ }
157
+ for (const flow of graph.flows) {
158
+ for (const sig of flow.raw.effects?.emits ?? []) signalNames.add(sig);
159
+ const trigger = flow.raw.trigger?.signal;
160
+ if (trigger) signalNames.add(trigger);
161
+ }
162
+
163
+ for (const name of [...signalNames].sort()) {
164
+ const ref = `signal:${name}`;
165
+ const emitters = graph.flows.filter((f) =>
166
+ (f.raw.effects?.emits ?? []).includes(name),
167
+ );
168
+ const consumers = graph.flows.filter(
169
+ (f) => f.raw.trigger?.signal === name,
170
+ );
171
+
172
+ if (emitters.length === 0 && consumers.length === 0) {
173
+ findings.push({
174
+ kind: "orphan-signal",
175
+ severity: "warning",
176
+ title: "Orphan signal",
177
+ detail: `${name} is declared but has no producers and no consumers`,
178
+ nodeIds: [ref],
179
+ });
180
+ continue;
181
+ }
182
+ if (emitters.length === 0) {
183
+ findings.push({
184
+ kind: "orphan-signal",
185
+ severity: "warning",
186
+ title: "Orphan signal",
187
+ detail: `${name} has consumers but no producer`,
188
+ nodeIds: [ref, ...consumers.map((c) => `flow:${c.id}`)],
189
+ });
190
+ continue;
191
+ }
192
+ if (consumers.length === 0) {
193
+ findings.push({
194
+ kind: "orphan-signal",
195
+ severity: "warning",
196
+ title: "Orphan signal",
197
+ detail: `${name} is emitted but has no consumers`,
198
+ nodeIds: [ref, ...emitters.map((e) => `flow:${e.id}`)],
199
+ });
200
+ }
201
+ }
202
+
203
+ return findings;
204
+ }
205
+
206
+ /**
207
+ * Single points of failure: widely-touched resources with exactly one writer/emitter.
208
+ *
209
+ * @param graph - Causality graph
210
+ */
211
+ export function findSinglePointsOfFailure(
212
+ graph: CausalityGraph,
213
+ ): ArchitectureFinding[] {
214
+ const findings: ArchitectureFinding[] = [];
215
+
216
+ for (const effect of graph.effects) {
217
+ if (effect.touchCount < 2) continue;
218
+ if (effect.ref.startsWith("secret:")) continue;
219
+ if (effect.ref.startsWith("channel:") || effect.ref.startsWith("ai:")) {
220
+ continue;
221
+ }
222
+
223
+ const writers = effect.flowIds.filter((id) => {
224
+ const flow = graph.flowById.get(id);
225
+ if (!flow?.raw.effects) return false;
226
+ if (effect.ref.startsWith("signal:")) {
227
+ const name = effect.ref.slice("signal:".length);
228
+ return (flow.raw.effects.emits ?? []).includes(name);
229
+ }
230
+ return (flow.raw.effects.writes ?? []).includes(effect.ref);
231
+ });
232
+
233
+ if (writers.length !== 1) continue;
234
+ const writer = writers[0]!;
235
+ findings.push({
236
+ kind: "spof",
237
+ severity: "critical",
238
+ title: "Single point of failure",
239
+ detail: `${effect.ref} is touched by ${effect.touchCount} flows but written/emitted by only ${writer}`,
240
+ nodeIds: [effect.ref, `flow:${writer}`],
241
+ });
242
+ }
243
+
244
+ return findings;
245
+ }
246
+
247
+ function rotateMin(cycle: readonly string[]): string[] {
248
+ if (cycle.length === 0) return [];
249
+ let best = [...cycle];
250
+ let bestKey = best.join("\0");
251
+ for (let i = 1; i < cycle.length; i++) {
252
+ const rotated = [...cycle.slice(i), ...cycle.slice(0, i)];
253
+ const key = rotated.join("\0");
254
+ if (key < bestKey) {
255
+ best = rotated;
256
+ bestKey = key;
257
+ }
258
+ }
259
+ return best;
260
+ }