Skip to content
This repository was archived by the owner on Jun 12, 2026. It is now read-only.

AEP Compliance Gap Analysis & Remediation Plan#27

Open
ebichman-1 wants to merge 1 commit into
dcm-project:mainfrom
ebichman-1:aep-rules-gap-analysis
Open

AEP Compliance Gap Analysis & Remediation Plan#27
ebichman-1 wants to merge 1 commit into
dcm-project:mainfrom
ebichman-1:aep-rules-gap-analysis

Conversation

@ebichman-1

@ebichman-1 ebichman-1 commented Apr 26, 2026

Copy link
Copy Markdown

AEP Compliance Gap Analysis & Remediation Plan

Context

Current state: The OpenAPI spec (api/v1alpha1/openapi.yaml) passes all 50+
rules from the aep-openapi-linter v0.5.3 with zero errors, warnings, or hints.
The compliance gaps are in tooling configuration and CI hardening, not in the
API spec itself.

Phase 1: Tooling & CI Hardening

1.1 Pin .spectral.yaml to a release tag

File: .spectral.yaml (line 2)

Problem: Extends from main branch, which is mutable and could introduce
breaking changes at any time.

Change:

Current

 extends:
   - https://raw.githubusercontent.com/aep-dev/aep-openapi-linter/main/spectral
 .yaml

New (pin to latest release v0.5.3)

 extends:
   - https://raw.githubusercontent.com/aep-dev/aep-openapi-linter/refs/tags/v0.
 5.3/spectral.yaml

Keep the existing custom x-aep-resource-no-boolean rule as-is.

1.2 Fix Makefile check-aep to use npx

File: Makefile (line 59-60)

Problem: Uses bare spectral command, which requires a global install. npx
ensures the correct version is used without requiring global install.

Change:

Current

 check-aep:
        spectral lint --fail-severity=warn ./api/v1alpha1/openapi.yaml

New

 check-aep:
        npx --yes @stoplight/spectral-cli lint --fail-severity=warn
 ./api/v1alpha1/openapi.yaml

1.3 Improve CI workflow path filtering (optional)

File: .github/workflows/check-aep.yaml

Problem: Currently triggers on ALL PRs to main, regardless of whether
API-related files changed. This creates unnecessary CI runs.

Possible change: Add path filters to only trigger when API spec or linter
config changes:

 on:
   pull_request:
     branches: [main]
     paths:
       - 'api/**'
       - '.spectral.yaml'

Note: This workflow delegates to dcm-project/shared-workflows. The shared
workflow handles Node.js setup and spectral installation, so no local changes
are needed for CI tooling itself.

Phase 2: AEP Rule Coverage Analysis

