- Java: JDK 25 via
JAVA_HOME; use the bundled Gradle wrapper (./gradlew). - Build tooling: Gradle composite build with
build-conventions,build-tools, andbuild-tools-internal; Docker is required for some packaging/tests. - OS packages: Packaging and QA jobs expect ephemeral hosts; do not run packaging suites on your workstation.
- Security: Default dev clusters enable security; use
elastic-admin:elastic-passwordor disable with-Dtests.es.xpack.security.enabled=false. - Cursor/Copilot rules: None provided in repo; follow this guide plus CONTRIBUTING.md.
- Refer to BUILDING.md, CONTRIBUTING.md & TESTING.asciidoc for comprehensive build/test instructions.
./gradlew spotlessJavaCheck/spotlessApply(or:server:spotlessJavaCheck): enforce formatter profile inbuild-conventions/formatterConfig.xml.
The repository is organized into several key directories:
server: The core Elasticsearch server.modules: Features shipped with Elasticsearch by default.plugins: Officially supported plugins.libs: Internal libraries used by other parts of the project.qa: Integration and multi-version tests.docs: Project documentation.distribution: Logic for building distribution packages.x-pack: Additional code modules and plugins under Elastic License.build-conventions,build-tools,build-tools-internal: Gradle build logic. Refer to BUILDING.md for details on how these are structured and used.
- Standard suite:
./gradlew test(respects cached results; add-Dtests.timestamp=$(date +%s)to bypass caches when reusing seeds). - Single project:
./gradlew :server:test(or other subproject path). - Single class:
./gradlew :server:test --tests org.elasticsearch.package.ClassName. - Single package:
./gradlew :server:test --tests 'org.elasticsearch.package.*'. - Single method / repeated runs:
./gradlew :server:test --tests org.elasticsearch.package.ClassName.methodName -Dtests.iters=N. - Deterministic seed: append
-Dtests.seed=DEADBEEF(each method uses derived seeds). - JVM tuning knobs:
-Dtests.jvms=8,-Dtests.heap.size=4G,-Dtests.jvm.argline="-verbose:gc",-Dtests.output=always, etc. - Debugging: append
--debug-jvmto the Gradle test task and attach a debugger on port 5005. - CI reproductions: copy the
REPRODUCE WITHline from CI logs; it includes project path, seed, and JVM flags. - Yaml REST tests:
./gradlew ":rest-api-spec:yamlRestTest" --tests "org.elasticsearch.test.rest.ClientYamlTestSuiteIT.test {yaml=<relative_test_file_path>}" - Use the Elasticsearch testing framework where possible for unit and yaml tests and be consistent in style with other elasticsearch tests.
- Use real classes over mocks or stubs for unit tests, unless the real class is complex then either a simplified subclass should be created within the test or, as a last resort, a mock or stub can be used. Unit tests must be as close to real-world scenarios as possible.
- Ensure mocks or stubs are well-documented and clearly indicate why they were necessary.
- Unit Tests: Preferred. Extend
ESTestCase. - Single Node: Extend
ESSingleNodeTestCase(lighter than full integ test). - Integration: Extend
ESIntegTestCase. - REST API: Extend
ESRestTestCaseorESClientYamlSuiteTestCase. YAML based REST tests are preferred for integration/API testing.
- Never add a dependency without checking for existing alternatives in the repo.
- Absolutely no wildcard imports; keep existing import order and avoid reordering untouched lines.
- Prefer type-safe constructs; avoid raw types and unchecked casts.
- If suppressing warnings, scope
@SuppressWarningsnarrowly (ideally a single statement or method). - Document non-obvious casts or type assumptions via Javadoc/comments for reviewers.
- REST handlers typically use the
Rest*Actionpattern; transport-layer handlers mirror them withTransport*Actionclasses. - REST classes expose routes via
RestHandler#routes; when adding endpoints ensure naming matches existing REST/Transport patterns to aid discoverability. - Transport
ActionTypestrings encode scope (indices:data/read/...,cluster:admin/..., etc.); align new names with these conventions to integrate with privilege resolution.
- Elasticsearch should prefer its own logger
org.elasticsearch.logging.LogManager&org.elasticsearch.logging.Logger; declareprivate static final Logger logger = LogManager.getLogger(Class.class). - Always use parameterized logging (
logger.debug("operation [{}]", value)); never build strings via concatenation. - Wrap expensive log-message construction in
() -> Strings.format(...)suppliers when logging atTRACE/DEBUGto avoid unnecessary work. - Log levels:
TRACE: highly verbose developer diagnostics; usually read alongside code.DEBUG: detailed production troubleshooting; ensure volume is bounded.INFO: default-enabled operational milestones; prefer factual language.WARN: actionable problems users must investigate; include context and, if needed, exception stack traces.ERROR: reserve for unrecoverable states (e.g., storage health failures); preferWARNotherwise.
- Only log client-caused exceptions when the cluster admin can act on them; otherwise rely on API responses.
- Tests can assert logging via
MockLogfor complex flows.
- New packages/classes/public or abstract methods require Javadoc explaining the "why" rather than the implementation details.
- Avoid documenting trivial getters/setters; focus on behavior, preconditions, or surprises.
- For tests, Javadoc can describe scenario setup/expectations to aid future contributors.
- Do not remove existing comments from code unless the code is also being removed or the comment has become incorrect.
- Default header (outside
x-pack): Elastic License 2.0, SSPL v1, or AGPL v3—they are already codified at the top of Java files; copy from existing sources. - Files under
x-packrequire the Elastic License 2.0-only header; IDEs configured per CONTRIBUTING.md can insert correct text automatically.
- Never edit unrelated files; keep diffs tightly scoped to the task at hand.
- Prefer Gradle tasks over ad-hoc scripts.
- When scripting CLI sequences, leverage
gradlewtask. - Unrecognized changes: assume other agent; keep going; focus your changes. If it causes issues, stop + ask user.
- Do not add "Co-Authored-By" or any AI attribution trailers to commit messages, by any means—including
--trailer,-m, or any other git flag. commit messages should adhere to the 50/72 rule: use a maximum of 50 columns for the commit summary
- For changes to a
Writeableimplementation (writeToand constructor fromStreamInput), add a newpublic static final <UNIQUE_DESCRIPTIVE_NAME> = TransportVersion.fromName("<unique_descriptive_name>")and use it in the new code paths. Confirm the backport branches and then generate a new version file with./gradlew generateTransportVersion.
- Prefer Gradle Enterprise build scans (
https://gradle-enterprise.elastic.co/s/<id>) over raw logs for root-cause analysis when available. - If given a Buildkite link, use the Buildkite MCP server first.
- First call
buildkite-list_annotationsand inspectcontext=gradle-build-scans-failed(failed jobs only). If needed, inspectcontext=gradle-build-scans(all jobs). - If annotations are incomplete, call
buildkite-get_buildand map failed job IDs tometa_datakeys:build-scan-<job_id>andbuild-scan-id-<job_id>. - Buildkite UI fallback (when MCP is unavailable): Build page ->
Jobs->Failures, then open/copy the Gradle Enterprise build scan links shown per failed job. - If given a Gradle Enterprise build scan link directly, start from that link instead of searching Buildkite logs first.
- If
dvcliis available, use it to extract failed tasks, exact failed tests, primary assertion/error, and reproduction details. - If
dvcliis unavailable, do not block: continue with Buildkite MCP logs (buildkite-search_logs,buildkite-tail_logs,buildkite-read_logs), artifacts, and annotations. - If either tool is missing, suggest installation to the user for faster future triage:
dvcli/develocity-cli-client:https://github.com/breskeby/develocity-cli-client- Buildkite MCP setup for AI tools:
https://buildkite.com/docs/apis/mcp-server/remote/configuring-ai-tools
- For Buildkite URLs that include
#<job_id>, prioritize that specific job and resolve its correspondingbuild-scan-<job_id>entry. - In reports, list exact failed tests first, then failed tasks and related build scan URLs.
Stay aligned with CONTRIBUTING.md, BUILDING.md, and TESTING.asciidoc; this AGENTS guide summarizes—but does not replace—those authoritative docs.