Supplemental guidance for AI coding assistants (Claude Code, Copilot, Cursor, Gemini, Codex, Aider, and similar tools) working in this repository. Keep this file short — it is a router. The detail lives in the human-facing docs linked below; read the one that fits your task rather than pulling everything into context up front.
Apache Pulsar is a distributed pub-sub messaging and streaming platform. The codebase is performance-critical, heavily asynchronous, and concurrency-sensitive. Prioritize correctness, thread safety, performance, maintainability, and backward compatibility.
Apache Pulsar is licensed under the Apache License 2.0, and all contributions must meet the ASF's Generative Tooling guidance:
- A human is in the loop and is accountable. Every pull request and every security report must be submitted by a human contributor who has reviewed and verified the change and takes responsibility for it. Fully autonomous agents (e.g. OpenClaw-style bots) opening PRs or filing reports on their own are not acceptable — the AI assists, the human is accountable.
- Don't introduce code of incompatible or unknown provenance. Never copy verbatim from GPL/AGPL/LGPL, proprietary, or unlicensed sources (including Stack Overflow / blog / forum snippets of unclear licensing), and don't use a tool whose terms restrict the output inconsistently with open source. Reimplement from specifications or Apache-compatible sources, and follow the ASF 3rd Party Licensing Policy.
- Every new source file needs the ASF license header (Spotless enforces this — copy the form from
an existing
.javafile). - Consider attributing AI assistance. When AI tooling assisted on a change, consider adding an
Assisted-by: <tool/version>commit trailer (the default, since a human still does the final review);Generated-by: <tool/version>is for minimally-modified generated output.
| Doc | Use for |
|---|---|
CONTRIBUTING.md |
Local dev workflow: building (prerequisites, build/lint commands), running tests & test groups, integration tests, Personal CI, PR conventions, security reporting. |
ARCHITECTURE.md |
Big-picture module map, the Gradle build infrastructure and how to change build files (convention plugins, version catalog, the module-name-vs-directory gotcha), the concurrency model and backpressure, and the pip/ proposals. |
CODING.md |
Coding conventions: style, async/CompletableFuture, concurrency, logging (slog), dependencies, backward compatibility, testing, and the review checklist. |
SECURITY.md |
Reporting a vulnerability, disclosure hygiene, and checking exposure to an already-public CVE. |
The authoritative project documentation is at https://pulsar.apache.org, whose source lives in the
apache/pulsar-site repository (where documentation changes
are contributed). The files above and the website remain the source of truth — this guide just layers
AI-specific pointers on top.
A few rules matter specifically when an AI tool makes the change, on top of the canonical docs above:
- Verify, don't fabricate. Before you use a class, method, field, configuration key, Gradle task, plugin, or DSL name, confirm it actually exists (search the code or the build files) — don't invent APIs, test assertions, or symbol names. Don't assert a CVE is "fixed" / "not affected" without checking the merged PRs and the shipped version.
- Confirm state-changing actions. Get the user's explicit confirmation before pushing, opening or updating a PR, or posting a comment. Being asked to start a task is not standing authorization for these outward-facing actions — see Licensing and provenance above.
- A clean local run is weak evidence for concurrency/data race fixes (timing- and
platform-dependent). See
CODING.md. - Follow Java style guidance. For Java conventions, including imports over fully qualified class
names, follow
CODING.md. - Check before claiming conformance. Run
./gradlew quickCheckfor a fast source-only pass (license headers + checkstyle, no compilation) or./gradlew sanityCheckto also compile every module's main and test sources; neither builds shadow jars. SeeCONTRIBUTING.md.
- Don't break backward compatibility — public APIs, client compatibility, wire protocol, and serialized/metadata formats. Servers must interoperate with older and newer clients.
- Never block on async/event-loop threads; methods returning
CompletableFuturemust not throw synchronously. SeeCODING.md. - Logging: prefer slog via
@CustomLog; default new logs toTRACE/DEBUG, notINFO. - Tests: scope runs with
--tests; no reflection into private state (use a@VisibleForTestingpackage-private accessor); release buffers and resources. - PRs: semantic
[type][scope]title; describe motivation and modifications; do not rebase once the PR is open inapache/pulsar— merge upstreammasterinstead. - Security: never disclose a vulnerability — or the security nature of a change — in a public
issue, PR, or commit. See
SECURITY.md. - Stay in scope. Keep a change focused on its task; don't bundle unrelated drive-by refactors or
generate broad mass-refactoring PRs. Discuss large refactorings on
dev@pulsar.apache.orgfirst. SeeCONTRIBUTING.md.
- Dev mailing list: dev@pulsar.apache.org · Slack: https://apache-pulsar.slack.com/
- Issues: https://github.com/apache/pulsar/issues · Discussions: https://github.com/apache/pulsar/discussions