@intentius/chant-lexicon-aws 0.124.30 → 0.124.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 (644) 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/identity-observe.d.ts.map +1 -1
  113. package/dist/identity-observe.js +127 -0
  114. package/dist/import/generator.js +757 -0
  115. package/dist/import/live-export.js +34 -0
  116. package/dist/import/parser.js +394 -0
  117. package/dist/index.js +69 -0
  118. package/dist/integrity.json +6 -6
  119. package/dist/intrinsics.js +393 -0
  120. package/dist/lint/audit-catalog.js +87 -0
  121. package/dist/lint/audit-lineage.js +150 -0
  122. package/dist/lint/post-synth/cf-refs.js +247 -0
  123. package/dist/lint/post-synth/cor020.js +60 -0
  124. package/dist/lint/post-synth/ext001.d.ts.map +1 -1
  125. package/dist/lint/post-synth/ext001.js +197 -0
  126. package/dist/lint/post-synth/index.js +124 -0
  127. package/dist/lint/post-synth/waw010.js +41 -0
  128. package/dist/lint/post-synth/waw011.js +41 -0
  129. package/dist/lint/post-synth/waw013.js +38 -0
  130. package/dist/lint/post-synth/waw014.js +42 -0
  131. package/dist/lint/post-synth/waw015.js +88 -0
  132. package/dist/lint/post-synth/waw016.d.ts.map +1 -1
  133. package/dist/lint/post-synth/waw016.js +116 -0
  134. package/dist/lint/post-synth/waw017.js +43 -0
  135. package/dist/lint/post-synth/waw018.js +61 -0
  136. package/dist/lint/post-synth/waw019.js +64 -0
  137. package/dist/lint/post-synth/waw020.js +56 -0
  138. package/dist/lint/post-synth/waw021.js +44 -0
  139. package/dist/lint/post-synth/waw022.js +36 -0
  140. package/dist/lint/post-synth/waw023.js +40 -0
  141. package/dist/lint/post-synth/waw024.js +46 -0
  142. package/dist/lint/post-synth/waw025.js +36 -0
  143. package/dist/lint/post-synth/waw026.js +38 -0
  144. package/dist/lint/post-synth/waw027.js +41 -0
  145. package/dist/lint/post-synth/waw028.js +39 -0
  146. package/dist/lint/post-synth/waw029.js +54 -0
  147. package/dist/lint/post-synth/waw030.js +282 -0
  148. package/dist/lint/post-synth/waw031.js +58 -0
  149. package/dist/lint/post-synth/waw032.js +45 -0
  150. package/dist/lint/post-synth/waw033.js +75 -0
  151. package/dist/lint/post-synth/waw034.js +52 -0
  152. package/dist/lint/post-synth/waw035.js +56 -0
  153. package/dist/lint/post-synth/waw036.js +79 -0
  154. package/dist/lint/post-synth/waw037.js +67 -0
  155. package/dist/lint/post-synth/waw038.js +42 -0
  156. package/dist/lint/post-synth/waw039.js +42 -0
  157. package/dist/lint/post-synth/waw040.js +45 -0
  158. package/dist/lint/post-synth/waw041.js +40 -0
  159. package/dist/lint/post-synth/waw042.js +99 -0
  160. package/dist/lint/post-synth/waw043.js +51 -0
  161. package/dist/lint/post-synth/waw044.js +64 -0
  162. package/dist/lint/post-synth/waw045.js +49 -0
  163. package/dist/lint/post-synth/waw046.js +52 -0
  164. package/dist/lint/post-synth/waw047.js +43 -0
  165. package/dist/lint/post-synth/waw048.js +40 -0
  166. package/dist/lint/post-synth/waw049.js +78 -0
  167. package/dist/lint/post-synth/waw050.js +44 -0
  168. package/dist/lint/post-synth/waw051.js +41 -0
  169. package/dist/lint/post-synth/waw052.js +43 -0
  170. package/dist/lint/post-synth/waw053.js +43 -0
  171. package/dist/lint/post-synth/waw054.js +41 -0
  172. package/dist/lint/post-synth/waw055.js +41 -0
  173. package/dist/lint/post-synth/waw056.js +65 -0
  174. package/dist/lint/post-synth/waw057.js +43 -0
  175. package/dist/lint/post-synth/waw058.js +61 -0
  176. package/dist/lint/post-synth/waw059.js +338 -0
  177. package/dist/lint/post-synth/waw060.js +83 -0
  178. package/dist/lint/post-synth/waw061.js +60 -0
  179. package/dist/lint/post-synth/waw062.js +0 -0
  180. package/dist/lint/post-synth/waw063.js +0 -0
  181. package/dist/lint/post-synth/waw064.js +45 -0
  182. package/dist/lint/post-synth/waw065.js +104 -0
  183. package/dist/lint/post-synth/waw066.js +145 -0
  184. package/dist/lint/post-synth/waw067.js +115 -0
  185. package/dist/lint/post-synth/waw068.js +69 -0
  186. package/dist/lint/post-synth/waw069.js +0 -0
  187. package/dist/lint/rules/hardcoded-region.js +38 -0
  188. package/dist/lint/rules/iam-wildcard.js +60 -0
  189. package/dist/lint/rules/index.js +6 -0
  190. package/dist/lint/rules/s3-encryption.js +60 -0
  191. package/dist/live-attrs.js +42 -0
  192. package/dist/lsp/completions.d.ts.map +1 -1
  193. package/dist/lsp/completions.js +18 -0
  194. package/dist/lsp/hover.d.ts.map +1 -1
  195. package/dist/lsp/hover.js +66 -0
  196. package/dist/manifest.json +1 -1
  197. package/dist/mapping.js +33 -0
  198. package/dist/meta.json +17359 -784
  199. package/dist/nested-stack.js +95 -0
  200. package/dist/okf/index.md +203 -0
  201. package/dist/okf/rules/EXT001.md +1 -0
  202. package/dist/okf/rules/WAW016.md +2 -0
  203. package/dist/okf/rules/WAW019.md +1 -0
  204. package/dist/okf/rules/WAW028.md +1 -0
  205. package/dist/okf/rules/WAW030.md +2 -0
  206. package/dist/okf/rules/WAW039.md +1 -0
  207. package/dist/okf/rules/WAW049.md +1 -0
  208. package/dist/okf/rules/WAW056.md +1 -0
  209. package/dist/okf/rules/WAW058.md +1 -0
  210. package/dist/okf/rules/WAW062.md +1 -0
  211. package/dist/okf/rules/WAW064.md +1 -0
  212. package/dist/okf/rules/WAW065.md +1 -0
  213. package/dist/okf/rules/WAW066.md +1 -0
  214. package/dist/okf/rules/WAW067.md +1 -0
  215. package/dist/okf/rules/WAW068.md +1 -0
  216. package/dist/okf/rules/WAW069.md +4 -0
  217. package/dist/okf/types/AIWorkloadConfig.md +23 -0
  218. package/dist/okf/types/ARCRegionSwitchPlan.md +1 -0
  219. package/dist/okf/types/AccountAccessApplication.md +28 -0
  220. package/dist/okf/types/AccountAccessEntitlement.md +22 -0
  221. package/dist/okf/types/ActionTarget.md +20 -0
  222. package/dist/okf/types/AdConfiguration.md +21 -0
  223. package/dist/okf/types/Adapter.md +26 -0
  224. package/dist/okf/types/AgentContext.md +35 -0
  225. package/dist/okf/types/AgentGoal.md +31 -0
  226. package/dist/okf/types/AgentProfile.md +34 -0
  227. package/dist/okf/types/Alarm.md +3 -1
  228. package/dist/okf/types/AlarmModel.md +14 -9
  229. package/dist/okf/types/AmplifyWebhook.md +25 -0
  230. package/dist/okf/types/ApiCache.md +8 -8
  231. package/dist/okf/types/ApiGatewayManagedOverrides.md +5 -5
  232. package/dist/okf/types/AppAuthorization.md +35 -0
  233. package/dist/okf/types/AppBlockBuilder.md +1 -0
  234. package/dist/okf/types/AppInstance.md +2 -2
  235. package/dist/okf/types/AppInstanceBot.md +2 -2
  236. package/dist/okf/types/AppStreamFleet.md +3 -2
  237. package/dist/okf/types/AppSyncApiKey.md +6 -6
  238. package/dist/okf/types/AppSyncType.md +22 -0
  239. package/dist/okf/types/ApplicationStatusCheck.md +36 -0
  240. package/dist/okf/types/ApplicationVersion.md +4 -1
  241. package/dist/okf/types/ApplicationsList.md +26 -0
  242. package/dist/okf/types/ApprovalPolicy.md +28 -0
  243. package/dist/okf/types/ArchiveRule.md +24 -0
  244. package/dist/okf/types/Asset.md +30 -0
  245. package/dist/okf/types/Backup.md +31 -0
  246. package/dist/okf/types/BedrockAgentCoreDataset.md +1 -1
  247. package/dist/okf/types/BedrockAgentCoreGateway.md +3 -0
  248. package/dist/okf/types/BedrockSession.md +28 -0
  249. package/dist/okf/types/BillEstimate.md +35 -0
  250. package/dist/okf/types/Brand.md +32 -0
  251. package/dist/okf/types/CallAnalyticsCategory.md +25 -0
  252. package/dist/okf/types/Campaign.md +28 -0
  253. package/dist/okf/types/CapacityProvider.md +30 -0
  254. package/dist/okf/types/Case.md +24 -0
  255. package/dist/okf/types/CertificateAssociation.md +13 -0
  256. package/dist/okf/types/ChangeSet.md +36 -0
  257. package/dist/okf/types/ChannelFlow.md +29 -0
  258. package/dist/okf/types/ChimeChannel.md +39 -0
  259. package/dist/okf/types/Classifier.md +6 -6
  260. package/dist/okf/types/ClientVpnAuthorizationRule.md +6 -6
  261. package/dist/okf/types/ClientVpnEndpoint.md +2 -0
  262. package/dist/okf/types/ClientVpnRoute.md +5 -5
  263. package/dist/okf/types/CloudConnector.md +29 -0
  264. package/dist/okf/types/Cluster.md +39 -0
  265. package/dist/okf/types/ClusterSchedulerConfig.md +30 -0
  266. package/dist/okf/types/CodeCommitRepository.md +12 -12
  267. package/dist/okf/types/CodeConnectionsHost.md +26 -0
  268. package/dist/okf/types/CodeRepository.md +5 -5
  269. package/dist/okf/types/CompositeAlarm.md +1 -0
  270. package/dist/okf/types/ComputeEnvironment.md +2 -0
  271. package/dist/okf/types/ComputeNodeGroup.md +1 -1
  272. package/dist/okf/types/ComputeQuota.md +34 -0
  273. package/dist/okf/types/ConfigRule.md +1 -1
  274. package/dist/okf/types/ConfigurationRecorder.md +7 -6
  275. package/dist/okf/types/ConnectAttachment.md +2 -0
  276. package/dist/okf/types/ConnectQueue.md +5 -1
  277. package/dist/okf/types/ConnectVocabulary.md +28 -0
  278. package/dist/okf/types/ConnectionType.md +24 -0
  279. package/dist/okf/types/ConsentPortal.md +33 -0
  280. package/dist/okf/types/ContactMethod.md +29 -0
  281. package/dist/okf/types/ContainerAssociation.md +26 -0
  282. package/dist/okf/types/ContainerFleet.md +1 -1
  283. package/dist/okf/types/ContainerGroupDefinition.md +1 -1
  284. package/dist/okf/types/Content.md +40 -0
  285. package/dist/okf/types/ContentAssociation.md +28 -0
  286. package/dist/okf/types/CustomDetectionRuleAssociation.md +28 -0
  287. package/dist/okf/types/CustomEntityType.md +4 -9
  288. package/dist/okf/types/Customization.md +22 -0
  289. package/dist/okf/types/CwIntegration.md +31 -0
  290. package/dist/okf/types/DAXParameterGroup.md +3 -8
  291. package/dist/okf/types/DAXSubnetGroup.md +0 -5
  292. package/dist/okf/types/DBClusterEndpoint.md +31 -0
  293. package/dist/okf/types/DBProxyTargetGroup.md +1 -0
  294. package/dist/okf/types/DBSnapshot.md +62 -0
  295. package/dist/okf/types/DLMLifecyclePolicy.md +12 -12
  296. package/dist/okf/types/DLPSetting.md +31 -0
  297. package/dist/okf/types/DMSInstanceProfile.md +1 -1
  298. package/dist/okf/types/DRSLaunchConfigurationTemplate.md +28 -0
  299. package/dist/okf/types/Daemon.md +1 -0
  300. package/dist/okf/types/DataExchangeDataSet.md +29 -0
  301. package/dist/okf/types/DataIntegrationFlow.md +27 -0
  302. package/dist/okf/types/DataMigration.md +1 -1
  303. package/dist/okf/types/DataProvider.md +2 -1
  304. package/dist/okf/types/DataQualityRuleset.md +6 -11
  305. package/dist/okf/types/DataSource.md +23 -0
  306. package/dist/okf/types/Dataset.md +20 -0
  307. package/dist/okf/types/DatasetIntegration.md +23 -0
  308. package/dist/okf/types/DbCluster.md +1 -1
  309. package/dist/okf/types/DbInstance.md +8 -2
  310. package/dist/okf/types/DeadlineBudget.md +29 -0
  311. package/dist/okf/types/DelegationSet.md +23 -0
  312. package/dist/okf/types/DeliveryChannel.md +6 -11
  313. package/dist/okf/types/DevOpsAgentAgentSpace.md +4 -0
  314. package/dist/okf/types/DevOpsAgentService.md +1 -0
  315. package/dist/okf/types/DevOpsAgentTrigger.md +28 -0
  316. package/dist/okf/types/DirectConnectGatewayAttachment.md +2 -0
  317. package/dist/okf/types/Directory.md +60 -0
  318. package/dist/okf/types/DocDBDBClusterParameterGroup.md +5 -10
  319. package/dist/okf/types/DocDBDBSubnetGroup.md +4 -9
  320. package/dist/okf/types/DocDBElasticClusterSnapshot.md +36 -0
  321. package/dist/okf/types/DocumentClassifierEndpoint.md +27 -0
  322. package/dist/okf/types/Domain.md +27 -0
  323. package/dist/okf/types/EKSCertificateAuthority.md +42 -0
  324. package/dist/okf/types/EKSCluster.md +8 -0
  325. package/dist/okf/types/EcSnapshot.md +66 -0
  326. package/dist/okf/types/EmailIdentityCertificate.md +15 -0
  327. package/dist/okf/types/EndpointConfig.md +14 -13
  328. package/dist/okf/types/EntityRecognizer.md +27 -0
  329. package/dist/okf/types/EntityRecognizerEndpoint.md +31 -0
  330. package/dist/okf/types/EnvironmentEC2.md +13 -13
  331. package/dist/okf/types/EvaluationForm.md +1 -0
  332. package/dist/okf/types/Evaluator.md +6 -2
  333. package/dist/okf/types/EventAction.md +26 -0
  334. package/dist/okf/types/EventRule.md +2 -0
  335. package/dist/okf/types/EventSource.md +30 -0
  336. package/dist/okf/types/EventTracker.md +22 -0
  337. package/dist/okf/types/EventsV2EventBus.md +28 -0
  338. package/dist/okf/types/EventsV2ResourcePolicy.md +19 -0
  339. package/dist/okf/types/EventsV2Subscriber.md +39 -0
  340. package/dist/okf/types/ExperimentDefinition.md +39 -0
  341. package/dist/okf/types/ExperimentRun.md +33 -0
  342. package/dist/okf/types/ExperimentTrialComponent.md +13 -11
  343. package/dist/okf/types/FHIRDatastore.md +3 -0
  344. package/dist/okf/types/FSxSnapshot.md +5 -5
  345. package/dist/okf/types/FSxVolume.md +9 -9
  346. package/dist/okf/types/FeaturedResultsSet.md +26 -0
  347. package/dist/okf/types/Feed.md +1 -0
  348. package/dist/okf/types/FieldLevelEncryptionConfig.md +25 -0
  349. package/dist/okf/types/FieldLevelEncryptionProfile.md +22 -0
  350. package/dist/okf/types/FileCache.md +45 -0
  351. package/dist/okf/types/Filter.md +27 -0
  352. package/dist/okf/types/Firewall.md +6 -0
  353. package/dist/okf/types/FlowMediaStream.md +28 -0
  354. package/dist/okf/types/FlowOutput.md +1 -0
  355. package/dist/okf/types/FpgaImage.md +38 -0
  356. package/dist/okf/types/Function.md +2 -2
  357. package/dist/okf/types/Gateway.md +41 -0
  358. package/dist/okf/types/GatewayClusterAssociations.md +23 -0
  359. package/dist/okf/types/GatewayRateLimit.md +26 -0
  360. package/dist/okf/types/GatewayRule.md +32 -0
  361. package/dist/okf/types/GlobalReplicationGroup.md +3 -0
  362. package/dist/okf/types/GlobalResolver.md +1 -1
  363. package/dist/okf/types/GlobalTable.md +1 -0
  364. package/dist/okf/types/GlueConnection.md +5 -4
  365. package/dist/okf/types/GlueSecurityConfiguration.md +1 -6
  366. package/dist/okf/types/GlueSession.md +38 -0
  367. package/dist/okf/types/GlueTable.md +5 -10
  368. package/dist/okf/types/GlueWorkflow.md +5 -10
  369. package/dist/okf/types/Group.md +27 -0
  370. package/dist/okf/types/Harness.md +1 -0
  371. package/dist/okf/types/HostKey.md +33 -0
  372. package/dist/okf/types/HostedZone.md +1 -0
  373. package/dist/okf/types/HttpApi.md +2 -0
  374. package/dist/okf/types/HttpNamespace.md +5 -5
  375. package/dist/okf/types/HubV2.md +1 -0
  376. package/dist/okf/types/HumanTaskUi.md +22 -0
  377. package/dist/okf/types/IPv4Pool.md +28 -0
  378. package/dist/okf/types/ImageBuilder.md +1 -0
  379. package/dist/okf/types/ImageBuilderImage.md +1 -1
  380. package/dist/okf/types/ImagePipeline.md +1 -1
  381. package/dist/okf/types/InferenceComponent.md +5 -1
  382. package/dist/okf/types/InfluxDBBackup.md +65 -0
  383. package/dist/okf/types/InfluxDBCluster.md +3 -0
  384. package/dist/okf/types/InfrastructureConfiguration.md +2 -0
  385. package/dist/okf/types/IngestionDestination.md +28 -0
  386. package/dist/okf/types/InputSecurityGroup.md +6 -4
  387. package/dist/okf/types/InspectorV2Connector.md +38 -0
  388. package/dist/okf/types/InstanceEventWindow.md +25 -0
  389. package/dist/okf/types/InstanceFleetConfig.md +10 -10
  390. package/dist/okf/types/InstanceGroupConfig.md +3 -3
  391. package/dist/okf/types/InstrumentationConfig.md +31 -0
  392. package/dist/okf/types/IntegrationAssociation.md +3 -0
  393. package/dist/okf/types/IoTSiteWiseApplication.md +34 -0
  394. package/dist/okf/types/IoTSiteWiseDataset.md +5 -2
  395. package/dist/okf/types/IoTSiteWiseTask.md +24 -0
  396. package/dist/okf/types/IpamExternalResourceVerificationToken.md +35 -0
  397. package/dist/okf/types/IpamInternetRegistryAssociation.md +32 -0
  398. package/dist/okf/types/Job.md +35 -0
  399. package/dist/okf/types/JobTemplate.md +26 -0
  400. package/dist/okf/types/KinesisChannel.md +31 -0
  401. package/dist/okf/types/KinesisStream.md +1 -0
  402. package/dist/okf/types/LambdaResourcePolicy.md +14 -0
  403. package/dist/okf/types/Lexicon.md +34 -0
  404. package/dist/okf/types/LicenseAssetGroup.md +23 -0
  405. package/dist/okf/types/LicenseConfiguration.md +33 -0
  406. package/dist/okf/types/LicenseServerEndpoint.md +32 -0
  407. package/dist/okf/types/LightsailKeyPair.md +29 -0
  408. package/dist/okf/types/LimitsProfile.md +27 -0
  409. package/dist/okf/types/LocationAzureBlob.md +2 -1
  410. package/dist/okf/types/LocationObjectStorage.md +1 -0
  411. package/dist/okf/types/LogAlarm.md +2 -0
  412. package/dist/okf/types/MGNConnector.md +23 -0
  413. package/dist/okf/types/MGNLaunchConfigurationTemplate.md +37 -0
  414. package/dist/okf/types/MLTransform.md +15 -15
  415. package/dist/okf/types/MWAAServerlessWorkflow.md +3 -0
  416. package/dist/okf/types/ManagedNotificationAccountContactAssociation.md +1 -0
  417. package/dist/okf/types/ManagedNotificationAdditionalChannelAssociation.md +1 -0
  418. package/dist/okf/types/MediaConvertJobTemplate.md +11 -13
  419. package/dist/okf/types/MediaConvertQueue.md +8 -10
  420. package/dist/okf/types/MediaInsightsPipelineConfiguration.md +28 -0
  421. package/dist/okf/types/MediaLiveInput.md +41 -18
  422. package/dist/okf/types/MediaPackageV2Channel.md +3 -0
  423. package/dist/okf/types/MediaPackageV2OriginEndpoint.md +1 -0
  424. package/dist/okf/types/MediaPipelineKinesisVideoStreamPool.md +28 -0
  425. package/dist/okf/types/MediaTailorFunction.md +27 -0
  426. package/dist/okf/types/MedicalVocabulary.md +21 -0
  427. package/dist/okf/types/Member.md +26 -0
  428. package/dist/okf/types/Memory.md +6 -0
  429. package/dist/okf/types/MemoryDBSnapshot.md +29 -0
  430. package/dist/okf/types/Metric.md +59 -0
  431. package/dist/okf/types/MetricAttribution.md +23 -0
  432. package/dist/okf/types/MicrosoftAD.md +11 -11
  433. package/dist/okf/types/MigrationProject.md +8 -1
  434. package/dist/okf/types/Monitor.md +26 -0
  435. package/dist/okf/types/NFSFileShare.md +44 -0
  436. package/dist/okf/types/NeptuneGraphGraph.md +1 -0
  437. package/dist/okf/types/NetworkConnector.md +4 -0
  438. package/dist/okf/types/NetworkFlowMonitorScope.md +23 -0
  439. package/dist/okf/types/NetworkMigrationDefinition.md +31 -0
  440. package/dist/okf/types/NetworkSecurityManagerDeployment.md +31 -0
  441. package/dist/okf/types/NetworkSecurityManagerPolicy.md +32 -0
  442. package/dist/okf/types/NetworkSecurityManagerScope.md +29 -0
  443. package/dist/okf/types/NotebookInstance.md +18 -18
  444. package/dist/okf/types/NotebookInstanceLifecycleConfig.md +6 -5
  445. package/dist/okf/types/NotifyConfiguration.md +35 -0
  446. package/dist/okf/types/OTelEnrichment.md +2 -0
  447. package/dist/okf/types/OnlineEvaluationConfig.md +0 -1
  448. package/dist/okf/types/OrganizationConfigRule.md +7 -7
  449. package/dist/okf/types/Outpost.md +32 -0
  450. package/dist/okf/types/ParallelData.md +40 -0
  451. package/dist/okf/types/Partition.md +5 -5
  452. package/dist/okf/types/PaymentConnector.md +4 -1
  453. package/dist/okf/types/Pentest.md +1 -0
  454. package/dist/okf/types/PerfReports.md +28 -0
  455. package/dist/okf/types/PermissionAssociation.md +30 -0
  456. package/dist/okf/types/PersonalizeDataset.md +1 -0
  457. package/dist/okf/types/PersonalizeDatasetGroup.md +1 -0
  458. package/dist/okf/types/PersonalizeSchema.md +1 -0
  459. package/dist/okf/types/Pipeline.md +25 -0
  460. package/dist/okf/types/PlaybackConfiguration.md +1 -0
  461. package/dist/okf/types/PolicyAssociation.md +1 -1
  462. package/dist/okf/types/PolicyGrant.md +2 -2
  463. package/dist/okf/types/PolicyPrincipalAttachment.md +2 -7
  464. package/dist/okf/types/PortalProduct.md +24 -0
  465. package/dist/okf/types/PrefetchSchedule.md +25 -0
  466. package/dist/okf/types/PricingPlanManagerSubscription.md +31 -0
  467. package/dist/okf/types/PrincipalAssociation.md +27 -0
  468. package/dist/okf/types/PrivateDnsNamespace.md +8 -8
  469. package/dist/okf/types/PrivateVirtualInterface.md +1 -0
  470. package/dist/okf/types/ProcurementPortalPreference.md +45 -0
  471. package/dist/okf/types/Program.md +33 -0
  472. package/dist/okf/types/ProjectMembership.md +1 -1
  473. package/dist/okf/types/ProtocolsList.md +26 -0
  474. package/dist/okf/types/PublicDnsNamespace.md +7 -7
  475. package/dist/okf/types/PublicVirtualInterface.md +1 -0
  476. package/dist/okf/types/QEV2IdcApplication.md +25 -0
  477. package/dist/okf/types/QueryLoggingConfig.md +21 -0
  478. package/dist/okf/types/QuerySuggestionsBlockList.md +25 -0
  479. package/dist/okf/types/QuickSightAssignment.md +24 -0
  480. package/dist/okf/types/RAMResourceAssociation.md +27 -0
  481. package/dist/okf/types/RDSClusterSnapshot.md +54 -0
  482. package/dist/okf/types/RDSDBParameterGroup.md +5 -0
  483. package/dist/okf/types/RDSDeployment.md +41 -0
  484. package/dist/okf/types/RcsAgent.md +38 -0
  485. package/dist/okf/types/ReceiptRule.md +5 -5
  486. package/dist/okf/types/ReceiptRuleSet.md +1 -6
  487. package/dist/okf/types/RecommenderFilter.md +27 -0
  488. package/dist/okf/types/RecommenderSchema.md +25 -0
  489. package/dist/okf/types/RecordSet.md +16 -22
  490. package/dist/okf/types/RecoveryPlan.md +28 -0
  491. package/dist/okf/types/RedshiftIdcApplication.md +31 -0
  492. package/dist/okf/types/RedshiftSnapshot.md +59 -0
  493. package/dist/okf/types/RegistrationAttachment.md +28 -0
  494. package/dist/okf/types/Registry.md +41 -0
  495. package/dist/okf/types/RegistryRecord.md +38 -0
  496. package/dist/okf/types/RelatedItem.md +24 -0
  497. package/dist/okf/types/ReplicationConfigurationTemplate.md +35 -0
  498. package/dist/okf/types/ReplicationSubnetGroup.md +4 -9
  499. package/dist/okf/types/ReplicationTask.md +14 -14
  500. package/dist/okf/types/ReportGenerator.md +29 -0
  501. package/dist/okf/types/ReportGroup.md +1 -3
  502. package/dist/okf/types/ResilienceHubV2Policy.md +1 -0
  503. package/dist/okf/types/ResilienceHubV2Service.md +1 -0
  504. package/dist/okf/types/ResourceConfiguration.md +1 -1
  505. package/dist/okf/types/ResourceMetricsConfiguration.md +21 -0
  506. package/dist/okf/types/RestApi.md +1 -0
  507. package/dist/okf/types/RetrievalInstruction.md +32 -0
  508. package/dist/okf/types/RouterOutput.md +1 -0
  509. package/dist/okf/types/Rule.md +31 -0
  510. package/dist/okf/types/RunCache.md +29 -0
  511. package/dist/okf/types/Runtime.md +2 -1
  512. package/dist/okf/types/SCNInstance.md +33 -0
  513. package/dist/okf/types/SDBDomain.md +2 -2
  514. package/dist/okf/types/SMBFileShare.md +49 -0
  515. package/dist/okf/types/SageMakerArtifact.md +27 -0
  516. package/dist/okf/types/SageMakerEndpoint.md +0 -1
  517. package/dist/okf/types/ScalableTarget.md +1 -0
  518. package/dist/okf/types/ScalingPlan.md +6 -6
  519. package/dist/okf/types/ScheduledReport.md +31 -0
  520. package/dist/okf/types/SecondaryNetwork.md +26 -0
  521. package/dist/okf/types/SecurityAgentArtifact.md +25 -0
  522. package/dist/okf/types/SecurityAgentIntegration.md +31 -0
  523. package/dist/okf/types/Server.md +1 -0
  524. package/dist/okf/types/ServerlessCache.md +2 -0
  525. package/dist/okf/types/ServerlessCacheSnapshot.md +31 -0
  526. package/dist/okf/types/ServerlessRepoApplication.md +32 -0
  527. package/dist/okf/types/ServiceDiscoveryInstance.md +3 -7
  528. package/dist/okf/types/SipMediaApplication.md +27 -0
  529. package/dist/okf/types/SiteToSiteVpnAttachment.md +2 -0
  530. package/dist/okf/types/SnapshotCopyGrant.md +20 -0
  531. package/dist/okf/types/Solution.md +1 -0
  532. package/dist/okf/types/SourceAssociation.md +25 -0
  533. package/dist/okf/types/SourceCredential.md +6 -6
  534. package/dist/okf/types/SourceNetwork.md +23 -0
  535. package/dist/okf/types/StackFleetAssociation.md +2 -7
  536. package/dist/okf/types/StorageTierPolicy.md +20 -0
  537. package/dist/okf/types/StorageVirtualMachine.md +9 -9
  538. package/dist/okf/types/Stream.md +28 -0
  539. package/dist/okf/types/SubnetCidrReservation.md +26 -0
  540. package/dist/okf/types/SubscriptionProvider.md +26 -0
  541. package/dist/okf/types/SupportPermit.md +29 -0
  542. package/dist/okf/types/Table.md +2 -1
  543. package/dist/okf/types/TableOptimizer.md +5 -10
  544. package/dist/okf/types/Tape.md +31 -0
  545. package/dist/okf/types/Template.md +36 -0
  546. package/dist/okf/types/Tenant.md +2 -0
  547. package/dist/okf/types/Terminology.md +39 -0
  548. package/dist/okf/types/Thesaurus.md +25 -0
  549. package/dist/okf/types/ThingPrincipalAttachment.md +3 -8
  550. package/dist/okf/types/Topic.md +1 -0
  551. package/dist/okf/types/TopicRuleDestination.md +1 -0
  552. package/dist/okf/types/TrafficPolicy.md +26 -0
  553. package/dist/okf/types/TrafficPolicyInstance.md +28 -0
  554. package/dist/okf/types/TranscribeVocabulary.md +27 -0
  555. package/dist/okf/types/TransitGatewayRouteTableAttachment.md +2 -0
  556. package/dist/okf/types/TransitVirtualInterface.md +1 -0
  557. package/dist/okf/types/Tunnel.md +25 -0
  558. package/dist/okf/types/UsageLimit.md +26 -0
  559. package/dist/okf/types/UseCase.md +23 -0
  560. package/dist/okf/types/User.md +47 -0
  561. package/dist/okf/types/VPCEndpoint.md +1 -1
  562. package/dist/okf/types/VPCEndpointService.md +6 -0
  563. package/dist/okf/types/VPCPeeringConnection.md +2 -2
  564. package/dist/okf/types/VPNConcentrator.md +1 -1
  565. package/dist/okf/types/VPNConnection.md +1 -1
  566. package/dist/okf/types/VerifiedDestinationNumber.md +25 -0
  567. package/dist/okf/types/View.md +27 -0
  568. package/dist/okf/types/VoiceConnector.md +30 -0
  569. package/dist/okf/types/Volume.md +44 -0
  570. package/dist/okf/types/Vpc.md +1 -1
  571. package/dist/okf/types/VpcAttachment.md +2 -0
  572. package/dist/okf/types/WebFunction.md +27 -0
  573. package/dist/okf/types/WebFunctionEndpoint.md +44 -0
  574. package/dist/okf/types/WebFunctionRevision.md +32 -0
  575. package/dist/okf/types/WickrNetwork.md +27 -0
  576. package/dist/okf/types/Worker.md +29 -0
  577. package/dist/okf/types/Workforce.md +26 -0
  578. package/dist/okf/types/Workload.md +35 -0
  579. package/dist/okf/types/WorkloadEstimate.md +35 -0
  580. package/dist/okf/types/Workspace.md +28 -0
  581. package/dist/okf/types/Workteam.md +8 -8
  582. package/dist/op/activities/aws-apply.js +214 -0
  583. package/dist/op/activities/floci.js +97 -0
  584. package/dist/op/activities/index.js +32 -0
  585. package/dist/op/builders.js +50 -0
  586. package/dist/ownership.js +52 -0
  587. package/dist/package-cli.js +25 -0
  588. package/dist/parameter.js +19 -0
  589. package/dist/plugin.d.ts.map +1 -1
  590. package/dist/plugin.js +1006 -0
  591. package/dist/properties.js +166 -0
  592. package/dist/pseudo.js +25 -0
  593. package/dist/receipt-store.d.ts.map +1 -1
  594. package/dist/receipt-store.js +233 -0
  595. package/dist/reference-catalog.js +106 -0
  596. package/dist/rules/ext001.ts +3 -3
  597. package/dist/rules/waw016.ts +2 -2
  598. package/dist/serializer.js +529 -0
  599. package/dist/spec/fetch.js +193 -0
  600. package/dist/spec/parse.js +259 -0
  601. package/dist/spec/pin.js +185 -0
  602. package/dist/spec/pinned-types.json +203 -0
  603. package/dist/stack-errors.js +14 -0
  604. package/dist/taggable.d.ts.map +1 -1
  605. package/dist/taggable.js +33 -0
  606. package/dist/teardown.js +199 -0
  607. package/dist/template-sections.js +53 -0
  608. package/dist/template-transform.js +50 -0
  609. package/dist/types/index.d.ts +18847 -1124
  610. package/dist/validate-cli.js +16 -0
  611. package/dist/validate.js +33 -0
  612. package/package.json +9 -9
  613. package/src/agentcore/trace-fetch.ts +2 -1
  614. package/src/api/credential-chain.ts +119 -9
  615. package/src/api/credential-isolation.test.ts +72 -0
  616. package/src/api/read-client-chain.test.ts +159 -0
  617. package/src/api/read-client.ts +42 -6
  618. package/src/api/sigv4.ts +4 -4
  619. package/src/caller-identity.ts +3 -5
  620. package/src/codegen/any-budget.test.ts +12 -2
  621. package/src/codegen/generate.ts +9 -0
  622. package/src/codegen/package.ts +2 -2
  623. package/src/codegen/patches.test.ts +95 -0
  624. package/src/codegen/patches.ts +53 -9
  625. package/src/codegen/property-overlay.json +1 -16
  626. package/src/components/apply.ts +218 -6
  627. package/src/components/cfn-plan-floci.e2e.test.ts +76 -0
  628. package/src/components/cfn-plan.test.ts +225 -16
  629. package/src/components/cloud-executor.ts +73 -25
  630. package/src/deep-observe.ts +2 -1
  631. package/src/disruption.ts +2 -1
  632. package/src/generated/index.d.ts +18847 -1124
  633. package/src/generated/index.ts +1376 -161
  634. package/src/generated/lexicon-aws.json +17359 -784
  635. package/src/identity-observe.ts +2 -1
  636. package/src/lint/post-synth/ext001.ts +3 -3
  637. package/src/lint/post-synth/waw016.ts +2 -2
  638. package/src/lsp/completions.ts +2 -1
  639. package/src/lsp/hover.ts +2 -1
  640. package/src/plugin.ts +2 -1
  641. package/src/receipt-store.ts +2 -1
  642. package/src/spec/pin.ts +3 -3
  643. package/src/spec/pinned-types.json +203 -0
  644. package/src/taggable.ts +2 -2
