Guidelines for AI agents working on this codebase.
Apache Camel K is a Kubernetes-native integration platform built on Apache Camel. It is a
Go operator plus the kamel CLI that turn user-supplied Camel route Custom Resources
(Integration, Pipe, Kamelet, …) into built container images and running workloads on
Kubernetes/OpenShift.
- Version: not hardcoded — read it from
pkg/util/defaults/defaults.go(Version = "…"), or runmake get-version. - Go: not hardcoded — read the
godirective ingo.mod. - Build:
make(Go toolchain, not Maven) - Module:
github.com/apache/camel-k/v2(seego.mod) - Issue tracker: GitHub Issues (not JIRA)
These rules apply to ALL AI agents working on this codebase.
- All AI-generated content (GitHub PR descriptions, review comments, issue comments) MUST clearly identify itself as AI-generated and mention the human operator. Example: "Claude Code on behalf of [Human Name]"
- An agent MUST NOT open more than 10 PRs per day per operator to ensure human reviewers can keep up.
- Prioritize quality over quantity — fewer well-tested PRs are better than many shallow ones.
- An agent MUST NEVER push commits to a branch it did not create.
- If a contributor's PR needs changes, the agent may suggest changes via review comments, but must not push to their branch without explicit permission.
- An agent should prefer to use its own fork to push branches instead of the main
apache/camel-krepository. It avoids filling the main repository with a long list of uncleaned branches. - An agent must provide a useful branch name following the project conventions:
fix/<ISSUE_NUMBER>,feature/<ISSUE_NUMBER>-<short-slug>,bugfix/<ISSUE_NUMBER>,quick-fix/<short-slug>, orci-issue/<short-slug>. - After a Pull Request is merged or rejected, the branch should be deleted.
- An agent MUST ONLY pick up unassigned GitHub issues.
- If an issue is already assigned to a human, the agent must not reassign it or work on it.
- Before starting work, the agent must assign the issue to its operator.
- Link the PR to the issue (
Fixes #<ISSUE_NUMBER>) so it is closed on merge, and apply the relevant labels/milestone before closing where the project uses them.
When pushing new commits to a PR, always update the PR description (and title if needed) to
reflect the current state of the changeset. PRs evolve across commits — the description must stay
accurate and complete. Use gh pr edit --title "..." --body "..." after each push.
When creating a PR, always identify and request reviews from the most relevant committers:
- Run
git log --format='%an' --since='1 year' -- <affected-files> | sort | uniq -c | sort -rn | head -10to find who has been most active on the affected files. - Use
git blameon key modified files to identify who wrote the code being changed. - Cross-reference with the committer list to ensure you request reviews from active committers (not just contributors).
- For controller/trait/builder changes, prefer reviewers who recently worked on that area.
- For cross-cutting changes (apis, controller, platform), include committers with broader project knowledge.
- Request review from at least 2 relevant committers using
gh pr edit --add-reviewer. - When all comments on the Pull Request are addressed (by providing a fix or more explanation) and the PR checks are green, re-request review so reviewers know the new changeset is ready.
- An agent MUST NOT merge a PR if there are any unresolved review conversations.
- An agent MUST NOT merge a PR without at least one human approval.
- An agent MUST NOT approve its own PRs — human review is always required.
- Every PR must include tests for new functionality or bug fixes.
- Every PR must include documentation updates where applicable.
- All code must be formatted (
make fmtandmake goimport) and passmake lint(golangci-lint) before pushing. - All generated artifacts must be regenerated and committed — run
make generate(codegen, CRDs, deepcopy, RBAC) andmake update-docs(autogenerated trait docs). CI fails if there are uncommitted changes after a build.
Do NOT use time.Sleep() to wait for asynchronous state in tests. It leads to flaky, slow,
and non-deterministic tests. Use polling with a timeout instead — Gomega's Eventually in the
e2e suites, or a bounded poll helper in unit tests.
Example — waiting for an Integration to reach the running phase (e2e):
import (
. "github.com/onsi/gomega"
v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
)
Eventually(IntegrationPhase(t, ctx, ns, "my-it"), TestTimeoutMedium).
Should(Equal(v1.IntegrationPhaseRunning))Rules:
- New test code MUST NOT introduce
time.Sleep()to await state. - When modifying existing test code that sleeps to await state, migrate it to
Eventually. - Always set an explicit timeout to avoid hanging builds.
- Use a clear assertion/predicate — do not replace a sleep with a busy-wait loop.
Before implementing a fix for a GitHub issue, thoroughly investigate the issue's validity and context. Camel K coordinates many moving parts (operator, builds, traits, CRDs, the Camel runtime); code often looks "wrong" but exists for good reasons. Do NOT jump straight to implementation after reading the issue description and the current code.
Required investigation steps:
- Validate the issue: Confirm the reported problem is real and reproducible. Question assumptions in the issue description — they may be incomplete or based on misunderstanding.
- Check git history: Run
git log --oneline <file>andgit blame <file>on the affected code. Read commit messages and linked issues/PRs to understand why the code is the way it is. - Search for related issues: Search GitHub for related issues/PRs (same area, similar keywords) to find prior discussions, rejected approaches, or intentional design decisions.
- Look for design documents: Check the
proposals/directory for design docs (.adoc) that may explain architectural decisions. Key proposals by area:- Security / monitoring (RBAC, metrics endpoint hardening, multi-tenancy):
proposals/monitoring-security.adoc - Kamelets (provided kamelet catalog):
proposals/provided-kamelets.adoc - Service binding:
proposals/service-binding.adoc - Threat model (trust boundaries, what is a vulnerability):
docs/threat-model.md
- Security / monitoring (RBAC, metrics endpoint hardening, multi-tenancy):
- Understand the broader context: If the issue involves a feature that replaced or
deprecated another (e.g.
podtrait, synthetic Integrations, multi-operator), understand why the change was made and what was intentionally changed vs. accidentally omitted. - Check if the "fix" reverts prior work: If your proposed change effectively reverts a prior intentional commit, stop and reconsider. If the revert is still justified, explicitly acknowledge it in the PR description and explain why despite the original rationale.
Present your findings to the operator before implementing. Flag any risks, ambiguities, or cases where the issue may be invalid or the proposed approach may conflict with prior decisions.
AI agents have a training data cutoff and may not know about recent releases, API changes, or deprecations in external projects (Kubernetes, Knative, Quarkus, the Camel runtime). Never make authoritative claims about external project state based solely on training knowledge.
- When an issue, PR, or code references a specific version of an external dependency, verify it exists via official sources before questioning or relying on it.
- When implementing or reviewing changes that depend on external project behavior, verify the current state rather than assuming training data is up to date.
- If uncertain whether something exists or has changed, say so and verify — do not confidently assert something is wrong based on potentially stale knowledge.
When reviewing PRs, apply the same investigative rigor:
- Check
git logandgit blameon modified files to see if the change conflicts with prior intentional decisions. - Verify that "fixes" don't revert deliberate behavior without justification.
- Check for design proposals (
proposals/*.adoc) and the threat model (docs/threat-model.md) related to the affected area. - Search for related GitHub issues that provide context on why the code was written that way.
When writing or modifying .adoc documentation under docs/modules/:
- Use
xref:for internal links, never externalhttps://camel.apache.org/camel-k/...URLs. - Trait reference pages and parts of the docs are autogenerated (see
cmd/util/doc-genand the// Start of autogenerated code - DO NOT EDIT!markers). Do not hand-edit autogenerated blocks; change the Go source and runmake update-docs. - When reviewing doc PRs, check that
xref:links and the Antora nav resolve correctly.
Camel K has a documented threat model that defines who is trusted, where the trust boundaries
sit, what counts as a Camel K vulnerability, and what is operator/deployer responsibility. The
canonical document is docs/threat-model.md. It is the additive
Camel-K sub-project expansion of the umbrella
Apache Camel Security Model, which
explicitly scopes itself to "Camel embedded in someone else's application, not a multi-tenant
managed service" — the Kubernetes operator / Custom Resource / cluster layer is Camel K's to
model. Use docs/threat-model.md (and its docs/threat-model.yaml triage sidecar) when
triaging security reports, deciding whether a finding warrants a CVE, or reviewing a
security-sensitive PR.
For the vulnerability reporting convention, SECURITY.md at the repository
root is the entry point GitHub and security tooling expect. It points to the threat model for
scope and to the ASF process for private disclosure. An agent that discovers or is handed a
suspected vulnerability MUST NOT open a public issue, PR, or mailing-list post about it —
follow the private process in SECURITY.md and stop.
- Platform admins / operator-deployers are fully trusted. They install the operator,
set its RBAC, and edit
IntegrationPlatform/IntegrationProfile(registry, base image, Maven settings, build strategy). Compromise here is total and out of model. - CR authors (whoever can create/patch
Integration,Pipe,Kamelet,IntegrationKit,Build,IntegrationProfile) are trusted only at the target namespace's level. Submitting such a CR is, by design, arbitrary code and container execution in that namespace; the only gate is Kubernetes RBAC. - Cluster tenants without Camel K CR RBAC are untrusted and in scope as adversaries.
- Network clients of the deployed integration are untrusted; the running route's own attack surface is Apache Camel core's threat model, not Camel K's.
- A principal without Camel K CR RBAC causing builds/workloads, or reading another tenant's secrets/artifacts through the operator.
- Cross-namespace / cross-trust escalation via the operator (it can create
roles/rolebindings/clusterrolebindings,serviceaccounts, andpods/exec): any path by which creating a CR in namespace A yields rights in namespace B / cluster-scope the author lacked isVALID. - Camel K weakening or bypassing Kubernetes RBAC as the authorization gate.
- Insecure defaults the operator ships that expose the above with zero extra configuration.
- A CR author running arbitrary code/containers in their own namespace (trusted at that
level — by design, not a vulnerability), incl.
builder.tasks,container.image, thepodtrait,spec.template. - Platform-admin /
IntegrationPlatformeditor actions; a hostile Maven repo / registry / base image / remote Kamelet catalog the deployer chose to trust (supply chain is the deployer's). - The deployed route's own runtime behavior (Apache Camel core's model).
- Behavior reachable only under a non-default, discouraged knob (
registry.insecure, MavenInsecureSkipVerify,routinebuild strategy with untrusted CR authors). - Shipped-but-unsupported code (
examples/,e2e/,proposals/, samples, deprecated Buildah/Kaniko/Spectrum tasks,podtrait, synthetic Integrations, multi-operator). - Automated scanner reports without a PoC demonstrating an actual trust-boundary breach.
When reviewing or recommending a deployment, surface the following:
- Treat "create/patch
Integration/Pipe/Kamelet/IntegrationKit/Build/IntegrationProfilein namespace N" as equivalent to "run arbitrary code in N" — grant that RBAC only to principals trusted at that level. - Lock down
IntegrationPlatform/IntegrationProfileand the install namespace. - For untrusted or multi-tenant CR authors, use the
podbuild strategy, notroutine(which runs the Maven build inside the operator pod). This is required, not advisory. - Provide a trusted Maven proxy/mirror and a controlled registry; never enable
insecure/InsecureSkipVerifyin production. - Apply Kubernetes-native isolation: namespaces, Pod Security Admission, ResourceQuota/LimitRange, NetworkPolicies (Camel K ships none).
- Set
runAsNonRoot/runAsUserexplicitly — the default does not.
When reviewing a PR that touches the operator, a controller, a trait, the builder, RBAC manifests, or a CRD:
- Does a new CR field or trait give a CR author new control over images, commands, mounts,
the raw pod spec, or the build? If so it must be covered by
docs/threat-model.md§4.6. - Does the change widen the operator's RBAC (
secrets,rolebindings,clusterrolebindings,pods/exec, cross-namespace)? Cross-namespace/cross-trust escalation isVALID— justify and minimize. - Does the change add a new external fetch (Maven repo, registry, remote Kamelet catalog, git, HTTP source)? Note it as a supply-chain edge.
- Does it relax a security-relevant default (build strategy,
runAsNonRoot, TLS verify)? New defaults err toward the safer value; a relaxation needs an upgrade note and PMC sign-off, and a matching update todocs/threat-model.md(§4.5a / §4.12). - Does it ship or change an admission webhook? Today there is none by design — adding one moves the §4.4 trust boundary and must be reflected in the threat model.
camel-k/
├── cmd/kamel/ # kamel CLI entrypoint
├── pkg/
│ ├── apis/ # CRD Go types (camel.apache.org/v1)
│ ├── controller/ # reconcilers (integration, integrationkit, build, …)
│ ├── trait/ # traits (how a CR maps to Kubernetes resources)
│ ├── builder/ # build subsystem (Maven, Jib, S2I)
│ ├── cmd/ # CLI + operator command implementations
│ ├── platform/ # IntegrationPlatform defaults & helpers
│ ├── client/ # generated Kubernetes client
│ └── resources/ # embedded manifests (CRDs, RBAC, samples)
├── e2e/ # end-to-end test suites
├── helm/ , install/ # install assets (Helm chart, Kustomize overlays)
├── proposals/ # design proposals (.adoc)
├── docs/ # Antora AsciiDoc docs + threat-model.md / .yaml
└── script/ # Makefile and build scripts
make build # codegen + resources + unit tests + kamel + e2e compile (full)
make build-kamel # build just the kamel CLI binary
make generate # regenerate codegen, CRDs, deepcopy, RBAC
make update-docs # regenerate autogenerated documentation (e.g. trait pages)
make fmt goimport # format Go code and imports
make lint # golangci-lint
make check # lint + vulnerability scan (govulncheck)Do NOT parallelize resource-intensive build/test jobs.
make test # unit tests
make test-common # common e2e suite (requires a cluster)
make test-smoke # smoke e2e suite
# other suites: test-advanced, test-knative, test-kafka, test-gateway,
# test-telemetry, test-install, test-quarkus-native, …E2E suites need a reachable Kubernetes cluster and use Gomega Eventually for asynchronous
assertions (see the async-testing rule above).
- Standard Go conventions:
gofmt/make fmt,go vet, andmake lint(golangci-lint, see.golangci.yml) must pass. - Follow the existing trait pattern in
pkg/traitand the Action/state-machine controller pattern inpkg/controllerrather than inventing new shapes. - Keep CRD Go types in
pkg/apis/camel/v1in sync with generated CRDs/RBAC — runmake generateand commit the result. - Maintain backwards compatibility for public Go APIs and CRD fields; do not change CRD field semantics without a justification and an upgrade note.
- Deprecation: mark Go fields/traits with a
// Deprecated:comment, reflect it in the CRD schema/catalog, and document it in the upgrade notes. Deprecated surface is in limited scope for security (documented migration is the primary remediation); removed surface is out of scope.
Fix #<ISSUE_NUMBER>: Brief description # bug/feature tied to a GitHub issue
chore: Brief description # quick-fix / no issue
ci: Brief description # CI-only change
Reference the GitHub issue (Fixes #<n>) when applicable so it closes on merge.