cdk-preflight 0.0.40 → 0.0.42

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.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: add-preflight-rule
3
- description: cdk-preflight に新しいルールを追加する半自動パイプライン。制約の抽出(ドキュメント/エラーメッセージ)→ rule.rego と fail/pass テンプレート生成 → 重複ガードテスト → 実機再現ゲート → meta.yaml 記録 → PR 準備までを 1 セッションで行う。
3
+ description: cdk-preflight に新しいルールを追加する半自動パイプライン。制約の抽出(ドキュメント/エラーメッセージ)→ rule.rego と fail/pass テンプレート生成 → 重複ガードテスト → 実機再現ゲート → meta.yaml 記録 → PR 準備まで。候補が複数ある場合はフェーズごとにセッションを分ける(「セッションの切り方」参照)。
4
4
  ---
5
5
 
6
6
  # add-preflight-rule
@@ -33,3 +33,20 @@ cdk-preflight のルール追加パイプライン。AGENTS.md の設計原則
33
33
  - **予想と違う理由**で失敗した場合(他アカウントの ARN、ドメイン所有権の検証など)は証拠にならない。サービスエラーが対象の制約そのものを名指しするまでテンプレートを作り直すか、除去できない交絡は `evidence` に明記する
34
34
  - `doc-only` は「再現に安価に作れないリソース(検証済み ACM 証明書、所有ドメイン等)が要る」場合に限る最終手段であって、まだ試していない制約への近道ではない。詳細は AGENTS.md の "A doc sentence is a hypothesis, not evidence" に従う
35
35
  6. **仕上げ**: `npx projen build` 全緑 → ブランチ作成 → conventional commit(`feat(rules): add <rule-id>`)→ PR 本文に: 制約の出典 / 重複チェック結果 / 実機再現ログ。
36
+
37
+ ## セッションの切り方(コンテキスト予算)
38
+
39
+ API コストは **`往復回数 × 平均コンテキスト長`** でほぼ決まる(実測 2026-09-06: cache_read がトークン総量の 96%、AgentCore 回は 1,289 往復 × 平均 365k = 471M)。**1 サービスぶんを 1 セッションで通さない**。`find-preflight-rules` から `candidates.json` を受け取り、下の境界で `/clear` して scratchpad の `<service>/` 配下のファイルだけを引き継ぐ:
40
+
41
+ | フェーズ | 入口 | 出口 |
42
+ |---|---|---|
43
+ | ⑤ ルール生成+ローカルゲート | `candidates.json` | `rules/<service>/*`、`pending.txt`(実機ゲート待ちの rule id) |
44
+ | ⑥ 実機ゲート | `pending.txt` | `bench-out/<rule-id>.log`、`meta.yaml#repro.evidence` |
45
+ | ⑦ 仕上げ | ⑥ のログ | `pr-body.md` → commit / PR |
46
+
47
+ 守ること:
48
+
49
+ - **rule.rego と fail/pass テンプレートを 1 本ずつヒアドキュメントで書かない**。`candidates.json` を読むジェネレータ(`rgen.py` 相当)を 1 個置き、直しはジェネレータ側に入れて再生成する。実測では打ち込んだコマンド文字列のコストが Bash 出力とほぼ同額($318 対 $389)で、その 73% が 4k 超のヒアドキュメント
50
+ - **書いたファイルを `cat` で読み返さない**。確認は `npx projen bundle-rules` と `npx jest` の結果だけで足りる
51
+ - **実機ゲートは 1 本ずつ対話で回さない**。`pending.txt` を回す 1 スクリプトをバックグラウンドで走らせ、ログは `bench-out/<rule-id>.log` に書かせて、戻すのは 1 行のサマリだけにする。完了待ちのポーリングを 1 往復 1 回やらない(1 往復 ≒ 平均コンテキスト長ぶんの再読み込み)
52
+ - ⑤ で候補が数十本あるなら、ジェネレータの入力(`candidates.json`)を直すサイクルに寄せる。個別ルールのデバッグは失敗した数本に絞る
@@ -93,6 +93,28 @@ EOL ランタイム、廃止インスタンスタイプ、リージョン非対
93
93
  4. **issue に記録**。生き残った候補をチェックリストに、落ちた候補を理由つきで残す。落選理由を残すのが重要で、これが無いと次の担当が同じ調査を繰り返す
94
94
  5. **実装へ引き継ぐ**。採用候補 1 本ごとに `add-preflight-rule` を起動する。実機再現ゲートはそちら側の責務
95
95
 
