openshift/api-review
Run strict OpenShift API review workflow for PR changes or local changes
npx skills add https://github.com/openshift/api --skill api-review
Run the preflight script to discover changed API files and run linting:
bash .claude/skills/api-review/scripts/preflight.sh $ARGUMENTS
Read the output:
NO_API_FILES_CHANGED, respond "No API files changed. Nothing to review." and stop.FAILED, report the lint failures and stop.Changed API Files section lists the files to review in Step 2.pr, note the Original-Branch for cleanup in Step 3.CRITICAL: Only review new or modified lines (the + lines in the diff). Do NOT flag pre-existing issues in unchanged context lines. There is significant tech debt in existing APIs and reviewing it is out of scope.
For each changed API file listed in the preflight output, validate only the new/modified lines for:
+kubebuilder:validation:Enum fields, each enum value must be listed AND its meaning explained in the field's own comment using the "When set to X, ..." pattern (e.g., "When set to Vault, HashiCorp Vault is used as the secret store"). Simply listing values without explaining what they do is insufficient. Note: explanations on the type definition do NOT satisfy this rule — the field comment is what users see in generated docs.+kubebuilder:validation:MinItems=1 is set but the comment says "an empty list means no items are excluded" — the validation prevents the documented behavior. Note: "omitted" (field not provided) is different from "empty" (field present with zero items or empty string). MinItems=1 preventing empty lists does NOT contradict documentation about omitted behavior — only flag when documentation describes behavior for a value that validation markers explicitly prevent.Pattern, XValidation, MaxLength, etc.) that enforces it. The API will silently accept values that violate the documented constraint. Either add the marker or remove the claim. Only flag when enforcement is completely absent — do not flag when a marker enforces the documented constraint but you think the enforcement could be stricter or more thorough.+kubebuilder:validation:XValidation rule enforcing that relationship. Documentation alone is not sufficient — the cluster will not enforce undocumented-in-code relationships.MinLength, MaxLength, MinItems, MaxItems, Minimum, Maximum, MaxProperties, Pattern) MUST be documented in the field's comment. If a field has +kubebuilder:validation:MinLength=5 but the comment does not mention the minimum length requirement, that is an issue. This includes MinLength=1 on required fields — even though "required + MinLength=1" may seem redundant, the MinLength constraint is separately enforced at the validation layer and must be documented so users know empty strings are rejected. Check every field with constraint markers, including fields on supporting/referenced types added in the same diff (e.g., a SecretNameReference type with a name field). Exception: MinProperties does not need to be documented — it is a structural constraint ("don't send an empty object") that is self-evident from the type definition.+kubebuilder:validation:XValidation rules, check that CEL expressions are logically correct: no unreachable branches, correct enum value references that match the actual +kubebuilder:validation:Enum values, proper use of has() guards for optional fields, and no tautological or contradictory conditions. Prefer combined ternary expressions for related required/forbidden checks (e.g., self.type == 'X' ? has(self.x) : !has(self.x)). Flag verbose or overly complex CEL that could be simplified.IMPORTANT: Only report issues that violate one of the 7 numbered rules above. Do not report design suggestions, code cleanup, type choice recommendations (e.g. *int32 vs int32), missing enhancementPR calls, or best practices that fall outside these rules. A false positive is worse than a missed issue.
For EACH changed field (including fields on supporting types introduced in the diff), check ALL of the following:
1. Field documentation present?
2. Optional fields explain omitted behavior?
3. Enum values explained in the FIELD's own comment (not just the type definition)?
4. Any validation marker contradicting the comment prose? Any comment claiming a constraint that has no marker to enforce it?
5. Documented field relationships enforced with XValidation?
6. ALL constraint markers (MinLength, MaxLength, MinItems, MaxItems, Minimum, Maximum, MaxProperties, Pattern) documented in comment? Including MinLength=1? (Exception: MinProperties does not need documentation)
7. CEL expressions logically correct? Prefer combined ternary for required/forbidden checks?
If the preflight output showed Mode: pr, switch back to the original branch:
git checkout <Original-Branch from preflight output>
After completing all analysis, you MUST produce a text response listing every issue found. If you do not output text, the review is lost. Do not end on a tool call.
Use this EXACT format for EACH issue:
path/to/file.go:+LineNumber: Brief description
Current (problematic) code:
[exact code from the PR diff]
Suggested change:
- [old code line]
+ [new code line]
Explanation: [Why this change is needed]
The path/to/file.go must be the relative path from the repository root (e.g., config/v1/types_console.go). The +LineNumber is the line number in the new version of the file.
Every issue must be enumerated individually. Do NOT summarize into tables or counts. If no issues are found, say "No issues found."
Take openshift/api-review from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.