@empire-builder-kit/nx 1.0.0-rc.38 → 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 +3 -1
  169. package/src/generators/slice/built-in-plan-shared.js +40 -18
  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 +191 -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,477 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderKeyValueRetentionWorkerFiles = renderKeyValueRetentionWorkerFiles;
4
+ const built_in_plan_shared_js_1 = require("./built-in-plan-shared.js");
5
+ /** Native bounded retention execution; no database credential, SQL adapter, or container prerequisite. */
6
+ function renderKeyValueRetentionWorkerFiles(name, pascalName) {
7
+ const prefix = (0, built_in_plan_shared_js_1.lowerCamelIdentifier)(pascalName);
8
+ return {
9
+ 'jobs/data-retention/src/adapter.ts': `import type { DataLifecycleRetentionCandidateV1 } from '@empire-builder-kit/runtime/data-lifecycle';
10
+ import type { KeyValueRecord } from '@empire-builder-kit/runtime/key-value';
11
+ import { productRecordReference } from '../../../data/pseudonymous-reference.js';
12
+ import { readProductRecord } from '../../../data/records.js';
13
+ import { RETENTION_DAYS } from '../../../data/retention-state.js';
14
+
15
+ export interface RetentionCandidate extends DataLifecycleRetentionCandidateV1 { recordId: string; recordVersion: number }
16
+ /** Adopter-owned selection of due Standard records; test-run cleanup is separate. */
17
+ export function selectRetentionCandidate(row: KeyValueRecord & { id: string }, asOf: string): RetentionCandidate | null {
18
+ const record = readProductRecord(row.value, row.id);
19
+ const dueAt = new Date(Date.parse(record.lastActivityAt) + RETENTION_DAYS * 86_400_000).toISOString();
20
+ if (record.testExpiresAt !== null || Date.parse(dueAt) > Date.parse(asOf)) return null;
21
+ return { categoryId: 'product-record', locationId: 'primary-database', dueAt,
22
+ recordRef: productRecordReference(row.id), recordId: row.id, recordVersion: row.version };
23
+ }
24
+ `,
25
+ 'data/retention-worker.ts': `import { createHash } from 'node:crypto';
26
+ import {
27
+ assertAuthorizationAllowed, beginApprovalExecution, completeApprovalExecution,
28
+ createAuthorizationEvaluator, defineCoarseAdmission, digestApprovalRequest,
29
+ type AuthorizationPrincipal,
30
+ } from '@empire-builder-kit/runtime/authorization';
31
+ import { buildEventEntry } from '@empire-builder-kit/runtime/events';
32
+ import {
33
+ createDataLifecycleEvidence, createDataLifecycleLedgerEntry, createDataLifecycleRetentionCheckpoint,
34
+ runDataLifecycleRetention, type DataLifecycleRetentionCheckpointV1,
35
+ } from '@empire-builder-kit/runtime/data-lifecycle';
36
+ import { ${prefix}AuthorizationActions, ${prefix}AuthorizationPolicy } from '../authorization/policy.js';
37
+ import { ${pascalName}DataLifecycleChanged } from '../contracts/events.js';
38
+ import { dispatchEventIntent } from '../async/key-value-delivery.js';
39
+ import { selectRetentionCandidate, type RetentionCandidate } from '../jobs/data-retention/src/adapter.js';
40
+ import { dataStore } from './key-value.js';
41
+ import { dataRightsAuditChange, canonicalDataRightsNow, plusDataRightsDays } from './data-rights-shared.js';
42
+ import { approvalReference, productRecordReference } from './pseudonymous-reference.js';
43
+ import { loadActiveRecordHolds } from './record-holds.js';
44
+ import { create${pascalName}DataLifecycleChanged } from './lifecycle-event.js';
45
+ import { createReportedRetentionRun, loadRetentionRun, retentionApprovalInput, retentionRunChange,
46
+ retentionRunReference, retentionStage, RETENTION_RUNS, RETENTION_POLICY, RETENTION_DAYS,
47
+ RETENTION_AUTHORIZATION_POLICY, type RetentionRun, type ${pascalName}RetentionPlanV1 } from './retention-state.js';
48
+
49
+ const TENANT = 'application';
50
+ const SNAPSHOTS = 'data-retention-snapshots';
51
+ const CANDIDATES = 'data-retention-candidates';
52
+ const EXECUTIONS = 'data-retention-executions';
53
+ const RECEIPTS = 'data-retention-receipts';
54
+ const CHUNK_SIZE = 50;
55
+ const MAX_ITEMS = 10000;
56
+ const REPORT_PAGES_PER_INVOCATION = 20;
57
+ const WORKLOAD = '${name}:data-retention-job';
58
+ const sha = (value: unknown) => 'sha256:' + createHash('sha256').update(JSON.stringify(value)).digest('hex');
59
+ const planDigest = (run: RetentionRun) => digestApprovalRequest(retentionApprovalInput(run.plan));
60
+ const chunkId = (runId: string, index: number) => runId + ':' + String(index).padStart(4, '0');
61
+ const now = () => new Date().toISOString();
62
+ class DeliveryPending extends Error {}
63
+ interface Snapshot {
64
+ kind: 'retention-snapshot'; runId: string; slice: '${name}'; stage: string;
65
+ status: 'building' | 'completed'; createdAt: string; expiresAt: string;
66
+ pages: string[]; due: number; scanned: number; queryPages: number; planDigest: string | null;
67
+ binding: string; afterId: string | null; tail: RetentionCandidate[]; scanComplete: boolean;
68
+ command: RetentionInput;
69
+ }
70
+ interface Execution {
71
+ kind: 'retention-execution'; runId: string; planDigest: string; approvalId: string;
72
+ checkpoint: DataLifecycleRetentionCheckpointV1;
73
+ pageAttempts: number; replays: number; completedAt: string | null;
74
+ }
75
+ interface Receipt {
76
+ kind: 'retention-receipt'; runId: string; planDigest: string; candidateDigest: string;
77
+ eventId: string; appliedAt: string; publishedAt: string | null; expiresAt: string;
78
+ }
79
+ export interface RetentionInput {
80
+ mode: 'report' | 'apply'; runId: string; approvalRequestId: string;
81
+ asOf: string; correlationId: string; slice: string; stage: string; sourceCommit: string;
82
+ resume?: true;
83
+ }
84
+ function reportBinding(command: RetentionInput) {
85
+ // Stored JSON is canonicalized; never bind to incidental object-key order.
86
+ return sha({ mode: command.mode, runId: command.runId, approvalRequestId: command.approvalRequestId,
87
+ asOf: command.asOf, correlationId: command.correlationId, slice: command.slice, stage: command.stage,
88
+ sourceCommit: command.sourceCommit, policy: RETENTION_POLICY, retentionDays: RETENTION_DAYS });
89
+ }
90
+ function input(value: RetentionInput) {
91
+ if (!value || (value.mode !== 'report' && value.mode !== 'apply') || value.slice !== '${name}' ||
92
+ value.stage !== retentionStage() || typeof value.asOf !== 'string' ||
93
+ !/^[a-f0-9]{40,64}$/.test(value.sourceCommit ?? '') ||
94
+ !/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(value.correlationId ?? ''))
95
+ throw new Error('Retention invocation identity or mode is invalid.');
96
+ retentionRunReference(value.runId); canonicalDataRightsNow(value.asOf);
97
+ if (value.resume !== undefined && (value.resume !== true || value.mode !== 'report'))
98
+ throw new Error('Only a report may resume its original selection.');
99
+ if (value.mode === 'apply') retentionRunReference(value.approvalRequestId);
100
+ else if (value.approvalRequestId !== '') throw new Error('A report cannot select mutation approval.');
101
+ }
102
+ export async function authorizeRetentionOperation(mode: 'report' | 'apply', at: string, runId: string): Promise<AuthorizationPrincipal> {
103
+ if (process.env.EBK_WORKLOAD_IDENTITY !== WORKLOAD) throw new Error('Retention Job workload identity is invalid.');
104
+ const principal: AuthorizationPrincipal = { actor: { id: WORKLOAD, type: 'service' }, audience: WORKLOAD,
105
+ authority: { machineIdentityId: WORKLOAD, mode: 'machine' }, kind: 'agent', roles: [], scopes: [], subject: { id: WORKLOAD, type: 'service' } };
106
+ await createAuthorizationEvaluator({ admission: defineCoarseAdmission({ anyOf: [{ kinds: ['agent'], subjectTypes: ['service'] }] }),
107
+ policy: ${prefix}AuthorizationPolicy, requiredPolicyVersion: RETENTION_AUTHORIZATION_POLICY }).authorize({
108
+ action: mode === 'report' ? ${prefix}AuthorizationActions.retentionReport : ${prefix}AuthorizationActions.retentionApply,
109
+ context: { facts: { operationId: runId }, now: at, stage: retentionStage() }, principal,
110
+ resource: { attributes: { collection: true }, type: 'slice' },
111
+ });
112
+ return principal;
113
+ }
114
+ function audit(command: RetentionInput, principal: AuthorizationPrincipal, purposeCode: string, at: string) {
115
+ return dataRightsAuditChange({ action: command.mode === 'report' ? 'retention-report' : 'retention-apply',
116
+ ...(command.approvalRequestId ? { approvalRequestId: command.approvalRequestId } : {}),
117
+ correlationId: command.correlationId, now: at, principal, resourceReference: retentionRunReference(command.runId),
118
+ purposeCode, outcome: 'succeeded', summary: 'A bounded native retention transition was committed.' });
119
+ }
120
+ function validateCandidate(value: RetentionCandidate, asOf: string): RetentionCandidate {
121
+ if (!value || typeof value.recordId !== 'string' || !/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(value.recordId) ||
122
+ !Number.isSafeInteger(value.recordVersion) || value.recordVersion < 1 || value.categoryId !== 'product-record' ||
123
+ value.locationId !== 'primary-database' || value.recordRef !== productRecordReference(value.recordId) || typeof value.dueAt !== 'string' ||
124
+ Object.keys(value).sort().join(',') !== 'categoryId,dueAt,locationId,recordId,recordRef,recordVersion')
125
+ throw new Error('Retention candidate does not belong to the exact record contract.');
126
+ canonicalDataRightsNow(value.dueAt);
127
+ if (Date.parse(value.dueAt) > Date.parse(asOf)) throw new Error('Retention candidate is not due.');
128
+ // Construct a deterministic projection independent of object property order.
129
+ return { categoryId: value.categoryId, locationId: value.locationId, dueAt: value.dueAt,
130
+ recordRef: value.recordRef, recordId: value.recordId, recordVersion: value.recordVersion };
131
+ }
132
+ function inventoryDigest(pages: readonly string[], due: number) { return sha({ pages, due, chunkSize: CHUNK_SIZE }); }
133
+ function bounded(deadline: number) {
134
+ if (Date.now() >= deadline) throw new Error('Retention invocation time budget exhausted; retained state requires retry, not success.');
135
+ }
136
+ async function report(command: RetentionInput, principal: AuthorizationPrincipal, startedAt: string, deadline: number) {
137
+ if (Date.parse(command.asOf) > Date.parse(startedAt)) throw new Error('Retention report cannot select future records.');
138
+ const store = dataStore();
139
+ const binding = reportBinding(command);
140
+ const retained = await store.get(TENANT, SNAPSHOTS, command.runId);
141
+ let version = retained?.version ?? 0;
142
+ let building: Snapshot = retained ? retained.value as Snapshot : {
143
+ kind: 'retention-snapshot', runId: command.runId, slice: '${name}', stage: retentionStage(),
144
+ status: 'building', createdAt: startedAt, expiresAt: plusDataRightsDays(startedAt, 400),
145
+ pages: [], due: 0, scanned: 0, queryPages: 0, planDigest: null,
146
+ binding, command: { ...command }, afterId: null, tail: [], scanComplete: false };
147
+ if (!building || building.kind !== 'retention-snapshot' || building.runId !== command.runId ||
148
+ building.slice !== '${name}' || building.stage !== retentionStage() || building.binding !== binding ||
149
+ !building.command || reportBinding(building.command) !== binding ||
150
+ !['building', 'completed'].includes(building.status) || !Array.isArray(building.pages) ||
151
+ building.pages.some(page => !/^sha256:[a-f0-9]{64}$/.test(page)) || !Array.isArray(building.tail) ||
152
+ building.tail.length >= CHUNK_SIZE || typeof building.scanComplete !== 'boolean' ||
153
+ !Number.isSafeInteger(building.due) || building.due < 0 || building.due > MAX_ITEMS ||
154
+ !Number.isSafeInteger(building.scanned) || building.scanned < building.due ||
155
+ !Number.isSafeInteger(building.queryPages) || building.queryPages < 0 ||
156
+ typeof building.createdAt !== 'string' || typeof building.expiresAt !== 'string' ||
157
+ (building.afterId !== null && !/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(building.afterId)) ||
158
+ building.expiresAt !== plusDataRightsDays(canonicalDataRightsNow(building.createdAt), 400) ||
159
+ Date.parse(startedAt) >= Date.parse(building.expiresAt))
160
+ throw new Error('Retention report checkpoint differs from this invocation or has expired.');
161
+ building.tail = building.tail.map(candidate => validateCandidate(candidate, command.asOf));
162
+ if (building.scanComplete ? building.tail.length !== 0 || building.pages.length !== Math.ceil(building.due / CHUNK_SIZE)
163
+ : building.pages.length * CHUNK_SIZE + building.tail.length !== building.due)
164
+ throw new Error('Retention report checkpoint has inconsistent candidate counts.');
165
+ if (building.status === 'completed') {
166
+ const { run } = await loadRetentionRun(command.runId, startedAt);
167
+ if (run.status !== 'reported')
168
+ throw new Error('Retention report cannot be resumed after approval or execution; retained apply evidence is unchanged.');
169
+ await snapshotFor(run);
170
+ return finishEvidence(command, run, { applied: 0, alreadyApplied: 0, applyPages: 0,
171
+ due: building.due, reportPages: building.queryPages }, building.createdAt, run.createdAt);
172
+ }
173
+ if (!retained) {
174
+ await store.commit({ tenantId: TENANT, changes: [
175
+ { action: 'check', collection: RETENTION_RUNS, id: command.runId, expectedVersion: 0 },
176
+ { action: 'put', collection: SNAPSHOTS, id: command.runId, expectedVersion: 0, value: building },
177
+ ] });
178
+ version++;
179
+ }
180
+ // Each invocation scans at most 1,000 rows. The 10,000 bound applies to the
181
+ // reviewed deletion batch, not to unrelated healthy records in the table.
182
+ for (let queries = 0; !building.scanComplete && queries < REPORT_PAGES_PER_INVOCATION; queries++) {
183
+ if (Date.now() >= deadline) return { complete: false as const, runRef: command.runId, checkpointComplete: false };
184
+ const page = await store.list(TENANT, 'records', { limit: CHUNK_SIZE,
185
+ ...(building.afterId ? { afterId: building.afterId } : {}) });
186
+ let afterId = building.afterId, scanned = building.scanned, due = building.due;
187
+ const candidates = [...building.tail];
188
+ for (const row of page.records) {
189
+ if (afterId && row.id <= afterId) throw new Error('Retention inventory did not advance.');
190
+ scanned++; afterId = row.id;
191
+ const selected = selectRetentionCandidate(row, command.asOf);
192
+ if (selected) {
193
+ const candidate = validateCandidate(selected, command.asOf);
194
+ if (candidate.recordId !== row.id || candidate.recordVersion !== row.version) throw new Error('Retention adapter substituted the record identity.');
195
+ candidates.push(candidate); due++;
196
+ }
197
+ if (due === MAX_ITEMS) break;
198
+ }
199
+ if (page.nextId && due < MAX_ITEMS && (page.records.length === 0 || page.nextId !== afterId))
200
+ throw new Error('Retention inventory is incomplete or its cursor is invalid.');
201
+ const scanComplete = !page.nextId || due === MAX_ITEMS;
202
+ const pages = [...building.pages], chunks = [];
203
+ while (candidates.length >= CHUNK_SIZE || (scanComplete && candidates.length)) {
204
+ const records = candidates.splice(0, CHUNK_SIZE), index = pages.length;
205
+ pages.push(sha(records));
206
+ chunks.push({ action: 'put' as const, collection: CANDIDATES, id: chunkId(command.runId, index), expectedVersion: 0,
207
+ value: { runId: command.runId, stage: retentionStage(), slice: '${name}', index, records, expiresAt: building.expiresAt } });
208
+ }
209
+ const next = { ...building, pages, due, scanned, queryPages: building.queryPages + 1,
210
+ afterId, tail: candidates, scanComplete };
211
+ bounded(deadline);
212
+ await store.commit({ tenantId: TENANT, changes: [
213
+ { action: 'check', collection: RETENTION_RUNS, id: command.runId, expectedVersion: 0 },
214
+ { action: 'put', collection: SNAPSHOTS, id: command.runId, expectedVersion: version, value: next }, ...chunks,
215
+ ] });
216
+ building = next; version++;
217
+ }
218
+ if (!building.scanComplete) return { complete: false as const, runRef: command.runId, checkpointComplete: false };
219
+ bounded(deadline);
220
+ const completedAt = now();
221
+ const plan: ${pascalName}RetentionPlanV1 = { asOf: command.asOf, candidateDigest: inventoryDigest(building.pages, building.due),
222
+ categoryId: 'product-record', due: building.due, locationId: 'primary-database', maxItems: 10000,
223
+ pageSize: 100, policyVersion: RETENTION_POLICY, retentionDays: RETENTION_DAYS, runId: command.runId };
224
+ const run = createReportedRetentionRun(plan, completedAt);
225
+ const snapshot: Snapshot = { ...building, status: 'completed', planDigest: planDigest(run) };
226
+ await store.commit({ tenantId: TENANT, changes: [retentionRunChange(run, 0),
227
+ { action: 'put', collection: SNAPSHOTS, id: command.runId, expectedVersion: version, value: snapshot },
228
+ audit(command, principal, 'report-completed', completedAt),
229
+ ] });
230
+ return finishEvidence(command, run, { applied: 0, alreadyApplied: 0, applyPages: 0, due: building.due, reportPages: building.queryPages }, building.createdAt, completedAt);
231
+ }
232
+ async function snapshotFor(run: RetentionRun) {
233
+ const row = await dataStore().get(TENANT, SNAPSHOTS, run.plan.runId);
234
+ const value = row?.value as Snapshot | undefined;
235
+ if (!value || value.kind !== 'retention-snapshot' || value.status !== 'completed' || value.runId !== run.plan.runId ||
236
+ value.stage !== run.stage || value.slice !== '${name}' || value.planDigest !== planDigest(run) || value.due !== run.plan.due ||
237
+ !Array.isArray(value.pages) || value.pages.length !== Math.ceil(value.due / CHUNK_SIZE) ||
238
+ value.pages.some(digest => typeof digest !== 'string' || !/^sha256:[a-f0-9]{64}$/.test(digest)) ||
239
+ inventoryDigest(value.pages, value.due) !== run.plan.candidateDigest ||
240
+ !Number.isSafeInteger(value.scanned) || value.scanned < value.due ||
241
+ !Number.isSafeInteger(value.queryPages) || value.queryPages < 1 ||
242
+ value.scanComplete !== true || value.tail?.length !== 0 ||
243
+ typeof value.createdAt !== 'string' || typeof value.expiresAt !== 'string')
244
+ throw new Error('The approved retention snapshot is missing or inconsistent.');
245
+ canonicalDataRightsNow(value.createdAt); canonicalDataRightsNow(value.expiresAt);
246
+ if (value.expiresAt !== plusDataRightsDays(value.createdAt, 400) || Date.parse(now()) >= Date.parse(value.expiresAt))
247
+ throw new Error('The approved retention snapshot is expired.');
248
+ return { snapshot: value, version: row!.version };
249
+ }
250
+ async function candidatePage(run: RetentionRun, snapshot: Snapshot, offset: number, limit: number) {
251
+ const result: RetentionCandidate[] = [];
252
+ for (let index = Math.floor(offset / CHUNK_SIZE); index < Math.ceil(Math.min(offset + limit, snapshot.due) / CHUNK_SIZE); index++) {
253
+ const row = await dataStore().get(TENANT, CANDIDATES, chunkId(run.plan.runId, index));
254
+ const value = row?.value as { runId: string; stage: string; slice: string; index: number; records: RetentionCandidate[]; expiresAt: string } | undefined;
255
+ if (!value || value.runId !== run.plan.runId || value.stage !== run.stage || value.slice !== '${name}' || value.index !== index ||
256
+ !Array.isArray(value.records) || value.records.length !== Math.min(CHUNK_SIZE, snapshot.due - index * CHUNK_SIZE) ||
257
+ value.expiresAt !== snapshot.expiresAt)
258
+ throw new Error('Retention candidate page is missing or outside its approved snapshot.');
259
+ const records = value.records.map(record => validateCandidate(record, run.plan.asOf));
260
+ if (sha(records) !== snapshot.pages[index]) throw new Error('Retention candidate page changed after approval.');
261
+ result.push(...records);
262
+ }
263
+ const selected = result.slice(offset % CHUNK_SIZE, offset % CHUNK_SIZE + limit);
264
+ if (new Set(selected.map(record => record.recordId)).size !== selected.length) throw new Error('Retention candidate page has duplicate records.');
265
+ return selected;
266
+ }
267
+ function offsetFor(checkpoint: DataLifecycleRetentionCheckpointV1, due: number) {
268
+ if (!checkpoint || checkpoint.version !== 1 || checkpoint.policyVersion !== RETENTION_POLICY || typeof checkpoint.complete !== 'boolean')
269
+ throw new Error('Retention execution checkpoint is malformed.');
270
+ if (checkpoint.complete) {
271
+ if (checkpoint.cursor !== undefined) throw new Error('Completed retention cannot retain a cursor.');
272
+ return due;
273
+ }
274
+ if (checkpoint.cursor === undefined) return 0;
275
+ if (!/^offset_[1-9][0-9]*$/.test(checkpoint.cursor)) throw new Error('Retention execution cursor is invalid.');
276
+ const offset = Number(checkpoint.cursor.slice(7));
277
+ if (!Number.isSafeInteger(offset) || offset % 100 || offset >= due) throw new Error('Retention execution cursor is outside its approved plan.');
278
+ return offset;
279
+ }
280
+ async function executionFor(run: RetentionRun) {
281
+ const row = await dataStore().get(TENANT, EXECUTIONS, run.plan.runId);
282
+ const value = row?.value as Execution | undefined;
283
+ if (!row || !value || value.kind !== 'retention-execution' || value.runId !== run.plan.runId || value.planDigest !== planDigest(run) ||
284
+ value.approvalId !== run.approval?.id || !Number.isSafeInteger(value.pageAttempts) || value.pageAttempts < 0 ||
285
+ !Number.isSafeInteger(value.replays) || value.replays < 0)
286
+ throw new Error('Retention execution is missing or no longer matches its approval.');
287
+ offsetFor(value.checkpoint, run.plan.due);
288
+ if (value.completedAt !== null) {
289
+ if (typeof value.completedAt !== 'string') throw new Error('Retention completion time is invalid.');
290
+ canonicalDataRightsNow(value.completedAt);
291
+ if (!value.checkpoint.complete || run.status !== 'completed' || value.completedAt !== run.approval?.execution?.completedAt)
292
+ throw new Error('Retention lacks matching completed execution evidence.');
293
+ } else if (run.status === 'completed') throw new Error('Retention completion evidence is missing.');
294
+ return { execution: value, version: row.version };
295
+ }
296
+ async function applyCandidate(command: RetentionInput, principal: AuthorizationPrincipal, run: RetentionRun, runVersion: number,
297
+ candidate: RetentionCandidate, idempotencyKey: string) {
298
+ const store = dataStore();
299
+ const eventId = 'retention-' + createHash('sha256').update(command.runId + '\\0' + idempotencyKey).digest('hex');
300
+ const receiptId = command.runId + ':' + eventId;
301
+ let row = await store.get(TENANT, RECEIPTS, receiptId);
302
+ let receipt = row?.value as Receipt | undefined;
303
+ const prior = !!row;
304
+ if (!row) {
305
+ const record = await store.get(TENANT, 'records', candidate.recordId);
306
+ if (!record || record.version !== candidate.recordVersion) throw new Error('A reviewed record changed; create and approve a new retention report.');
307
+ const current = selectRetentionCandidate({ ...record, id: candidate.recordId }, run.plan.asOf);
308
+ if (!current || sha(validateCandidate(current, run.plan.asOf)) !== sha(candidate)) throw new Error('The reviewed record is no longer due.');
309
+ const at = now();
310
+ const holds = await loadActiveRecordHolds(candidate.recordId, at, 'deletion');
311
+ if (holds.evaluation.blocked) throw new Error('Retention deletion is blocked by an active hold.');
312
+ receipt = { kind: 'retention-receipt', runId: command.runId, planDigest: planDigest(run), candidateDigest: sha(candidate),
313
+ eventId, appliedAt: at, publishedAt: null, expiresAt: plusDataRightsDays(at, 400) };
314
+ const ledger = createDataLifecycleLedgerEntry({ action: 'deletion', categoryId: 'product-record', effectiveAt: at,
315
+ expiresAt: receipt.expiresAt, policyVersion: RETENTION_POLICY, pseudonymousKey: candidate.recordRef });
316
+ const entry = buildEventEntry(${pascalName}DataLifecycleChanged,
317
+ create${pascalName}DataLifecycleChanged({ action: 'deletion', occurredAt: at, policyVersion: RETENTION_POLICY,
318
+ recordId: candidate.recordId, requestRef: approvalReference(command.approvalRequestId) }),
319
+ { busName: process.env.EVENT_BUS_NAME ?? '', stage: retentionStage(), eventId, occurredAt: at,
320
+ context: { correlationId: command.correlationId, tenantId: TENANT } }).entry;
321
+ await store.commit({ tenantId: TENANT, changes: [
322
+ { action: 'check', collection: RETENTION_RUNS, id: command.runId, expectedVersion: runVersion },
323
+ { action: 'delete', collection: 'records', id: candidate.recordId, expectedVersion: candidate.recordVersion },
324
+ holds.check,
325
+ { action: 'put', collection: RECEIPTS, id: receiptId, expectedVersion: 0, value: receipt },
326
+ { action: 'put', collection: 'data-lifecycle-ledger', id: eventId, expectedVersion: 0, value: ledger },
327
+ audit(command, principal, 'primary-deleted', at),
328
+ ], events: [entry], retainEventsUntilAcknowledged: true });
329
+ row = await store.get(TENANT, RECEIPTS, receiptId); receipt = row?.value as Receipt | undefined;
330
+ }
331
+ if (!row || !receipt || receipt.kind !== 'retention-receipt' || receipt.runId !== command.runId ||
332
+ receipt.planDigest !== planDigest(run) || receipt.candidateDigest !== sha(candidate) || receipt.eventId !== eventId ||
333
+ typeof receipt.appliedAt !== 'string' || receipt.expiresAt !== plusDataRightsDays(receipt.appliedAt, 400))
334
+ throw new Error('Retention receipt is missing or differs from the approved effect.');
335
+ canonicalDataRightsNow(receipt.appliedAt);
336
+ if (Date.parse(receipt.appliedAt) > Date.parse(now()) || Date.parse(now()) >= Date.parse(receipt.expiresAt)) throw new Error('Retention receipt is expired or future-dated.');
337
+ if (receipt.publishedAt !== null) {
338
+ if (typeof receipt.publishedAt !== 'string') throw new Error('Retention delivery evidence is invalid.');
339
+ canonicalDataRightsNow(receipt.publishedAt);
340
+ if (Date.parse(receipt.publishedAt) < Date.parse(receipt.appliedAt) || Date.parse(receipt.publishedAt) > Date.parse(now())) throw new Error('Retention delivery time is invalid.');
341
+ return 'already-applied' as const;
342
+ }
343
+ const delivery = await dispatchEventIntent(eventId);
344
+ if (delivery === 'delivery-pending') throw new DeliveryPending('Another worker holds the durable delivery lease.');
345
+ if (delivery !== 'published') throw new Error('Retention event remains unacknowledged; retry the exact approved run.');
346
+ await store.commit({ tenantId: TENANT, changes: [
347
+ { action: 'check', collection: RETENTION_RUNS, id: command.runId, expectedVersion: runVersion },
348
+ { action: 'put', collection: RECEIPTS, id: receiptId, expectedVersion: row.version, value: { ...receipt, publishedAt: now() } },
349
+ ], acknowledgeEvents: [eventId] });
350
+ return prior ? 'already-applied' as const : 'applied' as const;
351
+ }
352
+ function finishEvidence(command: RetentionInput, run: RetentionRun, counts: {
353
+ applied: number; alreadyApplied: number; applyPages: number; due: number; reportPages: number;
354
+ }, startedAt: string, completedAt: string) {
355
+ return { complete: true as const, runRef: command.runId, counts, planDigest: 'sha256:' + planDigest(run),
356
+ ...(command.mode === 'apply' ? { approvalRequestId: command.approvalRequestId, checkpointComplete: true } : {}),
357
+ evidence: createDataLifecycleEvidence({ categoryId: 'product-record', completedAt, counts,
358
+ operation: command.mode === 'apply' ? 'retention-apply' : 'retention-report', outcome: 'succeeded',
359
+ policyVersion: RETENTION_POLICY, ...(command.approvalRequestId ? { requestRef: approvalReference(command.approvalRequestId) } : {}),
360
+ startedAt, summary: command.mode === 'report' ? 'Bounded native retention report completed without product-data mutation.'
361
+ : 'Bounded native retention apply and durable event delivery completed under non-author approval.',
362
+ systemIds: ['primary-database', 'lifecycle-control'] }),
363
+ };
364
+ }
365
+ export async function runNativeRetention(command: RetentionInput, budgetMs = 240_000) {
366
+ input(command);
367
+ if (!Number.isSafeInteger(budgetMs) || budgetMs < 1 || budgetMs > 240_000) throw new Error('Retention requires a bounded invocation budget.');
368
+ const startedAt = now(), deadline = Date.now() + budgetMs;
369
+ const principal = await authorizeRetentionOperation(command.mode, startedAt, command.runId);
370
+ bounded(deadline);
371
+ if (command.resume) {
372
+ const row = await dataStore().get(TENANT, SNAPSHOTS, command.runId);
373
+ const original = (row?.value as Snapshot | undefined)?.command;
374
+ if (!original) throw new Error('Retention report resume requires its existing checkpoint.');
375
+ input(original);
376
+ if (original.mode !== 'report' || original.resume !== undefined || original.runId !== command.runId ||
377
+ original.slice !== command.slice || original.stage !== command.stage || original.sourceCommit !== command.sourceCommit)
378
+ throw new Error('Retention report resume differs from the original source or scope. Resume with the original checkout/artifacts and EBK_SOURCE_COMMIT=' + original.sourceCommit + '.');
379
+ // The new execution's clock/correlation cannot select additional records.
380
+ // report() revalidates the retained policy binding, expiry and checkpoint.
381
+ command = original;
382
+ }
383
+ if (command.mode === 'report') return report(command, principal, startedAt, deadline);
384
+ const store = dataStore();
385
+ let { run, version: runVersion } = await loadRetentionRun(command.runId, startedAt);
386
+ if (!run.approval || run.approval.id !== command.approvalRequestId) throw new Error('Retention apply requires its exact report approval.');
387
+ const { snapshot } = await snapshotFor(run);
388
+ if (run.status === 'completed') {
389
+ const { execution } = await executionFor(run);
390
+ if (!execution.completedAt) throw new Error('Retention completion is missing.');
391
+ return finishEvidence(command, run, { applied: run.plan.due, alreadyApplied: execution.replays,
392
+ applyPages: execution.pageAttempts, due: run.plan.due, reportPages: snapshot.queryPages }, run.approval.execution!.startedAt, execution.completedAt);
393
+ }
394
+ if (!['approval-approved', 'applying', 'retry-required'].includes(run.status)) throw new Error('Retention run is not approved for apply.');
395
+ const begun = beginApprovalExecution(run.approval, { ...retentionApprovalInput(run.plan), executionId: command.runId,
396
+ now: startedAt, requiredPolicyVersion: RETENTION_AUTHORIZATION_POLICY });
397
+ assertAuthorizationAllowed(begun.decision);
398
+ if (run.status === 'approval-approved') {
399
+ // Only the retained, approved candidates are mutation targets. Each target
400
+ // is revalidated with its exact version and hold set at the deletion below;
401
+ // later unrelated inserts cannot expand or invalidate this bounded approval.
402
+ const execution: Execution = { kind: 'retention-execution', runId: command.runId, planDigest: planDigest(run),
403
+ approvalId: command.approvalRequestId, checkpoint: createDataLifecycleRetentionCheckpoint(RETENTION_POLICY), pageAttempts: 0, replays: 0, completedAt: null };
404
+ bounded(deadline);
405
+ await store.commit({ tenantId: TENANT, changes: [
406
+ retentionRunChange({ ...run, approval: begun.request, status: 'applying', updatedAt: now() }, runVersion),
407
+ { action: 'put', collection: EXECUTIONS, id: command.runId, expectedVersion: 0, value: execution },
408
+ audit(command, principal, 'execution-started', now()),
409
+ ] });
410
+ ({ run, version: runVersion } = await loadRetentionRun(command.runId, now()));
411
+ }
412
+ let { execution, version: executionVersion } = await executionFor(run);
413
+ if (!execution.checkpoint.complete) {
414
+ const offset = offsetFor(execution.checkpoint, run.plan.due);
415
+ const candidates = await candidatePage(run, snapshot, offset, 100);
416
+ const lookup = new Map(candidates.map(candidate => [candidate.recordRef, candidate]));
417
+ let deliveryPending = false;
418
+ const result = await runDataLifecycleRetention({ asOf: run.plan.asOf, checkpoint: execution.checkpoint,
419
+ limit: 100, mode: 'apply', policyVersion: RETENTION_POLICY, adapter: {
420
+ scan: async () => ({ items: candidates, ...(offset + candidates.length < run.plan.due ? { nextCursor: 'offset_' + (offset + candidates.length) } : {}) }),
421
+ apply: async ({ candidate, idempotencyKey }) => {
422
+ bounded(deadline);
423
+ const retained = lookup.get(candidate.recordRef);
424
+ if (!retained) throw new Error('Retention candidate was not part of this reviewed page.');
425
+ try { return await applyCandidate(command, principal, run, runVersion, retained, idempotencyKey); }
426
+ catch (error) { deliveryPending = error instanceof DeliveryPending; throw error; }
427
+ },
428
+ } });
429
+ execution = { ...execution, checkpoint: result.checkpoint, pageAttempts: execution.pageAttempts + 1, replays: execution.replays + result.alreadyApplied };
430
+ await store.commit({ tenantId: TENANT, changes: [
431
+ { action: 'check', collection: RETENTION_RUNS, id: command.runId, expectedVersion: runVersion },
432
+ { action: 'put', collection: EXECUTIONS, id: command.runId, expectedVersion: executionVersion, value: execution },
433
+ ] });
434
+ executionVersion++;
435
+ if (result.status === 'retry-required') {
436
+ if (deliveryPending) return { complete: false as const, runRef: command.runId, checkpointComplete: false, deliveryPending: true };
437
+ throw new Error('Retention apply needs an exact-run retry; no success evidence was issued.');
438
+ }
439
+ if (!execution.checkpoint.complete) return { complete: false as const, runRef: command.runId, checkpointComplete: false };
440
+ }
441
+ bounded(deadline);
442
+ const completedAt = now();
443
+ const completed = completeApprovalExecution(run.approval!, { executionId: command.runId, now: completedAt, requiredPolicyVersion: RETENTION_AUTHORIZATION_POLICY });
444
+ assertAuthorizationAllowed(completed.decision);
445
+ run = { ...run, approval: completed.request, status: 'completed', updatedAt: completedAt };
446
+ await store.commit({ tenantId: TENANT, changes: [retentionRunChange(run, runVersion),
447
+ { action: 'put', collection: EXECUTIONS, id: command.runId, expectedVersion: executionVersion, value: { ...execution, completedAt } },
448
+ audit(command, principal, 'execution-completed', completedAt),
449
+ ] });
450
+ return finishEvidence(command, run, { applied: run.plan.due, alreadyApplied: execution.replays,
451
+ applyPages: execution.pageAttempts, due: run.plan.due, reportPages: snapshot.queryPages }, run.approval!.execution!.startedAt, completedAt);
452
+ }
453
+ `,
454
+ 'jobs/data-retention/src/run.ts': `import { createLogger } from '@empire-builder-kit/runtime/logging';
455
+ import { runNativeRetention, type RetentionInput } from '../../../data/retention-worker.js';
456
+ export { authorizeRetentionOperation } from '../../../data/retention-worker.js';
457
+
458
+ /** Step Functions invokes one bounded native page; only complete=true carries success evidence. */
459
+ export async function handler(event: RetentionInput, context?: { getRemainingTimeInMillis(): number }) {
460
+ const logger = createLogger({ component: 'job-data-retention', feature: 'data-lifecycle', operation: 'retention',
461
+ slice: '${name}', stage: process.env.EBK_STAGE ?? 'unknown', workspace: process.env.EBK_WORKSPACE ?? '${name}' });
462
+ try {
463
+ const remaining = context?.getRemainingTimeInMillis() ?? 250_000;
464
+ const result = await runNativeRetention(event, Math.min(240_000, remaining - 10_000));
465
+ logger.info('Native retention invocation completed', { attributes: { complete: result.complete },
466
+ outcome: result.complete ? 'success' : 'unknown' });
467
+ return result;
468
+ } catch (error) {
469
+ // No record values, secret material, snapshot identifiers or provider body is logged.
470
+ logger.error('Native retention invocation failed', { outcome: 'failure', attributes: { retryRequired: true } });
471
+ throw error;
472
+ }
473
+ }
474
+ `,
475
+ };
476
+ }
477
+ //# sourceMappingURL=built-in-plan-key-value-retention-worker.js.map
@@ -0,0 +1,2 @@
1
+ /** Framework retention control records remain in DynamoDB, including for SQL-enabled Slices. */
2
+ export declare function renderKeyValueRetentionFiles(name: string, pascalName: string): Readonly<Record<string, string>>;