96
+ ## セッションの切り方(コンテキスト予算)
97
+
98
+ このパイプラインの API コストは **`往復回数 × 平均コンテキスト長`** でほぼ決まる。実測(2026-09-06、過去のサービス調査ジョブのトランスクリプト集計)では cache_read がトークン総量の 96%: AgentCore 回が 1,289 往復 × 平均 365k = 471M、Bedrock 回が 461 往復 × 平均 274k = 126M。**1 往復あたりの固定費がコンテキスト長に比例する**ので、長いセッションを続けること自体が課金される。
99
+
100
+ 後段が必要とするのは前段の**成果ファイルだけ**で会話履歴ではない。フェーズ境界で `/clear` し、受け渡しは scratchpad の `<service>/` 配下のファイルに限る:
101
+
102
+ | フェーズ | 入口 | 出口 |
103
+ |---|---|---|
104
+ | ① 棚卸し | サービス名 | `inventory.md`(情報源 URL と拾った制約の生リスト) |
105
+ | ② 仮説列挙(6 レンズ) | `inventory.md` | `candidates.json`(1 件 = id / 制約文 / レンズ / 出典 / fail テンプレート) |
106
+ | ③ 重複ガード | `candidates.json` | `guard-out.txt` + 生き残りだけにした `candidates.json` |
107
+ | ④ issue コメント | ③ の出力 | `issue-comment.md` → 投稿。以降は `add-preflight-rule` へ |
108
+
109
+ ②→③ の境界が一番大きい。ドキュメント読みで膨らんだコンテキストは ③ 以降に一切要らない。① は「入力が巨大・出力は `inventory.md` だけ」という形なので subagent に投げてもよい。
110
+
111
+ 守ること:
112
+
113
+ - **ドキュメント本文をコンテキストに残さない**。`read_documentation` / WebFetch は 1 ページ 20〜30k 文字がそのまま以後の全往復ぶん再読みされる(実測で 1 セッション 53 回・$122 相当)。ファイルに落として grep で必要な段落だけ読む
114
+ - **同じテキストを二度載せない**。ヒアドキュメントで書く → `cat` で確認 → diff で再表示、で 3 倍払う。書いたものの確認は `wc -l` / `md5` / `assert` で済ませる。実測では**打ち込んだコマンド文字列のコストが出力とほぼ同額**($318 対 $389)で、その 73% は 4k 超のヒアドキュメント
115
+ - 候補テンプレートを 1 件ずつ手書きしない。`candidates.json` からジェネレータで吐き、重複ガードも 1 スクリプトで全件回してサマリ行だけ読む
116
+ - 独立した呼び出しは 1 レスポンスにまとめる(実測 1,289 往復中 848 がツール 1 個だけだった)
117
+
96
118
  ## issue コメントの書式
97
119
 
98
120
  ```markdown
package/.jsii CHANGED
@@ -9598,6 +9598,6 @@
9598
9598
  "symbolId": "src/index:PreflightOptions"
9599
9599
  }
9600
9600
  },
9601
- "version": "0.0.40",
9602
- "fingerprint": "PbEn3YhgIMxnTYEt8A4pmaqh3sYJbtevFgL42ipTfWM="
9601
+ "version": "0.0.42",
9602
+ "fingerprint": "YZM3lsbKPkJOC0NPtTQhrQ5N+CQuNHHl8gD7BlnxIvQ="
9603
9603
  }
package/AGENTS.md CHANGED
@@ -30,7 +30,7 @@ Five other validation layers sit around a CDK app. Exactly one of them is a boun
30
30
  | CDK L1 generated validators (`CfnXxx`) | synth, every CDK app | type and required-property checks only — never value ranges, patterns, or cross-field rules | **No practical overlap**: pack rules are value / cross-field constraints by construction |
31
31
  | Bundled engine default rules (`@aws/cloudformation-validate`: SCHEMA / CFN_LINT / ENGINE) | synth, via this plugin | patched registry-schema ranges/patterns/enums + cfn-lint rules | **The hard boundary** (principle 1) **and the only retirement trigger**. If the bare engine reports ERROR/FATAL on the minimal violating template, the rule must not exist — enforced by the jest duplication guard, which turns red by itself when the engine catches up |
32
32
  | cfn-lint (external CLI) | outside the synth path (a separate CI step, if the user runs one) | near-parity with the bundled engine | **Not a boundary** — never disqualifies a rule. A check cfn-lint has but the engine lacks is an upstream-PR candidate *for the engine* (project policy: contribute to cloudformation-validate, not to cfn-lint) |
33
- | CloudFormation server-side pre-deploy validation | CreateStack / UpdateStack / CreateChangeSet, before resources are touched | property syntax against RAW registry schemas for non-excluded types; resource name conflicts | **Effectively no overlap** with this pack's domain: ~420 resource types are excluded (IAM, EC2 SG, ECS, RDS, SFN, …) and raw schemas carry none of the doc-only limits — 0/16 real-world cases detected (measured 2026-09, cdk-validation-gap-research). Never a reason to reject a rule |
33
+ | CloudFormation server-side pre-deploy validation | CreateStack / UpdateStack / CreateChangeSet, before resources are touched | property syntax against RAW registry schemas for non-excluded types; resource name conflicts | **Almost no overlap** with this pack's domain: ~420 resource types are excluded (IAM, EC2 SG, ECS, RDS, SFN, …) and raw schemas carry none of the doc-only limits — 0/16 real-world cases detected (measured 2026-09, cdk-validation-gap-research). Not something to *look* for, but when it does fire it is a **retirement trigger** like the engine: a single-property range that the bundled schema misses can still be enforced here (`AWS::Kinesis::Stream.RetentionPeriodHours` < 24 fails as a stack-level `Validation failed with 1 error(s)`, measured 2026-09-06 — that candidate was dropped) |
34
34
  | CloudFormation + service APIs | deploy (CREATE/UPDATE) | everything else: cross-field rules, service-side business rules, quotas | **The target, not a duplicate to avoid.** A rule exists *iff* it front-runs a real deploy-time failure here; `meta.yaml#repro` (real-deploy gate) proves that equivalence |
35
35
 
36
36
  Selection algorithm for a new rule, in order: (1) duplication guard — run the minimal violating template through the bare engine; any built-in ERROR/FATAL kills the candidate. A **WARN-class-only** engine finding (`W…`) does *not* kill it but marks a gray zone: the engine knows about the constraint and under-classifies it, so nothing blocks the deploy (`strict` promotes only ERROR/FATAL) — prefer filing an upstream severity issue, and if a stopgap rule ships anyway, mark it `upstream: pending-engine` so it retires with the upstream fix. (2) real-deploy gate — the fail template must actually fail CREATE with the predicted service error; a fail template that deploys kills the candidate (it happened: the "30-day minimum before STANDARD_IA" and the "4096-char ZipFile" constraints are documented but not enforced, so those rules were dropped). There is no third gate: L1/L2 coverage, marginal value, and how exotic the mistake looks never disqualify a candidate.
@@ -172,7 +172,15 @@ bench/ # real-deploy verification (needs an AWS account; no
172
172
  - **Bench templates that create a VPC hit the 5-per-region VPC quota**: run those rules with low parallelism (`-P 2`) or a stack takes `The maximum number of VPCs has been reached` and the run is INCONCLUSIVE (measured 2026-09-06 with eight parallel EFS mount-target probes).
173
173
  - **Prefer a fail fixture whose resource is never created.** A stack that got as far as two EFS mount targets spends 20+ minutes in `ROLLBACK_IN_PROGRESS` (subnet and security-group deletion wait on the ENIs), which outruns `poll_terminal` and reports TIMEOUT / INCONCLUSIVE even though the constraint fired. Pick the branch that fails on the first call — for `pf-efs-mount-target-availability-zone` the One Zone mismatch instead of the duplicate zone — and cover the slower branch with an inline test (measured 2026-09-06).
174
174
  - **The CloudFormation handler can be stricter than the service API** (measured 2026-09-06): `CreateReplicationGroup` accepts a single-cluster ElastiCache group, but the same template through CloudFormation fails with "When using automatic failover, there must be at least 2 cache clusters" unless `AutomaticFailoverEnabled: false` is explicit — the handler turns failover on by default. An API probe that succeeds does not clear a candidate; deploy the template too.
175
+ - **A WASM trap poisons the engine for the rest of the process** (measured 2026-09-06). One bad template makes `validateDetailed` throw `RuntimeError: unreachable`, and *every subsequent template in the same process* throws the same thing — silently converting "the engine does not catch this" into "threw". A batch of 82 EC2 probes reported 70 spurious failures this way and would have hidden 70 live candidates. **Run one template per process** in duplication-guard sweeps; dropping the `cloudformation-validate` entries from `require.cache` and re-requiring does reset it, but it is far too slow to use for a sweep. Compile the probe into the repo (`.tmp/`, gitignored) rather than an outside directory — `loadEngine()` resolves `@aws/cloudformation-validate` through the repo's `node_modules` and returns `undefined` from elsewhere.
176
+ - **A malformed identifier in a probe fixture is reported as an engine detection** (measured 2026-09-06). `VpcId: "vpc-1"` yields `E1151 'vpc-1' does not match format 'AWS::EC2::VPC.Id'` (ids need 8 or 17 hex chars, e.g. `vpc-11112222`), which reads exactly like the candidate being covered — two EC2 hypotheses (`GroupName: default`, ICMP type/code) were nearly recorded as Rejected on that basis and are clean once the id is valid. **Pair every probe with a control template that differs only in the property under test**; if the control is also flagged, the finding is about the fixture.
175
177
  - **A probe that "should fail" can create an expensive resource**: `create-cache-cluster --num-cache-nodes 41` was accepted (the documented cap of 40 is not enforced) and ElastiCache/MemoryDB refuse `delete-*` until the cluster reaches `available`, so the 41 nodes ran for ~20 minutes. Quantity and limit probes belong in CloudFormation (a rollback deletes what it made); when probing the API directly, arm a wait-then-delete loop in the same breath (measured 2026-09-06).
176
178
  - **Fixture name tagging must skip reference properties.** The generator that suffixes fixture names with the rule id has to key off the resource type: `ACLName` is the name on `AWS::MemoryDB::ACL` but a *reference* on `AWS::MemoryDB::Cluster`, and tagging it made every MemoryDB pass template fail with "ACL open-access-port not found" (measured 2026-09-06). Same for `ParameterGroupName` / `CacheParameterGroupName`.
177
179
  - **`bench/verify-rule.sh` polls for 30 minutes** (raised from 15 on 2026-09-06): ElastiCache and MemoryDB clusters take 10-25 minutes to create and about as long to roll back, and the shorter poll reported TIMEOUT / INCONCLUSIVE on rules whose constraint had already fired.
