| name | kcl-composition-validator |
| description | Validates KCL Crossplane compositions with comprehensive checks including formatting, syntax validation, and rendering tests. Automatically activates when working with KCL files, Crossplane compositions, or before commits touching infrastructure/base/crossplane/configuration/. Prevents CI failures and catches critical bugs like the mutation pattern. |
| allowed-tools | Read, Bash, Grep, Glob |
KCL Composition Validator
When This Skill Activates
This skill automatically activates when:
- Modifying files in
infrastructure/base/crossplane/configuration/kcl/ - Working with KCL compositions or Crossplane resources
- User mentions "kcl", "crossplane", "composition", or "validate"
- Before committing changes that include
.kfiles - When running pre-commit validation
Critical: Why This Matters
The CI enforces strict KCL formatting and will fail your commit if validation doesn't pass.
Common issues this skill prevents:
- Formatting violations that fail CI
- Syntax errors in KCL code
- Resource mutation causing duplicate resources (issue #285)
- Rendering failures in composition pipeline
Three-Stage Validation Process
Stage 1: KCL Formatting (CRITICAL - CI Enforced)
Purpose: Ensure code follows strict formatting standards that CI will check.
What to check:
- Single-line list comprehensions (NOT multi-line)
- No trailing blank lines between sections
- Proper indentation and spacing
How to validate:
cd infrastructure/base/crossplane/configuration/kcl/<module>
kcl fmt .
Check for changes:
git diff --quiet . || echo "Files were reformatted - review changes"
If kcl fmt made changes, the formatting was incorrect. Review the diff and commit the formatted version.
Stage 2: KCL Syntax and Logic Validation
Purpose: Test KCL code executes without errors using example settings.
How to validate:
cd infrastructure/base/crossplane/configuration/kcl/<module>
kcl run . -Y settings-example.yaml
What this catches:
- Syntax errors in KCL code
- Logic errors in conditionals
- Type mismatches
- Reference errors
Stage 3: Crossplane Render Validation
Purpose: Test the complete composition pipeline end-to-end.
Comprehensive validation script:
# From repository root
./scripts/validate-kcl-compositions.sh
This script validates ALL compositions through all three stages automatically.
Manual validation (for specific compositions):
cd infrastructure/base/crossplane/configuration
# Test basic example
crossplane render examples/app-basic.yaml app-composition.yaml functions.yaml \
--extra-resources examples/environmentconfig.yaml > /tmp/rendered.yaml
# Test complete example
crossplane render examples/app-complete.yaml app-composition.yaml functions.yaml \
--extra-resources examples/environmentconfig.yaml > /tmp/rendered.yaml
Tested compositions:
app: app-basic.yaml, app-complete.yamlcloudnativepg(SQLInstance): sqlinstance-basic.yaml, sqlinstance-complete.yamleks-pod-identity: epi.yaml
Critical KCL Rules
Rule 1: NEVER MUTATE RESOURCES (Issue #285)
Background: https://github.com/crossplane-contrib/function-kcl/issues/285
Mutating dictionaries/resources after creation causes function-kcl to create duplicate resources. This is a known bug in function-kcl's duplicate detection mechanism.
WRONG - Mutation Pattern:
# ❌ Creating resource then modifying it later
_deployment = {
apiVersion = "apps/v1"
kind = "Deployment"
metadata = {
name = _name
annotations = {
"base-annotation" = "value"
}
}
}
# ❌ MUTATION! This causes duplicates
if _deploymentReady:
_deployment.metadata.annotations["krm.kcl.dev/ready"] = "True"
_items += [_deployment]
CORRECT - Inline Conditional Pattern:
# ✅ Using inline conditionals
_deployment = {
apiVersion = "apps/v1"
kind = "Deployment"
metadata = {
name = _name
annotations = {
"base-annotation" = "value"
if _deploymentReady:
"krm.kcl.dev/ready" = "True" # ✅ Inline conditional
}
}
}
_items += [_deployment]
CORRECT - List Comprehension Pattern:
# ✅ List comprehensions with inline definitions
_items += [{
apiVersion = "apps/v1"
kind = "Deployment"
metadata = {
name = _name + "-" + db.name
annotations = {
"base-annotation" = "value"
if _ready:
"krm.kcl.dev/ready" = "True"
}
}
} for db in databases]
Safe patterns:
- Inline conditionals within dictionary literals
- List comprehensions with inline definitions
- Ternary operators returning complete dictionaries
Unsafe patterns (NEVER use):
- Post-creation field assignment:
resource.field = value - Post-creation nested assignment:
resource.metadata.annotations["key"] = "value" - Any mutation of resource variables after initial creation
Rule 2: Single-Line List Comprehensions
WRONG:
# ❌ Multi-line comprehension (will fail CI)
_ready = any_true([
c.get("type") == "Available" and c.get("status") == "True"
for c in conditions or []
])
CORRECT:
# ✅ Single-line comprehension
_ready = any_true([c.get("type") == "Available" and c.get("status") == "True" for c in conditions or []])
Rule 3: No Trailing Blank Lines
Remove extra blank lines between logical sections. The kcl fmt tool will catch these.
Pre-Commit Workflow
ALWAYS run before committing KCL changes:
# From repository root
./scripts/validate-kcl-compositions.sh
Expected output:
╔════════════════════════════════════════════════════════════════╗
║ KCL Crossplane Composition Validation ║
╚════════════════════════════════════════════════════════════════╝
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Validating: app
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📝 [1/3] Checking KCL formatting...
✅ Formatting is correct
🧪 [2/3] Validating KCL syntax and logic...
✅ KCL syntax valid
🎨 [3/3] Testing crossplane render...
Testing: app-basic.yaml
✅ app-basic.yaml renders successfully
Testing: app-complete.yaml
✅ app-complete.yaml renders successfully
✅ All checks passed for app
Target: Zero errors, minimal warnings.
Common Issues and Fixes
Issue: Code Reformatted by kcl fmt
Symptom: kcl fmt makes changes to your code
Fix:
- Review the changes with
git diff - Commit the formatted version
- The formatting is now correct for CI
Issue: Syntax Errors
Symptom: kcl run fails with syntax error
Fix:
- Read the error message carefully
- Check the line number indicated
- Common causes: missing commas, incorrect indentation, typos
- Fix the syntax and re-run validation
Issue: Render Failures
Symptom: crossplane render fails
Fix:
- Check that example files match composition schema
- Verify
functions.yamlis correctly configured - Ensure
environmentconfig.yamlexists - Check function-kcl version compatibility
Issue: Duplicate Resources Created
Symptom: Multiple identical resources in rendered output
Fix:
- Search for resource mutation patterns in code
- Look for lines like:
_resource.field = value - Refactor to use inline conditionals
- See Rule 1 above for correct patterns
Quick Checklist
Before committing KCL changes, ensure:
- Run
./scripts/validate-kcl-compositions.shfrom repo root - All formatting checks pass (Stage 1)
- All syntax validations pass (Stage 2)
- All render tests pass (Stage 3)
- No resource mutation patterns in code
- List comprehensions are single-line
- No trailing blank lines
Additional Resources
- Mutation bug details: See
reference.mdin this skill folder - Code patterns: See
examples.mdin this skill folder - Quick reference: See
quick-reference.mdin this skill folder
Validation Targets
Modules validated:
app- Application composition with progressive complexitycloudnativepg- PostgreSQL database instanceseks-pod-identity- EKS Pod Identity for IAM roles
Example files tested:
- Basic examples (minimal configuration)
- Complete examples (production-ready with all features)
Success Criteria
Validation is successful when:
kcl fmtmakes no changes (formatting correct)kcl runexecutes without errors (syntax valid)crossplane rendersucceeds for all examples (composition valid)- Zero errors reported by validation script
- Minimal warnings (Docker availability only)