Conversation
The Standard and EKS adapters were producing zero YELLOW findings because
they didn't recognize the AWS-flavored cycle shapes:
* StandardSchemaAdapter assumed every product had both `support` and
`eol`. AWS ElastiCache cycles ship `eol` + `extendedSupport` (date)
with no `support` field, so the adapter mis-derived the boundaries
and never flagged the extended-support window.
* EKSSchemaAdapter still treated `cycle.extendedSupport` as a boolean.
The current amazon-eks payload uses a date there, and `cycle.eol`
is the end of standard support (not a true terminal date).
Refactor StandardSchemaAdapter into three explicit phases — parse,
derive boundaries, classify — so the three real cycle shapes (Aurora,
ElastiCache, OSS) collapse onto a single set of typed boundaries
(standardEnd / extendedEnd / trueEOL). Update EKSSchemaAdapter to
read `cycle.eol` as standardEnd and `cycle.extendedSupport` (date) as
extendedEnd, while keeping the boolean fallback for legacy cycles.
EKS keeps EOLDate=nil because clusters never truly stop running.
ADAPTERS.md rewritten to catalogue the three shapes the adapter now
recognizes and the gotchas around AWS's missing `support` field.
Verified end-to-end against live Wiz: 28354 findings, 347 YELLOW
(was 0), 81.76% compliance — meets regression targets.
Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019dd9e6-c726-72a8-86cd-e26adaeac367
nandiheath
left a comment
There was a problem hiding this comment.
One substantive issue in EKSSchemaAdapter.classifyEKS:
case standardEnd != nil && now.After(*standardEnd):
lifecycle.IsSupported = true
lifecycle.IsExtendedSupport = true
lifecycle.IsDeprecated = trueThis branch fires whenever standardEnd is past, regardless of whether extendedEnd is set. If cycle.extendedSupport is absent, false, or unparseable, parseEKSExtendedEnd returns nil, and a version past cycle.eol will then be classified as IsExtendedSupport=true, IsSupported=true indefinitely — there is no terminal date to ever flip it to RED.
Suggested guard: require extendedEnd != nil && now.Before(*extendedEnd) before marking IsExtendedSupport=true; otherwise (past standard support with no known extended-support window) classify as IsDeprecated=true, IsSupported=false, IsExtendedSupport=false (with EOLDate still nil per the EKS contract).
Worth adding a table-test row for extendedSupport: false and for extendedSupport omitted, both with cycle.eol in the past, asserting IsExtendedSupport=false. The current LegacyBooleanExtendedSupport test only covers the true case, where parseEKSExtendedEnd falls back to standardEnd and the first branch correctly fires.
Minor secondary note: in the Aurora pattern (support + eol + extendedSupport all present), cycle.eol is silently ignored once support is set. That matches current upstream data where support == eol, but the assumption is unguarded — if upstream ever ships support != eol for an Aurora-shaped cycle, the divergence will be invisible. Not a blocker, just worth a comment in deriveBoundaries or a sanity assertion.
Outside those, the three-shape refactor and reordering of the classify branches look correct and the new AWS-pattern tests pin the right behavior.
## What and Why ? The `add-version-guard-resource` skill was added in #33 and only had two incidental touches since (#57, #63), but ~10 intervening PRs changed the formats / schemas / workflows it teaches. Walked the skill end-to-end against current `resources.yaml` + `loader.go` and fixed every staleness an agent would hit today. Markdown-only. No code changes. ## Fixes | Spot | Was | Now | |------|-----|-----| | `SKILL.md` Step 1 (no-product STOP) | Stop on any missing product | Fall back to upstream product when AWS-flavored is missing (Valkey / Memcached pattern from #53); only stop if no product exists at all | | `SKILL.md` Step 3 (`native_type_pattern` examples) | `rds/AmazonAurora*/cluster`, `eks/Cluster`, `elastiCache/*/cluster` | Actual current patterns from `resources.yaml` + note that `*` only matches whole path segments (partial-segment globs silently match nothing) | | `SKILL.md` Step 4 (schema overview) | Standard = 3 fields; declarative = "EKS only" | Three real cycle shapes the standard adapter handles; declarative covers EKS *and* Lambda; inline lifecycle block; full field/action set incl. `supported`; accurate loader behavior (loader auto-fills `schema: declarative` when `lifecycle:` is present) | | `SKILL.md` Step 6 (OpenSearch example) | `native_type_pattern: "opensearch/Domain"` | `"elasticSearchService\|OpenSearch Domain"` (old value matched zero rows) | | `SKILL.md` Step 6 (examples menu) | `elasticache.yaml` = "wildcard patterns" | Per-engine split (#53); the example file itself warns against wildcard + single product | | `SKILL.md` Completion | Steered toward Go adapter | Steers toward declarative YAML; Go adapter is now exceptional (#63) | | `references/troubleshooting.md` ("Non-Standard Schema") | `schema: {resource}-adapter` + "refer to EKS adapter" | `schema: declarative` + `lifecycle:` block, link to `ADAPTERS.md`; EKS Go adapter no longer exists | | `SKILL.md` Step 7 footer | "Proceed to Step 7" | "Proceed to Step 8" | ## Driving PRs since #33 #36, #38, #42, #44, #45, #53, #54, #56, #62, #63.
Summary
Fixes a bug where the Standard and EKS schema adapters produced zero YELLOW (extended-support) findings across every adapter-driven resource type. Both adapters had stale assumptions about the endoflife.date payload shape that AWS-flavored products actually emit.
Root cause
StandardSchemaAdapterassumed every cycle ships bothsupportandeol. AWS ElastiCache cycles shipeol+extendedSupport(date) with nosupportfield, so the adapter mis-derived the boundaries and never flagged the extended-support window.EKSSchemaAdapterstill treatedcycle.extendedSupportas a boolean. The currentamazon-ekspayload uses a date there, andcycle.eolis the end of standard support, not a true terminal date.Fix
StandardSchemaAdapteris refactored into three explicit phases — parse → derive boundaries → classify — so the three real cycle shapes (Aurora, ElastiCache, OSS) collapse onto a single typed boundary set (standardEnd/extendedEnd/trueEOL).EKSSchemaAdapternow readscycle.eolasstandardEndandcycle.extendedSupport(date) asextendedEnd, while keeping the boolean fallback for legacy cycles. EKS keepsEOLDate=nilbecause clusters never truly stop running; past-extended-support is represented as RED viaIsDeprecated && !IsExtendedSupport.ADAPTERS.mdis rewritten to catalog the three shapes the adapter now recognizes and the gotchas around AWS's missingsupportfield.Verification
End-to-end run via
docker composeagainst live Wiz reports (with the EOL adapter rebuilt):Per-type YELLOW breakdown after fix: aurora-pg 25, aurora-mysql 9, eks 123, elasticache-redis 138, opensearch 23, rds-mysql 7, rds-pg 22.
Blockcell dashboard refreshed: https://blockcell.sqprod.co/sites/version-guard-dashboard/
Tests
go test ./pkg/eol/endoflife/...— all green;adapters_test.goextended with table tests covering all three Standard cycle shapes plus EKS date/boolean variants.golangci-lint run— clean.make build+ docker-compose end-to-end against live Wiz — green.