cdk-preflight 0.0.98 → 0.0.100
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.
- package/.claude/skills/add-preflight-rule/SKILL.md +2 -1
- package/.jsii +2 -2
- package/AGENTS.md +1 -1
- package/lib/index.js +1 -1
- package/package.json +1 -1
|
@@ -25,8 +25,9 @@ cdk-preflight のルール追加パイプライン。AGENTS.md の設計原則
|
|
|
25
25
|
- `walk` ビルトインは無い。`to_number`/`object.get`/`flatten_list`/`resolve` で明示的に書く
|
|
26
26
|
- fail テンプレートはこのルール**だけ**に違反、pass テンプレートは完全クリーン
|
|
27
27
|
- **数値・長さ・個数の制約は境界ちょうどで書く**。fail は「違反する値のうち限界に最も近いもの」、pass は「限界そのもの」— 20 文字下限なら fail=19 文字 / pass=20 文字であって、fail=5 文字 / pass=26 文字ではない。緩いペアはルールの向きしか証明しない(`count(v) < 20` は fail が 5 文字なら定数が `< 10` でも鳴り、pass が 26 文字なら `< 25` でも黙る)ので、定数も比較演算子も固定できないし、実機ゲートの証拠も弱くなる(19 文字が CREATE に失敗して初めて下限 20 が実証される)。ルールが両端を見ているレンジは fail に両端を置く(fail の判定は「自分のルールの診断が 1 件以上」なので、違反リソースを 2 つ並べてよい)。エンジンのスキーマが既に持っている側の端は入れない — ルールもそこは見ていない(原則 1)し、重複ガードが赤くなる。順序の無い制約(プロパティ欠落、enum の値違い、リソース間の不整合)には境界が無いので対象外
|
|
28
|
-
4. **ローカルゲート**: まず `npx ts-node --transpile-only --project test/tsconfig.json scripts/rule-check.ts check <service|rule-id>...` を回す。`rules/` を直接読んで 1 エンジンに全ルールを載せ、fail が自分のルールで鳴るか / pass が全ルール無音か / どちらも組み込みエンジンに止められないかを返す(`bundle-rules` も meta.yaml の evidence も要らないので、実機ゲート前の直しはここで回す。80 本で数秒)。全部 `ok` になってから `npx projen bundle-rules && npx jest test/rules.test.ts test/structure.test.ts
|
|
28
|
+
4. **ローカルゲート**: まず `npx ts-node --transpile-only --project test/tsconfig.json scripts/rule-check.ts check <service|rule-id>...` を回す。`rules/` を直接読んで 1 エンジンに全ルールを載せ、fail が自分のルールで鳴るか / pass が全ルール無音か / どちらも組み込みエンジンに止められないかを返す(`bundle-rules` も meta.yaml の evidence も要らないので、実機ゲート前の直しはここで回す。80 本で数秒)。全部 `ok` になってから `npx projen bundle-rules && npx jest test/rules.test.ts test/structure.test.ts`。`structure.test.ts` は手順 3 の境界値を機械で見る(rego のしきい値ごとに fail へ「限界に最も近い違反値」、pass へ「限界そのもの」が現れるか)。しきい値の検出が意味を持たないルールだけ `rules/_boundary-exceptions.txt` に理由付きで逃がす。**jest は `-t` で対象を絞る**。フルスイートは PR 直前の 1 回だけでよく、実測では 401 回中 73 回がフル実行で合計 5.8 時間を溶かしている。
|
|
29
29
|
5. **実機再現ゲート**: `bash bench/verify-rule.sh <rule-id>`(要 AWS 認証)。観測したエラーメッセージと日付を `meta.yaml#repro.evidence` に記録。
|
|
30
|
+
- **evidence には実際にデプロイした値を書く**(`bench 2026-09-13 us-east-1: 19-char Value -> "...at least 20 characters" (ROLLBACK_COMPLETE); pass 20-char -> CREATE_COMPLETE`)。境界ちょうどのフィクスチャと組で、限界の位置そのものが meta.yaml から読める
|
|
30
31
|
- fail テンプレートがデプロイに**成功**したら、それはドキュメント側の誤り(BROKEN-EXPECTATION)。ルールを削除し、証拠を issue に残して終了する。CloudFront では明文化された制約 9 件中 3 件がこれだった(2026-09-02)
|
|
31
32
|
- **予想と違う理由**で失敗した場合(他アカウントの ARN、ドメイン所有権の検証など)は証拠にならない。サービスエラーが対象の制約そのものを名指しするまでテンプレートを作り直すか、除去できない交絡は `evidence` に明記する
|
|
32
33
|
- `doc-only` は「再現に安価に作れないリソース(検証済み ACM 証明書、所有ドメイン等)が要る」場合に限る最終手段であって、まだ試していない制約への近道ではない。詳細は AGENTS.md の "A doc sentence is a hypothesis, not evidence" に従う
|
package/.jsii
CHANGED
|
@@ -9600,6 +9600,6 @@
|
|
|
9600
9600
|
"symbolId": "src/index:PreflightOptions"
|
|
9601
9601
|
}
|
|
9602
9602
|
},
|
|
9603
|
-
"version": "0.0.
|
|
9604
|
-
"fingerprint": "
|
|
9603
|
+
"version": "0.0.100",
|
|
9604
|
+
"fingerprint": "KaDvYx/SJkGYWImXLsYyQKSHZH2dMOuJxpmwnaxZRfk="
|
|
9605
9605
|
}
|
package/AGENTS.md
CHANGED
|
@@ -17,7 +17,7 @@ Growth is the normal state. The upstream engine ships slowly and carefully by de
|
|
|
17
17
|
1. **No duplication of the engine.** If the bundled engine already reports a constraint as ERROR/FATAL (schema check or built-in rule), we must not re-implement it. `test/rules.test.ts` enforces this mechanically ("does not duplicate a built-in blocker"). If that test fails for a new rule, the rule is unnecessary — delete it and record why in the PR.
|
|
18
18
|
2. **Every rule ships with proof.** `templates/fail.template.json` must violate exactly this rule; `templates/pass.template.json` must be clean. `meta.yaml#repro` records how the deploy-time failure was verified (`real-deploy` / `research-case` / `doc-only` — the last one requires an explanation in `evidence`).
|
|
19
19
|
|
|
20
|
-
**Both fixtures sit on the boundary.** For an ordered constraint (a number, a length, a count) the fail template carries the *tightest violating* value and the pass template the *exact limit* — a 20-character minimum gets a 19-character fail and a 20-character pass, not 5 and 26. A slack pair proves only the direction of the rule: `count(v) < 20` still fires on a 5-character fail template when the constant is wrong (`< 10`), and a 26-character pass template stays silent even at `< 25`, so neither the constant nor the comparison operator is pinned by the fixtures. It also weakens the real-deploy gate, which is the only thing that establishes where AWS's limit actually is — a 19-character key that fails CREATE proves the documented 20, a 5-character one proves "somewhere above 5". A range the rule checks at both ends gets a resource at each end (the fixture assertion is "at least one diagnostic for this rule", so several violating resources in one fail template are fine, and a branch a single fixture cannot reach gets a targeted case in `test/rules.test.ts`). An end the engine's schema already enforces stays out of the fail template — the rule does not check it (principle 1) and the duplication guard would flag it. Constraints with no ordering — a missing property, a wrong enum member, a cross-resource mismatch — have no boundary to sit on.
|
|
20
|
+
**Both fixtures sit on the boundary.** For an ordered constraint (a number, a length, a count) the fail template carries the *tightest violating* value and the pass template the *exact limit* — a 20-character minimum gets a 19-character fail and a 20-character pass, not 5 and 26. A slack pair proves only the direction of the rule: `count(v) < 20` still fires on a 5-character fail template when the constant is wrong (`< 10`), and a 26-character pass template stays silent even at `< 25`, so neither the constant nor the comparison operator is pinned by the fixtures. It also weakens the real-deploy gate, which is the only thing that establishes where AWS's limit actually is — a 19-character key that fails CREATE proves the documented 20, a 5-character one proves "somewhere above 5". A range the rule checks at both ends gets a resource at each end (the fixture assertion is "at least one diagnostic for this rule", so several violating resources in one fail template are fine, and a branch a single fixture cannot reach gets a targeted case in `test/rules.test.ts`). An end the engine's schema already enforces stays out of the fail template — the rule does not check it (principle 1) and the duplication guard would flag it. Constraints with no ordering — a missing property, a wrong enum member, a cross-resource mismatch — have no boundary to sit on. The evidence line records the values that were actually deployed, so it pins the boundary too: `bench 2026-09-13 us-east-1: 19-char Value -> "API Key value should be at least 20 characters" (ROLLBACK_COMPLETE); pass 20-char -> CREATE_COMPLETE`.
|
|
21
21
|
3. **Upstream contribution is welcome, never a gate.** Constraints expressible in schemas or generic engine rules make good PRs to [cloudformation-validate](https://github.com/aws-cloudformation/cloudformation-validate) (open an issue first) — but a rule ships here first and never waits on one. Track status in `meta.yaml#upstream` (`none` / `pending-engine` / `engine-pr` / `retired`); the field exists so that retirement is bookkeeping rather than archaeology.
|
|
22
22
|
4. **Tests are the contract.** Never merge with a red test; never weaken an assertion to make it pass. New behavior needs a new test first.
|
|
23
23
|
5. **The boundary is the engine, not the CDK L2 layer.** Rules validate synthesized templates, so an L2 construct that validates (or structurally prevents) the same mistake does not make a rule redundant — L1 usage, escape hatches, `addPropertyOverride`, and externally generated templates all bypass L2. Overlapping an L2 guard is fine and expected; overlapping the bundled engine is forbidden (principle 1). L2 coverage is not a retirement trigger either — deleting a rule because an L2 construct checks it would strip the coverage from exactly the users this pack exists for. Only a layer that sees the same synthesized template retires a rule: the bundled engine, or CloudFormation's server-side validation. Noting an L2 overlap in the PR is useful context, not something to justify. See "Where this pack sits among validation layers" below.
|
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.
|
|
20
|
+
static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk-preflight.Preflight", version: "0.0.100" };
|
|
21
21
|
/**
|
|
22
22
|
* Register the cdk-preflight rules on an App or Stage.
|
|
23
23
|
*/
|