This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new ed8ebec4201e chore: trim AGENTS.md (CLAUDE.md) to cut its size (#28588)
ed8ebec4201e is described below
commit ed8ebec4201ef3e3a68460e5b891637958168604
Author: Claus Ibsen <[email protected]>
AuthorDate: Wed Oct 28 07:10:11 2026 +0100
chore: trim AGENTS.md (CLAUDE.md) to cut its size (#28588)
AGENTS.md is loaded into every AI agent session, so cut it from 39 KB to
15 KB without dropping rules:
- Security model: keep the trust assumptions and the private-disclosure
rule; point to the in/out of scope lists, the reviewer guidance and the
deployment hardening in security-model.adoc instead of repeating them.
- Merge procedure: keep the merge rules, move the steps to
.oss-ai-helper-rules/project-guidelines.md (which already had them) and
fix the milestone example there (4.24.0-SNAPSHOT -> 4.24.0).
- Shorten the test, issue investigation and documentation sections; fold
git history review and knowledge cutoff into them.
- Remove the repository structure, component layout, links and the
"star the repository" section.
- Adding components: refer to the parent's case in MojoHelper instead of a
list of parent folders that had gone stale.
Signed-off-by: Claus Ibsen <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
---
.oss-ai-helper-rules/project-guidelines.md | 8 +-
AGENTS.md | 764 ++++++-----------------------
2 files changed, 151 insertions(+), 621 deletions(-)
diff --git a/.oss-ai-helper-rules/project-guidelines.md
b/.oss-ai-helper-rules/project-guidelines.md
index 4e982d5166a6..56666e972beb 100644
--- a/.oss-ai-helper-rules/project-guidelines.md
+++ b/.oss-ai-helper-rules/project-guidelines.md
@@ -18,10 +18,10 @@ This rule file contains branching, commit, PR, and
task-finding conventions for
- **Find-task experienced JQL:** `project = CAMEL AND status = Open AND labels
= help-wanted` (maxResults=10)
- **Scope-too-large redirect:** create a Jira issue directly
- **Merge procedure:**
- 1. Derive milestone from target branch: read `<version>` from root `pom.xml`
on the target branch and strip `-SNAPSHOT` (e.g., `4.24.0-SNAPSHOT` → `4.23.0`)
- 2. Assign milestone to PR (`gh pr edit <PR> --milestone <version>`) and set
`fixVersions` on the JIRA issue to the same version (before closing)
+ 1. Derive milestone from target branch: read `<version>` from root `pom.xml`
on the target branch and strip `-SNAPSHOT` (e.g., `4.24.0-SNAPSHOT` → `4.24.0`)
+ 2. Assign milestone to PR (`gh pr edit <PR> --milestone <version>`; if the
milestone does not exist yet, create it with `gh api
repos/{owner}/{repo}/milestones -f title="<version>"`) and set `fixVersions` on
the JIRA issue to the same version (before closing, as it cannot be set on a
closed issue)
3. Assign PR to the PR author (`gh pr edit <PR> --add-assignee <author>`)
and verify JIRA issue is assigned to the contributor. **Never guess the
author** — look it up with `gh pr view <PR> --json author --jq '.author.login'`
- 4. Categorize PR with labels based on JIRA issue type or PR content: `bug`
(Bug), `enhancement` (Improvement/New Feature), `documentation`
(Documentation), `task` (Task/refactoring), `dependency` (dependency upgrades),
`test` (Test)
- 5. Merge the PR (after verifying human approval and no unresolved
conversations)
+ 4. Categorize PR with labels based on JIRA issue type or PR content: `bug`
(Bug; Camel end-user facing fixes only, CI/build/internal fixes are `task`),
`enhancement` (Improvement/New Feature), `documentation` (Documentation),
`task` (Task/refactoring/build), `dependency` (dependency upgrades), `test`
(Test)
+ 5. Merge the PR (`gh pr merge <PR> --squash`, or `--merge` / `--rebase` as
appropriate) after verifying human approval and no unresolved conversations (a
straight-cherry-pick backport PR needs no new approval once CI is green). If
any commit was AI-assisted, the squash-merge commit message MUST keep the AI
co-authorship trailer (e.g., `Co-authored-by: Claude Opus 4.6
<[email protected]>`)
6. Close the JIRA issue (transition to Resolved/Fixed, add comment linking
to merged PR)
7. Delete the PR branch
diff --git a/AGENTS.md b/AGENTS.md
index 5a85c2332565..2db2f3c7c41f 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -1,14 +1,7 @@
# Apache Camel - AI Agent Guidelines
-Guidelines for AI agents working on this codebase.
-
-## Project Info
-
-Apache Camel is an integration framework supporting routing rules in Java, XML
and YAML DSLs.
-
-- Version: 4.24.0-SNAPSHOT
-- Java: 21+
-- Build: Maven 3.9.12+
+Guidelines for AI agents working on this codebase. Apache Camel is an
integration framework supporting routing rules in
+Java, XML and YAML DSLs. Java 21+, Maven 3.9.12+.
## AI Agent Rules of Engagement
@@ -19,9 +12,8 @@ These rules apply to ALL AI agents working on this codebase.
- All AI-generated content (GitHub PR descriptions, review comments, JIRA
comments) MUST clearly
identify itself as AI-generated and mention the human operator.
Example: "_Claude Code on behalf of [Human Name]_"
-- **Never guess or hallucinate the operator's name.** Always determine it
programmatically:
- - Use `gh api /user --jq '.login'` to get the authenticated GitHub username.
- - If for any reason the lookup fails, omit the name rather than guessing.
+- **Never guess or hallucinate the operator's name.** Look it up with `gh api
/user --jq '.login'`;
+ if the lookup fails, omit the name.
- AI coding agents MUST be configured to add co-authorship trailers to commits
(e.g., `Co-authored-by`). For Claude Code, enable this via the
[attribution
settings](https://code.claude.com/docs/en/settings#attribution-settings).
@@ -33,539 +25,156 @@ These rules apply to ALL AI agents working on this
codebase.
### Git branch
-- 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 MUST use its own fork to push branches instead of the main
apache/camel repository.
- Pushing directly to the upstream repo fills it with stale branches that
waste CI time and disk
- space for all contributors. A `pr-cleanup-branches.yml` workflow deletes
non-protected branches
- when their PR is closed, but using a fork avoids the problem entirely.
-- An agent must provide a useful name for the git branch. It should contain
the global topic and issue number if possible.
-- After a Pull Request is merged or rejected, the branch MUST be deleted. The
- `pr-cleanup-branches.yml` workflow handles this automatically for branches
pushed directly to
- `apache/camel`, but agents using forks must delete their remote branch
manually.
+- An agent MUST NEVER push commits to a branch it did not create. If a
contributor's PR needs changes,
+ suggest them via review comments; do not push to their branch without
explicit permission.
+- An agent MUST push branches to its own fork, not to apache/camel (stale
upstream branches waste CI time and
+ disk space for all contributors).
+- Give the branch a useful name, with the topic and the issue number if
possible.
+- After a PR is merged or rejected, delete the branch. The
`pr-cleanup-branches.yml` workflow only cleans up
+ branches pushed to `apache/camel`; branches on a fork must be deleted
manually.
### JIRA Ticket Ownership
-- An agent MUST ONLY pick up **Unassigned** JIRA tickets.
-- If a ticket is already assigned to a human, the agent must not reassign it
or work on it.
-- Before starting work, the agent must assign the ticket to its operator and
transition it to "In Progress".
- The CAMEL workflow (ASF JIRA) uses these numeric transition IDs:
- - `4` → Start Progress (In Progress)
- - `5` → Resolve Issue (Resolved)
- - `2` → Close Issue (Closed)
-
- Still query the issue's `/transitions` endpoint before firing one of these
IDs. Availability
- depends on both the current state and on the caller — `4` is only offered
once the issue is
- assigned to you, which is why the assign step above comes first. The list
saves a lookup, it
- does not replace the availability check.
-- Before closing a ticket, always set the correct `fixVersions` field.
- Note: `fixVersions` cannot be set on an already-closed issue — set it before
closing,
- or reopen/set/close if needed.
-
-### PR Description Maintenance
-
-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.
-
-### PR Reviewers
-
-When a PR is **ready for review** (not in draft), **always identify and
request reviews** from
-the most relevant committers. **Do NOT request reviewers on draft PRs** — wait
until the PR is
-marked ready for review.
-
-- Run `git log --format='%an' --since='1 year' -- <affected-files> | sort |
uniq -c | sort -rn | head -10`
- to find who has been most active on the affected files.
-- Use `git blame` on key modified files to identify who wrote the code being
changed.
-- Cross-reference with the [committer
list](https://home.apache.org/committers-by-project.html#camel)
- to ensure you request reviews from active committers (not just contributors).
-- For component-specific changes, prefer reviewers who have recently worked on
that component.
-- For cross-cutting changes (core, API), 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
providing more explanation) and the PR checks are green, re-request review on
existing reviewers so that they are aware that the new changeset is ready to be
reviewed.
-- **Exception — backport PRs:** do not request reviewers on a PR that is a
straight backport
- (cherry-pick) of a PR already reviewed and merged on `main`. See "Backport
PRs" below.
-
-### Backport PRs
-
-A backport PR that cherry-picks a commit from a PR already reviewed and merged
on `main` onto an
-older LTS maintenance branch (e.g. `camel-4.14.x`, `camel-4.18.x`) does not
need a fresh review —
-the code change already went through human review on the PR it was backported
from.
-
-- A backport PR MUST NOT be assigned any reviewers.
-- A backport PR MAY be merged as-is, once CI is green, without waiting for a
new human approval.
- This is the one exception to the "at least one human approval" rule in
"Merge Requirements" below.
-- This exception applies only to straight cherry-picks. If a backport required
manual conflict
- resolution that changed the code beyond a mechanical port, treat it as a
normal PR and request
- review.
-- **Verifying a straight cherry-pick:** diff the backport PR against the
original PR it was
- cherry-picked from — an empty (or whitespace/context-only) diff confirms a
mechanical port.
- ```bash
- gh pr diff <backport-pr> --repo apache/camel > /tmp/backport.diff
- gh pr diff <original-pr> --repo apache/camel > /tmp/original.diff
- diff /tmp/backport.diff /tmp/original.diff
- ```
- Any semantic difference means the backport diverged from the original —
treat it as a normal
- PR and request review.
+- An agent MUST ONLY pick up **Unassigned** JIRA tickets, and must not
reassign or work on a ticket assigned to a human.
+- Before starting work, assign the ticket to the operator and transition it to
"In Progress".
+ CAMEL transition IDs: `4` Start Progress, `5` Resolve Issue, `2` Close
Issue. Query the issue's `/transitions`
+ first: availability depends on the state and the caller (`4` is only offered
once the issue is assigned to you).
+- Set the `fixVersions` field before closing a ticket (it cannot be set on a
closed issue).
+
+### Pull Requests
+
+- When pushing new commits, **always update the PR description** (and title if
needed) so it describes the current
+ changeset: `gh pr edit --title "..." --body "..."`.
+- When a PR is **ready for review** (not draft), request review from **at
least 2 relevant committers**
+ (`gh pr edit --add-reviewer`). Find them with
+ `git log --format='%an' --since='1 year' -- <affected-files> | sort | uniq
-c | sort -rn | head -10` and `git blame`,
+ and check the [committer
list](https://home.apache.org/committers-by-project.html#camel). Prefer
committers active on
+ the component; for core/API changes include committers with broader project
knowledge.
+- Once all comments are addressed and checks are green, re-request review from
the existing reviewers.
+- **Backport PRs:** a straight cherry-pick of a PR already reviewed and merged
on `main` onto an LTS maintenance branch
+ (e.g. `camel-4.18.x`) gets **no reviewers** and MAY be merged once CI is
green without a new human approval.
+ Verify it is a straight cherry-pick by diffing the two PRs (`gh pr diff
<backport-pr>` vs `gh pr diff <original-pr>`);
+ any semantic difference, or a conflict resolution beyond a mechanical port,
makes it a normal PR that needs review.
### Doing a review
-When an AI agent is doing a review:
-
-- Wait until PR checks are green as they will already catch most trivial
issues using less resources
-- It must challenge the code and ensure that it respects all conventions
-- For Dependabot PRs, either do not review them or be able to do a real
review: check for deprecated APIs, removed features, or breaking changes in the
changelog
-
-### Merge Requirements
-
-- 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**
- (exception: backport PRs — see "Backport PRs" above).
-- An agent MUST NOT approve its own PRs — human review is always required.
-
-### Merge Procedure
-
-When merging a PR, an agent MUST perform the following steps **in order**:
-
-1. **Derive the milestone from the target branch**:
- - Read the `<version>` from the root `pom.xml` on the PR's **target
branch** (e.g., `main`,
- `camel-4.18.x`).
- - Strip the `-SNAPSHOT` suffix to get the milestone name (e.g.,
`4.24.0-SNAPSHOT` → `4.23.0`).
-
-2. **Assign the milestone**:
- - Set the GitHub milestone on the PR: `gh pr edit <PR> --milestone
<version>`.
- - If the milestone does not exist yet on GitHub, create it first:
- `gh api repos/{owner}/{repo}/milestones -f title="<version>"`.
- - Set `fixVersions` on the corresponding JIRA issue to the same version.
Note: `fixVersions`
- cannot be set on an already-closed issue — always set it **before**
closing.
-
-3. **Assign the PR and JIRA issue to the contributor**:
- - **Never guess or hallucinate the PR author's username.** Always look it
up programmatically:
- `gh pr view <PR> --json author --jq '.author.login'`.
- - Assign the PR to the PR author on GitHub: `gh pr edit <PR> --add-assignee
<author>`.
- - Ensure the JIRA issue is assigned to the contributor (it should already
be from the
- "JIRA Ticket Ownership" rules, but verify).
-
-4. **Categorize the PR with labels**:
- - Determine the PR category from the linked JIRA issue type or PR content:
- - `bug` — for Camel end user facing bug fixes (JIRA type: Bug) - any CI,
build system or internal project managed should be categorized as `task`.
- - `enhancement` — for improvements and new features (JIRA type:
Improvement, New Feature)
- - `documentation` — for documentation-only changes (JIRA type:
Documentation)
- - `task` — for chores, refactoring, build changes (JIRA type: Task)
- - `dependency` — for dependency upgrades
- - `test` — for test-only changes (JIRA type: Test)
- - Apply the label: `gh pr edit <PR> --add-label <category>`.
-
-5. **Merge the PR**:
- - Verify all merge requirements above are satisfied (human approval, no
unresolved conversations).
- Exception: a straight-cherry-pick backport PR (see "Backport PRs" above)
may be merged without
- a new human approval once CI is green.
- - If any commit in the PR was AI-assisted, the squash-merge commit message
MUST include the
- AI co-authorship trailer (e.g., `Co-authored-by: Claude Opus 4.6
<[email protected]>`).
- - Merge the PR: `gh pr merge <PR> --squash` (or `--merge` / `--rebase` as
appropriate).
-
-6. **Close the JIRA issue**:
- - Transition the JIRA issue to **Resolved/Fixed** (ensure `fixVersions` is
already set from step 2).
- The transition IDs are listed under "JIRA Ticket Ownership" above.
- - Add a comment linking to the merged PR.
-
-7. **Clean up the branch**:
- - Delete the PR branch after merge (GitHub may do this automatically if
configured).
- - As per the "Git branch" rules, branches must be cleaned up after merge or
rejection.
+- Wait until PR checks are green as they will already catch most trivial
issues using less resources.
+- Challenge the code and ensure that it respects all conventions. Check `git
log` / `git blame` and the design docs (see
+ "Issue Investigation") so a "fix" does not revert a deliberate decision
without justification.
+- For Dependabot PRs, either do not review them or do a real review: check for
deprecated APIs, removed features, or
+ breaking changes in the changelog.
+
+### Merging
+
+- An agent MUST NOT merge a PR with **unresolved review conversations**, or
without at least **one human approval**
+ (exception: straight-cherry-pick backport PRs, see above).
+- An agent MUST NOT approve its own PRs.
+- Follow the merge procedure in
[`.oss-ai-helper-rules/project-guidelines.md`](.oss-ai-helper-rules/project-guidelines.md)
+ (milestone, assignee, label, squash-merge, resolve JIRA, delete branch).
### Code Quality
- Every PR must include tests for new functionality or bug fixes.
-- Every PR must include documentation updates where applicable.
- New features must be documented in the relevant command or component
documentation page.
- Changes that affect existing users upgrading must also be documented in the
upgrade guide
- (`docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_XX.adoc`).
This includes:
- changed defaults, new auto-detection behavior, removed or renamed options,
changed header
- names or values, API/SPI signature changes, removed or deprecated
components, migrated
- libraries, and renamed documentation pages. The upgrade guide is for
migration only — do
- NOT add new features to it.
- For backported changes, the upgrade guide entry must be added on the `main`
branch (not on the
- maintenance branch where the fix is backported).
+- Every PR must include documentation updates where applicable; new features
are documented in the relevant command or
+ component page.
+- Changes that affect users upgrading go in the upgrade guide
+ (`docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_XX.adoc`):
changed defaults, new auto-detection,
+ removed or renamed options, changed header names or values, API/SPI
signature changes, removed or deprecated
+ components, migrated libraries, renamed documentation pages. It is for
migration only, not new features. For
+ backported changes, add the entry on `main`.
- All code must pass formatting checks (`mvn formatter:format impsort:sort`)
before pushing.
- All generated files must be regenerated and committed (CI checks for
uncommitted changes).
+- Avoid introducing static analysis issues (code smells, maintainability
regressions, CWE/OWASP weaknesses) and the
+ use of deprecated code.
-### Quality Expectations
-
-- Even if static analysis is not executed during contribution validation,
contributions should avoid introducing new static code analysis issues such as:
- - code smells
- - maintainability regressions
- - CWE (Common Weakness Enumeration)
- - Top OWASP vulnerabilities and security flows
- - Avoid usage of deprecated code
-- Changes should aim to preserve or improve overall code quality.
-
-### Assertions: Use AssertJ When Possible
-
-Prefer [AssertJ](https://assertj.github.io/doc/) assertions over JUnit
assertions in test code.
-AssertJ is already available as a test dependency in the project and provides
more readable,
-fluent assertions with better failure messages.
-
-**Examples:**
-
-```java
-// Preferred — AssertJ:
-assertThat(result).isEqualTo("expected");
-assertThat(list).hasSize(3).contains("a", "b");
-assertThat(exception).isInstanceOf(IOException.class).hasMessageContaining("timeout");
-assertThat(exchange.getIn().getBody(String.class)).startsWith("Hello");
-
-// Avoid — JUnit:
-assertEquals("expected", result);
-assertEquals(3, list.size());
-assertTrue(list.contains("a"));
-```
-
-**Rules:**
-
-- New test code is preferred to use AssertJ assertions (`assertThat(...)`)
instead of JUnit assertions
- (`assertEquals`, `assertTrue`, `assertFalse`, `assertNotNull`, etc.).
-- Do NOT mix styles within a project/module. Check the assertion style already
used by the other
- test classes in the component/module being touched: if they are
predominantly JUnit assertions,
- write new tests in that same JUnit style rather than introducing AssertJ as
an outlier. Only
- default to AssertJ when the module has no established convention either way.
-- When modifying existing test code that uses JUnit assertions, migrate
touched assertions to
- AssertJ where it improves readability and the surrounding module isn't
predominantly JUnit.
- No need to migrate the entire file.
-- Do NOT mix AssertJ and JUnit assertions in the same test method — pick one
style per method.
-- `MockEndpoint.assertIsSatisfied()` and other Camel-specific assertion
methods are NOT JUnit
- assertions — keep using them as-is.
-
-### Asynchronous Testing: Use Awaitility Instead of Thread.sleep
-
-Do **NOT** use `Thread.sleep()` in test code. It leads to flaky, slow, and
non-deterministic tests.
-Use the [Awaitility](https://github.com/awaitility/awaitility) library
instead, which is already
-available as a test dependency in the project.
-
-**Example — waiting for a route to be registered:**
-
-```java
-import static org.awaitility.Awaitility.await;
-
-await().atMost(20, TimeUnit.SECONDS)
- .untilAsserted(() -> assertEquals(1, context.getRoutes().size()));
-```
-
-**MockEndpoint tests — prefer built-in timed assertions:**
-
-When the wait condition is "mock expectations are met", use `MockEndpoint`'s
native timed
-assertion instead of wrapping with Awaitility. It is latch-based (more
efficient than polling)
-and requires no external dependency:
-
-```java
-// Preferred — native, latch-based, returns as soon as expectations are met:
-MockEndpoint.assertIsSatisfied(context, 10, TimeUnit.SECONDS);
-
-// Also available on a single endpoint:
-mock.setResultWaitTime(TimeUnit.SECONDS.toMillis(10));
-mock.assertIsSatisfied();
-
-// DO NOT wrap MockEndpoint assertions with Awaitility — it polls a mechanism
that already waits:
-// await().atMost(10, TimeUnit.SECONDS).untilAsserted(() ->
MockEndpoint.assertIsSatisfied(context));
-```
-
-Note: `MockEndpoint.assertIsSatisfied(context)` (no timeout argument) already
waits up to
-10 seconds internally — `waitForCompleteLatch` defaults to 10 000 ms when
`resultWaitTime`
-is not set. The timed overload is only needed when you want a **different**
timeout.
-
-Use Awaitility only when waiting on a condition that `MockEndpoint` cannot
express natively,
-such as waiting for a specific received count mid-test before performing the
next action:
-
-```java
-// Awaitility IS appropriate here — no MockEndpoint API for "wait until N
received" without asserting:
-await().atMost(10, TimeUnit.SECONDS).until(() -> mock.getReceivedCounter() >=
2);
-```
+### Test Code
-**Rules:**
-
-- New test code MUST NOT introduce `Thread.sleep()` calls.
-- When modifying existing test code that contains `Thread.sleep()`, migrate it
to
- `MockEndpoint`'s timed assertions (for mock-based waits) or Awaitility (for
other conditions).
-- Do NOT wrap `MockEndpoint.assertIsSatisfied()` with Awaitility — it already
waits internally
- via a `CountDownLatch`. Wrapping it with `untilAsserted` adds polling on top
of a mechanism
- that already blocks, which is redundant and less efficient.
-- Always set an explicit `atMost` timeout to avoid hanging builds.
-- Use `untilAsserted` or `until` with a clear predicate — do not replace a
sleep with a
- busy-wait loop.
+- Prefer AssertJ (`assertThat(...)`) over JUnit assertions, but match the
module: if its tests predominantly use JUnit
+ assertions, write new tests in that style. Never mix both styles in one test
method. When touching JUnit assertions in
+ a module that is not predominantly JUnit, migrate them where it helps
readability.
+- Never add `Thread.sleep()`; when touching a test that has one, replace it.
For mock expectations use
+ `MockEndpoint.assertIsSatisfied(context)` (it already waits 10 seconds) or
the timed overload
+ `assertIsSatisfied(context, 20, TimeUnit.SECONDS)`. Never wrap a
`MockEndpoint` assertion in Awaitility.
+- For any other condition use Awaitility with an explicit `atMost`, e.g.
+ `await().atMost(10, TimeUnit.SECONDS).until(() -> mock.getReceivedCounter()
>= 2)`.
+- `MockEndpoint` assertions are Camel assertions, not JUnit ones — keep using
them.
### Issue Investigation (Before Implementation)
-Before implementing a fix for a JIRA issue, **thoroughly investigate** the
issue's validity and context.
-Camel is a large, long-lived project — 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:**
-
-1. **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.
-2. **Check git history**: Run `git log --oneline <file>` and `git blame
<file>` on the affected code.
- Read the commit messages and linked JIRA tickets for prior changes to
understand *why* the code
- is written the way it is.
-3. **Search for related issues**: Search JIRA for related tickets (same
component, similar keywords)
- to find prior discussions, rejected approaches, or intentional design
decisions.
-4. **Look for design documents**: Check the `design/` directory for design
docs (`.adoc` files)
- that may explain architectural decisions in the affected area. Key
documents by area:
- - **Security** (secrets, SSL/TLS, serialization, policy enforcement):
[`design/security.adoc`](design/security.adoc)
- - **Tracing / Telemetry** (OpenTelemetry, spans, context propagation):
[`design/tracing.adoc`](design/tracing.adoc)
- - **MDC / Logging** (MDC propagation, logging context):
[`design/mdc.adoc`](design/mdc.adoc)
- - **Headers** (naming conventions, constants, upgrade policy):
[`design/headers.adoc`](design/headers.adoc)
- - **Cross-cutting features** (onException, interceptors, onCompletion,
route configurations and how they bind to routes):
[`design/cross-cutting-binding.adoc`](design/cross-cutting-binding.adoc)
- - **Chaos** (proposed; `camel-chaos`: faults turned on in a running
application, the send and step hooks in camel-core, `camel.chaos.*` options,
the report): [`design/chaos.adoc`](design/chaos.adoc)
- - **Java DSL parsing** (reading Java routes into the model without
compiling them, `LwJavaParser`, its safety rules):
[`design/java-dsl-parser.adoc`](design/java-dsl-parser.adoc)
-5. **Understand the broader context**: If the issue involves a module that
replaced or deprecated
- another (e.g., `camel-opentelemetry2` replacing `camel-opentelemetry`),
understand *why* the
- replacement was made and what was intentionally changed vs. accidentally
omitted.
-6. **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.
-
-### Knowledge Cutoff Awareness
-
-AI agents have a training data cutoff and may not know about recent releases,
API changes, or
-deprecations in external projects. **Never make authoritative claims about
external project state
-based solely on training knowledge.**
-
-- When a JIRA issue, PR, or code references a specific version of an external
dependency (e.g.,
- Spring Boot 4.0, JUnit 6, Jakarta EE 11), **verify it exists** by checking
official sources
- (web search, Maven Central, release notes) 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 about whether something exists or has changed, say so and
verify — do not
- confidently assert something is wrong based on potentially stale knowledge.
-
-### Git History Review (When Reviewing PRs)
-
-When reviewing PRs, apply the same investigative rigor:
-
-- Check `git log` and `git blame` on 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 documents (`design/*.adoc`) related to the affected area
- (see the area-to-document mapping in "Issue Investigation" above).
-- Search for related JIRA tickets that provide context on why the code was
written that way.
+Camel is a large, long-lived project — code often looks "wrong" but exists for
good reasons. Before implementing a fix:
+
+1. **Validate the issue**: confirm the problem is real and reproducible;
question the issue's assumptions.
+2. **Check git history**: `git log --oneline <file>` and `git blame <file>`,
and read the linked JIRA tickets.
+3. **Search JIRA** for related tickets, prior discussions and rejected
approaches.
+4. **Read the design docs** in `design/` for the area:
+ [`security.adoc`](design/security.adoc) (secrets, SSL/TLS, serialization,
policy enforcement),
+ [`tracing.adoc`](design/tracing.adoc) (OpenTelemetry, spans, context
propagation),
+ [`mdc.adoc`](design/mdc.adoc) (MDC, logging context),
+ [`headers.adoc`](design/headers.adoc) (header naming, constants, upgrade
policy),
+ [`cross-cutting-binding.adoc`](design/cross-cutting-binding.adoc)
(onException, interceptors, onCompletion, route
+ configurations), [`chaos.adoc`](design/chaos.adoc) (proposed `camel-chaos`),
+ [`java-dsl-parser.adoc`](design/java-dsl-parser.adoc) (`LwJavaParser`,
reading Java routes without compiling them).
+5. **Understand the broader context**: if a module replaced another (e.g.
`camel-opentelemetry2`), understand what was
+ intentionally changed vs. accidentally omitted.
+6. **Check if the fix reverts prior work**: if so, stop and reconsider; if
still justified, say so in the PR description.
+
+**Present your findings** to the operator before implementing, flagging risks,
ambiguities, or conflicts with prior
+decisions.
+
+Training data has a cutoff: verify the state of external projects (versions,
APIs, deprecations) against official
+sources before relying on it or calling something wrong.
### Documentation Conventions
-When writing or modifying `.adoc` documentation:
-
-- **Use `xref:` for internal links**, never external
`https://camel.apache.org/...` URLs.
- Example: `xref:manual::camel-jbang.adoc[Camel CLI]` instead of
- `https://camel.apache.org/manual/camel-jbang.html[Camel CLI]`.
-- **Cross-version xref fragments**: When linking to a section anchor (e.g.,
`#_my_section`) using
- the `components::` prefix, verify that the target section exists in the
**current released version**,
- not just on `main`. The `components::` prefix resolves to the latest
released version, so anchors
- that only exist on `main` will produce broken links. Either omit the
fragment or use a
- version-aware reference.
-- **When reviewing doc PRs**, check that all `xref:` links and anchors resolve
correctly, especially
- cross-component references that may span versions.
-- **Avoid explicit `[[anchor]]` blocks before a heading.** AsciiDoc already
auto-generates an id from
- the heading text (prefixed with `_`, e.g. `=== Structured error exchange
properties` becomes
- `#_structured_error_exchange_properties`). An explicit
`[[structured_error_exchange_properties]]`
- anchor sets the id *without* that prefix, so it silently diverges from the
id every other `xref:`
- in the codebase expects and breaks the website link checker. Only add an
explicit anchor when a
- stable id is needed that must survive a heading rename — never as a matter
of habit.
-- **Component doc changes require regenerating the catalog.** Editing a
component's
- `src/main/docs/*.adoc` also requires regenerating and committing the
mirrored copy under
-
`catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/`.
CI's
- "uncommitted changes" check fails otherwise — this applies even to small
doc-only edits like
- removing an anchor, not just code-driven metadata changes.
+- Use `xref:` for internal links, never `https://camel.apache.org/...` URLs
+ (e.g. `xref:manual::camel-jbang.adoc[Camel CLI]`).
+- `components::` xrefs resolve to the latest **released** version: only link
to a section anchor that exists there.
+ Check this when reviewing doc PRs too.
+- Do not add an explicit `[[anchor]]` before a heading: it replaces the
auto-generated `_`-prefixed id that other xrefs
+ expect and breaks the website link checker. Only add one when an id must
survive a heading rename.
+- Editing a component's `src/main/docs/*.adoc` requires regenerating and
committing the copy under
+
`catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/`,
even for small edits.
## Security Model
-Camel has a documented threat model that defines who is trusted, where the
trust boundaries sit,
-what counts as a framework vulnerability, and what is operator responsibility.
The canonical
-document is
[`docs/user-manual/modules/ROOT/pages/security-model.adoc`](docs/user-manual/modules/ROOT/pages/security-model.adoc).
-Use it as the reference when triaging security reports, deciding whether a
finding warrants a
-CVE, or reviewing a security-sensitive PR.
-
-For the vulnerability **reporting** convention, [`SECURITY.md`](SECURITY.md)
at the repository
-root is the entry point GitHub and security tooling expect. It points to the
threat model above
-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.
-
-### Trust assumptions
-
-- **Camel committers and component authors** are trusted to ship secure
defaults.
-- **Route authors** (the people writing DSL routes) are **fully trusted**.
They execute arbitrary
- Java in `.bean()` / `.process()`, evaluate arbitrary expressions in `simple`
/ `groovy` / `jexl`
- / `mvel` / `xpath`, and configure every component option. Code execution by
a route author is
- by design and is **not** a vulnerability.
-- **Deployment operators** are **fully trusted**. They set configuration,
secrets, network
- exposure and the JVM. Their misconfiguration is not a framework
vulnerability unless Camel's
- default exposed it.
-- **External message senders** (HTTP clients, JMS producers, file droppers,
SMTP senders, CoAP
- peers, etc.) are **untrusted**. This is the primary attacker model.
-
-The fundamental trust boundary is between **the route plus its configuration**
(trusted) and
-**the data flowing through the route** (untrusted). The framework must not
turn untrusted data
-into code execution, file read, request forgery, or auth bypass on its own.
-
-### What is in scope (concise summary)
-
-Reports that demonstrate untrusted input crossing a trust boundary the
framework should have
-held — in a default or reasonably-expected configuration — are in scope.
Concrete classes the
-PMC has historically accepted:
-
-- **Unsafe deserialisation** of untrusted input (XStream / Hessian / Jackson
polymorphic / raw
- `ObjectInputStream` in consumers, type converters, aggregation repositories,
key stores).
-- **XXE** and remote DTD/stylesheet resolution in XML/XSLT/XPath/XSD parsers.
-- **Expression or template language injection** where the framework itself
passes untrusted
- input to an evaluator (not the route author), including an expression taken
from a control
- message and property placeholders resolved in message content.
-- **Path traversal** in file/mail/FTP consumers and producers, including names
a remote server
- reports back (object keys, directory listings) on both the local and the
remote side.
-- **Request forgery and credential forwarding**: SSRF by parser default
resolution, a message
- body read as a URL or path, a peer-supplied callback address, credentials
re-sent on a redirect.
-- **Camel-header / bean-dispatch abuse** when a consumer maps untrusted input
into the Exchange
- header map without a strict, case-insensitive `HeaderFilterStrategy`.
-- **Auth/authz bypass** in components implementing AAA (Keycloak, Shiro,
platform-http auth,
- Spring Security integration).
-- **Integrity or signature verification that can be skipped** (a sender-chosen
downgrade, a
- verifier shared between exchanges).
-- **State shared between exchanges** that carries another party's data, keys
or authority.
-- **Information disclosure** of secrets or Exchange state via logs, events,
files other local
- accounts can read, HTTP responses, or route exceptions returned to the
caller.
-- **Insecure defaults** — any component shipping with deserialisation,
TLS-skip or admin-exposure
- enabled out of the box, including the stock settings of a library object
Camel builds to do its
- own work (a serializer, a filter, a parser factory).
-- **Injection into back-end queries** built by Camel itself (Cypher, XSLT
extension functions,
- etc.).
-- **Tooling that reads route sources without running them** (`LwJavaParser`,
the project overview,
- the TUI Architecture view, the `camel_project_overview` MCP tool) running
code from the source,
- loading its classes, resolving its secrets, reaching the network or not
finishing. Running the
- routes is the trusted route-author case.
-
-### What is out of scope
-
-The following are explicitly **not** framework vulnerabilities and will be
closed as such:
-
-- A **route author** executing arbitrary code through `.bean()`, `.process()`,
`Runtime.exec()`,
- or evaluating `simple` / `groovy` on untrusted input. Route code is trusted.
-- A route author building a SQL / Cypher / LDAP / HTTP URI from untrusted
input without
- parameterising. The route is at fault, not the framework.
-- Behaviour that is enabled by **explicit opt-in**:
`allowJavaSerializedObject=true`,
- `transferException=true`, `trustAllCertificates=true`,
`hostnameVerificationEnabled=false`,
- selecting an `ObjectInputStream`-using data format, or another option listed
under
- "Per-option opt-ins" in the security model (e.g.
`allowPredicateFromMessage=true`).
-- **DoS / resource exhaustion** through unthrottled routes. Operators apply
`throttle`,
- `circuitBreaker`, `resilience4j`, JVM limits.
-- A deployer exposing `camel-management`, the developer console,
`camel-jolokia` or JMX on a
- public network. A Camel endpoint fed by messages, such as
`dynamic-router-control:`, is not a
- management surface.
-- Third-party transitive dependency CVEs that are not reachable through any
Camel-exposed code
- path.
-- Automated scanner reports without a PoC demonstrating an actual
trust-boundary breach.
-- An **AI assistant in Camel TUI** (the AI panel's model, an ACP agent, an MCP
client) using the
- TUI's tools without asking, even after a prompt injection. Camel CLI and
Camel TUI are developer
- tools on the developer's own machine; the TUI asks first only before a file
write (its write
- mode), a message to an endpoint the integration does not have or with a body
read from a file
- outside the project, SQL that is not a `SELECT`, and a code-running
expression language such as
- Groovy. A tool breaking that contract is in scope. See
- "Developer tools" in the security model.
-
-### Operator hardening checklist
-
-When reviewing or recommending a deployment, surface the following:
-
-- Enable the security policy framework: set `camel.main.profile = prod` so the
default for
- `secret` / `insecure:ssl` / `insecure:serialization` / `insecure:dev` is
`fail`
- (see [`design/security.adoc`](design/security.adoc)).
-- Resolve secrets through one of the supported vaults rather than plain-text
properties.
-- Configure TLS through `SSLContextParameters` (the JSSE Utility); never
`trustAllCertificates`
- in production.
-- Strip Camel-internal headers (`Camel*`, `org.apache.camel.*`) from messages
arriving from
- untrusted producers using `removeHeaders("Camel*")` before any dispatching
processor.
-- Do not enable Java serialisation on consumers exposed to untrusted networks.
-- Keep `camel-management`, the developer console, `camel-jolokia` and JMX on a
trusted network
- only.
-- Restrict outbound network access to the hosts the routes need; it contains
the
- request-forgery family whatever triggers it.
-
-### Committer review checklist (for security-sensitive PRs)
-
-When reviewing a PR that touches a consumer, type converter, aggregation
repository, data
-format, parser, or anything that handles `@UriParam` security knobs:
-
-- Does the inbound side apply a `HeaderFilterStrategy` that blocks `Camel*` /
`camel*` /
- `org.apache.camel.*` **case-insensitively**? The header-injection family
(CVE-2025-27636 and
- five follow-ons) recurred precisely because new consumers shipped without it.
-- Does the change call `ObjectInputStream.readObject()` (directly or via
Hessian/Castor/XStream)
- without an `ObjectInputFilter`? Five sequential CVEs (CVE-2024-22369, 23114,
2026-25747, 27172,
- 40858) accepted this exact pattern in aggregation repositories.
-- Does any new `@UriParam` control a security-relevant default? If so, mark it
with
- `secret = true` for secrets or `security = "insecure:ssl"` /
`"insecure:serialization"` /
- `"insecure:dev"` for risky flags (see the `Annotations` subsection further
down).
-- Does the change relax a default? New defaults err toward "denied unless
opted in". A relaxed
- default needs an upgrade-guide entry and PMC sign-off.
-- Does an authentication or authorization component enforce what its option
names claim — issuer
- validation, audience checking, signature verification, every advertised
sub-path covered — and
- fail closed when the option or the claim is absent?
-- Does the change resolve property placeholders in message content, or compile
an expression or
- a language name taken from a message? Placeholder resolution belongs to
route and configuration
- text, not to message content (CVE-2026-78164); code from a message needs an
endpoint opt-in that
- no header can set (CVE-2026-83531).
-- Can the component present credentials to a host the route did not configure
— a redirect
- target, a peer-supplied callback or receipt address (CVE-2026-85251,
CVE-2026-80344)?
-- Does a verifier fail closed when the sender omits the protection, and keep
stateful verifier
- objects per exchange (CVE-2026-85243, CVE-2026-85248)?
-- Does the component build a third-party object to do its own work (a
serializer, a CORS filter,
- a JAXP factory) with the library's stock defaults? Those defaults ship as
Camel's
- (CVE-2026-78165, CVE-2026-85313, CVE-2026-91858).
-- Can a consumer with a reply path return the route's exception to the caller?
It needs a
- `muteException` option defaulting to `true`; faults the service contract
declares are the
- exception.
-- Does the change add a public method to the route builder (`RouteBuilder`,
`BuilderSupport`,
- `RouteConfigurationBuilder`) or the static DSL (`Builder`,
`PredicateBuilder`, `AggregationStrategies`)?
- `LwJavaParserSecurityTest` then fails on purpose: `LwJavaParser` can call
these methods while reading an
- unvetted source. Check that the new method only builds the model (no
`CamelContext`, files, class loading
- or network) before regenerating `replay-builder-methods.txt` with
`-Dcamel.java.in.updateSurface=true`.
- See [`design/java-dsl-parser.adoc`](design/java-dsl-parser.adoc).
-
-## Structure
-
-```
-camel/
-├── core/ # Core modules (camel-api, camel-core, camel-support, etc.)
-├── components/ # 300+ components (kafka, aws, http, etc.)
-├── dsl/ # DSLs (jbang, yaml-dsl, endpointdsl)
-├── test-infra/ # Testcontainers-based test services
-├── catalog/ # Component metadata
-├── tooling/ # Maven plugins
-├── archetypes/ # Maven archetypes
-├── tests/ # Integration tests
-└── docs/ # AsciiDoc docs
-```
+The threat model is
[`docs/user-manual/modules/ROOT/pages/security-model.adoc`](docs/user-manual/modules/ROOT/pages/security-model.adoc).
+Use it when triaging security reports, deciding whether a finding warrants a
CVE, or reviewing a security-sensitive PR.
-## Build
+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`](SECURITY.md) and stop.
-For project build commands, code style restrictions and other standards, check
+- **Route authors** and **deployment operators** are **fully trusted**: code
execution by a route author (`.bean()`,
+ `.process()`, `simple`/`groovy` expressions) and operator misconfiguration
are not vulnerabilities, unless a Camel
+ default exposed it.
+- **External message senders** (HTTP clients, JMS producers, file droppers,
etc.) are **untrusted**. The framework must
+ not turn data flowing through a route into code execution, file read,
request forgery, or auth bypass on its own.
+- What is in and out of scope is in the "Vulnerability scope" section.
Behaviour enabled by an explicit opt-in
+ (`allowJavaSerializedObject=true`, `trustAllCertificates=true`, ...), DoS
through unthrottled routes, and scanner
+ reports without a PoC are out of scope.
+- When reviewing a PR that touches a consumer, type converter, aggregation
repository, data format, parser, or a
+ security-relevant `@UriParam`, go through "Guidance for component authors
and reviewers" in the security model.
+ For deployment advice, see its "Deployment hardening" section.
+- A new public method on the route builder (`RouteBuilder`, `BuilderSupport`,
`RouteConfigurationBuilder`) or the static
+ DSL (`Builder`, `PredicateBuilder`, `AggregationStrategies`) fails
`LwJavaParserSecurityTest` on purpose. Check that
+ the method only builds the model (no `CamelContext`, files, class loading or
network) before regenerating
+ `replay-builder-methods.txt` with `-Dcamel.java.in.updateSurface=true`. See
+ [`design/java-dsl-parser.adoc`](design/java-dsl-parser.adoc).
+
+## Build and Test
+
+Build commands and code style rules are in
[`.oss-ai-helper-rules/project-standards.md`](.oss-ai-helper-rules/project-standards.md).
```bash
mvn clean install -Dquickly # fast build, no tests
-mvn clean install # full build
mvn clean install -pl components/camel-kafka -am # single module
mvn formatter:format && mvn impsort:sort # format code
mvn clean install -Psourcecheck # verify style
+mvn verify -Pit # integration tests
```
-## Testing
-
-```bash
-mvn test # unit tests
-mvn verify -Pit # integration tests
-```
+Tests needing external services use the Testcontainers-based services in
`test-infra/`:
-Test infra usage:
```java
@RegisterExtension
static KafkaService service = KafkaServiceFactory.createService();
@@ -578,81 +187,46 @@ fake of the external system. Before writing such a
"world" for a component, foll
The SQS world in
`components/camel-aws/camel-aws2-sqs/src/test/java/org/apache/camel/component/aws2/sqs/dst/`
is the
worked example. Do not report a failing seed as a bug before the triage step
of that guide.
-## Component Layout
-
-```
-camel-<name>/
-├── pom.xml
-└── src/
- ├── main/java/org/apache/camel/component/<name>/
- │ ├── <Name>Component.java
- │ ├── <Name>Endpoint.java
- │ ├── <Name>Producer.java
- │ └── <Name>Consumer.java
- ├── main/docs/
- ├── generated/
- └── test/java/
-```
+New integration tests with a container image: avoid Docker Hub images, prefer
`mirror.gcr.io` or `quay.io`. The image
+must be available for `amd64`, `ppc64le` and `s390x` (sometimes from another
registry such as `icr.io`); otherwise
+disable the tests with the `skipITs.ppc64le` and `skipITs.s390x` Maven
properties.
## Conventions
-Classes:
-- `<Name>Component extends DefaultComponent`
-- `<Name>Endpoint extends DefaultEndpoint`
-- `<Name>Producer extends DefaultProducer`
-- `<Name>Consumer extends DefaultConsumer`
-- Tests: `*Test.java` (JUnit 5)
-
-Packages:
-- Components: `org.apache.camel.component.<name>`
-- Core: `org.apache.camel.<module>`
-
Deprecation:
- Add `(deprecated)` suffix to `<name>` in `pom.xml`: `<name>Camel ::
MyComponent (deprecated)</name>`
- Add `(deprecated)` suffix to the doc page title in `src/main/docs/*.adoc`
- Add `@Deprecated` to Java classes
-- Document in the upgrade guide
(`docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_XX.adoc`)
+- Document in the upgrade guide
Annotations:
-- `@UriPath` for path params
-- `@UriParam` for query params
-- Always add `description` for docs
-- Mark sensitive parameters with `secret = true` on `@UriParam` or `@Metadata`
(passwords, tokens, API keys)
-- For insecure configuration flags (e.g., `trustAllCertificates`,
`allowJavaSerializedObject`),
- add `security = "insecure:ssl"` / `"insecure:serialization"` /
`"insecure:dev"` on `@UriParam`.
- See [`design/security.adoc`](design/security.adoc) for categories and
rationale.
-
-Import Style:
-- Do NOT use fully qualified class names (FQCNs) in Java code. Always add an
`import` statement
- and use the simple class name (e.g., write `List` not `java.util.List`).
-- Exception: when two classes share the same simple name (e.g.,
`java.util.Date` and `java.sql.Date`),
- import the most-used one and qualify the other.
-- This applies to all code: production, test, and test-infra.
-- Generated code (`src/generated/`) is excluded from this rule.
-- The build automatically shortens unnecessary FQCNs via OpenRewrite
(`rewrite-maven-plugin`).
- CI will fail if uncommitted FQCN changes are detected after the build.
-
-Javadoc `@since` Tags:
-- All new public classes, interfaces, enums, and annotations in
`core/camel-api` MUST include
- a `@since X.Y` Javadoc tag indicating the Camel version when they are
introduced.
-- All new public methods added to existing interfaces/classes in
`core/camel-api` MUST include
- a `@since X.Y` Javadoc tag on each new method.
-- Use the upcoming minor release version (e.g., `@since 4.21` if the current
SNAPSHOT is 4.21.0).
-- Place `@since` as the last Javadoc tag, after `@param`, `@return`,
`@throws`, etc.
+- `@UriPath` for path params, `@UriParam` for query params; always add a
`description` for the docs.
+- Mark sensitive parameters with `secret = true` on `@UriParam` or `@Metadata`
(passwords, tokens, API keys).
+- Mark insecure configuration flags (e.g., `trustAllCertificates`,
`allowJavaSerializedObject`) with
+ `security = "insecure:ssl"` / `"insecure:serialization"` / `"insecure:dev"`
on `@UriParam`.
+ See [`design/security.adoc`](design/security.adoc).
+- A new `@UriParam` that controls a security-relevant default errs toward
"denied unless opted in". Relaxing a default
+ needs an upgrade-guide entry and PMC sign-off.
+
+Imports:
+- Do NOT use fully qualified class names in Java code (production, test and
test-infra); import and use the simple
+ name. Exception: two classes with the same simple name — import the
most-used one and qualify the other.
+- Generated code (`src/generated/`) is excluded. The build shortens FQCNs via
OpenRewrite, and CI fails on the
+ resulting uncommitted changes.
+
+Javadoc `@since` tags:
+- New public classes, interfaces, enums and annotations in `core/camel-api`,
and new public methods added to existing
+ ones, MUST have a `@since X.Y` tag with the upcoming minor version (e.g.
`@since 4.24` for 4.24.0-SNAPSHOT), placed
+ as the last Javadoc tag.
+
+Commits: `CAMEL-XXXX: Brief description`, referencing JIRA when applicable.
## Adding Components
-### Direct child of components/
-
-No extra config needed.
-
-### Inside a parent folder (camel-aws, camel-ai, camel-azure, etc.)
-
-You must register the component in MojoHelper:
-
-**File:**
`tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/MojoHelper.java`
-
-Add to the `getComponentPath()` switch:
+A component that is a direct child of `components/` needs no extra config. A
component inside a parent folder
+(`camel-aws`, `camel-ai`, `camel-azure`, ...) must be added to that parent's
`case` in `getComponentPath()` of
+`tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/MojoHelper.java`,
or the build
+won't pick it up for catalog/docs generation:
```java
case "camel-aws":
@@ -660,47 +234,3 @@ case "camel-aws":
// ...
dir.resolve("camel-your-new-component"));
```
-
-Parent folders needing registration:
-- `camel-ai` (langchain4j, vector dbs)
-- `camel-aws`
-- `camel-azure`
-- `camel-google`
-- `camel-ibm`
-- `camel-huawei`
-- `camel-debezium`
-- `camel-vertx`
-- `camel-microprofile`
-- `camel-infinispan`
-- `camel-cxf`
-- `camel-spring-parent`
-- `camel-test`
-
-Without this, the build won't pick up your component for catalog/docs
generation.
-
-## Adding Integration tests with new container image
-
-- Avoid using Docker Hub images, prefer to use Google `mirror.gcr.io` or Red
Hat `quay.io` ones.
-- Verify that the container image is available for the tested architectures
(currently `amd64`, `ppc64le` and `s390x`). Sometimes the image is provided in
different registries such as `icr.io`. If not available, use `skipITs.ppc64le`
and `skipITs.s390x` Maven properties to disable it.
-
-## Commits
-
-```
-CAMEL-XXXX: Brief description
-```
-
-Reference JIRA when applicable.
-
-# Community Engagement
-
-- When contributing to this project, check if the user has starred it: `gh api
-X GET /user/starred`
-- If the user hasn't starred it, then ask if the user would like to do so
(explain why this is important: visibility, engagement, etc.).
-- If the user accepts to star the repository: `gh api -X PUT
/user/starred/apache/camel`
-
-## Links
-
-- https://camel.apache.org/
-- https://github.com/apache/camel
-- https://issues.apache.org/jira/browse/CAMEL
-- [email protected]
-- https://camel.zulipchat.com/