@empire-builder-kit/nx 1.0.0-rc.37 → 1.0.0-rc.39

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 (637) hide show
  1. package/README.md +18 -0
  2. package/executors.json +5 -0
  3. package/generators.json +10 -0
  4. package/package.json +20 -3
  5. package/src/aws-authority/index.d.ts +1 -0
  6. package/src/aws-authority/index.js +1 -0
  7. package/src/aws-authority/lambda-policy-ordering.d.ts +38 -0
  8. package/src/aws-authority/lambda-policy-ordering.js +56 -0
  9. package/src/aws-authority/stage-authority.d.ts +11 -3
  10. package/src/aws-authority/stage-authority.js +615 -29
  11. package/src/blueprints/external-sandbox.js +21 -9
  12. package/src/blueprints/manifest.d.ts +1 -1
  13. package/src/blueprints/resolver.js +28 -15
  14. package/src/cli/bootstrap.d.ts +1 -1
  15. package/src/cli/deploy-runtime.d.ts +6 -0
  16. package/src/cli/deploy-runtime.js +58 -0
  17. package/src/cli/dev-command.d.ts +16 -4
  18. package/src/cli/dev-command.js +63 -0
  19. package/src/cli/main.d.ts +7 -1
  20. package/src/cli/main.js +128 -20
  21. package/src/cli/output.d.ts +1 -1
  22. package/src/developer-agent/context.js +41 -9
  23. package/src/developer-agent/generator-planning.js +16 -2
  24. package/src/developer-agent/git-inspection.d.ts +6 -2
  25. package/src/developer-agent/git-inspection.js +78 -6
  26. package/src/developer-agent/model.d.ts +4 -2
  27. package/src/developer-agent/operation-registry.d.ts +5 -0
  28. package/src/developer-agent/operation-registry.js +179 -23
  29. package/src/developer-agent/preview-changes.d.ts +2 -0
  30. package/src/developer-agent/preview-changes.js +14 -2
  31. package/src/developer-agent/preview-source.js +3 -0
  32. package/src/developer-agent/validation.js +20 -8
  33. package/src/developer-agent/workspace-inspection.js +37 -3
  34. package/src/executors/deployment-plan/deployment-plan.d.ts +2 -0
  35. package/src/executors/deployment-plan/deployment-plan.js +51 -4
  36. package/src/executors/dev-doctor/dev-doctor.js +13 -6
  37. package/src/executors/dev-task-cleanup/dev-task-cleanup.d.ts +23 -0
  38. package/src/executors/dev-task-cleanup/dev-task-cleanup.js +145 -0
  39. package/src/executors/dev-task-cleanup/schema.json +9 -0
  40. package/src/executors/dev-task-cleanup/task-stack-absence.d.ts +27 -0
  41. package/src/executors/dev-task-cleanup/task-stack-absence.js +281 -0
  42. package/src/executors/dev-task-cleanup/task-stack-checkpoint.d.ts +12 -0
  43. package/src/executors/dev-task-cleanup/task-stack-checkpoint.js +92 -0
  44. package/src/executors/fleet/fleet.js +1 -1
  45. package/src/executors/foundation-remove-preflight/foundation-remove-preflight.js +28 -1
  46. package/src/executors/local-deploy/local-deploy.d.ts +8 -1
  47. package/src/executors/local-deploy/local-deploy.js +97 -24
  48. package/src/executors/local-deploy/schema.json +8 -0
  49. package/src/executors/router-waf-rehearsal/router-waf-rehearsal.js +30 -18
  50. package/src/executors/sst-lifecycle/governed-native-operation.d.ts +2 -0
  51. package/src/executors/sst-lifecycle/governed-native-operation.js +9 -0
  52. package/src/executors/sst-lifecycle/run-sst-command.d.ts +5 -0
  53. package/src/executors/sst-lifecycle/run-sst-command.js +220 -32
  54. package/src/executors/sst-lifecycle/sst-environment-source.d.ts +8 -0
  55. package/src/executors/sst-lifecycle/sst-environment-source.js +54 -0
  56. package/src/executors/sst-lifecycle/task-unlock.d.ts +15 -0
  57. package/src/executors/sst-lifecycle/task-unlock.js +126 -0
  58. package/src/foundation/capability-plan.d.ts +43 -0
  59. package/src/foundation/capability-plan.js +168 -0
  60. package/src/foundation/discovery.d.ts +14 -11
  61. package/src/foundation/discovery.js +32 -6
  62. package/src/foundation/index.d.ts +1 -0
  63. package/src/foundation/index.js +1 -0
  64. package/src/foundation/local-database-contract.d.ts +20 -0
  65. package/src/foundation/local-database-contract.js +262 -13
  66. package/src/foundation/local-private-smoke-access.d.ts +20 -0
  67. package/src/foundation/local-private-smoke-access.js +197 -0
  68. package/src/foundation/preflight.js +37 -18
  69. package/src/foundation/private-smoke-access.js +10 -2
  70. package/src/foundation/private-smoke-admission.d.ts +3 -1
  71. package/src/foundation/private-smoke-admission.js +29 -8
  72. package/src/foundation/private-smoke-control-plane.js +17 -6
  73. package/src/foundation/provision-database-bindings.d.ts +5 -0
  74. package/src/foundation/provision-database-bindings.js +41 -8
  75. package/src/foundation/provision-logical-database.js +13 -8
  76. package/src/foundation/requirements.d.ts +3 -3
  77. package/src/foundation/requirements.js +24 -12
  78. package/src/foundation/router-waf.d.ts +1 -0
  79. package/src/foundation/router-waf.js +14 -1
  80. package/src/generators/blueprint/blueprint.d.ts +5 -0
  81. package/src/generators/blueprint/blueprint.js +102 -0
  82. package/src/generators/blueprint/files.d.ts +6 -0
  83. package/src/generators/blueprint/files.js +217 -0
  84. package/src/generators/blueprint/schema.d.ts +4 -0
  85. package/src/generators/blueprint/schema.json +18 -0
  86. package/src/generators/formatting.js +24 -1
  87. package/src/generators/logging-registry.d.ts +2 -0
  88. package/src/generators/logging-registry.js +22 -0
  89. package/src/generators/preset/workspace-files-adopter-skills.d.ts +7 -0
  90. package/src/generators/preset/workspace-files-adopter-skills.js +301 -0
  91. package/src/generators/preset/workspace-files-ci-install.d.ts +2 -0
  92. package/src/generators/preset/workspace-files-ci-install.js +196 -0
  93. package/src/generators/preset/workspace-files-developer-agent.js +40 -13
  94. package/src/generators/preset/workspace-files-performance-load.js +8 -0
  95. package/src/generators/preset/workspace-files-stage-authority.js +40 -1
  96. package/src/generators/preset/workspace-files-thin-deploy.js +66 -34
  97. package/src/generators/preset/workspace-files-thin-docs.js +64 -18
  98. package/src/generators/preset/workspace-files.d.ts +4 -0
  99. package/src/generators/preset/workspace-files.js +159 -91
  100. package/src/generators/repository-policy/repository-policy.js +37 -0
  101. package/src/generators/slice/built-in-plan-api-contract-files.js +42 -7
  102. package/src/generators/slice/built-in-plan-api-files.d.ts +1 -1
  103. package/src/generators/slice/built-in-plan-api-files.js +47 -389
  104. package/src/generators/slice/built-in-plan-async-work-files.js +19 -1912
  105. package/src/generators/slice/built-in-plan-authorization-files.js +92 -329
  106. package/src/generators/slice/built-in-plan-authorization-infrastructure-files.js +36 -2
  107. package/src/generators/slice/built-in-plan-authorization-storage.d.ts +3 -0
  108. package/src/generators/slice/built-in-plan-authorization-storage.js +119 -0
  109. package/src/generators/slice/built-in-plan-background-work-files.d.ts +1 -1
  110. package/src/generators/slice/built-in-plan-background-work-files.js +15 -5
  111. package/src/generators/slice/built-in-plan-data-deletion-files.js +2 -830
  112. package/src/generators/slice/built-in-plan-data-files.d.ts +1 -1
  113. package/src/generators/slice/built-in-plan-data-files.js +61 -1164
  114. package/src/generators/slice/built-in-plan-data-lifecycle-files.js +53 -28
  115. package/src/generators/slice/built-in-plan-data-lifecycle-runtime-files.js +18 -2
  116. package/src/generators/slice/built-in-plan-data-retention-job-files.js +7 -2446
  117. package/src/generators/slice/built-in-plan-data-retention-launcher-files.js +30 -6
  118. package/src/generators/slice/built-in-plan-data-rights-files.js +6 -4482
  119. package/src/generators/slice/built-in-plan-database-lifecycle-files.js +4 -15
  120. package/src/generators/slice/built-in-plan-foundation-files.d.ts +2 -1
  121. package/src/generators/slice/built-in-plan-foundation-files.js +34 -10
  122. package/src/generators/slice/built-in-plan-frontend-files.js +2 -2
  123. package/src/generators/slice/built-in-plan-infrastructure-files.d.ts +1 -1
  124. package/src/generators/slice/built-in-plan-infrastructure-files.js +180 -522
  125. package/src/generators/slice/built-in-plan-key-value-cleanup.d.ts +4 -0
  126. package/src/generators/slice/built-in-plan-key-value-cleanup.js +100 -0
  127. package/src/generators/slice/built-in-plan-key-value-consumer.d.ts +4 -0
  128. package/src/generators/slice/built-in-plan-key-value-consumer.js +151 -0
  129. package/src/generators/slice/built-in-plan-key-value-deletion.d.ts +2 -0
  130. package/src/generators/slice/built-in-plan-key-value-deletion.js +377 -0
  131. package/src/generators/slice/built-in-plan-key-value-delivery.d.ts +2 -0
  132. package/src/generators/slice/built-in-plan-key-value-delivery.js +120 -0
  133. package/src/generators/slice/built-in-plan-key-value-export.d.ts +2 -0
  134. package/src/generators/slice/built-in-plan-key-value-export.js +595 -0
  135. package/src/generators/slice/built-in-plan-key-value-files.d.ts +2 -0
  136. package/src/generators/slice/built-in-plan-key-value-files.js +31 -0
  137. package/src/generators/slice/built-in-plan-key-value-holds.d.ts +2 -0
  138. package/src/generators/slice/built-in-plan-key-value-holds.js +189 -0
  139. package/src/generators/slice/built-in-plan-key-value-infrastructure.d.ts +2 -0
  140. package/src/generators/slice/built-in-plan-key-value-infrastructure.js +102 -0
  141. package/src/generators/slice/built-in-plan-key-value-performance.d.ts +5 -0
  142. package/src/generators/slice/built-in-plan-key-value-performance.js +530 -0
  143. package/src/generators/slice/built-in-plan-key-value-provider.d.ts +4 -0
  144. package/src/generators/slice/built-in-plan-key-value-provider.js +366 -0
  145. package/src/generators/slice/built-in-plan-key-value-records.d.ts +3 -0
  146. package/src/generators/slice/built-in-plan-key-value-records.js +232 -0
  147. package/src/generators/slice/built-in-plan-key-value-retention-infrastructure.d.ts +2 -0
  148. package/src/generators/slice/built-in-plan-key-value-retention-infrastructure.js +103 -0
  149. package/src/generators/slice/built-in-plan-key-value-retention-job-files.d.ts +2 -0
  150. package/src/generators/slice/built-in-plan-key-value-retention-job-files.js +160 -0
  151. package/src/generators/slice/built-in-plan-key-value-retention-maintenance.d.ts +2 -0
  152. package/src/generators/slice/built-in-plan-key-value-retention-maintenance.js +329 -0
  153. package/src/generators/slice/built-in-plan-key-value-retention-worker.d.ts +2 -0
  154. package/src/generators/slice/built-in-plan-key-value-retention-worker.js +477 -0
  155. package/src/generators/slice/built-in-plan-key-value-retention.d.ts +2 -0
  156. package/src/generators/slice/built-in-plan-key-value-retention.js +184 -0
  157. package/src/generators/slice/built-in-plan-metadata-files.d.ts +1 -1
  158. package/src/generators/slice/built-in-plan-metadata-files.js +140 -28
  159. package/src/generators/slice/built-in-plan-native-runtime-authority-files.d.ts +1 -1
  160. package/src/generators/slice/built-in-plan-native-runtime-authority-files.js +36 -19
  161. package/src/generators/slice/built-in-plan-operations-files.d.ts +1 -1
  162. package/src/generators/slice/built-in-plan-operations-files.js +89 -50
  163. package/src/generators/slice/built-in-plan-performance-files.js +84 -1010
  164. package/src/generators/slice/built-in-plan-project-files.js +116 -67
  165. package/src/generators/slice/built-in-plan-release-files.d.ts +1 -1
  166. package/src/generators/slice/built-in-plan-release-files.js +64 -15
  167. package/src/generators/slice/built-in-plan-reliability-files.js +54 -28
  168. package/src/generators/slice/built-in-plan-shared.d.ts +4 -2
  169. package/src/generators/slice/built-in-plan-shared.js +41 -19
  170. package/src/generators/slice/built-in-plan-sql-events.d.ts +2 -0
  171. package/src/generators/slice/built-in-plan-sql-events.js +257 -0
  172. package/src/generators/slice/built-in-plan-testing-files.d.ts +1 -1
  173. package/src/generators/slice/built-in-plan-testing-files.js +184 -132
  174. package/src/generators/slice/built-in-plan-testing-persistence-files.d.ts +2 -0
  175. package/src/generators/slice/built-in-plan-testing-persistence-files.js +178 -0
  176. package/src/generators/slice/built-in-plan-thin-release-files.d.ts +1 -1
  177. package/src/generators/slice/built-in-plan-thin-release-files.js +35 -2
  178. package/src/generators/slice/built-in-plan-verification-files.js +70 -0
  179. package/src/generators/slice/built-in-plan-web-files.d.ts +1 -1
  180. package/src/generators/slice/built-in-plan-web-files.js +206 -14
  181. package/src/generators/slice/built-in-plan-workload-role-files.d.ts +1 -1
  182. package/src/generators/slice/built-in-plan-workload-role-files.js +113 -274
  183. package/src/generators/slice/built-in-plan.d.ts +9 -1
  184. package/src/generators/slice/built-in-plan.js +49 -21
  185. package/src/generators/slice/data-policy-review-seed.d.ts +2 -0
  186. package/src/generators/slice/data-policy-review-seed.js +22 -0
  187. package/src/generators/slice/deployed-smoke-readiness.d.ts +2 -0
  188. package/src/generators/slice/deployed-smoke-readiness.js +214 -0
  189. package/src/generators/slice/local-source-identity.d.ts +2 -0
  190. package/src/generators/slice/local-source-identity.js +31 -0
  191. package/src/generators/slice/persistence-contract.d.ts +14 -0
  192. package/src/generators/slice/persistence-contract.js +32 -0
  193. package/src/generators/slice/slice.js +29 -24
  194. package/src/generators/sql/schema.d.ts +7 -0
  195. package/src/generators/sql/schema.json +38 -0
  196. package/src/generators/sql/sql.d.ts +6 -0
  197. package/src/generators/sql/sql.js +53 -0
  198. package/src/generators/upgrade/sql-seeded-reconciliation.d.ts +2 -0
  199. package/src/generators/upgrade/sql-seeded-reconciliation.js +170 -0
  200. package/src/generators/upgrade/upgrade.d.ts +2 -0
  201. package/src/generators/upgrade/upgrade.js +136 -9
  202. package/src/generators/workload/workload.js +51 -2
  203. package/src/local-dev/browser-verification.d.ts +37 -0
  204. package/src/local-dev/browser-verification.js +281 -0
  205. package/src/local-dev/contracts.d.ts +10 -1
  206. package/src/local-dev/contracts.js +114 -13
  207. package/src/local-dev/dev-command-core.js +24 -5
  208. package/src/local-dev/docker-credential-health.d.ts +14 -0
  209. package/src/local-dev/docker-credential-health.js +94 -0
  210. package/src/local-dev/environment-inspector.d.ts +7 -0
  211. package/src/local-dev/environment-inspector.js +42 -15
  212. package/src/local-dev/environment-state.js +2 -2
  213. package/src/local-dev/errors.d.ts +1 -1
  214. package/src/local-dev/errors.js +2 -0
  215. package/src/local-dev/fleet-client.js +2 -2
  216. package/src/local-dev/fleet-configuration.js +57 -25
  217. package/src/local-dev/fleet-inventory.js +46 -18
  218. package/src/local-dev/fleet-ipc.d.ts +7 -0
  219. package/src/local-dev/fleet-ipc.js +14 -2
  220. package/src/local-dev/fleet-launcher.d.ts +6 -0
  221. package/src/local-dev/fleet-launcher.js +14 -2
  222. package/src/local-dev/fleet-logs.js +50 -22
  223. package/src/local-dev/fleet-process.d.ts +20 -1
  224. package/src/local-dev/fleet-process.js +197 -41
  225. package/src/local-dev/fleet-runner-evidence.d.ts +5 -0
  226. package/src/local-dev/fleet-runner-evidence.js +56 -0
  227. package/src/local-dev/fleet-runtime.js +268 -229
  228. package/src/local-dev/fleet-session.d.ts +2 -0
  229. package/src/local-dev/fleet-session.js +28 -11
  230. package/src/local-dev/fleet-slice-runner-daemon.js +4 -0
  231. package/src/local-dev/fleet-state.d.ts +5 -2
  232. package/src/local-dev/fleet-state.js +25 -4
  233. package/src/local-dev/fleet-supervisor.d.ts +3 -0
  234. package/src/local-dev/fleet-supervisor.js +66 -11
  235. package/src/local-dev/fleet-web-start.d.ts +12 -0
  236. package/src/local-dev/fleet-web-start.js +48 -0
  237. package/src/local-dev/identity.js +3 -14
  238. package/src/local-dev/index.d.ts +1 -0
  239. package/src/local-dev/index.js +1 -0
  240. package/src/local-dev/native-completion.d.ts +9 -0
  241. package/src/local-dev/native-completion.js +130 -0
  242. package/src/local-dev/nx-workspace.d.ts +4 -2
  243. package/src/local-dev/nx-workspace.js +11 -6
  244. package/src/local-dev/personal-stage.d.ts +4 -5
  245. package/src/local-dev/personal-stage.js +6 -54
  246. package/src/local-dev/port-claims.d.ts +13 -0
  247. package/src/local-dev/port-claims.js +46 -0
  248. package/src/local-dev/ports.d.ts +14 -2
  249. package/src/local-dev/ports.js +78 -3
  250. package/src/local-dev/private-state.d.ts +6 -0
  251. package/src/local-dev/private-state.js +126 -34
  252. package/src/local-dev/process-group.d.ts +4 -0
  253. package/src/local-dev/process-group.js +29 -0
  254. package/src/local-dev/process-identity.d.ts +8 -0
  255. package/src/local-dev/process-identity.js +31 -1
  256. package/src/local-dev/proxy.js +11 -12
  257. package/src/local-dev/runtime-paths.js +1 -1
  258. package/src/local-dev/slice-claim.js +1 -1
  259. package/src/local-dev/slice-runner.d.ts +15 -6
  260. package/src/local-dev/slice-runner.js +189 -54
  261. package/src/local-dev/task-attachment.d.ts +17 -0
  262. package/src/local-dev/task-attachment.js +73 -0
  263. package/src/local-dev/task-authority.d.ts +10 -0
  264. package/src/local-dev/task-authority.js +27 -0
  265. package/src/local-dev/task-identity.d.ts +33 -0
  266. package/src/local-dev/task-identity.js +418 -0
  267. package/src/local-dev/task-native-writer.d.ts +18 -0
  268. package/src/local-dev/task-native-writer.js +329 -0
  269. package/src/local-dev/tls.js +3 -1
  270. package/src/local-dev/web-launch.d.ts +9 -0
  271. package/src/local-dev/web-launch.js +130 -0
  272. package/src/ownership/composition.d.ts +2 -1
  273. package/src/ownership/composition.js +1 -0
  274. package/src/performance/scenario.d.ts +22 -0
  275. package/src/performance/scenario.js +100 -92
  276. package/src/repository-policy/deployment-plan.d.ts +2 -2
  277. package/src/repository-policy/deployment-plan.js +2 -1
  278. package/src/repository-policy/policy.js +38 -3
  279. package/src/schemas/blueprint-v1.json +5 -4
  280. package/src/schemas/foundation-requirement-v1.json +5 -4
  281. package/src/schemas/testing-evidence-result-v1.json +1 -1
  282. package/src/secrets/operator.d.ts +3 -1
  283. package/src/secrets/operator.js +22 -3
  284. package/src/sst-environment-source-format.d.ts +3 -0
  285. package/src/sst-environment-source-format.js +20 -0
  286. package/src/supply-chain/blueprint-trust-git.js +13 -3
  287. package/src/supply-chain/build-output.js +15 -0
  288. package/src/supply-chain/generated-blueprint-trust-command.js +18 -1
  289. package/src/testing-evidence/fixture-scope.d.ts +2 -1
  290. package/src/testing-evidence/fixture-scope.js +4 -2
  291. package/src/testing-evidence/result.d.ts +2 -1
  292. package/src/testing-evidence/result.js +18 -4
  293. package/src/workload-roles/standard-slice.js +2 -3
  294. package/src/api-contract/baseline-update.js.map +0 -1
  295. package/src/api-contract/compatibility.js.map +0 -1
  296. package/src/api-contract/contract-graph.js.map +0 -1
  297. package/src/api-contract/evidence.js.map +0 -1
  298. package/src/api-contract/index.js.map +0 -1
  299. package/src/api-contract/model.fixtures.d.ts +0 -2
  300. package/src/api-contract/model.fixtures.js +0 -81
  301. package/src/api-contract/model.fixtures.js.map +0 -1
  302. package/src/api-contract/model.js.map +0 -1
  303. package/src/api-contract/rollout.js.map +0 -1
  304. package/src/authorization/compatibility.js.map +0 -1
  305. package/src/authorization/index.js.map +0 -1
  306. package/src/aws/child-environment.js.map +0 -1
  307. package/src/aws/identity.js.map +0 -1
  308. package/src/aws-authority/index.js.map +0 -1
  309. package/src/aws-authority/stage-authority.js.map +0 -1
  310. package/src/blueprints/execution.js.map +0 -1
  311. package/src/blueprints/external-sandbox.js.map +0 -1
  312. package/src/blueprints/index.js.map +0 -1
  313. package/src/blueprints/inputs.js.map +0 -1
  314. package/src/blueprints/manifest.js.map +0 -1
  315. package/src/blueprints/resolver.js.map +0 -1
  316. package/src/blueprints/transitions.js.map +0 -1
  317. package/src/cli/agent-command.js.map +0 -1
  318. package/src/cli/agent-runtime.js.map +0 -1
  319. package/src/cli/blueprint-authority.js.map +0 -1
  320. package/src/cli/blueprint-command.js.map +0 -1
  321. package/src/cli/bootstrap.js.map +0 -1
  322. package/src/cli/dev-command.js.map +0 -1
  323. package/src/cli/main.js.map +0 -1
  324. package/src/cli/output.js.map +0 -1
  325. package/src/cli/personal-secret-runtime.js.map +0 -1
  326. package/src/cli/secret-terminal.js.map +0 -1
  327. package/src/container-images.js.map +0 -1
  328. package/src/data-lifecycle/index.js.map +0 -1
  329. package/src/data-lifecycle/model.fixtures.d.ts +0 -2
  330. package/src/data-lifecycle/model.fixtures.js +0 -244
  331. package/src/data-lifecycle/model.fixtures.js.map +0 -1
  332. package/src/data-lifecycle/model.js.map +0 -1
  333. package/src/data-lifecycle/sensitive-artifacts.js.map +0 -1
  334. package/src/data-lifecycle/validation.js.map +0 -1
  335. package/src/database-retirement/contract.js.map +0 -1
  336. package/src/database-retirement/index.js.map +0 -1
  337. package/src/deterministic-order.js.map +0 -1
  338. package/src/developer-agent/context.js.map +0 -1
  339. package/src/developer-agent/generator-planning.js.map +0 -1
  340. package/src/developer-agent/generator-preview.js.map +0 -1
  341. package/src/developer-agent/git-inspection.js.map +0 -1
  342. package/src/developer-agent/handoff.js.map +0 -1
  343. package/src/developer-agent/index.js.map +0 -1
  344. package/src/developer-agent/model.js.map +0 -1
  345. package/src/developer-agent/operation-registry.js.map +0 -1
  346. package/src/developer-agent/ordering.js.map +0 -1
  347. package/src/developer-agent/planning.js.map +0 -1
  348. package/src/developer-agent/preview-changes.js.map +0 -1
  349. package/src/developer-agent/preview-source.js.map +0 -1
  350. package/src/developer-agent/validation.js.map +0 -1
  351. package/src/developer-agent/workspace-inspection.js.map +0 -1
  352. package/src/developer-agent/workspace-path.js.map +0 -1
  353. package/src/executors/blueprint-trust/blueprint-trust.js.map +0 -1
  354. package/src/executors/blueprint-verification/blueprint-verification.js.map +0 -1
  355. package/src/executors/deploy/deploy.js.map +0 -1
  356. package/src/executors/deployment-plan/deployment-plan.js.map +0 -1
  357. package/src/executors/dev/dev.js.map +0 -1
  358. package/src/executors/dev-doctor/dev-doctor.js.map +0 -1
  359. package/src/executors/dev-setup/dev-setup.js.map +0 -1
  360. package/src/executors/developer-context/developer-context.js.map +0 -1
  361. package/src/executors/fleet/fleet.js.map +0 -1
  362. package/src/executors/foundation-preflight/foundation-preflight.js.map +0 -1
  363. package/src/executors/foundation-profile-preflight/foundation-profile-preflight.js.map +0 -1
  364. package/src/executors/foundation-profile-preflight/production-database-safeguard.js.map +0 -1
  365. package/src/executors/foundation-remove-preflight/foundation-remove-preflight.js.map +0 -1
  366. package/src/executors/github-bootstrap/github-bootstrap.js.map +0 -1
  367. package/src/executors/infrastructure-plan/infrastructure-plan.js.map +0 -1
  368. package/src/executors/local-deploy/federated-credential-transport.js.map +0 -1
  369. package/src/executors/local-deploy/fixtures/local-deploy-state-machine.mjs +0 -53
  370. package/src/executors/local-deploy/local-approval.js.map +0 -1
  371. package/src/executors/local-deploy/local-deploy.js.map +0 -1
  372. package/src/executors/refresh/refresh.js.map +0 -1
  373. package/src/executors/remove/remove.js.map +0 -1
  374. package/src/executors/router-waf-rehearsal/router-waf-rehearsal.js.map +0 -1
  375. package/src/executors/secret-guardrails/secret-guardrails.js.map +0 -1
  376. package/src/executors/secret-initialize/secret-initialize.js.map +0 -1
  377. package/src/executors/secret-metadata/secret-metadata.js.map +0 -1
  378. package/src/executors/sst-lifecycle/generated-secret-retirement.js.map +0 -1
  379. package/src/executors/sst-lifecycle/governed-native-operation.js.map +0 -1
  380. package/src/executors/sst-lifecycle/logging-preflight.js.map +0 -1
  381. package/src/executors/sst-lifecycle/run-sst-command.js.map +0 -1
  382. package/src/executors/sst-lifecycle/secret-preflight.js.map +0 -1
  383. package/src/executors/sst-lifecycle/sst-environment-source.js.map +0 -1
  384. package/src/executors/unlock/unlock.js.map +0 -1
  385. package/src/executors/work-markers/work-markers.js.map +0 -1
  386. package/src/foundation/discovery.js.map +0 -1
  387. package/src/foundation/index.js.map +0 -1
  388. package/src/foundation/local-database-contract.js.map +0 -1
  389. package/src/foundation/logging-preflight.js.map +0 -1
  390. package/src/foundation/logging.js.map +0 -1
  391. package/src/foundation/partial-state.js.map +0 -1
  392. package/src/foundation/preflight.js.map +0 -1
  393. package/src/foundation/private-smoke-access.js.map +0 -1
  394. package/src/foundation/private-smoke-admission.js.map +0 -1
  395. package/src/foundation/private-smoke-control-plane.js.map +0 -1
  396. package/src/foundation/provision-database-bindings.js.map +0 -1
  397. package/src/foundation/provision-logical-database.js.map +0 -1
  398. package/src/foundation/requirements.js.map +0 -1
  399. package/src/foundation/router-origin-proof.js.map +0 -1
  400. package/src/foundation/router-waf-rate-rehearsal.js.map +0 -1
  401. package/src/foundation/router-waf.js.map +0 -1
  402. package/src/foundation/stages.js.map +0 -1
  403. package/src/frontend-security/index.js.map +0 -1
  404. package/src/frontend-security/security-headers.js.map +0 -1
  405. package/src/generators/feature-registry.js.map +0 -1
  406. package/src/generators/formatting.js.map +0 -1
  407. package/src/generators/function/function.js.map +0 -1
  408. package/src/generators/job/job.js.map +0 -1
  409. package/src/generators/logging-registry.js.map +0 -1
  410. package/src/generators/post-generation-install.js.map +0 -1
  411. package/src/generators/preset/dependency-overrides.js.map +0 -1
  412. package/src/generators/preset/generator.js.map +0 -1
  413. package/src/generators/preset/tool-versions.js.map +0 -1
  414. package/src/generators/preset/workspace-files-ci-acceptance.js.map +0 -1
  415. package/src/generators/preset/workspace-files-developer-agent.js.map +0 -1
  416. package/src/generators/preset/workspace-files-ecr-inspector.js.map +0 -1
  417. package/src/generators/preset/workspace-files-foundation-workload-roles.js.map +0 -1
  418. package/src/generators/preset/workspace-files-performance-cost.js.map +0 -1
  419. package/src/generators/preset/workspace-files-performance-load.js.map +0 -1
  420. package/src/generators/preset/workspace-files-stage-authority.js.map +0 -1
  421. package/src/generators/preset/workspace-files-thin-deploy.js.map +0 -1
  422. package/src/generators/preset/workspace-files-thin-docs.js.map +0 -1
  423. package/src/generators/preset/workspace-files-thin-release.js.map +0 -1
  424. package/src/generators/preset/workspace-files-workload-role-baseline.js.map +0 -1
  425. package/src/generators/preset/workspace-files.js.map +0 -1
  426. package/src/generators/repository-policy/repository-policy.js.map +0 -1
  427. package/src/generators/repository-policy/tree-policy.js.map +0 -1
  428. package/src/generators/service/service.js.map +0 -1
  429. package/src/generators/slice/built-in-plan-api-contract-files.js.map +0 -1
  430. package/src/generators/slice/built-in-plan-api-files.js.map +0 -1
  431. package/src/generators/slice/built-in-plan-async-work-files.js.map +0 -1
  432. package/src/generators/slice/built-in-plan-authorization-files.js.map +0 -1
  433. package/src/generators/slice/built-in-plan-authorization-infrastructure-files.js.map +0 -1
  434. package/src/generators/slice/built-in-plan-background-work-files.js.map +0 -1
  435. package/src/generators/slice/built-in-plan-data-deletion-files.js.map +0 -1
  436. package/src/generators/slice/built-in-plan-data-export-infrastructure-files.js.map +0 -1
  437. package/src/generators/slice/built-in-plan-data-files.js.map +0 -1
  438. package/src/generators/slice/built-in-plan-data-lifecycle-files.js.map +0 -1
  439. package/src/generators/slice/built-in-plan-data-lifecycle-runtime-files.js.map +0 -1
  440. package/src/generators/slice/built-in-plan-data-retention-job-files.js.map +0 -1
  441. package/src/generators/slice/built-in-plan-data-retention-launcher-files.js.map +0 -1
  442. package/src/generators/slice/built-in-plan-data-rights-files.js.map +0 -1
  443. package/src/generators/slice/built-in-plan-database-lifecycle-files.js.map +0 -1
  444. package/src/generators/slice/built-in-plan-database-retirement-rehearsal-files.js.map +0 -1
  445. package/src/generators/slice/built-in-plan-foundation-files.js.map +0 -1
  446. package/src/generators/slice/built-in-plan-frontend-files.js.map +0 -1
  447. package/src/generators/slice/built-in-plan-infrastructure-files.js.map +0 -1
  448. package/src/generators/slice/built-in-plan-infrastructure-safety-files.js.map +0 -1
  449. package/src/generators/slice/built-in-plan-metadata-files.js.map +0 -1
  450. package/src/generators/slice/built-in-plan-native-runtime-authority-files.js.map +0 -1
  451. package/src/generators/slice/built-in-plan-operations-files.js.map +0 -1
  452. package/src/generators/slice/built-in-plan-performance-files.js.map +0 -1
  453. package/src/generators/slice/built-in-plan-project-files.js.map +0 -1
  454. package/src/generators/slice/built-in-plan-release-files.js.map +0 -1
  455. package/src/generators/slice/built-in-plan-reliability-files.js.map +0 -1
  456. package/src/generators/slice/built-in-plan-secret-runtime-files.js.map +0 -1
  457. package/src/generators/slice/built-in-plan-shared.js.map +0 -1
  458. package/src/generators/slice/built-in-plan-testing-files.js.map +0 -1
  459. package/src/generators/slice/built-in-plan-thin-release-files.js.map +0 -1
  460. package/src/generators/slice/built-in-plan-verification-files.js.map +0 -1
  461. package/src/generators/slice/built-in-plan-web-files.js.map +0 -1
  462. package/src/generators/slice/built-in-plan-workload-role-files.js.map +0 -1
  463. package/src/generators/slice/built-in-plan.js.map +0 -1
  464. package/src/generators/slice/slice.js.map +0 -1
  465. package/src/generators/upgrade/upgrade.js.map +0 -1
  466. package/src/generators/workload/frozen-container.js.map +0 -1
  467. package/src/generators/workload/performance-registration.js.map +0 -1
  468. package/src/generators/workload/reliability-registration.js.map +0 -1
  469. package/src/generators/workload/service-performance-files.js.map +0 -1
  470. package/src/generators/workload/workload.js.map +0 -1
  471. package/src/git-policy/action-pins.js.map +0 -1
  472. package/src/git-policy/github-bootstrap.js.map +0 -1
  473. package/src/git-policy/index.js.map +0 -1
  474. package/src/git-policy/routing.js.map +0 -1
  475. package/src/index.js.map +0 -1
  476. package/src/infrastructure-change/convergence.js.map +0 -1
  477. package/src/infrastructure-change/drift.js.map +0 -1
  478. package/src/infrastructure-change/index.js.map +0 -1
  479. package/src/infrastructure-change/local-capability.js.map +0 -1
  480. package/src/infrastructure-change/model.js.map +0 -1
  481. package/src/infrastructure-change/normalize.js.map +0 -1
  482. package/src/infrastructure-change/plan.js.map +0 -1
  483. package/src/infrastructure-change/risk.js.map +0 -1
  484. package/src/infrastructure-change/summary.js.map +0 -1
  485. package/src/local-dev/context-discovery.js.map +0 -1
  486. package/src/local-dev/contract-validation.js.map +0 -1
  487. package/src/local-dev/contracts.js.map +0 -1
  488. package/src/local-dev/control-contract.js.map +0 -1
  489. package/src/local-dev/dev-command-core.js.map +0 -1
  490. package/src/local-dev/effects.js.map +0 -1
  491. package/src/local-dev/environment-inspector.js.map +0 -1
  492. package/src/local-dev/environment-state.js.map +0 -1
  493. package/src/local-dev/errors.js.map +0 -1
  494. package/src/local-dev/fleet-client.js.map +0 -1
  495. package/src/local-dev/fleet-configuration.js.map +0 -1
  496. package/src/local-dev/fleet-inventory.js.map +0 -1
  497. package/src/local-dev/fleet-ipc.js.map +0 -1
  498. package/src/local-dev/fleet-launcher.js.map +0 -1
  499. package/src/local-dev/fleet-lock.js.map +0 -1
  500. package/src/local-dev/fleet-logs.js.map +0 -1
  501. package/src/local-dev/fleet-process.js.map +0 -1
  502. package/src/local-dev/fleet-runtime.js.map +0 -1
  503. package/src/local-dev/fleet-session.js.map +0 -1
  504. package/src/local-dev/fleet-slice-runner-daemon.js.map +0 -1
  505. package/src/local-dev/fleet-startup.js.map +0 -1
  506. package/src/local-dev/fleet-state.js.map +0 -1
  507. package/src/local-dev/fleet-supervisor-daemon.js.map +0 -1
  508. package/src/local-dev/fleet-supervisor.js.map +0 -1
  509. package/src/local-dev/gateway-daemon.js.map +0 -1
  510. package/src/local-dev/gateway.js.map +0 -1
  511. package/src/local-dev/identity.js.map +0 -1
  512. package/src/local-dev/index.js.map +0 -1
  513. package/src/local-dev/local-context.js.map +0 -1
  514. package/src/local-dev/nx-workspace.js.map +0 -1
  515. package/src/local-dev/personal-secret-ledger.js.map +0 -1
  516. package/src/local-dev/personal-stage.js.map +0 -1
  517. package/src/local-dev/portless.js.map +0 -1
  518. package/src/local-dev/ports.js.map +0 -1
  519. package/src/local-dev/private-state.js.map +0 -1
  520. package/src/local-dev/process-identity.js.map +0 -1
  521. package/src/local-dev/proxy.js.map +0 -1
  522. package/src/local-dev/runtime-paths.js.map +0 -1
  523. package/src/local-dev/secret-slice-claim.js.map +0 -1
  524. package/src/local-dev/slice-claim.js.map +0 -1
  525. package/src/local-dev/slice-runner.js.map +0 -1
  526. package/src/local-dev/tls.js.map +0 -1
  527. package/src/ownership/composition.js.map +0 -1
  528. package/src/ownership/foundation-record.js.map +0 -1
  529. package/src/ownership/hash.js.map +0 -1
  530. package/src/ownership/index.js.map +0 -1
  531. package/src/ownership/json-ownership.js.map +0 -1
  532. package/src/ownership/record.js.map +0 -1
  533. package/src/ownership/workspace-record.js.map +0 -1
  534. package/src/performance/cost-collection.js.map +0 -1
  535. package/src/performance/cost-controls.js.map +0 -1
  536. package/src/performance/evidence.js.map +0 -1
  537. package/src/performance/index.js.map +0 -1
  538. package/src/performance/load-safety.js.map +0 -1
  539. package/src/performance/model.js.map +0 -1
  540. package/src/performance/pr-artifact-budget.js.map +0 -1
  541. package/src/performance/runner.js.map +0 -1
  542. package/src/performance/scenario-endpoint.js.map +0 -1
  543. package/src/performance/scenario.js.map +0 -1
  544. package/src/performance/test-fixtures.d.ts +0 -7
  545. package/src/performance/test-fixtures.js +0 -167
  546. package/src/performance/test-fixtures.js.map +0 -1
  547. package/src/performance/unit-cost.js.map +0 -1
  548. package/src/release/index.js.map +0 -1
  549. package/src/release/lifecycle.js.map +0 -1
  550. package/src/release/manifest.js.map +0 -1
  551. package/src/release/rollout.js.map +0 -1
  552. package/src/release/source-authority.js.map +0 -1
  553. package/src/repository-policy/aurora-preflight.js.map +0 -1
  554. package/src/repository-policy/capacity-migration.js.map +0 -1
  555. package/src/repository-policy/deployment-plan.js.map +0 -1
  556. package/src/repository-policy/foundation-profile.js.map +0 -1
  557. package/src/repository-policy/index.js.map +0 -1
  558. package/src/repository-policy/policy.js.map +0 -1
  559. package/src/secrets/adapters.js.map +0 -1
  560. package/src/secrets/aws-control-plane.js.map +0 -1
  561. package/src/secrets/declaration-verification.js.map +0 -1
  562. package/src/secrets/generated-aws-control-plane.js.map +0 -1
  563. package/src/secrets/guardrails.js.map +0 -1
  564. package/src/secrets/index.js.map +0 -1
  565. package/src/secrets/metadata.js.map +0 -1
  566. package/src/secrets/model.js.map +0 -1
  567. package/src/secrets/operator.js.map +0 -1
  568. package/src/secrets/permissions.js.map +0 -1
  569. package/src/secrets/personal-command.js.map +0 -1
  570. package/src/secrets/personal-ledger.js.map +0 -1
  571. package/src/secrets/registry.js.map +0 -1
  572. package/src/secrets/verification.js.map +0 -1
  573. package/src/secrets/workload-access.js.map +0 -1
  574. package/src/sst-environment-source-format.js.map +0 -1
  575. package/src/supply-chain/action-pins.js.map +0 -1
  576. package/src/supply-chain/blueprint-trust-git.js.map +0 -1
  577. package/src/supply-chain/blueprint-trust-process.js.map +0 -1
  578. package/src/supply-chain/blueprint-trust.js.map +0 -1
  579. package/src/supply-chain/blueprint-verification-authority.js.map +0 -1
  580. package/src/supply-chain/blueprint-verification-execution.js.map +0 -1
  581. package/src/supply-chain/build-output-bounds.js.map +0 -1
  582. package/src/supply-chain/build-output.js.map +0 -1
  583. package/src/supply-chain/common.js.map +0 -1
  584. package/src/supply-chain/container-artifact-contract.js.map +0 -1
  585. package/src/supply-chain/container-release.js.map +0 -1
  586. package/src/supply-chain/ecr-applicability.js.map +0 -1
  587. package/src/supply-chain/ecr-scanning.js.map +0 -1
  588. package/src/supply-chain/ecs-deployed-image.js.map +0 -1
  589. package/src/supply-chain/errors.js.map +0 -1
  590. package/src/supply-chain/generated-blueprint-trust-command.js.map +0 -1
  591. package/src/supply-chain/generated-command.js.map +0 -1
  592. package/src/supply-chain/generated-container-release-command.js.map +0 -1
  593. package/src/supply-chain/generated-ecr-collector-command.js.map +0 -1
  594. package/src/supply-chain/generated-files.js.map +0 -1
  595. package/src/supply-chain/generated-scanner-command.js.map +0 -1
  596. package/src/supply-chain/index.js.map +0 -1
  597. package/src/supply-chain/inventory.js.map +0 -1
  598. package/src/supply-chain/license-expression.js.map +0 -1
  599. package/src/supply-chain/pnpm-toolchain-authority.js.map +0 -1
  600. package/src/supply-chain/policy.js.map +0 -1
  601. package/src/supply-chain/publication.js.map +0 -1
  602. package/src/supply-chain/sbom.js.map +0 -1
  603. package/src/supply-chain/scanner.js.map +0 -1
  604. package/src/supply-chain/vendored-source.js.map +0 -1
  605. package/src/testing-evidence/fixture-scope.js.map +0 -1
  606. package/src/testing-evidence/index.js.map +0 -1
  607. package/src/testing-evidence/quarantine.js.map +0 -1
  608. package/src/testing-evidence/result.js.map +0 -1
  609. package/src/testing-evidence/runner-adapter.js.map +0 -1
  610. package/src/testing-evidence/sensitive-artifacts.js.map +0 -1
  611. package/src/validation.js.map +0 -1
  612. package/src/work-markers/index.js.map +0 -1
  613. package/src/work-markers/work-markers.js.map +0 -1
  614. package/src/workload-roles/account-baseline.js.map +0 -1
  615. package/src/workload-roles/authority.js.map +0 -1
  616. package/src/workload-roles/aws-adapter.js.map +0 -1
  617. package/src/workload-roles/aws-internal-handler.js.map +0 -1
  618. package/src/workload-roles/aws-s3-state.js.map +0 -1
  619. package/src/workload-roles/aws-sdk-control-plane.js.map +0 -1
  620. package/src/workload-roles/boundary.js.map +0 -1
  621. package/src/workload-roles/convergence.js.map +0 -1
  622. package/src/workload-roles/effective-policy.js.map +0 -1
  623. package/src/workload-roles/handler.js.map +0 -1
  624. package/src/workload-roles/history.js.map +0 -1
  625. package/src/workload-roles/index.js.map +0 -1
  626. package/src/workload-roles/injection.js.map +0 -1
  627. package/src/workload-roles/manifest.js.map +0 -1
  628. package/src/workload-roles/provisioner.js.map +0 -1
  629. package/src/workload-roles/registration.js.map +0 -1
  630. package/src/workload-roles/stage-boundary.js.map +0 -1
  631. package/src/workload-roles/standard-slice.js.map +0 -1
  632. package/src/workspace-deployment/affected-lifecycle.js.map +0 -1
  633. package/src/workspace-deployment/identity.js.map +0 -1
  634. package/src/workspace-deployment/index.js.map +0 -1
  635. package/src/workspace-deployment/migration-evidence.js.map +0 -1
  636. package/src/workspace-deployment/migration.js.map +0 -1
  637. package/src/workspace-deployment/ownership.js.map +0 -1