178
180
  - **Probing the raw engine with custom rules**: the rule set must be named `violation` (`data.<pkg>.violation` is looked up; a `diagnostics` set fails with "not a valid rule path"), and hand-built diagnostic objects need lowercase severities (`error`, not `ERROR`/`CUSTOM` — those are display labels added by the wrapper). Pack rules never see this because `make_diag_full` handles the shape.
181
+ - **`as` is a reserved keyword in the engine's Rego build** (measured 2026-09-06): `acts := object.get(s, "Action", null)` is fine but `as := ...` fails to parse ("unexpected keyword `as`") and, like every parse error, takes the whole custom package down — every rule stops firing, and the jest failure names an unrelated rule.
182
+ - **A Managed Flink application deploys with no `ApplicationConfiguration` at all** (measured 2026-09-06), which is what makes `AWS::KinesisAnalyticsV2::Application` fixtures cheap: no S3 bucket, no JAR, no Glue database, just an IAM role the service can assume. Adding a "minimal" code stanza is worse than none — CreateApplication really fetches the S3 object (`We are unable to get the specified fileKey`) and rejects `PLAINTEXT` for a Flink runtime.
183
+ - **A Studio (ZEPPELIN-FLINK) application cannot be created without `glue:GetDatabase` on its service role**, so a Studio *pass* fixture is expensive. Every Studio-specific check (application mode, snapshots, system rollback, custom artifacts, catalog region, note JSON) fires before the Glue call, so the fail fixture can be a Studio app while the clean fixture stays a plain Flink app (measured 2026-09-06).
184
+ - **The CloudFormation handler can word the same rejection differently from the API** (measured 2026-09-06): CreateStream says `ShardCount cannot be set while creating stream in On-Demand StreamMode`, the stack event says `ShardCount is not expected when StreamMode=ON_DEMAND`. Quote the handler's wording in the rule message — that is the string the user will search for.
185
+ - **Kinesis rejects a cross-region ARN before it looks the resource up** ("The region specified in the ARN ... does not match the endpoint region", measured 2026-09-06 for `RegisterStreamConsumer` and `PutResourcePolicy`; `StartStreamEncryption` answers `KMSNotFoundException: Invalid arn us-west-2`). A region-binding repro therefore needs no real resource in the other region.
186
+ - **CloudFormation's server-side validation does enforce some raw-schema ranges the bundled engine misses** (measured 2026-09-06): `RetentionPeriodHours: 12` on `AWS::Kinesis::Stream` fails before any resource is touched, as a stack-level `Validation failed with 1 error(s). Call DescribeEvents ...` with the stack itself as the LogicalResourceId — while the engine's patched schema carries only the 8760 maximum. A fail template that dies at the *stack* level rather than in a resource handler is the tell; the candidate is a duplicate and does not ship.
package/docs/rules.md CHANGED
@@ -41,6 +41,87 @@
41
41
  | `pf-batch-retry-attempts` | AWS::Batch::JobDefinition | RetryStrategy.Attempts may not exceed 10 | none |
42
42
  | `pf-batch-timeout-minimum` | AWS::Batch::JobDefinition | Timeout.AttemptDurationSeconds must be at least 60 | none |
43
43
  | `pf-batch-unmanaged-fargate` | AWS::Batch::ComputeEnvironment | UNMANAGED compute environments cannot be Fargate | none |
44
+ | `pf-bedrock-automated-reasoning-policy-names-unique` | AWS::Bedrock::AutomatedReasoningPolicy | Names and ids inside a policy definition must be unique | none |
45
+ | `pf-bedrock-automated-reasoning-policy-variable-type` | AWS::Bedrock::AutomatedReasoningPolicy | Policy variables must use a type declared in PolicyDefinition.Types | none |
46
+ | `pf-bedrock-automated-reasoning-policy-version` | AWS::Bedrock::AutomatedReasoningPolicy | PolicyDefinition.Version must be 1.0 | none |
47
+ | `pf-bedrock-bda-blueprint-schema` | AWS::Bedrock::Blueprint | A blueprint schema needs class, description and properties | none |
48
+ | `pf-bedrock-bda-project-blueprint-region` | AWS::Bedrock::DataAutomationProject | Blueprints must live in the project's Region | none |
49
+ | `pf-bedrock-bda-project-blueprint-stage` | AWS::Bedrock::DataAutomationProject<br>AWS::Bedrock::Blueprint | Blueprint references must name a stage or version the blueprint has | none |
50
+ | `pf-bedrock-bda-project-blueprints-unique` | AWS::Bedrock::DataAutomationProject<br>AWS::Bedrock::Blueprint | A project must not attach the same blueprint twice | none |
51
+ | `pf-bedrock-bda-project-modality-routing` | AWS::Bedrock::DataAutomationProject | Modality routing overrides must fit the file type | none |
52
+ | `pf-bedrock-bda-project-output-types` | AWS::Bedrock::DataAutomationProject | Document granularity and text-format type lists must not be empty | none |
53
+ | `pf-bedrock-bda-project-standard-output-required` | AWS::Bedrock::DataAutomationProject | A Data Automation project needs StandardOutputConfiguration | none |
54
+ | `pf-bedrock-bda-project-sync-modalities` | AWS::Bedrock::DataAutomationProject | A SYNC project cannot configure audio or video standard output | none |
55
+ | `pf-bedrock-bda-project-transcript-configuration` | AWS::Bedrock::DataAutomationProject | Audio transcript settings need TRANSCRIPT among the extraction types | none |
56
+ | `pf-bedrock-datasource-chunk-max-tokens` | AWS::Bedrock::DataSource | Fixed-size and semantic chunks are limited to 8192 tokens | none |
57
+ | `pf-bedrock-datasource-chunk-tokens-embedding-limit` | AWS::Bedrock::DataSource<br>AWS::Bedrock::KnowledgeBase | Chunk size must not exceed the embedding model's token limit | none |
58
+ | `pf-bedrock-datasource-chunking-configuration` | AWS::Bedrock::DataSource | ChunkingStrategy needs its matching configuration block | none |
59
+ | `pf-bedrock-datasource-context-enrichment-neptune` | AWS::Bedrock::DataSource<br>AWS::Bedrock::KnowledgeBase | Context enrichment is only available on Neptune Analytics knowledge bases | none |
60
+ | `pf-bedrock-datasource-hierarchical-levels` | AWS::Bedrock::DataSource | Hierarchical chunking levels must descend and OverlapTokens must stay below the child size | none |
61
+ | `pf-bedrock-datasource-multimodal-supplemental-storage` | AWS::Bedrock::DataSource<br>AWS::Bedrock::KnowledgeBase | Multimodal parsing needs supplemental data storage on the knowledge base | none |
62
+ | `pf-bedrock-datasource-parsing-configuration` | AWS::Bedrock::DataSource | BEDROCK_FOUNDATION_MODEL parsing needs BedrockFoundationModelConfiguration | none |
63
+ | `pf-bedrock-datasource-parsing-model-region` | AWS::Bedrock::DataSource | The parsing model must be reachable from the data source's Region | none |
64
+ | `pf-bedrock-datasource-supplemental-bucket-overlap` | AWS::Bedrock::DataSource<br>AWS::Bedrock::KnowledgeBase | A data source must not share its bucket with the knowledge base's supplemental storage unless it has an inclusion prefix | none |
65
+ | `pf-bedrock-datasource-transformation-bucket` | AWS::Bedrock::DataSource | Custom transformation intermediate storage must not use the data source bucket | none |
66
+ | `pf-bedrock-datasource-type-configuration` | AWS::Bedrock::DataSource | DataSourceConfiguration.Type needs its matching configuration block | none |
67
+ | `pf-bedrock-datasource-web-vector-store` | AWS::Bedrock::DataSource<br>AWS::Bedrock::KnowledgeBase | A web crawler data source needs an OpenSearch Serverless knowledge base | none |
68
+ | `pf-bedrock-flow-condition-default` | AWS::Bedrock::Flow | A Condition node needs a default condition | none |
69
+ | `pf-bedrock-flow-condition-unique` | AWS::Bedrock::Flow | Conditions within a Condition node need unique names and expressions | none |
70
+ | `pf-bedrock-flow-connection-condition` | AWS::Bedrock::Flow | A Conditional connection must leave a Condition node through one of its conditions | none |
71
+ | `pf-bedrock-flow-connection-name-unique` | AWS::Bedrock::Flow | Flow connection names must be unique | none |
72
+ | `pf-bedrock-flow-connection-nodes` | AWS::Bedrock::Flow | Flow connections must reference nodes that exist | none |
73
+ | `pf-bedrock-flow-connection-ports` | AWS::Bedrock::Flow | Data connections must use outputs and inputs the nodes declare | none |
74
+ | `pf-bedrock-flow-definition-source` | AWS::Bedrock::Flow | A flow takes exactly one of Definition, DefinitionString or DefinitionS3Location | none |
75
+ | `pf-bedrock-flow-definition-string-json` | AWS::Bedrock::Flow | DefinitionString must be JSON | none |
76
+ | `pf-bedrock-flow-input-expression` | AWS::Bedrock::Flow | A node input Expression must start with $.data | none |
77
+ | `pf-bedrock-flow-input-node` | AWS::Bedrock::Flow | A flow has exactly one Input node | none |
78
+ | `pf-bedrock-flow-input-node-output` | AWS::Bedrock::Flow | The Input node exposes a single output named document | none |
79
+ | `pf-bedrock-flow-input-single-connection` | AWS::Bedrock::Flow | A node input accepts a single incoming connection | none |
80
+ | `pf-bedrock-flow-node-configuration` | AWS::Bedrock::Flow | A flow node needs the Configuration member named after its Type | none |
81
+ | `pf-bedrock-flow-node-name-unique` | AWS::Bedrock::Flow | Flow node names must be unique | none |
82
+ | `pf-bedrock-guardrail-automated-reasoning-cross-region` | AWS::Bedrock::Guardrail | Automated Reasoning checks need CrossRegionConfig | none |
83
+ | `pf-bedrock-guardrail-automated-reasoning-policy-region` | AWS::Bedrock::Guardrail | An Automated Reasoning policy must live in the guardrail's Region | none |
84
+ | `pf-bedrock-guardrail-content-filter-unique` | AWS::Bedrock::Guardrail | A guardrail content policy must not list the same filter type twice | none |
85
+ | `pf-bedrock-guardrail-grounding-filter-unique` | AWS::Bedrock::Guardrail | A contextual grounding policy must not list the same filter type twice | none |
86
+ | `pf-bedrock-guardrail-grounding-threshold` | AWS::Bedrock::Guardrail | A contextual grounding threshold must be below 1 | none |
87
+ | `pf-bedrock-guardrail-managed-word-list-unique` | AWS::Bedrock::Guardrail | A guardrail must not list the same managed word list twice | none |
88
+ | `pf-bedrock-guardrail-pii-entity-unique` | AWS::Bedrock::Guardrail | A guardrail must not configure the same PII entity type twice | none |
89
+ | `pf-bedrock-guardrail-policy-required` | AWS::Bedrock::Guardrail | A guardrail needs at least one policy | none |
90
+ | `pf-bedrock-guardrail-profile-account` | AWS::Bedrock::Guardrail | A guardrail profile ARN must carry the deploying account | none |
91
+ | `pf-bedrock-guardrail-profile-geo` | AWS::Bedrock::Guardrail | A guardrail profile must belong to the deploy Region's geography | none |
92
+ | `pf-bedrock-guardrail-profile-region` | AWS::Bedrock::Guardrail | A guardrail profile ARN must carry the guardrail's own Region | none |
93
+ | `pf-bedrock-guardrail-prompt-attack-output-strength` | AWS::Bedrock::Guardrail | The PROMPT_ATTACK content filter must use OutputStrength NONE | none |
94
+ | `pf-bedrock-guardrail-regex-pattern-length` | AWS::Bedrock::Guardrail | A guardrail regex pattern is limited to 500 characters | none |
95
+ | `pf-bedrock-guardrail-regex-unique` | AWS::Bedrock::Guardrail | Guardrail regex filters must have unique names and unique patterns | none |
96
+ | `pf-bedrock-guardrail-standard-tier-cross-region` | AWS::Bedrock::Guardrail | The STANDARD safeguard tier needs CrossRegionConfig | none |
97
+ | `pf-bedrock-guardrail-topic-definition-length` | AWS::Bedrock::Guardrail | A denied topic definition is limited to 200 characters on the CLASSIC tier | none |
98
+ | `pf-bedrock-guardrail-topic-name-unique` | AWS::Bedrock::Guardrail | Denied topic names within a guardrail must be unique | none |
99
+ | `pf-bedrock-guardrail-word-length` | AWS::Bedrock::Guardrail | A guardrail custom word is limited to 100 characters | none |
100
+ | `pf-bedrock-guardrail-word-unique` | AWS::Bedrock::Guardrail | Guardrail custom words must be unique (case-insensitively) | none |
101
+ | `pf-bedrock-inference-profile-model-source-required` | AWS::Bedrock::ApplicationInferenceProfile | An application inference profile needs ModelSource | none |
102
+ | `pf-bedrock-inference-profile-source-region` | AWS::Bedrock::ApplicationInferenceProfile | An application inference profile copies from a model or profile of its own Region | none |
103
+ | `pf-bedrock-kb-embedding-binary` | AWS::Bedrock::KnowledgeBase | BINARY embeddings need a model and a vector store that support them | none |
104
+ | `pf-bedrock-kb-embedding-dimensions` | AWS::Bedrock::KnowledgeBase | Embedding Dimensions must be a size the embedding model supports | none |
105
+ | `pf-bedrock-kb-embedding-model-region` | AWS::Bedrock::KnowledgeBase | The embedding model ARN must carry the knowledge base's Region | none |
106
+ | `pf-bedrock-kb-s3-vectors-index-dimension` | AWS::Bedrock::KnowledgeBase | The embedding size must equal the S3 Vectors index Dimension | none |
107
+ | `pf-bedrock-kb-sql-auth-configuration` | AWS::Bedrock::KnowledgeBase | Redshift AuthConfiguration must carry exactly the fields its Type needs | none |
108
+ | `pf-bedrock-kb-sql-query-engine-configuration` | AWS::Bedrock::KnowledgeBase | A Redshift query engine needs the block matching its Type | none |
109
+ | `pf-bedrock-kb-sql-storage-configuration` | AWS::Bedrock::KnowledgeBase | A Redshift storage configuration needs the block matching its Type | none |
110
+ | `pf-bedrock-kb-storage-not-allowed` | AWS::Bedrock::KnowledgeBase | KENDRA and SQL knowledge bases must not carry StorageConfiguration | none |
111
+ | `pf-bedrock-kb-storage-type-configuration` | AWS::Bedrock::KnowledgeBase | StorageConfiguration.Type needs its matching configuration block | none |
112
+ | `pf-bedrock-kb-supplemental-storage-uri` | AWS::Bedrock::KnowledgeBase | Supplemental data storage must point at an S3 bucket root | none |
113
+ | `pf-bedrock-kb-type-configuration` | AWS::Bedrock::KnowledgeBase | KnowledgeBaseConfiguration.Type needs its matching configuration block | none |
114
+ | `pf-bedrock-kb-vector-storage-required` | AWS::Bedrock::KnowledgeBase | A VECTOR knowledge base needs StorageConfiguration | none |
115
+ | `pf-bedrock-kb-vector-store-region` | AWS::Bedrock::KnowledgeBase | An S3 Vectors index must live in the knowledge base's Region | none |
116
+ | `pf-bedrock-prompt-default-variant` | AWS::Bedrock::Prompt | DefaultVariant must name one of the prompt's variants | none |
117
+ | `pf-bedrock-prompt-router-fallback-model` | AWS::Bedrock::IntelligentPromptRouter | The prompt router's fallback model must be one of its routed models | none |
118
+ | `pf-bedrock-prompt-router-model-provider` | AWS::Bedrock::IntelligentPromptRouter | A prompt router's models must come from the same provider | none |
119
+ | `pf-bedrock-prompt-router-model-region` | AWS::Bedrock::IntelligentPromptRouter | Prompt router models must be reachable from the deploy Region | none |
120
+ | `pf-bedrock-prompt-router-models-count` | AWS::Bedrock::IntelligentPromptRouter | A prompt router routes between exactly two models | none |
121
+ | `pf-bedrock-prompt-router-models-unique` | AWS::Bedrock::IntelligentPromptRouter | A prompt router must not list the same model twice | none |
122
+ | `pf-bedrock-prompt-variant-model-or-agent` | AWS::Bedrock::Prompt | A prompt variant takes either ModelId or GenAiResource, not both | none |
123
+ | `pf-bedrock-prompt-variant-name-unique` | AWS::Bedrock::Prompt | Prompt variant names must be unique | none |
124
+ | `pf-bedrock-prompt-variant-template-type` | AWS::Bedrock::Prompt | A prompt variant's TemplateConfiguration must match its TemplateType | none |
44
125
  | `pf-agentcore-apikey-provider-secret-source` | AWS::BedrockAgentCore::ApiKeyCredentialProvider | An API key credential provider takes ApiKey when the secret is MANAGED and ApiKeySecretConfig when it is EXTERNAL, never both | none |
