Skip to content

Commit 683bd4b

Browse files
committed
chore(audit): handled-property WIRING critic + the two live gaps its first run caught
gen-property-coverage verifies every CFn property is ACCOUNTED FOR (declared in handledProperties or unhandledByDesign); gen-nested-key-coverage audits spellings INSIDE a forwarded blob. Neither checks that a handledProperties entry is actually WIRED. ECRProvider declared ImageTagMutabilityExclusionFilters handled while the property appeared on NO API call, so the pre-flight passed on the declaration alone and the value silently vanished (#1392, fixed in #1406) -- a FALSE handled claim, the exact thing the declaration system exists to prevent. The critic requires per-property read evidence in one of four AST shapes (element-read, property-read, destructure, table-loop), plus a delegated tag when the read happens in a callable reached by a call edge. Evidence is CLASS-SCOPED via a taint walk seeded from each method's desired-state parameter and propagated only through calls that pass the bag WHOLE, so a sibling class in the same file, a comment, a getDriftUnknownPaths entry, the declaration itself, and a readCurrentState write-back all fail to vouch for a property. Two strictness decisions were forced by the real tree, not by fixtures: - A whole-bag forward does NOT blanket-excuse un-read declarations. The first draft's excuse silenced the very #1392 property via ECRProvider's hasCdkAutoDeleteTag(properties) call in delete(); measured across the tree it rescued 0 of 1063 properties. Blind spots are recorded for visibility only. - A read of previousProperties is NOT evidence: a diff-only read proves change DETECTION, not delivery. Also 0 of 1063 today, so the strictness is free now and closes the disguise later. Coverage floors are per SHAPE rather than a grand total (84 classes / 1063 properties), with property-read and destructure pinned === 0 so a future first user cannot regress those recognizers silently. The first real-tree run found two live gaps, seeded as KNOWN GAP allow-list entries and FILED rather than fixed here (this PR introduces the tool; the fixes are separate): AWS::EC2::NatGateway.MaxDrainDurationSeconds (#1411) and AWS::Logs::LogGroup.ResourcePolicyDocument (#1412). IAMAccessKeyProvider#Serial and NestedStackProvider#TemplateURL are rationale'd NOT-A-BUG entries. Stale entries fail in both modes, so wiring a property forces its entry's removal. Real-code fail probe (the repo's checker rule, re-run independently): reverting the real ecr-provider.ts to its pre-#1406 state makes --check exit 1 naming ECRProvider#ImageTagMutabilityExclusionFilters, and the file restores byte-identical. A first probe that stripped only the lowercase-p reads PASSED -- the surviving previousProperties read cleared it -- and that false clean is what drove the previousProperties exclusion; both variants are now automated. Closes #1404
1 parent cd7fe67 commit 683bd4b

7 files changed

Lines changed: 14133 additions & 0 deletions

File tree

.claude/rules/code-layout.md

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

.github/workflows/ci.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,27 @@ jobs:
218218
fi
219219
- run: vp run audit:nested-key-coverage:check
220220

221+
# Fail CI when docs/_generated/handled-property-wiring.{json,md} is stale
222+
# relative to the provider sources. The matrix records, per SDK provider
223+
# class declaring handledProperties, whether each DECLARED property is
224+
# actually READ off the template property bag (following
225+
# this.helper(properties) delegation and table-driven loops). A
226+
# declaration with no read evidence is either a wiring gap or a
227+
# mis-declared property — the #1392 ECRProvider class, which
228+
# gen-property-coverage.ts structurally cannot see because that pre-flight
229+
# passes on the strength of the declaration alone (issue #1404). The
230+
# second step is the CRITIC: it hard-fails on any un-wired declaration
231+
# that is not allow-listed, and on a stale allow-list entry.
232+
- name: handled-property-wiring matrix is up-to-date
233+
run: |
234+
vp run gen:handled-property-wiring
235+
if ! git diff --quiet -- docs/_generated/handled-property-wiring.json docs/_generated/handled-property-wiring.md; then
236+
echo "::error::handled-property-wiring matrix is stale — run \`vp run gen:handled-property-wiring\` and commit the regenerated docs/_generated/handled-property-wiring.{json,md}"
237+
git --no-pager diff -- docs/_generated/handled-property-wiring.json docs/_generated/handled-property-wiring.md
238+
exit 1
239+
fi
240+
- run: vp run audit:handled-property-wiring:check
241+
221242
runtime-compat:
222243
runs-on: ubuntu-latest
223244
needs: check-build-test

0 commit comments

Comments
 (0)