{"owner":"redpanda-data","repo":"redpanda","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["CLAUDE.md"],"skills":{"CLAUDE.md":"# Copilot Coding Agent Onboarding Guide for `redpanda-data/redpanda`\n\n## High-Level Overview\n\n**What is Redpanda?**\n\nRedpanda is a high-performance, Apache Kafka®-compatible streaming data platform. It is written primarily in C++ for the core, with Go for CLI tooling (`rpk`), and some Python for auxiliary scripts and tests. Redpanda is designed to be lightweight, fast, and simple to operate, omitting ZooKeeper and the JVM.\n\nIt uses extensively the thread-per-core model and asynchronous (coroutines, futures) programming model.\n\n**Repository Characteristics:**\n- **Large multi-language codebase:** C++ (core), Go (CLI/tools), Python (testing/scripts), Bash and Bazel for builds.\n- **Build System:** Bazel (with Bazelisk) for core.\n- **Target Platforms:** Linux (primary), some support for macOS and Windows.\n- **Key Directories:**\n  - `src/v/`: Core C++ source code\n  - `src/go/`: Go CLI and tools\n  - `bazel/`, `BUILD`, `MODULE.bazel`: Bazel scripts and definitions\n  - `tools/`: Development and helper scripts\n  - `tests/`: Test suites\n  - `conf/`: Configuration files\n  - `proto/`: Protobuf definitions for Redpanda services and APIs\n  - `.github/`, `.buildkite/`: CI/workflow automation\n- **Documentation:** [Docs site](https://redpanda.com/documentation) and `docs/`.\n\n## Build, Test, and Validation Instructions\n\n### Prerequisites (Always Perform)\n\n1. **Install Bazelisk** (the required Bazel wrapper):\n   ```bash\n   wget -O ~/bin/bazel https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-amd64\n   chmod +x ~/bin/bazel\n   export PATH=\"$HOME/bin:$PATH\"\n   ```\n2. **Install system dependencies**:\n   ```bash\n   sudo ./bazel/install-deps.sh\n   ```\n   _This must always be run before any Bazel build, especially on a fresh system or after dependency updates._\n\n### Core Build Steps\n\n- **Build all (fastbuild):**\n  ```bash\n  bazel build //...\n  ```\n- **Test all:**\n  ```bash\n  bazel test //...\n  ```\n- **Lint (C++):**\n  - Formatting and linting are enforced. Use:\n    ```bash\n    bazel run //tools:clang_format\n    ```\n  - Configs: `.clang-format`, `.clang-tidy`, etc.\n\n- **Go CLI (`rpk`) Build:**\n  ```bash\n  bazel build //:rpk\n  ```\n\nSee `.bazelrc` for more details on build settings and config modes\n\n### Validation and CI\n\n- **Pre-push/merge:** All changes are validated by CI (GitHub Actions, Buildkite) for build, test, and lint.\n- **Formatting and lint checks are enforced; run locally before PRs.**\n- **Target branch:** Always open PRs against `dev`.\n\n## Project Layout & Architectural Notes\n\n- **Main C++ source:** `src/v/`\n- **Go CLI:** `src/go/rpk/`\n- **Build configuration:** `.bazelrc`, `.bazelversion`, `BUILD`, `MODULE.bazel`, and `bazel/`\n- **CI configuration:** `.github/workflows/`, `.buildkite/`\n- **Testing:** `tests/`\n- **Config:** `conf/`\n- **Docker:** `tools/docker/`\n\n### Lint/Formatting Configs:\n- `.clang-format`, `.clang-tidy*`: C++ style\n- `tools/ruff`, `.ruff.toml`: Python formatting\n\n### CI/CD Checks\n\n- **Build, test, and lint are enforced by CI.** Use the same steps as above locally before PRs.\n\n### File Index (Root Level)\n- `.bazelignore`, `.bazelrc`, `.bazelversion`, `BUILD`, `MODULE.bazel`, `README.md`, `CONTRIBUTING.md`, `SECURITY.md`, `CODE_OF_CONDUCT.md`, `LICENSES/`, `bazel/`, `src/`, `tests/`, `conf/`, `tools/`, `.github/`, `.buildkite/`, etc.\n\n---\n\n## Protobuf-Specific Instructions\n\n### Protobuf Coding Guidelines\n\nFollow the guidelines provided in `proto/redpanda/README.md` for basic Protobuf standards. For admin v2 ConnectRPC endpoints (proto → C++ service impl → registration → ducktape Python bindings), use the `add-admin-v2-endpoint` skill.\n\n### Protobuf Build & Environment\n- **Primary Protobuf code lives in `proto/`.**\n- **Formatting:** `.clang-format` in the root directory is enforced. Always run `clang-format` before committing changes or submitting a PR:\n  ```bash\n  bazel run //tools:clang_format\n  ```\n\n## C++-Specific Instructions\n\n### C++ Build & Environment\n\n- **Primary C++ code lives in `src/v/`.**\n- **C++ build is managed by Bazel.** All dependencies and toolchains are configured via Bazel rules and the `MODULE.bazel` file. Do not manually install C++ dependencies unless explicitly instructed in documentation.\n- **Compiler Standard:** C++23 is required. Some SDK components (e.g., `src/transform-sdk/cpp/`) use C++23 and specific flags like `-Wall`, `-fno-exceptions`, and for some targets, `-stdlib=libc++`.\n- **Sanitizers:** Some components and test builds use sanitizers (address, leak, undefined) via `-fsanitize=address,leak,undefined` for both compile and link.\n- **Suppression Files:** Leak, undefined, and other sanitizer suppressions can be found in the root as `lsan_suppressions.txt`, `ubsan_suppressions.txt`.\n- **C++ Linting:** `.clang-format` and `.clang-tidy` in the root directory are enforced. Always run `clang-format` before committing changes or submitting a PR:\n  ```bash\n  bazel run //tools:clang_format\n  ```\n- **C++ Libraries:** Bazel dependencies are managed in `MODULE.bazel` (e.g., Boost, Abseil, fmt, protobuf, googletest, yaml-cpp, etc.).\n- **Testing:** C++ unit tests are run via Bazel.\n\n### Common C++ Pitfalls & Workarounds\n\n- **Always use Bazelisk and Bazel for building the core.** Using a plain Bazel binary may result in missing dependencies or incompatible flags.\n- **If you encounter build issues related to missing system libraries, rerun `sudo ./bazel/install-deps.sh`.**\n- **Do not attempt to manually install or update C++ dependencies unless specifically instructed.**\n- **Always run lint and formatter before pushing. CI will fail on formatting/lint discrepancies.**\n- **If building in CI or a containerized environment, ensure the correct toolchain is available as specified in `tools/docker/README.md` or CI scripts.**\n- **Check for additional build and compile flags in `BUILD`, `MODULE.bazel` and related files.**\n\n### C++ coding guidelines\n\nCheck that these guidelines are followed for new code.\n\n- Do not declare new `operator<<(ostream& os, type)` overloads, instead prefer to use a `format_to` member function inside `type` as described in\nsrc/v/base/format_to.h.\n- Prefer using latest C++ features (C++23).\n- Use `ss` namespace as a prefix for Seastar types (e.g. `ss::future`, `ss::promise`).\n- Use `vassert(cond, msg, msg_args...)` macro for assertions. It is\n  similar to `assert(cond)` but it is always enabled and it prints the message\n  to the log. Use `dassert` for assertions that are only enabled in debug mode.\n- Use `vlog(method, fmt, args...)` for logging. `method` is the method reference\n  for the logger to use. I.e. `vlog(stlog.info, \"Hello world\");`. Where `stlog`\n  is defined as `ss::logger stlog(\"storage\");`.\n- Do not use `std::vector` for containers that may grow very large, instead use `chunked_vector`.\n- Do not use `std::unordered_map` for containers that may grow very large, instead use `chunked_hash_map`.\n- Instead of long if-else chains for mapping string to values, use\n  `string_switch` mechanism defined in\n  [string_switch.h](./src/v/strings/string_switch.h).\n- Don't use `ss::parallel_for_each` with ranges that can grow large such as\n  partitions, topics or segments. Instead prefer `ss::max_concurrent_for_each` to\n  limit concurrency. Think about how much concurrency is needed to adequately hide\n  latency. See our\n  [docs](https://redpandadata.atlassian.net/wiki/x/AQBZTw#Managing-Concurrency-in-the-system)\n  for more background.\n- Do not call the `get_exception` method on a future within a logging or\n  assertion statement (e.g. `vlog(..., fut.get_exception(), ...)`). Instead,\n  assign the return value of `get_exception` in a variable and pass the variable.\n\n#### Lambda coroutines, coroutine argument capture, and deducing this\n\nWhen a lambda coroutine is passed to APIs like `seastar::future::then()`,\nthe lambda object is stored in managed memory that gets freed once the\ncontinuation returns—but the coroutine may still be suspended and later\naccess its captures, causing use-after-free. This happens because the\ncoroutine frame holds a reference to the lambda's capture storage, which\nbecomes dangling. The C++23 \"deducing this\" syntax\n`([captures...](this auto, args...))` solves this by moving the captures\ndirectly into the coroutine frame rather than referencing them through the\nlambda object, decoupling capture lifetime from the lambda's lifetime.\nThis is distinct from the recursive-lambda use case—here this auto is required\nfor memory safety in coroutines, not self-reference.\n\n### Exception handling\n\n- Read the \"Exceptions in coroutines\" section within [tutorial.md](external/+non_module_dependencies+seastar/doc/tutorial.md)\n  to best understand how exceptions should be handled in Redpanda.\n- `throw` and `std::rethrow_exception()` may have an effect on performance, especially in hot paths.\n  There are several `seastar` utilities that should be preferred to explicitly throwing exceptions.\n  Namely, `ss::coroutine::try_future()`, `ss::coroutine::as_future()`, `ss::coroutine::return_exception()`,\n  and `ss::coroutine::return_exception_ptr()`. This is only a brief summary of the content in the tutorial above,\n  which must be read to fully understand exception handling in Redpanda.\n\n### C++ coding style\n\n- Use snake_case for identifiers. Use CamelCase for concepts.\n- Use Doxygen comments with 3-slashes (///) for public APIs\n\n### Code comments\n\n- **Default to no comments** - clear code and good names are better\n- **Avoid comments that restate the code** - they become stale\n- **Prefer alternatives:**\n  - Better variable/function names\n  - Log lines (serve as documentation and debugging)\n- **Do add comments for:**\n  - Doc comments (`/// \\brief`) on public types explaining purpose/usage\n  - Complex algorithms or non-obvious \"gotchas\"\n  - Test comments explaining input format or test intent\n  - Links to external resources (specs, docs, issues)\n  - Mapping internal types/concepts to external formats (e.g., wire protocols, APIs)\n  - ASCII diagrams for complex state machines or data flows\n- **Avoid obvious branching comments** - `if (x)` rarely needs `// when x is true`\n\n### Benchmarking\n\n  - Run benchmarks like `bazel run --config=release //src/v/utils/tests:coro_rpbench`\n  - Get --help like: `bazel run --config=release //src/v/utils/tests:coro_rpbench -- --help`\n  - If running/writing benchmarks read this also: external/+non_module_dependencies+seastar/tests/perf/perf-tests.md\n\n### More C++-Specific References\n\n- [MODULE.bazel](https://github.com/redpanda-data/redpanda/blob/dev/MODULE.bazel)\n- [BUILD](https://github.com/redpanda-data/redpanda/blob/dev/BUILD)\n\n---\n\n## Python specific instructions\n\n### Instructions for python test code under tests/rptest\n\n- Avoid catching bare `except:` as this can hide system exceptions, including exceptions\n  raised by a signal when a test is being forcibly timed out. Instead use `except Exception:`.\n- After modifying files under `tests/rptest`, run type checking via\n  `tools/type-checking/type-check.sh check <files...>` (paths positional, relative to `tests/`)\n  to scope it to your changes. Do not invoke `type-check.py` directly.\n  See `tools/type-checking/README.md` for more details: the per-file\n  strictness levels in `type-check-strictness.json` and how to promote\n  files to stricter levels after adding type hints.\n\n### Instructions for type hints\n\n- Use modern style with `|` instead of `Union` or `Optional`\n\nFor further details, consult:\n- [README.md](https://github.com/redpanda-data/redpanda/blob/dev/README.md)\n- [CONTRIBUTING.md](https://github.com/redpanda-data/redpanda/blob/dev/CONTRIBUTING.md)\n- [Redpanda Documentation](https://redpanda.com/documentation)\n- CI/CD configs in `.github/workflows/` and `.buildkite/`\n\n---\n\n## Commit message instructions\n\nWhen writing or critiquing commit messages, follow these guidelines:\n\n**Format:**\n```\narea[/detail]: short description\n\n<optional body>\n```\n\n- Title: ≤72 chars\n- Body: wrapped at 72 chars\n\n**Check git history first** to match the style of the area you're changing:\n```bash\ngit log --oneline --no-merges -- path/to/changed/files | head -20\n```\n\n**Goal:** Make the commit easy to review and provide context for future readers (via `git blame`/`git log`)\n\n**Rules:**\n- Title: imperative mood, lowercase after colon, no period\n- Keep bodies concise (1-2 lines typical, trivial changes need only a title)\n- Don't reference GitHub issues/PRs or Jira tickets\n- Use the body to help reviewers and future readers understand:\n  - The \"why\": motivation, design choices, preparation for future work\n  - The \"what\": new abstractions introduced, non-obvious changes\n  - Integration tests: briefly note what behaviors are covered\n- Don't restate what's obvious from the diff, but duplicating a doc comment is fine if it helps reviewers understand the change faster.\n\n_Results from code search may be incomplete. For more C++ details, see the [repository code search](https://github.com/redpanda-data/redpanda/search?q=c%2B%2B)._\n"},"files":{"CLAUDE.md":"# Copilot Coding Agent Onboarding Guide for `redpanda-data/redpanda`\n\n## High-Level Overview\n\n**What is Redpanda?**\n\nRedpanda is a high-performance, Apache Kafka®-compatible streaming data platform. It is written primarily in C++ for the core, with Go for CLI tooling (`rpk`), and some Python for auxiliary scripts and tests. Redpanda is designed to be lightweight, fast, and simple to operate, omitting ZooKeeper and the JVM.\n\nIt uses extensively the thread-per-core model and asynchronous (coroutines, futures) programming model.\n\n**Repository Characteristics:**\n- **Large multi-language codebase:** C++ (core), Go (CLI/tools), Python (testing/scripts), Bash and Bazel for builds.\n- **Build System:** Bazel (with Bazelisk) for core.\n- **Target Platforms:** Linux (primary), some support for macOS and Windows.\n- **Key Directories:**\n  - `src/v/`: Core C++ source code\n  - `src/go/`: Go CLI and tools\n  - `bazel/`, `BUILD`, `MODULE.bazel`: Bazel scripts and definitions\n  - `tools/`: Development and helper scripts\n  - `tests/`: Test suites\n  - `conf/`: Configuration files\n  - `proto/`: Protobuf definitions for Redpanda services and APIs\n  - `.github/`, `.buildkite/`: CI/workflow automation\n- **Documentation:** [Docs site](https://redpanda.com/documentation) and `docs/`.\n\n## Build, Test, and Validation Instructions\n\n### Prerequisites (Always Perform)\n\n1. **Install Bazelisk** (the required Bazel wrapper):\n   ```bash\n   wget -O ~/bin/bazel https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-amd64\n   chmod +x ~/bin/bazel\n   export PATH=\"$HOME/bin:$PATH\"\n   ```\n2. **Install system dependencies**:\n   ```bash\n   sudo ./bazel/install-deps.sh\n   ```\n   _This must always be run before any Bazel build, especially on a fresh system or after dependency updates._\n\n### Core Build Steps\n\n- **Build all (fastbuild):**\n  ```bash\n  bazel build //...\n  ```\n- **Test all:**\n  ```bash\n  bazel test //...\n  ```\n- **Lint (C++):**\n  - Formatting and linting are enforced. Use:\n    ```bash\n    bazel run //tools:clang_format\n    ```\n  - Configs: `.clang-format`, `.clang-tidy`, etc.\n\n- **Go CLI (`rpk`) Build:**\n  ```bash\n  bazel build //:rpk\n  ```\n\nSee `.bazelrc` for more details on build settings and config modes\n\n### Validation and CI\n\n- **Pre-push/merge:** All changes are validated by CI (GitHub Actions, Buildkite) for build, test, and lint.\n- **Formatting and lint checks are enforced; run locally before PRs.**\n- **Target branch:** Always open PRs against `dev`.\n\n## Project Layout & Architectural Notes\n\n- **Main C++ source:** `src/v/`\n- **Go CLI:** `src/go/rpk/`\n- **Build configuration:** `.bazelrc`, `.bazelversion`, `BUILD`, `MODULE.bazel`, and `bazel/`\n- **CI configuration:** `.github/workflows/`, `.buildkite/`\n- **Testing:** `tests/`\n- **Config:** `conf/`\n- **Docker:** `tools/docker/`\n\n### Lint/Formatting Configs:\n- `.clang-format`, `.clang-tidy*`: C++ style\n- `tools/ruff`, `.ruff.toml`: Python formatting\n\n### CI/CD Checks\n\n- **Build, test, and lint are enforced by CI.** Use the same steps as above locally before PRs.\n\n### File Index (Root Level)\n- `.bazelignore`, `.bazelrc`, `.bazelversion`, `BUILD`, `MODULE.bazel`, `README.md`, `CONTRIBUTING.md`, `SECURITY.md`, `CODE_OF_CONDUCT.md`, `LICENSES/`, `bazel/`, `src/`, `tests/`, `conf/`, `tools/`, `.github/`, `.buildkite/`, etc.\n\n---\n\n## Protobuf-Specific Instructions\n\n### Protobuf Coding Guidelines\n\nFollow the guidelines provided in `proto/redpanda/README.md` for basic Protobuf standards. For admin v2 ConnectRPC endpoints (proto → C++ service impl → registration → ducktape Python bindings), use the `add-admin-v2-endpoint` skill.\n\n### Protobuf Build & Environment\n- **Primary Protobuf code lives in `proto/`.**\n- **Formatting:** `.clang-format` in the root directory is enforced. Always run `clang-format` before committing changes or submitting a PR:\n  ```bash\n  bazel run //tools:clang_format\n  ```\n\n## C++-Specific Instructions\n\n### C++ Build & Environment\n\n- **Primary C++ code lives in `src/v/`.**\n- **C++ build is managed by Bazel.** All dependencies and toolchains are configured via Bazel rules and the `MODULE.bazel` file. Do not manually install C++ dependencies unless explicitly instructed in documentation.\n- **Compiler Standard:** C++23 is required. Some SDK components (e.g., `src/transform-sdk/cpp/`) use C++23 and specific flags like `-Wall`, `-fno-exceptions`, and for some targets, `-stdlib=libc++`.\n- **Sanitizers:** Some components and test builds use sanitizers (address, leak, undefined) via `-fsanitize=address,leak,undefined` for both compile and link.\n- **Suppression Files:** Leak, undefined, and other sanitizer suppressions can be found in the root as `lsan_suppressions.txt`, `ubsan_suppressions.txt`.\n- **C++ Linting:** `.clang-format` and `.clang-tidy` in the root directory are enforced. Always run `clang-format` before committing changes or submitting a PR:\n  ```bash\n  bazel run //tools:clang_format\n  ```\n- **C++ Libraries:** Bazel dependencies are managed in `MODULE.bazel` (e.g., Boost, Abseil, fmt, protobuf, googletest, yaml-cpp, etc.).\n- **Testing:** C++ unit tests are run via Bazel.\n\n### Common C++ Pitfalls & Workarounds\n\n- **Always use Bazelisk and Bazel for building the core.** Using a plain Bazel binary may result in missing dependencies or incompatible flags.\n- **If you encounter build issues related to missing system libraries, rerun `sudo ./bazel/install-deps.sh`.**\n- **Do not attempt to manually install or update C++ dependencies unless specifically instructed.**\n- **Always run lint and formatter before pushing. CI will fail on formatting/lint discrepancies.**\n- **If building in CI or a containerized environment, ensure the correct toolchain is available as specified in `tools/docker/README.md` or CI scripts.**\n- **Check for additional build and compile flags in `BUILD`, `MODULE.bazel` and related files.**\n\n### C++ coding guidelines\n\nCheck that these guidelines are followed for new code.\n\n- Do not declare new `operator<<(ostream& os, type)` overloads, instead prefer to use a `format_to` member function inside `type` as described in\nsrc/v/base/format_to.h.\n- Prefer using latest C++ features (C++23).\n- Use `ss` namespace as a prefix for Seastar types (e.g. `ss::future`, `ss::promise`).\n- Use `vassert(cond, msg, msg_args...)` macro for assertions. It is\n  similar to `assert(cond)` but it is always enabled and it prints the message\n  to the log. Use `dassert` for assertions that are only enabled in debug mode.\n- Use `vlog(method, fmt, args...)` for logging. `method` is the method reference\n  for the logger to use. I.e. `vlog(stlog.info, \"Hello world\");`. Where `stlog`\n  is defined as `ss::logger stlog(\"storage\");`.\n- Do not use `std::vector` for containers that may grow very large, instead use `chunked_vector`.\n- Do not use `std::unordered_map` for containers that may grow very large, instead use `chunked_hash_map`.\n- Instead of long if-else chains for mapping string to values, use\n  `string_switch` mechanism defined in\n  [string_switch.h](./src/v/strings/string_switch.h).\n- Don't use `ss::parallel_for_each` with ranges that can grow large such as\n  partitions, topics or segments. Instead prefer `ss::max_concurrent_for_each` to\n  limit concurrency. Think about how much concurrency is needed to adequately hide\n  latency. See our\n  [docs](https://redpandadata.atlassian.net/wiki/x/AQBZTw#Managing-Concurrency-in-the-system)\n  for more background.\n- Do not call the `get_exception` method on a future within a logging or\n  assertion statement (e.g. `vlog(..., fut.get_exception(), ...)`). Instead,\n  assign the return value of `get_exception` in a variable and pass the variable.\n\n#### Lambda coroutines, coroutine argument capture, and deducing this\n\nWhen a lambda coroutine is passed to APIs like `seastar::future::then()`,\nthe lambda object is stored in managed memory that gets freed once the\ncontinuation returns—but the coroutine may still be suspended and later\naccess its captures, causing use-after-free. This happens because the\ncoroutine frame holds a reference to the lambda's capture storage, which\nbecomes dangling. The C++23 \"deducing this\" syntax\n`([captures...](this auto, args...))` solves this by moving the captures\ndirectly into the coroutine frame rather than referencing them through the\nlambda object, decoupling capture lifetime from the lambda's lifetime.\nThis is distinct from the recursive-lambda use case—here this auto is required\nfor memory safety in coroutines, not self-reference.\n\n### Exception handling\n\n- Read the \"Exceptions in coroutines\" section within [tutorial.md](external/+non_module_dependencies+seastar/doc/tutorial.md)\n  to best understand how exceptions should be handled in Redpanda.\n- `throw` and `std::rethrow_exception()` may have an effect on performance, especially in hot paths.\n  There are several `seastar` utilities that should be preferred to explicitly throwing exceptions.\n  Namely, `ss::coroutine::try_future()`, `ss::coroutine::as_future()`, `ss::coroutine::return_exception()`,\n  and `ss::coroutine::return_exception_ptr()`. This is only a brief summary of the content in the tutorial above,\n  which must be read to fully understand exception handling in Redpanda.\n\n### C++ coding style\n\n- Use snake_case for identifiers. Use CamelCase for concepts.\n- Use Doxygen comments with 3-slashes (///) for public APIs\n\n### Code comments\n\n- **Default to no comments** - clear code and good names are better\n- **Avoid comments that restate the code** - they become stale\n- **Prefer alternatives:**\n  - Better variable/function names\n  - Log lines (serve as documentation and debugging)\n- **Do add comments for:**\n  - Doc comments (`/// \\brief`) on public types explaining purpose/usage\n  - Complex algorithms or non-obvious \"gotchas\"\n  - Test comments explaining input format or test intent\n  - Links to external resources (specs, docs, issues)\n  - Mapping internal types/concepts to external formats (e.g., wire protocols, APIs)\n  - ASCII diagrams for complex state machines or data flows\n- **Avoid obvious branching comments** - `if (x)` rarely needs `// when x is true`\n\n### Benchmarking\n\n  - Run benchmarks like `bazel run --config=release //src/v/utils/tests:coro_rpbench`\n  - Get --help like: `bazel run --config=release //src/v/utils/tests:coro_rpbench -- --help`\n  - If running/writing benchmarks read this also: external/+non_module_dependencies+seastar/tests/perf/perf-tests.md\n\n### More C++-Specific References\n\n- [MODULE.bazel](https://github.com/redpanda-data/redpanda/blob/dev/MODULE.bazel)\n- [BUILD](https://github.com/redpanda-data/redpanda/blob/dev/BUILD)\n\n---\n\n## Python specific instructions\n\n### Instructions for python test code under tests/rptest\n\n- Avoid catching bare `except:` as this can hide system exceptions, including exceptions\n  raised by a signal when a test is being forcibly timed out. Instead use `except Exception:`.\n- After modifying files under `tests/rptest`, run type checking via\n  `tools/type-checking/type-check.sh check <files...>` (paths positional, relative to `tests/`)\n  to scope it to your changes. Do not invoke `type-check.py` directly.\n  See `tools/type-checking/README.md` for more details: the per-file\n  strictness levels in `type-check-strictness.json` and how to promote\n  files to stricter levels after adding type hints.\n\n### Instructions for type hints\n\n- Use modern style with `|` instead of `Union` or `Optional`\n\nFor further details, consult:\n- [README.md](https://github.com/redpanda-data/redpanda/blob/dev/README.md)\n- [CONTRIBUTING.md](https://github.com/redpanda-data/redpanda/blob/dev/CONTRIBUTING.md)\n- [Redpanda Documentation](https://redpanda.com/documentation)\n- CI/CD configs in `.github/workflows/` and `.buildkite/`\n\n---\n\n## Commit message instructions\n\nWhen writing or critiquing commit messages, follow these guidelines:\n\n**Format:**\n```\narea[/detail]: short description\n\n<optional body>\n```\n\n- Title: ≤72 chars\n- Body: wrapped at 72 chars\n\n**Check git history first** to match the style of the area you're changing:\n```bash\ngit log --oneline --no-merges -- path/to/changed/files | head -20\n```\n\n**Goal:** Make the commit easy to review and provide context for future readers (via `git blame`/`git log`)\n\n**Rules:**\n- Title: imperative mood, lowercase after colon, no period\n- Keep bodies concise (1-2 lines typical, trivial changes need only a title)\n- Don't reference GitHub issues/PRs or Jira tickets\n- Use the body to help reviewers and future readers understand:\n  - The \"why\": motivation, design choices, preparation for future work\n  - The \"what\": new abstractions introduced, non-obvious changes\n  - Integration tests: briefly note what behaviors are covered\n- Don't restate what's obvious from the diff, but duplicating a doc comment is fine if it helps reviewers understand the change faster.\n\n_Results from code search may be incomplete. For more C++ details, see the [repository code search](https://github.com/redpanda-data/redpanda/search?q=c%2B%2B)._\n"},"items":[{"name":"CLAUDE.md","path":"CLAUDE.md","title":"CLAUDE.md","content":"# Copilot Coding Agent Onboarding Guide for `redpanda-data/redpanda`\n\n## High-Level Overview\n\n**What is Redpanda?**\n\nRedpanda is a high-performance, Apache Kafka®-compatible streaming data platform. It is written primarily in C++ for the core, with Go for CLI tooling (`rpk`), and some Python for auxiliary scripts and tests. Redpanda is designed to be lightweight, fast, and simple to operate, omitting ZooKeeper and the JVM.\n\nIt uses extensively the thread-per-core model and asynchronous (coroutines, futures) programming model.\n\n**Repository Characteristics:**\n- **Large multi-language codebase:** C++ (core), Go (CLI/tools), Python (testing/scripts), Bash and Bazel for builds.\n- **Build System:** Bazel (with Bazelisk) for core.\n- **Target Platforms:** Linux (primary), some support for macOS and Windows.\n- **Key Directories:**\n  - `src/v/`: Core C++ source code\n  - `src/go/`: Go CLI and tools\n  - `bazel/`, `BUILD`, `MODULE.bazel`: Bazel scripts and definitions\n  - `tools/`: Development and helper scripts\n  - `tests/`: Test suites\n  - `conf/`: Configuration files\n  - `proto/`: Protobuf definitions for Redpanda services and APIs\n  - `.github/`, `.buildkite/`: CI/workflow automation\n- **Documentation:** [Docs site](https://redpanda.com/documentation) and `docs/`.\n\n## Build, Test, and Validation Instructions\n\n### Prerequisites (Always Perform)\n\n1. **Install Bazelisk** (the required Bazel wrapper):\n   ```bash\n   wget -O ~/bin/bazel https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-amd64\n   chmod +x ~/bin/bazel\n   export PATH=\"$HOME/bin:$PATH\"\n   ```\n2. **Install system dependencies**:\n   ```bash\n   sudo ./bazel/install-deps.sh\n   ```\n   _This must always be run before any Bazel build, especially on a fresh system or after dependency updates._\n\n### Core Build Steps\n\n- **Build all (fastbuild):**\n  ```bash\n  bazel build //...\n  ```\n- **Test all:**\n  ```bash\n  bazel test //...\n  ```\n- **Lint (C++):**\n  - Formatting and linting are enforced. Use:\n    ```bash\n    bazel run //tools:clang_format\n    ```\n  - Configs: `.clang-format`, `.clang-tidy`, etc.\n\n- **Go CLI (`rpk`) Build:**\n  ```bash\n  bazel build //:rpk\n  ```\n\nSee `.bazelrc` for more details on build settings and config modes\n\n### Validation and CI\n\n- **Pre-push/merge:** All changes are validated by CI (GitHub Actions, Buildkite) for build, test, and lint.\n- **Formatting and lint checks are enforced; run locally before PRs.**\n- **Target branch:** Always open PRs against `dev`.\n\n## Project Layout & Architectural Notes\n\n- **Main C++ source:** `src/v/`\n- **Go CLI:** `src/go/rpk/`\n- **Build configuration:** `.bazelrc`, `.bazelversion`, `BUILD`, `MODULE.bazel`, and `bazel/`\n- **CI configuration:** `.github/workflows/`, `.buildkite/`\n- **Testing:** `tests/`\n- **Config:** `conf/`\n- **Docker:** `tools/docker/`\n\n### Lint/Formatting Configs:\n- `.clang-format`, `.clang-tidy*`: C++ style\n- `tools/ruff`, `.ruff.toml`: Python formatting\n\n### CI/CD Checks\n\n- **Build, test, and lint are enforced by CI.** Use the same steps as above locally before PRs.\n\n### File Index (Root Level)\n- `.bazelignore`, `.bazelrc`, `.bazelversion`, `BUILD`, `MODULE.bazel`, `README.md`, `CONTRIBUTING.md`, `SECURITY.md`, `CODE_OF_CONDUCT.md`, `LICENSES/`, `bazel/`, `src/`, `tests/`, `conf/`, `tools/`, `.github/`, `.buildkite/`, etc.\n\n---\n\n## Protobuf-Specific Instructions\n\n### Protobuf Coding Guidelines\n\nFollow the guidelines provided in `proto/redpanda/README.md` for basic Protobuf standards. For admin v2 ConnectRPC endpoints (proto → C++ service impl → registration → ducktape Python bindings), use the `add-admin-v2-endpoint` skill.\n\n### Protobuf Build & Environment\n- **Primary Protobuf code lives in `proto/`.**\n- **Formatting:** `.clang-format` in the root directory is enforced. Always run `clang-format` before committing changes or submitting a PR:\n  ```bash\n  bazel run //tools:clang_format\n  ```\n\n## C++-Specific Instructions\n\n### C++ Build & Environment\n\n- **Primary C++ code lives in `src/v/`.**\n- **C++ build is managed by Bazel.** All dependencies and toolchains are configured via Bazel rules and the `MODULE.bazel` file. Do not manually install C++ dependencies unless explicitly instructed in documentation.\n- **Compiler Standard:** C++23 is required. Some SDK components (e.g., `src/transform-sdk/cpp/`) use C++23 and specific flags like `-Wall`, `-fno-exceptions`, and for some targets, `-stdlib=libc++`.\n- **Sanitizers:** Some components and test builds use sanitizers (address, leak, undefined) via `-fsanitize=address,leak,undefined` for both compile and link.\n- **Suppression Files:** Leak, undefined, and other sanitizer suppressions can be found in the root as `lsan_suppressions.txt`, `ubsan_suppressions.txt`.\n- **C++ Linting:** `.clang-format` and `.clang-tidy` in the root directory are enforced. Always run `clang-format` before committing changes or submitting a PR:\n  ```bash\n  bazel run //tools:clang_format\n  ```\n- **C++ Libraries:** Bazel dependencies are managed in `MODULE.bazel` (e.g., Boost, Abseil, fmt, protobuf, googletest, yaml-cpp, etc.).\n- **Testing:** C++ unit tests are run via Bazel.\n\n### Common C++ Pitfalls & Workarounds\n\n- **Always use Bazelisk and Bazel for building the core.** Using a plain Bazel binary may result in missing dependencies or incompatible flags.\n- **If you encounter build issues related to missing system libraries, rerun `sudo ./bazel/install-deps.sh`.**\n- **Do not attempt to manually install or update C++ dependencies unless specifically instructed.**\n- **Always run lint and formatter before pushing. CI will fail on formatting/lint discrepancies.**\n- **If building in CI or a containerized environment, ensure the correct toolchain is available as specified in `tools/docker/README.md` or CI scripts.**\n- **Check for additional build and compile flags in `BUILD`, `MODULE.bazel` and related files.**\n\n### C++ coding guidelines\n\nCheck that these guidelines are followed for new code.\n\n- Do not declare new `operator<<(ostream& os, type)` overloads, instead prefer to use a `format_to` member function inside `type` as described in\nsrc/v/base/format_to.h.\n- Prefer using latest C++ features (C++23).\n- Use `ss` namespace as a prefix for Seastar types (e.g. `ss::future`, `ss::promise`).\n- Use `vassert(cond, msg, msg_args...)` macro for assertions. It is\n  similar to `assert(cond)` but it is always enabled and it prints the message\n  to the log. Use `dassert` for assertions that are only enabled in debug mode.\n- Use `vlog(method, fmt, args...)` for logging. `method` is the method reference\n  for the logger to use. I.e. `vlog(stlog.info, \"Hello world\");`. Where `stlog`\n  is defined as `ss::logger stlog(\"storage\");`.\n- Do not use `std::vector` for containers that may grow very large, instead use `chunked_vector`.\n- Do not use `std::unordered_map` for containers that may grow very large, instead use `chunked_hash_map`.\n- Instead of long if-else chains for mapping string to values, use\n  `string_switch` mechanism defined in\n  [string_switch.h](./src/v/strings/string_switch.h).\n- Don't use `ss::parallel_for_each` with ranges that can grow large such as\n  partitions, topics or segments. Instead prefer `ss::max_concurrent_for_each` to\n  limit concurrency. Think about how much concurrency is needed to adequately hide\n  latency. See our\n  [docs](https://redpandadata.atlassian.net/wiki/x/AQBZTw#Managing-Concurrency-in-the-system)\n  for more background.\n- Do not call the `get_exception` method on a future within a logging or\n  assertion statement (e.g. `vlog(..., fut.get_exception(), ...)`). Instead,\n  assign the return value of `get_exception` in a variable and pass the variable.\n\n#### Lambda coroutines, coroutine argument capture, and deducing this\n\nWhen a lambda coroutine is passed to APIs like `seastar::future::then()`,\nthe lambda object is stored in managed memory that gets freed once the\ncontinuation returns—but the coroutine may still be suspended and later\naccess its captures, causing use-after-free. This happens because the\ncoroutine frame holds a reference to the lambda's capture storage, which\nbecomes dangling. The C++23 \"deducing this\" syntax\n`([captures...](this auto, args...))` solves this by moving the captures\ndirectly into the coroutine frame rather than referencing them through the\nlambda object, decoupling capture lifetime from the lambda's lifetime.\nThis is distinct from the recursive-lambda use case—here this auto is required\nfor memory safety in coroutines, not self-reference.\n\n### Exception handling\n\n- Read the \"Exceptions in coroutines\" section within [tutorial.md](external/+non_module_dependencies+seastar/doc/tutorial.md)\n  to best understand how exceptions should be handled in Redpanda.\n- `throw` and `std::rethrow_exception()` may have an effect on performance, especially in hot paths.\n  There are several `seastar` utilities that should be preferred to explicitly throwing exceptions.\n  Namely, `ss::coroutine::try_future()`, `ss::coroutine::as_future()`, `ss::coroutine::return_exception()`,\n  and `ss::coroutine::return_exception_ptr()`. This is only a brief summary of the content in the tutorial above,\n  which must be read to fully understand exception handling in Redpanda.\n\n### C++ coding style\n\n- Use snake_case for identifiers. Use CamelCase for concepts.\n- Use Doxygen comments with 3-slashes (///) for public APIs\n\n### Code comments\n\n- **Default to no comments** - clear code and good names are better\n- **Avoid comments that restate the code** - they become stale\n- **Prefer alternatives:**\n  - Better variable/function names\n  - Log lines (serve as documentation and debugging)\n- **Do add comments for:**\n  - Doc comments (`/// \\brief`) on public types explaining purpose/usage\n  - Complex algorithms or non-obvious \"gotchas\"\n  - Test comments explaining input format or test intent\n  - Links to external resources (specs, docs, issues)\n  - Mapping internal types/concepts to external formats (e.g., wire protocols, APIs)\n  - ASCII diagrams for complex state machines or data flows\n- **Avoid obvious branching comments** - `if (x)` rarely needs `// when x is true`\n\n### Benchmarking\n\n  - Run benchmarks like `bazel run --config=release //src/v/utils/tests:coro_rpbench`\n  - Get --help like: `bazel run --config=release //src/v/utils/tests:coro_rpbench -- --help`\n  - If running/writing benchmarks read this also: external/+non_module_dependencies+seastar/tests/perf/perf-tests.md\n\n### More C++-Specific References\n\n- [MODULE.bazel](https://github.com/redpanda-data/redpanda/blob/dev/MODULE.bazel)\n- [BUILD](https://github.com/redpanda-data/redpanda/blob/dev/BUILD)\n\n---\n\n## Python specific instructions\n\n### Instructions for python test code under tests/rptest\n\n- Avoid catching bare `except:` as this can hide system exceptions, including exceptions\n  raised by a signal when a test is being forcibly timed out. Instead use `except Exception:`.\n- After modifying files under `tests/rptest`, run type checking via\n  `tools/type-checking/type-check.sh check <files...>` (paths positional, relative to `tests/`)\n  to scope it to your changes. Do not invoke `type-check.py` directly.\n  See `tools/type-checking/README.md` for more details: the per-file\n  strictness levels in `type-check-strictness.json` and how to promote\n  files to stricter levels after adding type hints.\n\n### Instructions for type hints\n\n- Use modern style with `|` instead of `Union` or `Optional`\n\nFor further details, consult:\n- [README.md](https://github.com/redpanda-data/redpanda/blob/dev/README.md)\n- [CONTRIBUTING.md](https://github.com/redpanda-data/redpanda/blob/dev/CONTRIBUTING.md)\n- [Redpanda Documentation](https://redpanda.com/documentation)\n- CI/CD configs in `.github/workflows/` and `.buildkite/`\n\n---\n\n## Commit message instructions\n\nWhen writing or critiquing commit messages, follow these guidelines:\n\n**Format:**\n```\narea[/detail]: short description\n\n<optional body>\n```\n\n- Title: ≤72 chars\n- Body: wrapped at 72 chars\n\n**Check git history first** to match the style of the area you're changing:\n```bash\ngit log --oneline --no-merges -- path/to/changed/files | head -20\n```\n\n**Goal:** Make the commit easy to review and provide context for future readers (via `git blame`/`git log`)\n\n**Rules:**\n- Title: imperative mood, lowercase after colon, no period\n- Keep bodies concise (1-2 lines typical, trivial changes need only a title)\n- Don't reference GitHub issues/PRs or Jira tickets\n- Use the body to help reviewers and future readers understand:\n  - The \"why\": motivation, design choices, preparation for future work\n  - The \"what\": new abstractions introduced, non-obvious changes\n  - Integration tests: briefly note what behaviors are covered\n- Don't restate what's obvious from the diff, but duplicating a doc comment is fine if it helps reviewers understand the change faster.\n\n_Results from code search may be incomplete. For more C++ details, see the [repository code search](https://github.com/redpanda-data/redpanda/search?q=c%2B%2B)._\n","category":"root","tokens":3246}]}