Reusable procedural skills extracted from CLAUDE.md. Each skill has a canonical name (kebab-case), trigger conditions, ordered steps, and a verification check. Invoke a skill by name: "run the cargo-quality skill" or "do a verify-crd-sync".
When to use:
- Before investigating reconciliation loops or infinite loops
- Before debugging "field not appearing in kubectl output" issues
- After ANY modification to structs in
src/crd.rs - When status patches succeed but data doesn't persist
- When user reports unexpected controller behavior
Steps:
# 1. Check deployed CRD schema in cluster
kubectl get crd scheduledmachines.5spot.eribourg.dev -o yaml | grep -A 20 "<field-name>:"
# 2. Check Rust struct definition
rg -A 10 "pub struct <StructName>" src/crd.rs
# 3. If mismatch detected, regenerate CRDs
cargo run --bin crdgen > deploy/crds/scheduledmachine.yaml
# 4. Apply updated CRDs
kubectl apply -f deploy/crds/scheduledmachine.yamlVerification: Field appears in kubectl get output after patch; no infinite reconciliation loop.
When to use:
- After ANY edit to Rust types in
src/crd.rs - Before deploying CRD changes to a cluster
Steps:
# 1. Regenerate CRD YAML file from Rust types
cargo run --bin crdgen > deploy/crds/scheduledmachine.yaml
# 2. Verify generated YAML
kubectl apply --dry-run=client -f deploy/crds/scheduledmachine.yaml
# 3. Update examples to match new schema (see validate-examples skill)
# 4. Deploy
kubectl apply -f deploy/crds/scheduledmachine.yamlVerification: kubectl apply --dry-run=client -f deploy/crds/scheduledmachine.yaml succeeds.
When to use:
- After all CRD changes, example updates, and validations are complete (run this LAST)
- Before any documentation release
Steps:
# Regenerate API reference from CRD types.
# Prefer the Makefile target — it writes to the mdBook source path that
# actually renders on the doc site.
make crddoc
# Equivalent:
# cargo run --bin crddoc > docs/src/reference/api.mdVerification: docs/src/reference/api.md reflects the current CRD schema.
When to use:
- After adding or modifying ANY
.rsfile - Before committing any Rust code changes
- At the end of EVERY task involving Rust code (NON-NEGOTIABLE)
Steps:
# 0. Ensure cargo is in PATH
source ~/.zshrc
# 1. Format
cargo fmt
# 2. Lint with strict warnings (fix ALL warnings)
cargo clippy --all-targets --all-features -- -D warnings -W clippy::pedantic -A clippy::module_name_repetitions
# 3. Test (ALL tests must pass)
cargo test
# 4. Security audit (optional, if installed)
cargo audit 2>/dev/null || trueVerification: All three commands exit with code 0. No warnings, no test failures.
When to use:
- Adding any new feature or function
- Fixing a bug
- Refactoring existing code
Steps:
RED — Write failing tests first (before any implementation):
# Edit src/<module>_tests.rs — add test(s) that define expected behavior
cargo test <test_name> # Must FAIL at this pointGREEN — Implement minimum code to pass tests:
# Edit src/<module>.rs — write simplest code that makes tests pass
cargo test <test_name> # Must PASS nowREFACTOR — Improve while keeping tests green:
# Extract constants, add docs, improve error handling
cargo test # Must still PASS
cargo clippy --all-targets --all-features -- -D warnings -W clippy::pedantic -A clippy::module_name_repetitionsTest file pattern:
- Source:
src/foo.rs→ declare#[cfg(test)] mod foo_tests;at the bottom - Tests:
src/foo_tests.rs→ wrap in#[cfg(test)] mod tests { use super::super::*; ... }
Verification: All tests pass, clippy is clean, test covers success path + error paths + edge cases.
When to use:
- After ANY code modification (mandatory for auditing in a regulated environment)
Steps:
Open .claude/CHANGELOG.md and prepend an entry in this exact format:
## [YYYY-MM-DD HH:MM] - Brief Title
**Author:** <Name of requester or approver>
### Changed
- `path/to/file.rs`: Description of the change
### Why
Brief explanation of the business or technical reason.
### Impact
- [ ] Breaking change
- [ ] Requires cluster rollout
- [ ] Config change only
- [ ] Documentation onlyVerification: Entry has **Author:** line (MANDATORY — no exceptions), timestamp, and at least one ### Changed item.
When to use:
- At the end of EVERY task (MANDATORY — same requirement as
cargo-quality) - Before opening a PR
- Any time docs may be out of sync with code
Steps:
For each of the following files, check the YAML examples and field descriptions
against src/crd.rs (source of truth) and examples/*.yaml (reference examples):
docs/src/installation/quickstart.md— YAML example in "Create Your First ScheduledMachine"docs/src/reference/api.md— all Spec Fields, Status Fields, and the top-level example (auto-generated — regenerate withmake crddoc, do not hand-edit)docs/src/advanced/capi-integration.md— Bootstrap/Infrastructure sections and provider examplesdocs/src/concepts/scheduled-machine.md— field tables (types, defaults, required flags)- Any other
.mdfile underdocs/that contains a YAML snippet withkind: ScheduledMachine
What to check:
- Field names match the Rust struct (remember:
snake_casein Rust →camelCasein YAML) - No non-existent fields (common culprits:
machine,bootstrapRef/infrastructureRefat spec level) bootstrapSpecandinfrastructureSpecuse inlinespec:— NOTname:/namespace:refspriorityrange is 0-255 (not 0-100)- Phase values match:
Pending,Active,ShuttingDown,Inactive,Disabled,Terminated,Error - Status field names:
lastScheduledTime,nextActivation,nextCleanup,inSchedule machineRefhasapiVersion,kind,name,namespace— nouid
Verification: No field in any doc example diverges from src/crd.rs.
When to use:
- After any code change in
src/ - After CRD changes, API changes, configuration changes, or new features
Steps:
- Identify what changed (feature, CRD field, behavior, error condition).
- Update
.claude/CHANGELOG.md(seeupdate-changelogskill). - Update affected pages in
docs/:- User guides, quickstart guides, configuration references, troubleshooting guides
- Update
examples/*.yamlto reflect schema or behavior changes. - If CRDs changed: run
regen-api-docsskill (LAST step). - If README getting-started or features changed: update
README.md.
Verification checklist:
-
.claude/CHANGELOG.mdupdated with author - All affected
docs/pages updated - All YAML examples validate:
kubectl apply --dry-run=client -f examples/ - API docs regenerated if CRDs changed
When to use:
- After any CRD schema change
- Before committing changes to
examples/ - As part of the
pre-commit-checklist
Steps:
# Validate all example YAML files
kubectl apply --dry-run=client -f examples/
# Or validate individually
for file in examples/*.yaml; do
echo "Validating $file"
kubectl apply --dry-run=client -f "$file"
doneVerification: All files pass dry-run with no errors. No unknown field or required field missing errors.
When to use:
- When adding a new Custom Resource Definition to the operator
Steps:
- Add the new
CustomResourcestruct tosrc/crd.rs:#[derive(CustomResource, Clone, Debug, Serialize, Deserialize, JsonSchema)] #[kube( group = "5spot.eribourg.dev", version = "v1alpha1", kind = "MyNewResource", namespaced )] #[serde(rename_all = "camelCase")] pub struct MyNewResourceSpec { pub field_name: String, }
- Register it in
src/bin/crdgen.rs. - Run
regen-crdsskill. - Add examples to
examples/. - Run
validate-examplesskill. - Add documentation in
docs/. - Run
regen-api-docsskill (LAST). - Run
cargo-qualityskill. - Run
update-changelogskill.
Verification: kubectl apply --dry-run=client -f deploy/crds/<newresource>.yaml succeeds; API docs include the new resource.
When to use:
- Before committing any change (mandatory gate)
Checklist:
- Tests updated/added/deleted to match changes (TDD — see
tdd-workflow) - All new public functions have tests
- All deleted functions have tests removed
-
cargo fmtpasses -
cargo clippy --all-targets --all-features -- -D warningspasses (fix ALL warnings) -
cargo testpasses (ALL tests green) - Rustdoc comments on all public items, accurate to actual behavior
-
docs/updated for user-facing changes
-
cargo run --bin crdgen > deploy/crds/scheduledmachine.yamlrun -
examples/*.yamlupdated to match new schema -
docs/documentation updated -
kubectl apply --dry-run=client -f examples/passes -
make crddocrun (LAST) — writes todocs/src/reference/api.md(mdBook source)
- Reconciliation flow diagrams updated in
docs/ -
docs/scheduledmachine-lifecycle.rstupdated if phase transitions changed - New behaviors documented in user guides
- Troubleshooting guides updated for new error conditions
-
sync-docsskill passed — no doc/code divergence -
.claude/CHANGELOG.mdupdated with Author: line (MANDATORY) - All YAML examples validate:
kubectl apply --dry-run=client -f examples/ -
kubectl apply --dry-run=client -f deploy/crds/succeeds - No secrets, tokens, credentials, internal hostnames, or IP addresses committed
- No
.unwrap()in production code
- Every open Trivy finding has a corresponding statement in
.vex/(triaged into one of:not_affected,affected,fixed,under_investigation). No silent "unknown" CVEs leave the door. -
./tools/validate-vex.shexits 0. -
./tools/tests/validate-vex-tests.shand./tools/tests/assemble-openvex-tests.shpass. -
.vex/changes referenced in the release notes / changelog.
Verification: Every checked box above passes. A task is NOT complete until the full checklist is green.
When to use:
- When planning a new feature or multi-phase implementation
- When documenting future work or optimization strategies
Steps:
- Create file in
docs/roadmaps/with lowercase, hyphenated filename - Include header with date, status, and impact
- Structure with phases, milestones, or steps
- Add success criteria and verification steps
File naming rules:
- ✅ CORRECT:
docs/roadmaps/integration-test-plan.md - ✅ CORRECT:
docs/roadmaps/phase-1-implementation.md - ❌ WRONG:
ROADMAP.md(root directory) - ❌ WRONG:
docs/roadmaps/PHASE_1.md(uppercase, underscores)
Verification: File exists in docs/roadmaps/, filename is lowercase with hyphens only.
When to use:
- Finding code definitions, usages, or patterns
- Investigating where a function or type is used
Steps:
# Search in Rust files only
rg -trs "<pattern>" . -g '!target/'
# Find function definitions
rg -trs "fn <function_name>" . -g '!target/'
# Find struct definitions
rg -trs "pub struct <StructName>" . -g '!target/'
# Find all usages of a constant
rg -trs "<CONSTANT_NAME>" . -g '!target/'Verification: Results show relevant matches without target/ directory noise.