Skip to content

fix(eol): correctly classify YELLOW (extended-support) for AWS products#62

Merged
bakayolo merged 1 commit intomainfrom
fix/eol-adapters-yellow-classification
Apr 29, 2026
Merged

fix(eol): correctly classify YELLOW (extended-support) for AWS products#62
bakayolo merged 1 commit intomainfrom
fix/eol-adapters-yellow-classification

Conversation

@bakayolo
Copy link
Copy Markdown
Collaborator

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

  • StandardSchemaAdapter assumed every cycle ships 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.

Fix

StandardSchemaAdapter is 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).

EKSSchemaAdapter now reads 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; past-extended-support is represented as RED via IsDeprecated && !IsExtendedSupport.

ADAPTERS.md is rewritten to catalog the three shapes the adapter now recognizes and the gotchas around AWS's missing support field.

Verification

End-to-end run via docker compose against live Wiz reports (with the EOL adapter rebuilt):

Metric Before After
Total findings 28,330 28,354
YELLOW 0 347
RED 4,636 4,636
GREEN 23,694 23,181
Compliance 83.64% 81.76%

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.go extended 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.

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
@bakayolo bakayolo requested a review from a team as a code owner April 29, 2026 15:57
@bakayolo bakayolo merged commit 88b999f into main Apr 29, 2026
7 checks passed
@bakayolo bakayolo deleted the fix/eol-adapters-yellow-classification branch April 29, 2026 16:31
Copy link
Copy Markdown

@nandiheath nandiheath left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One substantive issue in EKSSchemaAdapter.classifyEKS:

case standardEnd != nil && now.After(*standardEnd):
    lifecycle.IsSupported = true
    lifecycle.IsExtendedSupport = true
    lifecycle.IsDeprecated = true

This 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.

@Kiran01bm Kiran01bm mentioned this pull request Apr 30, 2026
Kiran01bm added a commit that referenced this pull request Apr 30, 2026
## 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants