@empire-builder-kit/nx 1.0.0-rc.30 → 1.0.0-rc.32

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 (310) hide show
  1. package/executors.json +8 -3
  2. package/package.json +14 -7
  3. package/src/aws/child-environment.d.ts +10 -0
  4. package/src/aws/child-environment.js +77 -0
  5. package/src/aws/child-environment.js.map +1 -0
  6. package/src/aws/identity.d.ts +13 -0
  7. package/src/aws/identity.js +41 -0
  8. package/src/aws/identity.js.map +1 -0
  9. package/src/aws-authority/index.d.ts +1 -0
  10. package/src/aws-authority/index.js +5 -0
  11. package/src/aws-authority/index.js.map +1 -0
  12. package/src/aws-authority/stage-authority.d.ts +240 -0
  13. package/src/aws-authority/stage-authority.js +2968 -0
  14. package/src/aws-authority/stage-authority.js.map +1 -0
  15. package/src/cli/main.d.ts +2 -0
  16. package/src/cli/main.js +11 -0
  17. package/src/cli/main.js.map +1 -1
  18. package/src/developer-agent/generator-planning.js +4 -4
  19. package/src/developer-agent/generator-planning.js.map +1 -1
  20. package/src/developer-agent/operation-registry.js +14 -6
  21. package/src/developer-agent/operation-registry.js.map +1 -1
  22. package/src/developer-agent/workspace-inspection.js +11 -2
  23. package/src/developer-agent/workspace-inspection.js.map +1 -1
  24. package/src/executors/deployment-plan/deployment-plan.js +1 -1
  25. package/src/executors/deployment-plan/deployment-plan.js.map +1 -1
  26. package/src/executors/foundation-preflight/foundation-preflight.d.ts +0 -1
  27. package/src/executors/foundation-preflight/foundation-preflight.js.map +1 -1
  28. package/src/executors/foundation-preflight/schema.json +0 -5
  29. package/src/executors/foundation-profile-preflight/foundation-profile-preflight.d.ts +12 -3
  30. package/src/executors/foundation-profile-preflight/foundation-profile-preflight.js +95 -32
  31. package/src/executors/foundation-profile-preflight/foundation-profile-preflight.js.map +1 -1
  32. package/src/executors/foundation-profile-preflight/production-database-safeguard.d.ts +64 -0
  33. package/src/executors/foundation-profile-preflight/production-database-safeguard.js +221 -0
  34. package/src/executors/foundation-profile-preflight/production-database-safeguard.js.map +1 -0
  35. package/src/executors/foundation-profile-preflight/schema.json +1 -6
  36. package/src/executors/foundation-remove-preflight/foundation-remove-preflight.d.ts +11 -1
  37. package/src/executors/foundation-remove-preflight/foundation-remove-preflight.js +44 -21
  38. package/src/executors/foundation-remove-preflight/foundation-remove-preflight.js.map +1 -1
  39. package/src/executors/foundation-remove-preflight/schema.json +6 -1
  40. package/src/executors/github-bootstrap/github-bootstrap.d.ts +1 -0
  41. package/src/executors/github-bootstrap/github-bootstrap.js +1 -0
  42. package/src/executors/github-bootstrap/github-bootstrap.js.map +1 -1
  43. package/src/executors/github-bootstrap/schema.json +7 -1
  44. package/src/executors/infrastructure-plan/infrastructure-plan.d.ts +27 -369
  45. package/src/executors/infrastructure-plan/infrastructure-plan.js +237 -5470
  46. package/src/executors/infrastructure-plan/infrastructure-plan.js.map +1 -1
  47. package/src/executors/infrastructure-plan/schema.json +8 -64
  48. package/src/executors/local-deploy/federated-credential-transport.d.ts +48 -0
  49. package/src/executors/local-deploy/federated-credential-transport.js +252 -0
  50. package/src/executors/local-deploy/federated-credential-transport.js.map +1 -0
  51. package/src/executors/local-deploy/local-approval.d.ts +4 -9
  52. package/src/executors/local-deploy/local-approval.js +3 -7
  53. package/src/executors/local-deploy/local-approval.js.map +1 -1
  54. package/src/executors/local-deploy/local-deploy.d.ts +60 -43
  55. package/src/executors/local-deploy/local-deploy.js +955 -804
  56. package/src/executors/local-deploy/local-deploy.js.map +1 -1
  57. package/src/executors/local-deploy/schema.json +3 -20
  58. package/src/executors/refresh/refresh.js +2 -2
  59. package/src/executors/refresh/refresh.js.map +1 -1
  60. package/src/executors/remove/remove.js +2 -2
  61. package/src/executors/remove/remove.js.map +1 -1
  62. package/src/executors/router-waf-rehearsal/router-waf-rehearsal.d.ts +27 -1
  63. package/src/executors/router-waf-rehearsal/router-waf-rehearsal.js +907 -22
  64. package/src/executors/router-waf-rehearsal/router-waf-rehearsal.js.map +1 -1
  65. package/src/executors/router-waf-rehearsal/schema.json +17 -2
  66. package/src/executors/secret-initialize/schema.json +42 -0
  67. package/src/executors/secret-initialize/secret-initialize.d.ts +32 -0
  68. package/src/executors/secret-initialize/secret-initialize.js +243 -0
  69. package/src/executors/secret-initialize/secret-initialize.js.map +1 -0
  70. package/src/executors/secret-metadata/secret-metadata.d.ts +4 -1
  71. package/src/executors/secret-metadata/secret-metadata.js +76 -29
  72. package/src/executors/secret-metadata/secret-metadata.js.map +1 -1
  73. package/src/executors/sst-lifecycle/generated-secret-retirement.d.ts +53 -0
  74. package/src/executors/sst-lifecycle/generated-secret-retirement.js +192 -0
  75. package/src/executors/sst-lifecycle/generated-secret-retirement.js.map +1 -0
  76. package/src/executors/sst-lifecycle/governed-native-operation.d.ts +46 -0
  77. package/src/executors/sst-lifecycle/governed-native-operation.js +153 -0
  78. package/src/executors/sst-lifecycle/governed-native-operation.js.map +1 -0
  79. package/src/executors/sst-lifecycle/run-sst-command.d.ts +27 -7
  80. package/src/executors/sst-lifecycle/run-sst-command.js +474 -89
  81. package/src/executors/sst-lifecycle/run-sst-command.js.map +1 -1
  82. package/src/executors/sst-lifecycle/schema.json +0 -5
  83. package/src/executors/sst-lifecycle/secret-preflight.d.ts +2 -0
  84. package/src/executors/sst-lifecycle/secret-preflight.js +13 -7
  85. package/src/executors/sst-lifecycle/secret-preflight.js.map +1 -1
  86. package/src/executors/unlock/unlock.js +2 -2
  87. package/src/executors/unlock/unlock.js.map +1 -1
  88. package/src/foundation/provision-logical-database.js +2 -0
  89. package/src/foundation/provision-logical-database.js.map +1 -1
  90. package/src/foundation/router-waf-rate-rehearsal.d.ts +97 -0
  91. package/src/foundation/router-waf-rate-rehearsal.js +210 -0
  92. package/src/foundation/router-waf-rate-rehearsal.js.map +1 -0
  93. package/src/foundation/router-waf.d.ts +59 -9
  94. package/src/foundation/router-waf.js +427 -32
  95. package/src/foundation/router-waf.js.map +1 -1
  96. package/src/foundation/stages.d.ts +1 -0
  97. package/src/foundation/stages.js +11 -0
  98. package/src/foundation/stages.js.map +1 -1
  99. package/src/generators/formatting.d.ts +8 -0
  100. package/src/generators/formatting.js +118 -0
  101. package/src/generators/formatting.js.map +1 -0
  102. package/src/generators/function/function.js +37 -17
  103. package/src/generators/function/function.js.map +1 -1
  104. package/src/generators/post-generation-install.js +2 -2
  105. package/src/generators/post-generation-install.js.map +1 -1
  106. package/src/generators/preset/generator.js +28 -8
  107. package/src/generators/preset/generator.js.map +1 -1
  108. package/src/generators/preset/schema.d.ts +3 -0
  109. package/src/generators/preset/schema.json +5 -5
  110. package/src/generators/preset/workspace-files-developer-agent.js +15 -7
  111. package/src/generators/preset/workspace-files-developer-agent.js.map +1 -1
  112. package/src/generators/preset/workspace-files-ecr-inspector.d.ts +18 -0
  113. package/src/generators/preset/workspace-files-ecr-inspector.js +298 -0
  114. package/src/generators/preset/workspace-files-ecr-inspector.js.map +1 -0
  115. package/src/generators/preset/workspace-files-performance-cost.d.ts +2 -2
  116. package/src/generators/preset/workspace-files-performance-cost.js +8 -8
  117. package/src/generators/preset/workspace-files-performance-cost.js.map +1 -1
  118. package/src/generators/preset/workspace-files-performance-load.d.ts +1 -1
  119. package/src/generators/preset/workspace-files-performance-load.js +29 -24
  120. package/src/generators/preset/workspace-files-performance-load.js.map +1 -1
  121. package/src/generators/preset/workspace-files-stage-authority.d.ts +6 -0
  122. package/src/generators/preset/workspace-files-stage-authority.js +479 -0
  123. package/src/generators/preset/workspace-files-stage-authority.js.map +1 -0
  124. package/src/generators/preset/workspace-files-thin-deploy.d.ts +40 -0
  125. package/src/generators/preset/workspace-files-thin-deploy.js +1500 -0
  126. package/src/generators/preset/workspace-files-thin-deploy.js.map +1 -0
  127. package/src/generators/preset/workspace-files-thin-docs.d.ts +5 -0
  128. package/src/generators/preset/workspace-files-thin-docs.js +240 -0
  129. package/src/generators/preset/workspace-files-thin-docs.js.map +1 -0
  130. package/src/generators/preset/workspace-files-thin-release.d.ts +14 -0
  131. package/src/generators/preset/workspace-files-thin-release.js +26 -0
  132. package/src/generators/preset/workspace-files-thin-release.js.map +1 -0
  133. package/src/generators/preset/workspace-files.d.ts +2 -1
  134. package/src/generators/preset/workspace-files.js +448 -680
  135. package/src/generators/preset/workspace-files.js.map +1 -1
  136. package/src/generators/repository-policy/repository-policy.js +149 -19
  137. package/src/generators/repository-policy/repository-policy.js.map +1 -1
  138. package/src/generators/repository-policy/schema.d.ts +2 -0
  139. package/src/generators/repository-policy/schema.json +11 -1
  140. package/src/generators/repository-policy/tree-policy.d.ts +3 -0
  141. package/src/generators/repository-policy/tree-policy.js +25 -0
  142. package/src/generators/repository-policy/tree-policy.js.map +1 -0
  143. package/src/generators/slice/built-in-plan-api-files.js +1 -0
  144. package/src/generators/slice/built-in-plan-api-files.js.map +1 -1
  145. package/src/generators/slice/built-in-plan-async-work-files.js +41 -0
  146. package/src/generators/slice/built-in-plan-async-work-files.js.map +1 -1
  147. package/src/generators/slice/built-in-plan-authorization-infrastructure-files.js +6 -0
  148. package/src/generators/slice/built-in-plan-authorization-infrastructure-files.js.map +1 -1
  149. package/src/generators/slice/built-in-plan-data-export-infrastructure-files.js +5 -31
  150. package/src/generators/slice/built-in-plan-data-export-infrastructure-files.js.map +1 -1
  151. package/src/generators/slice/built-in-plan-data-files.d.ts +1 -1
  152. package/src/generators/slice/built-in-plan-data-files.js +89 -30
  153. package/src/generators/slice/built-in-plan-data-files.js.map +1 -1
  154. package/src/generators/slice/built-in-plan-data-lifecycle-runtime-files.js +19 -0
  155. package/src/generators/slice/built-in-plan-data-lifecycle-runtime-files.js.map +1 -1
  156. package/src/generators/slice/built-in-plan-data-retention-launcher-files.js +21 -3
  157. package/src/generators/slice/built-in-plan-data-retention-launcher-files.js.map +1 -1
  158. package/src/generators/slice/built-in-plan-database-retirement-rehearsal-files.js +20 -1
  159. package/src/generators/slice/built-in-plan-database-retirement-rehearsal-files.js.map +1 -1
  160. package/src/generators/slice/built-in-plan-foundation-files.js +3 -5
  161. package/src/generators/slice/built-in-plan-foundation-files.js.map +1 -1
  162. package/src/generators/slice/built-in-plan-frontend-files.js +5 -1
  163. package/src/generators/slice/built-in-plan-frontend-files.js.map +1 -1
  164. package/src/generators/slice/built-in-plan-infrastructure-files.d.ts +1 -1
  165. package/src/generators/slice/built-in-plan-infrastructure-files.js +199 -188
  166. package/src/generators/slice/built-in-plan-infrastructure-files.js.map +1 -1
  167. package/src/generators/slice/built-in-plan-metadata-files.js +13 -0
  168. package/src/generators/slice/built-in-plan-metadata-files.js.map +1 -1
  169. package/src/generators/slice/built-in-plan-native-runtime-authority-files.d.ts +2 -0
  170. package/src/generators/slice/built-in-plan-native-runtime-authority-files.js +307 -0
  171. package/src/generators/slice/built-in-plan-native-runtime-authority-files.js.map +1 -0
  172. package/src/generators/slice/built-in-plan-operations-files.js +65 -51
  173. package/src/generators/slice/built-in-plan-operations-files.js.map +1 -1
  174. package/src/generators/slice/built-in-plan-performance-files.js +97 -19
  175. package/src/generators/slice/built-in-plan-performance-files.js.map +1 -1
  176. package/src/generators/slice/built-in-plan-project-files.js +9 -68
  177. package/src/generators/slice/built-in-plan-project-files.js.map +1 -1
  178. package/src/generators/slice/built-in-plan-secret-runtime-files.d.ts +1 -1
  179. package/src/generators/slice/built-in-plan-secret-runtime-files.js +87 -76
  180. package/src/generators/slice/built-in-plan-secret-runtime-files.js.map +1 -1
  181. package/src/generators/slice/built-in-plan-testing-files.js +94 -47
  182. package/src/generators/slice/built-in-plan-testing-files.js.map +1 -1
  183. package/src/generators/slice/built-in-plan-thin-release-files.d.ts +11 -0
  184. package/src/generators/slice/built-in-plan-thin-release-files.js +129 -0
  185. package/src/generators/slice/built-in-plan-thin-release-files.js.map +1 -0
  186. package/src/generators/slice/built-in-plan-verification-files.js +6 -2
  187. package/src/generators/slice/built-in-plan-verification-files.js.map +1 -1
  188. package/src/generators/slice/built-in-plan-web-files.js +4 -2
  189. package/src/generators/slice/built-in-plan-web-files.js.map +1 -1
  190. package/src/generators/slice/built-in-plan-workload-role-files.js +26 -4
  191. package/src/generators/slice/built-in-plan-workload-role-files.js.map +1 -1
  192. package/src/generators/slice/built-in-plan.d.ts +1 -0
  193. package/src/generators/slice/built-in-plan.js +28 -11
  194. package/src/generators/slice/built-in-plan.js.map +1 -1
  195. package/src/generators/slice/slice.js +30 -32
  196. package/src/generators/slice/slice.js.map +1 -1
  197. package/src/generators/upgrade/upgrade.d.ts +1 -1
  198. package/src/generators/upgrade/upgrade.js +200 -48
  199. package/src/generators/upgrade/upgrade.js.map +1 -1
  200. package/src/generators/workload/performance-registration.d.ts +1 -0
  201. package/src/generators/workload/performance-registration.js +9 -11
  202. package/src/generators/workload/performance-registration.js.map +1 -1
  203. package/src/generators/workload/service-performance-files.d.ts +1 -0
  204. package/src/generators/workload/service-performance-files.js +27 -7
  205. package/src/generators/workload/service-performance-files.js.map +1 -1
  206. package/src/generators/workload/workload.d.ts +1 -1
  207. package/src/generators/workload/workload.js +55 -28
  208. package/src/generators/workload/workload.js.map +1 -1
  209. package/src/git-policy/github-bootstrap.d.ts +28 -7
  210. package/src/git-policy/github-bootstrap.js +205 -163
  211. package/src/git-policy/github-bootstrap.js.map +1 -1
  212. package/src/index.d.ts +1 -0
  213. package/src/index.js +1 -0
  214. package/src/index.js.map +1 -1
  215. package/src/local-dev/private-state.d.ts +3 -0
  216. package/src/local-dev/private-state.js +17 -5
  217. package/src/local-dev/private-state.js.map +1 -1
  218. package/src/local-dev/tls.js +5 -1
  219. package/src/local-dev/tls.js.map +1 -1
  220. package/src/performance/cost-collection.d.ts +1 -1
  221. package/src/performance/cost-collection.js +4 -2
  222. package/src/performance/cost-collection.js.map +1 -1
  223. package/src/performance/cost-controls.d.ts +3 -1
  224. package/src/performance/cost-controls.js +9 -4
  225. package/src/performance/cost-controls.js.map +1 -1
  226. package/src/performance/evidence.d.ts +1 -1
  227. package/src/performance/evidence.js +5 -3
  228. package/src/performance/evidence.js.map +1 -1
  229. package/src/performance/load-safety.js +5 -3
  230. package/src/performance/load-safety.js.map +1 -1
  231. package/src/performance/model.d.ts +2 -2
  232. package/src/performance/model.js +4 -3
  233. package/src/performance/model.js.map +1 -1
  234. package/src/release/index.d.ts +0 -2
  235. package/src/release/index.js +0 -2
  236. package/src/release/index.js.map +1 -1
  237. package/src/release/source-authority.d.ts +4 -5
  238. package/src/release/source-authority.js +13 -123
  239. package/src/release/source-authority.js.map +1 -1
  240. package/src/repository-policy/aurora-preflight.d.ts +1 -1
  241. package/src/repository-policy/aurora-preflight.js +4 -1
  242. package/src/repository-policy/aurora-preflight.js.map +1 -1
  243. package/src/repository-policy/policy.d.ts +21 -2
  244. package/src/repository-policy/policy.js +290 -25
  245. package/src/repository-policy/policy.js.map +1 -1
  246. package/src/schemas/performance-policy-v1.json +3 -1
  247. package/src/schemas/repository-policy-v1.json +46 -2
  248. package/src/secrets/adapters.d.ts +7 -2
  249. package/src/secrets/adapters.js +34 -3
  250. package/src/secrets/adapters.js.map +1 -1
  251. package/src/secrets/aws-control-plane.d.ts +10 -1
  252. package/src/secrets/aws-control-plane.js +67 -0
  253. package/src/secrets/aws-control-plane.js.map +1 -1
  254. package/src/secrets/generated-aws-control-plane.d.ts +23 -0
  255. package/src/secrets/generated-aws-control-plane.js +259 -0
  256. package/src/secrets/generated-aws-control-plane.js.map +1 -0
  257. package/src/secrets/metadata.js +38 -10
  258. package/src/secrets/metadata.js.map +1 -1
  259. package/src/secrets/model.d.ts +8 -1
  260. package/src/secrets/model.js +24 -3
  261. package/src/secrets/model.js.map +1 -1
  262. package/src/secrets/operator.d.ts +89 -3
  263. package/src/secrets/operator.js +422 -9
  264. package/src/secrets/operator.js.map +1 -1
  265. package/src/secrets/registry.d.ts +2 -1
  266. package/src/secrets/registry.js +18 -1
  267. package/src/secrets/registry.js.map +1 -1
  268. package/src/secrets/workload-access.js +10 -2
  269. package/src/secrets/workload-access.js.map +1 -1
  270. package/src/supply-chain/action-pins.js +61 -7
  271. package/src/supply-chain/action-pins.js.map +1 -1
  272. package/src/supply-chain/build-output-bounds.d.ts +2 -0
  273. package/src/supply-chain/build-output-bounds.js +12 -0
  274. package/src/supply-chain/build-output-bounds.js.map +1 -0
  275. package/src/supply-chain/build-output.js +2 -4
  276. package/src/supply-chain/build-output.js.map +1 -1
  277. package/src/supply-chain/ecr-scanning.d.ts +5 -3
  278. package/src/supply-chain/ecr-scanning.js +11 -7
  279. package/src/supply-chain/ecr-scanning.js.map +1 -1
  280. package/src/supply-chain/ecs-deployed-image.d.ts +5 -3
  281. package/src/supply-chain/ecs-deployed-image.js +6 -4
  282. package/src/supply-chain/ecs-deployed-image.js.map +1 -1
  283. package/src/supply-chain/generated-container-release-command.js +849 -44
  284. package/src/supply-chain/generated-container-release-command.js.map +1 -1
  285. package/src/supply-chain/generated-ecr-collector-command.d.ts +0 -1
  286. package/src/supply-chain/generated-ecr-collector-command.js +188 -91
  287. package/src/supply-chain/generated-ecr-collector-command.js.map +1 -1
  288. package/src/supply-chain/generated-files.js +4 -3
  289. package/src/supply-chain/generated-files.js.map +1 -1
  290. package/src/supply-chain/index.d.ts +1 -1
  291. package/src/supply-chain/index.js +2 -1
  292. package/src/supply-chain/index.js.map +1 -1
  293. package/src/workload-roles/index.d.ts +10 -17
  294. package/src/workload-roles/index.js +5 -18
  295. package/src/workload-roles/index.js.map +1 -1
  296. package/src/workspace-deployment/identity.d.ts +3 -0
  297. package/src/workspace-deployment/identity.js +22 -0
  298. package/src/workspace-deployment/identity.js.map +1 -0
  299. package/src/workspace-deployment/index.d.ts +3 -0
  300. package/src/workspace-deployment/index.js +7 -0
  301. package/src/workspace-deployment/index.js.map +1 -0
  302. package/src/workspace-deployment/migration-evidence.d.ts +29 -0
  303. package/src/workspace-deployment/migration-evidence.js +83 -0
  304. package/src/workspace-deployment/migration-evidence.js.map +1 -0
  305. package/src/workspace-deployment/migration.d.ts +27 -0
  306. package/src/workspace-deployment/migration.js +109 -0
  307. package/src/workspace-deployment/migration.js.map +1 -0
  308. package/src/workspace-deployment/ownership.d.ts +81 -0
  309. package/src/workspace-deployment/ownership.js +381 -0
  310. package/src/workspace-deployment/ownership.js.map +1 -0
