- Be concise and direct - Avoid repetitive explanations
- Focus on actions, not discussions - Show progress through tool use, not lengthy descriptions
- Skip conversational phrases - No "Great!", "Certainly!", "Okay!" - get straight to the point
- One clear message per concept - Don't repeat the same information in different ways
CRITICAL: These commands MUST pass before any implementation is considered complete:
Exception: if the change is markdown/docs-only and does not modify Go code, generated manifests, Helm/chart behavior, Taskfiles, CI, shell scripts, or any executable/test configuration, you do not need to run the full validation suite below. In that case, limit validation to a quick sanity check of the edited markdown and links.
Run the e2e commands sequentially, not in parallel!
task lint # Must pass golangci-lint checks
task test # Must pass all unit tests + the coverage ratchet (see TESTING REQUIREMENTS)
task test-e2e # Must pass end-to-end teststask lint also runs actionlint on every workflow under .github/workflows/ (via the
lint-actions task) and hadolint on the Dockerfiles (via lint-dockerfiles), so a
workflow or Dockerfile change is covered by the normal lint gate; you can also run
task lint-actions or task lint-dockerfiles directly. actionlint, hadolint, and
golangci-lint all ship in the devcontainer image.
- Check Docker availability for e2e tests: Before running
task test-e2e, verify Docker is running withdocker infoor ask user to start Docker daemon if needed - Always read project context first: Use
read_fileto understand existing patterns in target directories - Search for similar implementations: Use
search_filesto find existing patterns before writing new code - Follow established architecture: Maintain consistency with
internal/directory structure
- Follow Go naming conventions and add godoc comments for exports
- Maintain 120-character line limit (enforced by
.golangci.yml) - Use consistent error handling patterns from existing codebase
- Cover new code with tests; total coverage must not regress (see TESTING REQUIREMENTS)
- Write table-driven tests where appropriate
- Follow kubebuilder patterns and annotations
- Implement idempotent reconciliation logic
- Add appropriate RBAC markers
- Handle finalizers for cleanup
- Implement admission webhook interface correctly
- Add proper validation/mutation logic
- Update webhook configuration in
config/webhook/
- Add kubebuilder validation tags
- Include JSON tags and field descriptions
- Run
task manifeststo update CRDs - Test CRD installation and usage
- Handle Git errors gracefully
- Implement proper conflict resolution
- Add race condition protection
- Use temporary directories for testing
- After editing any workflow, run
task lint-actionsto catch errors withactionlintbefore pushing - A workflow-only change still counts as a CI/config change, so it is not covered by the markdown/docs-only validation exception
- Cover new code with tests (both positive and negative cases)
- Add integration tests for complex workflows
- Follow naming convention:
TestFunctionName_Scenario(t *testing.T)
task testrunscover-check, a self-ratcheting gate: it fails if total unit coverage drops more than a small tolerance below.coverage-baseline(a committed high-water mark).- When coverage improves,
cover-checkauto-raises.coverage-baseline. Commit the bumped file so the floor advances; otherwise the change is just discarded. - e2e coverage of the deployed controller:
E2E_COVERAGE=1 task test-e2ethentask e2e-coverage-collect(writese2e-cover.out). - On PRs, Codecov reports the merged
unit+e2ecoverage (codecov.yml); its project status is a non-regression ratchet (compared to the base commit).
- Update README.md for user-facing changes
- Add/update godoc comments for all exports
- Update API documentation if modifying webhook behavior
- Update API documentation if modifying CRDs
For markdown/docs-only edits, skip this full sequence unless the documentation change depends on or describes behavior you also changed in code/config during the same task.
task fmt- Format codetask generate- Update generated code (if needed)task manifests- Update CRDs (if API changes)task vet- Run go vettask lint- Run golangci-lint (MANDATORY)task test- Run unit tests (MANDATORY)task test-e2e- Run e2e tests (MANDATORY)
- If
task lintfails: Runtask lint-fixfirst - If tests fail: Fix issues; keep total coverage at or above
.coverage-baseline(commit the bump when it auto-raises) - If e2e fails: Check k3d cluster setup and Docker availability
- If Docker not available: Ask user to start Docker daemon before running e2e tests
- Contributing guide:
CONTRIBUTING.md - In the devcontainer, agents may use
ghin read-only mode when the repo-root.envsetsGH_TOKEN. That.envfile is optional, local-only, and must never be committed.