@@ -0,0 +1,709 @@
1
+ /**
2
+ * AWS deep observation (#1015) — the reference implementation of the epic's
3
+ * deep-observe contract (#1014).
4
+ *
5
+ * `describeResources` reads `cloudformation describe-stack-resources`, which
6
+ * returns a status, a physical id and a timestamp per resource. That is
7
+ * CloudFormation's view of the world, and CloudFormation only compares
8
+ * properties it was told about. A property somebody edited in the console — an
9
+ * inline policy, a bucket setting, a security-group rule — is invisible to it.
10
+ * That gap is why go-to-k/cdk-real-drift exists, and it is what this reader
11
+ * closes: the live resource model comes from the **Cloud Control API**, which
12
+ * bypasses CloudFormation entirely and returns the resource as the service
13
+ * actually holds it.
14
+ *
15
+ * Correlation is unchanged: Cloud Control is addressed by the physical id that
16
+ * `describe-stack-resources` already reports per logical id, so the results
17
+ * line up with the same IR node ids `live-attrs.ts` relies on.
18
+ *
19
+ * ## One reader, several sources (#1269)
20
+ *
21
+ * Cloud Control is the default source, not the only one. It has the property
22
+ * this reader wants most — it returns the *CloudFormation resource model*, so
23
+ * its payload lines up with the declared side without translation — but its
24
+ * coverage is not the same as the provider's. A security group read through
25
+ * Cloud Control comes back as identity and a description; read through
26
+ * `ec2 describe-security-groups` it comes back with every ingress and egress
27
+ * rule, which is the property people actually edit out of band.
28
+ *
29
+ * So each type names its source in {@link DEEP_SOURCES}, and a source that is
30
+ * not Cloud Control supplies a `toModel` that maps the provider's shape onto
31
+ * the CloudFormation one. Translation is the price of the richer read, and it
32
+ * belongs next to the type it translates rather than inside the diff.
33
+ *
34
+ * A declared resource of a type with no source reports NOT-OBSERVED with
35
+ * `unsupported-kind` — it may well exist, and saying nothing about it is the
36
+ * only honest answer.
37
+ *
38
+ * ## Nothing here talks to real AWS on its own terms
39
+ *
40
+ * Every call goes through `./api/read-client.ts` — the applier's own transport,
41
+ * pointed at the read APIs (#1206) — so `AWS_ENDPOINT_URL` redirects the whole
42
+ * reader at a local emulator, with no CLI to spawn and typed failures instead of
43
+ * parsed stderr.
44
+ */
45
+ import { AwsReadError, describeStackResources, getResource, listResources, } from "./api/read-client.js";
46
+ import { declaredIdentifier } from "./identity-observe.js";
47
+ import { AWS_TAG_OWNERSHIP_KEYS } from "./ownership.js";
48
+ import { AWS_DEEP_BLIND_SPOTS, EC2_TOPOLOGY_GENERATED_NAMES, EC2_TOPOLOGY_SERVICE_DEFAULTS, EC2_TOPOLOGY_SOURCES, } from "./deep-topology.js";
49
+ import { applyAwsEndpointArgv } from "./components/cloud-executor.js";
50
+ import { toIngressRules } from "./dependencies.js";
51
+ import { createRequire } from "node:module";
52
+ import { moduleSourceUrl } from "@intentius/chant/module-source";
53
+ const require = createRequire(moduleSourceUrl(import.meta.url));
54
+ export const DEEP_SOURCES = {
55
+ "AWS::S3::Bucket": { via: "cloud-control" },
56
+ "AWS::IAM::Role": { via: "cloud-control" },
57
+ "AWS::IAM::ManagedPolicy": { via: "cloud-control" },
58
+ // Cloud Control returns a security group's identity and description and none
59
+ // of its rules (#1269). The EC2 API returns the whole thing, so the drift
60
+ // people care about — an ingress rule edited in the console — is legible.
61
+ "AWS::EC2::SecurityGroup": {
62
+ via: "ec2",
63
+ argv: ["ec2", "describe-security-groups"],
64
+ idFlag: "--group-ids",
65
+ key: "SecurityGroups",
66
+ id: "GroupId",
67
+ toModel: securityGroupToModel,
68
+ },
69
+ // The EC2 topology types the folds fold over (#1269), sources and
70
+ // translations alongside their type in ./deep-topology.ts.
71
+ ...EC2_TOPOLOGY_SOURCES,
72
+ };
73
+ /**
74
+ * Types this reader can read live. Derived from {@link DEEP_SOURCES} so the two
75
+ * cannot drift apart — the shape of bug #1280 is about.
76
+ */
77
+ export const DEEP_READABLE_TYPES = new Set(Object.keys(DEEP_SOURCES));
78
+ /**
79
+ * Parent type → the child types worth listing under it. Scoped like
80
+ * {@link DEEP_SOURCES}: the high-signal cases first — the issue's own
81
+ * examples — and widened per type, not by wildcard. A child type Cloud
82
+ * Control cannot list parent-scoped does not belong here.
83
+ */
84
+ export const DEEP_CHILD_SOURCES = {
85
+ "AWS::IAM::Role": [
86
+ {
87
+ childType: "AWS::IAM::RolePolicy",
88
+ model: (roleName) => ({ RoleName: roleName }),
89
+ // A RolePolicy identifier is `PolicyName|RoleName` — the schema's own
90
+ // primaryIdentifier order, which is what the manifest records and what
91
+ // `declaredIdentifier` joins by. The legacy type's physical id is the
92
+ // policy name, the first part.
93
+ declaredVia: [{ type: "AWS::IAM::Policy", part: (id) => id.split("|")[0] }],
94
+ },
95
+ ],
96
+ "AWS::SNS::Topic": [
97
+ {
98
+ childType: "AWS::SNS::Subscription",
99
+ model: (topicArn) => ({ TopicArn: topicArn }),
100
+ },
101
+ ],
102
+ };
103
+ /**
104
+ * The name an out-of-band child reports under. There is no chant entity name
105
+ * to use — nobody declared it — so the name has to carry the finding on its
106
+ * own: what kind of thing, and which one.
107
+ */
108
+ export function outOfBandChildName(childType, identifier) {
109
+ return `${childType}:${identifier}`;
110
+ }
111
+ /**
112
+ * `describe-security-groups` -> the `AWS::EC2::SecurityGroup` resource model.
113
+ *
114
+ * The two surfaces disagree about names and about nesting. EC2 says
115
+ * `Description` where the template says `GroupDescription`, and nests rule
116
+ * sources under `IpRanges[]` / `Ipv6Ranges[]` / `UserIdGroupPairs[]` where the
117
+ * template writes one flat rule per source. `toIngressRules` already resolves
118
+ * the nesting for the topology fold (#1273); this reuses it so there is one
119
+ * translation of that shape in the lexicon, not two.
120
+ *
121
+ * Rules are matched by their whole canonical value (the `orderKey` hook below),
122
+ * so a field the template carries and this mapping drops is not a smaller diff —
123
+ * it is every rule reported twice, once absent and once undeclared. That is why
124
+ * a range's own `Description` is carried through.
125
+ */
126
+ export function securityGroupToModel(row) {
127
+ const ingress = toIngressRules((row.IpPermissions ?? []));
128
+ const egress = toIngressRules((row.IpPermissionsEgress ?? []));
129
+ return {
130
+ ...(typeof row.Description === "string" ? { GroupDescription: row.Description } : {}),
131
+ ...(typeof row.GroupName === "string" ? { GroupName: row.GroupName } : {}),
132
+ ...(typeof row.VpcId === "string" ? { VpcId: row.VpcId } : {}),
133
+ ...(typeof row.GroupId === "string" ? { GroupId: row.GroupId } : {}),
134
+ // An empty tag set is the absence of tags, not a value. EC2 always sends
135
+ // the key, so carrying it through reports `Tags: <undeclared> -> []` on
136
+ // every untagged group — agreement rendered as drift.
137
+ ...(Array.isArray(row.Tags) && row.Tags.length > 0 ? { Tags: row.Tags } : {}),
138
+ ...(ingress.length > 0 ? { SecurityGroupIngress: ingress } : {}),
139
+ ...(egress.length > 0 ? { SecurityGroupEgress: egress } : {}),
140
+ };
141
+ }
142
+ /**
143
+ * Property names that are server-populated wherever they appear — identifiers
144
+ * the service mints, timestamps it stamps, counters it maintains. Matched on
145
+ * the final path segment, because AWS repeats these names at every nesting
146
+ * depth and a per-type list of full paths would be a maintenance trap.
147
+ *
148
+ * Deliberately excludes ambiguous names like `Id` and `Name`: `VpcId` and
149
+ * `BucketName` are declared inputs, and pruning a declared input is how a
150
+ * normalization pass starts hiding real drift.
151
+ */
152
+ export const AWS_READ_ONLY_NAMES = new Set([
153
+ "Arn",
154
+ "RoleId",
155
+ "PolicyId",
156
+ "GroupId",
157
+ "OwnerId",
158
+ "AttachmentCount",
159
+ "PermissionsBoundaryUsageCount",
160
+ "DefaultVersionId",
161
+ "IsAttachable",
162
+ "CreateDate",
163
+ "CreationDate",
164
+ "UpdateDate",
165
+ "LastModified",
166
+ "LastModifiedTime",
167
+ "DualStackDomainName",
168
+ "RegionalDomainName",
169
+ "WebsiteURL",
170
+ ]);
171
+ /**
172
+ * Service defaults, per type, as index-erased property paths. A live value
173
+ * equal to its default is subtracted **only when source never declared that
174
+ * property** — cdk-real-drift's default subtraction, and the reason
175
+ * {@link DeepNode.counterpart} exists. Declaring the default explicitly keeps
176
+ * the property in the diff, so a later change to it still reports.
177
+ */
178
+ export const AWS_SERVICE_DEFAULTS = {
179
+ "AWS::S3::Bucket": {
180
+ "VersioningConfiguration.Status": "Suspended",
181
+ "AccelerateConfiguration.AccelerationStatus": "Suspended",
182
+ "ObjectLockEnabled": false,
183
+ },
184
+ "AWS::IAM::Role": {
185
+ "Path": "/",
186
+ "MaxSessionDuration": 3600,
187
+ },
188
+ "AWS::IAM::ManagedPolicy": {
189
+ "Path": "/",
190
+ },
191
+ "AWS::EC2::SecurityGroup": {
192
+ "GroupDescription": "default VPC security group",
193
+ // EC2 gives every group an allow-all egress rule when the template declares
194
+ // none (#1269). Patterns are index-erased, so these two match the default
195
+ // rule wherever it lands in the set — and only while source declares no
196
+ // egress at all, which is what `counterpart: "absent"` checks.
197
+ "SecurityGroupEgress[].CidrIp": "0.0.0.0/0",
198
+ "SecurityGroupEgress[].IpProtocol": "-1",
199
+ },
200
+ ...EC2_TOPOLOGY_SERVICE_DEFAULTS,
201
+ };
202
+ /**
203
+ * Names the service mints when a template does not supply one (#1269).
204
+ *
205
+ * Unlike {@link AWS_SERVICE_DEFAULTS} there is no fixed value to compare: a
206
+ * CloudFormation-generated security-group name is a different random string on
207
+ * every deploy. Pruned on the live side only, and only where source is silent —
208
+ * a template that names the group keeps the property in the diff, so a later
209
+ * rename still reports.
210
+ */
211
+ export const AWS_GENERATED_NAMES = {
212
+ "AWS::EC2::SecurityGroup": new Set(["GroupName"]),
213
+ ...EC2_TOPOLOGY_GENERATED_NAMES,
214
+ };
215
+ /** Stable JSON with sorted keys — the fallback ordering key for a set-like array. */
216
+ function canonicalJson(value) {
217
+ return JSON.stringify(value, (_k, v) => v && typeof v === "object" && !Array.isArray(v)
218
+ ? Object.fromEntries(Object.entries(v).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0)))
219
+ : v) ?? "";
220
+ }
221
+ /**
222
+ * The read-only properties of one type, as index-erased patterns, straight from
223
+ * the CloudFormation schema's `readOnlyProperties` (#1641).
224
+ *
225
+ * The codegen already turns that list into each class's GetAtt attributes
226
+ * (`attrs` in `lexicon-aws.json`), so this reads the same registry from the
227
+ * other side: a path the schema says only the service can write is an
228
+ * attribute, and an attribute the live read reports is not property drift. No
229
+ * declaration can contain one, so `<undeclared> -> value` is the shape every
230
+ * clean apply would otherwise produce. `AWS::IAM::ManagedPolicy.PolicyArn`,
231
+ * which is also the type's Cloud Control primary identifier, is the case that
232
+ * surfaced it.
233
+ *
234
+ * The manifest spells an array element `Subscribers.*.Status`; the
235
+ * normalization pass spells the same thing `Subscribers[].Status`.
236
+ *
237
+ * Complements {@link AWS_READ_ONLY_NAMES} rather than replacing it: the
238
+ * name-based list also covers translated models (an EC2 row mapped onto the
239
+ * CloudFormation shape) and nested documents the schema never enumerates.
240
+ */
241
+ export function schemaReadOnlyPatterns(entityType) {
242
+ const cached = readOnlyByType.get(entityType);
243
+ if (cached)
244
+ return cached;
245
+ const entry = manifestByType().get(entityType);
246
+ const patterns = new Set();
247
+ for (const attr of Object.values(entry?.attrs ?? {})) {
248
+ patterns.add(attr.replace(/\.\*(?=\.|$)/g, "[]"));
249
+ }
250
+ readOnlyByType.set(entityType, patterns);
251
+ return patterns;
252
+ }
253
+ const readOnlyByType = new Map();
254
+ let manifestIndex;
255
+ function manifestByType() {
256
+ if (!manifestIndex) {
257
+ const manifest = require("./generated/lexicon-aws.json");
258
+ manifestIndex = new Map(Object.values(manifest)
259
+ .filter((e) => e.kind === "resource")
260
+ .map((e) => [e.resourceType, e]));
261
+ }
262
+ return manifestIndex;
263
+ }
264
+ /** The final segment of an index-erased pattern (`Policies[].PolicyName` → `PolicyName`). */
265
+ function lastSegment(pattern) {
266
+ const withoutIndex = pattern.replace(/\[\]$/, "");
267
+ const dot = withoutIndex.lastIndexOf(".");
268
+ return dot === -1 ? withoutIndex : withoutIndex.slice(dot + 1);
269
+ }
270
+ /**
271
+ * The aws lexicon's noise rules. The three classes the epic names for AWS —
272
+ * server-populated fields, unstable ordering (tags, policy statements), and
273
+ * provider defaults — plus nothing else: a rule that is not one of those is a
274
+ * rule that hides drift.
275
+ */
276
+ export const awsDeepNormalizationHooks = {
277
+ prune(node) {
278
+ // Read-only / server-populated. Pruned on both sides: if source somehow
279
+ // declares an arn-shaped output, comparing it to the live one is still
280
+ // meaningless. The schema's own `readOnlyProperties` first (#1641), then
281
+ // the name-based list for what the schema does not enumerate.
282
+ if (schemaReadOnlyPatterns(node.entityType).has(node.pattern))
283
+ return true;
284
+ if (AWS_READ_ONLY_NAMES.has(lastSegment(node.pattern)))
285
+ return true;
286
+ // A declared property this type's source cannot see (#1269). With nothing
287
+ // live to stand against it would report `value -> <absent>` on every clean
288
+ // apply — a blind spot rendered as drift. Counterpart-gated the other way
289
+ // round: a live tree that does carry the field is still compared.
290
+ if (node.side === "declared" &&
291
+ node.counterpart === "absent" &&
292
+ AWS_DEEP_BLIND_SPOTS[node.entityType]?.has(node.pattern)) {
293
+ return true;
294
+ }
295
+ // Provider defaults, on the live side only, and only where source is silent
296
+ // about the property. `"unknown"` (a one-sided normalization) never prunes:
297
+ // the reader must not decide this before the declared tree is in hand.
298
+ if (node.side !== "live" || node.counterpart !== "absent")
299
+ return false;
300
+ // chant's own ownership marker. The serializer stamps it onto the template,
301
+ // so it is live on every managed resource and absent from the declared
302
+ // *properties* the diff compares — chant reading its own signature back as
303
+ // drift. Counterpart-gated, so a template that declares the tag itself is
304
+ // still compared against what is live.
305
+ if (isOwnershipTag(node.value))
306
+ return true;
307
+ // A name the service generated because source did not supply one.
308
+ if (AWS_GENERATED_NAMES[node.entityType]?.has(node.pattern))
309
+ return true;
310
+ const defaults = AWS_SERVICE_DEFAULTS[node.entityType];
311
+ if (!defaults)
312
+ return false;
313
+ if (!Object.prototype.hasOwnProperty.call(defaults, node.pattern))
314
+ return false;
315
+ return defaults[node.pattern] === node.value;
316
+ },
317
+ /**
318
+ * The key doubles as a path segment (`Tags[#env].Value`), so it is the
319
+ * element's own identity where AWS gives one — a tag key, a statement Sid, an
320
+ * action string — and canonical JSON only as a fallback.
321
+ */
322
+ orderKey(element) {
323
+ const name = lastSegment(element.pattern);
324
+ const el = element.element;
325
+ // Tags are a set. AWS returns them in whatever order it likes, and a
326
+ // reordered tag list is the single loudest false positive in a raw diff.
327
+ if (name === "Tags") {
328
+ const key = isRecord(el) ? el.Key : undefined;
329
+ return typeof key === "string" ? key : canonicalJson(el);
330
+ }
331
+ // IAM policy statements are a set, and so are the Action/Resource lists
332
+ // inside them. `Sid` is the natural identity when the author gave one.
333
+ if (name === "Statement") {
334
+ const sid = isRecord(el) ? el.Sid : undefined;
335
+ return typeof sid === "string" ? sid : canonicalJson(el);
336
+ }
337
+ if (name === "Action" || name === "NotAction" || name === "Resource" || name === "NotResource") {
338
+ return typeof el === "string" ? el : canonicalJson(el);
339
+ }
340
+ // Security-group rules are a set — the console appends, chant declares in
341
+ // source order, and neither order means anything to EC2.
342
+ if (name === "SecurityGroupIngress" || name === "SecurityGroupEgress") {
343
+ return securityGroupRuleKey(el) ?? canonicalJson(el);
344
+ }
345
+ if (name === "IpRanges") {
346
+ return canonicalJson(el);
347
+ }
348
+ return undefined;
349
+ },
350
+ };
351
+ function isRecord(value) {
352
+ return typeof value === "object" && value !== null && !Array.isArray(value);
353
+ }
354
+ /**
355
+ * Classify a failed read the same way the thin path does — off the API's own
356
+ * error code where there is one (#1206), falling back to the message for a
357
+ * transport-level failure that never reached the service.
358
+ */
359
+ function classifyFailure(err) {
360
+ const code = err instanceof AwsReadError ? err.code ?? "" : "";
361
+ const message = err instanceof Error ? err.message : String(err);
362
+ return /credential|token|expired|AccessDenied|NotAuthorized|Unauthorized/i.test(`${code} ${message}`)
363
+ ? "no-credentials"
364
+ : "read-failed";
365
+ }
366
+ /** The message a failed read reports, without a stack trace or a stderr tail. */
367
+ function failureDetail(err) {
368
+ if (err instanceof AwsReadError)
369
+ return err.code ? `${err.code}: ${err.message}` : err.message;
370
+ return err instanceof Error ? err.message : String(err);
371
+ }
372
+ /** True when a CloudFormation read failed only because the stack isn't there yet. */
373
+ function isStackMissing(err) {
374
+ return err instanceof AwsReadError && /does not exist/i.test(err.message);
375
+ }
376
+ /**
377
+ * What identifies a security-group rule, as a path segment.
378
+ *
379
+ * `canonicalJson` of a rule runs past the length a path segment may carry
380
+ * (`MAX_KEYED_SEGMENT`, 60), so keying by it makes the flattener give up and
381
+ * compare the set positionally. A rule added at the top then shifts every rule
382
+ * below it, and one added rule reports as "the first rule changed, and a new
383
+ * one appeared at the end" — detection is right, attribution is not.
384
+ *
385
+ * Identity is protocol, port range and source, which is what EC2 itself
386
+ * enforces uniqueness on. `Description` is deliberately excluded: editing a
387
+ * rule's description is a change *to that rule*, not the removal of one rule
388
+ * and the addition of another.
389
+ */
390
+ function securityGroupRuleKey(element) {
391
+ if (!isRecord(element))
392
+ return undefined;
393
+ const source = typeof element.CidrIp === "string"
394
+ ? element.CidrIp
395
+ : typeof element.CidrIpv6 === "string"
396
+ ? element.CidrIpv6
397
+ : typeof element.SourceSecurityGroupId === "string"
398
+ ? element.SourceSecurityGroupId
399
+ : undefined;
400
+ // No recognisable source is not a rule this can identify; the caller falls
401
+ // back rather than keying every such rule to the same segment.
402
+ if (source === undefined)
403
+ return undefined;
404
+ const protocol = typeof element.IpProtocol === "string" ? element.IpProtocol : "-1";
405
+ const from = element.FromPort ?? "*";
406
+ const to = element.ToPort ?? "*";
407
+ return `${protocol}:${String(from)}:${String(to)}:${source}`;
408
+ }
409
+ /** Every tag key the serializer stamps as chant's ownership marker. */
410
+ const OWNERSHIP_TAG_KEYS = new Set(Object.values(AWS_TAG_OWNERSHIP_KEYS));
411
+ /** True when `value` is a `{Key, Value}` tag whose key is one chant stamps itself. */
412
+ function isOwnershipTag(value) {
413
+ return isRecord(value) && typeof value.Key === "string" && OWNERSHIP_TAG_KEYS.has(value.Key);
414
+ }
415
+ /** True when the live property tree carries chant's ownership marker tag. */
416
+ export function hasOwnershipMarker(properties) {
417
+ const tags = properties.Tags;
418
+ if (!Array.isArray(tags))
419
+ return false;
420
+ return tags.some((t) => isRecord(t) && t.Key === AWS_TAG_OWNERSHIP_KEYS.managedBy);
421
+ }
422
+ /**
423
+ * Read the live property tree for each declared entity via Cloud Control.
424
+ *
425
+ * Two reads per run plus one per readable resource: `DescribeStackResources`
426
+ * resolves logical id → (type, physical id), then `GetResource` fetches each
427
+ * model. The first read's failure modes are the thin path's, verbatim — a stack
428
+ * that does not exist yet is a real absence (nothing is deployed, so there are
429
+ * no properties to drift), anything else is a hole for every declared entity.
430
+ *
431
+ * The per-resource reads run concurrently (#1201/#1206). They were serial when
432
+ * each one was a process spawn, which made a deep snapshot of a large stack
433
+ * cost N round trips end to end.
434
+ */
435
+ export async function observeResourcesDeepAws(options) {
436
+ const { deepObservation, normalizeDeepProperties } = await import("@intentius/chant/deep-observation");
437
+ const { unobservedAll, boundedConcurrently } = await import("@intentius/chant/observation");
438
+ const stackName = options.stack ?? options.environment;
439
+ const client = {
440
+ ...(options.region ? { region: options.region } : {}),
441
+ ...(options.http ? { http: options.http } : {}),
442
+ };
443
+ let stackResources;
444
+ try {
445
+ stackResources = await describeStackResources(stackName, client);
446
+ }
447
+ catch (err) {
448
+ if (isStackMissing(err))
449
+ return deepObservation({});
450
+ return deepObservation({}, unobservedAll(options.entityNames, classifyFailure(err), `DescribeStackResources failed for stack "${stackName}": ${failureDetail(err)}`));
451
+ }
452
+ const byLogicalId = new Map(stackResources.map((r) => [r.logicalId, r]));
453
+ const resources = {};
454
+ const unobserved = {};
455
+ // Types with a bulk source are read once for the whole stack, before the
456
+ // per-entity pass — one `describe-security-groups` for every group, not one
457
+ // call per group.
458
+ const bulk = await readBulkSources(options.entityNames.flatMap((name) => {
459
+ const r = byLogicalId.get(name);
460
+ return r?.physicalId ? [{ type: r.type, id: r.physicalId }] : [];
461
+ }), options.region);
462
+ await boundedConcurrently(options.entityNames, async (entityName) => {
463
+ const stackResource = byLogicalId.get(entityName);
464
+ // Not in the stack at all. The thin read reports that absence; restating it
465
+ // here as a property hole would turn one finding into two.
466
+ if (!stackResource)
467
+ return;
468
+ const type = stackResource.type;
469
+ const source = DEEP_SOURCES[type];
470
+ if (!source) {
471
+ unobserved[entityName] = {
472
+ type,
473
+ reason: "unsupported-kind",
474
+ detail: `no deep reader for ${type} — coverage is opt-in per type`,
475
+ };
476
+ return;
477
+ }
478
+ const identifier = stackResource.physicalId;
479
+ if (!identifier) {
480
+ unobserved[entityName] = {
481
+ type,
482
+ reason: "read-failed",
483
+ detail: "the stack reports no physical id, so the live resource cannot be addressed",
484
+ };
485
+ return;
486
+ }
487
+ let properties;
488
+ if (source.via === "ec2") {
489
+ const answer = bulk.get(type);
490
+ if (!answer) {
491
+ unobserved[entityName] = {
492
+ type,
493
+ reason: "read-failed",
494
+ detail: `${source.argv.join(" ")} failed, so ${type} could not be read deeply`,
495
+ };
496
+ return;
497
+ }
498
+ const row = answer.get(identifier);
499
+ // The describe answered, and this id was not in it. That is absence, and
500
+ // the thin read already reports it — same reasoning as a resource missing
501
+ // from the stack.
502
+ if (!row)
503
+ return;
504
+ properties = source.toModel(row);
505
+ }
506
+ else {
507
+ let parsed;
508
+ try {
509
+ parsed = await getResource(type, identifier, client);
510
+ }
511
+ catch (err) {
512
+ unobserved[entityName] = {
513
+ type,
514
+ reason: classifyFailure(err),
515
+ detail: `GetResource failed for ${type} "${identifier}": ${failureDetail(err)}`,
516
+ };
517
+ return;
518
+ }
519
+ if (!parsed) {
520
+ unobserved[entityName] = {
521
+ type,
522
+ reason: "read-failed",
523
+ detail: `unparseable GetResource response for ${type} "${identifier}"`,
524
+ };
525
+ return;
526
+ }
527
+ properties = parsed.properties;
528
+ }
529
+ // Both sources return tags where the service carries them, so unlike the
530
+ // thin path this one can answer the ownership question (#1015's open note).
531
+ // A resource withheld by the filter is `filtered`, never absent: it exists,
532
+ // it just isn't chant's.
533
+ const owned = hasOwnershipMarker(properties);
534
+ if (options.owned && !owned) {
535
+ unobserved[entityName] = {
536
+ type,
537
+ reason: "filtered",
538
+ detail: `live resource carries no ${AWS_TAG_OWNERSHIP_KEYS.managedBy} tag`,
539
+ };
540
+ return;
541
+ }
542
+ resources[entityName] = {
543
+ type,
544
+ physicalId: identifier,
545
+ properties: normalizeDeepProperties(properties, {
546
+ entityType: type,
547
+ side: "live",
548
+ hooks: awsDeepNormalizationHooks,
549
+ }),
550
+ };
551
+ });
552
+ // The out-of-band pass (#1015): under each declared parent whose type names
553
+ // child sources, list what actually exists and keep what nothing declared.
554
+ // A parent `--owned` withheld keeps its children out too — reporting a
555
+ // foreign resource's children while withholding the resource itself would
556
+ // be the filter half-applied. A parent with no deep reader of its own
557
+ // (`unsupported-kind`) still gets its children enumerated: listing under it
558
+ // needs only the physical id the stack already resolved.
559
+ const parents = [];
560
+ for (const entityName of options.entityNames) {
561
+ const resource = byLogicalId.get(entityName);
562
+ const sources = resource ? DEEP_CHILD_SOURCES[resource.type] : undefined;
563
+ if (!resource?.physicalId || !sources)
564
+ continue;
565
+ if (unobserved[entityName]?.reason === "filtered")
566
+ continue;
567
+ parents.push({ resource, sources });
568
+ }
569
+ const children = await enumerateOutOfBandChildren({
570
+ parents,
571
+ allStackResources: stackResources,
572
+ entities: options.entities,
573
+ client,
574
+ normalize: (childType, properties) => normalizeDeepProperties(properties, {
575
+ entityType: childType,
576
+ side: "live",
577
+ hooks: awsDeepNormalizationHooks,
578
+ }),
579
+ concurrently: boundedConcurrently,
580
+ });
581
+ for (const [name, child] of Object.entries(children)) {
582
+ if (!resources[name])
583
+ resources[name] = child;
584
+ }
585
+ return deepObservation(resources, unobserved);
586
+ }
587
+ /**
588
+ * List every child-sourced type under its declared parents and return the
589
+ * resources nothing declared, named by {@link outOfBandChildName}.
590
+ *
591
+ * "Declared" is answered three ways, in order of how directly the stack says
592
+ * it: the child identifier is some stack resource's physical id (the normal
593
+ * case — a declared `AWS::SNS::Subscription` deploys under its ARN); a
594
+ * `declaredVia` legacy form's physical id is the identifier's relevant part;
595
+ * or a declared entity's props spell the identifier (`declaredIdentifier`,
596
+ * the carve case — declared in source, not yet in any stack).
597
+ *
598
+ * A listing that fails is silence about that parent's children, never a
599
+ * finding and never a hole: there is no declared entity to hang a hole on,
600
+ * and fabricating one would put an undeclared name in the unobserved report.
601
+ * `UnsupportedOperation` — an emulator without parent-scoped listing — lands
602
+ * here too, which is what keeps the Floci lanes quiet.
603
+ */
604
+ async function enumerateOutOfBandChildren(args) {
605
+ const out = {};
606
+ if (args.parents.length === 0)
607
+ return out;
608
+ // Physical ids by type, over the WHOLE stack — a stack resource that is not
609
+ // a declared chant entity (a nested stack's row, a resource another tool
610
+ // added to the same stack) is still stack-managed, not out-of-band.
611
+ const addTo = (map, key, value) => {
612
+ const set = map.get(key) ?? new Set();
613
+ set.add(value);
614
+ map.set(key, set);
615
+ };
616
+ const stackIdsByType = new Map();
617
+ for (const r of args.allStackResources) {
618
+ if (r.physicalId)
619
+ addTo(stackIdsByType, r.type, r.physicalId);
620
+ }
621
+ const declaredIdsByType = new Map();
622
+ for (const entity of args.entities?.values() ?? []) {
623
+ const id = declaredIdentifier(entity.entityType, entity.props ?? {});
624
+ if (id)
625
+ addTo(declaredIdsByType, entity.entityType, id);
626
+ }
627
+ const isDeclared = (source, identifier) => {
628
+ if (stackIdsByType.get(source.childType)?.has(identifier))
629
+ return true;
630
+ if (declaredIdsByType.get(source.childType)?.has(identifier))
631
+ return true;
632
+ for (const via of source.declaredVia ?? []) {
633
+ const part = via.part(identifier);
634
+ if (part && stackIdsByType.get(via.type)?.has(part))
635
+ return true;
636
+ }
637
+ return false;
638
+ };
639
+ const listings = args.parents.flatMap(({ resource, sources }) => sources.map((source) => ({ physicalId: resource.physicalId, source })));
640
+ await args.concurrently(listings, async ({ physicalId, source }) => {
641
+ let listed;
642
+ try {
643
+ listed = await listResources(source.childType, args.client, source.model(physicalId));
644
+ }
645
+ catch {
646
+ return;
647
+ }
648
+ for (const child of listed) {
649
+ if (!child.identifier || isDeclared(source, child.identifier))
650
+ continue;
651
+ out[outOfBandChildName(source.childType, child.identifier)] = {
652
+ type: source.childType,
653
+ physicalId: child.identifier,
654
+ properties: args.normalize(source.childType, child.properties),
655
+ };
656
+ }
657
+ });
658
+ return out;
659
+ }
660
+ /**
661
+ * Read every `ec2`-sourced type in bulk, keyed by physical id.
662
+ *
663
+ * A type whose describe fails is absent from the returned map, which the caller
664
+ * turns into a hole for each of its resources — never into an absence, because
665
+ * a failed read establishes nothing about what exists.
666
+ *
667
+ * These reads still shell the CLI, unlike the Cloud Control path (#1206). The
668
+ * EC2 API speaks the Query protocol with its own lowerCamelCase XML, so going
669
+ * native here is a second wire format rather than a reuse of the existing
670
+ * client, and it belongs with the port of `properties.ts` / `ambient.ts` /
671
+ * `dependencies.ts` — the modules that already read EC2 this way.
672
+ */
673
+ async function readBulkSources(wanted, region) {
674
+ const byType = new Map();
675
+ for (const { type, id } of wanted) {
676
+ if (DEEP_SOURCES[type]?.via !== "ec2")
677
+ continue;
678
+ byType.set(type, [...(byType.get(type) ?? []), id]);
679
+ }
680
+ const out = new Map();
681
+ if (byType.size === 0)
682
+ return out;
683
+ const { getRuntime } = await import("@intentius/chant/runtime-adapter");
684
+ const rt = getRuntime();
685
+ const regionArgs = region ? ["--region", region] : [];
686
+ for (const [type, ids] of byType) {
687
+ const source = DEEP_SOURCES[type];
688
+ if (source?.via !== "ec2")
689
+ continue;
690
+ try {
691
+ const result = await rt.spawn(applyAwsEndpointArgv(["aws", ...source.argv, source.idFlag, ...ids, ...regionArgs, "--output", "json"], process.env.AWS_ENDPOINT_URL));
692
+ if (result.exitCode !== 0)
693
+ continue;
694
+ const rows = (JSON.parse(result.stdout)[source.key] ?? []);
695
+ const byId = new Map();
696
+ for (const row of rows) {
697
+ const id = row[source.id];
698
+ if (typeof id === "string")
699
+ byId.set(id, row);
700
+ }
701
+ out.set(type, byId);
702
+ }
703
+ catch {
704
+ // One type's transport failing is that type's hole, not the whole read's.
705
+ continue;
706
+ }
707
+ }
708
+ return out;
709
+ }