@@ -1,5 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.assertGovernedAwsLifecyclePlatform = assertGovernedAwsLifecyclePlatform;
4
+ exports.runGovernedChildProcess = runGovernedChildProcess;
3
5
  exports.createSstChildEnvironment = createSstChildEnvironment;
4
6
  exports.assertSafeSstForwardedArguments = assertSafeSstForwardedArguments;
5
7
  exports.resolveSstDevMode = resolveSstDevMode;
@@ -10,13 +12,19 @@ exports.runSstLifecyclePreflights = runSstLifecyclePreflights;
10
12
  exports.runSstCommand = runSstCommand;
11
13
  const devkit_1 = require("@nx/devkit");
12
14
  const node_child_process_1 = require("node:child_process");
15
+ const node_fs_1 = require("node:fs");
13
16
  const node_path_1 = require("node:path");
17
+ const index_js_1 = require("../../aws-authority/index.js");
18
+ const child_environment_js_1 = require("../../aws/child-environment.js");
19
+ const identity_js_1 = require("../../aws/identity.js");
14
20
  const stages_js_1 = require("../../foundation/stages.js");
15
21
  const personal_stage_js_1 = require("../../local-dev/personal-stage.js");
16
- const index_js_1 = require("../../repository-policy/index.js");
17
- const index_js_2 = require("../../work-markers/index.js");
18
- const logging_preflight_js_1 = require("./logging-preflight.js");
22
+ const federated_credential_transport_js_1 = require("../local-deploy/federated-credential-transport.js");
23
+ const index_js_2 = require("../../repository-policy/index.js");
24
+ const index_js_3 = require("../../workspace-deployment/index.js");
25
+ const index_js_4 = require("../../work-markers/index.js");
19
26
  const secret_preflight_js_1 = require("./secret-preflight.js");
27
+ const generated_secret_retirement_js_1 = require("./generated-secret-retirement.js");
20
28
  const sst_environment_source_js_1 = require("./sst-environment-source.js");
21
29
  const GOVERNED_STAGES = new Set(['development', 'staging', 'production']);
22
30
  const DEPLOYMENT_STAGES = new Set(['development', 'staging', 'production']);
@@ -30,6 +38,274 @@ const RESERVED_FORWARDED_OPTIONS = new Set([
30
38
  const SST_DEV_MODES = new Set(['basic', 'mono']);
31
39
  const AWS_REGION_PATTERN = /^[a-z]{2}(?:-gov)?-[a-z]+-\d$/;
32
40
  const AWS_ROLE_ARN_PATTERN = /^arn:(aws|aws-us-gov|aws-cn):iam::\d{12}:role\/[A-Za-z0-9+=,.@_/-]{1,512}$/;
41
+ const MAX_CALLER_IDENTITY_BYTES = 1024 * 1024;
42
+ const SST_SIGNAL_GRACE_PERIOD_MS = 10_000;
43
+ const SST_SIGNAL_KILL_WAIT_MS = 5_000;
44
+ const SST_PROCESS_GROUP_POLL_MS = 25;
45
+ const GOVERNED_PROCESS_GROUP_ENV = 'EBK_GOVERNED_PROCESS_GROUP';
46
+ function assertGovernedAwsLifecyclePlatform(platform = process.platform) {
47
+ if (platform === 'win32') {
48
+ throw new Error('Governed AWS infrastructure lifecycle is unavailable on native Windows; use macOS, Linux, or WSL2. Native Windows remains supported for local development and verification.');
49
+ }
50
+ }
51
+ function isMissingProcessError(error) {
52
+ return (typeof error === 'object' &&
53
+ error !== null &&
54
+ 'code' in error &&
55
+ error.code === 'ESRCH');
56
+ }
57
+ function exactWindowsSystemRoot() {
58
+ const values = new Set(Object.entries(process.env)
59
+ .filter(([name, value]) => name.toLowerCase() === 'systemroot' &&
60
+ typeof value === 'string' &&
61
+ value.length > 0)
62
+ .map(([, value]) => value));
63
+ if (values.size !== 1) {
64
+ throw new Error('Workspace SST tree cleanup requires exact SystemRoot.');
65
+ }
66
+ const systemRoot = values.values().next().value;
67
+ if (typeof systemRoot !== 'string' ||
68
+ !(0, node_path_1.isAbsolute)(systemRoot) ||
69
+ /[\0\r\n"]/u.test(systemRoot)) {
70
+ throw new Error('Workspace SST tree cleanup has an unsafe SystemRoot.');
71
+ }
72
+ return systemRoot;
73
+ }
74
+ function exactWindowsTaskkill() {
75
+ const systemRoot = exactWindowsSystemRoot();
76
+ const requested = (0, node_path_1.join)(systemRoot, 'System32', 'taskkill.exe');
77
+ const metadata = (0, node_fs_1.lstatSync)(requested);
78
+ const canonical = (0, node_fs_1.realpathSync)(requested);
79
+ if (metadata.isSymbolicLink() ||
80
+ !metadata.isFile() ||
81
+ canonical.toLowerCase() !== requested.toLowerCase()) {
82
+ throw new Error('Workspace SST taskkill authority is not exact.');
83
+ }
84
+ return { executable: canonical, systemRoot };
85
+ }
86
+ function signalExactGovernedProcessTree(child, signal) {
87
+ const pid = child.pid;
88
+ if (typeof pid !== 'number' || !Number.isSafeInteger(pid) || pid <= 0) {
89
+ throw new Error('Workspace SST child has no exact process identity.');
90
+ }
91
+ if (process.platform === 'win32') {
92
+ const taskkill = exactWindowsTaskkill();
93
+ const terminated = (0, node_child_process_1.spawnSync)(taskkill.executable, ['/pid', String(pid), '/t', '/f'], {
94
+ env: { SystemRoot: taskkill.systemRoot },
95
+ shell: false,
96
+ stdio: 'ignore',
97
+ timeout: 15_000,
98
+ windowsHide: true,
99
+ });
100
+ if ((terminated.error || terminated.signal || terminated.status !== 0) &&
101
+ child.exitCode === null &&
102
+ child.signalCode === null) {
103
+ throw new Error('Workspace SST process-tree termination failed.');
104
+ }
105
+ return;
106
+ }
107
+ try {
108
+ process.kill(-pid, signal);
109
+ }
110
+ catch (error) {
111
+ if (!isMissingProcessError(error))
112
+ throw error;
113
+ if (child.exitCode === null && child.signalCode === null) {
114
+ child.kill(signal);
115
+ }
116
+ }
117
+ }
118
+ function exactGovernedProcessTreeExists(pid) {
119
+ if (process.platform === 'win32')
120
+ return false;
121
+ try {
122
+ process.kill(-pid, 0);
123
+ return true;
124
+ }
125
+ catch (error) {
126
+ if (isMissingProcessError(error))
127
+ return false;
128
+ throw error;
129
+ }
130
+ }
131
+ async function waitForExactGovernedProcessTreeExit(pid, deadline = Date.now() + SST_SIGNAL_GRACE_PERIOD_MS + SST_SIGNAL_KILL_WAIT_MS) {
132
+ while (exactGovernedProcessTreeExists(pid)) {
133
+ if (Date.now() >= deadline) {
134
+ throw new Error('Workspace SST process tree did not stop within the bounded deadline.');
135
+ }
136
+ await new Promise((resolveWait) => setTimeout(resolveWait, SST_PROCESS_GROUP_POLL_MS));
137
+ }
138
+ }
139
+ async function waitForGovernedChildSettlement(childSettled, deadline) {
140
+ const remaining = deadline - Date.now();
141
+ if (remaining <= 0) {
142
+ throw new Error('Workspace SST child did not stop within the bounded deadline.');
143
+ }
144
+ let timeout;
145
+ try {
146
+ await Promise.race([
147
+ childSettled,
148
+ new Promise((_resolve, reject) => {
149
+ timeout = setTimeout(() => reject(new Error('Workspace SST child did not stop within the bounded deadline.')), remaining);
150
+ }),
151
+ ]);
152
+ }
153
+ finally {
154
+ if (timeout)
155
+ clearTimeout(timeout);
156
+ }
157
+ }
158
+ async function terminateRetainedGovernedProcessGroup(pid) {
159
+ if (process.platform === 'win32' || !exactGovernedProcessTreeExists(pid)) {
160
+ return false;
161
+ }
162
+ const deadline = Date.now() + SST_SIGNAL_GRACE_PERIOD_MS + SST_SIGNAL_KILL_WAIT_MS;
163
+ try {
164
+ process.kill(-pid, 'SIGTERM');
165
+ }
166
+ catch (error) {
167
+ if (!isMissingProcessError(error))
168
+ throw error;
169
+ return false;
170
+ }
171
+ const escalation = setTimeout(() => {
172
+ try {
173
+ process.kill(-pid, 'SIGKILL');
174
+ }
175
+ catch (error) {
176
+ if (!isMissingProcessError(error)) {
177
+ process.stderr.write('Governed descendant process-tree escalation failed.\n');
178
+ }
179
+ }
180
+ }, SST_SIGNAL_GRACE_PERIOD_MS);
181
+ try {
182
+ await waitForExactGovernedProcessTreeExit(pid, deadline);
183
+ }
184
+ finally {
185
+ clearTimeout(escalation);
186
+ }
187
+ return true;
188
+ }
189
+ async function stopExactGovernedProcessTree(child, signal, childSettled, isSettled, ownsProcessGroup = true) {
190
+ const pid = child.pid;
191
+ const deadline = Date.now() + SST_SIGNAL_GRACE_PERIOD_MS + SST_SIGNAL_KILL_WAIT_MS;
192
+ if (process.platform === 'win32' || ownsProcessGroup) {
193
+ signalExactGovernedProcessTree(child, signal);
194
+ }
195
+ else {
196
+ child.kill(signal);
197
+ }
198
+ let escalationError;
199
+ const escalation = setTimeout(() => {
200
+ try {
201
+ if (!isSettled() ||
202
+ (ownsProcessGroup && pid && exactGovernedProcessTreeExists(pid))) {
203
+ if (process.platform === 'win32' || ownsProcessGroup) {
204
+ signalExactGovernedProcessTree(child, 'SIGKILL');
205
+ }
206
+ else {
207
+ child.kill('SIGKILL');
208
+ }
209
+ }
210
+ }
211
+ catch (error) {
212
+ escalationError = error;
213
+ }
214
+ }, SST_SIGNAL_GRACE_PERIOD_MS);
215
+ try {
216
+ await waitForGovernedChildSettlement(childSettled, deadline);
217
+ if (ownsProcessGroup && pid && process.platform !== 'win32') {
218
+ await waitForExactGovernedProcessTreeExit(pid, deadline);
219
+ }
220
+ if (escalationError)
221
+ throw escalationError;
222
+ }
223
+ finally {
224
+ clearTimeout(escalation);
225
+ }
226
+ }
227
+ /** Run one exact shell-free child as an owned process tree. The returned
228
+ * promise settles only after child teardown and the bounded caller-supplied
229
+ * close reconciliation complete. */
230
+ function runGovernedChildProcess(input) {
231
+ return new Promise((resolveChildRun) => {
232
+ const environment = { ...input.environment };
233
+ for (const name of Object.keys(environment)) {
234
+ if (name.toUpperCase() === GOVERNED_PROCESS_GROUP_ENV) {
235
+ delete environment[name];
236
+ }
237
+ }
238
+ if (process.platform !== 'win32') {
239
+ environment[GOVERNED_PROCESS_GROUP_ENV] = '1';
240
+ }
241
+ const child = (input.spawnChild ?? node_child_process_1.spawn)(input.executable, [...input.args], {
242
+ cwd: input.cwd,
243
+ detached: process.platform !== 'win32',
244
+ env: environment,
245
+ shell: false,
246
+ stdio: 'inherit',
247
+ });
248
+ let finishing = false;
249
+ let settled = false;
250
+ let spawnError;
251
+ let unregisterSignalCleanup = () => undefined;
252
+ let resolveChildSettled = () => undefined;
253
+ const childSettled = new Promise((resolveChild) => {
254
+ resolveChildSettled = resolveChild;
255
+ });
256
+ const finish = async (status, signal) => {
257
+ if (finishing)
258
+ return;
259
+ finishing = true;
260
+ const result = {
261
+ ...(spawnError ? { error: spawnError } : {}),
262
+ signal,
263
+ status,
264
+ };
265
+ if (!(0, federated_credential_transport_js_1.governedSignalCleanupInProgress)() && child.pid) {
266
+ try {
267
+ if (await terminateRetainedGovernedProcessGroup(child.pid)) {
268
+ result.error ??= new Error('Governed child exited before its exact descendant process tree stopped.');
269
+ }
270
+ }
271
+ catch (error) {
272
+ result.error =
273
+ error instanceof Error
274
+ ? error
275
+ : new Error('Governed child descendant process-tree reconciliation failed.');
276
+ }
277
+ }
278
+ try {
279
+ await input.afterClose?.(result);
280
+ }
281
+ catch (error) {
282
+ result.error =
283
+ error instanceof Error
284
+ ? error
285
+ : new Error('Governed child close reconciliation failed.');
286
+ }
287
+ settled = true;
288
+ unregisterSignalCleanup();
289
+ resolveChildSettled();
290
+ resolveChildRun(result);
291
+ };
292
+ unregisterSignalCleanup = (0, federated_credential_transport_js_1.registerGovernedSignalCleanup)((signal) => stopExactGovernedProcessTree(child, signal, childSettled, () => settled), 100);
293
+ child.once('error', (error) => {
294
+ spawnError = error;
295
+ void finish(null, null);
296
+ });
297
+ child.once('close', (status, signal) => {
298
+ void finish(status, signal);
299
+ });
300
+ });
301
+ }
302
+ function partitionForRegion(region) {
303
+ if (region.startsWith('cn-'))
304
+ return 'aws-cn';
305
+ if (region.startsWith('us-gov-'))
306
+ return 'aws-us-gov';
307
+ return 'aws';
308
+ }
33
309
  function captureSstEnvironmentSource(context) {
34
310
  const projectName = context.projectName;
35
311
  const configured = projectName
@@ -45,24 +321,62 @@ function captureSstEnvironmentSource(context) {
45
321
  workspaceRoot: context.root,
46
322
  });
47
323
  }
48
- function requiresInfrastructureBinding(command, stage) {
324
+ function requiresSourceReconciliation(command, stage) {
49
325
  return (GOVERNED_STAGES.has(stage) &&
50
326
  (command === 'deploy' || command === 'refresh' || command === 'remove'));
51
327
  }
52
- async function authorizeInfrastructureMutation(command, options, context, invocation) {
53
- const { revalidateInfrastructureMutationAuthorization } = await Promise.resolve().then(() => require('../infrastructure-plan/infrastructure-plan.js'));
54
- await revalidateInfrastructureMutationAuthorization(command, options, context, invocation);
328
+ function isGovernedLocalCommand(command) {
329
+ return (command === 'deploy' ||
330
+ command === 'refresh' ||
331
+ command === 'remove' ||
332
+ command === 'unlock');
55
333
  }
56
- async function authorizeLocalUnlock(options, invocation) {
57
- const { revalidateLocalUnlockCallerAuthority } = await Promise.resolve().then(() => require('../infrastructure-plan/infrastructure-plan.js'));
58
- revalidateLocalUnlockCallerAuthority({
59
- invocation,
60
- profile: options.profile,
334
+ async function authorizeLocalUnlock(options, invocation, environment = process.env) {
335
+ const expectedAccount = invocation.environment.AWS_EXPECTED_ACCOUNT_ID?.trim() ?? '';
336
+ const expectedRoleArn = invocation.environment.EBK_EXPECTED_DEPLOYMENT_ROLE_ARN?.trim() ?? '';
337
+ if (!/^\d{12}$/.test(expectedAccount) || !expectedRoleArn) {
338
+ throw new Error('Local unlock requires one exact committed account and temporary assumed role.');
339
+ }
340
+ const ambientExpectedAccount = environment.AWS_EXPECTED_ACCOUNT_ID?.trim();
341
+ if (ambientExpectedAccount && ambientExpectedAccount !== expectedAccount) {
342
+ throw new Error('Ambient AWS_EXPECTED_ACCOUNT_ID does not match committed deployment topology.');
343
+ }
344
+ const result = (0, node_child_process_1.spawnSync)('aws', [
345
+ 'sts',
346
+ 'get-caller-identity',
347
+ '--endpoint-url',
348
+ (0, identity_js_1.canonicalStsEndpoint)(invocation.environment.AWS_REGION?.trim() ?? ''),
349
+ '--output',
350
+ 'json',
351
+ ...(options.profile ? ['--profile', options.profile] : []),
352
+ ], {
353
+ cwd: invocation.cwd,
354
+ encoding: 'utf8',
355
+ env: createSstChildEnvironment(environment, invocation.environment),
356
+ maxBuffer: MAX_CALLER_IDENTITY_BYTES,
357
+ shell: false,
358
+ windowsHide: true,
61
359
  });
62
- }
63
- async function retainInfrastructureConvergence(command, options, context, invocation, applySucceeded) {
64
- const { recordInfrastructureMutationConvergence } = await Promise.resolve().then(() => require('../infrastructure-plan/infrastructure-plan.js'));
65
- return recordInfrastructureMutationConvergence(command, options, context, invocation, applySucceeded);
360
+ if (result.error || result.status !== 0 || result.signal) {
361
+ throw new Error('Local unlock AWS caller identity could not be verified.');
362
+ }
363
+ let caller;
364
+ try {
365
+ caller = JSON.parse(result.stdout);
366
+ }
367
+ catch {
368
+ throw new Error('Local unlock AWS caller identity is not valid JSON.');
369
+ }
370
+ if (!caller ||
371
+ typeof caller !== 'object' ||
372
+ Array.isArray(caller) ||
373
+ !('Account' in caller) ||
374
+ !('Arn' in caller) ||
375
+ caller.Account !== expectedAccount ||
376
+ typeof caller.Arn !== 'string' ||
377
+ !(0, identity_js_1.matchesExpectedAssumedRoleArn)(expectedAccount, caller.Arn, expectedRoleArn)) {
378
+ throw new Error('Local unlock AWS caller does not match the committed account and exact temporary assumed role.');
379
+ }
66
380
  }
67
381
  function projectKind(context) {
68
382
  if (!context.projectName) {
@@ -77,18 +391,21 @@ function projectKind(context) {
77
391
  return foundation ? 'foundation' : 'slice';
78
392
  }
79
393
  function createSstChildEnvironment(ambient, invocation) {
80
- const sanitized = (0, personal_stage_js_1.isFrameworkPersonalStage)(invocation.EBK_CONSUMER_STAGE)
394
+ const stageSanitized = (0, personal_stage_js_1.isFrameworkPersonalStage)(invocation.EBK_CONSUMER_STAGE)
81
395
  ? (0, personal_stage_js_1.createPersonalDevelopmentEnvironment)(invocation.EBK_CONSUMER_STAGE, ambient)
82
396
  : (0, personal_stage_js_1.stripAmbientStageAuthority)(ambient);
397
+ const sanitized = (0, child_environment_js_1.sanitizeGovernedAwsChildEnvironment)(stageSanitized, {
398
+ preserveVerifiedGithubCredentials: stageSanitized.GITHUB_ACTIONS === 'true',
399
+ });
83
400
  delete sanitized.EBK_PRODUCTION_FOUNDATION_PROFILE;
84
401
  delete sanitized.EBK_LOCAL_MUTATION_CAPABILITY_NONCE;
85
402
  delete sanitized.EBK_LOCAL_MUTATION_CAPABILITY_PATH;
403
+ delete sanitized.EBK_GITHUB_JOB_WORKFLOW_REF;
404
+ delete sanitized.EBK_NX_STAGE_LIFECYCLE;
86
405
  // Nx injects task identity, target, hash, terminal, cache, and invocation
87
- // metadata into every executor process. A reviewed infrastructure-plan and
88
- // its mutation-time revalidation intentionally run under different Nx
89
- // targets, so those values are orchestration context rather than desired
90
- // infrastructure inputs. Never let them reach SST, where build tools can
91
- // persist ambient environment values into deployment archives.
406
+ // metadata into every executor process. Those values describe orchestration,
407
+ // not desired infrastructure. Never let them reach SST, where build tools
408
+ // can persist ambient environment values into deployment archives.
92
409
  for (const name of Object.keys(sanitized)) {
93
410
  if (name.startsWith('NX_') || name === 'LERNA_PACKAGE_NAME') {
94
411
  delete sanitized[name];
@@ -124,19 +441,33 @@ function assertSstLifecyclePolicy(command, stage, environment = process.env, dep
124
441
  if (command === 'dev') {
125
442
  throw new Error(`SST dev is not permitted for protected stage ${stage}.`);
126
443
  }
127
- if (!(0, index_js_1.requiresGithubDeployment)(deploymentProfile, stage) &&
444
+ if (command === 'remove' &&
445
+ stage === 'production' &&
446
+ environment.EBK_ALLOW_PRODUCTION_REMOVE !== 'true') {
447
+ throw new Error('Production removal requires EBK_ALLOW_PRODUCTION_REMOVE=true in the governed production environment.');
448
+ }
449
+ if (!(0, index_js_2.requiresGithubDeployment)(deploymentProfile, stage) &&
128
450
  environment.GITHUB_ACTIONS !== 'true') {
129
451
  return;
130
452
  }
131
453
  const repository = environment.GITHUB_REPOSITORY;
132
- const expectedBranch = stage === 'staging' ? 'develop' : 'main';
454
+ const expectedBranch = stage === 'production' ? 'main' : 'develop';
133
455
  const expectedRef = `refs/heads/${expectedBranch}`;
134
- const expectedWorkflowRef = repository
456
+ const expectedCalledWorkflowRef = repository
135
457
  ? `${repository}/.github/workflows/deploy.yml@${expectedRef}`
136
458
  : undefined;
137
459
  const eventName = environment.GITHUB_EVENT_NAME;
138
460
  const allowedEvent = eventName === 'workflow_dispatch' ||
139
- (eventName === 'push' && command === 'deploy');
461
+ (eventName === 'push' &&
462
+ command === 'deploy' &&
463
+ deploymentProfile !== 'starter');
464
+ const expectedCallerWorkflowRef = eventName === 'push'
465
+ ? repository
466
+ ? `${repository}/.github/workflows/ci.yml@${expectedRef}`
467
+ : undefined
468
+ : eventName === 'workflow_dispatch'
469
+ ? expectedCalledWorkflowRef
470
+ : undefined;
140
471
  // These GitHub-provided values are a fail-closed provenance consistency
141
472
  // check, not a credential boundary: a local process can spoof them. Actual
142
473
  // protected-stage authority comes from environment-scoped OIDC role access
@@ -146,14 +477,10 @@ function assertSstLifecyclePolicy(command, stage, environment = process.env, dep
146
477
  environment.GITHUB_ACTIONS === 'true' &&
147
478
  allowedEvent &&
148
479
  environment.GITHUB_REF === expectedRef &&
149
- environment.GITHUB_WORKFLOW_REF === expectedWorkflowRef;
480
+ environment.GITHUB_WORKFLOW_REF === expectedCallerWorkflowRef &&
481
+ environment.EBK_GITHUB_JOB_WORKFLOW_REF === expectedCalledWorkflowRef;
150
482
  if (!workflowProvenanceMatches) {
151
- throw new Error(`SST ${command} for protected stage ${stage} must run from the ${expectedBranch}-branch deploy workflow; pushes may run only deploy and other lifecycle actions require workflow_dispatch.`);
152
- }
153
- if (command === 'remove' &&
154
- stage === 'production' &&
155
- environment.EBK_ALLOW_PRODUCTION_REMOVE !== 'true') {
156
- throw new Error('Production removal requires EBK_ALLOW_PRODUCTION_REMOVE=true in the protected production environment.');
483
+ throw new Error(`SST ${command} for protected stage ${stage} must run from the exact ${expectedBranch}-branch caller and reusable deploy workflows; isolated-profile pushes may run only deploy and other lifecycle actions require workflow_dispatch.`);
157
484
  }
158
485
  }
159
486
  function resolveSstLifecycleStages(options, environment = process.env) {
@@ -222,19 +549,23 @@ function buildSstCommandInvocation(command, options, context, environment = proc
222
549
  stages.mapped) {
223
550
  throw new Error(`Full deploy is not permitted for mapped personal stage ${stages.consumerStage}. Use ebk dev against the ${stages.foundationStage} Foundation.`);
224
551
  }
225
- const operatingPolicy = DEPLOYMENT_STAGES.has(stages.consumerStage) &&
226
- (command === 'deploy' ||
227
- command === 'refresh' ||
228
- command === 'remove' ||
229
- command === 'unlock')
230
- ? (0, index_js_1.readRepositoryOperatingPolicy)(context.root)
552
+ const operatingPolicy = command === 'dev' ||
553
+ (DEPLOYMENT_STAGES.has(stages.consumerStage) &&
554
+ (command === 'deploy' ||
555
+ command === 'refresh' ||
556
+ command === 'remove' ||
557
+ command === 'unlock'))
558
+ ? (0, index_js_2.readRepositoryOperatingPolicy)(context.root)
231
559
  : undefined;
232
560
  assertSstLifecyclePolicy(command, stages.consumerStage, environment, operatingPolicy?.deploymentProfile);
233
- const deploymentAccounts = operatingPolicy
234
- ? (0, index_js_1.configuredDeploymentAccountTopology)(operatingPolicy.deploymentProfile, operatingPolicy.deploymentAccounts)
561
+ const authorityStage = command === 'dev'
562
+ ? 'development'
563
+ : stages.consumerStage;
564
+ const deploymentAccount = operatingPolicy
565
+ ? (0, index_js_2.configuredDeploymentAccountForStage)(operatingPolicy.deploymentProfile, operatingPolicy.deploymentAccounts, authorityStage)
235
566
  : undefined;
236
567
  const deploymentRegion = operatingPolicy
237
- ? (0, index_js_1.configuredDeploymentRegion)(operatingPolicy.deploymentRegion)
568
+ ? (0, index_js_2.configuredDeploymentRegion)(operatingPolicy.deploymentRegion)
238
569
  : undefined;
239
570
  if (deploymentRegion &&
240
571
  options.region?.trim() &&
@@ -245,6 +576,22 @@ function buildSstCommandInvocation(command, options, context, environment = proc
245
576
  !AWS_ROLE_ARN_PATTERN.test(options.expectedRoleArn.trim())) {
246
577
  throw new Error('SST lifecycle expectedRoleArn must be one exact IAM role ARN.');
247
578
  }
579
+ const committedRoleArn = operatingPolicy &&
580
+ deploymentAccount &&
581
+ deploymentRegion &&
582
+ isGovernedLocalCommand(command)
583
+ ? (0, index_js_1.createStageAuthorityIdentity)({
584
+ accountId: deploymentAccount,
585
+ partition: partitionForRegion(deploymentRegion),
586
+ region: deploymentRegion,
587
+ stage: authorityStage,
588
+ }).deploymentRoleArn
589
+ : undefined;
590
+ if (committedRoleArn &&
591
+ options.expectedRoleArn?.trim() &&
592
+ options.expectedRoleArn.trim() !== committedRoleArn) {
593
+ throw new Error(`SST ${command} requires the exact committed ${authorityStage} stage authority role ${committedRoleArn}.`);
594
+ }
248
595
  const profile = options.profile?.trim();
249
596
  if (options.profile !== undefined &&
250
597
  (!profile || profile !== options.profile || profile.length > 128)) {
@@ -252,21 +599,24 @@ function buildSstCommandInvocation(command, options, context, environment = proc
252
599
  }
253
600
  if (operatingPolicy &&
254
601
  environment.GITHUB_ACTIONS !== 'true' &&
255
- (command === 'deploy' ||
256
- command === 'refresh' ||
257
- command === 'remove' ||
258
- command === 'unlock') &&
602
+ command === 'deploy' &&
603
+ environment.EBK_NX_STAGE_LIFECYCLE !== 'local') {
604
+ throw new Error(`Local deploy for ${stages.consumerStage} must be invoked by the governed root stage lifecycle (EBK_NX_STAGE_LIFECYCLE=local).`);
605
+ }
606
+ if (operatingPolicy &&
607
+ environment.GITHUB_ACTIONS !== 'true' &&
608
+ isGovernedLocalCommand(command) &&
259
609
  !options.expectedRoleArn?.trim()) {
260
610
  throw new Error(`Local ${command} for ${stages.consumerStage} requires --expectedRoleArn for one temporary assumed-role session.`);
261
611
  }
262
612
  if (GOVERNED_STAGES.has(stages.consumerStage) &&
263
613
  (command === 'deploy' || command === 'refresh')) {
264
- (0, index_js_2.assertWorkMarkerReport)((0, index_js_2.scanWorkMarkers)(context.root), {
265
- protectedPromotion: true,
614
+ (0, index_js_4.assertWorkMarkerReport)((0, index_js_4.scanWorkMarkers)(context.root), {
615
+ protectedPromotion: stages.consumerStage !== 'development',
266
616
  });
267
617
  }
268
618
  const policyDecision = stages.consumerStage === 'production'
269
- ? (0, index_js_1.assertRepositoryPolicyRequest)(context.root, {
619
+ ? (0, index_js_2.assertRepositoryPolicyRequest)(context.root, {
270
620
  action: command,
271
621
  projects: [
272
622
  {
@@ -278,6 +628,8 @@ function buildSstCommandInvocation(command, options, context, environment = proc
278
628
  })
279
629
  : undefined;
280
630
  const args = [command, '--stage', stages.consumerStage];
631
+ if (command === 'refresh')
632
+ args.push('--yes');
281
633
  if (options.target) {
282
634
  args.push('--target', options.target);
283
635
  }
@@ -297,9 +649,9 @@ function buildSstCommandInvocation(command, options, context, environment = proc
297
649
  ],
298
650
  cwd,
299
651
  environment: {
300
- ...(deploymentAccounts
652
+ ...(deploymentAccount
301
653
  ? {
302
- AWS_EXPECTED_ACCOUNT_ID: deploymentAccounts[stages.consumerStage],
654
+ AWS_EXPECTED_ACCOUNT_ID: deploymentAccount,
303
655
  }
304
656
  : {}),
305
657
  ...(profile ? { AWS_PROFILE: profile } : {}),
@@ -309,9 +661,9 @@ function buildSstCommandInvocation(command, options, context, environment = proc
309
661
  ? { AWS_REGION: options.region.trim() }
310
662
  : {}),
311
663
  EBK_CONSUMER_STAGE: stages.consumerStage,
312
- ...(options.expectedRoleArn?.trim()
664
+ ...((committedRoleArn ?? options.expectedRoleArn?.trim())
313
665
  ? {
314
- EBK_EXPECTED_DEPLOYMENT_ROLE_ARN: options.expectedRoleArn.trim(),
666
+ EBK_EXPECTED_DEPLOYMENT_ROLE_ARN: committedRoleArn ?? options.expectedRoleArn?.trim(),
315
667
  }
316
668
  : {}),
317
669
  EBK_FOUNDATION_STAGE: stages.foundationStage,
@@ -324,35 +676,47 @@ function buildSstCommandInvocation(command, options, context, environment = proc
324
676
  executable: process.execPath,
325
677
  };
326
678
  }
327
- async function runSstLifecyclePreflights(command, options, context, invocation, dependencies = {}) {
328
- if (command === 'deploy' || command === 'dev') {
329
- await (dependencies.logging ?? logging_preflight_js_1.preflightManagedLogGroups)(command, options, context, invocation);
330
- }
679
+ async function runSstLifecyclePreflights(command, options, context, invocation, dependencies = {}, environment = process.env) {
680
+ const stage = command === 'dev'
681
+ ? 'development'
682
+ : invocation.environment.EBK_CONSUMER_STAGE;
683
+ await (dependencies.ownership ?? index_js_3.assertWorkspaceStageOwnershipForWorkspace)(context.root, stage, {
684
+ ...(environment.AWS_CONFIG_FILE
685
+ ? { configFilepath: environment.AWS_CONFIG_FILE }
686
+ : {}),
687
+ ...(environment.AWS_SHARED_CREDENTIALS_FILE
688
+ ? { credentialsFilepath: environment.AWS_SHARED_CREDENTIALS_FILE }
689
+ : {}),
690
+ ...(invocation.environment.AWS_PROFILE
691
+ ? { profile: invocation.environment.AWS_PROFILE }
692
+ : {}),
693
+ });
331
694
  if (command === 'deploy') {
332
695
  await (dependencies.secrets ?? secret_preflight_js_1.preflightSliceSecretMetadata)(options, context, invocation);
333
696
  }
334
697
  if (command === 'unlock' &&
335
698
  invocation.environment.EBK_EXPECTED_DEPLOYMENT_ROLE_ARN) {
336
- await (dependencies.unlockAuthorization ?? authorizeLocalUnlock)(options, invocation);
337
- }
338
- if (requiresInfrastructureBinding(command, invocation.environment.EBK_CONSUMER_STAGE)) {
339
- await (dependencies.infrastructureAuthorization ??
340
- authorizeInfrastructureMutation)(command, options, context, invocation);
699
+ await (dependencies.unlockAuthorization ?? authorizeLocalUnlock)(options, invocation, environment);
341
700
  }
342
701
  }
343
702
  async function runSstCommand(command, options, context, dependencies = {}) {
703
+ if (command !== 'dev') {
704
+ assertGovernedAwsLifecyclePlatform(dependencies.platform);
705
+ }
706
+ const environment = dependencies.environment ?? process.env;
707
+ const joinsGovernedProcessGroup = process.platform !== 'win32' &&
708
+ environment[GOVERNED_PROCESS_GROUP_ENV] === '1';
344
709
  let invocation;
345
710
  let environmentSource;
346
711
  try {
347
- invocation = buildSstCommandInvocation(command, options, context);
348
- if (requiresInfrastructureBinding(command, invocation.environment.EBK_CONSUMER_STAGE)) {
349
- // Infrastructure authorization runs an SST plan and SST can rewrite its
350
- // generated environment declaration during that preflight. Capture the
351
- // committed source before any SST-bearing operation so neither the plan
352
- // nor the mutation child can become the restoration baseline.
712
+ invocation = buildSstCommandInvocation(command, options, context, environment);
713
+ if (requiresSourceReconciliation(command, invocation.environment.EBK_CONSUMER_STAGE)) {
714
+ // Native SST can rewrite its generated environment declaration. Capture
715
+ // committed tool-owned source before the child so successful and failed
716
+ // lifecycle commands restore the repository exactly.
353
717
  environmentSource = captureSstEnvironmentSource(context);
354
718
  }
355
- await runSstLifecyclePreflights(command, options, context, invocation, dependencies);
719
+ await runSstLifecyclePreflights(command, options, context, invocation, dependencies, environment);
356
720
  if (environmentSource)
357
721
  (0, sst_environment_source_js_1.reconcileSstEnvironmentSourceTree)(environmentSource);
358
722
  }
@@ -378,22 +742,52 @@ async function runSstCommand(command, options, context, dependencies = {}) {
378
742
  return new Promise((resolve) => {
379
743
  const child = (dependencies.spawnChild ?? node_child_process_1.spawn)(invocation.executable, invocation.args, {
380
744
  cwd: invocation.cwd,
381
- env: createSstChildEnvironment(process.env, invocation.environment),
745
+ detached: process.platform !== 'win32' && !joinsGovernedProcessGroup,
746
+ env: createSstChildEnvironment(environment, invocation.environment),
382
747
  shell: false,
383
748
  stdio: 'inherit',
384
749
  });
385
750
  let settled = false;
751
+ let unregisterSignalCleanup = () => undefined;
752
+ let resolveChildSettled = () => undefined;
753
+ const childSettled = new Promise((resolveChild) => {
754
+ resolveChildSettled = resolveChild;
755
+ });
386
756
  const settle = (success) => {
387
757
  if (settled)
388
758
  return;
389
759
  settled = true;
760
+ unregisterSignalCleanup();
761
+ resolveChildSettled();
390
762
  resolve({ success });
391
763
  };
764
+ unregisterSignalCleanup = (0, federated_credential_transport_js_1.registerGovernedSignalCleanup)((signal) => {
765
+ if (settled)
766
+ return;
767
+ return stopExactGovernedProcessTree(child, signal, childSettled, () => settled, !joinsGovernedProcessGroup);
768
+ }, 100);
392
769
  child.on('error', (error) => {
393
770
  devkit_1.logger.error(`Failed to start workspace SST: ${error.message}`);
394
771
  settle(false);
395
772
  });
396
773
  child.on('close', async (code, signal) => {
774
+ if (settled)
775
+ return;
776
+ let retainedProcessTree = false;
777
+ if (!(0, federated_credential_transport_js_1.governedSignalCleanupInProgress)() &&
778
+ !joinsGovernedProcessGroup &&
779
+ child.pid) {
780
+ try {
781
+ retainedProcessTree = await terminateRetainedGovernedProcessGroup(child.pid);
782
+ }
783
+ catch (error) {
784
+ retainedProcessTree = true;
785
+ devkit_1.logger.error(`Failed to stop retained SST descendant process tree: ${error instanceof Error ? error.message : String(error)}`);
786
+ }
787
+ if (retainedProcessTree) {
788
+ devkit_1.logger.error('SST exited before its exact descendant process tree stopped.');
789
+ }
790
+ }
397
791
  if (code !== 0) {
398
792
  devkit_1.logger.error(signal
399
793
  ? `SST ${command} terminated with signal ${signal}.`
@@ -412,30 +806,21 @@ async function runSstCommand(command, options, context, dependencies = {}) {
412
806
  devkit_1.logger.error(`Failed to restore SST tool-owned source: ${error instanceof Error ? error.message : String(error)}`);
413
807
  }
414
808
  }
415
- const applySucceeded = code === 0 && sourceRestored;
416
- if (requiresInfrastructureBinding(command, invocation.environment.EBK_CONSUMER_STAGE)) {
809
+ const applySucceeded = code === 0 && sourceRestored && !retainedProcessTree;
810
+ let generatedSecretRetirementSucceeded = true;
811
+ if (applySucceeded &&
812
+ command === 'remove' &&
813
+ projectKind(context) === 'slice') {
417
814
  try {
418
- const mutationEvidenceRetained = await (dependencies.infrastructureConvergence ??
419
- retainInfrastructureConvergence)(command, options, context, invocation, applySucceeded);
420
- if (!mutationEvidenceRetained) {
421
- devkit_1.logger.error(`SST ${command} did not retain valid infrastructure mutation evidence.`);
422
- }
423
- // A deploy retains apply-complete-unverified as a successful handoff
424
- // to deployed smoke. It is not terminal convergence; the protected
425
- // finalizer consumes the exact alarm, data, and journey evidence.
426
- // Convergence remains the fail-closed authority for governed
427
- // mutations. A child failure remains failed even if refresh wrote a
428
- // newer state snapshot; that condition is retained as recovery
429
- // evidence and cannot be upgraded into accepted success.
430
- settle(sourceRestored && mutationEvidenceRetained && applySucceeded);
815
+ await (dependencies.generatedSecretRetirement ??
816
+ generated_secret_retirement_js_1.retireGeneratedSecretsAfterSliceRemove)(options, context, invocation, { environment });
431
817
  }
432
818
  catch (error) {
433
- devkit_1.logger.error(`Failed to retain infrastructure convergence: ${error instanceof Error ? error.message : String(error)}`);
434
- settle(false);
819
+ generatedSecretRetirementSucceeded = false;
820
+ devkit_1.logger.error(`Generated stage-secret retirement failed after native Slice removal: ${error instanceof Error ? error.message : String(error)}`);
435
821
  }
436
- return;
437
822
  }
438
- settle(applySucceeded);
823
+ settle(applySucceeded && generatedSecretRetirementSucceeded);
439
824
  });
440
825
  });
441
826
  }