45
126
  | `pf-agentcore-config-bundle-components-empty` | AWS::BedrockAgentCore::ConfigurationBundle | A configuration bundle needs at least one component | none |
46
127
  | `pf-agentcore-dataset-source-exactly-one` | AWS::BedrockAgentCore::Dataset | Dataset Source must hold exactly one of InlineExamples or S3Source | none |
@@ -252,6 +333,39 @@
252
333
  | `pf-iam-policy-version` | AWS::IAM::Role<br>AWS::IAM::Policy<br>AWS::IAM::ManagedPolicy | Policy Version must be 2012-10-17 or 2008-10-17 | none |
253
334
  | `pf-iam-trust-policy-no-resource` | AWS::IAM::Role | Trust policies cannot carry a Resource field | none |
254
335
  | `pf-iam-trust-policy-service-principal` | AWS::IAM::Role | Service principals live under amazonaws.com | none |
336
+ | `pf-kinesis-consumer-duplicate-name` | AWS::Kinesis::StreamConsumer | Two consumers of one stream cannot share a ConsumerName | none |
337
+ | `pf-kinesis-consumer-stream-region` | AWS::Kinesis::StreamConsumer | A stream consumer must reference a stream in its own region | none |
338
+ | `pf-kinesis-encryption-key-region` | AWS::Kinesis::Stream | The stream encryption key must live in the stream region | none |
339
+ | `pf-kinesis-on-demand-shard-count` | AWS::Kinesis::Stream | An on-demand stream cannot set ShardCount | none |
340
+ | `pf-kinesis-provisioned-shard-count` | AWS::Kinesis::Stream | A provisioned stream must set ShardCount | none |
341
+ | `pf-kinesis-resource-policy-action` | AWS::Kinesis::ResourcePolicy | Resource policy actions must be plain kinesis: actions | none |
342
+ | `pf-kinesis-resource-policy-principal` | AWS::Kinesis::ResourcePolicy | Every policy statement needs a Principal (and no NotPrincipal) | none |
343
+ | `pf-kinesis-resource-policy-region` | AWS::Kinesis::ResourcePolicy | A resource policy must target a stream in its own region | none |
344
+ | `pf-kinesis-resource-policy-resource` | AWS::Kinesis::ResourcePolicy | Every policy statement Resource must equal the ResourceArn | none |
345
+ | `pf-kinesis-shard-level-metrics-all` | AWS::Kinesis::Stream | DesiredShardLevelMetrics cannot mix ALL with named metrics | none |
346
+ | `pf-kinesis-warm-throughput-shard-count` | AWS::Kinesis::Stream | WarmThroughputMiBps cannot be combined with ShardCount or provisioned mode | none |
347
+ | `pf-kinesisanalytics-application-mode-runtime` | AWS::KinesisAnalyticsV2::Application | ApplicationMode must match the runtime family | none |
348
+ | `pf-kinesisanalytics-checkpoint-configuration-type` | AWS::KinesisAnalyticsV2::Application | CheckpointConfiguration needs ConfigurationType CUSTOM to carry values | none |
349
+ | `pf-kinesisanalytics-code-content-member` | AWS::KinesisAnalyticsV2::Application | CodeContent must carry exactly the member its type names | none |
350
+ | `pf-kinesisanalytics-code-content-type` | AWS::KinesisAnalyticsV2::Application | CodeContentType must match the runtime family | none |
351
+ | `pf-kinesisanalytics-custom-artifact-source` | AWS::KinesisAnalyticsV2::Application | Every Studio custom artifact needs an S3 location or a Maven reference | none |
352
+ | `pf-kinesisanalytics-encryption-key-type` | AWS::KinesisAnalyticsV2::Application | KeyId presence must match the encryption KeyType | none |
353
+ | `pf-kinesisanalytics-glue-database-region` | AWS::KinesisAnalyticsV2::Application | The Studio Glue catalog database must be in the application region | none |
354
+ | `pf-kinesisanalytics-log-stream-arn` | AWS::KinesisAnalyticsV2::ApplicationCloudWatchLoggingOption | LogStreamARN must name a log stream, not a log group | none |
355
+ | `pf-kinesisanalytics-maven-artifact-type` | AWS::KinesisAnalyticsV2::Application | MavenReference is only valid for DEPENDENCY_JAR artifacts | none |
356
+ | `pf-kinesisanalytics-monitoring-configuration-type` | AWS::KinesisAnalyticsV2::Application | MonitoringConfiguration needs ConfigurationType CUSTOM to carry values | none |
357
+ | `pf-kinesisanalytics-parallelism-configuration-type` | AWS::KinesisAnalyticsV2::Application | ParallelismConfiguration needs ConfigurationType CUSTOM to carry values | none |
358
+ | `pf-kinesisanalytics-parallelism-per-kpu` | AWS::KinesisAnalyticsV2::Application | ParallelismPerKPU cannot exceed 8 | none |
359
+ | `pf-kinesisanalytics-property-group-duplicate` | AWS::KinesisAnalyticsV2::Application | PropertyGroupId must be unique within an application | none |
360
+ | `pf-kinesisanalytics-runtime-deprecated` | AWS::KinesisAnalyticsV2::Application | Deprecated runtime environments can no longer be created | none |
361
+ | `pf-kinesisanalytics-service-role-account` | AWS::KinesisAnalyticsV2::Application | ServiceExecutionRole must belong to the deploying account | none |
362
+ | `pf-kinesisanalytics-snapshot-runtime` | AWS::KinesisAnalyticsV2::Application | ApplicationSnapshotConfiguration is not applicable to Studio runtimes | none |
363
+ | `pf-kinesisanalytics-sql-configuration-runtime` | AWS::KinesisAnalyticsV2::Application | SqlApplicationConfiguration belongs to the SQL runtime only | none |
364
+ | `pf-kinesisanalytics-sql-only-resource` | AWS::KinesisAnalyticsV2::ApplicationOutput<br>AWS::KinesisAnalyticsV2::ApplicationReferenceDataSource | Outputs and reference data sources need a SQL application | none |
365
+ | `pf-kinesisanalytics-sql-runtime-unsupported` | AWS::KinesisAnalyticsV2::Application | SQL applications can no longer be created | none |
366
+ | `pf-kinesisanalytics-system-rollback-runtime` | AWS::KinesisAnalyticsV2::Application | ApplicationSystemRollbackConfiguration is not applicable to Studio runtimes | none |
367
+ | `pf-kinesisanalytics-zeppelin-configuration-runtime` | AWS::KinesisAnalyticsV2::Application | ZeppelinApplicationConfiguration belongs to Studio runtimes only | none |
368
+ | `pf-kinesisanalytics-zeppelin-note-json` | AWS::KinesisAnalyticsV2::Application | Studio TextContent must be a Zeppelin note JSON | none |
255
369
  | `pf-kms-alias-name` | AWS::KMS::Alias | AliasName must not start with alias/aws/ (reserved for AWS managed keys) and may not contain a colon (the CloudFormation schema allows it, CreateAlias does not) | none |
256
370
  | `pf-kms-alias-target` | AWS::KMS::Alias | TargetKeyId must be a key id or key ARN (not an alias) of a key in the same account and region | none |
257
371
  | `pf-kms-key-origin` | AWS::KMS::Key | Origin AWS_CLOUDHSM and EXTERNAL_KEY_STORE cannot be created by CloudFormation, and Origin EXTERNAL does not support ML-DSA key specs | none |
package/lib/index.js CHANGED
@@ -17,7 +17,7 @@ const rules_generated_1 = require("./rules.generated");
17
17
  * Preflight.apply(app);
18
18
  */
19
19
  class Preflight {
20
- static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk-preflight.Preflight", version: "0.0.40" };
20
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk-preflight.Preflight", version: "0.0.42" };
21
21
  /**
22
22
  * Register the cdk-preflight rules on an App or Stage.
23
23
  */