@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,193 @@
1
+ import { homedir } from "os";
2
+ import { join } from "path";
3
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
4
+ import { execFile } from "child_process";
5
+ import { promisify } from "util";
6
+ import { fetchWithCache, extractFromZip, clearCacheFile } from "@intentius/chant/codegen/fetch";
7
+ import { RELEASE_GATE_ENV } from "@intentius/chant/codegen/validate";
8
+ import { ACCEPT_ENV, AWS_SPEC_PIN, specContentDigest } from "./pin.js";
9
+ /** Per-attempt download timeout for a multi-megabyte archive. */
10
+ const ARCHIVE_ATTEMPT_TIMEOUT_MS = 120000;
11
+ const SCHEMA_ZIP_URL = "https://schema.cloudformation.us-east-1.amazonaws.com/CloudformationSchema.zip";
12
+ const CACHE_DIR = join(homedir(), ".chant");
13
+ const CACHE_FILE = join(CACHE_DIR, "CloudformationSchema.zip");
14
+ /**
15
+ * The pinned-spec store (chant #1511): assets on one dedicated GitHub release,
16
+ * named by content digest, in a public repo — so nothing binary ever enters
17
+ * git history, and the download needs no auth anywhere (CI included).
18
+ *
19
+ * Why a store at all: `prepack` regenerates from upstream, and the registry
20
+ * serves a single mutable "latest" artifact — on 2026-08-05 four distinct
21
+ * contents were observed in one day, two *contradicting* each other about the
22
+ * same resources, so the surface gate compared artifacts built from whichever
23
+ * variant that fetch happened to hit. Publishing aws was a retry lottery
24
+ * (v0.41.1 and v0.41.2 both stranded it). The accepted content itself is the
25
+ * only deterministic input; the accept uploads it, every build downloads it
26
+ * by digest and verifies before trusting it.
27
+ */
28
+ const SPEC_PIN_RELEASE_TAG = "aws-spec-pin";
29
+ const SPEC_PIN_REPO = "INTENTIUS/chant";
30
+ /** Verified-by-digest local copies of pin assets, so repeat builds skip the download. Content-addressed: no TTL, never invalidated. */
31
+ const PIN_CACHE_DIR = join(CACHE_DIR, "spec-pin");
32
+ /** `<first 12 digest hex>.zip` — the asset (and local cache) name for a pin. */
33
+ export function pinAssetName(pin = AWS_SPEC_PIN) {
34
+ return `${pin.digest.replace(/^sha256:/, "").slice(0, 12)}.zip`;
35
+ }
36
+ /** Public, unauthenticated download URL for a pin's asset. */
37
+ export function pinAssetUrl(pin = AWS_SPEC_PIN) {
38
+ return `https://github.com/${SPEC_PIN_REPO}/releases/download/${SPEC_PIN_RELEASE_TAG}/${pinAssetName(pin)}`;
39
+ }
40
+ const downloadPinAsset = async (url) => {
41
+ try {
42
+ const res = await fetch(url, { redirect: "follow" });
43
+ if (!res.ok)
44
+ return undefined;
45
+ return Buffer.from(await res.arrayBuffer());
46
+ }
47
+ catch {
48
+ return undefined;
49
+ }
50
+ };
51
+ /**
52
+ * Load and verify the pinned spec: the local verified cache first, then the
53
+ * release asset. Returns undefined when neither is available (offline and
54
+ * cold, or the accept never uploaded) — the caller falls back to the live
55
+ * fetch and the pin's existing advisory drift report. Content that does not
56
+ * digest to the pin throws: a tampered or half-uploaded asset must never
57
+ * silently pass as the accepted spec, wherever it came from.
58
+ */
59
+ export async function loadPinnedSchemas(options = {}) {
60
+ const pin = options.pin ?? AWS_SPEC_PIN;
61
+ const cacheDir = options.cacheDir ?? PIN_CACHE_DIR;
62
+ const cachePath = join(cacheDir, pinAssetName(pin));
63
+ const verify = async (zipData, source) => {
64
+ const schemas = await extractRawSchemas(zipData);
65
+ const digest = specContentDigest(schemas);
66
+ if (digest !== pin.digest) {
67
+ throw new Error(`pinned spec from ${source} extracts to ${digest}, but the pin declares ${pin.digest} — ` +
68
+ `refusing to build from it. Re-run the accept (${ACCEPT_ENV}=1 npm run generate) to ` +
69
+ `upload the content the pin actually names.`);
70
+ }
71
+ return schemas;
72
+ };
73
+ if (existsSync(cachePath)) {
74
+ return verify(readFileSync(cachePath), cachePath);
75
+ }
76
+ const url = pinAssetUrl(pin);
77
+ const zipData = await (options.download ?? downloadPinAsset)(url);
78
+ if (zipData === undefined)
79
+ return undefined;
80
+ const schemas = await verify(zipData, url);
81
+ // Cache only after verification, so the cache can never hold a bad copy.
82
+ mkdirSync(cacheDir, { recursive: true });
83
+ writeFileSync(cachePath, zipData);
84
+ return schemas;
85
+ }
86
+ /**
87
+ * The accept flow's upload half: push the just-accepted zip to the pin
88
+ * release via `gh` (dev-machine path — publishes never upload). Creates the
89
+ * rolling `aws-spec-pin` release on first use. Assets are content-addressed
90
+ * and never overwritten. A missing/unauthenticated `gh` degrades to printing
91
+ * the exact command to run by hand — the accept still completes, and the pin
92
+ * block still prints.
93
+ */
94
+ async function uploadPinAsset(zipData, digest) {
95
+ const pin = { ...AWS_SPEC_PIN, digest };
96
+ mkdirSync(PIN_CACHE_DIR, { recursive: true });
97
+ const localPath = join(PIN_CACHE_DIR, pinAssetName(pin));
98
+ writeFileSync(localPath, zipData);
99
+ const run = promisify(execFile);
100
+ try {
101
+ try {
102
+ await run("gh", ["release", "view", SPEC_PIN_RELEASE_TAG, "--repo", SPEC_PIN_REPO]);
103
+ }
104
+ catch {
105
+ await run("gh", [
106
+ "release", "create", SPEC_PIN_RELEASE_TAG,
107
+ "--repo", SPEC_PIN_REPO,
108
+ "--title", "aws spec pin assets",
109
+ "--notes", "Content-addressed CloudFormation registry archives, one per accepted spec pin (chant #1511). Uploaded by the accept flow; downloaded and digest-verified by every build. Not a chant release.",
110
+ ]);
111
+ }
112
+ await run("gh", ["release", "upload", SPEC_PIN_RELEASE_TAG, localPath, "--repo", SPEC_PIN_REPO]);
113
+ console.error(`Accepted spec uploaded: ${pinAssetUrl(pin)}`);
114
+ }
115
+ catch (err) {
116
+ console.error(`Could not upload the accepted spec via gh (${err instanceof Error ? err.message.split("\n")[0] : String(err)}).\n` +
117
+ `Upload it yourself before merging the pin:\n` +
118
+ ` gh release upload ${SPEC_PIN_RELEASE_TAG} ${localPath} --repo ${SPEC_PIN_REPO}`);
119
+ }
120
+ }
121
+ /**
122
+ * Fetch the CloudFormation Registry schema zip and extract per-resource JSON schemas.
123
+ * Returns a Map keyed by typeName (e.g. "AWS::S3::Bucket") to raw JSON bytes.
124
+ *
125
+ * chant #1511 — the pinned release asset is the primary source: when it
126
+ * resolves and digest-verifies, generation uses the content a human accepted
127
+ * rather than whatever upstream variant this fetch happens to hit, so every
128
+ * build (CI, prepack, publish) is deterministic. The live fetch remains for:
129
+ * `force`, the accept flow (`CHANT_ACCEPT_AWS_SPEC=1`, which must sample
130
+ * upstream — and bypasses the 24h cache for the same reason), and when the
131
+ * asset is unreachable. The live path keeps its 24h local cache.
132
+ *
133
+ * chant #1481 — the fallback is what made two workflows disagree about one
134
+ * commit. The live archive is served from CloudFront and two fetches seconds
135
+ * apart can get different variants; under the release gate, building from
136
+ * it would ship a surface nobody reviewed on a retry lottery, so the gate
137
+ * refuses instead. Anywhere else the fallback stays, but says so, because a
138
+ * silent fallback is indistinguishable from the pinned path in a CI log.
139
+ */
140
+ export async function fetchSchemaZip(force = false, options = {}) {
141
+ const env = options.env ?? process.env;
142
+ const accepting = !!env[ACCEPT_ENV];
143
+ if (!force && !accepting) {
144
+ const pinned = await loadPinnedSchemas({ download: options.download, cacheDir: options.pinCacheDir });
145
+ if (pinned)
146
+ return pinned;
147
+ if (env[RELEASE_GATE_ENV] === "1") {
148
+ throw new Error(`${RELEASE_GATE_ENV}=1 and the pinned spec asset could not be loaded (${pinAssetUrl()}) — ` +
149
+ `refusing to build a release from the live CloudFormation archive, which is not the content ` +
150
+ `the pin was reviewed against. Check the asset exists on the ${SPEC_PIN_RELEASE_TAG} release ` +
151
+ `(the accept flow uploads it: ${ACCEPT_ENV}=1 npm run generate).`);
152
+ }
153
+ console.error(`pinned spec asset unavailable (${pinAssetUrl()}); falling back to the live CloudFormation archive`);
154
+ }
155
+ const zipData = await fetchWithCache({ url: SCHEMA_ZIP_URL, cacheFile: CACHE_FILE, attemptTimeoutMs: ARCHIVE_ATTEMPT_TIMEOUT_MS }, force || accepting);
156
+ const schemas = await extractRawSchemas(zipData);
157
+ if (accepting) {
158
+ await uploadPinAsset(zipData, specContentDigest(schemas));
159
+ }
160
+ return schemas;
161
+ }
162
+ /**
163
+ * Extract raw JSON schema bytes from the zip, keyed by typeName.
164
+ */
165
+ async function extractRawSchemas(zipData) {
166
+ const files = await extractFromZip(zipData, (name) => name.endsWith(".json"));
167
+ const schemas = new Map();
168
+ for (const [_name, data] of files) {
169
+ try {
170
+ const text = data.toString("utf-8");
171
+ const partial = JSON.parse(text);
172
+ if (!partial.typeName)
173
+ continue;
174
+ schemas.set(partial.typeName, data);
175
+ }
176
+ catch {
177
+ // Skip files that can't be parsed
178
+ }
179
+ }
180
+ return schemas;
181
+ }
182
+ /**
183
+ * Get the cache file path (for testing)
184
+ */
185
+ export function getCachePath() {
186
+ return CACHE_FILE;
187
+ }
188
+ /**
189
+ * Clear the cache (for testing)
190
+ */
191
+ export function clearCache() {
192
+ clearCacheFile(CACHE_FILE);
193
+ }
@@ -0,0 +1,259 @@
1
+ /**
2
+ * CloudFormation Registry JSON Schema parser.
3
+ *
4
+ * Parses each CFNSchema into typed structures suitable for code generation:
5
+ * resources with properties and attributes, property types from definitions,
6
+ * and enum types from string enum definitions.
7
+ */
8
+ import { resolvePropertyType as coreResolvePropertyType, extractConstraints as coreExtractConstraints, constraintsIsEmpty as coreConstraintsIsEmpty, isEnumDefinition as coreIsEnumDefinition, } from "@intentius/chant/codegen/json-schema";
9
+ import { boundPropertyTypes } from "@intentius/chant/codegen/bound-property-types";
10
+ /**
11
+ * Maximum nesting depth of generated property-type interfaces. Bounds the
12
+ * shipped `.d.ts` size: property types reachable from a resource's top-level
13
+ * properties within this depth stay typed; deeper ones are loosened to
14
+ * `Record<string, unknown>`. Set high enough that the shapes composites consume
15
+ * (which reach a few levels into CFN config) remain typed. (#440)
16
+ */
17
+ const MAX_PROPERTY_TYPE_DEPTH = 3;
18
+ /**
19
+ * Prose signals that a property description is describing a deprecation.
20
+ * A hit is a guess, not a reading — see `ParsedResource.inferredDeprecations`.
21
+ */
22
+ const DEPRECATION_RE = /\bdeprecated\b|\blegacy\b|no longer (available|recommended|used|supported)|is not recommended|has been discontinued/i;
23
+ /**
24
+ * Parse a CloudFormation Registry JSON Schema into typed structures.
25
+ */
26
+ export function parseCFNSchema(data) {
27
+ const schema = JSON.parse(typeof data === "string" ? data : data.toString("utf-8"));
28
+ const requiredSet = new Set(schema.required ?? []);
29
+ const shortName = cfnShortName(schema.typeName);
30
+ // Parse top-level properties
31
+ const props = [];
32
+ if (schema.properties) {
33
+ for (const [name, prop] of Object.entries(schema.properties)) {
34
+ const tsType = resolvePropertyType(prop, schema);
35
+ props.push({
36
+ name,
37
+ tsType,
38
+ required: requiredSet.has(name),
39
+ description: prop.description,
40
+ enum: prop.enum,
41
+ constraints: extractConstraints(prop),
42
+ });
43
+ }
44
+ }
45
+ // Parse readOnlyProperties as attributes
46
+ // Deduplicate — some upstream schemas (e.g. aws-s3files-filesystem) list the same
47
+ // property twice in readOnlyProperties, which would produce duplicate class members.
48
+ const attrs = [];
49
+ const seenAttrs = new Set();
50
+ for (const path of schema.readOnlyProperties ?? []) {
51
+ const attrName = stripPointerPath(path, schema);
52
+ // Flatten nested paths: "Endpoint/Address" → attr name "Endpoint.Address"
53
+ const cfnAttr = attrName.replace(/\//g, ".");
54
+ if (seenAttrs.has(cfnAttr))
55
+ continue;
56
+ seenAttrs.add(cfnAttr);
57
+ let tsType = "string";
58
+ // For top-level attrs, look up type from properties
59
+ if (!cfnAttr.includes(".") && schema.properties?.[cfnAttr]) {
60
+ tsType = resolvePropertyType(schema.properties[cfnAttr], schema);
61
+ }
62
+ // For nested attrs, type is always string (CF GetAtt returns strings for leaf values)
63
+ attrs.push({ name: cfnAttr, tsType });
64
+ }
65
+ // Parse definitions into property types and enums
66
+ const propertyTypes = [];
67
+ const enums = [];
68
+ if (schema.definitions) {
69
+ for (const [defName, def] of Object.entries(schema.definitions)) {
70
+ if (isEnumDefinition(def)) {
71
+ enums.push({
72
+ name: `${shortName}_${defName}`,
73
+ values: def.enum,
74
+ });
75
+ continue;
76
+ }
77
+ if (def.properties) {
78
+ const defRequired = new Set(def.required ?? []);
79
+ const defProps = [];
80
+ for (const [propName, prop] of Object.entries(def.properties)) {
81
+ const tsType = resolvePropertyType(prop, schema);
82
+ defProps.push({
83
+ name: propName,
84
+ tsType,
85
+ required: defRequired.has(propName),
86
+ description: prop.description,
87
+ enum: prop.enum,
88
+ constraints: extractConstraints(prop),
89
+ });
90
+ }
91
+ propertyTypes.push({
92
+ name: `${shortName}_${defName}`,
93
+ specType: defName,
94
+ properties: defProps,
95
+ });
96
+ }
97
+ }
98
+ }
99
+ // --- Deprecated properties: declared upstream, plus description-mined ---
100
+ // The declared half is what the Registry schema states. The mined half is a
101
+ // regex over English prose and is recorded separately (#1701): a description
102
+ // can mention the deprecation of a sibling property, of an enum value, or of
103
+ // something the property merely configures.
104
+ const deprecatedSet = new Set(stripPointerPaths(schema.deprecatedProperties ?? [], schema));
105
+ const inferredDeprecations = [];
106
+ // Mine top-level property descriptions
107
+ if (schema.properties) {
108
+ for (const [name, prop] of Object.entries(schema.properties)) {
109
+ if (!prop.description || !DEPRECATION_RE.test(prop.description))
110
+ continue;
111
+ // A hit upstream already declares adds nothing, and is not an inference.
112
+ if (deprecatedSet.has(name))
113
+ continue;
114
+ deprecatedSet.add(name);
115
+ inferredDeprecations.push(name);
116
+ }
117
+ }
118
+ // --- Tagging ---
119
+ let tagging;
120
+ if (schema.tagging && schema.tagging.taggable) {
121
+ tagging = {
122
+ taggable: true,
123
+ tagOnCreate: schema.tagging.tagOnCreate ?? false,
124
+ tagUpdatable: schema.tagging.tagUpdatable ?? false,
125
+ };
126
+ }
127
+ // --- Replacement strategy ---
128
+ let replacementStrategy;
129
+ if (schema.replacementStrategy === "delete_then_create" || schema.replacementStrategy === "create_then_delete") {
130
+ replacementStrategy = schema.replacementStrategy;
131
+ }
132
+ // Bound the emitted property types to keep the shipped declaration small while
133
+ // preserving the shapes composites and shallow authoring rely on (#440).
134
+ const boundedPropertyTypes = boundPropertyTypes(shortName, props, propertyTypes, new Set(enums.map((e) => e.name)), { maxDepth: MAX_PROPERTY_TYPE_DEPTH });
135
+ return {
136
+ resource: {
137
+ typeName: schema.typeName,
138
+ properties: props,
139
+ attributes: attrs,
140
+ createOnly: stripPointerPaths(schema.createOnlyProperties ?? [], schema),
141
+ writeOnly: stripPointerPaths(schema.writeOnlyProperties ?? [], schema),
142
+ primaryIdentifier: stripPointerPaths(schema.primaryIdentifier ?? [], schema),
143
+ deprecatedProperties: [...deprecatedSet],
144
+ inferredDeprecations,
145
+ conditionalCreateOnly: stripPointerPaths(schema.conditionalCreateOnlyProperties ?? [], schema),
146
+ ...(replacementStrategy && { replacementStrategy }),
147
+ ...(tagging && { tagging }),
148
+ },
149
+ propertyTypes: boundedPropertyTypes,
150
+ enums,
151
+ };
152
+ }
153
+ // --- Type resolution (delegated to core) ---
154
+ function resolvePropertyType(prop, schema) {
155
+ const shortName = cfnShortName(schema.typeName);
156
+ return coreResolvePropertyType(prop, schema, (defName) => `${shortName}_${defName}`);
157
+ }
158
+ function extractConstraints(prop) {
159
+ return coreExtractConstraints(prop);
160
+ }
161
+ export const constraintsIsEmpty = coreConstraintsIsEmpty;
162
+ function isEnumDefinition(def) {
163
+ return coreIsEnumDefinition(def);
164
+ }
165
+ /**
166
+ * Extract short resource name: "AWS::S3::Bucket" → "Bucket"
167
+ */
168
+ export function cfnShortName(typeName) {
169
+ const parts = typeName.split("::");
170
+ return parts.length >= 3 ? parts[2] : typeName;
171
+ }
172
+ /**
173
+ * Extract service name: "AWS::S3::Bucket" → "S3"
174
+ */
175
+ export function cfnServiceName(typeName) {
176
+ const parts = typeName.split("::");
177
+ return parts.length >= 2 ? parts[1] : typeName;
178
+ }
179
+ /** Bound on the `$ref` walk that resolves a definition-scoped pointer. */
180
+ const MAX_DEFINITION_PATH_DEPTH = 6;
181
+ /** The definition a `#/definitions/Name` ref names, or undefined for anything else. */
182
+ function refDefinitionName(ref) {
183
+ const prefix = "#/definitions/";
184
+ return ref?.startsWith(prefix) ? ref.slice(prefix.length) : undefined;
185
+ }
186
+ function pushProperties(queue, path, properties) {
187
+ for (const [name, prop] of Object.entries(properties))
188
+ queue.push({ path: [...path, name], node: prop });
189
+ }
190
+ /**
191
+ * The property path that reaches `defName`, searched breadth-first from the
192
+ * top-level properties so the shortest one wins. Undefined when nothing
193
+ * declared reaches the definition; the pointer is then left as the Registry
194
+ * wrote it rather than naming a key no template has.
195
+ */
196
+ function definitionPropertyPath(defName, schema) {
197
+ const defs = schema.definitions ?? {};
198
+ const expanded = new Set();
199
+ const queue = [];
200
+ pushProperties(queue, [], schema.properties ?? {});
201
+ while (queue.length > 0) {
202
+ const { path, node } = queue.shift();
203
+ if (path.length > MAX_DEFINITION_PATH_DEPTH)
204
+ continue;
205
+ const ref = refDefinitionName(node.$ref);
206
+ if (ref === defName)
207
+ return path.join("/");
208
+ if (ref !== undefined) {
209
+ // Shortest path wins, so a definition already reached needs no second visit.
210
+ if (expanded.has(ref))
211
+ continue;
212
+ expanded.add(ref);
213
+ const def = defs[ref];
214
+ if (def?.properties)
215
+ pushProperties(queue, path, def.properties);
216
+ continue;
217
+ }
218
+ if (node.items) {
219
+ queue.push({ path: [...path, "*"], node: node.items });
220
+ continue;
221
+ }
222
+ if (node.properties)
223
+ pushProperties(queue, path, node.properties);
224
+ }
225
+ return undefined;
226
+ }
227
+ /**
228
+ * Flatten a CloudFormation Registry JSON pointer to the property path a
229
+ * template expresses, `/`-joined.
230
+ *
231
+ * Three shapes occur upstream. `/properties/BucketName` is the plain one.
232
+ * A pointer can re-enter the `properties` keyword mid-path
233
+ * (`/properties/DistributionConfig/properties/S3Origin`), which a template
234
+ * never writes. And a pointer can be scoped to a shared definition
235
+ * (`/definitions/ContinuousDeploymentPolicyConfig/properties/Type`), which a
236
+ * template expresses only through whichever property carries that definition.
237
+ *
238
+ * Array positions stay as `*`. `readOnlyProperties` attribute names are
239
+ * generated from this output, so dropping the wildcard would rename them.
240
+ */
241
+ export function stripPointerPath(path, schema) {
242
+ if (!path.startsWith("/"))
243
+ return path;
244
+ const segments = path.split("/").filter((s) => s.length > 0);
245
+ if (segments[0] === "definitions") {
246
+ const prefix = segments[1] && schema ? definitionPropertyPath(segments[1], schema) : undefined;
247
+ if (prefix === undefined)
248
+ return path;
249
+ return [prefix, ...segments.slice(2).filter((s) => s !== "properties")].join("/");
250
+ }
251
+ if (segments[0] !== "properties")
252
+ return path;
253
+ return segments.slice(1).filter((s) => s !== "properties").join("/");
254
+ }
255
+ function stripPointerPaths(paths, schema) {
256
+ if (paths.length === 0)
257
+ return [];
258
+ return paths.map((p) => stripPointerPath(p, schema));
259
+ }
@@ -0,0 +1,185 @@
1
+ /**
2
+ * Content pin for the CloudFormation Registry schema (#1390).
3
+ *
4
+ * cfn-lint is pinned to a git tag (`PINNED_VERSIONS.cfnLint`). The registry
5
+ * schema could not be: it is a single "latest" artifact with no version in the
6
+ * path, republished constantly —
7
+ *
8
+ * $ curl -sI .../CloudformationSchema.zip
9
+ * Last-Modified: Mon, 03 Aug 2026 01:29:20 GMT
10
+ *
11
+ * — so `npm run --prefix lexicons/aws prepack`, which CI runs on every build and
12
+ * any local codegen or docs task triggers, resolved to whatever CloudFormation
13
+ * shipped that morning. During the #1312 docs work a docs-only branch twice
14
+ * picked up a resource-count move with nothing in the commit explaining it. The
15
+ * count was only the visible symptom; the same regeneration rewrites generated
16
+ * types and the resource registry.
17
+ *
18
+ * Since there is no version to pin, the pin is over content. Specifically over
19
+ * the **extracted schemas**, not the zip: AWS repackaging the archive changes
20
+ * its `ETag` and its bytes while the schemas are identical, and a pin that fires
21
+ * on that would be noise. Sorted `typeName` → `sha256(schema)`, hashed in order,
22
+ * moves exactly when a schema does.
23
+ *
24
+ * Advisory is not enough here, unlike the emulator image pins (#808). An
25
+ * emulator that drifts fails a test you can see; a spec that drifts silently
26
+ * rewrites committed artifacts in a branch about something else. So a mismatch
27
+ * refuses, and accepting is a deliberate act that lands as its own commit.
28
+ */
29
+ import { createHash } from "crypto";
30
+ import pinnedTypes from "./pinned-types.json" with { type: "json" };
31
+ /**
32
+ * The resource types the pinned archive contained.
33
+ *
34
+ * Committed beside the digest so accepting a new spec is reviewable as a diff:
35
+ * the PR that moves the pin shows exactly which types AWS added or removed,
36
+ * rather than one opaque hash replacing another. The generated artifacts cannot
37
+ * play that role — `src/generated/` is not committed.
38
+ */
39
+ export const PINNED_TYPE_NAMES = new Set(pinnedTypes);
40
+ /**
41
+ * The accepted upstream spec.
42
+ *
43
+ * To move it: run generation, read the refusal, confirm the delta is one you
44
+ * want, and paste the printed pin here in its own commit.
45
+ */
46
+ export const AWS_SPEC_PIN = {
47
+ digest: "sha256:398259716cca4a83d8ffc719fb214caf3ed6239c6be775e6d21952ce7ad8dae4",
48
+ resources: 1856,
49
+ accepted: "2026-10-19",
50
+ };
51
+ /** Env var that accepts whatever upstream currently serves, printing the new pin. */
52
+ export const ACCEPT_ENV = "CHANT_ACCEPT_AWS_SPEC";
53
+ /**
54
+ * Digest the extracted schemas. Stable against repackaging; changes when any
55
+ * schema's bytes change, or when a type is added or removed.
56
+ */
57
+ export function specContentDigest(schemas) {
58
+ const hash = createHash("sha256");
59
+ for (const typeName of [...schemas.keys()].sort()) {
60
+ hash.update(typeName);
61
+ hash.update(createHash("sha256").update(schemas.get(typeName)).digest());
62
+ }
63
+ return `sha256:${hash.digest("hex")}`;
64
+ }
65
+ /** Compare a freshly fetched archive against a pin. `null` when it matches. */
66
+ export function specDrift(schemas, pinnedNames, pin = AWS_SPEC_PIN) {
67
+ const digest = specContentDigest(schemas);
68
+ if (digest === pin.digest)
69
+ return null;
70
+ const names = new Set(schemas.keys());
71
+ return {
72
+ digest,
73
+ resources: names.size,
74
+ // Type names are only known when a caller supplies the previous set;
75
+ // without it the count delta still tells a reader the shape of the change.
76
+ added: pinnedNames ? [...names].filter((n) => !pinnedNames.has(n)).sort() : [],
77
+ removed: pinnedNames ? [...pinnedNames].filter((n) => !names.has(n)).sort() : [],
78
+ };
79
+ }
80
+ /** The refusal a mismatch produces, or the acceptance notice under {@link ACCEPT_ENV}. */
81
+ export function driftMessage(drift, pin = AWS_SPEC_PIN, options = {}) {
82
+ const fatal = options.fatal ?? true;
83
+ const delta = drift.resources - pin.resources;
84
+ const countLine = delta === 0
85
+ ? `${drift.resources} resource types, unchanged in count`
86
+ : `${drift.resources} resource types, ${delta > 0 ? "+" : ""}${delta} against the pin`;
87
+ const lines = [
88
+ "The upstream CloudFormation schema has moved since the pinned one.",
89
+ "",
90
+ ` pinned ${pin.digest} (${pin.resources} resources, accepted ${pin.accepted})`,
91
+ ` upstream ${drift.digest} (${countLine})`,
92
+ ];
93
+ if (drift.added.length > 0) {
94
+ lines.push(` added ${drift.added.slice(0, 5).join(", ")}${drift.added.length > 5 ? ` (+${drift.added.length - 5} more)` : ""}`);
95
+ }
96
+ if (drift.removed.length > 0) {
97
+ lines.push(` removed ${drift.removed.slice(0, 5).join(", ")}${drift.removed.length > 5 ? ` (+${drift.removed.length - 5} more)` : ""}`);
98
+ }
99
+ if (fatal) {
100
+ lines.push("", "Generation refuses rather than regenerating against a spec nobody chose:", "a docs or codegen task on an unrelated branch would otherwise rewrite the", "generated types and resource registry with no commit saying why.");
101
+ }
102
+ else {
103
+ // chant #1473 — the type set is identical, so this is upstream editing
104
+ // schemas in place, not a spec swap. Generation continues; whether it
105
+ // changed anything visible is decided by the surface snapshot.
106
+ lines.push("", "The resource set is unchanged, so this is upstream editing schemas in", "place rather than a different spec. Generation continues — whether it", "changed the published API is decided by surface.snapshot.json, which is", "checked against the generated artifacts before anything is packed.");
107
+ }
108
+ lines.push("", "To refresh the pin, confirm the delta is one you want and update", "lexicons/aws/src/spec/pin.ts, in its own commit:", "", ` digest: "${drift.digest}",`, ` resources: ${drift.resources},`, ` accepted: "<today>",`);
109
+ if (fatal) {
110
+ lines.push("", `Or re-run with ${ACCEPT_ENV}=1 to proceed this once and print the same block.`);
111
+ }
112
+ return lines.join("\n");
113
+ }
114
+ /**
115
+ * Refuse a fetched archive whose RESOURCE SET does not match the pin.
116
+ *
117
+ * Under {@link ACCEPT_ENV} it warns with the same detail instead, so the
118
+ * accept-then-paste loop is one command rather than two.
119
+ *
120
+ * ## Why byte drift alone is a warning (chant #1473)
121
+ *
122
+ * This originally threw on any digest mismatch, which made the aws lexicon
123
+ * unpublishable. `prepack` runs `generate`, `generate` fetches from upstream,
124
+ * and CloudFormation republishes individual schemas several times a day: three
125
+ * distinct digests were observed on 2026-08-03 alone, all with an unchanged
126
+ * count of 1650, and two fetches two hours apart differed in 4 of 1650 files.
127
+ * `chant-v0.39.0` published 13 packages and failed on aws for exactly this,
128
+ * with a pin ~18 hours old.
129
+ *
130
+ * A pin that goes stale by itself within hours cannot gate a release: it does
131
+ * not distinguish "someone regenerated against a spec nobody chose" from
132
+ * "AWS edited a description this afternoon".
133
+ *
134
+ * So the two cases are separated:
135
+ *
136
+ * - **The resource set moved** (a type added or removed) — still a refusal.
137
+ * That always changes the published API, and it is the case #1390 was filed
138
+ * about.
139
+ * - **Only bytes moved**, with an identical type set — a warning. Whether it
140
+ * matters is decided downstream by the surface gate in core's
141
+ * `validateLexiconArtifacts`, which compares the generated API against the
142
+ * committed `surface.snapshot.json`. That gate is exact: a byte change that
143
+ * alters the emitted surface fails the build, and one that does not is
144
+ * correctly ignored.
145
+ *
146
+ * The guarantee is unchanged in substance — nothing ships whose surface was
147
+ * not reviewed — and it is now enforced against the thing that actually
148
+ * matters rather than against an archive that is not stable enough to pin.
149
+ */
150
+ export function assertPinnedSpec(schemas, options = {}) {
151
+ const pin = options.pin ?? AWS_SPEC_PIN;
152
+ const pinnedNames = options.pinnedNames ?? PINNED_TYPE_NAMES;
153
+ const drift = specDrift(schemas, pinnedNames, pin);
154
+ if (!drift)
155
+ return;
156
+ const env = options.env ?? process.env;
157
+ const warn = options.warn ?? ((m) => console.error(m));
158
+ if (env[ACCEPT_ENV]) {
159
+ warn(driftMessage(drift, pin));
160
+ return;
161
+ }
162
+ // chant #1473 — an identical type set with different bytes is upstream
163
+ // churn, not an unchosen spec. Reported so a stale pin stays visible, but
164
+ // not fatal; the surface gate decides whether it changed anything.
165
+ //
166
+ // Guarded on actually HAVING a previous type set: `specDrift` reports empty
167
+ // added/removed when it has nothing to compare against, which would
168
+ // otherwise read as "no type moved" and downgrade every mismatch.
169
+ // chant #1473 — the pin reports, it does not gate.
170
+ //
171
+ // Refusing here made every aws PR hostage to CloudFormation: the archive
172
+ // gains and edits types through the day, and `generate` runs on every CI
173
+ // job, so an unrelated change goes red the moment upstream moves. Both the
174
+ // 0.39.0 and 0.40.1 releases died this way, and a PR *accepting* the drift
175
+ // was itself refused by a newer drift that arrived while its CI queued.
176
+ //
177
+ // Enforcement lives where the consequence is: core's
178
+ // `validateLexiconArtifacts` compares the generated API against the reviewed
179
+ // `surface.snapshot.json` and, armed by CHANT_RELEASE_GATE, refuses to
180
+ // publish a surface nobody reviewed. A new or removed type always shows up
181
+ // there, so nothing is lost by reporting rather than throwing here — while a
182
+ // description edit, which changes the digest and no declaration, stops
183
+ // costing a red build.
184
+ warn(driftMessage(drift, pin, { fatal: drift.added.length > 0 || drift.removed.length > 0 }));
185
+ }