@intentius/chant-lexicon-aws 0.124.31 → 0.124.33

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 (649) hide show
  1. package/dist/actions/dynamodb.js +41 -0
  2. package/dist/actions/ecr.js +9 -0
  3. package/dist/actions/ecs.js +5 -0
  4. package/dist/actions/iam.js +3 -0
  5. package/dist/actions/index.js +9 -0
  6. package/dist/actions/lambda.js +11 -0
  7. package/dist/actions/logs.js +4 -0
  8. package/dist/actions/s3.js +40 -0
  9. package/dist/actions/sns.js +5 -0
  10. package/dist/actions/sqs.js +15 -0
  11. package/dist/agentcore/trace-fetch.d.ts.map +1 -1
  12. package/dist/agentcore/trace-fetch.js +472 -0
  13. package/dist/agentcore/trace-render.js +359 -0
  14. package/dist/ambient.js +148 -0
  15. package/dist/api/credential-chain.d.ts +30 -3
  16. package/dist/api/credential-chain.d.ts.map +1 -1
  17. package/dist/api/credential-chain.js +509 -0
  18. package/dist/api/read-client.d.ts +16 -43
  19. package/dist/api/read-client.d.ts.map +1 -1
  20. package/dist/api/read-client.js +458 -0
  21. package/dist/api/sigv4.d.ts +4 -4
  22. package/dist/api/sigv4.js +185 -0
  23. package/dist/behaviour-kinds.js +114 -0
  24. package/dist/caller-identity.d.ts +3 -5
  25. package/dist/caller-identity.d.ts.map +1 -1
  26. package/dist/caller-identity.js +146 -0
  27. package/dist/codegen/docs-cli.js +2 -0
  28. package/dist/codegen/docs.js +120 -0
  29. package/dist/codegen/enum-overlay.js +162 -0
  30. package/dist/codegen/extensions.js +139 -0
  31. package/dist/codegen/fallback.js +32 -0
  32. package/dist/codegen/generate-cli.js +15 -0
  33. package/dist/codegen/generate-lexicon.js +70 -0
  34. package/dist/codegen/generate-typescript.js +226 -0
  35. package/dist/codegen/generate.d.ts.map +1 -1
  36. package/dist/codegen/generate.js +234 -0
  37. package/dist/codegen/naming.js +135 -0
  38. package/dist/codegen/package.js +67 -0
  39. package/dist/codegen/patches.d.ts +26 -1
  40. package/dist/codegen/patches.d.ts.map +1 -1
  41. package/dist/codegen/patches.js +90 -0
  42. package/dist/codegen/property-overlay.js +85 -0
  43. package/dist/codegen/property-overlay.json +1 -16
  44. package/dist/codegen/sam.js +402 -0
  45. package/dist/codegen/typecheck.js +4 -0
  46. package/dist/codegen/versions.js +31 -0
  47. package/dist/components/__tests__/mock-cloud-executor.js +326 -0
  48. package/dist/components/apply.d.ts +44 -1
  49. package/dist/components/apply.d.ts.map +1 -1
  50. package/dist/components/apply.js +752 -0
  51. package/dist/components/builders.js +37 -0
  52. package/dist/components/capability-plugin.js +66 -0
  53. package/dist/components/cloud-executor.d.ts +35 -0
  54. package/dist/components/cloud-executor.d.ts.map +1 -1
  55. package/dist/components/cloud-executor.js +576 -0
  56. package/dist/components/config-bom.js +207 -0
  57. package/dist/components/host-delivery.js +117 -0
  58. package/dist/components/index.js +18 -0
  59. package/dist/components/job-submission.js +77 -0
  60. package/dist/components/publish.js +234 -0
  61. package/dist/components/safety.js +62 -0
  62. package/dist/components/wait-aws.js +68 -0
  63. package/dist/composites/agentcore-agent.js +187 -0
  64. package/dist/composites/agentcore-trust-policy.js +13 -0
  65. package/dist/composites/alb-shared.js +84 -0
  66. package/dist/composites/bucket-deployment.js +93 -0
  67. package/dist/composites/catalog.js +2714 -0
  68. package/dist/composites/dynamodb-table.js +66 -0
  69. package/dist/composites/ec2-instance-bundle.js +75 -0
  70. package/dist/composites/ec2-instance-role.js +26 -0
  71. package/dist/composites/ecr-repository.js +64 -0
  72. package/dist/composites/ecs-trust-policy.js +10 -0
  73. package/dist/composites/efs-with-access-point.js +44 -0
  74. package/dist/composites/eks-cluster.js +118 -0
  75. package/dist/composites/fargate-alb.js +216 -0
  76. package/dist/composites/fargate-service.js +222 -0
  77. package/dist/composites/index.js +28 -0
  78. package/dist/composites/lambda-api.js +15 -0
  79. package/dist/composites/lambda-dynamodb.js +77 -0
  80. package/dist/composites/lambda-eventbridge.js +27 -0
  81. package/dist/composites/lambda-function.js +54 -0
  82. package/dist/composites/lambda-s3.js +93 -0
  83. package/dist/composites/lambda-sns.js +23 -0
  84. package/dist/composites/lambda-sqs.js +34 -0
  85. package/dist/composites/landing-zone.js +82 -0
  86. package/dist/composites/microvm-app.js +293 -0
  87. package/dist/composites/minimal-vpc.js +40 -0
  88. package/dist/composites/monitoring-stack.js +105 -0
  89. package/dist/composites/nlb-service.js +61 -0
  90. package/dist/composites/rds-instance.js +98 -0
  91. package/dist/composites/scheduled-lambda.js +28 -0
  92. package/dist/composites/solr-fargate-service.js +33 -0
  93. package/dist/composites/step-functions-workflow.js +78 -0
  94. package/dist/composites/vpc-default.js +132 -0
  95. package/dist/condition.js +43 -0
  96. package/dist/coverage.js +4 -0
  97. package/dist/deep-observe.d.ts.map +1 -1
  98. package/dist/deep-observe.js +709 -0
  99. package/dist/deep-topology.js +226 -0
  100. package/dist/default-tags.js +50 -0
  101. package/dist/defaults.js +85 -0
  102. package/dist/dependencies.js +269 -0
  103. package/dist/detect.js +21 -0
  104. package/dist/disruption.d.ts.map +1 -1
  105. package/dist/disruption.js +129 -0
  106. package/dist/effect-receipt-row.js +107 -0
  107. package/dist/generated/index.d.ts +1297 -82
  108. package/dist/generated/index.d.ts.map +1 -1
  109. package/dist/generated/index.js +12382 -0
  110. package/dist/generated/runtime.js +4 -0
  111. package/dist/governance.js +131 -0
  112. package/dist/health.d.ts +61 -0
  113. package/dist/health.d.ts.map +1 -0
  114. package/dist/health.js +216 -0
  115. package/dist/identity-observe.d.ts.map +1 -1
  116. package/dist/identity-observe.js +127 -0
  117. package/dist/import/generator.js +757 -0
  118. package/dist/import/live-export.js +34 -0
  119. package/dist/import/parser.js +394 -0
  120. package/dist/index.js +69 -0
  121. package/dist/integrity.json +6 -6
  122. package/dist/intrinsics.js +393 -0
  123. package/dist/lint/audit-catalog.js +87 -0
  124. package/dist/lint/audit-lineage.js +150 -0
  125. package/dist/lint/post-synth/cf-refs.js +247 -0
  126. package/dist/lint/post-synth/cor020.js +60 -0
  127. package/dist/lint/post-synth/ext001.d.ts.map +1 -1
  128. package/dist/lint/post-synth/ext001.js +197 -0
  129. package/dist/lint/post-synth/index.js +124 -0
  130. package/dist/lint/post-synth/waw010.js +41 -0
  131. package/dist/lint/post-synth/waw011.js +41 -0
  132. package/dist/lint/post-synth/waw013.js +38 -0
  133. package/dist/lint/post-synth/waw014.js +42 -0
  134. package/dist/lint/post-synth/waw015.js +88 -0
  135. package/dist/lint/post-synth/waw016.d.ts.map +1 -1
  136. package/dist/lint/post-synth/waw016.js +116 -0
  137. package/dist/lint/post-synth/waw017.js +43 -0
  138. package/dist/lint/post-synth/waw018.js +61 -0
  139. package/dist/lint/post-synth/waw019.js +64 -0
  140. package/dist/lint/post-synth/waw020.js +56 -0
  141. package/dist/lint/post-synth/waw021.js +44 -0
  142. package/dist/lint/post-synth/waw022.js +36 -0
  143. package/dist/lint/post-synth/waw023.js +40 -0
  144. package/dist/lint/post-synth/waw024.js +46 -0
  145. package/dist/lint/post-synth/waw025.js +36 -0
  146. package/dist/lint/post-synth/waw026.js +38 -0
  147. package/dist/lint/post-synth/waw027.js +41 -0
  148. package/dist/lint/post-synth/waw028.js +39 -0
  149. package/dist/lint/post-synth/waw029.js +54 -0
  150. package/dist/lint/post-synth/waw030.js +282 -0
  151. package/dist/lint/post-synth/waw031.js +58 -0
  152. package/dist/lint/post-synth/waw032.js +45 -0
  153. package/dist/lint/post-synth/waw033.js +75 -0
  154. package/dist/lint/post-synth/waw034.js +52 -0
  155. package/dist/lint/post-synth/waw035.js +56 -0
  156. package/dist/lint/post-synth/waw036.js +79 -0
  157. package/dist/lint/post-synth/waw037.js +67 -0
  158. package/dist/lint/post-synth/waw038.js +42 -0
  159. package/dist/lint/post-synth/waw039.js +42 -0
  160. package/dist/lint/post-synth/waw040.js +45 -0
  161. package/dist/lint/post-synth/waw041.js +40 -0
  162. package/dist/lint/post-synth/waw042.js +99 -0
  163. package/dist/lint/post-synth/waw043.js +51 -0
  164. package/dist/lint/post-synth/waw044.js +64 -0
  165. package/dist/lint/post-synth/waw045.js +49 -0
  166. package/dist/lint/post-synth/waw046.js +52 -0
  167. package/dist/lint/post-synth/waw047.js +43 -0
  168. package/dist/lint/post-synth/waw048.js +40 -0
  169. package/dist/lint/post-synth/waw049.js +78 -0
  170. package/dist/lint/post-synth/waw050.js +44 -0
  171. package/dist/lint/post-synth/waw051.js +41 -0
  172. package/dist/lint/post-synth/waw052.js +43 -0
  173. package/dist/lint/post-synth/waw053.js +43 -0
  174. package/dist/lint/post-synth/waw054.js +41 -0
  175. package/dist/lint/post-synth/waw055.js +41 -0
  176. package/dist/lint/post-synth/waw056.js +65 -0
  177. package/dist/lint/post-synth/waw057.js +43 -0
  178. package/dist/lint/post-synth/waw058.js +61 -0
  179. package/dist/lint/post-synth/waw059.js +338 -0
  180. package/dist/lint/post-synth/waw060.js +83 -0
  181. package/dist/lint/post-synth/waw061.js +60 -0
  182. package/dist/lint/post-synth/waw062.js +0 -0
  183. package/dist/lint/post-synth/waw063.js +0 -0
  184. package/dist/lint/post-synth/waw064.js +45 -0
  185. package/dist/lint/post-synth/waw065.js +104 -0
  186. package/dist/lint/post-synth/waw066.js +145 -0
  187. package/dist/lint/post-synth/waw067.js +115 -0
  188. package/dist/lint/post-synth/waw068.js +69 -0
  189. package/dist/lint/post-synth/waw069.js +0 -0
  190. package/dist/lint/rules/hardcoded-region.js +38 -0
  191. package/dist/lint/rules/iam-wildcard.js +60 -0
  192. package/dist/lint/rules/index.js +6 -0
  193. package/dist/lint/rules/s3-encryption.js +60 -0
  194. package/dist/live-attrs.js +42 -0
  195. package/dist/lsp/completions.d.ts.map +1 -1
  196. package/dist/lsp/completions.js +18 -0
  197. package/dist/lsp/hover.d.ts.map +1 -1
  198. package/dist/lsp/hover.js +66 -0
  199. package/dist/manifest.json +1 -1
  200. package/dist/mapping.js +33 -0
  201. package/dist/meta.json +17359 -784
  202. package/dist/nested-stack.js +95 -0
  203. package/dist/okf/index.md +203 -0
  204. package/dist/okf/rules/EXT001.md +1 -0
  205. package/dist/okf/rules/WAW016.md +2 -0
  206. package/dist/okf/rules/WAW019.md +1 -0
  207. package/dist/okf/rules/WAW028.md +1 -0
  208. package/dist/okf/rules/WAW030.md +2 -0
  209. package/dist/okf/rules/WAW039.md +1 -0
  210. package/dist/okf/rules/WAW049.md +1 -0
  211. package/dist/okf/rules/WAW056.md +1 -0
  212. package/dist/okf/rules/WAW058.md +1 -0
  213. package/dist/okf/rules/WAW062.md +1 -0
  214. package/dist/okf/rules/WAW064.md +1 -0
  215. package/dist/okf/rules/WAW065.md +1 -0
  216. package/dist/okf/rules/WAW066.md +1 -0
  217. package/dist/okf/rules/WAW067.md +1 -0
  218. package/dist/okf/rules/WAW068.md +1 -0
  219. package/dist/okf/rules/WAW069.md +4 -0
  220. package/dist/okf/types/AIWorkloadConfig.md +23 -0
  221. package/dist/okf/types/ARCRegionSwitchPlan.md +1 -0
  222. package/dist/okf/types/AccountAccessApplication.md +28 -0
  223. package/dist/okf/types/AccountAccessEntitlement.md +22 -0
  224. package/dist/okf/types/ActionTarget.md +20 -0
  225. package/dist/okf/types/AdConfiguration.md +21 -0
  226. package/dist/okf/types/Adapter.md +26 -0
  227. package/dist/okf/types/AgentContext.md +35 -0
  228. package/dist/okf/types/AgentGoal.md +31 -0
  229. package/dist/okf/types/AgentProfile.md +34 -0
  230. package/dist/okf/types/Alarm.md +3 -1
  231. package/dist/okf/types/AlarmModel.md +14 -9
  232. package/dist/okf/types/AmplifyWebhook.md +25 -0
  233. package/dist/okf/types/ApiCache.md +8 -8
  234. package/dist/okf/types/ApiGatewayManagedOverrides.md +5 -5
  235. package/dist/okf/types/AppAuthorization.md +35 -0
  236. package/dist/okf/types/AppBlockBuilder.md +1 -0
  237. package/dist/okf/types/AppInstance.md +2 -2
  238. package/dist/okf/types/AppInstanceBot.md +2 -2
  239. package/dist/okf/types/AppStreamFleet.md +3 -2
  240. package/dist/okf/types/AppSyncApiKey.md +6 -6
  241. package/dist/okf/types/AppSyncType.md +22 -0
  242. package/dist/okf/types/ApplicationStatusCheck.md +36 -0
  243. package/dist/okf/types/ApplicationVersion.md +4 -1
  244. package/dist/okf/types/ApplicationsList.md +26 -0
  245. package/dist/okf/types/ApprovalPolicy.md +28 -0
  246. package/dist/okf/types/ArchiveRule.md +24 -0
  247. package/dist/okf/types/Asset.md +30 -0
  248. package/dist/okf/types/Backup.md +31 -0
  249. package/dist/okf/types/BedrockAgentCoreDataset.md +1 -1
  250. package/dist/okf/types/BedrockAgentCoreGateway.md +3 -0
  251. package/dist/okf/types/BedrockSession.md +28 -0
  252. package/dist/okf/types/BillEstimate.md +35 -0
  253. package/dist/okf/types/Brand.md +32 -0
  254. package/dist/okf/types/CallAnalyticsCategory.md +25 -0
  255. package/dist/okf/types/Campaign.md +28 -0
  256. package/dist/okf/types/CapacityProvider.md +30 -0
  257. package/dist/okf/types/Case.md +24 -0
  258. package/dist/okf/types/CertificateAssociation.md +13 -0
  259. package/dist/okf/types/ChangeSet.md +36 -0
  260. package/dist/okf/types/ChannelFlow.md +29 -0
  261. package/dist/okf/types/ChimeChannel.md +39 -0
  262. package/dist/okf/types/Classifier.md +6 -6
  263. package/dist/okf/types/ClientVpnAuthorizationRule.md +6 -6
  264. package/dist/okf/types/ClientVpnEndpoint.md +2 -0
  265. package/dist/okf/types/ClientVpnRoute.md +5 -5
  266. package/dist/okf/types/CloudConnector.md +29 -0
  267. package/dist/okf/types/Cluster.md +39 -0
  268. package/dist/okf/types/ClusterSchedulerConfig.md +30 -0
  269. package/dist/okf/types/CodeCommitRepository.md +12 -12
  270. package/dist/okf/types/CodeConnectionsHost.md +26 -0
  271. package/dist/okf/types/CodeRepository.md +5 -5
  272. package/dist/okf/types/CompositeAlarm.md +1 -0
  273. package/dist/okf/types/ComputeEnvironment.md +2 -0
  274. package/dist/okf/types/ComputeNodeGroup.md +1 -1
  275. package/dist/okf/types/ComputeQuota.md +34 -0
  276. package/dist/okf/types/ConfigRule.md +1 -1
  277. package/dist/okf/types/ConfigurationRecorder.md +7 -6
  278. package/dist/okf/types/ConnectAttachment.md +2 -0
  279. package/dist/okf/types/ConnectQueue.md +5 -1
  280. package/dist/okf/types/ConnectVocabulary.md +28 -0
  281. package/dist/okf/types/ConnectionType.md +24 -0
  282. package/dist/okf/types/ConsentPortal.md +33 -0
  283. package/dist/okf/types/ContactMethod.md +29 -0
  284. package/dist/okf/types/ContainerAssociation.md +26 -0
  285. package/dist/okf/types/ContainerFleet.md +1 -1
  286. package/dist/okf/types/ContainerGroupDefinition.md +1 -1
  287. package/dist/okf/types/Content.md +40 -0
  288. package/dist/okf/types/ContentAssociation.md +28 -0
  289. package/dist/okf/types/CustomDetectionRuleAssociation.md +28 -0
  290. package/dist/okf/types/CustomEntityType.md +4 -9
  291. package/dist/okf/types/Customization.md +22 -0
  292. package/dist/okf/types/CwIntegration.md +31 -0
  293. package/dist/okf/types/DAXParameterGroup.md +3 -8
  294. package/dist/okf/types/DAXSubnetGroup.md +0 -5
  295. package/dist/okf/types/DBClusterEndpoint.md +31 -0
  296. package/dist/okf/types/DBProxyTargetGroup.md +1 -0
  297. package/dist/okf/types/DBSnapshot.md +62 -0
  298. package/dist/okf/types/DLMLifecyclePolicy.md +12 -12
  299. package/dist/okf/types/DLPSetting.md +31 -0
  300. package/dist/okf/types/DMSInstanceProfile.md +1 -1
  301. package/dist/okf/types/DRSLaunchConfigurationTemplate.md +28 -0
  302. package/dist/okf/types/Daemon.md +1 -0
  303. package/dist/okf/types/DataExchangeDataSet.md +29 -0
  304. package/dist/okf/types/DataIntegrationFlow.md +27 -0
  305. package/dist/okf/types/DataMigration.md +1 -1
  306. package/dist/okf/types/DataProvider.md +2 -1
  307. package/dist/okf/types/DataQualityRuleset.md +6 -11
  308. package/dist/okf/types/DataSource.md +23 -0
  309. package/dist/okf/types/Dataset.md +20 -0
  310. package/dist/okf/types/DatasetIntegration.md +23 -0
  311. package/dist/okf/types/DbCluster.md +1 -1
  312. package/dist/okf/types/DbInstance.md +8 -2
  313. package/dist/okf/types/DeadlineBudget.md +29 -0
  314. package/dist/okf/types/DelegationSet.md +23 -0
  315. package/dist/okf/types/DeliveryChannel.md +6 -11
  316. package/dist/okf/types/DevOpsAgentAgentSpace.md +4 -0
  317. package/dist/okf/types/DevOpsAgentService.md +1 -0
  318. package/dist/okf/types/DevOpsAgentTrigger.md +28 -0
  319. package/dist/okf/types/DirectConnectGatewayAttachment.md +2 -0
  320. package/dist/okf/types/Directory.md +60 -0
  321. package/dist/okf/types/DocDBDBClusterParameterGroup.md +5 -10
  322. package/dist/okf/types/DocDBDBSubnetGroup.md +4 -9
  323. package/dist/okf/types/DocDBElasticClusterSnapshot.md +36 -0
  324. package/dist/okf/types/DocumentClassifierEndpoint.md +27 -0
  325. package/dist/okf/types/Domain.md +27 -0
  326. package/dist/okf/types/EKSCertificateAuthority.md +42 -0
  327. package/dist/okf/types/EKSCluster.md +8 -0
  328. package/dist/okf/types/EcSnapshot.md +66 -0
  329. package/dist/okf/types/EmailIdentityCertificate.md +15 -0
  330. package/dist/okf/types/EndpointConfig.md +14 -13
  331. package/dist/okf/types/EntityRecognizer.md +27 -0
  332. package/dist/okf/types/EntityRecognizerEndpoint.md +31 -0
  333. package/dist/okf/types/EnvironmentEC2.md +13 -13
  334. package/dist/okf/types/EvaluationForm.md +1 -0
  335. package/dist/okf/types/Evaluator.md +6 -2
  336. package/dist/okf/types/EventAction.md +26 -0
  337. package/dist/okf/types/EventRule.md +2 -0
  338. package/dist/okf/types/EventSource.md +30 -0
  339. package/dist/okf/types/EventTracker.md +22 -0
  340. package/dist/okf/types/EventsV2EventBus.md +28 -0
  341. package/dist/okf/types/EventsV2ResourcePolicy.md +19 -0
  342. package/dist/okf/types/EventsV2Subscriber.md +39 -0
  343. package/dist/okf/types/ExperimentDefinition.md +39 -0
  344. package/dist/okf/types/ExperimentRun.md +33 -0
  345. package/dist/okf/types/ExperimentTrialComponent.md +13 -11
  346. package/dist/okf/types/FHIRDatastore.md +3 -0
  347. package/dist/okf/types/FSxSnapshot.md +5 -5
  348. package/dist/okf/types/FSxVolume.md +9 -9
  349. package/dist/okf/types/FeaturedResultsSet.md +26 -0
  350. package/dist/okf/types/Feed.md +1 -0
  351. package/dist/okf/types/FieldLevelEncryptionConfig.md +25 -0
  352. package/dist/okf/types/FieldLevelEncryptionProfile.md +22 -0
  353. package/dist/okf/types/FileCache.md +45 -0
  354. package/dist/okf/types/Filter.md +27 -0
  355. package/dist/okf/types/Firewall.md +6 -0
  356. package/dist/okf/types/FlowMediaStream.md +28 -0
  357. package/dist/okf/types/FlowOutput.md +1 -0
  358. package/dist/okf/types/FpgaImage.md +38 -0
  359. package/dist/okf/types/Function.md +2 -2
  360. package/dist/okf/types/Gateway.md +41 -0
  361. package/dist/okf/types/GatewayClusterAssociations.md +23 -0
  362. package/dist/okf/types/GatewayRateLimit.md +26 -0
  363. package/dist/okf/types/GatewayRule.md +32 -0
  364. package/dist/okf/types/GlobalReplicationGroup.md +3 -0
  365. package/dist/okf/types/GlobalResolver.md +1 -1
  366. package/dist/okf/types/GlobalTable.md +1 -0
  367. package/dist/okf/types/GlueConnection.md +5 -4
  368. package/dist/okf/types/GlueSecurityConfiguration.md +1 -6
  369. package/dist/okf/types/GlueSession.md +38 -0
  370. package/dist/okf/types/GlueTable.md +5 -10
  371. package/dist/okf/types/GlueWorkflow.md +5 -10
  372. package/dist/okf/types/Group.md +27 -0
  373. package/dist/okf/types/Harness.md +1 -0
  374. package/dist/okf/types/HostKey.md +33 -0
  375. package/dist/okf/types/HostedZone.md +1 -0
  376. package/dist/okf/types/HttpApi.md +2 -0
  377. package/dist/okf/types/HttpNamespace.md +5 -5
  378. package/dist/okf/types/HubV2.md +1 -0
  379. package/dist/okf/types/HumanTaskUi.md +22 -0
  380. package/dist/okf/types/IPv4Pool.md +28 -0
  381. package/dist/okf/types/ImageBuilder.md +1 -0
  382. package/dist/okf/types/ImageBuilderImage.md +1 -1
  383. package/dist/okf/types/ImagePipeline.md +1 -1
  384. package/dist/okf/types/InferenceComponent.md +5 -1
  385. package/dist/okf/types/InfluxDBBackup.md +65 -0
  386. package/dist/okf/types/InfluxDBCluster.md +3 -0
  387. package/dist/okf/types/InfrastructureConfiguration.md +2 -0
  388. package/dist/okf/types/IngestionDestination.md +28 -0
  389. package/dist/okf/types/InputSecurityGroup.md +6 -4
  390. package/dist/okf/types/InspectorV2Connector.md +38 -0
  391. package/dist/okf/types/InstanceEventWindow.md +25 -0
  392. package/dist/okf/types/InstanceFleetConfig.md +10 -10
  393. package/dist/okf/types/InstanceGroupConfig.md +3 -3
  394. package/dist/okf/types/InstrumentationConfig.md +31 -0
  395. package/dist/okf/types/IntegrationAssociation.md +3 -0
  396. package/dist/okf/types/IoTSiteWiseApplication.md +34 -0
  397. package/dist/okf/types/IoTSiteWiseDataset.md +5 -2
  398. package/dist/okf/types/IoTSiteWiseTask.md +24 -0
  399. package/dist/okf/types/IpamExternalResourceVerificationToken.md +35 -0
  400. package/dist/okf/types/IpamInternetRegistryAssociation.md +32 -0
  401. package/dist/okf/types/Job.md +35 -0
  402. package/dist/okf/types/JobTemplate.md +26 -0
  403. package/dist/okf/types/KinesisChannel.md +31 -0
  404. package/dist/okf/types/KinesisStream.md +1 -0
  405. package/dist/okf/types/LambdaResourcePolicy.md +14 -0
  406. package/dist/okf/types/Lexicon.md +34 -0
  407. package/dist/okf/types/LicenseAssetGroup.md +23 -0
  408. package/dist/okf/types/LicenseConfiguration.md +33 -0
  409. package/dist/okf/types/LicenseServerEndpoint.md +32 -0
  410. package/dist/okf/types/LightsailKeyPair.md +29 -0
  411. package/dist/okf/types/LimitsProfile.md +27 -0
  412. package/dist/okf/types/LocationAzureBlob.md +2 -1
  413. package/dist/okf/types/LocationObjectStorage.md +1 -0
  414. package/dist/okf/types/LogAlarm.md +2 -0
  415. package/dist/okf/types/MGNConnector.md +23 -0
  416. package/dist/okf/types/MGNLaunchConfigurationTemplate.md +37 -0
  417. package/dist/okf/types/MLTransform.md +15 -15
  418. package/dist/okf/types/MWAAServerlessWorkflow.md +3 -0
  419. package/dist/okf/types/ManagedNotificationAccountContactAssociation.md +1 -0
  420. package/dist/okf/types/ManagedNotificationAdditionalChannelAssociation.md +1 -0
  421. package/dist/okf/types/MediaConvertJobTemplate.md +11 -13
  422. package/dist/okf/types/MediaConvertQueue.md +8 -10
  423. package/dist/okf/types/MediaInsightsPipelineConfiguration.md +28 -0
  424. package/dist/okf/types/MediaLiveInput.md +41 -18
  425. package/dist/okf/types/MediaPackageV2Channel.md +3 -0
  426. package/dist/okf/types/MediaPackageV2OriginEndpoint.md +1 -0
  427. package/dist/okf/types/MediaPipelineKinesisVideoStreamPool.md +28 -0
  428. package/dist/okf/types/MediaTailorFunction.md +27 -0
  429. package/dist/okf/types/MedicalVocabulary.md +21 -0
  430. package/dist/okf/types/Member.md +26 -0
  431. package/dist/okf/types/Memory.md +6 -0
  432. package/dist/okf/types/MemoryDBSnapshot.md +29 -0
  433. package/dist/okf/types/Metric.md +59 -0
  434. package/dist/okf/types/MetricAttribution.md +23 -0
  435. package/dist/okf/types/MicrosoftAD.md +11 -11
  436. package/dist/okf/types/MigrationProject.md +8 -1
  437. package/dist/okf/types/Monitor.md +26 -0
  438. package/dist/okf/types/NFSFileShare.md +44 -0
  439. package/dist/okf/types/NeptuneGraphGraph.md +1 -0
  440. package/dist/okf/types/NetworkConnector.md +4 -0
  441. package/dist/okf/types/NetworkFlowMonitorScope.md +23 -0
  442. package/dist/okf/types/NetworkMigrationDefinition.md +31 -0
  443. package/dist/okf/types/NetworkSecurityManagerDeployment.md +31 -0
  444. package/dist/okf/types/NetworkSecurityManagerPolicy.md +32 -0
  445. package/dist/okf/types/NetworkSecurityManagerScope.md +29 -0
  446. package/dist/okf/types/NotebookInstance.md +18 -18
  447. package/dist/okf/types/NotebookInstanceLifecycleConfig.md +6 -5
  448. package/dist/okf/types/NotifyConfiguration.md +35 -0
  449. package/dist/okf/types/OTelEnrichment.md +2 -0
  450. package/dist/okf/types/OnlineEvaluationConfig.md +0 -1
  451. package/dist/okf/types/OrganizationConfigRule.md +7 -7
  452. package/dist/okf/types/Outpost.md +32 -0
  453. package/dist/okf/types/ParallelData.md +40 -0
  454. package/dist/okf/types/Partition.md +5 -5
  455. package/dist/okf/types/PaymentConnector.md +4 -1
  456. package/dist/okf/types/Pentest.md +1 -0
  457. package/dist/okf/types/PerfReports.md +28 -0
  458. package/dist/okf/types/PermissionAssociation.md +30 -0
  459. package/dist/okf/types/PersonalizeDataset.md +1 -0
  460. package/dist/okf/types/PersonalizeDatasetGroup.md +1 -0
  461. package/dist/okf/types/PersonalizeSchema.md +1 -0
  462. package/dist/okf/types/Pipeline.md +25 -0
  463. package/dist/okf/types/PlaybackConfiguration.md +1 -0
  464. package/dist/okf/types/PolicyAssociation.md +1 -1
  465. package/dist/okf/types/PolicyGrant.md +2 -2
  466. package/dist/okf/types/PolicyPrincipalAttachment.md +2 -7
  467. package/dist/okf/types/PortalProduct.md +24 -0
  468. package/dist/okf/types/PrefetchSchedule.md +25 -0
  469. package/dist/okf/types/PricingPlanManagerSubscription.md +31 -0
  470. package/dist/okf/types/PrincipalAssociation.md +27 -0
  471. package/dist/okf/types/PrivateDnsNamespace.md +8 -8
  472. package/dist/okf/types/PrivateVirtualInterface.md +1 -0
  473. package/dist/okf/types/ProcurementPortalPreference.md +45 -0
  474. package/dist/okf/types/Program.md +33 -0
  475. package/dist/okf/types/ProjectMembership.md +1 -1
  476. package/dist/okf/types/ProtocolsList.md +26 -0
  477. package/dist/okf/types/PublicDnsNamespace.md +7 -7
  478. package/dist/okf/types/PublicVirtualInterface.md +1 -0
  479. package/dist/okf/types/QEV2IdcApplication.md +25 -0
  480. package/dist/okf/types/QueryLoggingConfig.md +21 -0
  481. package/dist/okf/types/QuerySuggestionsBlockList.md +25 -0
  482. package/dist/okf/types/QuickSightAssignment.md +24 -0
  483. package/dist/okf/types/RAMResourceAssociation.md +27 -0
  484. package/dist/okf/types/RDSClusterSnapshot.md +54 -0
  485. package/dist/okf/types/RDSDBParameterGroup.md +5 -0
  486. package/dist/okf/types/RDSDeployment.md +41 -0
  487. package/dist/okf/types/RcsAgent.md +38 -0
  488. package/dist/okf/types/ReceiptRule.md +5 -5
  489. package/dist/okf/types/ReceiptRuleSet.md +1 -6
  490. package/dist/okf/types/RecommenderFilter.md +27 -0
  491. package/dist/okf/types/RecommenderSchema.md +25 -0
  492. package/dist/okf/types/RecordSet.md +16 -22
  493. package/dist/okf/types/RecoveryPlan.md +28 -0
  494. package/dist/okf/types/RedshiftIdcApplication.md +31 -0
  495. package/dist/okf/types/RedshiftSnapshot.md +59 -0
  496. package/dist/okf/types/RegistrationAttachment.md +28 -0
  497. package/dist/okf/types/Registry.md +41 -0
  498. package/dist/okf/types/RegistryRecord.md +38 -0
  499. package/dist/okf/types/RelatedItem.md +24 -0
  500. package/dist/okf/types/ReplicationConfigurationTemplate.md +35 -0
  501. package/dist/okf/types/ReplicationSubnetGroup.md +4 -9
  502. package/dist/okf/types/ReplicationTask.md +14 -14
  503. package/dist/okf/types/ReportGenerator.md +29 -0
  504. package/dist/okf/types/ReportGroup.md +1 -3
  505. package/dist/okf/types/ResilienceHubV2Policy.md +1 -0
  506. package/dist/okf/types/ResilienceHubV2Service.md +1 -0
  507. package/dist/okf/types/ResourceConfiguration.md +1 -1
  508. package/dist/okf/types/ResourceMetricsConfiguration.md +21 -0
  509. package/dist/okf/types/RestApi.md +1 -0
  510. package/dist/okf/types/RetrievalInstruction.md +32 -0
  511. package/dist/okf/types/RouterOutput.md +1 -0
  512. package/dist/okf/types/Rule.md +31 -0
  513. package/dist/okf/types/RunCache.md +29 -0
  514. package/dist/okf/types/Runtime.md +2 -1
  515. package/dist/okf/types/SCNInstance.md +33 -0
  516. package/dist/okf/types/SDBDomain.md +2 -2
  517. package/dist/okf/types/SMBFileShare.md +49 -0
  518. package/dist/okf/types/SageMakerArtifact.md +27 -0
  519. package/dist/okf/types/SageMakerEndpoint.md +0 -1
  520. package/dist/okf/types/ScalableTarget.md +1 -0
  521. package/dist/okf/types/ScalingPlan.md +6 -6
  522. package/dist/okf/types/ScheduledReport.md +31 -0
  523. package/dist/okf/types/SecondaryNetwork.md +26 -0
  524. package/dist/okf/types/SecurityAgentArtifact.md +25 -0
  525. package/dist/okf/types/SecurityAgentIntegration.md +31 -0
  526. package/dist/okf/types/Server.md +1 -0
  527. package/dist/okf/types/ServerlessCache.md +2 -0
  528. package/dist/okf/types/ServerlessCacheSnapshot.md +31 -0
  529. package/dist/okf/types/ServerlessRepoApplication.md +32 -0
  530. package/dist/okf/types/ServiceDiscoveryInstance.md +3 -7
  531. package/dist/okf/types/SipMediaApplication.md +27 -0
  532. package/dist/okf/types/SiteToSiteVpnAttachment.md +2 -0
  533. package/dist/okf/types/SnapshotCopyGrant.md +20 -0
  534. package/dist/okf/types/Solution.md +1 -0
  535. package/dist/okf/types/SourceAssociation.md +25 -0
  536. package/dist/okf/types/SourceCredential.md +6 -6
  537. package/dist/okf/types/SourceNetwork.md +23 -0
  538. package/dist/okf/types/StackFleetAssociation.md +2 -7
  539. package/dist/okf/types/StorageTierPolicy.md +20 -0
  540. package/dist/okf/types/StorageVirtualMachine.md +9 -9
  541. package/dist/okf/types/Stream.md +28 -0
  542. package/dist/okf/types/SubnetCidrReservation.md +26 -0
  543. package/dist/okf/types/SubscriptionProvider.md +26 -0
  544. package/dist/okf/types/SupportPermit.md +29 -0
  545. package/dist/okf/types/Table.md +2 -1
  546. package/dist/okf/types/TableOptimizer.md +5 -10
  547. package/dist/okf/types/Tape.md +31 -0
  548. package/dist/okf/types/Template.md +36 -0
  549. package/dist/okf/types/Tenant.md +2 -0
  550. package/dist/okf/types/Terminology.md +39 -0
  551. package/dist/okf/types/Thesaurus.md +25 -0
  552. package/dist/okf/types/ThingPrincipalAttachment.md +3 -8
  553. package/dist/okf/types/Topic.md +1 -0
  554. package/dist/okf/types/TopicRuleDestination.md +1 -0
  555. package/dist/okf/types/TrafficPolicy.md +26 -0
  556. package/dist/okf/types/TrafficPolicyInstance.md +28 -0
  557. package/dist/okf/types/TranscribeVocabulary.md +27 -0
  558. package/dist/okf/types/TransitGatewayRouteTableAttachment.md +2 -0
  559. package/dist/okf/types/TransitVirtualInterface.md +1 -0
  560. package/dist/okf/types/Tunnel.md +25 -0
  561. package/dist/okf/types/UsageLimit.md +26 -0
  562. package/dist/okf/types/UseCase.md +23 -0
  563. package/dist/okf/types/User.md +47 -0
  564. package/dist/okf/types/VPCEndpoint.md +1 -1
  565. package/dist/okf/types/VPCEndpointService.md +6 -0
  566. package/dist/okf/types/VPCPeeringConnection.md +2 -2
  567. package/dist/okf/types/VPNConcentrator.md +1 -1
  568. package/dist/okf/types/VPNConnection.md +1 -1
  569. package/dist/okf/types/VerifiedDestinationNumber.md +25 -0
  570. package/dist/okf/types/View.md +27 -0
  571. package/dist/okf/types/VoiceConnector.md +30 -0
  572. package/dist/okf/types/Volume.md +44 -0
  573. package/dist/okf/types/Vpc.md +1 -1
  574. package/dist/okf/types/VpcAttachment.md +2 -0
  575. package/dist/okf/types/WebFunction.md +27 -0
  576. package/dist/okf/types/WebFunctionEndpoint.md +44 -0
  577. package/dist/okf/types/WebFunctionRevision.md +32 -0
  578. package/dist/okf/types/WickrNetwork.md +27 -0
  579. package/dist/okf/types/Worker.md +29 -0
  580. package/dist/okf/types/Workforce.md +26 -0
  581. package/dist/okf/types/Workload.md +35 -0
  582. package/dist/okf/types/WorkloadEstimate.md +35 -0
  583. package/dist/okf/types/Workspace.md +28 -0
  584. package/dist/okf/types/Workteam.md +8 -8
  585. package/dist/op/activities/aws-apply.js +214 -0
  586. package/dist/op/activities/floci.js +97 -0
  587. package/dist/op/activities/index.js +32 -0
  588. package/dist/op/builders.js +50 -0
  589. package/dist/ownership.js +52 -0
  590. package/dist/package-cli.js +25 -0
  591. package/dist/parameter.js +19 -0
  592. package/dist/plugin.d.ts.map +1 -1
  593. package/dist/plugin.js +1012 -0
  594. package/dist/properties.js +166 -0
  595. package/dist/pseudo.js +25 -0
  596. package/dist/receipt-store.d.ts.map +1 -1
  597. package/dist/receipt-store.js +233 -0
  598. package/dist/reference-catalog.js +106 -0
  599. package/dist/rules/ext001.ts +3 -3
  600. package/dist/rules/waw016.ts +2 -2
  601. package/dist/serializer.js +529 -0
  602. package/dist/spec/fetch.js +193 -0
  603. package/dist/spec/parse.js +259 -0
  604. package/dist/spec/pin.js +185 -0
  605. package/dist/spec/pinned-types.json +203 -0
  606. package/dist/stack-errors.js +14 -0
  607. package/dist/taggable.d.ts.map +1 -1
  608. package/dist/taggable.js +33 -0
  609. package/dist/teardown.js +199 -0
  610. package/dist/template-sections.js +53 -0
  611. package/dist/template-transform.js +50 -0
  612. package/dist/types/index.d.ts +18847 -1124
  613. package/dist/validate-cli.js +16 -0
  614. package/dist/validate.js +33 -0
  615. package/package.json +9 -9
  616. package/src/agentcore/trace-fetch.ts +2 -1
  617. package/src/api/credential-chain.ts +119 -9
  618. package/src/api/credential-isolation.test.ts +72 -0
  619. package/src/api/read-client-chain.test.ts +159 -0
  620. package/src/api/read-client.ts +42 -6
  621. package/src/api/sigv4.ts +4 -4
  622. package/src/caller-identity.ts +3 -5
  623. package/src/codegen/any-budget.test.ts +12 -2
  624. package/src/codegen/generate.ts +9 -0
  625. package/src/codegen/package.ts +2 -2
  626. package/src/codegen/patches.test.ts +95 -0
  627. package/src/codegen/patches.ts +53 -9
  628. package/src/codegen/property-overlay.json +1 -16
  629. package/src/components/apply.ts +218 -6
  630. package/src/components/cfn-plan-floci.e2e.test.ts +76 -0
  631. package/src/components/cfn-plan.test.ts +225 -16
  632. package/src/components/cloud-executor.ts +73 -25
  633. package/src/deep-observe.ts +2 -1
  634. package/src/disruption.ts +2 -1
  635. package/src/generated/index.d.ts +18847 -1124
  636. package/src/generated/index.ts +1376 -161
  637. package/src/generated/lexicon-aws.json +17359 -784
  638. package/src/health.test.ts +136 -0
  639. package/src/health.ts +281 -0
  640. package/src/identity-observe.ts +2 -1
  641. package/src/lint/post-synth/ext001.ts +3 -3
  642. package/src/lint/post-synth/waw016.ts +2 -2
  643. package/src/lsp/completions.ts +2 -1
  644. package/src/lsp/hover.ts +2 -1
  645. package/src/plugin.ts +10 -1
  646. package/src/receipt-store.ts +2 -1
  647. package/src/spec/pin.ts +3 -3
  648. package/src/spec/pinned-types.json +203 -0
  649. package/src/taggable.ts +2 -2
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Runtime factory constructors — re-exported from core.
3
+ */
4
+ export { createResource, createProperty } from "@intentius/chant/runtime";
@@ -0,0 +1,131 @@
1
+ /**
2
+ * AWS governance authoring: the desired-state config
3
+ * shape an external governance reconciler applies, and `landingZoneConfig()` —
4
+ * the typed authoring layer that emits it.
5
+ *
6
+ * This is deliberately NOT a composite. The evaluability rules (EVL002/004,
7
+ * #916/#952) require composites to declare a fixed set of resources, so a
8
+ * data-driven OU tree walker cannot be one. The split mirrors the SCM
9
+ * reconcilers: authoring emits config (this module, arbitrary cardinality);
10
+ * resources for greenfield bootstrap are the fixed-shape composites in
11
+ * `composites/landing-zone.ts`; the reconciler consumes only the config.
12
+ *
13
+ * GCP (Folder/OrgPolicy/AuditConfig) and Azure (blocked on #1545)
14
+ * counterparts followed the same shape.
15
+ */
16
+ // ---------------------------------------------------------------------------
17
+ // Baseline guardrails (shared with the bootstrap composites)
18
+ // ---------------------------------------------------------------------------
19
+ export const DENY_LEAVE_ORGANIZATION = {
20
+ description: "Member accounts may not remove themselves from the organization.",
21
+ document: {
22
+ Version: "2012-10-17",
23
+ Statement: [{ Effect: "Deny", Action: "organizations:LeaveOrganization", Resource: "*" }],
24
+ },
25
+ };
26
+ export const DENY_AUDIT_TAMPER = {
27
+ description: "Audit trails and recorders cannot be stopped or deleted from member accounts.",
28
+ document: {
29
+ Version: "2012-10-17",
30
+ Statement: [
31
+ {
32
+ Effect: "Deny",
33
+ Action: [
34
+ "cloudtrail:StopLogging",
35
+ "cloudtrail:DeleteTrail",
36
+ "config:StopConfigurationRecorder",
37
+ "config:DeleteConfigurationRecorder",
38
+ "config:DeleteDeliveryChannel",
39
+ ],
40
+ Resource: "*",
41
+ },
42
+ ],
43
+ },
44
+ };
45
+ /** Deny requests outside `regions`, excepting global services. */
46
+ export function regionRestriction(regions) {
47
+ return {
48
+ description: `Deny requests outside [${regions.join(", ")}] except global services.`,
49
+ document: {
50
+ Version: "2012-10-17",
51
+ Statement: [
52
+ {
53
+ Effect: "Deny",
54
+ NotAction: [
55
+ "iam:*",
56
+ "organizations:*",
57
+ "route53:*",
58
+ "cloudfront:*",
59
+ "sts:*",
60
+ "support:*",
61
+ "budgets:*",
62
+ ],
63
+ Resource: "*",
64
+ Condition: { StringNotEquals: { "aws:RequestedRegion": regions } },
65
+ },
66
+ ],
67
+ },
68
+ };
69
+ }
70
+ /**
71
+ * The recommended foundation OU structure. Exported so callers can extend it
72
+ * rather than restate it.
73
+ */
74
+ export const FOUNDATION_OUS = {
75
+ Security: { scps: ["deny-audit-tamper"] },
76
+ Infrastructure: {},
77
+ Sandbox: {},
78
+ Workloads: {},
79
+ };
80
+ /**
81
+ * Author the desired-state tree an external governance reconciler applies.
82
+ * Pure. Throws when the tree attaches an SCP name with no definition; only
83
+ * SCPs the tree actually attaches are included in the output.
84
+ */
85
+ export function landingZoneConfig(props = {}) {
86
+ const foundation = props.foundation ?? true;
87
+ const scps = {
88
+ ...(foundation
89
+ ? { "deny-leave-organization": DENY_LEAVE_ORGANIZATION, "deny-audit-tamper": DENY_AUDIT_TAMPER }
90
+ : {}),
91
+ ...(props.allowedRegions?.length ? { "region-restriction": regionRestriction(props.allowedRegions) } : {}),
92
+ ...props.scps,
93
+ };
94
+ const ous = { ...(foundation ? FOUNDATION_OUS : {}), ...props.ous };
95
+ const rootScps = [
96
+ ...(foundation ? ["deny-leave-organization"] : []),
97
+ ...(props.allowedRegions?.length ? ["region-restriction"] : []),
98
+ ...(props.rootScps ?? []),
99
+ ];
100
+ const attached = new Set(rootScps);
101
+ const collect = (tree) => {
102
+ for (const node of Object.values(tree)) {
103
+ for (const s of node.scps ?? [])
104
+ attached.add(s);
105
+ if (node.children)
106
+ collect(node.children);
107
+ }
108
+ };
109
+ collect(ous);
110
+ for (const name of attached) {
111
+ if (!scps[name])
112
+ throw new Error(`landingZoneConfig: SCP "${name}" is attached but not defined in scps`);
113
+ }
114
+ if (props.identity) {
115
+ const granted = [...(props.identity.assignments ?? []), ...(props.identity.breakGlass ? [props.identity.breakGlass] : [])];
116
+ for (const a of granted) {
117
+ if (!props.identity.permissionSets[a.permissionSet]) {
118
+ throw new Error(`landingZoneConfig: assignment for "${a.principal}" references permission set "${a.permissionSet}" not defined in identity.permissionSets`);
119
+ }
120
+ }
121
+ }
122
+ return {
123
+ organization: rootScps.length ? { scps: rootScps } : {},
124
+ ous,
125
+ scps: Object.fromEntries(Object.entries(scps).filter(([n]) => attached.has(n))),
126
+ ...(props.identity ? { identity: props.identity } : {}),
127
+ ...(props.cloudtrailBucket
128
+ ? { auditSinks: { cloudtrail: { bucket: props.cloudtrailBucket, multiRegion: true } } }
129
+ : {}),
130
+ };
131
+ }
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Runtime health for AWS (#4177): Route 53 health checks and ECS services.
3
+ *
4
+ * The stack's own resource list maps each logical id (the graph's node id) to
5
+ * the physical id the health APIs take. A stack that does not exist yet means
6
+ * nothing is deployed, so every entity is absent. Any other stack failure is a
7
+ * hole for every entity, never `unhealthy`.
8
+ *
9
+ * - `AWS::Route53::HealthCheck`: `GetHealthCheckStatus`, aggregated as Route 53
10
+ * does: healthy when more than 18% of the checkers report healthy.
11
+ * - `AWS::ECS::Service`: `DescribeServices`, `runningCount` against
12
+ * `desiredCount`.
13
+ *
14
+ * Both go through the read transport's endpoint rule, so `AWS_ENDPOINT_URL`
15
+ * (Floci) answers them.
16
+ */
17
+ import type { HealthEntry, HealthReadOptions, HealthReadResult } from "@intentius/chant/lexicon";
18
+ import { type AwsReadClientOptions } from "./api/read-client.js";
19
+ export declare const AWS_HEALTH_TYPES: readonly ["AWS::Route53::HealthCheck", "AWS::ECS::Service"];
20
+ /** Injectable HTTP for both calls, so tests never reach the network. */
21
+ export type AwsHealthHttp = (method: "GET" | "POST", url: string, init: {
22
+ headers: Record<string, string>;
23
+ body?: string;
24
+ }) => Promise<{
25
+ status: number;
26
+ text: string;
27
+ }>;
28
+ export interface AwsHealthOptions extends HealthReadOptions {
29
+ http?: AwsHealthHttp;
30
+ /** Read client for the stack list and the signing decision. Tests inject `http` and `env` here. */
31
+ client?: AwsReadClientOptions;
32
+ now?: () => Date;
33
+ }
34
+ /** One checker's report, as `GetHealthCheckStatus` returns it. */
35
+ export interface CheckerObservation {
36
+ region?: string;
37
+ ipAddress?: string;
38
+ status: string;
39
+ checkedTime?: string;
40
+ }
41
+ /** Parse `GetHealthCheckStatusResponse`'s observations. */
42
+ export declare function parseHealthCheckStatus(xml: string): CheckerObservation[];
43
+ /** Route 53's verdict over its checkers' observations. */
44
+ export declare function healthCheckEntry(observations: CheckerObservation[], observedAt: string): HealthEntry;
45
+ /** The parts of an ECS service `DescribeServices` returns that decide health. */
46
+ export interface EcsServiceState {
47
+ status?: string;
48
+ desiredCount?: number;
49
+ runningCount?: number;
50
+ pendingCount?: number;
51
+ deployments?: Array<{
52
+ rolloutState?: string;
53
+ updatedAt?: number | string;
54
+ }>;
55
+ }
56
+ /** Running against desired. Scaled to zero is `unknown`: nothing is serving, by choice. */
57
+ export declare function ecsServiceEntry(service: EcsServiceState, observedAt: string): HealthEntry;
58
+ /** The cluster a service ARN names: `service/<cluster>/<name>`, or the default cluster for the old `service/<name>` form. */
59
+ export declare function clusterOfServiceArn(arn: string): string;
60
+ export declare function observeHealthAws(options: AwsHealthOptions): Promise<HealthReadResult>;
61
+ //# sourceMappingURL=health.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../src/health.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,gBAAgB,EAAoB,MAAM,0BAA0B,CAAC;AACnH,OAAO,EASL,KAAK,oBAAoB,EAC1B,MAAM,mBAAmB,CAAC;AAI3B,eAAO,MAAM,gBAAgB,YAAI,2BAA2B,EAAE,mBAAmB,CAAU,CAAC;AAE5F,wEAAwE;AACxE,MAAM,MAAM,aAAa,GAAG,CAC1B,MAAM,EAAE,KAAK,GAAG,MAAM,EACtB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,KACrD,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAO/C,MAAM,WAAW,gBAAiB,SAAQ,iBAAiB;IACzD,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,mGAAmG;IACnG,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB;AAKD,kEAAkE;AAClE,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,2DAA2D;AAC3D,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB,EAAE,CAcxE;AAOD,0DAA0D;AAC1D,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,kBAAkB,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,WAAW,CAepG;AAED,iFAAiF;AACjF,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC,CAAC;CAC7E;AAED,2FAA2F;AAC3F,wBAAgB,eAAe,CAAC,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,GAAG,WAAW,CAazF;AAED,6HAA6H;AAC7H,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAIvD;AAkED,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAgF3F"}
package/dist/health.js ADDED
@@ -0,0 +1,216 @@
1
+ /**
2
+ * Runtime health for AWS (#4177): Route 53 health checks and ECS services.
3
+ *
4
+ * The stack's own resource list maps each logical id (the graph's node id) to
5
+ * the physical id the health APIs take. A stack that does not exist yet means
6
+ * nothing is deployed, so every entity is absent. Any other stack failure is a
7
+ * hole for every entity, never `unhealthy`.
8
+ *
9
+ * - `AWS::Route53::HealthCheck`: `GetHealthCheckStatus`, aggregated as Route 53
10
+ * does: healthy when more than 18% of the checkers report healthy.
11
+ * - `AWS::ECS::Service`: `DescribeServices`, `runningCount` against
12
+ * `desiredCount`.
13
+ *
14
+ * Both go through the read transport's endpoint rule, so `AWS_ENDPOINT_URL`
15
+ * (Floci) answers them.
16
+ */
17
+ import { AwsReadError, describeStackResources, requestHeaders, serviceUrl, withChainCredentials, withEndpointOverride, xmlError, xmlLeaves, } from "./api/read-client.js";
18
+ import { resolveCredentials, signRequest } from "./api/sigv4.js";
19
+ import { stackDoesNotExist } from "./stack-errors.js";
20
+ export const AWS_HEALTH_TYPES = ["AWS::Route53::HealthCheck", "AWS::ECS::Service"];
21
+ const defaultHttp = async (method, url, init) => {
22
+ const res = await fetch(url, { method, headers: init.headers, ...(init.body !== undefined ? { body: init.body } : {}) });
23
+ return { status: res.status, text: await res.text() };
24
+ };
25
+ /** Route 53 treats an endpoint as healthy when more than this share of checkers says so. */
26
+ const ROUTE53_HEALTHY_SHARE = 0.18;
27
+ /** Parse `GetHealthCheckStatusResponse`'s observations. */
28
+ export function parseHealthCheckStatus(xml) {
29
+ const out = [];
30
+ for (const m of xml.matchAll(/<HealthCheckObservation>([\s\S]*?)<\/HealthCheckObservation>/g)) {
31
+ const body = m[1] ?? "";
32
+ const report = xmlLeaves(body.match(/<StatusReport>([\s\S]*?)<\/StatusReport>/)?.[1] ?? "");
33
+ const top = xmlLeaves(body.replace(/<StatusReport>[\s\S]*?<\/StatusReport>/, ""));
34
+ out.push({
35
+ ...(top.Region ? { region: top.Region } : {}),
36
+ ...(top.IPAddress ? { ipAddress: top.IPAddress } : {}),
37
+ status: report.Status ?? "",
38
+ ...(report.CheckedTime ? { checkedTime: report.CheckedTime } : {}),
39
+ });
40
+ }
41
+ return out;
42
+ }
43
+ /** A checker's status text starts with `Success` when it found the endpoint healthy. */
44
+ function checkerHealthy(o) {
45
+ return /^success/i.test(o.status.trim());
46
+ }
47
+ /** Route 53's verdict over its checkers' observations. */
48
+ export function healthCheckEntry(observations, observedAt) {
49
+ const type = "AWS::Route53::HealthCheck";
50
+ if (observations.length === 0) {
51
+ return { type, state: "unknown", detail: "no checker has reported yet", observedAt };
52
+ }
53
+ const healthy = observations.filter(checkerHealthy).length;
54
+ const latest = [...observations].sort((a, b) => (b.checkedTime ?? "").localeCompare(a.checkedTime ?? ""))[0];
55
+ const state = healthy / observations.length > ROUTE53_HEALTHY_SHARE ? "healthy" : "unhealthy";
56
+ return {
57
+ type,
58
+ state,
59
+ detail: `${healthy}/${observations.length} checkers healthy; last: ${latest.status}`,
60
+ observedAt,
61
+ ...(latest.checkedTime ? { checkedAt: latest.checkedTime } : {}),
62
+ };
63
+ }
64
+ /** Running against desired. Scaled to zero is `unknown`: nothing is serving, by choice. */
65
+ export function ecsServiceEntry(service, observedAt) {
66
+ const type = "AWS::ECS::Service";
67
+ const desired = service.desiredCount ?? 0;
68
+ const running = service.runningCount ?? 0;
69
+ const pending = service.pendingCount ?? 0;
70
+ const counts = `${running}/${desired} running${pending > 0 ? `, ${pending} pending` : ""}`;
71
+ const rollout = service.deployments?.find((d) => d.rolloutState)?.rolloutState;
72
+ const detail = `${counts}${rollout ? `, rollout ${rollout}` : ""}`;
73
+ if (service.status && service.status !== "ACTIVE") {
74
+ return { type, state: "unhealthy", detail: `service is ${service.status}; ${detail}`, observedAt };
75
+ }
76
+ if (desired === 0)
77
+ return { type, state: "unknown", detail: `desired count is 0; ${detail}`, observedAt };
78
+ return { type, state: running >= desired ? "healthy" : "unhealthy", detail, observedAt };
79
+ }
80
+ /** The cluster a service ARN names: `service/<cluster>/<name>`, or the default cluster for the old `service/<name>` form. */
81
+ export function clusterOfServiceArn(arn) {
82
+ const resource = arn.split(":").slice(5).join(":");
83
+ const parts = resource.split("/");
84
+ return parts.length >= 3 ? parts[1] : "default";
85
+ }
86
+ function holeFrom(type, err) {
87
+ const detail = err instanceof AwsReadError && err.code ? `${err.code}: ${err.message}` : err instanceof Error ? err.message : String(err);
88
+ const reason = /credential|token|expired|AccessDenied|not authorized|Unauthorized/i.test(detail) ? "no-credentials" : "read-failed";
89
+ return { type, reason, detail: detail.slice(0, 200) };
90
+ }
91
+ async function getHealthCheckStatus(id, client, http) {
92
+ const options = await withChainCredentials(withEndpointOverride("route53", client));
93
+ // Route 53 is global: one host, signed in us-east-1.
94
+ const base = (options.endpoint ?? "https://route53.amazonaws.com").replace(/\/$/, "");
95
+ const url = `${base}/2013-04-01/healthcheck/${encodeURIComponent(id)}/status`;
96
+ const env = options.env ?? process.env;
97
+ const credentials = resolveCredentials(options.credentials, env);
98
+ const signable = credentials && (!options.endpoint || options.signEndpointOverride === true);
99
+ const headers = signable
100
+ ? signRequest({ method: "GET", url, headers: {}, body: "", service: "route53", region: "us-east-1", credentials, ...(options.now ? { now: options.now } : {}) })
101
+ : {};
102
+ const res = await http("GET", url, { headers });
103
+ const err = xmlError(res.text);
104
+ if (err || res.status >= 400) {
105
+ throw new AwsReadError(err?.message ?? `GetHealthCheckStatus failed with HTTP ${res.status}`, res.status, err?.code);
106
+ }
107
+ return parseHealthCheckStatus(res.text);
108
+ }
109
+ async function describeServices(cluster, arns, client, http) {
110
+ const options = await withChainCredentials(withEndpointOverride("ecs", client));
111
+ const url = serviceUrl("ecs", options.endpoint, options.region);
112
+ const body = JSON.stringify({ cluster, services: arns });
113
+ const headers = requestHeaders("ecs", url, body, { "content-type": "application/x-amz-json-1.1", "x-amz-target": "AmazonEC2ContainerServiceV20141113.DescribeServices" }, options);
114
+ const res = await http("POST", url, { headers, body });
115
+ let parsed = {};
116
+ try {
117
+ const value = JSON.parse(res.text);
118
+ if (value && typeof value === "object" && !Array.isArray(value))
119
+ parsed = value;
120
+ }
121
+ catch {
122
+ throw new AwsReadError("unparseable DescribeServices response", res.status);
123
+ }
124
+ const errType = typeof parsed.__type === "string" ? parsed.__type.split("#").pop() : undefined;
125
+ if (errType || res.status >= 400) {
126
+ const message = typeof parsed.message === "string" ? parsed.message : `DescribeServices failed with HTTP ${res.status}`;
127
+ throw new AwsReadError(message, res.status, errType);
128
+ }
129
+ return {
130
+ services: Array.isArray(parsed.services) ? parsed.services : [],
131
+ failures: Array.isArray(parsed.failures) ? parsed.failures : [],
132
+ };
133
+ }
134
+ export async function observeHealthAws(options) {
135
+ const http = options.http ?? defaultHttp;
136
+ const observedAt = (options.now?.() ?? new Date()).toISOString();
137
+ const client = { ...(options.client ?? {}), ...(options.region ? { region: options.region } : {}) };
138
+ const entities = {};
139
+ const unobserved = {};
140
+ const absent = [];
141
+ if (options.entities.size === 0)
142
+ return { entities, unobserved, absent };
143
+ const stackName = options.stack ?? options.environment;
144
+ let physical;
145
+ try {
146
+ const resources = await describeStackResources(stackName, client);
147
+ physical = new Map(resources.filter((r) => r.physicalId).map((r) => [r.logicalId, r.physicalId]));
148
+ }
149
+ catch (err) {
150
+ if (err instanceof AwsReadError && stackDoesNotExist(err.message))
151
+ return { entities, unobserved, absent: [...options.entities.keys()] };
152
+ for (const [name, { entityType }] of options.entities) {
153
+ unobserved[name] = holeFrom(entityType, err);
154
+ unobserved[name].detail = `DescribeStackResources failed for stack "${stackName}": ${unobserved[name].detail}`;
155
+ }
156
+ return { entities, unobserved, absent };
157
+ }
158
+ const services = new Map();
159
+ const checks = [];
160
+ for (const [name, { entityType }] of options.entities) {
161
+ const id = physical.get(name);
162
+ if (!id) {
163
+ absent.push(name);
164
+ continue;
165
+ }
166
+ if (entityType === "AWS::ECS::Service") {
167
+ const cluster = clusterOfServiceArn(id);
168
+ const list = services.get(cluster) ?? [];
169
+ list.push({ name, arn: id });
170
+ services.set(cluster, list);
171
+ }
172
+ else if (entityType === "AWS::Route53::HealthCheck") {
173
+ checks.push({ name, id });
174
+ }
175
+ }
176
+ await Promise.all(checks.map(async ({ name, id }) => {
177
+ try {
178
+ entities[name] = healthCheckEntry(await getHealthCheckStatus(id, client, http), observedAt);
179
+ }
180
+ catch (err) {
181
+ if (err instanceof AwsReadError && err.code === "NoSuchHealthCheck")
182
+ absent.push(name);
183
+ else
184
+ unobserved[name] = holeFrom("AWS::Route53::HealthCheck", err);
185
+ }
186
+ }));
187
+ await Promise.all([...services].map(async ([cluster, members]) => {
188
+ // DescribeServices takes at most ten services per call.
189
+ for (let i = 0; i < members.length; i += 10) {
190
+ const batch = members.slice(i, i + 10);
191
+ try {
192
+ const { services: found, failures } = await describeServices(cluster, batch.map((m) => m.arn), client, http);
193
+ for (const member of batch) {
194
+ const service = found.find((s) => s.serviceArn === member.arn || s.serviceArn?.endsWith(`/${member.arn.split("/").pop()}`));
195
+ const failure = failures.find((f) => f.arn === member.arn);
196
+ if (service)
197
+ entities[member.name] = ecsServiceEntry(service, observedAt);
198
+ else if (failure?.reason === "MISSING")
199
+ absent.push(member.name);
200
+ else {
201
+ unobserved[member.name] = {
202
+ type: "AWS::ECS::Service",
203
+ reason: "read-failed",
204
+ detail: failure?.reason ? `DescribeServices: ${failure.reason}` : "DescribeServices did not return the service",
205
+ };
206
+ }
207
+ }
208
+ }
209
+ catch (err) {
210
+ for (const member of batch)
211
+ unobserved[member.name] = holeFrom("AWS::ECS::Service", err);
212
+ }
213
+ }
214
+ }));
215
+ return { entities, unobserved, absent };
216
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"identity-observe.d.ts","sourceRoot":"","sources":["../src/identity-observe.ts"],"names":[],"mappings":"AAwBA,OAAO,EAA4C,KAAK,oBAAoB,EAAgC,MAAM,mBAAmB,CAAC;AACtI,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAmBjE;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,SAAS,CAazG;AAkCD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,MAAM,EAAE,EACrB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC,GAAG,SAAS,EACzF,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,EACzC,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAAC,CA4B3F"}
1
+ {"version":3,"file":"identity-observe.d.ts","sourceRoot":"","sources":["../src/identity-observe.ts"],"names":[],"mappings":"AAyBA,OAAO,EAA4C,KAAK,oBAAoB,EAAgC,MAAM,mBAAmB,CAAC;AACtI,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAmBjE;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,SAAS,CAazG;AAkCD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,MAAM,EAAE,EACrB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC,GAAG,SAAS,EACzF,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,EACzC,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAAC,CA4B3F"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * The identity fallback on the stack read (#1647).
3
+ *
4
+ * `describeResources` asks CloudFormation exactly one question — is there a
5
+ * logical id named <entity> in this stack? — which reads a freshly
6
+ * carve-emitted, still-Terraform-owned resource as confirmed-absent even
7
+ * though the declared `BucketName` names it precisely. When a declared entity
8
+ * is absent from the stack AND its props spell the type's full primary
9
+ * identifier (the spec knowledge the codegen already compiled into
10
+ * `lexicon-aws.json`), ask Cloud Control for it by identity. Found means
11
+ * OBSERVED: `ownership: "foreign"` (it exists and something other than this
12
+ * stack owns it — Terraform, a console hand, another tool) and
13
+ * `status: "EXTERNAL"` (live outside the stack, deliberately not a
14
+ * CloudFormation status word).
15
+ *
16
+ * Best-effort ON TOP of a stack answer, never instead of one: a genuine miss
17
+ * (`ResourceNotFoundException`) keeps the stack's absent verdict, and so does
18
+ * every other refusal (`UnsupportedOperation` — a Floci without Cloud
19
+ * Control — credentials, throttling). The stack read succeeded; absence at
20
+ * stack scope is an honest verdict this fallback can refine but must never
21
+ * degrade into a hole, or a pre-first-apply plan would stop proposing
22
+ * `create` the moment the emulator lacks Cloud Control.
23
+ */
24
+ import { createRequire } from "module";
25
+ import { moduleSourceUrl } from "@intentius/chant/module-source";
26
+ import { AwsReadError, getResource, listResources } from "./api/read-client.js";
27
+ const require = createRequire(moduleSourceUrl(import.meta.url));
28
+ let byResourceType;
29
+ function manifestByType() {
30
+ if (!byResourceType) {
31
+ const manifest = require("./generated/lexicon-aws.json");
32
+ byResourceType = new Map(Object.values(manifest).map((e) => [e.resourceType, e]));
33
+ }
34
+ return byResourceType;
35
+ }
36
+ /**
37
+ * The Cloud Control identifier the declared props spell, or undefined when the
38
+ * type has no primary identifier on record or any part of it is absent or
39
+ * non-scalar (a Ref, an intrinsic, a server-assigned name). Multi-part
40
+ * identifiers join with `|`, Cloud Control's own separator.
41
+ */
42
+ export function declaredIdentifier(entityType, props) {
43
+ const entry = manifestByType().get(entityType);
44
+ const parts = entry?.primaryIdentifier;
45
+ if (!entry || entry.kind !== "resource" || !parts || parts.length === 0)
46
+ return undefined;
47
+ const values = [];
48
+ for (const part of parts) {
49
+ const v = props[part];
50
+ if (typeof v !== "string" && typeof v !== "number")
51
+ return undefined;
52
+ const s = String(v);
53
+ if (!s)
54
+ return undefined;
55
+ values.push(s);
56
+ }
57
+ return values.join("|");
58
+ }
59
+ /**
60
+ * `GetResource`, with a `ListResources` + identifier-match fallback when the
61
+ * endpoint says the operation itself is unsupported. That is Floci's exact
62
+ * answer (read-client's own note) while it serves `ListResources` fine — and
63
+ * an emulator is exactly where the carve state lives, so without this leg the
64
+ * fallback proves itself everywhere except the one place the walkthrough
65
+ * films it. Every other refusal propagates: the caller decides what a failed
66
+ * refinement means.
67
+ */
68
+ async function readByIdentity(typeName, identifier, client) {
69
+ try {
70
+ return await getResource(typeName, identifier, client);
71
+ }
72
+ catch (err) {
73
+ if (!(err instanceof AwsReadError) || err.code !== "UnsupportedOperation")
74
+ throw err;
75
+ const listed = await listResources(typeName, client);
76
+ return listed.find((d) => d.identifier === identifier) ?? null;
77
+ }
78
+ }
79
+ /** The same scrub the stack-output path applies, on live property KEYS. */
80
+ function redactSensitive(properties) {
81
+ const out = {};
82
+ for (const [key, value] of Object.entries(properties)) {
83
+ out[key] = /password|secret|token/i.test(key) ? "[REDACTED]" : value;
84
+ }
85
+ return Object.keys(out).length > 0 ? out : undefined;
86
+ }
87
+ /**
88
+ * Identity-read every entity the stack did not answer for and whose props
89
+ * spell an identifier. `already` is the stack's answer — an entity the stack
90
+ * DID return is never re-read. The `queried` map records the address each
91
+ * attempted read was issued against (#1620), whatever the verdict.
92
+ */
93
+ export async function observeByIdentity(entityNames, entities, already, client) {
94
+ const resources = {};
95
+ const queried = {};
96
+ if (!entities)
97
+ return { resources, queried };
98
+ for (const name of entityNames) {
99
+ if (already[name])
100
+ continue;
101
+ const entity = entities.get(name);
102
+ if (!entity)
103
+ continue;
104
+ const identifier = declaredIdentifier(entity.entityType, entity.props ?? {});
105
+ if (!identifier)
106
+ continue;
107
+ queried[name] = `cloudcontrol:GetResource:${entity.entityType}:${identifier}`;
108
+ try {
109
+ const found = await readByIdentity(entity.entityType, identifier, client);
110
+ if (!found)
111
+ continue;
112
+ resources[name] = {
113
+ type: entity.entityType,
114
+ physicalId: found.identifier || identifier,
115
+ status: "EXTERNAL",
116
+ ownership: "foreign",
117
+ ...(redactSensitive(found.properties) ? { attributes: redactSensitive(found.properties) } : {}),
118
+ };
119
+ }
120
+ catch {
121
+ // Refusals of every kind keep the stack's verdict — see the module
122
+ // comment for why a failed refinement must not become a hole.
123
+ continue;
124
+ }
125
+ }
126
+ return { resources, queried };
127
+ }