@empire-builder-kit/nx 1.0.0-beta.9 → 1.0.0-rc.2

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 (824) hide show
  1. package/NOTICE +6 -0
  2. package/README.md +113 -3
  3. package/executors.json +30 -0
  4. package/package.json +84 -6
  5. package/src/api-contract/baseline-update.d.ts +82 -0
  6. package/src/api-contract/baseline-update.js +225 -0
  7. package/src/api-contract/baseline-update.js.map +1 -0
  8. package/src/api-contract/compatibility.d.ts +30 -0
  9. package/src/api-contract/compatibility.js +643 -0
  10. package/src/api-contract/compatibility.js.map +1 -0
  11. package/src/api-contract/contract-graph.d.ts +35 -0
  12. package/src/api-contract/contract-graph.js +141 -0
  13. package/src/api-contract/contract-graph.js.map +1 -0
  14. package/src/api-contract/evidence.d.ts +23 -0
  15. package/src/api-contract/evidence.js +87 -0
  16. package/src/api-contract/evidence.js.map +1 -0
  17. package/src/api-contract/index.d.ts +6 -0
  18. package/src/api-contract/index.js +10 -0
  19. package/src/api-contract/index.js.map +1 -0
  20. package/src/api-contract/model.d.ts +144 -0
  21. package/src/api-contract/model.fixtures.d.ts +2 -0
  22. package/src/api-contract/model.fixtures.js +81 -0
  23. package/src/api-contract/model.fixtures.js.map +1 -0
  24. package/src/api-contract/model.js +993 -0
  25. package/src/api-contract/model.js.map +1 -0
  26. package/src/api-contract/rollout.d.ts +32 -0
  27. package/src/api-contract/rollout.js +88 -0
  28. package/src/api-contract/rollout.js.map +1 -0
  29. package/src/authorization/compatibility.d.ts +62 -0
  30. package/src/authorization/compatibility.js +175 -0
  31. package/src/authorization/compatibility.js.map +1 -0
  32. package/src/authorization/index.d.ts +1 -0
  33. package/src/authorization/index.js +5 -0
  34. package/src/authorization/index.js.map +1 -0
  35. package/src/blueprints/execution.d.ts +25 -1
  36. package/src/blueprints/execution.js +246 -83
  37. package/src/blueprints/execution.js.map +1 -1
  38. package/src/blueprints/external-sandbox.d.ts +53 -0
  39. package/src/blueprints/external-sandbox.js +1182 -0
  40. package/src/blueprints/external-sandbox.js.map +1 -0
  41. package/src/blueprints/manifest.d.ts +42 -2
  42. package/src/blueprints/manifest.js +82 -27
  43. package/src/blueprints/manifest.js.map +1 -1
  44. package/src/blueprints/resolver.d.ts +14 -5
  45. package/src/blueprints/resolver.js +228 -68
  46. package/src/blueprints/resolver.js.map +1 -1
  47. package/src/cli/agent-command.d.ts +30 -0
  48. package/src/cli/agent-command.js +204 -0
  49. package/src/cli/agent-command.js.map +1 -0
  50. package/src/cli/agent-runtime.d.ts +25 -0
  51. package/src/cli/agent-runtime.js +488 -0
  52. package/src/cli/agent-runtime.js.map +1 -0
  53. package/src/cli/blueprint-authority.d.ts +9 -0
  54. package/src/cli/blueprint-authority.js +43 -0
  55. package/src/cli/blueprint-authority.js.map +1 -0
  56. package/src/cli/blueprint-command.d.ts +24 -0
  57. package/src/cli/blueprint-command.js +63 -0
  58. package/src/cli/blueprint-command.js.map +1 -0
  59. package/src/cli/bootstrap.d.ts +31 -0
  60. package/src/cli/bootstrap.js +165 -0
  61. package/src/cli/bootstrap.js.map +1 -0
  62. package/src/cli/dev-command.d.ts +92 -0
  63. package/src/cli/dev-command.js +561 -0
  64. package/src/cli/dev-command.js.map +1 -0
  65. package/src/cli/main.d.ts +131 -0
  66. package/src/cli/main.js +1199 -0
  67. package/src/cli/main.js.map +1 -0
  68. package/src/cli/output.d.ts +19 -0
  69. package/src/cli/output.js +51 -0
  70. package/src/cli/output.js.map +1 -0
  71. package/src/cli/personal-secret-runtime.d.ts +81 -0
  72. package/src/cli/personal-secret-runtime.js +567 -0
  73. package/src/cli/personal-secret-runtime.js.map +1 -0
  74. package/src/cli/secret-terminal.d.ts +12 -0
  75. package/src/cli/secret-terminal.js +128 -0
  76. package/src/cli/secret-terminal.js.map +1 -0
  77. package/src/container-images.d.ts +1 -0
  78. package/src/container-images.js +5 -0
  79. package/src/container-images.js.map +1 -0
  80. package/src/data-lifecycle/index.d.ts +3 -0
  81. package/src/data-lifecycle/index.js +7 -0
  82. package/src/data-lifecycle/index.js.map +1 -0
  83. package/src/data-lifecycle/model.d.ts +172 -0
  84. package/src/data-lifecycle/model.fixtures.d.ts +2 -0
  85. package/src/data-lifecycle/model.fixtures.js +244 -0
  86. package/src/data-lifecycle/model.fixtures.js.map +1 -0
  87. package/src/data-lifecycle/model.js +95 -0
  88. package/src/data-lifecycle/model.js.map +1 -0
  89. package/src/data-lifecycle/sensitive-artifacts.d.ts +28 -0
  90. package/src/data-lifecycle/sensitive-artifacts.js +146 -0
  91. package/src/data-lifecycle/sensitive-artifacts.js.map +1 -0
  92. package/src/data-lifecycle/validation.d.ts +32 -0
  93. package/src/data-lifecycle/validation.js +837 -0
  94. package/src/data-lifecycle/validation.js.map +1 -0
  95. package/src/database-retirement/contract.d.ts +68 -0
  96. package/src/database-retirement/contract.js +166 -0
  97. package/src/database-retirement/contract.js.map +1 -0
  98. package/src/database-retirement/index.d.ts +1 -0
  99. package/src/database-retirement/index.js +5 -0
  100. package/src/database-retirement/index.js.map +1 -0
  101. package/src/deterministic-order.d.ts +2 -0
  102. package/src/deterministic-order.js +7 -0
  103. package/src/deterministic-order.js.map +1 -0
  104. package/src/developer-agent/context.d.ts +27 -0
  105. package/src/developer-agent/context.js +497 -0
  106. package/src/developer-agent/context.js.map +1 -0
  107. package/src/developer-agent/generator-planning.d.ts +34 -0
  108. package/src/developer-agent/generator-planning.js +645 -0
  109. package/src/developer-agent/generator-planning.js.map +1 -0
  110. package/src/developer-agent/generator-preview.d.ts +8 -0
  111. package/src/developer-agent/generator-preview.js +650 -0
  112. package/src/developer-agent/generator-preview.js.map +1 -0
  113. package/src/developer-agent/git-inspection.d.ts +108 -0
  114. package/src/developer-agent/git-inspection.js +815 -0
  115. package/src/developer-agent/git-inspection.js.map +1 -0
  116. package/src/developer-agent/handoff.d.ts +43 -0
  117. package/src/developer-agent/handoff.js +698 -0
  118. package/src/developer-agent/handoff.js.map +1 -0
  119. package/src/developer-agent/index.d.ts +10 -0
  120. package/src/developer-agent/index.js +14 -0
  121. package/src/developer-agent/index.js.map +1 -0
  122. package/src/developer-agent/model.d.ts +481 -0
  123. package/src/developer-agent/model.js +143 -0
  124. package/src/developer-agent/model.js.map +1 -0
  125. package/src/developer-agent/operation-registry.d.ts +45 -0
  126. package/src/developer-agent/operation-registry.js +1255 -0
  127. package/src/developer-agent/operation-registry.js.map +1 -0
  128. package/src/developer-agent/ordering.d.ts +9 -0
  129. package/src/developer-agent/ordering.js +15 -0
  130. package/src/developer-agent/ordering.js.map +1 -0
  131. package/src/developer-agent/planning.d.ts +18 -0
  132. package/src/developer-agent/planning.js +447 -0
  133. package/src/developer-agent/planning.js.map +1 -0
  134. package/src/developer-agent/preview-changes.d.ts +26 -0
  135. package/src/developer-agent/preview-changes.js +203 -0
  136. package/src/developer-agent/preview-changes.js.map +1 -0
  137. package/src/developer-agent/preview-source.d.ts +2 -0
  138. package/src/developer-agent/preview-source.js +16 -0
  139. package/src/developer-agent/preview-source.js.map +1 -0
  140. package/src/developer-agent/validation.d.ts +18 -0
  141. package/src/developer-agent/validation.js +2617 -0
  142. package/src/developer-agent/validation.js.map +1 -0
  143. package/src/developer-agent/workspace-inspection.d.ts +20 -0
  144. package/src/developer-agent/workspace-inspection.js +1134 -0
  145. package/src/developer-agent/workspace-inspection.js.map +1 -0
  146. package/src/developer-agent/workspace-path.d.ts +6 -0
  147. package/src/developer-agent/workspace-path.js +22 -0
  148. package/src/developer-agent/workspace-path.js.map +1 -0
  149. package/src/executors/blueprint-trust/blueprint-trust.d.ts +29 -0
  150. package/src/executors/blueprint-trust/blueprint-trust.js +115 -0
  151. package/src/executors/blueprint-trust/blueprint-trust.js.map +1 -0
  152. package/src/executors/blueprint-trust/schema.json +27 -0
  153. package/src/executors/blueprint-verification/blueprint-verification.d.ts +13 -0
  154. package/src/executors/blueprint-verification/blueprint-verification.js +110 -0
  155. package/src/executors/blueprint-verification/blueprint-verification.js.map +1 -0
  156. package/src/executors/blueprint-verification/schema.json +44 -0
  157. package/src/executors/deployment-plan/deployment-plan.js +1 -0
  158. package/src/executors/deployment-plan/deployment-plan.js.map +1 -1
  159. package/src/executors/dev-doctor/dev-doctor.d.ts +19 -5
  160. package/src/executors/dev-doctor/dev-doctor.js +186 -32
  161. package/src/executors/dev-doctor/dev-doctor.js.map +1 -1
  162. package/src/executors/dev-doctor/schema.json +1 -6
  163. package/src/executors/dev-setup/dev-setup.d.ts +7 -1
  164. package/src/executors/dev-setup/dev-setup.js +14 -3
  165. package/src/executors/dev-setup/dev-setup.js.map +1 -1
  166. package/src/executors/developer-context/developer-context.d.ts +38 -0
  167. package/src/executors/developer-context/developer-context.js +78 -0
  168. package/src/executors/developer-context/developer-context.js.map +1 -0
  169. package/src/executors/developer-context/schema.json +87 -0
  170. package/src/executors/fleet/fleet.d.ts +12 -43
  171. package/src/executors/fleet/fleet.js +120 -500
  172. package/src/executors/fleet/fleet.js.map +1 -1
  173. package/src/executors/fleet/schema.json +64 -14
  174. package/src/executors/github-bootstrap/github-bootstrap.d.ts +1 -0
  175. package/src/executors/github-bootstrap/github-bootstrap.js +1 -0
  176. package/src/executors/github-bootstrap/github-bootstrap.js.map +1 -1
  177. package/src/executors/github-bootstrap/schema.json +5 -0
  178. package/src/executors/infrastructure-plan/infrastructure-plan.d.ts +144 -0
  179. package/src/executors/infrastructure-plan/infrastructure-plan.js +3320 -0
  180. package/src/executors/infrastructure-plan/infrastructure-plan.js.map +1 -0
  181. package/src/executors/infrastructure-plan/schema.json +78 -0
  182. package/src/executors/secret-guardrails/schema.json +6 -0
  183. package/src/executors/secret-guardrails/secret-guardrails.d.ts +3 -0
  184. package/src/executors/secret-guardrails/secret-guardrails.js +44 -0
  185. package/src/executors/secret-guardrails/secret-guardrails.js.map +1 -0
  186. package/src/executors/secret-metadata/schema.json +31 -0
  187. package/src/executors/secret-metadata/secret-metadata.d.ts +32 -0
  188. package/src/executors/secret-metadata/secret-metadata.js +131 -0
  189. package/src/executors/secret-metadata/secret-metadata.js.map +1 -0
  190. package/src/executors/sst-lifecycle/logging-preflight.d.ts +17 -0
  191. package/src/executors/sst-lifecycle/logging-preflight.js +196 -0
  192. package/src/executors/sst-lifecycle/logging-preflight.js.map +1 -0
  193. package/src/executors/sst-lifecycle/run-sst-command.d.ts +23 -3
  194. package/src/executors/sst-lifecycle/run-sst-command.js +113 -10
  195. package/src/executors/sst-lifecycle/run-sst-command.js.map +1 -1
  196. package/src/executors/sst-lifecycle/schema.json +9 -5
  197. package/src/executors/sst-lifecycle/secret-preflight.d.ts +25 -0
  198. package/src/executors/sst-lifecycle/secret-preflight.js +119 -0
  199. package/src/executors/sst-lifecycle/secret-preflight.js.map +1 -0
  200. package/src/foundation/discovery.d.ts +17 -1
  201. package/src/foundation/discovery.js +16 -1
  202. package/src/foundation/discovery.js.map +1 -1
  203. package/src/foundation/index.d.ts +3 -0
  204. package/src/foundation/index.js +3 -0
  205. package/src/foundation/index.js.map +1 -1
  206. package/src/foundation/local-database-contract.d.ts +1 -0
  207. package/src/foundation/local-database-contract.js +3 -0
  208. package/src/foundation/local-database-contract.js.map +1 -1
  209. package/src/foundation/logging-preflight.d.ts +30 -0
  210. package/src/foundation/logging-preflight.js +138 -0
  211. package/src/foundation/logging-preflight.js.map +1 -0
  212. package/src/foundation/logging.d.ts +70 -0
  213. package/src/foundation/logging.js +133 -0
  214. package/src/foundation/logging.js.map +1 -0
  215. package/src/foundation/preflight.d.ts +9 -0
  216. package/src/foundation/preflight.js +58 -2
  217. package/src/foundation/preflight.js.map +1 -1
  218. package/src/foundation/provision-database-bindings.d.ts +9 -1
  219. package/src/foundation/provision-database-bindings.js +25 -5
  220. package/src/foundation/provision-database-bindings.js.map +1 -1
  221. package/src/foundation/provision-logical-database.d.ts +10 -2
  222. package/src/foundation/provision-logical-database.js +68 -113
  223. package/src/foundation/provision-logical-database.js.map +1 -1
  224. package/src/foundation/router-origin-proof.d.ts +2 -0
  225. package/src/foundation/router-origin-proof.js +25 -0
  226. package/src/foundation/router-origin-proof.js.map +1 -0
  227. package/src/foundation/stages.d.ts +1 -0
  228. package/src/foundation/stages.js +9 -1
  229. package/src/foundation/stages.js.map +1 -1
  230. package/src/frontend-security/index.d.ts +1 -0
  231. package/src/frontend-security/index.js +5 -0
  232. package/src/frontend-security/index.js.map +1 -0
  233. package/src/frontend-security/security-headers.d.ts +50 -0
  234. package/src/frontend-security/security-headers.js +418 -0
  235. package/src/frontend-security/security-headers.js.map +1 -0
  236. package/src/generators/feature-registry.d.ts +13 -0
  237. package/src/generators/feature-registry.js +73 -0
  238. package/src/generators/feature-registry.js.map +1 -0
  239. package/src/generators/function/function.d.ts +1 -1
  240. package/src/generators/function/function.js +51 -6
  241. package/src/generators/function/function.js.map +1 -1
  242. package/src/generators/function/schema.d.ts +1 -0
  243. package/src/generators/function/schema.json +6 -1
  244. package/src/generators/logging-registry.d.ts +13 -0
  245. package/src/generators/logging-registry.js +62 -0
  246. package/src/generators/logging-registry.js.map +1 -0
  247. package/src/generators/post-generation-install.d.ts +67 -0
  248. package/src/generators/post-generation-install.js +3308 -0
  249. package/src/generators/post-generation-install.js.map +1 -0
  250. package/src/generators/preset/generator.js +3 -0
  251. package/src/generators/preset/generator.js.map +1 -1
  252. package/src/generators/preset/tool-versions.d.ts +18 -0
  253. package/src/generators/preset/tool-versions.js +22 -0
  254. package/src/generators/preset/tool-versions.js.map +1 -0
  255. package/src/generators/preset/workspace-files-developer-agent.d.ts +14 -0
  256. package/src/generators/preset/workspace-files-developer-agent.js +511 -0
  257. package/src/generators/preset/workspace-files-developer-agent.js.map +1 -0
  258. package/src/generators/preset/workspace-files-foundation-workload-roles.d.ts +6 -0
  259. package/src/generators/preset/workspace-files-foundation-workload-roles.js +406 -0
  260. package/src/generators/preset/workspace-files-foundation-workload-roles.js.map +1 -0
  261. package/src/generators/preset/workspace-files-performance-cost.d.ts +66 -0
  262. package/src/generators/preset/workspace-files-performance-cost.js +866 -0
  263. package/src/generators/preset/workspace-files-performance-cost.js.map +1 -0
  264. package/src/generators/preset/workspace-files-performance-load.d.ts +73 -0
  265. package/src/generators/preset/workspace-files-performance-load.js +801 -0
  266. package/src/generators/preset/workspace-files-performance-load.js.map +1 -0
  267. package/src/generators/preset/workspace-files-workload-role-baseline.d.ts +9 -0
  268. package/src/generators/preset/workspace-files-workload-role-baseline.js +1102 -0
  269. package/src/generators/preset/workspace-files-workload-role-baseline.js.map +1 -0
  270. package/src/generators/preset/workspace-files.d.ts +14 -1
  271. package/src/generators/preset/workspace-files.js +8189 -245
  272. package/src/generators/preset/workspace-files.js.map +1 -1
  273. package/src/generators/repository-policy/repository-policy.js +3 -47
  274. package/src/generators/repository-policy/repository-policy.js.map +1 -1
  275. package/src/generators/slice/built-in-plan-api-contract-files.d.ts +2 -0
  276. package/src/generators/slice/built-in-plan-api-contract-files.js +2656 -0
  277. package/src/generators/slice/built-in-plan-api-contract-files.js.map +1 -0
  278. package/src/generators/slice/built-in-plan-api-files.d.ts +2 -0
  279. package/src/generators/slice/built-in-plan-api-files.js +1186 -0
  280. package/src/generators/slice/built-in-plan-api-files.js.map +1 -0
  281. package/src/generators/slice/built-in-plan-async-work-files.d.ts +2 -0
  282. package/src/generators/slice/built-in-plan-async-work-files.js +7903 -0
  283. package/src/generators/slice/built-in-plan-async-work-files.js.map +1 -0
  284. package/src/generators/slice/built-in-plan-authorization-files.d.ts +2 -0
  285. package/src/generators/slice/built-in-plan-authorization-files.js +2314 -0
  286. package/src/generators/slice/built-in-plan-authorization-files.js.map +1 -0
  287. package/src/generators/slice/built-in-plan-authorization-infrastructure-files.d.ts +2 -0
  288. package/src/generators/slice/built-in-plan-authorization-infrastructure-files.js +559 -0
  289. package/src/generators/slice/built-in-plan-authorization-infrastructure-files.js.map +1 -0
  290. package/src/generators/slice/built-in-plan-data-deletion-files.d.ts +2 -0
  291. package/src/generators/slice/built-in-plan-data-deletion-files.js +1101 -0
  292. package/src/generators/slice/built-in-plan-data-deletion-files.js.map +1 -0
  293. package/src/generators/slice/built-in-plan-data-export-infrastructure-files.d.ts +2 -0
  294. package/src/generators/slice/built-in-plan-data-export-infrastructure-files.js +249 -0
  295. package/src/generators/slice/built-in-plan-data-export-infrastructure-files.js.map +1 -0
  296. package/src/generators/slice/built-in-plan-data-files.d.ts +2 -0
  297. package/src/generators/slice/built-in-plan-data-files.js +1530 -0
  298. package/src/generators/slice/built-in-plan-data-files.js.map +1 -0
  299. package/src/generators/slice/built-in-plan-data-lifecycle-files.d.ts +2 -0
  300. package/src/generators/slice/built-in-plan-data-lifecycle-files.js +750 -0
  301. package/src/generators/slice/built-in-plan-data-lifecycle-files.js.map +1 -0
  302. package/src/generators/slice/built-in-plan-data-lifecycle-runtime-files.d.ts +2 -0
  303. package/src/generators/slice/built-in-plan-data-lifecycle-runtime-files.js +828 -0
  304. package/src/generators/slice/built-in-plan-data-lifecycle-runtime-files.js.map +1 -0
  305. package/src/generators/slice/built-in-plan-data-retention-job-files.d.ts +2 -0
  306. package/src/generators/slice/built-in-plan-data-retention-job-files.js +2604 -0
  307. package/src/generators/slice/built-in-plan-data-retention-job-files.js.map +1 -0
  308. package/src/generators/slice/built-in-plan-data-retention-launcher-files.d.ts +2 -0
  309. package/src/generators/slice/built-in-plan-data-retention-launcher-files.js +144 -0
  310. package/src/generators/slice/built-in-plan-data-retention-launcher-files.js.map +1 -0
  311. package/src/generators/slice/built-in-plan-data-rights-files.d.ts +2 -0
  312. package/src/generators/slice/built-in-plan-data-rights-files.js +4628 -0
  313. package/src/generators/slice/built-in-plan-data-rights-files.js.map +1 -0
  314. package/src/generators/slice/built-in-plan-database-lifecycle-files.d.ts +2 -0
  315. package/src/generators/slice/built-in-plan-database-lifecycle-files.js +1901 -0
  316. package/src/generators/slice/built-in-plan-database-lifecycle-files.js.map +1 -0
  317. package/src/generators/slice/built-in-plan-database-retirement-rehearsal-files.d.ts +2 -0
  318. package/src/generators/slice/built-in-plan-database-retirement-rehearsal-files.js +485 -0
  319. package/src/generators/slice/built-in-plan-database-retirement-rehearsal-files.js.map +1 -0
  320. package/src/generators/slice/built-in-plan-foundation-files.d.ts +2 -0
  321. package/src/generators/slice/built-in-plan-foundation-files.js +184 -0
  322. package/src/generators/slice/built-in-plan-foundation-files.js.map +1 -0
  323. package/src/generators/slice/built-in-plan-frontend-files.d.ts +2 -0
  324. package/src/generators/slice/built-in-plan-frontend-files.js +2233 -0
  325. package/src/generators/slice/built-in-plan-frontend-files.js.map +1 -0
  326. package/src/generators/slice/built-in-plan-infrastructure-files.d.ts +2 -0
  327. package/src/generators/slice/built-in-plan-infrastructure-files.js +3038 -0
  328. package/src/generators/slice/built-in-plan-infrastructure-files.js.map +1 -0
  329. package/src/generators/slice/built-in-plan-infrastructure-safety-files.d.ts +2 -0
  330. package/src/generators/slice/built-in-plan-infrastructure-safety-files.js +312 -0
  331. package/src/generators/slice/built-in-plan-infrastructure-safety-files.js.map +1 -0
  332. package/src/generators/slice/built-in-plan-metadata-files.d.ts +3 -0
  333. package/src/generators/slice/built-in-plan-metadata-files.js +219 -0
  334. package/src/generators/slice/built-in-plan-metadata-files.js.map +1 -0
  335. package/src/generators/slice/built-in-plan-operations-files.d.ts +2 -0
  336. package/src/generators/slice/built-in-plan-operations-files.js +630 -0
  337. package/src/generators/slice/built-in-plan-operations-files.js.map +1 -0
  338. package/src/generators/slice/built-in-plan-performance-files.d.ts +3 -0
  339. package/src/generators/slice/built-in-plan-performance-files.js +3293 -0
  340. package/src/generators/slice/built-in-plan-performance-files.js.map +1 -0
  341. package/src/generators/slice/built-in-plan-project-files.d.ts +3 -0
  342. package/src/generators/slice/built-in-plan-project-files.js +979 -0
  343. package/src/generators/slice/built-in-plan-project-files.js.map +1 -0
  344. package/src/generators/slice/built-in-plan-release-files.d.ts +2 -0
  345. package/src/generators/slice/built-in-plan-release-files.js +6387 -0
  346. package/src/generators/slice/built-in-plan-release-files.js.map +1 -0
  347. package/src/generators/slice/built-in-plan-reliability-files.d.ts +2 -0
  348. package/src/generators/slice/built-in-plan-reliability-files.js +4499 -0
  349. package/src/generators/slice/built-in-plan-reliability-files.js.map +1 -0
  350. package/src/generators/slice/built-in-plan-secret-runtime-files.d.ts +2 -0
  351. package/src/generators/slice/built-in-plan-secret-runtime-files.js +1004 -0
  352. package/src/generators/slice/built-in-plan-secret-runtime-files.js.map +1 -0
  353. package/src/generators/slice/built-in-plan-shared.d.ts +53 -0
  354. package/src/generators/slice/built-in-plan-shared.js +113 -0
  355. package/src/generators/slice/built-in-plan-shared.js.map +1 -0
  356. package/src/generators/slice/built-in-plan-testing-files.d.ts +2 -0
  357. package/src/generators/slice/built-in-plan-testing-files.js +2356 -0
  358. package/src/generators/slice/built-in-plan-testing-files.js.map +1 -0
  359. package/src/generators/slice/built-in-plan-verification-files.d.ts +2 -0
  360. package/src/generators/slice/built-in-plan-verification-files.js +358 -0
  361. package/src/generators/slice/built-in-plan-verification-files.js.map +1 -0
  362. package/src/generators/slice/built-in-plan-web-files.d.ts +2 -0
  363. package/src/generators/slice/built-in-plan-web-files.js +430 -0
  364. package/src/generators/slice/built-in-plan-web-files.js.map +1 -0
  365. package/src/generators/slice/built-in-plan-workload-role-files.d.ts +2 -0
  366. package/src/generators/slice/built-in-plan-workload-role-files.js +2356 -0
  367. package/src/generators/slice/built-in-plan-workload-role-files.js.map +1 -0
  368. package/src/generators/slice/built-in-plan.d.ts +8 -0
  369. package/src/generators/slice/built-in-plan.js +264 -0
  370. package/src/generators/slice/built-in-plan.js.map +1 -0
  371. package/src/generators/slice/schema.json +1 -1
  372. package/src/generators/slice/slice.d.ts +1 -22
  373. package/src/generators/slice/slice.js +185 -1510
  374. package/src/generators/slice/slice.js.map +1 -1
  375. package/src/generators/upgrade/schema.d.ts +2 -0
  376. package/src/generators/upgrade/schema.json +11 -1
  377. package/src/generators/upgrade/upgrade.d.ts +51 -1
  378. package/src/generators/upgrade/upgrade.js +820 -82
  379. package/src/generators/upgrade/upgrade.js.map +1 -1
  380. package/src/generators/workload/frozen-container.d.ts +8 -0
  381. package/src/generators/workload/frozen-container.js +36 -0
  382. package/src/generators/workload/frozen-container.js.map +1 -0
  383. package/src/generators/workload/performance-registration.d.ts +32 -0
  384. package/src/generators/workload/performance-registration.js +226 -0
  385. package/src/generators/workload/performance-registration.js.map +1 -0
  386. package/src/generators/workload/reliability-registration.d.ts +16 -0
  387. package/src/generators/workload/reliability-registration.js +150 -0
  388. package/src/generators/workload/reliability-registration.js.map +1 -0
  389. package/src/generators/workload/schema.d.ts +1 -0
  390. package/src/generators/workload/schema.json +6 -1
  391. package/src/generators/workload/service-performance-files.d.ts +4 -0
  392. package/src/generators/workload/service-performance-files.js +1846 -0
  393. package/src/generators/workload/service-performance-files.js.map +1 -0
  394. package/src/generators/workload/workload.d.ts +3 -2
  395. package/src/generators/workload/workload.js +1083 -18
  396. package/src/generators/workload/workload.js.map +1 -1
  397. package/src/git-policy/action-pins.d.ts +10 -0
  398. package/src/git-policy/action-pins.js +10 -0
  399. package/src/git-policy/action-pins.js.map +1 -1
  400. package/src/git-policy/github-bootstrap.d.ts +14 -1
  401. package/src/git-policy/github-bootstrap.js +274 -46
  402. package/src/git-policy/github-bootstrap.js.map +1 -1
  403. package/src/index.d.ts +2 -0
  404. package/src/index.js +2 -0
  405. package/src/index.js.map +1 -1
  406. package/src/infrastructure-change/convergence.d.ts +13 -0
  407. package/src/infrastructure-change/convergence.js +85 -0
  408. package/src/infrastructure-change/convergence.js.map +1 -0
  409. package/src/infrastructure-change/drift.d.ts +13 -0
  410. package/src/infrastructure-change/drift.js +112 -0
  411. package/src/infrastructure-change/drift.js.map +1 -0
  412. package/src/infrastructure-change/index.d.ts +7 -0
  413. package/src/infrastructure-change/index.js +11 -0
  414. package/src/infrastructure-change/index.js.map +1 -0
  415. package/src/infrastructure-change/model.d.ts +253 -0
  416. package/src/infrastructure-change/model.js +28 -0
  417. package/src/infrastructure-change/model.js.map +1 -0
  418. package/src/infrastructure-change/normalize.d.ts +12 -0
  419. package/src/infrastructure-change/normalize.js +245 -0
  420. package/src/infrastructure-change/normalize.js.map +1 -0
  421. package/src/infrastructure-change/plan.d.ts +40 -0
  422. package/src/infrastructure-change/plan.js +361 -0
  423. package/src/infrastructure-change/plan.js.map +1 -0
  424. package/src/infrastructure-change/risk.d.ts +7 -0
  425. package/src/infrastructure-change/risk.js +269 -0
  426. package/src/infrastructure-change/risk.js.map +1 -0
  427. package/src/infrastructure-change/summary.d.ts +20 -0
  428. package/src/infrastructure-change/summary.js +130 -0
  429. package/src/infrastructure-change/summary.js.map +1 -0
  430. package/src/local-dev/context-discovery.d.ts +2 -0
  431. package/src/local-dev/context-discovery.js +59 -0
  432. package/src/local-dev/context-discovery.js.map +1 -0
  433. package/src/local-dev/contract-validation.d.ts +15 -0
  434. package/src/local-dev/contract-validation.js +84 -0
  435. package/src/local-dev/contract-validation.js.map +1 -0
  436. package/src/local-dev/contracts.d.ts +10 -1
  437. package/src/local-dev/contracts.js +57 -5
  438. package/src/local-dev/contracts.js.map +1 -1
  439. package/src/local-dev/control-contract.d.ts +67 -0
  440. package/src/local-dev/control-contract.js +180 -0
  441. package/src/local-dev/control-contract.js.map +1 -0
  442. package/src/local-dev/dev-command-core.d.ts +60 -0
  443. package/src/local-dev/dev-command-core.js +89 -0
  444. package/src/local-dev/dev-command-core.js.map +1 -0
  445. package/src/local-dev/effects.d.ts +16 -0
  446. package/src/local-dev/effects.js +63 -0
  447. package/src/local-dev/effects.js.map +1 -0
  448. package/src/local-dev/environment-inspector.d.ts +125 -0
  449. package/src/local-dev/environment-inspector.js +687 -0
  450. package/src/local-dev/environment-inspector.js.map +1 -0
  451. package/src/local-dev/environment-state.d.ts +113 -0
  452. package/src/local-dev/environment-state.js +463 -0
  453. package/src/local-dev/environment-state.js.map +1 -0
  454. package/src/local-dev/errors.d.ts +6 -0
  455. package/src/local-dev/errors.js +41 -0
  456. package/src/local-dev/errors.js.map +1 -0
  457. package/src/local-dev/fleet-client.d.ts +33 -0
  458. package/src/local-dev/fleet-client.js +156 -0
  459. package/src/local-dev/fleet-client.js.map +1 -0
  460. package/src/local-dev/fleet-configuration.d.ts +13 -0
  461. package/src/local-dev/fleet-configuration.js +71 -0
  462. package/src/local-dev/fleet-configuration.js.map +1 -0
  463. package/src/local-dev/fleet-inventory.d.ts +56 -0
  464. package/src/local-dev/fleet-inventory.js +469 -0
  465. package/src/local-dev/fleet-inventory.js.map +1 -0
  466. package/src/local-dev/fleet-ipc.d.ts +28 -0
  467. package/src/local-dev/fleet-ipc.js +267 -0
  468. package/src/local-dev/fleet-ipc.js.map +1 -0
  469. package/src/local-dev/fleet-launcher.d.ts +53 -0
  470. package/src/local-dev/fleet-launcher.js +379 -0
  471. package/src/local-dev/fleet-launcher.js.map +1 -0
  472. package/src/local-dev/fleet-lock.d.ts +41 -0
  473. package/src/local-dev/fleet-lock.js +135 -0
  474. package/src/local-dev/fleet-lock.js.map +1 -0
  475. package/src/local-dev/fleet-logs.d.ts +66 -0
  476. package/src/local-dev/fleet-logs.js +542 -0
  477. package/src/local-dev/fleet-logs.js.map +1 -0
  478. package/src/local-dev/fleet-process.d.ts +50 -0
  479. package/src/local-dev/fleet-process.js +289 -0
  480. package/src/local-dev/fleet-process.js.map +1 -0
  481. package/src/local-dev/fleet-runtime.d.ts +22 -0
  482. package/src/local-dev/fleet-runtime.js +368 -0
  483. package/src/local-dev/fleet-runtime.js.map +1 -0
  484. package/src/local-dev/fleet-session.d.ts +70 -0
  485. package/src/local-dev/fleet-session.js +301 -0
  486. package/src/local-dev/fleet-session.js.map +1 -0
  487. package/src/local-dev/fleet-slice-runner-daemon.d.ts +1 -0
  488. package/src/local-dev/fleet-slice-runner-daemon.js +21 -0
  489. package/src/local-dev/fleet-slice-runner-daemon.js.map +1 -0
  490. package/src/local-dev/fleet-startup.d.ts +22 -0
  491. package/src/local-dev/fleet-startup.js +114 -0
  492. package/src/local-dev/fleet-startup.js.map +1 -0
  493. package/src/local-dev/fleet-state.d.ts +62 -0
  494. package/src/local-dev/fleet-state.js +297 -0
  495. package/src/local-dev/fleet-state.js.map +1 -0
  496. package/src/local-dev/fleet-supervisor-daemon.d.ts +1 -0
  497. package/src/local-dev/fleet-supervisor-daemon.js +41 -0
  498. package/src/local-dev/fleet-supervisor-daemon.js.map +1 -0
  499. package/src/local-dev/fleet-supervisor.d.ts +52 -0
  500. package/src/local-dev/fleet-supervisor.js +384 -0
  501. package/src/local-dev/fleet-supervisor.js.map +1 -0
  502. package/src/local-dev/gateway.js +1 -1
  503. package/src/local-dev/gateway.js.map +1 -1
  504. package/src/local-dev/identity.js +4 -6
  505. package/src/local-dev/identity.js.map +1 -1
  506. package/src/local-dev/index.d.ts +1 -0
  507. package/src/local-dev/index.js +1 -0
  508. package/src/local-dev/index.js.map +1 -1
  509. package/src/local-dev/local-context.d.ts +62 -0
  510. package/src/local-dev/local-context.js +299 -0
  511. package/src/local-dev/local-context.js.map +1 -0
  512. package/src/local-dev/nx-workspace.d.ts +45 -0
  513. package/src/local-dev/nx-workspace.js +228 -0
  514. package/src/local-dev/nx-workspace.js.map +1 -0
  515. package/src/local-dev/personal-secret-ledger.d.ts +75 -0
  516. package/src/local-dev/personal-secret-ledger.js +391 -0
  517. package/src/local-dev/personal-secret-ledger.js.map +1 -0
  518. package/src/local-dev/personal-stage.d.ts +18 -0
  519. package/src/local-dev/personal-stage.js +129 -0
  520. package/src/local-dev/personal-stage.js.map +1 -0
  521. package/src/local-dev/private-state.d.ts +17 -0
  522. package/src/local-dev/private-state.js +254 -0
  523. package/src/local-dev/private-state.js.map +1 -0
  524. package/src/local-dev/process-identity.d.ts +9 -0
  525. package/src/local-dev/process-identity.js +79 -0
  526. package/src/local-dev/process-identity.js.map +1 -0
  527. package/src/local-dev/runtime-paths.d.ts +17 -0
  528. package/src/local-dev/runtime-paths.js +33 -0
  529. package/src/local-dev/runtime-paths.js.map +1 -0
  530. package/src/local-dev/secret-slice-claim.d.ts +17 -0
  531. package/src/local-dev/secret-slice-claim.js +75 -0
  532. package/src/local-dev/secret-slice-claim.js.map +1 -0
  533. package/src/local-dev/slice-claim.d.ts +36 -0
  534. package/src/local-dev/slice-claim.js +199 -0
  535. package/src/local-dev/slice-claim.js.map +1 -0
  536. package/src/local-dev/slice-runner.d.ts +121 -0
  537. package/src/local-dev/slice-runner.js +715 -0
  538. package/src/local-dev/slice-runner.js.map +1 -0
  539. package/src/local-dev/tls.js +51 -17
  540. package/src/local-dev/tls.js.map +1 -1
  541. package/src/ownership/composition.d.ts +5 -2
  542. package/src/ownership/composition.js +26 -3
  543. package/src/ownership/composition.js.map +1 -1
  544. package/src/ownership/hash.d.ts +1 -1
  545. package/src/ownership/hash.js +3 -1
  546. package/src/ownership/hash.js.map +1 -1
  547. package/src/ownership/record.d.ts +32 -1
  548. package/src/ownership/record.js +139 -2
  549. package/src/ownership/record.js.map +1 -1
  550. package/src/performance/cost-collection.d.ts +225 -0
  551. package/src/performance/cost-collection.js +825 -0
  552. package/src/performance/cost-collection.js.map +1 -0
  553. package/src/performance/cost-controls.d.ts +131 -0
  554. package/src/performance/cost-controls.js +336 -0
  555. package/src/performance/cost-controls.js.map +1 -0
  556. package/src/performance/evidence.d.ts +140 -0
  557. package/src/performance/evidence.js +599 -0
  558. package/src/performance/evidence.js.map +1 -0
  559. package/src/performance/index.d.ts +10 -0
  560. package/src/performance/index.js +14 -0
  561. package/src/performance/index.js.map +1 -0
  562. package/src/performance/load-safety.d.ts +84 -0
  563. package/src/performance/load-safety.js +346 -0
  564. package/src/performance/load-safety.js.map +1 -0
  565. package/src/performance/model.d.ts +129 -0
  566. package/src/performance/model.js +452 -0
  567. package/src/performance/model.js.map +1 -0
  568. package/src/performance/pr-artifact-budget.d.ts +42 -0
  569. package/src/performance/pr-artifact-budget.js +151 -0
  570. package/src/performance/pr-artifact-budget.js.map +1 -0
  571. package/src/performance/runner.d.ts +75 -0
  572. package/src/performance/runner.js +227 -0
  573. package/src/performance/runner.js.map +1 -0
  574. package/src/performance/scenario-endpoint.d.ts +1 -0
  575. package/src/performance/scenario-endpoint.js +5 -0
  576. package/src/performance/scenario-endpoint.js.map +1 -0
  577. package/src/performance/scenario.d.ts +193 -0
  578. package/src/performance/scenario.js +736 -0
  579. package/src/performance/scenario.js.map +1 -0
  580. package/src/performance/test-fixtures.d.ts +7 -0
  581. package/src/performance/test-fixtures.js +169 -0
  582. package/src/performance/test-fixtures.js.map +1 -0
  583. package/src/performance/unit-cost.d.ts +105 -0
  584. package/src/performance/unit-cost.js +364 -0
  585. package/src/performance/unit-cost.js.map +1 -0
  586. package/src/release/index.d.ts +4 -0
  587. package/src/release/index.js +8 -0
  588. package/src/release/index.js.map +1 -0
  589. package/src/release/lifecycle.d.ts +132 -0
  590. package/src/release/lifecycle.js +411 -0
  591. package/src/release/lifecycle.js.map +1 -0
  592. package/src/release/manifest.d.ts +148 -0
  593. package/src/release/manifest.js +503 -0
  594. package/src/release/manifest.js.map +1 -0
  595. package/src/release/rollout.d.ts +170 -0
  596. package/src/release/rollout.js +578 -0
  597. package/src/release/rollout.js.map +1 -0
  598. package/src/release/source-authority.d.ts +19 -0
  599. package/src/release/source-authority.js +195 -0
  600. package/src/release/source-authority.js.map +1 -0
  601. package/src/repository-policy/deployment-plan.d.ts +2 -1
  602. package/src/repository-policy/deployment-plan.js +2 -0
  603. package/src/repository-policy/deployment-plan.js.map +1 -1
  604. package/src/repository-policy/policy.d.ts +1 -1
  605. package/src/repository-policy/policy.js +29 -25
  606. package/src/repository-policy/policy.js.map +1 -1
  607. package/src/schemas/aggregate-count-evidence-v1.json +135 -0
  608. package/src/schemas/api-contract-baseline-v1.json +674 -0
  609. package/src/schemas/api-contract-compatibility-report-v1.json +126 -0
  610. package/src/schemas/aws-billing-actual-evidence-v1.json +407 -0
  611. package/src/schemas/blueprint-v1.json +18 -1
  612. package/src/schemas/data-lifecycle-policy-v1.json +517 -0
  613. package/src/schemas/generated-ownership-v2.json +22 -0
  614. package/src/schemas/performance-policy-v1.json +335 -0
  615. package/src/schemas/repository-policy-v1.json +1 -0
  616. package/src/schemas/testing-evidence-quarantine-v1.json +168 -0
  617. package/src/schemas/testing-evidence-result-v1.json +319 -0
  618. package/src/secrets/adapters.d.ts +49 -0
  619. package/src/secrets/adapters.js +184 -0
  620. package/src/secrets/adapters.js.map +1 -0
  621. package/src/secrets/aws-control-plane.d.ts +20 -0
  622. package/src/secrets/aws-control-plane.js +255 -0
  623. package/src/secrets/aws-control-plane.js.map +1 -0
  624. package/src/secrets/declaration-verification.d.ts +11 -0
  625. package/src/secrets/declaration-verification.js +68 -0
  626. package/src/secrets/declaration-verification.js.map +1 -0
  627. package/src/secrets/guardrails.d.ts +26 -0
  628. package/src/secrets/guardrails.js +328 -0
  629. package/src/secrets/guardrails.js.map +1 -0
  630. package/src/secrets/index.d.ts +12 -0
  631. package/src/secrets/index.js +16 -0
  632. package/src/secrets/index.js.map +1 -0
  633. package/src/secrets/metadata.d.ts +48 -0
  634. package/src/secrets/metadata.js +171 -0
  635. package/src/secrets/metadata.js.map +1 -0
  636. package/src/secrets/model.d.ts +49 -0
  637. package/src/secrets/model.js +125 -0
  638. package/src/secrets/model.js.map +1 -0
  639. package/src/secrets/operator.d.ts +101 -0
  640. package/src/secrets/operator.js +229 -0
  641. package/src/secrets/operator.js.map +1 -0
  642. package/src/secrets/permissions.d.ts +34 -0
  643. package/src/secrets/permissions.js +86 -0
  644. package/src/secrets/permissions.js.map +1 -0
  645. package/src/secrets/personal-command.d.ts +83 -0
  646. package/src/secrets/personal-command.js +197 -0
  647. package/src/secrets/personal-command.js.map +1 -0
  648. package/src/secrets/personal-ledger.d.ts +21 -0
  649. package/src/secrets/personal-ledger.js +135 -0
  650. package/src/secrets/personal-ledger.js.map +1 -0
  651. package/src/secrets/registry.d.ts +9 -0
  652. package/src/secrets/registry.js +86 -0
  653. package/src/secrets/registry.js.map +1 -0
  654. package/src/secrets/verification.d.ts +18 -0
  655. package/src/secrets/verification.js +139 -0
  656. package/src/secrets/verification.js.map +1 -0
  657. package/src/secrets/workload-access.d.ts +46 -0
  658. package/src/secrets/workload-access.js +163 -0
  659. package/src/secrets/workload-access.js.map +1 -0
  660. package/src/supply-chain/action-pins.d.ts +26 -0
  661. package/src/supply-chain/action-pins.js +208 -0
  662. package/src/supply-chain/action-pins.js.map +1 -0
  663. package/src/supply-chain/blueprint-trust-git.d.ts +130 -0
  664. package/src/supply-chain/blueprint-trust-git.js +1581 -0
  665. package/src/supply-chain/blueprint-trust-git.js.map +1 -0
  666. package/src/supply-chain/blueprint-trust-process.d.ts +4 -0
  667. package/src/supply-chain/blueprint-trust-process.js +88 -0
  668. package/src/supply-chain/blueprint-trust-process.js.map +1 -0
  669. package/src/supply-chain/blueprint-trust.d.ts +354 -0
  670. package/src/supply-chain/blueprint-trust.js +1558 -0
  671. package/src/supply-chain/blueprint-trust.js.map +1 -0
  672. package/src/supply-chain/blueprint-verification-authority.d.ts +62 -0
  673. package/src/supply-chain/blueprint-verification-authority.js +588 -0
  674. package/src/supply-chain/blueprint-verification-authority.js.map +1 -0
  675. package/src/supply-chain/blueprint-verification-execution.d.ts +68 -0
  676. package/src/supply-chain/blueprint-verification-execution.js +624 -0
  677. package/src/supply-chain/blueprint-verification-execution.js.map +1 -0
  678. package/src/supply-chain/build-output.d.ts +35 -0
  679. package/src/supply-chain/build-output.js +398 -0
  680. package/src/supply-chain/build-output.js.map +1 -0
  681. package/src/supply-chain/common.d.ts +21 -0
  682. package/src/supply-chain/common.js +107 -0
  683. package/src/supply-chain/common.js.map +1 -0
  684. package/src/supply-chain/container-artifact-contract.d.ts +23 -0
  685. package/src/supply-chain/container-artifact-contract.js +208 -0
  686. package/src/supply-chain/container-artifact-contract.js.map +1 -0
  687. package/src/supply-chain/container-release.d.ts +119 -0
  688. package/src/supply-chain/container-release.js +496 -0
  689. package/src/supply-chain/container-release.js.map +1 -0
  690. package/src/supply-chain/ecr-applicability.d.ts +19 -0
  691. package/src/supply-chain/ecr-applicability.js +103 -0
  692. package/src/supply-chain/ecr-applicability.js.map +1 -0
  693. package/src/supply-chain/ecr-scanning.d.ts +83 -0
  694. package/src/supply-chain/ecr-scanning.js +321 -0
  695. package/src/supply-chain/ecr-scanning.js.map +1 -0
  696. package/src/supply-chain/ecs-deployed-image.d.ts +85 -0
  697. package/src/supply-chain/ecs-deployed-image.js +300 -0
  698. package/src/supply-chain/ecs-deployed-image.js.map +1 -0
  699. package/src/supply-chain/errors.d.ts +6 -0
  700. package/src/supply-chain/errors.js +15 -0
  701. package/src/supply-chain/errors.js.map +1 -0
  702. package/src/supply-chain/generated-blueprint-trust-command.d.ts +4 -0
  703. package/src/supply-chain/generated-blueprint-trust-command.js +1362 -0
  704. package/src/supply-chain/generated-blueprint-trust-command.js.map +1 -0
  705. package/src/supply-chain/generated-command.d.ts +1 -0
  706. package/src/supply-chain/generated-command.js +687 -0
  707. package/src/supply-chain/generated-command.js.map +1 -0
  708. package/src/supply-chain/generated-container-release-command.d.ts +16 -0
  709. package/src/supply-chain/generated-container-release-command.js +2087 -0
  710. package/src/supply-chain/generated-container-release-command.js.map +1 -0
  711. package/src/supply-chain/generated-ecr-collector-command.d.ts +21 -0
  712. package/src/supply-chain/generated-ecr-collector-command.js +1338 -0
  713. package/src/supply-chain/generated-ecr-collector-command.js.map +1 -0
  714. package/src/supply-chain/generated-files.d.ts +13 -0
  715. package/src/supply-chain/generated-files.js +401 -0
  716. package/src/supply-chain/generated-files.js.map +1 -0
  717. package/src/supply-chain/generated-scanner-command.d.ts +1 -0
  718. package/src/supply-chain/generated-scanner-command.js +718 -0
  719. package/src/supply-chain/generated-scanner-command.js.map +1 -0
  720. package/src/supply-chain/index.d.ts +28 -0
  721. package/src/supply-chain/index.js +35 -0
  722. package/src/supply-chain/index.js.map +1 -0
  723. package/src/supply-chain/inventory.d.ts +79 -0
  724. package/src/supply-chain/inventory.js +717 -0
  725. package/src/supply-chain/inventory.js.map +1 -0
  726. package/src/supply-chain/license-expression.d.ts +7 -0
  727. package/src/supply-chain/license-expression.js +128 -0
  728. package/src/supply-chain/license-expression.js.map +1 -0
  729. package/src/supply-chain/pnpm-toolchain-authority.d.ts +31 -0
  730. package/src/supply-chain/pnpm-toolchain-authority.js +316 -0
  731. package/src/supply-chain/pnpm-toolchain-authority.js.map +1 -0
  732. package/src/supply-chain/policy.d.ts +105 -0
  733. package/src/supply-chain/policy.js +301 -0
  734. package/src/supply-chain/policy.js.map +1 -0
  735. package/src/supply-chain/publication.d.ts +48 -0
  736. package/src/supply-chain/publication.js +85 -0
  737. package/src/supply-chain/publication.js.map +1 -0
  738. package/src/supply-chain/sbom.d.ts +228 -0
  739. package/src/supply-chain/sbom.js +826 -0
  740. package/src/supply-chain/sbom.js.map +1 -0
  741. package/src/supply-chain/scanner.d.ts +77 -0
  742. package/src/supply-chain/scanner.js +502 -0
  743. package/src/supply-chain/scanner.js.map +1 -0
  744. package/src/supply-chain/vendored-source.d.ts +95 -0
  745. package/src/supply-chain/vendored-source.js +315 -0
  746. package/src/supply-chain/vendored-source.js.map +1 -0
  747. package/src/testing-evidence/fixture-scope.d.ts +52 -0
  748. package/src/testing-evidence/fixture-scope.js +140 -0
  749. package/src/testing-evidence/fixture-scope.js.map +1 -0
  750. package/src/testing-evidence/index.d.ts +5 -0
  751. package/src/testing-evidence/index.js +9 -0
  752. package/src/testing-evidence/index.js.map +1 -0
  753. package/src/testing-evidence/quarantine.d.ts +48 -0
  754. package/src/testing-evidence/quarantine.js +253 -0
  755. package/src/testing-evidence/quarantine.js.map +1 -0
  756. package/src/testing-evidence/result.d.ts +108 -0
  757. package/src/testing-evidence/result.js +571 -0
  758. package/src/testing-evidence/result.js.map +1 -0
  759. package/src/testing-evidence/runner-adapter.d.ts +51 -0
  760. package/src/testing-evidence/runner-adapter.js +288 -0
  761. package/src/testing-evidence/runner-adapter.js.map +1 -0
  762. package/src/testing-evidence/sensitive-artifacts.d.ts +13 -0
  763. package/src/testing-evidence/sensitive-artifacts.js +93 -0
  764. package/src/testing-evidence/sensitive-artifacts.js.map +1 -0
  765. package/src/work-markers/work-markers.js +4 -3
  766. package/src/work-markers/work-markers.js.map +1 -1
  767. package/src/workload-roles/account-baseline.d.ts +132 -0
  768. package/src/workload-roles/account-baseline.js +743 -0
  769. package/src/workload-roles/account-baseline.js.map +1 -0
  770. package/src/workload-roles/authority.d.ts +38 -0
  771. package/src/workload-roles/authority.js +156 -0
  772. package/src/workload-roles/authority.js.map +1 -0
  773. package/src/workload-roles/aws-adapter.d.ts +99 -0
  774. package/src/workload-roles/aws-adapter.js +416 -0
  775. package/src/workload-roles/aws-adapter.js.map +1 -0
  776. package/src/workload-roles/aws-internal-handler.d.ts +27 -0
  777. package/src/workload-roles/aws-internal-handler.js +58 -0
  778. package/src/workload-roles/aws-internal-handler.js.map +1 -0
  779. package/src/workload-roles/aws-s3-state.d.ts +52 -0
  780. package/src/workload-roles/aws-s3-state.js +164 -0
  781. package/src/workload-roles/aws-s3-state.js.map +1 -0
  782. package/src/workload-roles/aws-sdk-control-plane.d.ts +12 -0
  783. package/src/workload-roles/aws-sdk-control-plane.js +291 -0
  784. package/src/workload-roles/aws-sdk-control-plane.js.map +1 -0
  785. package/src/workload-roles/boundary.d.ts +33 -0
  786. package/src/workload-roles/boundary.js +130 -0
  787. package/src/workload-roles/boundary.js.map +1 -0
  788. package/src/workload-roles/convergence.d.ts +66 -0
  789. package/src/workload-roles/convergence.js +186 -0
  790. package/src/workload-roles/convergence.js.map +1 -0
  791. package/src/workload-roles/effective-policy.d.ts +51 -0
  792. package/src/workload-roles/effective-policy.js +183 -0
  793. package/src/workload-roles/effective-policy.js.map +1 -0
  794. package/src/workload-roles/handler.d.ts +43 -0
  795. package/src/workload-roles/handler.js +130 -0
  796. package/src/workload-roles/handler.js.map +1 -0
  797. package/src/workload-roles/history.d.ts +47 -0
  798. package/src/workload-roles/history.js +324 -0
  799. package/src/workload-roles/history.js.map +1 -0
  800. package/src/workload-roles/index.d.ts +17 -0
  801. package/src/workload-roles/index.js +21 -0
  802. package/src/workload-roles/index.js.map +1 -0
  803. package/src/workload-roles/injection.d.ts +119 -0
  804. package/src/workload-roles/injection.js +495 -0
  805. package/src/workload-roles/injection.js.map +1 -0
  806. package/src/workload-roles/manifest.d.ts +54 -0
  807. package/src/workload-roles/manifest.js +343 -0
  808. package/src/workload-roles/manifest.js.map +1 -0
  809. package/src/workload-roles/provisioner.d.ts +70 -0
  810. package/src/workload-roles/provisioner.js +231 -0
  811. package/src/workload-roles/provisioner.js.map +1 -0
  812. package/src/workload-roles/registration.d.ts +101 -0
  813. package/src/workload-roles/registration.js +457 -0
  814. package/src/workload-roles/registration.js.map +1 -0
  815. package/src/workload-roles/stage-boundary.d.ts +31 -0
  816. package/src/workload-roles/stage-boundary.js +208 -0
  817. package/src/workload-roles/stage-boundary.js.map +1 -0
  818. package/src/workload-roles/standard-slice.d.ts +54 -0
  819. package/src/workload-roles/standard-slice.js +252 -0
  820. package/src/workload-roles/standard-slice.js.map +1 -0
  821. package/migrations/standard-pre-v1-to-v1.md +0 -11
  822. package/src/foundation/aurora-logical-database.d.ts +0 -76
  823. package/src/foundation/aurora-logical-database.js +0 -419
  824. package/src/foundation/aurora-logical-database.js.map +0 -1