Rules that apply and pass (verified by running the linter)

 ┌──────────┬───────────────────────────────┬──────────────────────────────┐
 │ AEP Rule │        What It Checks         │            Status            │
 ├──────────┼───────────────────────────────┼──────────────────────────────┤
 │          │ x-aep-resource structure      │ PASS — Resource and Health   │
 │ AEP-0004 │ (singular, plural, patterns,  │ schemas fully compliant      │
 │          │ type)                         │                              │
 ├──────────┼───────────────────────────────┼──────────────────────────────┤
 │          │ Resource path field,          │                              │
 │ AEP-0122 │ collection identifier format, │ PASS                         │
 │          │  ID field type, no self_link  │                              │
 ├──────────┼───────────────────────────────┼──────────────────────────────┤
 │          │ Get operation: operationId,   │ PASS — getResource matches   │
 │ AEP-0131 │ no request body, response is  │ ^[Gg][Ee][Tt][A-Z].*$        │
 │          │ AEP resource                  │                              │
 ├──────────┼───────────────────────────────┼──────────────────────────────┤
 │          │ List operation: operationId,  │ PASS — listResources matches │
 │ AEP-0132 │ no request body, parameter    │  pattern                     │
 │          │ types                         │                              │
 ├──────────┼───────────────────────────────┼──────────────────────────────┤
 │          │ Create operation:             │ PASS — createResource with   │
 │ AEP-0133 │ operationId, id parameter,    │ id query param               │
 │          │ request/response body         │                              │
 ├──────────┼───────────────────────────────┼──────────────────────────────┤
 │          │ Delete operation:             │ PASS — deleteResource with   │
 │ AEP-0135 │ operationId, no request body, │ 204 response                 │
 │          │  204 response                 │                              │
 ├──────────┼───────────────────────────────┼──────────────────────────────┤
 │          │ Custom method: HTTP method    │ PASS — :RehydrateResource is │
 │ AEP-0136 │ (POST), operationId starts    │  correct                     │
 │          │ with :+capital                │                              │
 ├──────────┼───────────────────────────────┼──────────────────────────────┤
 │          │ Boolean naming (no is_        │                              │
 │ AEP-0140 │ prefix), URI naming (uri not  │ PASS — no violations         │
 │          │ url)                          │                              │
 ├──────────┼───────────────────────────────┼──────────────────────────────┤
 │ AEP-0142 │ Time field types, naming      │ PASS — create_time,          │
 │          │ conventions, _time suffix     │ update_time are correct      │
 ├──────────┼───────────────────────────────┼──────────────────────────────┤
 │ AEP-0143 │ Standardized code field       │ PASS — no code fields        │
 │          │ conventions                   │ present                      │
 ├──────────┼───────────────────────────────┼──────────────────────────────┤
 │ AEP-0158 │ Pagination: max_page_size,    │ PASS — all present on list   │
 │          │ page_token, next_page_token   │ operation                    │
 ├──────────┼───────────────────────────────┼──────────────────────────────┤
 │ AEP-0193 │ Error response schema (RFC    │ PASS — type, title, status,  │
 │          │ 7807 fields)                  │ detail, instance all present │
 └──────────┴───────────────────────────────┴──────────────────────────────┘

Rules that don't apply (no matching endpoints)

 ┌──────────┬──────────────────────────┬───────────────────────────────────┐
 │ AEP Rule │      What It Checks      │              Why N/A              │
 ├──────────┼──────────────────────────┼───────────────────────────────────┤
 │          │                          │ No PATCH endpoint exists. The     │
 │ AEP-0134 │ Update (PATCH) operation │ linter only validates existing    │
 │          │                          │ endpoints.                        │
 ├──────────┼──────────────────────────┼───────────────────────────────────┤
 │ AEP-0137 │ Apply (PUT) operation    │ No PUT endpoint exists.           │
 ├──────────┼──────────────────────────┼───────────────────────────────────┤
 │          │ Update Array             │                                   │
 │ AEP-0144 │ (:add/:remove custom     │ No array update endpoints.        │
 │          │ methods)                 │                                   │
 ├──────────┼──────────────────────────┼───────────────────────────────────┤
 │ AEP-0151 │ Long-running operations  │ No 202 responses defined.         │
 │          │ (202 responses)          │                                   │
 └──────────┴──────────────────────────┴───────────────────────────────────┘

Note on operationId casing

The AEP linter uses case-insensitive prefix matching (e.g.,
^[Gg][Ee][Tt][A-Z].*$). The current camelCase operationIds (getResource,
listResources, etc.) are valid and pass the linter. PascalCase (GetResource,
ListResources) would also pass. No change is required, though PascalCase is
the more common AEP convention.

Phase 3: Verification

After making changes, verify with:

  1. Lint: make check-aep — should pass with zero findings
  2. Build: make build — should compile cleanly (no spec changes needed)
  3. Test: make test — all tests should pass (no spec changes needed)
  4. Sync check: make check-generate-api — generated files should still match

Summary of Changes

 ┌──────────────────────────────────┬─────────────────────────┬─────────────┐
 │               File               │         Change          │  Priority   │
 ├──────────────────────────────────┼─────────────────────────┼─────────────┤
 │                                  │                         │ Must —      │
 │ .spectral.yaml                   │ Pin to refs/tags/v0.5.3 │ production  │
 │                                  │                         │ stability   │
 ├──────────────────────────────────┼─────────────────────────┼─────────────┤
 │ Makefile                         │ Use npx --yes           │ Must —      │
 │                                  │ @stoplight/spectral-cli │ portability │
 ├──────────────────────────────────┼─────────────────────────┼─────────────┤
 │ .gitignore                       │ Add node_modules/       │ Should —    │
 │                                  │                         │ hygiene     │
 ├──────────────────────────────────┼─────────────────────────┼─────────────┤
 │ .github/workflows/check-aep.yaml │ Add path filters        │ May — CI    │
 │                                  │ (optional)              │ efficiency  │
 └──────────────────────────────────┴─────────────────────────┴─────────────┘