@@ -0,0 +1,366 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderKeyValueProviderFiles = renderKeyValueProviderFiles;
4
+ exports.renderKeyValueProviderTestCases = renderKeyValueProviderTestCases;
5
+ /** Native provider inbox. External effects remain at-least-once or require reconciliation. */
6
+ function renderKeyValueProviderFiles(name) {
7
+ return {
8
+ 'async/provider-inbox.ts': `import { randomUUID } from 'node:crypto';
9
+ import { asyncWorkDigest, createProviderDelivery, type ProviderDeliveryV1 } from '@empire-builder-kit/runtime/async-work';
10
+ import type { KeyValueChange } from '@empire-builder-kit/runtime/key-value';
11
+ import { dataStore } from '../data/key-value.js';
12
+
13
+ type Store = ReturnType<typeof dataStore>;
14
+ const COLLECTION = 'provider-inbox';
15
+ const LEASE_MS = 120_000;
16
+ const RETENTION_MS = 30 * 24 * 60 * 60 * 1_000;
17
+ interface Claim {
18
+ schemaVersion: 1; deliveryId: string; operationDigest: string;
19
+ createdAt: string; expiresAt: string; lastAttemptAt: string;
20
+ attemptToken: string; attempts: number;
21
+ state: 'prepared' | 'effect-started' | 'failed' | 'succeeded';
22
+ resultReference: string | null;
23
+ }
24
+ export type ProviderClaimResult =
25
+ | { outcome: 'claimed'; attemptToken: string }
26
+ | { outcome: 'conflict' | 'duplicate' | 'retry' | 'expired' | 'terminal-permanent' | 'terminal-reconciliation' };
27
+
28
+ function timestamp(value: string): number {
29
+ const time = Date.parse(value);
30
+ if (!Number.isFinite(time) || new Date(time).toISOString() !== value)
31
+ throw new Error('provider-timestamp-invalid');
32
+ return time;
33
+ }
34
+ export function parseProviderDelivery(body: string): ProviderDeliveryV1<unknown> {
35
+ if (typeof body !== 'string' || Buffer.byteLength(body) > 128 * 1024)
36
+ throw new Error('provider-delivery-invalid');
37
+ const delivery = JSON.parse(body) as ProviderDeliveryV1<unknown>;
38
+ const expected = createProviderDelivery({ contract: delivery.contract,
39
+ createdAt: delivery.createdAt, operationId: delivery.idempotencyKey, request: delivery.request });
40
+ if (asyncWorkDigest(delivery) !== asyncWorkDigest(expected))
41
+ throw new Error('provider-delivery-invalid');
42
+ const retry = expected.contract.retry;
43
+ // The generated provider Lambda has a one-minute execution budget. Leave
44
+ // room to persist the outcome, and never start an unbounded provider call.
45
+ if (!retry || ![retry.maximumAttempts, retry.attemptTimeoutMs, retry.baseDelayMs,
46
+ retry.maximumDelayMs, retry.totalTimeoutMs].every((value) => Number.isSafeInteger(value) && value > 0) ||
47
+ retry.maximumAttempts > 100 || retry.baseDelayMs > retry.maximumDelayMs ||
48
+ retry.attemptTimeoutMs >= retry.totalTimeoutMs || retry.totalTimeoutMs > 50_000)
49
+ throw new Error('provider-retry-budget-invalid');
50
+ return expected;
51
+ }
52
+ function operationDigest(delivery: ProviderDeliveryV1<unknown>) {
53
+ return asyncWorkDigest({ contract: delivery.contract, createdAt: delivery.createdAt,
54
+ deliveryId: delivery.deliveryId, idempotencyKey: delivery.idempotencyKey, requestDigest: delivery.requestDigest });
55
+ }
56
+ function readClaim(value: unknown, id: string): Claim {
57
+ const claim = value as Claim;
58
+ if (!claim || claim.schemaVersion !== 1 || claim.deliveryId !== id ||
59
+ !/^sha256:[a-f0-9]{64}$/.test(claim.operationDigest) ||
60
+ !/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(claim.attemptToken) ||
61
+ !Number.isSafeInteger(claim.attempts) || claim.attempts < 1 ||
62
+ !['prepared', 'effect-started', 'failed', 'succeeded'].includes(claim.state) ||
63
+ (claim.resultReference !== null && (typeof claim.resultReference !== 'string' || claim.resultReference.length > 256)))
64
+ throw new Error('provider-inbox-invalid');
65
+ if (timestamp(claim.expiresAt) !== timestamp(claim.createdAt) + RETENTION_MS ||
66
+ timestamp(claim.lastAttemptAt) < timestamp(claim.createdAt))
67
+ throw new Error('provider-inbox-invalid');
68
+ if (claim.state === 'succeeded' && !claim.resultReference)
69
+ throw new Error('provider-inbox-confirmation-missing');
70
+ return claim;
71
+ }
72
+ function conditionalConflict(error: unknown): boolean {
73
+ return error instanceof Error && error.name === 'TransactionCanceledException' &&
74
+ (error as Error & { CancellationReasons?: { Code?: string }[] }).CancellationReasons?.some(
75
+ ({ Code }) => Code === 'ConditionalCheckFailed') === true;
76
+ }
77
+ async function put(store: Store, value: Claim, version: number): Promise<boolean> {
78
+ try {
79
+ await store.commit({ tenantId: 'system', changes: [{ action: 'put', collection: COLLECTION,
80
+ id: value.deliveryId, expectedVersion: version, value }] });
81
+ return true;
82
+ } catch (error) {
83
+ if (conditionalConflict(error)) return false;
84
+ throw error;
85
+ }
86
+ }
87
+ export async function claimProviderDelivery(store: Store, raw: ProviderDeliveryV1<unknown>,
88
+ now: string, createAttemptToken: () => string = randomUUID): Promise<ProviderClaimResult> {
89
+ const delivery = parseProviderDelivery(JSON.stringify(raw));
90
+ const time = timestamp(now);
91
+ const created = timestamp(delivery.createdAt);
92
+ // This check works even after physical deletion; TTL timing is not replay authority.
93
+ if (created > time || time >= created + RETENTION_MS) return { outcome: 'expired' };
94
+ const row = await store.get('system', COLLECTION, delivery.deliveryId);
95
+ const previous = row ? readClaim(row.value, delivery.deliveryId) : null;
96
+ const digest = operationDigest(delivery);
97
+ if (previous) {
98
+ if (previous.operationDigest !== digest) return { outcome: 'conflict' };
99
+ if (previous.state === 'succeeded') return { outcome: 'duplicate' };
100
+ if (previous.state === 'failed' && previous.resultReference?.startsWith('terminal-permanent-'))
101
+ return { outcome: 'terminal-permanent' };
102
+ if (previous.state === 'failed' && previous.resultReference?.startsWith('terminal-reconciliation-'))
103
+ return { outcome: 'terminal-reconciliation' };
104
+ if (time < timestamp(previous.lastAttemptAt)) throw new Error('provider-clock-regressed');
105
+ if ((previous.state === 'prepared' || previous.state === 'effect-started') &&
106
+ time - timestamp(previous.lastAttemptAt) < LEASE_MS) return { outcome: 'retry' };
107
+ if (previous.state === 'effect-started' && delivery.contract.idempotencyRepeatSafety === 'unproven') {
108
+ const saved = await put(store, { ...previous, state: 'failed', lastAttemptAt: now,
109
+ resultReference: 'terminal-reconciliation-' + asyncWorkDigest({ deliveryId: delivery.deliveryId, result: 'provider-effect-outcome-unknown' }) }, row!.version);
110
+ return { outcome: saved ? 'terminal-reconciliation' : 'retry' };
111
+ }
112
+ }
113
+ const attemptToken = createAttemptToken();
114
+ const next: Claim = { schemaVersion: 1, deliveryId: delivery.deliveryId, operationDigest: digest,
115
+ createdAt: delivery.createdAt, expiresAt: new Date(created + RETENTION_MS).toISOString(),
116
+ lastAttemptAt: now, attemptToken, attempts: (previous?.attempts ?? 0) + 1, state: 'prepared', resultReference: null };
117
+ readClaim(next, delivery.deliveryId);
118
+ return await put(store, next, row?.version ?? 0) ? { outcome: 'claimed', attemptToken } : { outcome: 'retry' };
119
+ }
120
+ async function ownedClaim(store: Store, id: string, token: string, state: Claim['state'], now: string) {
121
+ const row = await store.get('system', COLLECTION, id);
122
+ if (!row) return null;
123
+ const value = readClaim(row.value, id);
124
+ const time = timestamp(now);
125
+ if (value.attemptToken !== token || value.state !== state || time >= timestamp(value.expiresAt) ||
126
+ time < timestamp(value.lastAttemptAt) || time - timestamp(value.lastAttemptAt) >= LEASE_MS) return null;
127
+ return { value, version: row.version };
128
+ }
129
+ export async function markProviderEffectStarted(store: Store, id: string, token: string, now: string): Promise<boolean> {
130
+ const row = await ownedClaim(store, id, token, 'prepared', now);
131
+ return row ? put(store, { ...row.value, state: 'effect-started', lastAttemptAt: now }, row.version) : false;
132
+ }
133
+ export async function finishProviderDelivery(store: Store, id: string, token: string, now: string,
134
+ input: { expectedState?: 'prepared' | 'effect-started'; resultReference: string; status: 'failed' | 'succeeded' }): Promise<boolean> {
135
+ if (!input.resultReference || input.resultReference.length > 256 ||
136
+ !['failed', 'succeeded'].includes(input.status) ||
137
+ (input.status === 'succeeded' && input.expectedState === 'prepared'))
138
+ throw new Error('provider-finish-invalid');
139
+ const row = await ownedClaim(store, id, token, input.expectedState ?? 'effect-started', now);
140
+ return row ? put(store, { ...row.value, state: input.status, resultReference: input.resultReference,
141
+ lastAttemptAt: now }, row.version) : false;
142
+ }
143
+
144
+ // Logical expiry above rejects replay even after a terminal row is physically
145
+ // removed. Never erase an uncertain external effect merely because it is old.
146
+ export async function cleanupProviderInbox(store: Store, now: string,
147
+ clock: () => number = Date.now, deadline?: number) {
148
+ const time = timestamp(now);
149
+ const started = clock(), end = Math.min(deadline ?? Infinity, started + 4 * 60_000);
150
+ if (!Number.isFinite(started) || !Number.isFinite(end)) throw new Error('provider-cleanup-clock-invalid');
151
+ const cursor = await store.get('system', 'provider-maintenance', 'cleanup');
152
+ const saved = cursor?.value as { afterId: string | null } | undefined;
153
+ if (cursor && (!saved || (saved.afterId !== null &&
154
+ !/^sha256:[a-f0-9]{64}$/.test(saved.afterId)))) throw new Error('provider-cleanup-cursor-invalid');
155
+ let afterId = saved?.afterId ?? undefined, sawBeginning = afterId === undefined;
156
+ let inspected = 0, removed = 0, version = cursor?.version ?? 0;
157
+ const uncertain = new Set<string>();
158
+ const result = (completeScan: boolean) => ({ removed, inspected, retainedUncertain: uncertain.size,
159
+ continuationRequired: !completeScan, completeScan });
160
+ while (inspected < 10_000) {
161
+ const current = clock();
162
+ if (!Number.isFinite(current) || current < started) throw new Error('provider-cleanup-clock-invalid');
163
+ if (current >= end) return result(false);
164
+ const page = await store.list('system', COLLECTION, { limit: Math.min(20, 10_000 - inspected), afterId });
165
+ inspected += page.records.length;
166
+ const changes: KeyValueChange[] = [];
167
+ for (const row of page.records) {
168
+ const claim = readClaim(row.value, row.id);
169
+ if (timestamp(claim.expiresAt) > time) continue;
170
+ const terminal = claim.state === 'succeeded' || (claim.state === 'failed' &&
171
+ (claim.resultReference?.startsWith('terminal-permanent-') ||
172
+ claim.resultReference?.startsWith('terminal-reconciliation-') ||
173
+ claim.resultReference === 'configuration-disabled' || claim.resultReference === 'configuration-invalid'));
174
+ if (!terminal) { uncertain.add(row.id); continue; }
175
+ changes.push({ action: 'delete', collection: COLLECTION, id: row.id, expectedVersion: row.version });
176
+ }
177
+ const count = changes.length;
178
+ changes.push({ action: 'put', collection: 'provider-maintenance', id: 'cleanup',
179
+ expectedVersion: version, value: { afterId: page.nextId ?? null } });
180
+ // The cursor advances in the exact deletion transaction, including empty pages.
181
+ await store.commit({ tenantId: 'system', changes });
182
+ removed += count; version++; afterId = page.nextId;
183
+ if (afterId === undefined) {
184
+ if (sawBeginning) return result(true);
185
+ sawBeginning = true;
186
+ }
187
+ }
188
+ return result(false);
189
+ }
190
+ `,
191
+ 'async/provider-worker.ts': `import { randomUUID } from 'node:crypto';
192
+ import { asyncWorkDigest, processSqsBatch, runProviderDelivery, type ProviderDeliveryAdapter } from '@empire-builder-kit/runtime/async-work';
193
+ import { deriveOperationalRolloutStableKey } from '@empire-builder-kit/runtime/configuration';
194
+ import { createLogger, type Logger } from '@empire-builder-kit/runtime/logging';
195
+ import { createSliceAwsConfigurationProvider, createSliceLocalConfigurationProvider } from '../configuration/provider.js';
196
+ import { evaluateLambdaProviderDelivery } from '../configuration/rollout.js';
197
+ import { dataStore } from '../data/key-value.js';
198
+ import { asyncAdapterDeclaration, createAsyncRecoveryAdapters } from './recovery-adapters.js';
199
+ import { claimProviderDelivery, finishProviderDelivery, markProviderEffectStarted, parseProviderDelivery } from './provider-inbox.js';
200
+ export { claimProviderDelivery, finishProviderDelivery, markProviderEffectStarted } from './provider-inbox.js';
201
+
202
+ const protectedStage = process.env.EBK_STAGE === 'staging' || process.env.EBK_STAGE === 'production';
203
+ function required(name: string): string {
204
+ const value = process.env[name]?.trim();
205
+ if (!value) throw new Error(name + ' is required.');
206
+ return value;
207
+ }
208
+ const configurationProvider = protectedStage ? createSliceAwsConfigurationProvider({
209
+ applicationIdentifier: required('EBK_APPCONFIG_APPLICATION_ID'),
210
+ environmentIdentifier: required('EBK_APPCONFIG_ENVIRONMENT_ID'),
211
+ profileIdentifier: required('EBK_APPCONFIG_PROFILE_ID'),
212
+ }) : createSliceLocalConfigurationProvider();
213
+ const stableKey = deriveOperationalRolloutStableKey({ kind: 'lambda', slice: '${name}', workload: 'provider-worker' });
214
+ interface QueueRecord { body: string; messageId: string }
215
+ interface Dependencies {
216
+ store: typeof dataStore; now(): string; createAttemptToken(): string;
217
+ configured(): boolean; adapter(): ProviderDeliveryAdapter<unknown>;
218
+ evaluateRollout: typeof evaluateLambdaProviderDelivery;
219
+ logger: Logger;
220
+ }
221
+ export function createProviderWorkerHandler(dependencies: Dependencies) {
222
+ return async (event: { Records: QueueRecord[] }) => {
223
+ if (!dependencies.configured()) throw new Error('async-provider-adapter-disabled');
224
+ const result = await processSqsBatch({ records: event.Records, handler: async (record) => {
225
+ try {
226
+ const delivery = parseProviderDelivery(record.body);
227
+ const store = dependencies.store();
228
+ const claim = await claimProviderDelivery(store, delivery, dependencies.now(), dependencies.createAttemptToken);
229
+ if (claim.outcome === 'duplicate') return { outcome: 'succeeded' as const };
230
+ if (claim.outcome !== 'claimed') return {
231
+ outcome: claim.outcome === 'retry' ? 'retry' as const : 'terminal' as const,
232
+ errorCode: 'provider-' + claim.outcome,
233
+ };
234
+ const token = claim.attemptToken;
235
+ let assigned: boolean;
236
+ try {
237
+ assigned = (await dependencies.evaluateRollout(configurationProvider, stableKey)).assigned;
238
+ } catch {
239
+ const persisted = await finishProviderDelivery(store, delivery.deliveryId, token, dependencies.now(), {
240
+ expectedState: 'prepared', resultReference: 'configuration-invalid', status: 'failed' });
241
+ if (!persisted) throw new Error('provider-configuration-result-state-lost');
242
+ return { errorCode: 'provider-delivery-configuration-invalid', outcome: 'retry' as const };
243
+ }
244
+ if (!assigned) {
245
+ const persisted = await finishProviderDelivery(store, delivery.deliveryId, token, dependencies.now(), {
246
+ expectedState: 'prepared', resultReference: 'configuration-disabled', status: 'failed' });
247
+ if (!persisted) throw new Error('provider-configuration-result-state-lost');
248
+ return { errorCode: 'provider-delivery-disabled', outcome: 'retry' as const };
249
+ }
250
+ if (!await markProviderEffectStarted(store, delivery.deliveryId, token, dependencies.now()))
251
+ return { errorCode: 'idempotency-claim-lost', outcome: 'retry' as const };
252
+ const result = await runProviderDelivery({ adapter: dependencies.adapter(), delivery });
253
+ const confirmed = result.outcome === 'confirmed';
254
+ const reference = result.outcome === 'confirmed' ? result.providerReference :
255
+ (result.outcome === 'permanent-failure' ? 'terminal-permanent-' : 'terminal-reconciliation-') + result.reconciliationId;
256
+ if (!await finishProviderDelivery(store, delivery.deliveryId, token, dependencies.now(), {
257
+ status: confirmed ? 'succeeded' : 'failed', resultReference: reference }))
258
+ throw new Error('provider-delivery-result-state-lost');
259
+ dependencies.logger.info('Provider delivery outcome retained', {
260
+ attributes: { deliveryIdDigest: asyncWorkDigest(delivery.deliveryId), attempts: result.attempts },
261
+ outcome: confirmed ? 'success' : 'failure',
262
+ });
263
+ return result.outcome === 'confirmed' ? { outcome: 'succeeded' as const } :
264
+ { outcome: 'terminal' as const, errorCode: result.errorCode };
265
+ } catch {
266
+ // The queue retains failure; never log the provider request or accept
267
+ // an unpersisted effect. A stale uncertain claim needs reconciliation.
268
+ dependencies.logger.error('Provider delivery handler failed', {
269
+ attributes: { messageIdDigest: asyncWorkDigest(record.messageId) }, outcome: 'failure' });
270
+ return { errorCode: 'provider-delivery-failed', outcome: 'retry' as const };
271
+ }
272
+ } });
273
+ return result.response;
274
+ };
275
+ }
276
+ export const handler = createProviderWorkerHandler({
277
+ store: dataStore, now: () => new Date().toISOString(), createAttemptToken: randomUUID,
278
+ configured: () => asyncAdapterDeclaration.configured,
279
+ adapter: () => createAsyncRecoveryAdapters().providerDelivery,
280
+ evaluateRollout: evaluateLambdaProviderDelivery,
281
+ logger: createLogger({ component: 'provider-worker', feature: 'async-work', operation: 'provider-delivery',
282
+ slice: '${name}', stage: process.env.EBK_STAGE ?? 'local', workspace: process.env.EBK_WORKSPACE ?? '${name}' }),
283
+ });
284
+ `,
285
+ };
286
+ }
287
+ /** Replace only the SQL-specific provider cases; other async acceptance stays mandatory. */
288
+ function renderKeyValueProviderTestCases(name) {
289
+ return ` function providerFixture() {
290
+ type Item = Record<string, AttributeValue>;
291
+ const rows = new Map<string, Item>();
292
+ let rejectTerminal = false;
293
+ const key = (item: Item) => item.pk.S + '/' + item.sk.S;
294
+ const client = { async send(command: unknown) {
295
+ if (command instanceof GetItemCommand) return { Item: structuredClone(rows.get(key(command.input.Key!))) };
296
+ if (!(command instanceof TransactWriteItemsCommand)) throw new Error('Unexpected test transport');
297
+ const writes = command.input.TransactItems!;
298
+ for (const item of writes) {
299
+ const op = item.Put!;
300
+ const previous = rows.get(key(op.Item!));
301
+ const allowed = op.ConditionExpression === 'attribute_not_exists(pk)' ? !previous : previous &&
302
+ previous.version.N === op.ExpressionAttributeValues![':version'].N && previous.scope.S === op.ExpressionAttributeValues![':scope'].S;
303
+ if (!allowed || (rejectTerminal && JSON.parse(op.Item!.value.S!).state === 'failed'))
304
+ throw Object.assign(new Error('conditional'), { name: 'TransactionCanceledException', CancellationReasons: [{ Code: 'ConditionalCheckFailed' }] });
305
+ }
306
+ for (const item of writes) rows.set(key(item.Put!.Item!), structuredClone(item.Put!.Item!));
307
+ return {};
308
+ } } as DynamoDBClient;
309
+ const store = createDynamoPersistence({ client, tableName: '${name}-development-task-test',
310
+ stage: 'development-task-test', slice: '${name}', eventBusName: 'test-event-bus' });
311
+ return { store, rows, rejectTerminal: () => { rejectTerminal = true; } };
312
+ }
313
+
314
+ it('routes a stale unproven provider effect to reconciliation without delivery', async () => {
315
+ const fixture = providerFixture();
316
+ const delivery = createQueuedProviderDelivery({ createdAt: '2026-01-01T00:00:00.000Z',
317
+ operationId: 'operation-one', request: { value: true } });
318
+ const claimed = await claimProviderDelivery(fixture.store, delivery, delivery.createdAt, () => 'first');
319
+ expect(claimed.outcome).toBe('claimed');
320
+ await markProviderEffectStarted(fixture.store, delivery.deliveryId, 'first', delivery.createdAt);
321
+ const deliver = vi.fn();
322
+ const handler = createProviderWorkerHandler({
323
+ store: () => fixture.store, createAttemptToken: () => 'next', configured: () => true,
324
+ adapter: () => ({ deliver }), evaluateRollout: vi.fn() as never,
325
+ logger: logger as never, now: () => '2026-01-01T00:03:00.000Z',
326
+ });
327
+ await expect(handler({ Records: [{ body: JSON.stringify(delivery), messageId: 'message-one' }] }))
328
+ .resolves.toEqual({ batchItemFailures: [{ itemIdentifier: 'message-one' }] });
329
+ expect(deliver).not.toHaveBeenCalled();
330
+ const row = await fixture.store.get('system', 'provider-inbox', delivery.deliveryId);
331
+ expect(row?.value).toMatchObject({ state: 'failed', resultReference: expect.stringContaining('terminal-reconciliation-') });
332
+ });
333
+
334
+ it('retains the uncertain claim when the terminal reconciliation transition loses its condition', async () => {
335
+ const fixture = providerFixture();
336
+ const delivery = createQueuedProviderDelivery({ createdAt: '2026-01-01T00:00:00.000Z',
337
+ operationId: 'operation-lost', request: { value: true } });
338
+ await claimProviderDelivery(fixture.store, delivery, delivery.createdAt, () => 'first');
339
+ await markProviderEffectStarted(fixture.store, delivery.deliveryId, 'first', delivery.createdAt);
340
+ fixture.rejectTerminal();
341
+ await expect(claimProviderDelivery(fixture.store, delivery, '2026-01-01T00:03:00.000Z'))
342
+ .resolves.toEqual({ outcome: 'retry' });
343
+ expect((await fixture.store.get('system', 'provider-inbox', delivery.deliveryId))?.value)
344
+ .toMatchObject({ state: 'effect-started', attemptToken: 'first' });
345
+ });
346
+
347
+ it('retries a stale effect only when provider repeat safety is guaranteed', async () => {
348
+ const fixture = providerFixture();
349
+ const delivery = createQueuedProviderDelivery({ createdAt: '2026-01-01T00:00:00.000Z',
350
+ operationId: 'operation-guaranteed', request: { value: true } });
351
+ delivery.contract.idempotencyRepeatSafety = 'provider-guaranteed';
352
+ await claimProviderDelivery(fixture.store, delivery, delivery.createdAt, () => 'first');
353
+ await markProviderEffectStarted(fixture.store, delivery.deliveryId, 'first', delivery.createdAt);
354
+ const deliver = vi.fn().mockResolvedValue({ outcome: 'confirmed', providerReference: 'provider-reference', statusCode: 202 });
355
+ const handler = createProviderWorkerHandler({
356
+ store: () => fixture.store, createAttemptToken: () => 'next', configured: () => true,
357
+ adapter: () => ({ deliver }), evaluateRollout: vi.fn().mockResolvedValue({ assigned: true }) as never,
358
+ logger: logger as never, now: () => '2026-01-01T00:03:00.000Z',
359
+ });
360
+ await expect(handler({ Records: [{ body: JSON.stringify(delivery), messageId: 'message-one' }] }))
361
+ .resolves.toEqual({ batchItemFailures: [] });
362
+ expect(deliver).toHaveBeenCalledTimes(1);
363
+ });
364
+ `;
365
+ }
366
+ //# sourceMappingURL=built-in-plan-key-value-provider.js.map
@@ -0,0 +1,3 @@
1
+ /** Seeded native record behavior. SQL declarations do not switch existing records between stores. */
2
+ export declare function renderKeyValueRecordFiles(name: string, pascalName: string): Readonly<Record<string, string>>;
3
+ export declare function renderKeyValueRecordApi(pascalName: string, workspace: string): string;
@@ -0,0 +1,232 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderKeyValueRecordFiles = renderKeyValueRecordFiles;
4
+ exports.renderKeyValueRecordApi = renderKeyValueRecordApi;
5
+ const built_in_plan_shared_js_1 = require("./built-in-plan-shared.js");
6
+ /** Seeded native record behavior. SQL declarations do not switch existing records between stores. */
7
+ function renderKeyValueRecordFiles(name, pascalName) {
8
+ return {
9
+ 'data/records.ts': `import { createHash } from 'node:crypto';
10
+ import type { AuthorizationPrincipal } from '@empire-builder-kit/runtime/authorization';
11
+ import { buildEventEntry } from '@empire-builder-kit/runtime/events';
12
+ import { RuntimeError } from '@empire-builder-kit/runtime/response';
13
+ import {
14
+ createDataLifecycleAuditRecord,
15
+ createDataLifecycleLedgerEntry,
16
+ createDataLifecyclePseudonymousReference,
17
+ lifecycleIdempotencyKey,
18
+ } from '@empire-builder-kit/runtime/data-lifecycle';
19
+ import { ${pascalName}Created, ${pascalName}DataLifecycleChanged } from '../contracts/events.js';
20
+ import { create${pascalName}DataLifecycleChanged } from './lifecycle-event.js';
21
+ import { productRecordReference } from './pseudonymous-reference.js';
22
+ import { ${pascalName}DataLifecycleRuntimePolicy } from './runtime-policy.cjs';
23
+ import { dataStore } from './key-value.js';
24
+
25
+ export interface ProductRecord {
26
+ id: string;
27
+ name: string;
28
+ ownerId: string;
29
+ runScope: string;
30
+ createdAt: string;
31
+ lastActivityAt: string;
32
+ testExpiresAt: string | null;
33
+ }
34
+ export interface RecordMutationInput {
35
+ correlationId: string;
36
+ name: string;
37
+ now?: string;
38
+ principal: AuthorizationPrincipal;
39
+ recordId: string;
40
+ runScope: string;
41
+ testExpiresAt?: string;
42
+ }
43
+ export interface RecordMutationResult {
44
+ id: string;
45
+ name: string;
46
+ runScope: string;
47
+ propagation: 'pending';
48
+ requestRef: string;
49
+ created: boolean;
50
+ }
51
+
52
+ function failure(code: string, message: string, status: number): never {
53
+ throw new RuntimeError({ code, message, status, retryable: code === 'record_write_conflict' });
54
+ }
55
+ const hash = (value: unknown) => createHash('sha256').update(JSON.stringify(value)).digest('hex');
56
+ const canonical = (value: unknown): value is string =>
57
+ typeof value === 'string' && Number.isFinite(Date.parse(value)) && new Date(value).toISOString() === value;
58
+
59
+ export function effectiveRecordOwner(principal: AuthorizationPrincipal): string {
60
+ if (principal.authority.mode === 'machine')
61
+ throw new Error('Machine authority cannot mutate a subject-owned record.');
62
+ return principal.authority.mode === 'delegated' ? principal.authority.delegatedBy.id : principal.actor.id;
63
+ }
64
+
65
+ export function readProductRecord(value: unknown, id: string): ProductRecord {
66
+ const record = value as ProductRecord;
67
+ if (!record || record.id !== id || typeof record.ownerId !== 'string' || !record.ownerId ||
68
+ typeof record.name !== 'string' || !record.name || record.name.length > 256 ||
69
+ typeof record.runScope !== 'string' || !record.runScope || record.runScope.length > 128 ||
70
+ !canonical(record.createdAt) || !canonical(record.lastActivityAt) ||
71
+ (record.testExpiresAt !== null && !canonical(record.testExpiresAt)))
72
+ throw new Error('Stored product record is malformed or has a different identity.');
73
+ // Explicit projection prevents unrelated fields from becoming API/export data.
74
+ return { id, name: record.name, ownerId: record.ownerId, runScope: record.runScope,
75
+ createdAt: record.createdAt, lastActivityAt: record.lastActivityAt, testExpiresAt: record.testExpiresAt };
76
+ }
77
+
78
+ export async function getOwnedRecord(id: string, ownerId: string): Promise<ProductRecord | null> {
79
+ const row = await dataStore().get('application', 'records', id);
80
+ if (!row) return null;
81
+ const record = readProductRecord(row.value, id);
82
+ return record.ownerId === ownerId ? record : null;
83
+ }
84
+
85
+ function conditionConflict(error: unknown): boolean {
86
+ return error instanceof Error && error.name === 'TransactionCanceledException' &&
87
+ (error as Error & { CancellationReasons?: { Code?: string }[] }).CancellationReasons?.some(
88
+ ({ Code }) => Code === 'ConditionalCheckFailed') === true;
89
+ }
90
+
91
+ /** Record, audit, lifecycle ledger and event intent either all commit or none do. */
92
+ export async function mutateRecord(input: RecordMutationInput, allowCreate: boolean): Promise<RecordMutationResult> {
93
+ const ownerId = effectiveRecordOwner(input.principal);
94
+ const now = input.now ?? new Date().toISOString();
95
+ if (!canonical(now) || typeof input.name !== 'string' || !input.name || input.name.length > 256 ||
96
+ typeof input.runScope !== 'string' || !input.runScope || input.runScope.length > 128 ||
97
+ !input.correlationId || input.correlationId.length > 128)
98
+ failure('record_input_invalid', 'Record input is invalid.', 400);
99
+ const requestRef = lifecycleIdempotencyKey('record-put', [input.recordId, ownerId, input.correlationId]);
100
+ // Time is assigned only on the first successful mutation, not reconstructed on retry.
101
+ const commandDigest = hash([input.recordId, ownerId, input.principal.actor.id, input.principal.authority.mode,
102
+ input.name, input.runScope, input.testExpiresAt ?? null]);
103
+ const store = dataStore();
104
+ const row = await store.get('application', 'records', input.recordId);
105
+ const previous = row ? readProductRecord(row.value, input.recordId) : null;
106
+ if (previous && previous.ownerId !== ownerId)
107
+ failure('record_conflict', 'The record identifier is owned by another principal.', 409);
108
+ if (!previous && !allowCreate) failure('record_not_found', 'The correction target was not found.', 404);
109
+
110
+ async function retained(): Promise<RecordMutationResult | null> {
111
+ const receipt = await store.get('application', 'record-mutations', requestRef);
112
+ if (!receipt) return null;
113
+ const value = receipt.value as { commandDigest: string; result: { requestRef: string; created: boolean } };
114
+ if (!value || value.commandDigest !== commandDigest ||
115
+ value.result?.requestRef !== requestRef || typeof value.result.created !== 'boolean')
116
+ failure('record_idempotency_conflict', 'The mutation receipt does not match this exact request.', 409);
117
+ return { id: input.recordId, name: input.name, runScope: input.runScope,
118
+ propagation: 'pending', requestRef, created: value.result.created };
119
+ }
120
+ const repeated = await retained();
121
+ if (repeated) {
122
+ if (!previous) failure('record_not_found', 'The record no longer exists.', 404);
123
+ return repeated;
124
+ }
125
+ if (input.testExpiresAt !== undefined && (!canonical(input.testExpiresAt) ||
126
+ Date.parse(input.testExpiresAt) <= Date.parse(now) ||
127
+ Date.parse(input.testExpiresAt) - Date.parse(now) > 48 * 60 * 60 * 1_000))
128
+ failure('test_data_expiry_invalid', 'Test data expiry must be a canonical future timestamp within 48 hours.', 400);
129
+ const record: ProductRecord = {
130
+ id: input.recordId, name: input.name, ownerId, runScope: input.runScope,
131
+ createdAt: previous?.createdAt ?? now, lastActivityAt: now,
132
+ testExpiresAt: input.testExpiresAt ?? previous?.testExpiresAt ?? null,
133
+ };
134
+ const result: RecordMutationResult = { id: record.id, name: record.name, runScope: record.runScope,
135
+ propagation: 'pending', requestRef, created: !previous };
136
+ const policyVersion = ${pascalName}DataLifecycleRuntimePolicy.policyVersion;
137
+ const expiresAt = new Date(Date.parse(now) + 400 * 24 * 60 * 60 * 1_000).toISOString();
138
+ const recordRef = productRecordReference(record.id);
139
+ const entry = buildEventEntry(previous ? ${pascalName}DataLifecycleChanged : ${pascalName}Created,
140
+ previous ? create${pascalName}DataLifecycleChanged({ action: 'correction', occurredAt: now,
141
+ policyVersion, recordId: record.id, requestRef }) : { id: record.id, occurredBy: ownerId }, {
142
+ busName: process.env.EVENT_BUS_NAME ?? '', stage: process.env.EBK_STAGE ?? '',
143
+ context: { correlationId: input.correlationId, tenantId: 'application' }, eventId: requestRef, occurredAt: now,
144
+ }).entry;
145
+ const changes: Parameters<typeof store.commit>[0]['changes'][number][] = [
146
+ { action: 'put', collection: 'records', id: record.id, expectedVersion: row?.version ?? 0, value: record },
147
+ { action: 'put', collection: 'record-mutations', id: requestRef, expectedVersion: 0,
148
+ // Retry metadata must not retain a second copy of subject-owned content.
149
+ value: { commandDigest, result: { requestRef, created: result.created }, occurredAt: now, expiresAt } },
150
+ ];
151
+ if (previous) {
152
+ const pseudonym = (categoryId: string, value: string) => createDataLifecyclePseudonymousReference({
153
+ categoryId, slice: '${name}', value });
154
+ const audit = createDataLifecycleAuditRecord({ action: 'correction',
155
+ actorRef: pseudonym('authorization-subject', input.principal.actor.id), authorityCode: input.principal.authority.mode,
156
+ correlationRef: pseudonym('correlation', input.correlationId), outcome: 'succeeded', policyVersion,
157
+ purposeCode: 'record-correction', summary: 'A record correction and its downstream event were committed.',
158
+ targetCategoryId: 'product-record', timestamp: now });
159
+ changes.push(
160
+ { action: 'put', collection: 'data-lifecycle-ledger', id: requestRef, expectedVersion: 0,
161
+ value: createDataLifecycleLedgerEntry({ action: 'correction', categoryId: 'product-record',
162
+ effectiveAt: now, expiresAt, policyVersion, pseudonymousKey: recordRef }) },
163
+ { action: 'put', collection: 'data-lifecycle-audit', id: requestRef, expectedVersion: 0,
164
+ value: { audit, resourceReference: recordRef, principalKind: input.principal.kind,
165
+ subjectType: input.principal.actor.type, slice: '${name}', stage: process.env.EBK_STAGE,
166
+ approvalReference: null, expiresAt } },
167
+ );
168
+ }
169
+ try {
170
+ await store.commit({ tenantId: 'application', changes, events: [entry] });
171
+ } catch (error) {
172
+ if (!conditionConflict(error)) throw error;
173
+ // A concurrent exact retry may have committed. Anything else is a real
174
+ // optimistic-write conflict, never an accepted partial correction.
175
+ const latest = await getOwnedRecord(input.recordId, ownerId);
176
+ const replay = latest ? await retained() : null;
177
+ if (replay) return replay;
178
+ failure('record_write_conflict', 'The record changed concurrently; retry the request.', 409);
179
+ }
180
+ return result;
181
+ }
182
+ `,
183
+ 'data/record-correction.ts': `import { mutateRecord, type RecordMutationInput } from './records.js';
184
+ import { dispatchEventIntent } from '../async/key-value-delivery.js';
185
+
186
+ export type RecordCorrectionInput = RecordMutationInput;
187
+ export const correctRecordWithLifecycle = (input: RecordCorrectionInput) => mutateRecord(input, false);
188
+ export const putRecordWithLifecycle = (input: RecordMutationInput) => mutateRecord(input, true);
189
+
190
+ export async function publishRecordCorrection(_correlationId: string, requestRef: string) {
191
+ return dispatchEventIntent(requestRef);
192
+ }
193
+ `,
194
+ };
195
+ }
196
+ function renderKeyValueRecordApi(pascalName, workspace) {
197
+ const prefix = (0, built_in_plan_shared_js_1.lowerCamelIdentifier)(pascalName);
198
+ return `import type { RuntimeHttpEvent } from '@empire-builder-kit/runtime';
199
+ import type { Principal } from '@empire-builder-kit/runtime/auth';
200
+ import type { AuthorizationPrincipal } from '@empire-builder-kit/runtime/authorization';
201
+ import { createContractHttpJsonHandler } from '@empire-builder-kit/runtime/api-server';
202
+ import { RuntimeError } from '@empire-builder-kit/runtime/response';
203
+ import { ${prefix}GetRecord, ${prefix}PutRecord } from '../api/contracts/protected.js';
204
+ import { authorize${pascalName}DataRightsOperation, authorize${pascalName}Operation } from '../authorization/runtime.js';
205
+ import { putRecordWithLifecycle } from '../data/record-correction.js';
206
+ import { getOwnedRecord } from '../data/records.js';
207
+
208
+ export const putHandler = createContractHttpJsonHandler<typeof ${prefix}PutRecord, RuntimeHttpEvent, AuthorizationPrincipal>({
209
+ component: 'database-records', operation: ${prefix}PutRecord, workspace: '${workspace}',
210
+ authorize: authorize${pascalName}DataRightsOperation,
211
+ async handle({ context, principal, request }) {
212
+ const result = await putRecordWithLifecycle({ correlationId: context.correlationId, principal,
213
+ recordId: request.path.recordId, name: request.body.name, runScope: request.body.runScope,
214
+ testExpiresAt: request.body.testExpiresAt });
215
+ // The durable intent commits with the record; Streams/reconciliation own
216
+ // delivery. An EventBridge outage cannot turn a committed write into loss.
217
+ return { id: result.id, name: result.name, runScope: result.runScope };
218
+ },
219
+ });
220
+
221
+ export const getHandler = createContractHttpJsonHandler<typeof ${prefix}GetRecord, RuntimeHttpEvent, Principal>({
222
+ component: 'database-records', operation: ${prefix}GetRecord, workspace: '${workspace}',
223
+ authorize: authorize${pascalName}Operation,
224
+ async handle({ principal, request }) {
225
+ const record = await getOwnedRecord(request.path.recordId, principal.id);
226
+ if (!record) throw new RuntimeError({ code: 'record_not_found', message: 'The record was not found.', status: 404, retryable: false });
227
+ return { id: record.id, name: record.name, runScope: record.runScope };
228
+ },
229
+ });
230
+ `;
231
+ }
232
+ //# sourceMappingURL=built-in-plan-key-value-records.js.map
@@ -0,0 +1,2 @@
1
+ /** Framework retention uses native DynamoDB regardless of optional feature SQL. */
2
+ export declare function renderKeyValueRetentionInfrastructureFiles(name: string, pascalName: string): Readonly<Record<string, string>>;