@@ -0,0 +1,3293 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PRODUCT_PERFORMANCE_SEEDED_PATHS = void 0;
4
+ exports.renderProductPerformanceFiles = renderProductPerformanceFiles;
5
+ const built_in_plan_shared_js_1 = require("./built-in-plan-shared.js");
6
+ const index_js_1 = require("../../performance/index.js");
7
+ exports.PRODUCT_PERFORMANCE_SEEDED_PATHS = [
8
+ 'docs/runbooks/performance-capacity-cost.md',
9
+ 'performance/aggregate-count-provider.ts',
10
+ 'performance/cost-allocation.json',
11
+ 'performance/cost-collection.json',
12
+ 'performance/load-scenarios.json',
13
+ 'performance/policy.json',
14
+ ];
15
+ /** @internal */
16
+ function renderProductPerformanceFiles(name) {
17
+ const pascalName = name
18
+ .split('-')
19
+ .map((part) => `${part.charAt(0).toUpperCase()}${part.slice(1)}`)
20
+ .join('');
21
+ return {
22
+ 'infra/performance-cost-controls.ts': `import {
23
+ createFoundationAccountCostControlPlan,
24
+ createPerformanceCostControlPlan,
25
+ requireExactFoundationAccountCostAuthority,
26
+ } from '@empire-builder-kit/nx/performance';
27
+ import accountCostPolicy from '../../foundation/performance/account-cost-policy.json';
28
+ import performancePolicy from '../performance/policy.json';
29
+
30
+ function budgetNotifications(
31
+ notifications: readonly {
32
+ comparisonOperator: 'GREATER_THAN';
33
+ notificationType: 'ACTUAL' | 'FORECASTED';
34
+ threshold: number;
35
+ thresholdType: 'PERCENTAGE';
36
+ }[],
37
+ alertTopicArn: any,
38
+ ) {
39
+ return notifications.map((notification) => ({
40
+ ...notification,
41
+ subscriberSnsTopicArns: [alertTopicArn],
42
+ }));
43
+ }
44
+
45
+ export function create${pascalName}PerformanceCostControls(input: {
46
+ accountCostPolicyDigest: any;
47
+ accountMonthlyMaximumUsd: any;
48
+ alertTopicArn: any;
49
+ evaluatedAt?: string;
50
+ workspace: string;
51
+ }) {
52
+ const evaluatedAt = input.evaluatedAt ?? new Date().toISOString();
53
+ const foundationAccountCostControl = createFoundationAccountCostControlPlan({
54
+ evaluatedAt,
55
+ policy: accountCostPolicy,
56
+ region: process.env.AWS_REGION,
57
+ stage: $app.stage,
58
+ workspace: input.workspace,
59
+ });
60
+ const plan = createPerformanceCostControlPlan({
61
+ accountBudgetAuthority: foundationAccountCostControl.authority,
62
+ evaluatedAt,
63
+ policy: performancePolicy,
64
+ region: process.env.AWS_REGION,
65
+ stage: $app.stage,
66
+ workspace: input.workspace,
67
+ });
68
+ if (plan.status === 'disabled-non-protected-stage') {
69
+ return {
70
+ accountBudgetAuthority: plan.accountBudgetAuthority,
71
+ anomalyMonitor: undefined,
72
+ anomalySubscription: undefined,
73
+ materialDigest: plan.materialDigest,
74
+ pilotBudget: undefined,
75
+ policyDigest: plan.policyDigest,
76
+ };
77
+ }
78
+ const deployedAccountBudgetAuthority = input.accountCostPolicyDigest.apply(
79
+ (policyDigest: string) =>
80
+ input.accountMonthlyMaximumUsd.apply((monthlyMaximumUsd: number) =>
81
+ requireExactFoundationAccountCostAuthority({
82
+ actual: {
83
+ kind: 'ebk-foundation-account-cost-authority',
84
+ monthlyMaximumUsd,
85
+ policyDigest,
86
+ stage: $app.stage,
87
+ workspace: input.workspace,
88
+ },
89
+ expected: plan.accountBudgetAuthority,
90
+ }),
91
+ ),
92
+ );
93
+ const tags = {
94
+ 'ebk:account-cost-policy-digest': deployedAccountBudgetAuthority.apply(
95
+ (authority: { policyDigest: string }) => authority.policyDigest,
96
+ ),
97
+ 'ebk:cost-control-material-digest': deployedAccountBudgetAuthority.apply(
98
+ () => plan.materialDigest,
99
+ ),
100
+ 'ebk:cost-scope':
101
+ plan.workspace + '/' + plan.slice + '/' + plan.stage,
102
+ 'ebk:cost-policy-digest': plan.policyDigest,
103
+ 'ebk:cost-route': plan.route.semanticRef,
104
+ 'ebk:owner': plan.owner,
105
+ };
106
+ const pilotBudget = plan.pilotBudget
107
+ ? new aws.budgets.Budget('${pascalName}PilotCostBudget', {
108
+ budgetType: plan.pilotBudget.budgetType,
109
+ filterExpression: plan.pilotBudget.filterExpression,
110
+ limitAmount: plan.pilotBudget.limitAmount,
111
+ limitUnit: plan.pilotBudget.limitUnit,
112
+ metrics: 'UnblendedCost',
113
+ name: plan.pilotBudget.name,
114
+ notifications: budgetNotifications(
115
+ plan.pilotBudget.notifications,
116
+ input.alertTopicArn,
117
+ ),
118
+ tags,
119
+ timeUnit: plan.pilotBudget.timeUnit,
120
+ })
121
+ : undefined;
122
+ const anomalyMonitor = plan.anomaly
123
+ ? new aws.costexplorer.AnomalyMonitor(
124
+ '${pascalName}CostAnomalyMonitor',
125
+ {
126
+ monitorSpecification: plan.anomaly.monitor.monitorSpecification,
127
+ monitorType: plan.anomaly.monitor.monitorType,
128
+ name: plan.anomaly.monitor.name,
129
+ tags,
130
+ },
131
+ )
132
+ : undefined;
133
+ const anomalySubscription =
134
+ plan.anomaly && anomalyMonitor
135
+ ? new aws.costexplorer.AnomalySubscription(
136
+ '${pascalName}CostAnomalySubscription',
137
+ {
138
+ frequency: plan.anomaly.subscription.frequency,
139
+ monitorArnLists: [anomalyMonitor.arn],
140
+ name: plan.anomaly.subscription.name,
141
+ subscribers: [
142
+ { address: input.alertTopicArn, type: 'SNS' },
143
+ ],
144
+ tags,
145
+ thresholdExpression:
146
+ plan.anomaly.subscription.thresholdExpression,
147
+ },
148
+ { dependsOn: [anomalyMonitor] },
149
+ )
150
+ : undefined;
151
+ return {
152
+ accountBudgetAuthority: deployedAccountBudgetAuthority,
153
+ anomalyMonitor,
154
+ anomalySubscription,
155
+ materialDigest: plan.materialDigest,
156
+ pilotBudget,
157
+ policyDigest: plan.policyDigest,
158
+ };
159
+ }
160
+ `,
161
+ 'performance/policy.json': (0, built_in_plan_shared_js_1.json)({
162
+ $schema: '../../../node_modules/@empire-builder-kit/nx/schemas/performance-policy-v1.json',
163
+ authority: {
164
+ journeyAuthorityPath: 'docs/reliability/slo.json',
165
+ operationsAuthorityPath: 'operations/reliability.json',
166
+ releaseManifestPath: 'operations/release.json',
167
+ repositoryPolicyPath: '../../ebk.repository-policy.json',
168
+ },
169
+ budgets: [
170
+ {
171
+ comparator: 'maximum',
172
+ evidenceProvenance: ['test', 'actual'],
173
+ id: 'api-warm-p95',
174
+ journeyRef: 'journey:replace-with-api-journey',
175
+ metric: 'latency-milliseconds',
176
+ percentile: 95,
177
+ population: 'warm',
178
+ scenarioRef: 'scenario:api-peak',
179
+ status: 'example',
180
+ threshold: 750,
181
+ unit: 'milliseconds',
182
+ },
183
+ {
184
+ comparator: 'maximum',
185
+ evidenceProvenance: ['test', 'actual'],
186
+ id: 'async-backlog-p99',
187
+ journeyRef: 'journey:replace-with-async-journey',
188
+ metric: 'backlog-age-seconds',
189
+ percentile: 99,
190
+ population: 'all',
191
+ scenarioRef: 'scenario:async-burst',
192
+ status: 'example',
193
+ threshold: 300,
194
+ unit: 'seconds',
195
+ },
196
+ {
197
+ comparator: 'maximum',
198
+ evidenceProvenance: ['test', 'actual'],
199
+ id: 'database-cold-resume-p95',
200
+ journeyRef: 'journey:replace-with-database-journey',
201
+ metric: 'cold-resume-milliseconds',
202
+ percentile: 95,
203
+ population: 'cold',
204
+ scenarioRef: 'scenario:database-cold-resume',
205
+ status: 'example',
206
+ threshold: 15_000,
207
+ unit: 'milliseconds',
208
+ },
209
+ {
210
+ comparator: 'maximum',
211
+ evidenceProvenance: ['estimate', 'actual'],
212
+ id: 'monthly-cost',
213
+ journeyRef: 'journey:replace-with-business-outcome',
214
+ metric: 'monthly-cost-usd',
215
+ population: 'all',
216
+ scenarioRef: 'scenario:normal-month',
217
+ status: 'example',
218
+ threshold: 1_000,
219
+ unit: 'usd',
220
+ },
221
+ ],
222
+ capacity: [
223
+ {
224
+ capacityUnit: 'requests-per-second',
225
+ configuredMaximum: null,
226
+ downstreamMaximum: null,
227
+ failureMode: 'api-throttles-or-overloads-database',
228
+ id: 'api-lambda',
229
+ kind: 'api-lambda',
230
+ protectionRef: 'control:api-lambda-concurrency',
231
+ quotaMaximum: null,
232
+ saturationSignalRef: 'runtime:nodejs-heap-utilization-percent',
233
+ status: 'requires-adopter-value',
234
+ },
235
+ {
236
+ capacityUnit: 'messages-per-second',
237
+ configuredMaximum: null,
238
+ downstreamMaximum: null,
239
+ failureMode: 'backlog-age-grows-or-provider-throttles',
240
+ id: 'async-worker',
241
+ kind: 'async-worker',
242
+ protectionRef: 'control:async-worker-concurrency',
243
+ quotaMaximum: null,
244
+ saturationSignalRef: 'database:protected-async-backlog-utilization-percent',
245
+ status: 'requires-adopter-value',
246
+ },
247
+ {
248
+ capacityUnit: 'database-connections',
249
+ configuredMaximum: null,
250
+ downstreamMaximum: null,
251
+ failureMode: 'connection-or-capacity-exhaustion',
252
+ id: 'database',
253
+ kind: 'database',
254
+ protectionRef: 'control:database-connections',
255
+ quotaMaximum: null,
256
+ saturationSignalRef: 'database:connection-utilization-percent',
257
+ status: 'requires-adopter-value',
258
+ },
259
+ {
260
+ capacityUnit: 'concurrent-requests',
261
+ configuredMaximum: null,
262
+ downstreamMaximum: null,
263
+ failureMode: 'service-saturates-or-overloads-dependency',
264
+ id: 'service-extension',
265
+ kind: 'service',
266
+ protectionRef: 'control:service-extension-concurrency',
267
+ quotaMaximum: null,
268
+ saturationSignalRef: 'adopter:service-saturation-percent',
269
+ status: 'requires-adopter-value',
270
+ },
271
+ ],
272
+ cost: {
273
+ accountMonthlyMaximumUsd: 1_000,
274
+ actualNotificationThresholdPercent: 80,
275
+ anomalyRouteRef: 'alarm:cost-anomaly',
276
+ anomalyThresholdUsd: 50,
277
+ forecastNotificationThresholdPercent: 100,
278
+ notificationRoute: 'foundation-alert-topic',
279
+ pilotMonthlyMaximumUsd: 250,
280
+ sharedCostAllocationRef: 'performance/cost-allocation.json',
281
+ status: 'example',
282
+ testRunMaximumUsd: 25,
283
+ unitCostRefs: ['completed-business-journey', 'delivered-async-work'],
284
+ },
285
+ evidence: {
286
+ maximumAgeDays: { actual: 45, estimate: 30, test: 14 },
287
+ protectedEvidenceRequiresExactRelease: true,
288
+ },
289
+ kind: 'ebk-performance-policy',
290
+ load: {
291
+ allowedProtectedStages: ['staging'],
292
+ maximumConcurrency: 100,
293
+ maximumDurationSeconds: 1_800,
294
+ maximumEstimatedCostUsd: 25,
295
+ maximumRatePerSecond: 200,
296
+ maximumRequests: 100_000,
297
+ productionExceptionalOnly: true,
298
+ },
299
+ owner: 'REPLACE_WITH_OWNER',
300
+ reviewAt: null,
301
+ schemaVersion: 1,
302
+ slice: name,
303
+ tags: {
304
+ forbiddenKeys: ['ebk:feature'],
305
+ requiredKeys: [
306
+ 'ebk:cost-allocation',
307
+ 'ebk:cost-scope',
308
+ 'ebk:framework-version',
309
+ 'ebk:managed-by',
310
+ 'ebk:owner',
311
+ 'ebk:production-profile',
312
+ 'ebk:repository',
313
+ 'ebk:slice',
314
+ 'ebk:stage',
315
+ 'ebk:workspace',
316
+ ],
317
+ unsupportedResourcePolicy: 'report-with-reason-and-allocation',
318
+ },
319
+ }),
320
+ 'performance/load-scenarios.json': (0, built_in_plan_shared_js_1.json)({
321
+ kind: 'ebk-protected-load-scenario-catalog',
322
+ scenarios: [
323
+ {
324
+ adapterStatus: 'managed',
325
+ adapterId: 'ebk-api-lambda-v1',
326
+ demandShape: 'normal-to-peak-ramp',
327
+ disabledUntilAdopted: true,
328
+ estimatedCostUsdPerRequest: 0.00001,
329
+ id: 'api-peak',
330
+ saturationSignalRef: 'runtime:nodejs-heap-utilization-percent',
331
+ workload: 'api-lambda',
332
+ },
333
+ {
334
+ adapterStatus: 'managed',
335
+ adapterId: 'ebk-async-worker-v1',
336
+ demandShape: 'bounded-flash-burst-and-recovery',
337
+ disabledUntilAdopted: true,
338
+ estimatedCostUsdPerRequest: 0.00002,
339
+ id: 'async-burst',
340
+ saturationSignalRef: 'database:protected-async-backlog-utilization-percent',
341
+ workload: 'async-worker',
342
+ },
343
+ {
344
+ adapterStatus: 'managed',
345
+ adapterId: 'ebk-database-v1',
346
+ demandShape: 'idle-window-then-first-request',
347
+ disabledUntilAdopted: true,
348
+ estimatedCostUsdPerRequest: 0.0001,
349
+ id: 'database-cold-resume',
350
+ saturationSignalRef: 'database:connection-utilization-percent',
351
+ workload: 'database',
352
+ },
353
+ {
354
+ adapterStatus: 'requires-adopter-service-endpoint',
355
+ adapterId: 'ebk-service-v1',
356
+ demandShape: 'bounded-steady-and-saturation-ramp',
357
+ disabledUntilAdopted: true,
358
+ estimatedCostUsdPerRequest: 0.00002,
359
+ id: 'service-extension',
360
+ saturationSignalRef: 'adopter:service-saturation-percent',
361
+ workload: 'service',
362
+ },
363
+ ],
364
+ schemaVersion: 1,
365
+ slice: name,
366
+ }),
367
+ 'performance/cost-allocation.json': (0, built_in_plan_shared_js_1.json)({
368
+ allocations: [
369
+ {
370
+ capabilityId: 'completed-business-journey',
371
+ driver: 'replace-with-reviewed-resource-allocation',
372
+ id: 'completed-business-journey',
373
+ status: 'requires-adopter-value',
374
+ },
375
+ {
376
+ capabilityId: 'delivered-async-work',
377
+ driver: 'replace-with-reviewed-resource-allocation',
378
+ id: 'delivered-async-work',
379
+ status: 'requires-adopter-value',
380
+ },
381
+ ],
382
+ actualCostProvider: 'aws-billing-actual',
383
+ forecastProviders: ['infrastructure-plan', 'aws-price-estimate'],
384
+ kind: 'ebk-cost-allocation-contract',
385
+ provenanceLabels: ['estimate', 'test', 'actual'],
386
+ resourceTagKey: 'ebk:cost-allocation',
387
+ schemaVersion: 1,
388
+ sharedCostsRemainExplicit: true,
389
+ slice: name,
390
+ unitCosts: [
391
+ {
392
+ aggregateCountRef: 'operations:completed-business-journey',
393
+ anomalyIncreasePercent: 20,
394
+ id: 'completed-business-journey',
395
+ ownerRouteRef: 'alarm:cost-anomaly',
396
+ status: 'requires-adopter-value',
397
+ unit: 'completed-business-journey',
398
+ },
399
+ {
400
+ aggregateCountRef: 'operations:delivered-async-work',
401
+ anomalyIncreasePercent: 20,
402
+ id: 'delivered-async-work',
403
+ ownerRouteRef: 'alarm:cost-anomaly',
404
+ status: 'requires-adopter-value',
405
+ unit: 'delivered-async-work',
406
+ },
407
+ ],
408
+ }),
409
+ 'performance/cost-collection.json': (0, built_in_plan_shared_js_1.json)((0, index_js_1.createExternalCostCollectionContract)({
410
+ outputPath: '.ebk/evidence/performance-cost-actual.json',
411
+ owner: `${name}-product`,
412
+ slice: name,
413
+ })),
414
+ 'operations/performance.json': (0, built_in_plan_shared_js_1.json)({
415
+ authorityHooks: {
416
+ alarmAndRouting: 'operations/reliability.json',
417
+ journeyAndSlo: 'docs/reliability/slo.json',
418
+ release: 'operations/release.json',
419
+ repositoryProfile: '../../ebk.repository-policy.json',
420
+ },
421
+ costCollection: {
422
+ contract: 'performance/cost-collection.json',
423
+ liveCollectorOwnerRequired: true,
424
+ operationsConsoleRequired: false,
425
+ },
426
+ costControls: {
427
+ accountBudgetAuthority: 'packages/foundation/performance/account-cost-policy.json',
428
+ accountBudgetBinding: 'foundation-discovery-schema-v6-policy-digest-and-amount',
429
+ accountBudgetInfrastructure: 'packages/foundation/infra/foundation.ts',
430
+ accountBudgetOwner: 'foundation',
431
+ accountBudgetStages: ['staging', 'production'],
432
+ anomalyMonitorScope: 'workspace-slice-stage-composite-tag',
433
+ anomalySubscriptionFrequency: 'IMMEDIATE',
434
+ automaticSpendActions: 'forbidden',
435
+ infrastructure: 'infra/performance-cost-controls.ts',
436
+ owner: 'performance/policy.json#owner',
437
+ pilotBudgetOwner: 'product-slice',
438
+ pilotBudgetStage: 'staging',
439
+ policy: 'performance/policy.json#cost',
440
+ route: 'foundation-alert-topic',
441
+ status: 'blocked-until-cost-policy-adopted',
442
+ },
443
+ unitCost: {
444
+ capabilities: ['completed-business-journey', 'delivered-async-work'],
445
+ evaluator: 'scripts/performance-unit-cost.mjs',
446
+ liveBillingAndAggregateEvidenceRequired: true,
447
+ operationsConsoleRequired: false,
448
+ status: 'incomplete-until-live-evidence',
449
+ },
450
+ evidence: {
451
+ exactReleaseRequiredForProtectedResults: true,
452
+ provenanceLabels: ['estimate', 'test', 'actual'],
453
+ stagingIsNotProduction: true,
454
+ },
455
+ liveEvidence: {
456
+ accountBudgetAndAnomalyRoute: 'required-pre-v1',
457
+ actualBillingAndTwoUnitCosts: 'required-pre-v1',
458
+ coldAndWarmLambdaNextPaths: 'required-pre-v1',
459
+ databaseColdResumeAndIdleCost: 'required-pre-v1',
460
+ profileTransitionRehearsal: 'required-pre-v1',
461
+ protectedApiAsyncDatabaseLoad: 'required-pre-v1',
462
+ serviceRuntimeLoad: 'required-pre-v1-adopter-integration',
463
+ status: 'incomplete',
464
+ },
465
+ load: {
466
+ allowlistedScenarioAdapters: [
467
+ 'ebk-api-lambda-v1',
468
+ 'ebk-async-worker-v1',
469
+ 'ebk-database-v1',
470
+ ],
471
+ localProtectedMutationForbidden: true,
472
+ productionExceptionalOnly: true,
473
+ protectedGuard: 'scripts/performance-load-guard.mjs',
474
+ protectedRunner: '.github/workflows/performance-load.yml',
475
+ runnerStatus: 'managed-fixed-scenario-v1',
476
+ serviceAdapterOwner: null,
477
+ serviceAdapterStatus: 'requires-adopter-service-runtime-endpoint',
478
+ },
479
+ metricDimensions: [
480
+ 'Stage',
481
+ 'Slice',
482
+ 'Feature',
483
+ 'Component',
484
+ 'Operation',
485
+ 'Outcome',
486
+ ],
487
+ prohibitedMetricDimensions: [
488
+ 'release',
489
+ 'user',
490
+ 'tenant',
491
+ 'request',
492
+ 'work-item',
493
+ 'payload',
494
+ 'raw-error',
495
+ ],
496
+ schemaVersion: 1,
497
+ slice: name,
498
+ workloads: [
499
+ 'api-lambda',
500
+ 'async-worker',
501
+ 'browser',
502
+ 'database',
503
+ 'job',
504
+ 'service',
505
+ ],
506
+ }),
507
+ 'scripts/performance-policy-check.mjs': `import { existsSync, readFileSync } from 'node:fs';
508
+ import {
509
+ assessPerformancePolicyReadiness,
510
+ evaluateCapacitySafety,
511
+ unitCostLiveEvidenceStatus,
512
+ validatePerformancePolicy,
513
+ verifyPerformanceOperationalHooks,
514
+ } from '@empire-builder-kit/nx/performance';
515
+
516
+ const policy = validatePerformancePolicy(
517
+ JSON.parse(
518
+ readFileSync(
519
+ new URL('../performance/policy.json', import.meta.url),
520
+ 'utf8',
521
+ ),
522
+ ),
523
+ );
524
+ const requireReady = process.argv.includes('--require-ready');
525
+ const readAuthority = (authorityPath) => {
526
+ const [path] = authorityPath.split('#', 1);
527
+ const url = new URL('../' + path, import.meta.url);
528
+ return existsSync(url) ? JSON.parse(readFileSync(url, 'utf8')) : undefined;
529
+ };
530
+ for (const path of Object.values(policy.authority)) {
531
+ if (!readAuthority(path)) {
532
+ throw new Error('Performance authority is missing: ' + path);
533
+ }
534
+ }
535
+ if (requireReady) {
536
+ await verifyPerformanceOperationalHooks(
537
+ policy,
538
+ (kind, authorityPath, semanticRef) => {
539
+ const authority = readAuthority(authorityPath);
540
+ if (!authority) return false;
541
+ if (kind === 'journey') {
542
+ return (
543
+ typeof semanticRef === 'string' &&
544
+ Array.isArray(authority.objectives) &&
545
+ authority.objectives.some(
546
+ (objective) => 'journey:' + objective?.journey === semanticRef,
547
+ )
548
+ );
549
+ }
550
+ if (kind === 'alarm') {
551
+ return (
552
+ typeof semanticRef === 'string' &&
553
+ authority.performanceReferences?.alarms?.includes(semanticRef)
554
+ );
555
+ }
556
+ if (kind === 'capacity-control') {
557
+ return (
558
+ typeof semanticRef === 'string' &&
559
+ authority.performanceReferences?.capacityControls?.includes(
560
+ semanticRef,
561
+ )
562
+ );
563
+ }
564
+ if (kind === 'capacity-signal') {
565
+ return (
566
+ typeof semanticRef === 'string' &&
567
+ authority.performanceReferences?.capacitySignals?.includes(
568
+ semanticRef,
569
+ )
570
+ );
571
+ }
572
+ return true;
573
+ },
574
+ );
575
+ }
576
+ const readiness = assessPerformancePolicyReadiness(policy);
577
+ const capacity = evaluateCapacitySafety(policy.capacity);
578
+ const result = {
579
+ capacity,
580
+ readiness,
581
+ schemaVersion: 1,
582
+ slice: policy.slice,
583
+ unitCost: unitCostLiveEvidenceStatus(policy),
584
+ };
585
+ process.stdout.write(JSON.stringify(result) + '\\n');
586
+ if (
587
+ requireReady &&
588
+ (!readiness.ready || capacity.status !== 'safe')
589
+ ) process.exitCode = 2;
590
+ `,
591
+ 'scripts/performance-budget-check.mjs': `import { chmodSync, mkdirSync, writeFileSync } from 'node:fs';
592
+ import { fileURLToPath } from 'node:url';
593
+ import {
594
+ collectManagedPrArtifactBudget,
595
+ } from '@empire-builder-kit/nx/performance';
596
+
597
+ const result = collectManagedPrArtifactBudget({
598
+ slice: '${name}',
599
+ sliceRoot: fileURLToPath(new URL('../', import.meta.url)),
600
+ });
601
+ const evidenceDirectory = new URL('../.ebk/evidence/', import.meta.url);
602
+ mkdirSync(evidenceDirectory, { recursive: true, mode: 0o700 });
603
+ chmodSync(evidenceDirectory, 0o700);
604
+ const evidencePath = new URL(
605
+ 'performance-budget.json',
606
+ evidenceDirectory,
607
+ );
608
+ writeFileSync(evidencePath, JSON.stringify(result, null, 2) + '\\n', {
609
+ encoding: 'utf8',
610
+ mode: 0o600,
611
+ });
612
+ chmodSync(evidencePath, 0o600);
613
+ process.stdout.write(JSON.stringify(result) + '\\n');
614
+ if (result.outcome !== 'passed') process.exitCode = 2;
615
+ `,
616
+ 'scripts/performance-evidence-evaluate.mjs': `import { chmodSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
617
+ import {
618
+ evaluatePerformanceBudgets,
619
+ validatePerformancePolicy,
620
+ } from '@empire-builder-kit/nx/performance';
621
+
622
+ const observationsPath = process.env.EBK_PERFORMANCE_OBSERVATIONS_PATH?.trim();
623
+ const releasePath = process.env.EBK_RELEASE_BINDING_PATH?.trim();
624
+ const now = process.env.EBK_EVIDENCE_NOW?.trim();
625
+ if (!observationsPath || !releasePath || !now) {
626
+ throw new Error(
627
+ 'Adopted performance evidence requires exact observation, release-binding, and evidence-time paths.',
628
+ );
629
+ }
630
+ const policy = validatePerformancePolicy(
631
+ JSON.parse(
632
+ readFileSync(
633
+ new URL('../performance/policy.json', import.meta.url),
634
+ 'utf8',
635
+ ),
636
+ ),
637
+ );
638
+ const result = evaluatePerformanceBudgets({
639
+ expectedRelease: JSON.parse(readFileSync(releasePath, 'utf8')),
640
+ now,
641
+ observations: JSON.parse(readFileSync(observationsPath, 'utf8')),
642
+ policy,
643
+ });
644
+ const evidenceDirectory = new URL('../.ebk/evidence/', import.meta.url);
645
+ mkdirSync(evidenceDirectory, { recursive: true, mode: 0o700 });
646
+ chmodSync(evidenceDirectory, 0o700);
647
+ const evidencePath = new URL(
648
+ 'performance-adopted-budget.json',
649
+ evidenceDirectory,
650
+ );
651
+ writeFileSync(evidencePath, JSON.stringify(result, null, 2) + '\\n', {
652
+ encoding: 'utf8',
653
+ mode: 0o600,
654
+ });
655
+ chmodSync(evidencePath, 0o600);
656
+ process.stdout.write(JSON.stringify(result) + '\\n');
657
+ if (result.outcome !== 'passed') process.exitCode = 2;
658
+ `,
659
+ 'scripts/performance-unit-cost.mjs': `import { chmodSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
660
+ import {
661
+ evaluateUnitCostTrends,
662
+ validateAwsBillingActualEvidence,
663
+ validateCostAllocationContract,
664
+ validatePerformancePolicy,
665
+ } from '@empire-builder-kit/nx/performance';
666
+
667
+ const baselinePath = process.env.EBK_UNIT_COST_BASELINE_PATH?.trim();
668
+ const baselineBillingPath =
669
+ process.env.EBK_BASELINE_BILLING_EVIDENCE_PATH?.trim();
670
+ const expectedBaselineBillingDigest =
671
+ process.env.EBK_EXPECTED_BASELINE_BILLING_EVIDENCE_DIGEST?.trim();
672
+ const baselineReleasePath =
673
+ process.env.EBK_BASELINE_RELEASE_BINDING_PATH?.trim();
674
+ const billingPath = process.env.EBK_BILLING_OBSERVATION_PATH?.trim();
675
+ const expectedBillingDigest =
676
+ process.env.EBK_EXPECTED_BILLING_EVIDENCE_DIGEST?.trim();
677
+ const currentPath = process.env.EBK_UNIT_COST_CURRENT_PATH?.trim();
678
+ const releasePath = process.env.EBK_RELEASE_BINDING_PATH?.trim();
679
+ const evaluatedAt = process.env.EBK_EVIDENCE_NOW?.trim();
680
+ if (
681
+ !baselinePath ||
682
+ !baselineBillingPath ||
683
+ !expectedBaselineBillingDigest ||
684
+ !baselineReleasePath ||
685
+ !billingPath ||
686
+ !expectedBillingDigest ||
687
+ !currentPath ||
688
+ !releasePath ||
689
+ !evaluatedAt
690
+ ) {
691
+ throw new Error(
692
+ 'Unit-cost evaluation requires independently expected baseline/current billing digests, exact observations, release bindings, and evidence time.',
693
+ );
694
+ }
695
+ const allocation = validateCostAllocationContract(
696
+ JSON.parse(
697
+ readFileSync(
698
+ new URL('../performance/cost-allocation.json', import.meta.url),
699
+ 'utf8',
700
+ ),
701
+ ),
702
+ { requireAdopted: true },
703
+ );
704
+ const capabilities = allocation.unitCosts.map(
705
+ ({ anomalyIncreasePercent, id, ownerRouteRef, unit }) => ({
706
+ anomalyIncreasePercent,
707
+ id,
708
+ ownerRouteRef,
709
+ unit,
710
+ }),
711
+ );
712
+ const baselineBilling = validateAwsBillingActualEvidence(
713
+ JSON.parse(readFileSync(baselineBillingPath, 'utf8')),
714
+ );
715
+ const billing = validateAwsBillingActualEvidence(
716
+ JSON.parse(readFileSync(billingPath, 'utf8')),
717
+ );
718
+ const policy = validatePerformancePolicy(
719
+ JSON.parse(
720
+ readFileSync(
721
+ new URL('../performance/policy.json', import.meta.url),
722
+ 'utf8',
723
+ ),
724
+ ),
725
+ );
726
+ const result = evaluateUnitCostTrends({
727
+ baseline: JSON.parse(readFileSync(baselinePath, 'utf8')),
728
+ baselineBillingEvidence: baselineBilling,
729
+ capabilities,
730
+ current: JSON.parse(readFileSync(currentPath, 'utf8')),
731
+ currentBillingEvidence: billing,
732
+ evaluatedAt,
733
+ expectedBaselineBillingEvidenceDigest: expectedBaselineBillingDigest,
734
+ expectedBaselineRelease: JSON.parse(
735
+ readFileSync(baselineReleasePath, 'utf8'),
736
+ ),
737
+ expectedCurrentBillingEvidenceDigest: expectedBillingDigest,
738
+ expectedCurrentRelease: JSON.parse(readFileSync(releasePath, 'utf8')),
739
+ policy,
740
+ });
741
+ const evidenceDirectory = new URL('../.ebk/evidence/', import.meta.url);
742
+ mkdirSync(evidenceDirectory, { recursive: true, mode: 0o700 });
743
+ chmodSync(evidenceDirectory, 0o700);
744
+ const evidencePath = new URL('performance-unit-cost.json', evidenceDirectory);
745
+ writeFileSync(evidencePath, JSON.stringify(result, null, 2) + '\\n', {
746
+ encoding: 'utf8',
747
+ mode: 0o600,
748
+ });
749
+ chmodSync(evidencePath, 0o600);
750
+ process.stdout.write(JSON.stringify(result) + '\\n');
751
+ `,
752
+ 'performance/aggregate-count-provider.ts': `export interface ProtectedAggregateCountRequest {
753
+ authority: Readonly<{
754
+ mode: 'dedicated-oidc-read-role';
755
+ permissionContract: 'adopter-owned-least-privilege-read-v1';
756
+ }>;
757
+ capabilities: readonly string[];
758
+ environment: Readonly<{
759
+ accountFingerprint: string;
760
+ region: string;
761
+ slice: string;
762
+ stage: 'production' | 'staging';
763
+ workspace: string;
764
+ }>;
765
+ period: Readonly<{ end: string; start: string }>;
766
+ release: Readonly<{
767
+ candidateDigest: string;
768
+ releaseId: string;
769
+ releaseMaterialDigest: string;
770
+ sourceCommit: string;
771
+ }>;
772
+ }
773
+
774
+ export interface ProtectedAggregateCountResult {
775
+ counts: readonly Readonly<{
776
+ aggregateId: string;
777
+ capabilityId: string;
778
+ count: number;
779
+ sourceRef: string;
780
+ }>[];
781
+ requestId: string;
782
+ }
783
+
784
+ export async function collectAggregateCounts(
785
+ request: ProtectedAggregateCountRequest,
786
+ ): Promise<ProtectedAggregateCountResult> {
787
+ void request;
788
+ throw new Error(
789
+ 'Adopt performance/aggregate-count-provider.ts before protected aggregate collection.',
790
+ );
791
+ }
792
+ `,
793
+ 'scripts/performance-aggregate-counts.mjs': `import {
794
+ chmodSync,
795
+ existsSync,
796
+ lstatSync,
797
+ mkdirSync,
798
+ readFileSync,
799
+ readdirSync,
800
+ realpathSync,
801
+ writeFileSync,
802
+ } from 'node:fs';
803
+ import { isAbsolute, relative, resolve, sep } from 'node:path';
804
+ import { fileURLToPath } from 'node:url';
805
+ import {
806
+ awsAccountFingerprint,
807
+ createAggregateCountEvidence,
808
+ validateAggregateCountEvidence,
809
+ validateCostAllocationContract,
810
+ } from '@empire-builder-kit/nx/performance';
811
+ import { isBoundedSafeReference } from '@empire-builder-kit/runtime/safe-reference';
812
+ import { collectAggregateCounts } from '../performance/aggregate-count-provider.ts';
813
+
814
+ const sliceRoot = fileURLToPath(new URL('../', import.meta.url));
815
+ const workspaceRoot = resolve(sliceRoot, '../..');
816
+ const required = (name) => {
817
+ const value = process.env[name]?.trim();
818
+ if (!value) throw new Error(name + ' is required.');
819
+ return value;
820
+ };
821
+ const authorityOnly =
822
+ process.argv.length === 3 && process.argv[2] === '--validate-authority';
823
+ if (process.argv.length > (authorityOnly ? 3 : 2)) {
824
+ throw new Error('Aggregate-count wrapper received unsupported arguments.');
825
+ }
826
+ const exactKeys = (value, keys, label) => {
827
+ if (
828
+ !value ||
829
+ typeof value !== 'object' ||
830
+ Array.isArray(value) ||
831
+ Object.keys(value).sort().join(',') !== [...keys].sort().join(',')
832
+ ) {
833
+ throw new Error(label + ' contains unsupported fields.');
834
+ }
835
+ return value;
836
+ };
837
+ const readBoundedJson = (path, label) => {
838
+ const metadata = lstatSync(path);
839
+ if (
840
+ !metadata.isFile() ||
841
+ metadata.isSymbolicLink() ||
842
+ metadata.size < 2 ||
843
+ metadata.size > 1024 * 1024
844
+ ) {
845
+ throw new Error(label + ' must be one bounded regular file.');
846
+ }
847
+ return JSON.parse(readFileSync(path, 'utf8'));
848
+ };
849
+ const releaseArtifactRoot = resolve(
850
+ sliceRoot,
851
+ '.ebk/performance-aggregate-input/release-artifact',
852
+ );
853
+ const artifactRootMetadata = lstatSync(releaseArtifactRoot);
854
+ const artifactRootRelative = relative(
855
+ sliceRoot,
856
+ realpathSync(releaseArtifactRoot),
857
+ );
858
+ if (
859
+ !artifactRootMetadata.isDirectory() ||
860
+ artifactRootMetadata.isSymbolicLink() ||
861
+ artifactRootRelative === '..' ||
862
+ artifactRootRelative.startsWith('..' + sep) ||
863
+ isAbsolute(artifactRootRelative)
864
+ ) {
865
+ throw new Error('Release artifact root is unsafe.');
866
+ }
867
+ const releaseFiles = [];
868
+ let releaseBytes = 0;
869
+ const visit = (directory) => {
870
+ if (releaseFiles.length > 4096 || releaseBytes > 64 * 1024 * 1024) {
871
+ throw new Error('Release artifact exceeds its traversal bound.');
872
+ }
873
+ for (const name of readdirSync(directory).sort()) {
874
+ const path = resolve(directory, name);
875
+ const metadata = lstatSync(path);
876
+ if (metadata.isSymbolicLink()) {
877
+ throw new Error('Release artifact contains a symbolic link.');
878
+ }
879
+ if (metadata.isDirectory()) visit(path);
880
+ else if (metadata.isFile()) {
881
+ releaseBytes += metadata.size;
882
+ releaseFiles.push(path);
883
+ if (
884
+ releaseFiles.length > 4096 ||
885
+ releaseBytes > 64 * 1024 * 1024
886
+ ) {
887
+ throw new Error('Release artifact exceeds its traversal bound.');
888
+ }
889
+ } else {
890
+ throw new Error('Release artifact contains a special file.');
891
+ }
892
+ }
893
+ };
894
+ visit(releaseArtifactRoot);
895
+ const bindingSuffix =
896
+ '/packages/${name}/.ebk/evidence/active-protected-release.json';
897
+ const bindingMatches = releaseFiles.filter((path) =>
898
+ ('/' + relative(releaseArtifactRoot, path).replaceAll('\\\\', '/')).endsWith(
899
+ bindingSuffix,
900
+ ),
901
+ );
902
+ if (bindingMatches.length !== 1) {
903
+ throw new Error(
904
+ 'Release artifact lacks one exact ${name} active protected release binding.',
905
+ );
906
+ }
907
+ const source = exactKeys(
908
+ readBoundedJson(bindingMatches[0], 'Active protected release binding'),
909
+ [
910
+ 'candidateDigest',
911
+ 'deploymentCommit',
912
+ 'kind',
913
+ 'manifestDigest',
914
+ 'releaseId',
915
+ 'releaseMaterialDigest',
916
+ 'releaseSourceCommit',
917
+ 'runAttempt',
918
+ 'runId',
919
+ 'schemaVersion',
920
+ 'stage',
921
+ 'workflow',
922
+ ],
923
+ 'Active protected release binding',
924
+ );
925
+ const digestPattern = /^[a-f0-9]{64}$/;
926
+ const commitPattern = /^(?:[a-f0-9]{40}|[a-f0-9]{64})$/;
927
+ const stage = required('EBK_STAGE');
928
+ const sourceCommit = required('EBK_SOURCE_COMMIT');
929
+ if (
930
+ source.kind !== 'ebk-active-protected-release-binding' ||
931
+ source.schemaVersion !== 1 ||
932
+ source.stage !== stage ||
933
+ source.workflow !== 'Deploy' ||
934
+ String(source.runId) !== required('EBK_RELEASE_ARTIFACT_RUN_ID') ||
935
+ String(source.runAttempt) !== required('EBK_RELEASE_RUN_ATTEMPT') ||
936
+ source.deploymentCommit !== sourceCommit ||
937
+ !commitPattern.test(source.deploymentCommit ?? '') ||
938
+ !digestPattern.test(source.candidateDigest ?? '') ||
939
+ !digestPattern.test(source.manifestDigest ?? '') ||
940
+ !digestPattern.test(source.releaseMaterialDigest ?? '') ||
941
+ !commitPattern.test(source.releaseSourceCommit ?? '') ||
942
+ !isBoundedSafeReference(source.releaseId, 'performance-evidence')
943
+ ) {
944
+ throw new Error(
945
+ 'Active protected release binding does not match its exact Deploy authority.',
946
+ );
947
+ }
948
+ const release = {
949
+ candidateDigest: source.candidateDigest,
950
+ releaseId: source.releaseId,
951
+ releaseMaterialDigest: source.releaseMaterialDigest,
952
+ sourceCommit: source.deploymentCommit,
953
+ };
954
+ const workspaceManifest = readBoundedJson(
955
+ resolve(workspaceRoot, 'package.json'),
956
+ 'Workspace manifest',
957
+ );
958
+ if (
959
+ !isBoundedSafeReference(
960
+ workspaceManifest.name,
961
+ 'performance-evidence',
962
+ )
963
+ ) {
964
+ throw new Error('Workspace manifest lacks one bounded name.');
965
+ }
966
+ const environment = {
967
+ accountFingerprint: awsAccountFingerprint(
968
+ required('AWS_EXPECTED_ACCOUNT_ID'),
969
+ ),
970
+ region: required('AWS_REGION'),
971
+ slice: '${name}',
972
+ stage,
973
+ workspace: workspaceManifest.name,
974
+ };
975
+ const period = {
976
+ end: required('EBK_AGGREGATE_PERIOD_END'),
977
+ start: required('EBK_AGGREGATE_PERIOD_START'),
978
+ };
979
+ const collectionStartedAt = new Date();
980
+ const instantPattern = /^\\d{4}-\\d{2}-\\d{2}T00:00:00\\.000Z$/;
981
+ const durationDays =
982
+ (Date.parse(period.end) - Date.parse(period.start)) / 86_400_000;
983
+ if (
984
+ !instantPattern.test(period.start) ||
985
+ !instantPattern.test(period.end) ||
986
+ !Number.isSafeInteger(durationDays) ||
987
+ durationDays < 1 ||
988
+ durationDays > 370 ||
989
+ Date.parse(period.end) > collectionStartedAt.getTime() ||
990
+ !/^(?:af|ap|ca|cn|eu|il|me|mx|sa|us)(?:-gov|-iso|-isob)?-[a-z]+-\\d$/.test(
991
+ environment.region,
992
+ ) ||
993
+ (stage !== 'staging' && stage !== 'production')
994
+ ) {
995
+ throw new Error(
996
+ 'Aggregate environment and closed billing period are invalid.',
997
+ );
998
+ }
999
+ const allocation = validateCostAllocationContract(
1000
+ readBoundedJson(
1001
+ resolve(sliceRoot, 'performance/cost-allocation.json'),
1002
+ 'Cost allocation authority',
1003
+ ),
1004
+ { requireAdopted: true },
1005
+ );
1006
+ if (allocation.slice !== '${name}') {
1007
+ throw new Error('Cost allocation authority belongs to another Slice.');
1008
+ }
1009
+ const capabilities = allocation.allocations
1010
+ .map(({ capabilityId }) => capabilityId)
1011
+ .sort();
1012
+ if (authorityOnly) {
1013
+ process.stdout.write(
1014
+ JSON.stringify({
1015
+ kind: 'ebk-protected-aggregate-authority-result',
1016
+ outcome: 'passed',
1017
+ release,
1018
+ schemaVersion: 1,
1019
+ }) + '\\n',
1020
+ );
1021
+ process.exit(0);
1022
+ }
1023
+ if (
1024
+ required('EBK_AGGREGATE_ACTUAL_ACCOUNT_ID') !==
1025
+ required('AWS_EXPECTED_ACCOUNT_ID')
1026
+ ) {
1027
+ throw new Error(
1028
+ 'Aggregate-count provider lacks a verified protected account binding.',
1029
+ );
1030
+ }
1031
+ const provider = exactKeys(
1032
+ await collectAggregateCounts({
1033
+ authority: {
1034
+ mode: 'dedicated-oidc-read-role',
1035
+ permissionContract: 'adopter-owned-least-privilege-read-v1',
1036
+ },
1037
+ capabilities,
1038
+ environment,
1039
+ period,
1040
+ release,
1041
+ }),
1042
+ ['counts', 'requestId'],
1043
+ 'Aggregate-count provider result',
1044
+ );
1045
+ if (!Array.isArray(provider.counts)) {
1046
+ throw new Error('Aggregate-count provider counts must be an array.');
1047
+ }
1048
+ const providerCapabilities = provider.counts
1049
+ .map(({ capabilityId }) => capabilityId)
1050
+ .sort();
1051
+ if (JSON.stringify(providerCapabilities) !== JSON.stringify(capabilities)) {
1052
+ throw new Error(
1053
+ 'Aggregate-count provider must return the exact adopted capability set.',
1054
+ );
1055
+ }
1056
+ const evidence = createAggregateCountEvidence({
1057
+ collectedAt: new Date().toISOString(),
1058
+ counts: provider.counts,
1059
+ environment,
1060
+ kind: 'ebk-aggregate-count-evidence',
1061
+ period,
1062
+ producer: {
1063
+ access: {
1064
+ mode: 'dedicated-oidc-read-role',
1065
+ permissionContract: 'adopter-owned-least-privilege-read-v1',
1066
+ },
1067
+ authority: 'adopter-protected-aggregate-v1',
1068
+ requestId: provider.requestId,
1069
+ },
1070
+ release,
1071
+ schemaVersion: 1,
1072
+ });
1073
+ const evidenceRoot = resolve(sliceRoot, '.ebk/evidence');
1074
+ for (const directory of [resolve(sliceRoot, '.ebk'), evidenceRoot]) {
1075
+ if (!existsSync(directory)) mkdirSync(directory, { mode: 0o700 });
1076
+ const metadata = lstatSync(directory);
1077
+ if (!metadata.isDirectory() || metadata.isSymbolicLink()) {
1078
+ throw new Error('Aggregate-count evidence directory is unsafe.');
1079
+ }
1080
+ chmodSync(directory, 0o700);
1081
+ }
1082
+ const evidenceRootRelative = relative(sliceRoot, realpathSync(evidenceRoot));
1083
+ if (
1084
+ evidenceRootRelative === '..' ||
1085
+ evidenceRootRelative.startsWith('..' + sep) ||
1086
+ isAbsolute(evidenceRootRelative)
1087
+ ) {
1088
+ throw new Error('Aggregate-count evidence directory escaped its Slice.');
1089
+ }
1090
+ const evidencePath = resolve(evidenceRoot, 'aggregate-count-evidence.json');
1091
+ const evidenceBytes = Buffer.from(
1092
+ JSON.stringify(evidence, null, 2) + '\\n',
1093
+ 'utf8',
1094
+ );
1095
+ if (evidenceBytes.length > 1024 * 1024) {
1096
+ throw new Error('Aggregate-count evidence exceeds its byte bound.');
1097
+ }
1098
+ writeFileSync(evidencePath, evidenceBytes, {
1099
+ flag: 'wx',
1100
+ mode: 0o600,
1101
+ });
1102
+ chmodSync(evidencePath, 0o600);
1103
+ const outputMetadata = lstatSync(evidencePath);
1104
+ if (
1105
+ !outputMetadata.isFile() ||
1106
+ outputMetadata.isSymbolicLink() ||
1107
+ outputMetadata.size !== evidenceBytes.length ||
1108
+ validateAggregateCountEvidence(
1109
+ JSON.parse(readFileSync(evidencePath, 'utf8')),
1110
+ ).materialDigest !== evidence.materialDigest
1111
+ ) {
1112
+ throw new Error('Aggregate-count evidence output did not remain canonical.');
1113
+ }
1114
+ process.stdout.write(
1115
+ JSON.stringify({
1116
+ kind: 'ebk-protected-aggregate-count-result',
1117
+ materialDigest: evidence.materialDigest,
1118
+ outcome: 'passed',
1119
+ schemaVersion: 1,
1120
+ }) + '\\n',
1121
+ );
1122
+ `,
1123
+ 'scripts/performance-cost-collect.mjs': `import {
1124
+ CostExplorerClient,
1125
+ GetCostAndUsageCommand,
1126
+ ListCostAllocationTagsCommand,
1127
+ } from '@aws-sdk/client-cost-explorer';
1128
+ import {
1129
+ GetCallerIdentityCommand,
1130
+ STSClient,
1131
+ } from '@aws-sdk/client-sts';
1132
+ import { createHash } from 'node:crypto';
1133
+ import {
1134
+ chmodSync,
1135
+ lstatSync,
1136
+ mkdirSync,
1137
+ readFileSync,
1138
+ writeFileSync,
1139
+ } from 'node:fs';
1140
+ import {
1141
+ collectAwsBillingActualEvidence,
1142
+ validateAggregateCountEvidence,
1143
+ validateCostAllocationContract,
1144
+ } from '@empire-builder-kit/nx/performance';
1145
+
1146
+ const required = (name) => {
1147
+ const value = process.env[name]?.trim();
1148
+ if (!value) throw new Error(name + ' is required.');
1149
+ return value;
1150
+ };
1151
+ const digest = (bytes) =>
1152
+ createHash('sha256').update(bytes).digest('hex');
1153
+ const readBoundedJson = (path, expectedDigest, label) => {
1154
+ const metadata = lstatSync(path);
1155
+ if (
1156
+ !metadata.isFile() ||
1157
+ metadata.isSymbolicLink() ||
1158
+ metadata.size <= 0 ||
1159
+ metadata.size > 1024 * 1024
1160
+ ) {
1161
+ throw new Error(label + ' must be one bounded regular file.');
1162
+ }
1163
+ const bytes = readFileSync(path);
1164
+ if (!/^[a-f0-9]{64}$/.test(expectedDigest) || digest(bytes) !== expectedDigest) {
1165
+ throw new Error(label + ' does not match its independently expected digest.');
1166
+ }
1167
+ return JSON.parse(bytes.toString('utf8'));
1168
+ };
1169
+ const aggregate = validateAggregateCountEvidence(
1170
+ readBoundedJson(
1171
+ required('EBK_AGGREGATE_COUNT_EVIDENCE_PATH'),
1172
+ required('EBK_EXPECTED_AGGREGATE_COUNT_EVIDENCE_DIGEST'),
1173
+ 'Aggregate-count evidence',
1174
+ ),
1175
+ );
1176
+ const release = readBoundedJson(
1177
+ required('EBK_RELEASE_BINDING_PATH'),
1178
+ required('EBK_EXPECTED_RELEASE_BINDING_DIGEST'),
1179
+ 'Release binding',
1180
+ );
1181
+ if (JSON.stringify(release) !== JSON.stringify(aggregate.release)) {
1182
+ throw new Error('Aggregate counts and reviewed release binding differ.');
1183
+ }
1184
+ const environment = aggregate.environment;
1185
+ if (
1186
+ environment.slice !== '${name}' ||
1187
+ environment.stage !== required('EBK_STAGE') ||
1188
+ environment.region !== required('AWS_REGION') ||
1189
+ environment.workspace !== required('EBK_WORKSPACE') ||
1190
+ environment.accountFingerprint !== required('EBK_ACCOUNT_FINGERPRINT') ||
1191
+ release.sourceCommit !== required('EBK_SOURCE_COMMIT') ||
1192
+ aggregate.period.start !==
1193
+ required('EBK_EXPECTED_BILLING_PERIOD_START') ||
1194
+ aggregate.period.end !== required('EBK_EXPECTED_BILLING_PERIOD_END')
1195
+ ) {
1196
+ throw new Error('Cost collection escaped its exact reviewed cohort.');
1197
+ }
1198
+ const allocation = validateCostAllocationContract(
1199
+ JSON.parse(
1200
+ readFileSync(
1201
+ new URL('../performance/cost-allocation.json', import.meta.url),
1202
+ 'utf8',
1203
+ ),
1204
+ ),
1205
+ { requireAdopted: true },
1206
+ );
1207
+ if (allocation.slice !== '${name}') {
1208
+ throw new Error('Cost allocation authority belongs to another Slice.');
1209
+ }
1210
+ const allocations = allocation.allocations.map(
1211
+ ({ capabilityId, id }) => ({ allocationId: id, capabilityId }),
1212
+ );
1213
+ const sts = new STSClient({ region: environment.region });
1214
+ const costExplorer = new CostExplorerClient({ region: 'us-east-1' });
1215
+ const requiredCostAllocationTags = [
1216
+ 'ebk:cost-allocation',
1217
+ 'ebk:cost-scope',
1218
+ 'ebk:slice',
1219
+ 'ebk:stage',
1220
+ 'ebk:workspace',
1221
+ ];
1222
+ const costAllocationTagResponse = await costExplorer.send(
1223
+ new ListCostAllocationTagsCommand({
1224
+ MaxResults: 100,
1225
+ Status: 'Active',
1226
+ TagKeys: requiredCostAllocationTags,
1227
+ Type: 'UserDefined',
1228
+ }),
1229
+ );
1230
+ const activeCostAllocationTags = (costAllocationTagResponse.CostAllocationTags ?? [])
1231
+ .map(({ Status, TagKey, Type }) => ({ Status, TagKey, Type }))
1232
+ .sort((left, right) =>
1233
+ (left.TagKey ?? '') < (right.TagKey ?? '')
1234
+ ? -1
1235
+ : (left.TagKey ?? '') > (right.TagKey ?? '')
1236
+ ? 1
1237
+ : 0,
1238
+ );
1239
+ if (
1240
+ costAllocationTagResponse.NextToken ||
1241
+ !costAllocationTagResponse.$metadata.requestId ||
1242
+ JSON.stringify(activeCostAllocationTags) !==
1243
+ JSON.stringify(
1244
+ requiredCostAllocationTags.map((TagKey) => ({
1245
+ Status: 'Active',
1246
+ TagKey,
1247
+ Type: 'UserDefined',
1248
+ })),
1249
+ )
1250
+ ) {
1251
+ throw new Error(
1252
+ 'Required Product cost-allocation tags are not all ACTIVE in AWS.',
1253
+ );
1254
+ }
1255
+ const client = {
1256
+ async getCallerIdentity() {
1257
+ const response = await sts.send(new GetCallerIdentityCommand({}));
1258
+ if (!response.Account || !response.$metadata.requestId) {
1259
+ throw new Error('AWS STS identity response is incomplete.');
1260
+ }
1261
+ return {
1262
+ accountId: response.Account,
1263
+ requestId: response.$metadata.requestId,
1264
+ };
1265
+ },
1266
+ async getCostAndUsage(request) {
1267
+ const filter = {
1268
+ And: request.filter.tags.map(({ key, value }) => ({
1269
+ Tags: {
1270
+ Key: key,
1271
+ MatchOptions: ['EQUALS'],
1272
+ Values: [value],
1273
+ },
1274
+ })),
1275
+ };
1276
+ const response = await costExplorer.send(
1277
+ new GetCostAndUsageCommand({
1278
+ Filter: filter,
1279
+ Granularity: request.granularity,
1280
+ GroupBy: request.groupBy
1281
+ ? [{ Key: request.groupBy.key, Type: request.groupBy.type }]
1282
+ : undefined,
1283
+ Metrics: [request.metric],
1284
+ TimePeriod: {
1285
+ End: request.timePeriod.end,
1286
+ Start: request.timePeriod.start,
1287
+ },
1288
+ }),
1289
+ );
1290
+ if (response.NextPageToken || !response.$metadata.requestId) {
1291
+ throw new Error('AWS Cost Explorer result exceeded its exact page bound.');
1292
+ }
1293
+ return {
1294
+ requestId: response.$metadata.requestId,
1295
+ results: (response.ResultsByTime ?? []).map((result) => ({
1296
+ end: result.TimePeriod?.End ?? '',
1297
+ estimated: result.Estimated ?? true,
1298
+ groups: (result.Groups ?? []).map((group) => {
1299
+ const key = group.Keys?.[0] ?? '';
1300
+ const prefix = 'ebk:cost-allocation$';
1301
+ const metric = group.Metrics?.UnblendedCost;
1302
+ if (
1303
+ group.Keys?.length !== 1 ||
1304
+ !key.startsWith(prefix) ||
1305
+ !metric?.Amount
1306
+ ) {
1307
+ throw new Error('AWS allocation row is incomplete or unallocated.');
1308
+ }
1309
+ return {
1310
+ allocationId: key.slice(prefix.length),
1311
+ amountUsd: metric.Amount,
1312
+ currency: metric.Unit === 'USD' ? 'USD' : metric.Unit,
1313
+ };
1314
+ }),
1315
+ start: result.TimePeriod?.Start ?? '',
1316
+ total: request.groupBy
1317
+ ? null
1318
+ : {
1319
+ amountUsd: result.Total?.UnblendedCost?.Amount ?? '',
1320
+ currency:
1321
+ result.Total?.UnblendedCost?.Unit === 'USD'
1322
+ ? 'USD'
1323
+ : result.Total?.UnblendedCost?.Unit,
1324
+ },
1325
+ })),
1326
+ };
1327
+ },
1328
+ };
1329
+ const report = await collectAwsBillingActualEvidence({
1330
+ aggregateEvidence: aggregate,
1331
+ allocations,
1332
+ client,
1333
+ collectedAt: new Date().toISOString(),
1334
+ collection: {
1335
+ aggregateArtifact: {
1336
+ name: required('EBK_AGGREGATE_ARTIFACT_NAME'),
1337
+ runId: required('EBK_AGGREGATE_ARTIFACT_RUN_ID'),
1338
+ sha256: required('EBK_EXPECTED_AGGREGATE_COUNT_EVIDENCE_DIGEST'),
1339
+ },
1340
+ releaseArtifact: {
1341
+ name: required('EBK_RELEASE_ARTIFACT_NAME'),
1342
+ runId: required('EBK_RELEASE_ARTIFACT_RUN_ID'),
1343
+ sha256: required('EBK_EXPECTED_RELEASE_BINDING_DIGEST'),
1344
+ },
1345
+ repository: required('GITHUB_REPOSITORY'),
1346
+ runAttempt: required('GITHUB_RUN_ATTEMPT'),
1347
+ runId: required('GITHUB_RUN_ID'),
1348
+ sourceCommit: release.sourceCommit,
1349
+ workflow: '.github/workflows/performance-cost-actual.yml',
1350
+ },
1351
+ environment,
1352
+ period: aggregate.period,
1353
+ release,
1354
+ });
1355
+ const evidenceDirectory = new URL('../.ebk/evidence/', import.meta.url);
1356
+ mkdirSync(evidenceDirectory, { recursive: true, mode: 0o700 });
1357
+ chmodSync(evidenceDirectory, 0o700);
1358
+ const evidencePath = new URL(
1359
+ 'performance-cost-actual.json',
1360
+ evidenceDirectory,
1361
+ );
1362
+ writeFileSync(evidencePath, JSON.stringify(report, null, 2) + '\\n', {
1363
+ encoding: 'utf8',
1364
+ flag: 'wx',
1365
+ mode: 0o600,
1366
+ });
1367
+ chmodSync(evidencePath, 0o600);
1368
+ process.stdout.write(JSON.stringify(report) + '\\n');
1369
+ `,
1370
+ 'scripts/performance-load-guard.mjs': `import {
1371
+ lstatSync,
1372
+ readFileSync,
1373
+ realpathSync,
1374
+ } from 'node:fs';
1375
+ import { fileURLToPath } from 'node:url';
1376
+ import { relative, resolve, sep } from 'node:path';
1377
+ import {
1378
+ validateProtectedLoadAuthorization,
1379
+ validatePerformancePolicy,
1380
+ } from '@empire-builder-kit/nx/performance';
1381
+
1382
+ const requestedPlanPath =
1383
+ process.env.EBK_PROTECTED_LOAD_PLAN_PATH?.trim();
1384
+ const requestedApprovalPath =
1385
+ process.env.EBK_PROTECTED_LOAD_APPROVAL_PATH?.trim();
1386
+ const currentSourceCommit = process.env.EBK_SOURCE_COMMIT?.trim();
1387
+ const expectedAccountFingerprint =
1388
+ process.env.EBK_ACCOUNT_FINGERPRINT?.trim();
1389
+ const expectedEndpoint = process.env.EBK_LOAD_ENDPOINT?.trim();
1390
+ const expectedRegion = process.env.AWS_REGION?.trim();
1391
+ const now = process.env.EBK_EVIDENCE_NOW?.trim();
1392
+ if (
1393
+ !requestedPlanPath ||
1394
+ !requestedApprovalPath ||
1395
+ !currentSourceCommit ||
1396
+ !expectedAccountFingerprint ||
1397
+ !expectedEndpoint ||
1398
+ !expectedRegion ||
1399
+ !now
1400
+ ) {
1401
+ throw new Error(
1402
+ 'Protected load guard requires exact plan, approval, source, target, Region, and time inputs.',
1403
+ );
1404
+ }
1405
+
1406
+ const sliceRoot = realpathSync(
1407
+ fileURLToPath(new URL('../', import.meta.url)),
1408
+ );
1409
+
1410
+ function managedInput(requestedPath, directory, label) {
1411
+ const root = resolve(sliceRoot, '.ebk/performance-load', directory);
1412
+ const rootChild = relative(sliceRoot, root);
1413
+ let cursor = sliceRoot;
1414
+ for (const component of rootChild.split(sep).filter(Boolean)) {
1415
+ cursor = resolve(cursor, component);
1416
+ const metadata = lstatSync(cursor);
1417
+ if (!metadata.isDirectory() || metadata.isSymbolicLink()) {
1418
+ throw new Error(label + ' managed directory contains a symbolic link.');
1419
+ }
1420
+ }
1421
+ const candidate = resolve(process.cwd(), requestedPath);
1422
+ const child = relative(root, candidate);
1423
+ if (
1424
+ !/^[a-z0-9][a-z0-9._-]*\\.json$/.test(child) ||
1425
+ child.includes(sep) ||
1426
+ child === '..' ||
1427
+ child.startsWith('..' + sep)
1428
+ ) {
1429
+ throw new Error(label + ' must be one exact managed JSON file.');
1430
+ }
1431
+ const metadata = lstatSync(candidate);
1432
+ if (
1433
+ !metadata.isFile() ||
1434
+ metadata.isSymbolicLink() ||
1435
+ (process.platform !== 'win32' && (metadata.mode & 0o077) !== 0) ||
1436
+ (typeof process.getuid === 'function' &&
1437
+ metadata.uid !== process.getuid()) ||
1438
+ metadata.size <= 0 ||
1439
+ metadata.size > 1024 * 1024
1440
+ ) {
1441
+ throw new Error(label + ' must be a regular bounded non-symlink file.');
1442
+ }
1443
+ const realRoot = realpathSync(root);
1444
+ const realCandidate = realpathSync(candidate);
1445
+ if (relative(realRoot, realCandidate) !== child) {
1446
+ throw new Error(label + ' resolves outside its managed directory.');
1447
+ }
1448
+ return realCandidate;
1449
+ }
1450
+
1451
+ const planPath = managedInput(requestedPlanPath, 'plans', 'Protected plan');
1452
+ const approvalPath = managedInput(
1453
+ requestedApprovalPath,
1454
+ 'approvals',
1455
+ 'Protected approval',
1456
+ );
1457
+ const policy = validatePerformancePolicy(
1458
+ JSON.parse(
1459
+ readFileSync(
1460
+ new URL('../performance/policy.json', import.meta.url),
1461
+ 'utf8',
1462
+ ),
1463
+ ),
1464
+ );
1465
+ const result = validateProtectedLoadAuthorization({
1466
+ approval: JSON.parse(readFileSync(approvalPath, 'utf8')),
1467
+ currentSourceCommit,
1468
+ expectedAccountFingerprint,
1469
+ expectedEndpoint,
1470
+ expectedRegion,
1471
+ now,
1472
+ plan: JSON.parse(readFileSync(planPath, 'utf8')),
1473
+ policy,
1474
+ });
1475
+ process.stdout.write(JSON.stringify(result) + '\\n');
1476
+ `,
1477
+ 'scripts/performance-load-runner.mjs': `import {
1478
+ appendFileSync,
1479
+ chmodSync,
1480
+ closeSync,
1481
+ constants,
1482
+ existsSync,
1483
+ lstatSync,
1484
+ mkdirSync,
1485
+ openSync,
1486
+ readFileSync,
1487
+ writeFileSync,
1488
+ } from 'node:fs';
1489
+ import {
1490
+ createProtectedLoadPlan,
1491
+ createProtectedLoadScenarioDriver,
1492
+ runBoundedProtectedLoad,
1493
+ validatePerformancePolicy,
1494
+ } from '@empire-builder-kit/nx/performance';
1495
+
1496
+ const planPath = process.env.EBK_PROTECTED_LOAD_PLAN_PATH?.trim();
1497
+ const authorizationPath =
1498
+ process.env.EBK_PROTECTED_LOAD_AUTHORIZATION_PATH?.trim();
1499
+ const hmacKeyPath =
1500
+ process.env.EBK_PERFORMANCE_LOAD_HMAC_KEY_PATH?.trim();
1501
+ const emergencyStopPath = process.env.EBK_EMERGENCY_STOP_PATH?.trim();
1502
+ if (!planPath || !authorizationPath || !hmacKeyPath || !emergencyStopPath) {
1503
+ throw new Error(
1504
+ 'Protected load runner requires exact plan, authorization, job-scoped HMAC-key, and emergency-stop paths.',
1505
+ );
1506
+ }
1507
+ const readHmacKey = (path) => {
1508
+ const metadata = lstatSync(path);
1509
+ if (
1510
+ !metadata.isFile() ||
1511
+ metadata.isSymbolicLink() ||
1512
+ (process.platform !== 'win32' && (metadata.mode & 0o077) !== 0) ||
1513
+ (typeof process.getuid === 'function' &&
1514
+ metadata.uid !== process.getuid()) ||
1515
+ metadata.size <= 0 ||
1516
+ metadata.size > 2_048
1517
+ ) {
1518
+ throw new Error('Protected load HMAC key must be one bounded regular file.');
1519
+ }
1520
+ const value = JSON.parse(readFileSync(path, 'utf8'));
1521
+ const secret =
1522
+ value && typeof value.secret === 'string' ? value.secret : '';
1523
+ const decoded = /^[A-Za-z0-9_-]{43}$/.test(secret)
1524
+ ? Buffer.from(secret, 'base64url')
1525
+ : Buffer.alloc(0);
1526
+ if (
1527
+ !value ||
1528
+ typeof value !== 'object' ||
1529
+ Array.isArray(value) ||
1530
+ Object.keys(value).sort().join() !== 'id,secret' ||
1531
+ typeof value.id !== 'string' ||
1532
+ !/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/.test(value.id) ||
1533
+ decoded.length !== 32 ||
1534
+ decoded.toString('base64url') !== secret
1535
+ ) {
1536
+ throw new Error('Protected load HMAC key material is invalid.');
1537
+ }
1538
+ return Object.freeze({ id: value.id, secret: value.secret });
1539
+ };
1540
+ const hmacKey = readHmacKey(hmacKeyPath);
1541
+ const policy = validatePerformancePolicy(
1542
+ JSON.parse(
1543
+ readFileSync(
1544
+ new URL('../performance/policy.json', import.meta.url),
1545
+ 'utf8',
1546
+ ),
1547
+ ),
1548
+ );
1549
+ if (
1550
+ policy.authority.operationsAuthorityPath !==
1551
+ 'operations/reliability.json'
1552
+ ) {
1553
+ throw new Error(
1554
+ 'Protected load requires the exact generated reliability operations authority.',
1555
+ );
1556
+ }
1557
+ const operationsAuthority = JSON.parse(
1558
+ readFileSync(
1559
+ new URL('../operations/reliability.json', import.meta.url),
1560
+ 'utf8',
1561
+ ),
1562
+ );
1563
+ const providedPlan = JSON.parse(readFileSync(planPath, 'utf8'));
1564
+ const plan = createProtectedLoadPlan(policy, providedPlan);
1565
+ if (plan.materialDigest !== providedPlan.materialDigest) {
1566
+ throw new Error('Protected load plan material changed after authorization.');
1567
+ }
1568
+ if (plan.evidencePath !== '.ebk/evidence/performance-load-report.json') {
1569
+ throw new Error('Protected load evidence path is not the managed path.');
1570
+ }
1571
+ const catalog = JSON.parse(
1572
+ readFileSync(
1573
+ new URL('../performance/load-scenarios.json', import.meta.url),
1574
+ 'utf8',
1575
+ ),
1576
+ );
1577
+ const authorization = JSON.parse(readFileSync(authorizationPath, 'utf8'));
1578
+ const evidenceDirectory = new URL('../.ebk/evidence/', import.meta.url);
1579
+ mkdirSync(evidenceDirectory, { recursive: true, mode: 0o700 });
1580
+ chmodSync(evidenceDirectory, 0o700);
1581
+ const effectsPath = new URL('performance-load-effects.jsonl', evidenceDirectory);
1582
+ const maximumEffectLineBytes = 2_048;
1583
+ const maximumEffectLedgerBytes = Math.min(
1584
+ 64 * 1024 * 1024,
1585
+ plan.maximumRequests * maximumEffectLineBytes,
1586
+ );
1587
+ const effects = new Map();
1588
+ let effectLedgerBytes = 0;
1589
+ if (existsSync(effectsPath)) {
1590
+ const metadata = lstatSync(effectsPath);
1591
+ if (
1592
+ !metadata.isFile() ||
1593
+ metadata.isSymbolicLink() ||
1594
+ metadata.size > maximumEffectLedgerBytes
1595
+ ) {
1596
+ throw new Error('Protected load effect ledger must be a bounded regular file.');
1597
+ }
1598
+ const bytes = readFileSync(effectsPath, 'utf8');
1599
+ effectLedgerBytes = Buffer.byteLength(bytes);
1600
+ if (bytes && !bytes.endsWith('\\n')) {
1601
+ throw new Error('Protected load effect ledger has an incomplete record.');
1602
+ }
1603
+ const lines = bytes ? bytes.slice(0, -1).split('\\n') : [];
1604
+ if (lines.length > plan.maximumRequests) {
1605
+ throw new Error('Protected load effect ledger exceeds the request budget.');
1606
+ }
1607
+ for (const line of lines) {
1608
+ if (Buffer.byteLength(line) > maximumEffectLineBytes) {
1609
+ throw new Error('Protected load effect ledger record is oversized.');
1610
+ }
1611
+ const effect = JSON.parse(line);
1612
+ if (
1613
+ !effect ||
1614
+ typeof effect !== 'object' ||
1615
+ typeof effect.effectId !== 'string' ||
1616
+ effects.has(effect.effectId)
1617
+ ) {
1618
+ throw new Error('Protected load effect ledger identity is invalid.');
1619
+ }
1620
+ effects.set(effect.effectId, effect);
1621
+ }
1622
+ }
1623
+ const effectLedger = openSync(
1624
+ effectsPath,
1625
+ constants.O_APPEND |
1626
+ constants.O_CREAT |
1627
+ constants.O_WRONLY |
1628
+ constants.O_NOFOLLOW,
1629
+ 0o600,
1630
+ );
1631
+ chmodSync(effectsPath, 0o600);
1632
+ const recordEffect = async (effect) => {
1633
+ const prior = effects.get(effect.effectId);
1634
+ if (prior) {
1635
+ if (JSON.stringify(prior) !== JSON.stringify(effect)) {
1636
+ throw new Error('Protected load effect identity contains other material.');
1637
+ }
1638
+ return;
1639
+ }
1640
+ const line = JSON.stringify(effect) + '\\n';
1641
+ const lineBytes = Buffer.byteLength(line);
1642
+ if (
1643
+ lineBytes > maximumEffectLineBytes ||
1644
+ effects.size >= plan.maximumRequests ||
1645
+ effectLedgerBytes + lineBytes > maximumEffectLedgerBytes
1646
+ ) {
1647
+ throw new Error('Protected load effect ledger exceeded its hard bounds.');
1648
+ }
1649
+ appendFileSync(effectLedger, line, 'utf8');
1650
+ effectLedgerBytes += lineBytes;
1651
+ effects.set(effect.effectId, effect);
1652
+ };
1653
+ const { allowedDriver, driver } = createProtectedLoadScenarioDriver({
1654
+ catalog,
1655
+ hmacKey,
1656
+ operationsAuthority,
1657
+ plan,
1658
+ policy,
1659
+ recordEffect,
1660
+ });
1661
+ const report = await runBoundedProtectedLoad({
1662
+ abortRequested: () => existsSync(emergencyStopPath),
1663
+ allowedDrivers: [allowedDriver],
1664
+ authorization,
1665
+ driver,
1666
+ plan,
1667
+ });
1668
+ closeSync(effectLedger);
1669
+ const output = new URL('performance-load-report.json', evidenceDirectory);
1670
+ const bytes = JSON.stringify(report, null, 2) + '\\n';
1671
+ try {
1672
+ writeFileSync(output, bytes, { encoding: 'utf8', flag: 'wx', mode: 0o600 });
1673
+ } catch {
1674
+ if (readFileSync(output, 'utf8') !== bytes) {
1675
+ throw new Error('Protected load evidence path already contains other bytes.');
1676
+ }
1677
+ }
1678
+ chmodSync(output, 0o600);
1679
+ process.stdout.write(JSON.stringify(report) + '\\n');
1680
+ `,
1681
+ 'scripts/performance-load-cleanup.mjs': `import {
1682
+ chmodSync,
1683
+ existsSync,
1684
+ lstatSync,
1685
+ mkdirSync,
1686
+ readFileSync,
1687
+ writeFileSync,
1688
+ } from 'node:fs';
1689
+ import {
1690
+ cleanupProtectedLoadScenarioEffects,
1691
+ createProtectedLoadPlan,
1692
+ validatePerformancePolicy,
1693
+ } from '@empire-builder-kit/nx/performance';
1694
+
1695
+ const planPath = process.env.EBK_PROTECTED_LOAD_PLAN_PATH?.trim();
1696
+ const hmacKeyPath =
1697
+ process.env.EBK_PERFORMANCE_LOAD_HMAC_KEY_PATH?.trim();
1698
+ if (!planPath || !hmacKeyPath) {
1699
+ throw new Error(
1700
+ 'Protected load cleanup requires one exact plan path and job-scoped HMAC key.',
1701
+ );
1702
+ }
1703
+ const metadata = lstatSync(hmacKeyPath);
1704
+ if (
1705
+ !metadata.isFile() ||
1706
+ metadata.isSymbolicLink() ||
1707
+ (process.platform !== 'win32' && (metadata.mode & 0o077) !== 0) ||
1708
+ (typeof process.getuid === 'function' &&
1709
+ metadata.uid !== process.getuid()) ||
1710
+ metadata.size <= 0 ||
1711
+ metadata.size > 2_048
1712
+ ) {
1713
+ throw new Error('Protected load HMAC key must be one bounded regular file.');
1714
+ }
1715
+ const hmacKey = JSON.parse(readFileSync(hmacKeyPath, 'utf8'));
1716
+ const hmacSecret =
1717
+ hmacKey && typeof hmacKey.secret === 'string' ? hmacKey.secret : '';
1718
+ const decodedHmacSecret = /^[A-Za-z0-9_-]{43}$/.test(hmacSecret)
1719
+ ? Buffer.from(hmacSecret, 'base64url')
1720
+ : Buffer.alloc(0);
1721
+ if (
1722
+ !hmacKey ||
1723
+ typeof hmacKey !== 'object' ||
1724
+ Array.isArray(hmacKey) ||
1725
+ Object.keys(hmacKey).sort().join() !== 'id,secret' ||
1726
+ typeof hmacKey.id !== 'string' ||
1727
+ !/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/.test(hmacKey.id) ||
1728
+ decodedHmacSecret.length !== 32 ||
1729
+ decodedHmacSecret.toString('base64url') !== hmacSecret
1730
+ ) {
1731
+ throw new Error('Protected load HMAC key material is invalid.');
1732
+ }
1733
+ const policy = validatePerformancePolicy(
1734
+ JSON.parse(
1735
+ readFileSync(
1736
+ new URL('../performance/policy.json', import.meta.url),
1737
+ 'utf8',
1738
+ ),
1739
+ ),
1740
+ );
1741
+ if (
1742
+ policy.authority.operationsAuthorityPath !==
1743
+ 'operations/reliability.json'
1744
+ ) {
1745
+ throw new Error(
1746
+ 'Protected load cleanup requires the exact generated reliability operations authority.',
1747
+ );
1748
+ }
1749
+ const operationsAuthority = JSON.parse(
1750
+ readFileSync(
1751
+ new URL('../operations/reliability.json', import.meta.url),
1752
+ 'utf8',
1753
+ ),
1754
+ );
1755
+ const providedPlan = JSON.parse(readFileSync(planPath, 'utf8'));
1756
+ const plan = createProtectedLoadPlan(policy, providedPlan);
1757
+ if (plan.materialDigest !== providedPlan.materialDigest) {
1758
+ throw new Error('Protected load cleanup plan material is inconsistent.');
1759
+ }
1760
+ const catalog = JSON.parse(
1761
+ readFileSync(
1762
+ new URL('../performance/load-scenarios.json', import.meta.url),
1763
+ 'utf8',
1764
+ ),
1765
+ );
1766
+ const evidenceDirectory = new URL('../.ebk/evidence/', import.meta.url);
1767
+ mkdirSync(evidenceDirectory, { recursive: true, mode: 0o700 });
1768
+ chmodSync(evidenceDirectory, 0o700);
1769
+ const effectsPath = new URL('performance-load-effects.jsonl', evidenceDirectory);
1770
+ const maximumEffectLineBytes = 2_048;
1771
+ const maximumEffectLedgerBytes = Math.min(
1772
+ 64 * 1024 * 1024,
1773
+ plan.maximumRequests * maximumEffectLineBytes,
1774
+ );
1775
+ let effects = [];
1776
+ if (existsSync(effectsPath)) {
1777
+ const metadata = lstatSync(effectsPath);
1778
+ if (
1779
+ !metadata.isFile() ||
1780
+ metadata.isSymbolicLink() ||
1781
+ metadata.size > maximumEffectLedgerBytes
1782
+ ) {
1783
+ throw new Error('Protected load effect ledger must be a bounded regular file.');
1784
+ }
1785
+ const bytes = readFileSync(effectsPath, 'utf8');
1786
+ if (bytes && !bytes.endsWith('\\n')) {
1787
+ throw new Error('Protected load effect ledger has an incomplete record.');
1788
+ }
1789
+ const lines = bytes ? bytes.slice(0, -1).split('\\n') : [];
1790
+ if (
1791
+ lines.length > plan.maximumRequests ||
1792
+ lines.some((line) => Buffer.byteLength(line) > maximumEffectLineBytes)
1793
+ ) {
1794
+ throw new Error('Protected load effect ledger exceeds its hard bounds.');
1795
+ }
1796
+ effects = lines.map((line) => JSON.parse(line));
1797
+ }
1798
+ const report = await cleanupProtectedLoadScenarioEffects({
1799
+ catalog,
1800
+ effects,
1801
+ hmacKey,
1802
+ operationsAuthority,
1803
+ plan,
1804
+ policy,
1805
+ });
1806
+ const output = new URL('performance-load-cleanup.json', evidenceDirectory);
1807
+ const bytes = JSON.stringify(report, null, 2) + '\\n';
1808
+ try {
1809
+ writeFileSync(output, bytes, { encoding: 'utf8', flag: 'wx', mode: 0o600 });
1810
+ } catch {
1811
+ if (readFileSync(output, 'utf8') !== bytes) {
1812
+ throw new Error('Protected cleanup evidence path contains other bytes.');
1813
+ }
1814
+ }
1815
+ chmodSync(output, 0o600);
1816
+ process.stdout.write(JSON.stringify(report) + '\\n');
1817
+ `,
1818
+ 'scripts/performance-tag-coverage.mjs': `import { chmodSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
1819
+ import {
1820
+ deriveExpectedResourceTagInventory,
1821
+ evaluateResourceTagCoverage,
1822
+ } from '@empire-builder-kit/nx/performance';
1823
+
1824
+ const deploymentPath =
1825
+ process.env.EBK_DEPLOYMENT_RESOURCE_TAG_INVENTORY_PATH?.trim();
1826
+ const observedPath =
1827
+ process.env.EBK_OBSERVED_RESOURCE_TAG_INVENTORY_PATH?.trim();
1828
+ if (!deploymentPath || !observedPath) {
1829
+ throw new Error(
1830
+ 'Exact deployment resource inventory and observed tag inventory paths are required.',
1831
+ );
1832
+ }
1833
+ const expected = deriveExpectedResourceTagInventory(
1834
+ JSON.parse(readFileSync(deploymentPath, 'utf8')),
1835
+ );
1836
+ const result = evaluateResourceTagCoverage({
1837
+ expected,
1838
+ observed: JSON.parse(readFileSync(observedPath, 'utf8')),
1839
+ });
1840
+ const evidenceDirectory = new URL('../.ebk/evidence/', import.meta.url);
1841
+ mkdirSync(evidenceDirectory, { recursive: true, mode: 0o700 });
1842
+ chmodSync(evidenceDirectory, 0o700);
1843
+ const evidencePath = new URL(
1844
+ 'performance-tag-coverage.json',
1845
+ evidenceDirectory,
1846
+ );
1847
+ writeFileSync(evidencePath, JSON.stringify(result, null, 2) + '\\n', {
1848
+ encoding: 'utf8',
1849
+ mode: 0o600,
1850
+ });
1851
+ chmodSync(evidencePath, 0o600);
1852
+ process.stdout.write(JSON.stringify(result) + '\\n');
1853
+ if (result.status !== 'complete') process.exitCode = 2;
1854
+ `,
1855
+ 'web/src/app/%5F%5Febk/performance/handler.ts': `import 'server-only';
1856
+ import {
1857
+ handleProtectedLoadCleanupEndpoint,
1858
+ handleProtectedLoadScenarioEndpoint,
1859
+ type ProtectedLoadEndpointBindingV1,
1860
+ type ProtectedLoadEndpointAdapterId,
1861
+ type ProtectedLoadRequestAuthorizationV1,
1862
+ } from '@empire-builder-kit/runtime/performance';
1863
+ import { randomUUID } from 'node:crypto';
1864
+ import { withPrimaryDatabase } from '../../../../../database/runtime-client';
1865
+ import { Secrets } from '../../../../../secrets/declarations';
1866
+ import { createStandardSliceSecretRuntime } from '../../../../../secrets/runtime';
1867
+
1868
+ type ManagedAdapterId = Exclude<
1869
+ ProtectedLoadEndpointAdapterId,
1870
+ 'ebk-service-v1'
1871
+ >;
1872
+
1873
+ function required(name: string): string {
1874
+ const value = process.env[name]?.trim();
1875
+ if (!value) throw new Error('protected-performance-endpoint-disabled');
1876
+ return value;
1877
+ }
1878
+
1879
+ type EndpointSecretRuntime = ReturnType<
1880
+ typeof createStandardSliceSecretRuntime
1881
+ >;
1882
+ let endpointSecretRuntime: EndpointSecretRuntime | undefined;
1883
+ let endpointSecretRuntimeStage: 'production' | 'staging' | undefined;
1884
+
1885
+ function performanceSecretRuntime(
1886
+ stage: 'production' | 'staging',
1887
+ ): EndpointSecretRuntime {
1888
+ if (
1889
+ endpointSecretRuntimeStage !== undefined &&
1890
+ endpointSecretRuntimeStage !== stage
1891
+ ) {
1892
+ throw new Error('protected-performance-endpoint-disabled');
1893
+ }
1894
+ endpointSecretRuntimeStage = stage;
1895
+ endpointSecretRuntime ??= createStandardSliceSecretRuntime({
1896
+ stage,
1897
+ workload: '${name}.web-server',
1898
+ });
1899
+ return endpointSecretRuntime;
1900
+ }
1901
+
1902
+ async function withEndpointBinding<Result>(
1903
+ adapterId: ManagedAdapterId,
1904
+ operation: (binding: ProtectedLoadEndpointBindingV1) => Promise<Result>,
1905
+ ): Promise<Result> {
1906
+ const stage = process.env.EBK_STAGE;
1907
+ if (
1908
+ process.env.EBK_PERFORMANCE_LOAD_ENABLED !== 'true' ||
1909
+ (stage !== 'staging' && stage !== 'production')
1910
+ ) {
1911
+ throw new Error('protected-performance-endpoint-disabled');
1912
+ }
1913
+ return performanceSecretRuntime(stage).runWithSecret({
1914
+ declaration: Secrets.${pascalName}PerformanceLoadHmacKeys,
1915
+ isAuthenticationFailure: () => false,
1916
+ operation: (hmacKeys) =>
1917
+ operation({
1918
+ adapterId,
1919
+ deployedCandidateDigest: required(
1920
+ 'EBK_PERFORMANCE_CANDIDATE_DIGEST',
1921
+ ),
1922
+ deployedReleaseId: required('EBK_PERFORMANCE_RELEASE_ID'),
1923
+ deployedReleaseMaterialDigest: required(
1924
+ 'EBK_PERFORMANCE_RELEASE_MATERIAL_DIGEST',
1925
+ ),
1926
+ deployedSourceCommit: required('EBK_SOURCE_COMMIT'),
1927
+ hmacKeys,
1928
+ stage,
1929
+ target: {
1930
+ accountFingerprint: required(
1931
+ 'EBK_PERFORMANCE_ACCOUNT_FINGERPRINT',
1932
+ ),
1933
+ origin: required('EBK_PERFORMANCE_ORIGIN'),
1934
+ region: required('EBK_PERFORMANCE_REGION'),
1935
+ slice: required('EBK_PERFORMANCE_SLICE'),
1936
+ },
1937
+ }),
1938
+ });
1939
+ }
1940
+
1941
+ function requestMaterial(request: Request, body?: unknown) {
1942
+ return {
1943
+ ...(body === undefined ? {} : { body }),
1944
+ headers: Object.fromEntries(request.headers.entries()),
1945
+ method: request.method as 'GET' | 'POST',
1946
+ url: request.url,
1947
+ };
1948
+ }
1949
+
1950
+ async function boundedRequestBody(request: Request): Promise<unknown> {
1951
+ const maximumBytes = 32 * 1024;
1952
+ const declaredLength = request.headers.get('content-length');
1953
+ if (
1954
+ declaredLength !== null &&
1955
+ (!/^\\d+$/.test(declaredLength) ||
1956
+ Number(declaredLength) <= 0 ||
1957
+ Number(declaredLength) > maximumBytes)
1958
+ ) {
1959
+ throw new Error('protected-performance-request-body-invalid');
1960
+ }
1961
+ if (!request.body) {
1962
+ throw new Error('protected-performance-request-body-invalid');
1963
+ }
1964
+ const reader = request.body.getReader();
1965
+ const chunks: Uint8Array[] = [];
1966
+ let size = 0;
1967
+ try {
1968
+ for (;;) {
1969
+ const { done, value } = await reader.read();
1970
+ if (done) break;
1971
+ size += value.byteLength;
1972
+ if (size > maximumBytes) {
1973
+ await reader.cancel();
1974
+ throw new Error('protected-performance-request-body-invalid');
1975
+ }
1976
+ chunks.push(value);
1977
+ }
1978
+ } finally {
1979
+ reader.releaseLock();
1980
+ }
1981
+ if (size === 0) {
1982
+ throw new Error('protected-performance-request-body-invalid');
1983
+ }
1984
+ const bytes = new Uint8Array(size);
1985
+ let offset = 0;
1986
+ for (const chunk of chunks) {
1987
+ bytes.set(chunk, offset);
1988
+ offset += chunk.byteLength;
1989
+ }
1990
+ return JSON.parse(new TextDecoder('utf-8', { fatal: true }).decode(bytes));
1991
+ }
1992
+
1993
+ function memorySaturation(): number {
1994
+ const memory = process.memoryUsage();
1995
+ if (memory.heapTotal <= 0) return 0;
1996
+ return Math.min(100, (memory.heapUsed / memory.heapTotal) * 100);
1997
+ }
1998
+
1999
+ function effectUuid(effectId: string): string {
2000
+ return [
2001
+ effectId.slice(0, 8),
2002
+ effectId.slice(8, 12),
2003
+ '4' + effectId.slice(13, 16),
2004
+ '8' + effectId.slice(17, 20),
2005
+ effectId.slice(20, 32),
2006
+ ].join('-');
2007
+ }
2008
+
2009
+ interface ProtectedPerformanceRunRow {
2010
+ adapterId: string;
2011
+ cleanupStartedAt: Date | null;
2012
+ createdAt: Date;
2013
+ expiresAt: Date;
2014
+ maximumRequests: number;
2015
+ releaseMaterialDigest: string;
2016
+ runId: string;
2017
+ scenarioId: string;
2018
+ sourceCommit: string;
2019
+ stage: string;
2020
+ }
2021
+
2022
+ function matchesProtectedPerformanceRun(
2023
+ actual: ProtectedPerformanceRunRow | undefined,
2024
+ authorization: ProtectedLoadRequestAuthorizationV1,
2025
+ ): actual is ProtectedPerformanceRunRow {
2026
+ return (
2027
+ actual !== undefined &&
2028
+ actual.adapterId === authorization.adapterId &&
2029
+ actual.createdAt.toISOString() === authorization.createdAt &&
2030
+ actual.expiresAt.toISOString() === authorization.expiresAt &&
2031
+ actual.maximumRequests === authorization.maximumRequests &&
2032
+ actual.releaseMaterialDigest ===
2033
+ authorization.release.releaseMaterialDigest &&
2034
+ actual.runId === authorization.runId &&
2035
+ actual.scenarioId === authorization.scenarioId &&
2036
+ actual.sourceCommit === authorization.release.sourceCommit &&
2037
+ actual.stage === authorization.stage
2038
+ );
2039
+ }
2040
+
2041
+ export async function reserveRequest(
2042
+ authorization: ProtectedLoadRequestAuthorizationV1,
2043
+ ) {
2044
+ return withPrimaryDatabase(
2045
+ { correlationId: randomUUID() },
2046
+ 'web-server',
2047
+ async (client) => {
2048
+ await client.query('BEGIN');
2049
+ try {
2050
+ await client.query(
2051
+ \`INSERT INTO performance_load_runs
2052
+ (plan_digest, run_id, adapter_id, scenario_id, stage,
2053
+ source_commit, release_material_digest, maximum_requests,
2054
+ created_at, expires_at)
2055
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9::timestamptz,
2056
+ $10::timestamptz)
2057
+ ON CONFLICT (plan_digest) DO NOTHING\`,
2058
+ [
2059
+ authorization.planMaterialDigest,
2060
+ authorization.runId,
2061
+ authorization.adapterId,
2062
+ authorization.scenarioId,
2063
+ authorization.stage,
2064
+ authorization.release.sourceCommit,
2065
+ authorization.release.releaseMaterialDigest,
2066
+ authorization.maximumRequests,
2067
+ authorization.createdAt,
2068
+ authorization.expiresAt,
2069
+ ],
2070
+ );
2071
+ const run = await client.query<ProtectedPerformanceRunRow>(
2072
+ \`SELECT
2073
+ adapter_id AS "adapterId",
2074
+ cleanup_started_at AS "cleanupStartedAt",
2075
+ created_at AS "createdAt",
2076
+ expires_at AS "expiresAt",
2077
+ maximum_requests AS "maximumRequests",
2078
+ release_material_digest AS "releaseMaterialDigest",
2079
+ run_id AS "runId",
2080
+ scenario_id AS "scenarioId",
2081
+ source_commit AS "sourceCommit",
2082
+ stage
2083
+ FROM performance_load_runs
2084
+ WHERE plan_digest = $1
2085
+ FOR UPDATE\`,
2086
+ [authorization.planMaterialDigest],
2087
+ );
2088
+ const actual = run.rows[0];
2089
+ if (
2090
+ !matchesProtectedPerformanceRun(actual, authorization) ||
2091
+ actual.cleanupStartedAt !== null
2092
+ ) {
2093
+ throw new Error('protected-performance-run-collision');
2094
+ }
2095
+ const claimed = await client.query(
2096
+ \`INSERT INTO performance_load_requests
2097
+ (plan_digest, request_ordinal, effect_id)
2098
+ VALUES ($1, $2, $3)
2099
+ ON CONFLICT (plan_digest, request_ordinal) DO NOTHING\`,
2100
+ [
2101
+ authorization.planMaterialDigest,
2102
+ authorization.requestOrdinal,
2103
+ authorization.effectId,
2104
+ ],
2105
+ );
2106
+ if (claimed.rowCount !== 1) {
2107
+ throw new Error('protected-performance-request-replayed');
2108
+ }
2109
+ await client.query('COMMIT');
2110
+ return 'claimed' as const;
2111
+ } catch (error) {
2112
+ await client.query('ROLLBACK').catch(() => undefined);
2113
+ throw error;
2114
+ }
2115
+ },
2116
+ );
2117
+ }
2118
+
2119
+ export async function databaseExecution(
2120
+ adapterId: 'ebk-async-worker-v1' | 'ebk-database-v1',
2121
+ effectId: string,
2122
+ authorization: ProtectedLoadRequestAuthorizationV1,
2123
+ ) {
2124
+ return withPrimaryDatabase(
2125
+ { correlationId: randomUUID() },
2126
+ 'web-server',
2127
+ async (client) => {
2128
+ await client.query('BEGIN');
2129
+ try {
2130
+ const run = await client.query<ProtectedPerformanceRunRow>(
2131
+ \`SELECT
2132
+ adapter_id AS "adapterId",
2133
+ cleanup_started_at AS "cleanupStartedAt",
2134
+ created_at AS "createdAt",
2135
+ expires_at AS "expiresAt",
2136
+ maximum_requests AS "maximumRequests",
2137
+ release_material_digest AS "releaseMaterialDigest",
2138
+ run_id AS "runId",
2139
+ scenario_id AS "scenarioId",
2140
+ source_commit AS "sourceCommit",
2141
+ stage
2142
+ FROM performance_load_runs
2143
+ WHERE plan_digest = $1
2144
+ FOR UPDATE\`,
2145
+ [authorization.planMaterialDigest],
2146
+ );
2147
+ const activeRun = run.rows[0];
2148
+ if (
2149
+ !matchesProtectedPerformanceRun(activeRun, authorization) ||
2150
+ activeRun.cleanupStartedAt !== null
2151
+ ) {
2152
+ throw new Error('protected-performance-run-cleaning');
2153
+ }
2154
+ if (adapterId === 'ebk-async-worker-v1') {
2155
+ const inserted = await client.query(
2156
+ \`INSERT INTO performance_load_async_effects
2157
+ (effect_id, plan_digest, run_id, expires_at)
2158
+ VALUES ($1, $2, $3, now() + INTERVAL '24 hours')
2159
+ ON CONFLICT (effect_id) DO NOTHING\`,
2160
+ [
2161
+ effectId,
2162
+ authorization.planMaterialDigest,
2163
+ authorization.runId,
2164
+ ],
2165
+ );
2166
+ const identity = await client.query<{
2167
+ planDigest: string;
2168
+ runId: string;
2169
+ }>(
2170
+ \`SELECT
2171
+ plan_digest AS "planDigest",
2172
+ run_id AS "runId"
2173
+ FROM performance_load_async_effects
2174
+ WHERE effect_id = $1\`,
2175
+ [effectId],
2176
+ );
2177
+ if (
2178
+ identity.rows[0]?.planDigest !==
2179
+ authorization.planMaterialDigest ||
2180
+ identity.rows[0]?.runId !== authorization.runId
2181
+ ) {
2182
+ throw new Error('protected-performance-effect-collision');
2183
+ }
2184
+ const pending = await client.query<{ count: string }>(
2185
+ \`SELECT count(*)::text AS count
2186
+ FROM performance_load_async_effects
2187
+ WHERE processed_at IS NULL AND expires_at > now()\`,
2188
+ );
2189
+ const maximum = authorization.configuredMaximum;
2190
+ if (!Number.isFinite(maximum) || maximum <= 0) {
2191
+ throw new Error('protected-performance-async-maximum-invalid');
2192
+ }
2193
+ const result = {
2194
+ effectState:
2195
+ inserted.rowCount === 1
2196
+ ? ('created' as const)
2197
+ : ('already-existed' as const),
2198
+ saturationPercent: Math.min(
2199
+ 100,
2200
+ (Number(pending.rows[0]?.count ?? 0) / maximum) * 100,
2201
+ ),
2202
+ };
2203
+ await client.query('COMMIT');
2204
+ return result;
2205
+ }
2206
+ const id = effectUuid(effectId);
2207
+ const inserted = await client.query(
2208
+ \`INSERT INTO records
2209
+ (id, name, owner_id, run_scope, test_expires_at)
2210
+ VALUES (
2211
+ $1::uuid,
2212
+ 'ebk-protected-performance-load',
2213
+ 'ebk-performance',
2214
+ $2,
2215
+ now() + INTERVAL '24 hours'
2216
+ )
2217
+ ON CONFLICT (id) DO NOTHING\`,
2218
+ [id, authorization.planMaterialDigest],
2219
+ );
2220
+ const identity = await client.query<{
2221
+ name: string;
2222
+ ownerId: string;
2223
+ runScope: string;
2224
+ }>(
2225
+ \`SELECT
2226
+ name,
2227
+ owner_id AS "ownerId",
2228
+ run_scope AS "runScope"
2229
+ FROM records
2230
+ WHERE id = $1::uuid\`,
2231
+ [id],
2232
+ );
2233
+ if (
2234
+ identity.rows[0]?.name !== 'ebk-protected-performance-load' ||
2235
+ identity.rows[0]?.ownerId !== 'ebk-performance' ||
2236
+ identity.rows[0]?.runScope !== authorization.planMaterialDigest
2237
+ ) {
2238
+ throw new Error('protected-performance-effect-collision');
2239
+ }
2240
+ const activity = await client.query<{
2241
+ active: string;
2242
+ maximum: string;
2243
+ }>(
2244
+ \`SELECT
2245
+ count(*)::text AS active,
2246
+ current_setting('max_connections') AS maximum
2247
+ FROM pg_stat_activity
2248
+ WHERE datname = current_database()\`,
2249
+ );
2250
+ const active = Number(activity.rows[0]?.active ?? 0);
2251
+ const maximum = Number(activity.rows[0]?.maximum ?? 0);
2252
+ if (!Number.isFinite(maximum) || maximum <= 0) {
2253
+ throw new Error('protected-performance-database-maximum-invalid');
2254
+ }
2255
+ const result = {
2256
+ effectState:
2257
+ inserted.rowCount === 1
2258
+ ? ('created' as const)
2259
+ : ('already-existed' as const),
2260
+ saturationPercent: Math.min(100, (active / maximum) * 100),
2261
+ };
2262
+ await client.query('COMMIT');
2263
+ return result;
2264
+ } catch (error) {
2265
+ await client.query('ROLLBACK').catch(() => undefined);
2266
+ throw error;
2267
+ }
2268
+ },
2269
+ );
2270
+ }
2271
+
2272
+ export async function cleanupRun(
2273
+ adapterId: 'ebk-async-worker-v1' | 'ebk-database-v1',
2274
+ authorization: ProtectedLoadRequestAuthorizationV1,
2275
+ ) {
2276
+ return withPrimaryDatabase(
2277
+ { correlationId: randomUUID() },
2278
+ 'web-server',
2279
+ async (client) => {
2280
+ await client.query('BEGIN');
2281
+ try {
2282
+ await client.query(
2283
+ \`INSERT INTO performance_load_runs
2284
+ (plan_digest, run_id, adapter_id, scenario_id, stage,
2285
+ source_commit, release_material_digest, maximum_requests,
2286
+ created_at, expires_at, cleanup_started_at)
2287
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9::timestamptz,
2288
+ $10::timestamptz, now())
2289
+ ON CONFLICT (plan_digest) DO NOTHING\`,
2290
+ [
2291
+ authorization.planMaterialDigest,
2292
+ authorization.runId,
2293
+ authorization.adapterId,
2294
+ authorization.scenarioId,
2295
+ authorization.stage,
2296
+ authorization.release.sourceCommit,
2297
+ authorization.release.releaseMaterialDigest,
2298
+ authorization.maximumRequests,
2299
+ authorization.createdAt,
2300
+ authorization.expiresAt,
2301
+ ],
2302
+ );
2303
+ const run = await client.query<ProtectedPerformanceRunRow>(
2304
+ \`SELECT
2305
+ adapter_id AS "adapterId",
2306
+ cleanup_started_at AS "cleanupStartedAt",
2307
+ created_at AS "createdAt",
2308
+ expires_at AS "expiresAt",
2309
+ maximum_requests AS "maximumRequests",
2310
+ release_material_digest AS "releaseMaterialDigest",
2311
+ run_id AS "runId",
2312
+ scenario_id AS "scenarioId",
2313
+ source_commit AS "sourceCommit",
2314
+ stage
2315
+ FROM performance_load_runs
2316
+ WHERE plan_digest = $1
2317
+ FOR UPDATE\`,
2318
+ [authorization.planMaterialDigest],
2319
+ );
2320
+ if (!matchesProtectedPerformanceRun(run.rows[0], authorization)) {
2321
+ throw new Error('protected-performance-run-collision');
2322
+ }
2323
+ await client.query(
2324
+ \`UPDATE performance_load_runs
2325
+ SET cleanup_started_at = COALESCE(cleanup_started_at, now())
2326
+ WHERE plan_digest = $1\`,
2327
+ [authorization.planMaterialDigest],
2328
+ );
2329
+ await client.query('COMMIT');
2330
+ } catch (error) {
2331
+ await client.query('ROLLBACK').catch(() => undefined);
2332
+ throw error;
2333
+ }
2334
+
2335
+ await client.query('BEGIN');
2336
+ try {
2337
+ const removed =
2338
+ adapterId === 'ebk-async-worker-v1'
2339
+ ? await client.query(
2340
+ \`DELETE FROM performance_load_async_effects
2341
+ WHERE plan_digest = $1
2342
+ AND run_id = $2\`,
2343
+ [authorization.planMaterialDigest, authorization.runId],
2344
+ )
2345
+ : await client.query(
2346
+ \`DELETE FROM records
2347
+ WHERE owner_id = 'ebk-performance'
2348
+ AND name = 'ebk-protected-performance-load'
2349
+ AND run_scope = $1\`,
2350
+ [authorization.planMaterialDigest],
2351
+ );
2352
+ const remaining =
2353
+ adapterId === 'ebk-async-worker-v1'
2354
+ ? await client.query<{ count: string }>(
2355
+ \`SELECT count(*)::text AS count
2356
+ FROM performance_load_async_effects
2357
+ WHERE plan_digest = $1
2358
+ AND run_id = $2\`,
2359
+ [authorization.planMaterialDigest, authorization.runId],
2360
+ )
2361
+ : await client.query<{ count: string }>(
2362
+ \`SELECT count(*)::text AS count
2363
+ FROM records
2364
+ WHERE owner_id = 'ebk-performance'
2365
+ AND name = 'ebk-protected-performance-load'
2366
+ AND run_scope = $1\`,
2367
+ [authorization.planMaterialDigest],
2368
+ );
2369
+ const remainingEffectCount = Number(remaining.rows[0]?.count ?? 0);
2370
+ if (
2371
+ !Number.isSafeInteger(remainingEffectCount) ||
2372
+ remainingEffectCount !== 0
2373
+ ) {
2374
+ throw new Error('protected-performance-cleanup-incomplete');
2375
+ }
2376
+ await client.query('COMMIT');
2377
+ return {
2378
+ remainingEffectCount,
2379
+ removedEffectCount: removed.rowCount ?? 0,
2380
+ };
2381
+ } catch (error) {
2382
+ await client.query('ROLLBACK').catch(() => undefined);
2383
+ throw error;
2384
+ }
2385
+ },
2386
+ );
2387
+ }
2388
+
2389
+ function refused() {
2390
+ return Response.json(
2391
+ {
2392
+ kind: 'ebk-protected-load-endpoint-refusal',
2393
+ status: 'not-found',
2394
+ },
2395
+ { status: 404 },
2396
+ );
2397
+ }
2398
+
2399
+ export async function runPerformanceScenarioEndpoint(
2400
+ adapterId: ManagedAdapterId,
2401
+ request: Request,
2402
+ ) {
2403
+ try {
2404
+ const body =
2405
+ request.method === 'POST'
2406
+ ? await boundedRequestBody(request)
2407
+ : undefined;
2408
+ const result = await withEndpointBinding(adapterId, (binding) =>
2409
+ handleProtectedLoadScenarioEndpoint({
2410
+ binding,
2411
+ execute: async ({ authorization, effectId }) => {
2412
+ if (
2413
+ adapterId === 'ebk-async-worker-v1' ||
2414
+ adapterId === 'ebk-database-v1'
2415
+ ) {
2416
+ if (!effectId) throw new Error('protected-effect-required');
2417
+ return databaseExecution(adapterId, effectId, authorization);
2418
+ }
2419
+ return { saturationPercent: memorySaturation() };
2420
+ },
2421
+ request: requestMaterial(request, body),
2422
+ reserve: reserveRequest,
2423
+ }),
2424
+ );
2425
+ return Response.json(result.body, { status: result.status });
2426
+ } catch {
2427
+ return refused();
2428
+ }
2429
+ }
2430
+
2431
+ export async function runPerformanceCleanupEndpoint(
2432
+ adapterId: 'ebk-async-worker-v1' | 'ebk-database-v1',
2433
+ request: Request,
2434
+ ) {
2435
+ try {
2436
+ const body = await boundedRequestBody(request);
2437
+ const result = await withEndpointBinding(adapterId, (binding) =>
2438
+ handleProtectedLoadCleanupEndpoint({
2439
+ binding,
2440
+ cleanup: (authorization) => cleanupRun(adapterId, authorization),
2441
+ request: requestMaterial(request, body),
2442
+ }),
2443
+ );
2444
+ return Response.json(result.body, { status: result.status });
2445
+ } catch {
2446
+ return refused();
2447
+ }
2448
+ }
2449
+ `,
2450
+ 'web/src/app/%5F%5Febk/performance/handler.spec.ts': `import {
2451
+ beforeAll,
2452
+ describe,
2453
+ expect,
2454
+ it,
2455
+ vi,
2456
+ } from 'vitest';
2457
+
2458
+ const mocks = vi.hoisted(() => {
2459
+ const runWithSecret = vi.fn(async ({ operation }) =>
2460
+ operation({
2461
+ current: {
2462
+ id: 'performance-current-v1',
2463
+ secret: 'current-performance-secret-material-0001',
2464
+ },
2465
+ }),
2466
+ );
2467
+ return {
2468
+ createSecretRuntime: vi.fn(() => ({ runWithSecret })),
2469
+ runWithSecret,
2470
+ };
2471
+ });
2472
+
2473
+ vi.mock('server-only', () => ({}));
2474
+ vi.mock('@empire-builder-kit/runtime/performance', () => ({
2475
+ handleProtectedLoadCleanupEndpoint: vi.fn(),
2476
+ handleProtectedLoadScenarioEndpoint: vi.fn(async ({ binding }) => ({
2477
+ body: {
2478
+ candidateDigest: binding.deployedCandidateDigest,
2479
+ kind: 'ebk-protected-load-endpoint-telemetry',
2480
+ status: 'accepted',
2481
+ },
2482
+ status: 200,
2483
+ })),
2484
+ }));
2485
+ vi.mock('../../../../../database/runtime-client', () => ({
2486
+ withPrimaryDatabase: vi.fn(),
2487
+ }));
2488
+ vi.mock('../../../../../secrets/declarations', () => ({
2489
+ Secrets: { ${pascalName}PerformanceLoadHmacKeys: {} },
2490
+ }));
2491
+ vi.mock('../../../../../secrets/runtime', () => ({
2492
+ createStandardSliceSecretRuntime: mocks.createSecretRuntime,
2493
+ }));
2494
+
2495
+ import { runPerformanceScenarioEndpoint } from './handler';
2496
+
2497
+ describe('${name} protected performance secret cache lifetime', () => {
2498
+ beforeAll(() => {
2499
+ process.env.EBK_PERFORMANCE_ACCOUNT_FINGERPRINT =
2500
+ 'sha256:' + 'a'.repeat(64);
2501
+ process.env.EBK_PERFORMANCE_CANDIDATE_DIGEST = 'b'.repeat(64);
2502
+ process.env.EBK_PERFORMANCE_LOAD_ENABLED = 'true';
2503
+ process.env.EBK_PERFORMANCE_ORIGIN =
2504
+ 'https://performance.example.test';
2505
+ process.env.EBK_PERFORMANCE_REGION = 'us-east-1';
2506
+ process.env.EBK_PERFORMANCE_RELEASE_ID = 'release-handler-test';
2507
+ process.env.EBK_PERFORMANCE_RELEASE_MATERIAL_DIGEST = 'd'.repeat(64);
2508
+ process.env.EBK_PERFORMANCE_SLICE = '${name}';
2509
+ process.env.EBK_SOURCE_COMMIT = 'c'.repeat(40);
2510
+ process.env.EBK_STAGE = 'staging';
2511
+ });
2512
+
2513
+ it('reuses one resolver across requests so declaration TTL is effective', async () => {
2514
+ const endpoint =
2515
+ 'https://performance.example.test/${name}/__ebk/performance/api-lambda';
2516
+ await expect(
2517
+ runPerformanceScenarioEndpoint(
2518
+ 'ebk-api-lambda-v1',
2519
+ new Request(endpoint),
2520
+ ),
2521
+ ).resolves.toMatchObject({ status: 200 });
2522
+ await expect(
2523
+ runPerformanceScenarioEndpoint(
2524
+ 'ebk-api-lambda-v1',
2525
+ new Request(endpoint),
2526
+ ),
2527
+ ).resolves.toMatchObject({ status: 200 });
2528
+ expect(mocks.createSecretRuntime).toHaveBeenCalledTimes(1);
2529
+ expect(mocks.runWithSecret).toHaveBeenCalledTimes(2);
2530
+ });
2531
+ });
2532
+ `,
2533
+ 'integration/performance-load-cleanup.spec.ts': `import { Client } from 'pg';
2534
+ import { afterEach, describe, expect, it, vi } from 'vitest';
2535
+ import type { ProtectedLoadRequestAuthorizationV1 } from '@empire-builder-kit/runtime/performance';
2536
+ import { createInboxCleanupHandler } from '../async/inbox-cleanup.js';
2537
+ import {
2538
+ cleanupRun,
2539
+ databaseExecution,
2540
+ reserveRequest,
2541
+ } from '../web/src/app/%5F%5Febk/performance/handler.js';
2542
+
2543
+ vi.mock('server-only', () => ({}));
2544
+ vi.mock('../database/runtime-client.js', () => ({
2545
+ withPrimaryDatabase: async (
2546
+ _context: unknown,
2547
+ _workload: unknown,
2548
+ operation: (client: Client) => Promise<unknown>,
2549
+ ) => {
2550
+ const { Client: RuntimeClient } = await import('pg');
2551
+ const client = new RuntimeClient({
2552
+ connectionString: process.env.DATABASE_URL,
2553
+ });
2554
+ await client.connect();
2555
+ try {
2556
+ return await operation(client);
2557
+ } finally {
2558
+ await client.end();
2559
+ }
2560
+ },
2561
+ }));
2562
+
2563
+ const databaseUrl = process.env.DATABASE_URL;
2564
+ if (!databaseUrl) {
2565
+ throw new Error(
2566
+ 'DATABASE_URL is required for ${name} performance cleanup integration proof.',
2567
+ );
2568
+ }
2569
+
2570
+ const touchedPlanDigests = new Set<string>();
2571
+
2572
+ function authorization(input: {
2573
+ effectId: string | null;
2574
+ operation: 'cleanup' | 'execute';
2575
+ planMaterialDigest: string;
2576
+ requestOrdinal?: number;
2577
+ }): ProtectedLoadRequestAuthorizationV1 {
2578
+ return {
2579
+ adapterId: 'ebk-async-worker-v1',
2580
+ configuredMaximum: 100,
2581
+ createdAt: '2026-07-29T12:00:00.000Z',
2582
+ durationSeconds: 60,
2583
+ effectId: input.effectId,
2584
+ expiresAt: '2026-07-29T13:00:00.000Z',
2585
+ hmacKeyId: 'integration-v1',
2586
+ maximumRequests: 10,
2587
+ operation: input.operation,
2588
+ planMaterialDigest: input.planMaterialDigest,
2589
+ release: {
2590
+ candidateDigest: 'c'.repeat(64),
2591
+ releaseId: 'integration-release',
2592
+ releaseMaterialDigest: 'd'.repeat(64),
2593
+ sourceCommit: 'b'.repeat(40),
2594
+ },
2595
+ requestOrdinal: input.requestOrdinal ?? 1,
2596
+ runId: 'integration-run-' + input.planMaterialDigest.slice(0, 8),
2597
+ saturationSignalRef:
2598
+ 'database:protected-async-backlog-utilization-percent',
2599
+ scenarioId: 'async-burst',
2600
+ stage: 'staging',
2601
+ target: {
2602
+ accountFingerprint: 'sha256:' + 'e'.repeat(64),
2603
+ endpoint:
2604
+ 'https://performance.example.test/${name}/__ebk/performance/async-worker',
2605
+ region: 'us-east-1',
2606
+ slice: '${name}',
2607
+ },
2608
+ workload: 'async-worker',
2609
+ };
2610
+ }
2611
+
2612
+ async function withClient<Result>(
2613
+ operation: (client: Client) => Promise<Result>,
2614
+ ): Promise<Result> {
2615
+ const client = new Client({ connectionString: databaseUrl });
2616
+ await client.connect();
2617
+ try {
2618
+ return await operation(client);
2619
+ } finally {
2620
+ await client.end();
2621
+ }
2622
+ }
2623
+
2624
+ // A loaded-host budget: hosted runners share four cores between Vitest,
2625
+ // the proof registry, and the dockerized database.
2626
+ async function waitForActiveStatement(
2627
+ client: Client,
2628
+ fragment: string,
2629
+ ): Promise<void> {
2630
+ const deadline = Date.now() + 15_000;
2631
+ while (Date.now() < deadline) {
2632
+ const active = await client.query<{ count: string }>(
2633
+ \`SELECT count(*)::text AS count
2634
+ FROM pg_stat_activity
2635
+ WHERE datname = current_database()
2636
+ AND pid <> pg_backend_pid()
2637
+ AND state = 'active'
2638
+ AND query LIKE $1\`,
2639
+ ['%' + fragment + '%'],
2640
+ );
2641
+ if (Number(active.rows[0]?.count ?? 0) > 0) return;
2642
+ await new Promise((resolve) => setTimeout(resolve, 10));
2643
+ }
2644
+ throw new Error('Timed out waiting for the adversarial database statement.');
2645
+ }
2646
+
2647
+ afterEach(async () => {
2648
+ await withClient(async (client) => {
2649
+ await client
2650
+ .query(
2651
+ 'DROP TRIGGER IF EXISTS ebk_performance_delay_effect ON performance_load_async_effects',
2652
+ )
2653
+ .catch(() => undefined);
2654
+ await client
2655
+ .query('DROP FUNCTION IF EXISTS ebk_performance_delay_effect()')
2656
+ .catch(() => undefined);
2657
+ for (const planDigest of touchedPlanDigests) {
2658
+ await client.query('DELETE FROM records WHERE run_scope = $1', [
2659
+ planDigest,
2660
+ ]);
2661
+ await client.query(
2662
+ 'DELETE FROM performance_load_async_effects WHERE plan_digest = $1',
2663
+ [planDigest],
2664
+ );
2665
+ await client.query(
2666
+ 'DELETE FROM performance_load_requests WHERE plan_digest = $1',
2667
+ [planDigest],
2668
+ );
2669
+ await client.query(
2670
+ 'DELETE FROM performance_load_runs WHERE plan_digest = $1',
2671
+ [planDigest],
2672
+ );
2673
+ }
2674
+ await client.query(
2675
+ "DELETE FROM cleanup_deadline_reports WHERE feature = 'performance-load'",
2676
+ );
2677
+ });
2678
+ touchedPlanDigests.clear();
2679
+ });
2680
+
2681
+ describe('${name} protected performance cleanup integration', () => {
2682
+ it('serializes cleanup behind an in-flight effect and rejects every late effect', async () => {
2683
+ const planMaterialDigest = '1'.repeat(64);
2684
+ const effectId = '2'.repeat(64);
2685
+ touchedPlanDigests.add(planMaterialDigest);
2686
+ const executeAuthorization = authorization({
2687
+ effectId,
2688
+ operation: 'execute',
2689
+ planMaterialDigest,
2690
+ });
2691
+ const cleanupAuthorization = authorization({
2692
+ effectId: null,
2693
+ operation: 'cleanup',
2694
+ planMaterialDigest,
2695
+ });
2696
+
2697
+ await reserveRequest(executeAuthorization);
2698
+ await withClient(async (client) => {
2699
+ await client.query(
2700
+ \`CREATE OR REPLACE FUNCTION ebk_performance_delay_effect()
2701
+ RETURNS trigger
2702
+ LANGUAGE plpgsql
2703
+ AS $$
2704
+ BEGIN
2705
+ PERFORM pg_sleep(1);
2706
+ RETURN NEW;
2707
+ END
2708
+ $$\`,
2709
+ );
2710
+ await client.query(
2711
+ \`CREATE TRIGGER ebk_performance_delay_effect
2712
+ BEFORE INSERT ON performance_load_async_effects
2713
+ FOR EACH ROW EXECUTE FUNCTION ebk_performance_delay_effect()\`,
2714
+ );
2715
+ });
2716
+
2717
+ const observer = new Client({ connectionString: databaseUrl });
2718
+ await observer.connect();
2719
+ try {
2720
+ const effect = databaseExecution(
2721
+ 'ebk-async-worker-v1',
2722
+ effectId,
2723
+ executeAuthorization,
2724
+ );
2725
+ await waitForActiveStatement(
2726
+ observer,
2727
+ 'INSERT INTO performance_load_async_effects',
2728
+ );
2729
+ const cleanup = cleanupRun(
2730
+ 'ebk-async-worker-v1',
2731
+ cleanupAuthorization,
2732
+ );
2733
+ await expect(effect).resolves.toMatchObject({ effectState: 'created' });
2734
+ await expect(cleanup).resolves.toEqual({
2735
+ remainingEffectCount: 0,
2736
+ removedEffectCount: 1,
2737
+ });
2738
+ } finally {
2739
+ await observer.end();
2740
+ }
2741
+
2742
+ await expect(
2743
+ databaseExecution(
2744
+ 'ebk-async-worker-v1',
2745
+ '3'.repeat(64),
2746
+ {
2747
+ ...executeAuthorization,
2748
+ effectId: '3'.repeat(64),
2749
+ requestOrdinal: 2,
2750
+ },
2751
+ ),
2752
+ ).rejects.toThrow('protected-performance-run-cleaning');
2753
+ await expect(
2754
+ reserveRequest({
2755
+ ...executeAuthorization,
2756
+ effectId: '3'.repeat(64),
2757
+ requestOrdinal: 2,
2758
+ }),
2759
+ ).rejects.toThrow('protected-performance-run-collision');
2760
+
2761
+ await withClient(async (client) => {
2762
+ const state = await client.query<{
2763
+ cleanupStarted: boolean;
2764
+ effects: string;
2765
+ }>(
2766
+ \`SELECT
2767
+ run.cleanup_started_at IS NOT NULL AS "cleanupStarted",
2768
+ (
2769
+ SELECT count(*)::text
2770
+ FROM performance_load_async_effects AS effect
2771
+ WHERE effect.plan_digest = run.plan_digest
2772
+ ) AS effects
2773
+ FROM performance_load_runs AS run
2774
+ WHERE run.plan_digest = $1\`,
2775
+ [planMaterialDigest],
2776
+ );
2777
+ expect(state.rows).toEqual([
2778
+ { cleanupStarted: true, effects: '0' },
2779
+ ]);
2780
+ });
2781
+ });
2782
+
2783
+ it('tombstones and proves an effect-free run absent without a local ledger', async () => {
2784
+ const planMaterialDigest = '4'.repeat(64);
2785
+ touchedPlanDigests.add(planMaterialDigest);
2786
+ const cleanupAuthorization = authorization({
2787
+ effectId: null,
2788
+ operation: 'cleanup',
2789
+ planMaterialDigest,
2790
+ });
2791
+
2792
+ await expect(
2793
+ cleanupRun('ebk-async-worker-v1', cleanupAuthorization),
2794
+ ).resolves.toEqual({
2795
+ remainingEffectCount: 0,
2796
+ removedEffectCount: 0,
2797
+ });
2798
+ await expect(
2799
+ cleanupRun('ebk-async-worker-v1', cleanupAuthorization),
2800
+ ).resolves.toEqual({
2801
+ remainingEffectCount: 0,
2802
+ removedEffectCount: 0,
2803
+ });
2804
+ await expect(
2805
+ reserveRequest({
2806
+ ...cleanupAuthorization,
2807
+ effectId: '5'.repeat(64),
2808
+ operation: 'execute',
2809
+ }),
2810
+ ).rejects.toThrow('protected-performance-run-collision');
2811
+ });
2812
+
2813
+ it('expires only framework-owned due rows and retains fresh audit state', async () => {
2814
+ const oldPlan = '6'.repeat(64);
2815
+ const freshPlan = '7'.repeat(64);
2816
+ const expiredEffectPlan = '8'.repeat(64);
2817
+ const freshEffectPlan = '9'.repeat(64);
2818
+ for (const digest of [
2819
+ oldPlan,
2820
+ freshPlan,
2821
+ expiredEffectPlan,
2822
+ freshEffectPlan,
2823
+ ]) {
2824
+ touchedPlanDigests.add(digest);
2825
+ }
2826
+ const expiredRecordId = '10000000-0000-4000-8000-000000000001';
2827
+ const freshRecordId = '10000000-0000-4000-8000-000000000002';
2828
+ const adopterRecordId = '10000000-0000-4000-8000-000000000003';
2829
+
2830
+ await withClient(async (client) => {
2831
+ await client.query(
2832
+ \`INSERT INTO performance_load_runs
2833
+ (plan_digest, run_id, adapter_id, scenario_id, stage,
2834
+ source_commit, release_material_digest, maximum_requests,
2835
+ created_at, expires_at)
2836
+ VALUES
2837
+ ($1, 'old-run', 'ebk-async-worker-v1', 'async-burst', 'staging',
2838
+ $3, $4, 10, now() - INTERVAL '32 days',
2839
+ now() - INTERVAL '31 days'),
2840
+ ($2, 'fresh-run', 'ebk-async-worker-v1', 'async-burst', 'staging',
2841
+ $3, $4, 10, now() - INTERVAL '30 days',
2842
+ now() - INTERVAL '29 days')\`,
2843
+ [oldPlan, freshPlan, 'b'.repeat(40), 'd'.repeat(64)],
2844
+ );
2845
+ await client.query(
2846
+ \`INSERT INTO performance_load_requests
2847
+ (plan_digest, request_ordinal, effect_id)
2848
+ VALUES ($1, 1, NULL), ($2, 1, NULL)\`,
2849
+ [oldPlan, freshPlan],
2850
+ );
2851
+ await client.query(
2852
+ \`INSERT INTO performance_load_async_effects
2853
+ (effect_id, plan_digest, run_id, expires_at)
2854
+ VALUES
2855
+ ($1, $2, 'expired', now() - INTERVAL '1 minute'),
2856
+ ($3, $4, 'fresh', now() + INTERVAL '1 day')\`,
2857
+ ['a'.repeat(64), expiredEffectPlan, 'f'.repeat(64), freshEffectPlan],
2858
+ );
2859
+ await client.query(
2860
+ \`INSERT INTO records
2861
+ (id, name, owner_id, run_scope, test_expires_at)
2862
+ VALUES
2863
+ ($1::uuid, 'ebk-protected-performance-load', 'ebk-performance',
2864
+ $4, now() - INTERVAL '1 minute'),
2865
+ ($2::uuid, 'ebk-protected-performance-load', 'ebk-performance',
2866
+ $5, now() + INTERVAL '1 day'),
2867
+ ($3::uuid, 'adopter-performance-data', 'adopter-owner',
2868
+ $4, now() - INTERVAL '1 minute')\`,
2869
+ [
2870
+ expiredRecordId,
2871
+ freshRecordId,
2872
+ adopterRecordId,
2873
+ expiredEffectPlan,
2874
+ freshEffectPlan,
2875
+ ],
2876
+ );
2877
+ });
2878
+
2879
+ const emitted: Array<{ metricName?: string; value?: number }> = [];
2880
+ const handler = createInboxCleanupHandler({
2881
+ logger: {
2882
+ error: vi.fn(),
2883
+ info: vi.fn(),
2884
+ } as never,
2885
+ metrics: {
2886
+ emit: (metric: { metricName?: string; value?: number }) => {
2887
+ emitted.push(metric);
2888
+ return {} as never;
2889
+ },
2890
+ } as never,
2891
+ now: Date.now,
2892
+ withDatabase: (async (
2893
+ _context: unknown,
2894
+ _workload: unknown,
2895
+ operation: (client: Client) => Promise<unknown>,
2896
+ ) => withClient(operation)) as never,
2897
+ });
2898
+ await expect(handler({ id: 'performance-expiry-proof' })).resolves.toMatchObject({
2899
+ performanceAuditRetentionDays: 30,
2900
+ performanceCleanupDeadlineHours: 24,
2901
+ reportedPerformanceDeadlineBreaches: 0,
2902
+ remainingPerformanceExpired: 0,
2903
+ removedPerformance: 4,
2904
+ });
2905
+ expect(emitted).toContainEqual(
2906
+ expect.objectContaining({
2907
+ metricName: 'PerformanceLoadCleanupBacklog',
2908
+ value: 0,
2909
+ }),
2910
+ );
2911
+ expect(emitted).toContainEqual(
2912
+ expect.objectContaining({
2913
+ metricName: 'PerformanceLoadCleanupDeadlineBreaches',
2914
+ value: 0,
2915
+ }),
2916
+ );
2917
+
2918
+ await withClient(async (client) => {
2919
+ const effects = await client.query<{ planDigest: string }>(
2920
+ \`SELECT plan_digest AS "planDigest"
2921
+ FROM performance_load_async_effects
2922
+ WHERE plan_digest = ANY($1::text[])
2923
+ ORDER BY plan_digest\`,
2924
+ [[expiredEffectPlan, freshEffectPlan]],
2925
+ );
2926
+ expect(effects.rows).toEqual([{ planDigest: freshEffectPlan }]);
2927
+ const records = await client.query<{ id: string }>(
2928
+ \`SELECT id::text AS id
2929
+ FROM records
2930
+ WHERE id = ANY($1::uuid[])
2931
+ ORDER BY id\`,
2932
+ [[expiredRecordId, freshRecordId, adopterRecordId]],
2933
+ );
2934
+ expect(records.rows).toEqual([
2935
+ { id: freshRecordId },
2936
+ { id: adopterRecordId },
2937
+ ]);
2938
+ const audits = await client.query<{
2939
+ planDigest: string;
2940
+ requests: string;
2941
+ }>(
2942
+ \`SELECT
2943
+ run.plan_digest AS "planDigest",
2944
+ count(request.request_ordinal)::text AS requests
2945
+ FROM performance_load_runs AS run
2946
+ LEFT JOIN performance_load_requests AS request
2947
+ ON request.plan_digest = run.plan_digest
2948
+ WHERE run.plan_digest = ANY($1::text[])
2949
+ GROUP BY run.plan_digest
2950
+ ORDER BY run.plan_digest\`,
2951
+ [[oldPlan, freshPlan]],
2952
+ );
2953
+ expect(audits.rows).toEqual([
2954
+ { planDigest: freshPlan, requests: '1' },
2955
+ ]);
2956
+ });
2957
+ });
2958
+
2959
+ it('durably retries deadline telemetry after deleting stale protected residue', async () => {
2960
+ const stalePlan = 'a'.repeat(64);
2961
+ const staleEffectId = 'b'.repeat(64);
2962
+ const atDeadlinePlan = 'c'.repeat(64);
2963
+ const atDeadlineEffectId = 'd'.repeat(64);
2964
+ const beforeDeadlinePlan = 'e'.repeat(64);
2965
+ const beforeDeadlineEffectId = 'f'.repeat(64);
2966
+ const staleRecordId = '10000000-0000-4000-8000-000000000004';
2967
+ for (const planDigest of [
2968
+ stalePlan,
2969
+ atDeadlinePlan,
2970
+ beforeDeadlinePlan,
2971
+ ]) {
2972
+ touchedPlanDigests.add(planDigest);
2973
+ }
2974
+ await withClient(async (client) => {
2975
+ await client.query(
2976
+ \`INSERT INTO performance_load_async_effects
2977
+ (effect_id, plan_digest, run_id, expires_at)
2978
+ VALUES
2979
+ ($1, $2, 'stale-deadline',
2980
+ clock_timestamp() - INTERVAL '25 hours'),
2981
+ ($3, $4, 'exact-deadline',
2982
+ clock_timestamp() - INTERVAL '24 hours'),
2983
+ ($5, $6, 'before-deadline',
2984
+ clock_timestamp() - INTERVAL '23 hours 59 minutes')\`,
2985
+ [
2986
+ staleEffectId,
2987
+ stalePlan,
2988
+ atDeadlineEffectId,
2989
+ atDeadlinePlan,
2990
+ beforeDeadlineEffectId,
2991
+ beforeDeadlinePlan,
2992
+ ],
2993
+ );
2994
+ await client.query(
2995
+ \`INSERT INTO records
2996
+ (id, name, owner_id, run_scope, test_expires_at)
2997
+ VALUES ($1::uuid, 'ebk-protected-performance-load',
2998
+ 'ebk-performance', $2, now() - INTERVAL '25 hours')\`,
2999
+ [staleRecordId, stalePlan],
3000
+ );
3001
+ });
3002
+
3003
+ const failedEmissions: Array<{ metricName?: string; value?: number }> = [];
3004
+ const failedHandler = createInboxCleanupHandler({
3005
+ logger: { error: vi.fn(), info: vi.fn() } as never,
3006
+ metrics: {
3007
+ emit: (metric: { metricName?: string; value?: number }) => {
3008
+ failedEmissions.push(metric);
3009
+ return metric.metricName ===
3010
+ 'PerformanceLoadCleanupDeadlineBreaches'
3011
+ ? undefined
3012
+ : ({} as never);
3013
+ },
3014
+ } as never,
3015
+ now: Date.now,
3016
+ withDatabase: (async (
3017
+ _context: unknown,
3018
+ _workload: unknown,
3019
+ operation: (client: Client) => Promise<unknown>,
3020
+ ) => withClient(operation)) as never,
3021
+ });
3022
+ await expect(
3023
+ failedHandler({ id: 'performance-deadline-report-failure' }),
3024
+ ).rejects.toThrow('Performance cleanup deadline metric delivery failed.');
3025
+
3026
+ await withClient(async (client) => {
3027
+ const state = await client.query<{
3028
+ effects: string;
3029
+ records: string;
3030
+ reports: string;
3031
+ resourceRefs: string[];
3032
+ }>(
3033
+ \`SELECT
3034
+ (SELECT count(*)::text
3035
+ FROM performance_load_async_effects
3036
+ WHERE effect_id = ANY($1::text[])) AS effects,
3037
+ (SELECT count(*)::text
3038
+ FROM records
3039
+ WHERE id = $2::uuid) AS records,
3040
+ (SELECT count(*)::text
3041
+ FROM cleanup_deadline_reports
3042
+ WHERE feature = 'performance-load') AS reports,
3043
+ (SELECT array_agg(resource_ref ORDER BY resource_ref)
3044
+ FROM cleanup_deadline_reports
3045
+ WHERE feature = 'performance-load') AS "resourceRefs"\`,
3046
+ [
3047
+ [staleEffectId, atDeadlineEffectId, beforeDeadlineEffectId],
3048
+ staleRecordId,
3049
+ ],
3050
+ );
3051
+ expect(state.rows).toEqual([
3052
+ {
3053
+ effects: '0',
3054
+ records: '0',
3055
+ reports: '3',
3056
+ resourceRefs: [
3057
+ 'async-effect:' + staleEffectId,
3058
+ 'async-effect:' + atDeadlineEffectId,
3059
+ 'record:' + staleRecordId,
3060
+ ].sort(),
3061
+ },
3062
+ ]);
3063
+ });
3064
+ expect(JSON.stringify(failedEmissions)).not.toContain(staleEffectId);
3065
+ expect(JSON.stringify(failedEmissions)).not.toContain(staleRecordId);
3066
+ expect(JSON.stringify(failedEmissions)).not.toContain(atDeadlineEffectId);
3067
+ expect(JSON.stringify(failedEmissions)).not.toContain(
3068
+ beforeDeadlineEffectId,
3069
+ );
3070
+
3071
+ const retryEmissions: Array<{ metricName?: string; value?: number }> = [];
3072
+ const retryHandler = createInboxCleanupHandler({
3073
+ logger: { error: vi.fn(), info: vi.fn() } as never,
3074
+ metrics: {
3075
+ emit: (metric: { metricName?: string; value?: number }) => {
3076
+ retryEmissions.push(metric);
3077
+ return {} as never;
3078
+ },
3079
+ } as never,
3080
+ now: Date.now,
3081
+ withDatabase: (async (
3082
+ _context: unknown,
3083
+ _workload: unknown,
3084
+ operation: (client: Client) => Promise<unknown>,
3085
+ ) => withClient(operation)) as never,
3086
+ });
3087
+ await expect(
3088
+ retryHandler({ id: 'performance-deadline-report-retry' }),
3089
+ ).rejects.toThrow('performance-load-cleanup-deadline-breached');
3090
+ expect(retryEmissions).toContainEqual(
3091
+ expect.objectContaining({
3092
+ metricName: 'PerformanceLoadCleanupDeadlineBreaches',
3093
+ value: 3,
3094
+ }),
3095
+ );
3096
+ expect(JSON.stringify(retryEmissions)).not.toContain(staleEffectId);
3097
+ expect(JSON.stringify(retryEmissions)).not.toContain(staleRecordId);
3098
+ expect(JSON.stringify(retryEmissions)).not.toContain(atDeadlineEffectId);
3099
+ expect(JSON.stringify(retryEmissions)).not.toContain(
3100
+ beforeDeadlineEffectId,
3101
+ );
3102
+
3103
+ await withClient(async (client) => {
3104
+ const reports = await client.query<{ count: string }>(
3105
+ \`SELECT count(*)::text AS count
3106
+ FROM cleanup_deadline_reports
3107
+ WHERE feature = 'performance-load'\`,
3108
+ );
3109
+ expect(reports.rows).toEqual([{ count: '0' }]);
3110
+ });
3111
+ await expect(
3112
+ retryHandler({ id: 'performance-deadline-after-ack' }),
3113
+ ).resolves.toMatchObject({ reportedPerformanceDeadlineBreaches: 0 });
3114
+ });
3115
+ });
3116
+ `,
3117
+ 'web/src/app/%5F%5Febk/performance/api-lambda/route.ts': `import 'server-only';
3118
+ import { runPerformanceScenarioEndpoint } from '../handler';
3119
+
3120
+ export function GET(request: Request) {
3121
+ return runPerformanceScenarioEndpoint('ebk-api-lambda-v1', request);
3122
+ }
3123
+ `,
3124
+ 'web/src/app/%5F%5Febk/performance/async-worker/route.ts': `import 'server-only';
3125
+ import { runPerformanceScenarioEndpoint } from '../handler';
3126
+
3127
+ export function POST(request: Request) {
3128
+ return runPerformanceScenarioEndpoint('ebk-async-worker-v1', request);
3129
+ }
3130
+ `,
3131
+ 'web/src/app/%5F%5Febk/performance/async-worker/cleanup/route.ts': `import 'server-only';
3132
+ import { runPerformanceCleanupEndpoint } from '../../handler';
3133
+
3134
+ export function POST(request: Request) {
3135
+ return runPerformanceCleanupEndpoint('ebk-async-worker-v1', request);
3136
+ }
3137
+ `,
3138
+ 'web/src/app/%5F%5Febk/performance/database/route.ts': `import 'server-only';
3139
+ import { runPerformanceScenarioEndpoint } from '../handler';
3140
+
3141
+ export function POST(request: Request) {
3142
+ return runPerformanceScenarioEndpoint('ebk-database-v1', request);
3143
+ }
3144
+ `,
3145
+ 'web/src/app/%5F%5Febk/performance/database/cleanup/route.ts': `import 'server-only';
3146
+ import { runPerformanceCleanupEndpoint } from '../../handler';
3147
+
3148
+ export function POST(request: Request) {
3149
+ return runPerformanceCleanupEndpoint('ebk-database-v1', request);
3150
+ }
3151
+ `,
3152
+ 'docs/runbooks/performance-capacity-cost.md': `# Performance, capacity, and cost
3153
+
3154
+ The generated policy is deliberately an unadopted seed. Replace example budgets,
3155
+ unknown capacity values, owner, review date, and allocation drivers from actual
3156
+ product requirements before protected promotion. Reliability remains authority
3157
+ for journey/SLO, alarm, and routing semantics; release and repository policy
3158
+ remain authority for candidate and production-profile identity. The performance
3159
+ contract consumes those files through explicit hooks and does not duplicate
3160
+ their schemas.
3161
+
3162
+ Keep warm/cold and cache hit/miss populations separate. Record p50, p95, and p99
3163
+ where meaningful, achieved throughput, the first exhausted dependency, quota
3164
+ headroom, and the scenario/tool/network limits. Estimates, test measurements,
3165
+ and delayed actual billing are different provenance classes. Never label a
3166
+ forecast or staging measurement as production actual.
3167
+
3168
+ Local commands can validate policy, budgets, capacity, and tag coverage. They
3169
+ cannot run protected load. The protected workflow must call
3170
+ \`performance-load-guard.mjs\` immediately before an allowlisted runner and
3171
+ must bind the exact candidate, target account, Region, endpoint, maximum
3172
+ concurrency/rate/requests/duration/cost, stop conditions, cleanup, and emergency
3173
+ termination. Production load is exceptional and requires explicit human
3174
+ evidence; prefer staging, synthetics, canaries, and production observation.
3175
+ The three base-Slice managed adapters use fixed API/Lambda, async-worker, and database
3176
+ request/cleanup paths. They remain disabled unless the deployed staging
3177
+ environment binds the exact plan, run, release, source commit, scenario, signal,
3178
+ adapter, exact Slice URL, and deployment-bound HMAC key ID. The workflow obtains
3179
+ only the current per-Slice signer from the exact AWSCURRENT Secrets Manager
3180
+ generation after OIDC target verification. Each response must return an
3181
+ exact-release JSON telemetry envelope for its reviewed saturation signal.
3182
+ Adding a generated Service promotes its reserved scenario to the managed
3183
+ Service runtime endpoint, exact per-task admission signal, and cleanup ledger;
3184
+ before that generator runs, Service load remains explicitly blocked.
3185
+ Next/Lambda heap data is never relabeled as Service evidence. The runner
3186
+ computes estimated test cost from the reviewed per-request
3187
+ scenario value; target headers are never cost authority. Async and database
3188
+ adapters persist a deterministic cleanup identity before each request and
3189
+ cleanup must prove every identity absent, including after a runner crash.
3190
+ The plan target is the exact fixed adapter request URL—not merely an origin or
3191
+ base path—so target approval and the URL actually exercised remain identical.
3192
+ The scenario signal must resolve exactly one capacity resource in the
3193
+ plan-bound policy; the report binds the adapter and complete scenario-contract
3194
+ digest so changed cost, signal, or adoption material cannot reuse evidence.
3195
+
3196
+ ## Performance load HMAC rotation
3197
+
3198
+ The HMAC secret is scoped to one Slice and contains exact \`current\` and
3199
+ optional \`previous\` records. The endpoint keeps one resolver for the deployed
3200
+ web workload, caches a successful AWSCURRENT read for at most one second, and
3201
+ has no stale fallback. Execution accepts only \`current\`; cleanup accepts
3202
+ \`current\` or the immediately previous generation so an interrupted old run
3203
+ can remove its effects. This control-plane read rate and the corresponding
3204
+ Secrets Manager request cost belong in the load cost model.
3205
+
3206
+ Each \`secret\` is the canonical unpadded base64url encoding of exactly 32
3207
+ cryptographically random bytes (43 characters). Generate a new value with a
3208
+ reviewed cryptographic random-byte source; a long passphrase, repeated text, or
3209
+ arbitrary 32-character string is rejected.
3210
+
3211
+ For routine rotation, disable new performance runs, publish
3212
+ \`{ current: new, previous: old }\`, deploy, and prove every endpoint observes
3213
+ the new key within the one-second cache bound. Then switch the protected signer
3214
+ to the new current key and re-enable new runs. Retain previous until all jobs
3215
+ signed by it are terminal, cleanup and expiry backlogs are zero, and both the
3216
+ 24-hour authorization window and subsequent 24-hour cleanup window have
3217
+ elapsed. Do not start another rotation or retire previous during that overlap.
3218
+ The hourly worker measures residue at least 24 hours past its
3219
+ eligible expiry, emits \`PerformanceLoadCleanupDeadlineBreaches\`, and fails the
3220
+ invocation so the dedicated alarm cannot silently clear. This is an executable
3221
+ deadline-violation signal, not a claim that deletion succeeds through an AWS or
3222
+ database outage. Previous-key retirement remains a protected operator action;
3223
+ operators must not retire it while either cleanup metric is nonzero.
3224
+ For suspected compromise, disable the workflow and endpoint first, rotate,
3225
+ redeploy, and investigate before restoring access.
3226
+
3227
+ Evidence retains only the bounded HMAC key ID. Never log, hash, upload, or place
3228
+ the secret in GitHub environment output. Live rotation evidence must show
3229
+ current execution succeeds, previous execution fails, previous cleanup
3230
+ succeeds, retired cleanup fails, cross-Slice substitution fails, and no secret
3231
+ sentinel appears in logs or retained artifacts.
3232
+
3233
+ ## AWS cost controls
3234
+
3235
+ Protected deployments fail until the seeded cost policy names a real owner, a
3236
+ future review instant, and declares the account, pilot, anomaly, notification,
3237
+ and per-test values adopted. Stable v1 provisions these controls only in the
3238
+ commercial \`aws\` partition, where the workload account is also the billing
3239
+ authority. GovCloud, China, and isolated partitions fail before resource
3240
+ construction; a separately modeled commercial billing-account provider is
3241
+ required before those partitions can adopt this path. The protected Foundation
3242
+ stack is the sole owner of the account monthly actual/forecast Budget. It
3243
+ publishes the exact policy digest and monthly maximum through Foundation
3244
+ discovery. Every protected Product plan must bind both and adopt the same
3245
+ maximum before creating a cost resource. The production Product stack creates
3246
+ only the Slice-tag-filtered custom Cost Anomaly monitor plus its immediate SNS
3247
+ subscription. The custom monitor avoids the
3248
+ one-per-account dimensional-monitor collision when several Slices coexist. The
3249
+ staging Product stack creates the lower pilot monthly Budget filtered to the exact
3250
+ \`ebk:slice\` and \`ebk:stage=staging\` allocation tags. Personal and
3251
+ development stages create none of these global billing resources.
3252
+
3253
+ Both Budgets and the anomaly subscription route only to the Foundation alert
3254
+ topic and retain the policy digest, semantic route, and named owner in resource
3255
+ tags. The Foundation topic policy must allow only \`sns:Publish\` from
3256
+ \`budgets.amazonaws.com\`, \`costalerts.amazonaws.com\`, and its existing RDS
3257
+ events publisher. These controls notify; generated infrastructure contains no
3258
+ BudgetAction, auto-adjustment, stop, throttle, IAM-policy change, or other
3259
+ automatic spend-changing response. Investigate through the named owner and
3260
+ runbook, then use a separately approved owning tool for any intervention.
3261
+
3262
+ Every supported resource must carry the bounded workspace/Slice/stage/owner/
3263
+ repository/profile/managed-by/framework tags where AWS supports them.
3264
+ Unsupported resources remain visible with a reason and shared-cost allocation
3265
+ reference. Never use feature, user, tenant, request, work-item, payload, or raw
3266
+ error identifiers as resource tags or metric dimensions.
3267
+ Tag coverage compares observations with a nonempty exact resource inventory
3268
+ derived from deployment plan/state and bound to the same release; an empty,
3269
+ omitted, extra, or cross-release inventory fails. The external cost collection
3270
+ contract names its adopter-owned read-only collector and requires canonical
3271
+ closed-window AWS Cost Explorer allocation and total queries. Evidence binds
3272
+ the STS-derived account fingerprint, Region, stage, workspace, Slice, period,
3273
+ release/source, request identities, response digests, reconciled allocation
3274
+ rows, and independently sourced aggregate-count evidence. Generation does not
3275
+ manufacture live cost values.
3276
+ The managed PR budget derives its observation directly from the completed
3277
+ Next.js client artifact and does not consume caller-authored measurements.
3278
+ Adopter performance budgets remain a separate readiness and exact-release
3279
+ evaluation. Unit-cost evaluation validates baseline and current billing
3280
+ evidence before it accepts observations. Each of the two capability
3281
+ observations must name the exact allocation and aggregate identifiers, amounts,
3282
+ counts, evidence digests, account, Region, stage, workspace, Slice, period, and
3283
+ release from that validated evidence; clean generation reports the missing live
3284
+ evidence as incomplete.
3285
+
3286
+ The generated scenarios cover API/Lambda, async worker, database cold resume,
3287
+ and a Service extension that becomes managed when its Service is generated,
3288
+ but are disabled until deliberately adopted. A clean generated Slice therefore reports incomplete rather than
3289
+ claiming capacity, cost, or live load evidence.
3290
+ `,
3291
+ };
3292
+ }
3293
+ //# sourceMappingURL=built-in-plan-performance-files.js.map