Last Summary

  • No OpenAPI spec changes are needed — the spec already passes all applicable
    AEP linter rules.

Summary by Sourcery

Harden AEP compliance tooling and CI triggers without changing the OpenAPI spec itself.

Enhancements:

  • Pin the Spectral configuration to a specific aep-openapi-linter release tag for stable linting behavior.
  • Update the AEP compliance Makefile target to run Spectral via npx for reproducible, non-global installation usage.
  • Restrict the AEP compliance GitHub workflow to run only when API or Spectral config files change to reduce unnecessary CI runs.

 Harden AEP linter tooling and CI configuration

- Pin .spectral.yaml to aep-openapi-linter v0.5.3 release tag instead of mutable main branch for reproducible builds.
- Switch Makefile check-aep target from bare spectral to npx @stoplight/spectral-cli to eliminate global install requirement.
- Add path filters to check-aep CI workflow so it only triggers on API spec or linter config changes.
- No OpenAPI spec changes
- all 50+ AEP linter rules already pass.

Assisted-by: Claude Opus 4.6 (Anthropic)
Signed-off-by: ebichman-1 <ebichman@redhat.com>

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've found 1 issue, and left some high level feedback:

  • The new paths filter in check-aep.yaml will prevent this workflow from running when the workflow file itself changes; consider adding .github/workflows/check-aep.yaml to the list so CI runs when the AEP check pipeline is modified.
  • The npx --yes @stoplight/spectral-cli invocation will always pull the latest spectral CLI, which may drift from the pinned ruleset version (v0.5.3); consider pinning the spectral CLI version in the npx command to keep tooling and rules in sync.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new `paths` filter in `check-aep.yaml` will prevent this workflow from running when the workflow file itself changes; consider adding `.github/workflows/check-aep.yaml` to the list so CI runs when the AEP check pipeline is modified.
- The `npx --yes @stoplight/spectral-cli` invocation will always pull the latest spectral CLI, which may drift from the pinned ruleset version (`v0.5.3`); consider pinning the spectral CLI version in the `npx` command to keep tooling and rules in sync.

## Individual Comments

### Comment 1
<location path=".spectral.yaml" line_range="2" />
<code_context>
 extends:
-  - https://raw.githubusercontent.com/aep-dev/aep-openapi-linter/main/spectral.yaml
+  - https://raw.githubusercontent.com/aep-dev/aep-openapi-linter/refs/tags/v0.5.3/spectral.yaml

 rules:
</code_context>
<issue_to_address>
**issue (bug_risk):** The raw GitHub URL for the tagged spectral config likely should not include `refs/tags`.

The raw GitHub URL for tags is typically `https://raw.githubusercontent.com/<org>/<repo>/<tag>/<path>`, e.g. `.../v0.5.3/spectral.yaml`. Please verify this link resolves as expected and, if not, update it to use the tag name directly instead of `refs/tags` in the path.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread .spectral.yaml
@@ -1,5 +1,5 @@
extends:
- https://raw.githubusercontent.com/aep-dev/aep-openapi-linter/main/spectral.yaml
- https://raw.githubusercontent.com/aep-dev/aep-openapi-linter/refs/tags/v0.5.3/spectral.yaml

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

issue (bug_risk): The raw GitHub URL for the tagged spectral config likely should not include refs/tags.

The raw GitHub URL for tags is typically https://raw.githubusercontent.com/<org>/<repo>/<tag>/<path>, e.g. .../v0.5.3/spectral.yaml. Please verify this link resolves as expected and, if not, update it to use the tag name directly instead of refs/tags in the path.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant