Skip to content

feat(provisioning): CC-API enrichment-coverage matrix + CI critic - #869

Merged
go-to-k merged 2 commits into
mainfrom
feat/enrichment-coverage-matrix
Jun 15, 2026
Merged

feat(provisioning): CC-API enrichment-coverage matrix + CI critic#869
go-to-k merged 2 commits into
mainfrom
feat/enrichment-coverage-matrix

Conversation

@go-to-k

@go-to-k go-to-k commented Jun 15, 2026

Copy link
Copy Markdown
Owner

Summary

Adds a CC-API enrichment-coverage completeness matrix + CI critic so the enrichment-gap bug class (one-off fixed in #844 / #864 / #865 / #866) cannot silently regrow.

CloudControlProvider.enrichResourceAttributes is a hand-maintained switch that overlays computed Fn::GetAtt attributes onto the flat-key shape cdkd's intrinsic resolver expects for CC-routed resources. Until now nothing prevented a new CC-routed type with a computed readOnly attribute from silently falling through constructAttribute to the physicalId.

What this adds

  • scripts/gen-enrichment-coverage.ts — parses the enrichResourceAttributes switch via the TypeScript Compiler API, cross-references each type's readOnlyProperties from the cached CFn schema fixtures, and classifies every CC-routable type into one of: enriched / no-computed-attr / sdk-fallback-gap (informational, Add Cloud Control API greenfield fallback for unhandled top-level properties #614 path only) / unenriched-computed (the real bug class — a pure-CC type with no SDK provider whose computed readOnly attr falls through to physicalId).
  • vp run gen:enrichment-coverage (regenerate) + vp run audit:enrichment-coverage:check (CI critic — hard-fails ONLY on unenriched-computed, plus drift-on-git diff).
  • docs/_generated/enrichment-coverage.{json,md} — the generated matrix.
  • scripts/refresh-cfn-schemas.mjs — extended to capture primaryIdentifier into the fixtures so a readOnly prop that IS the primaryIdentifier is auto-classified not-a-gap.
  • Seed ENRICHMENT_ALLOW_LIST carves out AWS::MSK::Cluster (Arn == primaryIdentifier == physicalId) + AWS::Elasticsearch::Domain (Tier-3 non-provisionable).

Current classification (offline, cached fixtures)

114 CC-routable types classified — 3 enriched, 13 no-computed-attr, 0 pure-CC latent gaps. The critic passes by construction today (every cached schema is an SDK-backed Tier-1 type) and becomes load-bearing the moment a pure-CC type's schema is cached. 98 SDK-fallback gaps reported informationally for a future #614-hardening pass.

Test plan

  • 24 unit tests (tests/unit/scripts/gen-enrichment-coverage.test.ts) covering the switch parser (plain / try-catch / fall-through / empty-body / non-enriched / block-scoped case — the dominant real shape for the pure-CC types), the classifier (every bucket, flat-key-to-nested matching, primaryIdentifier auto-allow-list, enrichment-precedence), buildReport, and findLatentGaps — the exact bucket the --check critic gates on (so a regression that flipped the filter and made the critic silently never fire is caught).
  • Full suite green: 389 files / 5898 tests, 0 type errors.
  • vp run gen:enrichment-coverage + vp run audit:enrichment-coverage:check both run clean with no drift.
  • No AWS integ (pure static analysis / codegen); only /check + /check-docs gates apply.

Known follow-up (accepted, not blocking)

Independent code + test review (PR #869) flagged that the primaryIdentifier auto-allow-list and the seed ENRICHMENT_ALLOW_LIST entries are inert today: no cached fixture carries a primaryIdentifier field yet (the refresh-cfn-schemas.mjs extension that captures it requires AWS creds + a ~15-min audit:coverage:regenerate to backfill), and neither MSK::Cluster nor Elasticsearch::Domain has a cached fixture. This is fail-open in the safe direction — fewer allow-listed attrs, never a missed gap — and both mechanisms are unit-tested in isolation, so the wiring is proven; only the against-real-fixture-data exercise is deferred. Backfilling the fixtures (which would also pull ElastiCache::ReplicationGroup / Redshift::Cluster / OpenSearchService::Domain from enrichedWithoutCachedSchema into the actively-classified set) is a follow-up that needs an AWS-cred'd schema refresh, intentionally out of scope for this codegen-only PR.

go-to-k added 2 commits June 15, 2026 10:13
Add a codegen + CI critic that makes the CC-API enrichment-gap bug class
(#844 / #864 / #865 / #866) non-regressing. enrichResourceAttributes in
cloud-control-provider.ts is a hand-maintained switch; previously nothing
prevented a new CC-routed type with a computed readOnly Fn::GetAtt
attribute from silently falling through the intrinsic resolver to the
physicalId.

scripts/gen-enrichment-coverage.ts (modeled on gen-property-coverage /
gen-unsupported-types) parses the enrichResourceAttributes switch via the
TypeScript Compiler API, cross-references each type's readOnlyProperties
from the cached CFn schema fixtures, and classifies every CC-routable
type into: enriched / no-computed-attr / sdk-fallback-gap (gap only on
the #614 CC-fallback path, informational) / unenriched-computed (gap on a
pure-CC type with no SDK provider, the real bug class). The
audit:enrichment-coverage:check critic hard-fails ONLY on
unenriched-computed. A readOnly prop that is the type's primaryIdentifier
is auto-classified not-a-gap; refresh-cfn-schemas.mjs now captures
primaryIdentifier into the fixtures so this is data-driven going forward.
Seed ENRICHMENT_ALLOW_LIST carves out MSK::Cluster (Arn ==
primaryIdentifier) and Elasticsearch::Domain (Tier-3 non-provisionable).

Current offline classification: 114 CC-routable types, 0 pure-CC latent
gaps (every cached schema today is an SDK-backed Tier 1 type, so the
critic passes by construction and becomes load-bearing the moment a
pure-CC type's schema is cached). 98 SDK-fallback gaps reported
informationally for a future #614-hardening pass; 8 enrichment cases lack
a cached schema and are listed as needing a fixture refresh.

- Emit docs/_generated/enrichment-coverage.{json,md}
- vp run gen:enrichment-coverage + vp run audit:enrichment-coverage:check
- CI staleness guard + critic step in ci.yml
- 20 unit tests (switch parser, classifier buckets, buildReport)

No AWS integ (pure static analysis / codegen); diff touches no integ-gate
scope.
… block-scoped case parsing

Address review on #869 (2 cheap, high-value test gaps; both reviewers: no blockers):

- Extract findLatentGaps(report) from main()'s --check branch and unit-test it.
  The critic's whole value is failing CI on the unenriched-computed bucket; a
  regression flipping that filter (or dropping it) would have passed every
  existing classifier test while making the critic silently never fire. Now
  pinned (3 tests: returns the pure-CC gap, empty on the passing case, never
  counts an SDK-fallback gap).
- Add a block-scoped case 'X': { ... } parser test. That is the dominant
  real-world shape in cloud-control-provider.ts (ElastiCache / Redshift /
  OpenSearchService) - exactly the pure-CC types this tool guards. The parser
  already handled it; this pins it against a regression.

Full suite 5898 tests pass (+4). No src/ behavior change; generated matrix
unchanged (no drift).
@go-to-k
go-to-k merged commit e55ff37 into main Jun 15, 2026
6 checks passed
@go-to-k
go-to-k deleted the feat/enrichment-coverage-matrix branch June 15, 2026 01:30
github-actions Bot pushed a commit that referenced this pull request Jun 15, 2026
# [0.222.0](v0.221.16...v0.222.0) (2026-06-15)

### Features

* **provisioning:** CC-API enrichment-coverage matrix + CI critic ([#869](#869)) ([e55ff37](e55ff37))
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 0.222.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant