{"owner":"quickwit-oss","repo":"quickwit","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["CLAUDE.md"],"skills":{"CLAUDE.md":"# Quickwit Development Guide\n\n## About Quickwit\n\n[Quickwit](https://github.com/quickwit-oss/quickwit) is a cloud-native search engine for observability data (logs, traces, metrics). Key components:\n\n- **Tantivy + Parquet hybrid**: Full-text search via Tantivy, columnar analytics via Parquet\n- **Parquet metrics pipeline** (`quickwit-parquet-engine`): DataFusion/Parquet-based analytics (under active development)\n- **Three observability signals**: Metrics, traces, and logs — architectural decisions must generalize across all three\n\nSee `quickwit/CLAUDE.md` for architecture overview, crate descriptions, and build commands.\n\n## Core Policies\n\n- Execute given tasks fully, avoid TODOs or stubs.\n- If TODOs or stubs are absolutely necessary, ensure user is made aware and they are recorded in any resulting plans, phases, or specs.\n- Produce code and make decisions that are consistent across metrics, traces, and logs. Metrics is the current priority, then traces, then logs — but decisions should generalize to all three.\n- Tests should be holistic: do not work around broken implementations by manipulating tests.\n- Follow [CODE_STYLE.md](CODE_STYLE.md) for all coding conventions.\n\n## Known Pitfalls (Update When Claude Misbehaves)\n\n**Add rules here when Claude makes mistakes. This is a living document.**\n\n| Mistake | Correct Behavior | Bug Reference |\n|---------|------------------|---------------|\n| Adds mock/fallback implementations | Use real dependencies, no error masking | User preference |\n| Claims feature works without integration test | Run through the actual REST/gRPC stack | CLAUDE.md policy |\n| Uses workarounds to avoid proper setup | **NEVER** workaround — follow the rigorous path (clone deps, fix env, run real tests) | User policy |\n| Bypasses production path in tests | **MUST** test through HTTP/gRPC, not internal APIs | CLAUDE.md policy |\n| Uses `Path::exists()` | Disallowed by `clippy.toml` — use fallible alternatives | clippy.toml |\n| Uses `Option::is_some_and`, `is_none_or`, `xor`, `map_or`, `map_or_else` | Disallowed by `clippy.toml` — use explicit match/if-let instead | clippy.toml |\n| Ignores clippy warnings | Run `cargo clippy --workspace --all-features --tests`. Fix warnings or add targeted `#[allow()]` with justification | Code quality |\n| Uses `debug_assert` for user-facing validation | Use `Result` errors — debug_assert is silent in release | Code quality |\n| Uses `unwrap()` in library code | Use `?` operator or proper error types | Quickwit style |\n| File over 500 lines | Split into focused modules by responsibility | Code quality |\n| Unnecessary `.clone()` in non-concurrent code | Return `&self` references or `Arc<T>` — cloning is OK in actor/async code for simplicity | Code quality |\n| Raw String for new domain types | Prefer existing type aliases (`IndexId`, `SplitId`, `SourceId` from `quickwit-proto`) | Quickwit style |\n| Shadowing variable names within a function | Avoid reusing the same variable name (see CODE_STYLE.md) | Quickwit style |\n| Uses chained iterators with complex error handling | Use procedural for-loops when chaining hurts readability | Quickwit style |\n| Uses `tokio::sync::Mutex` | **FORBIDDEN** — causes data corruption on cancel. Use actor model with message passing | GAP-002 |\n| Uses `JoinHandle::abort()` | **FORBIDDEN** — arbitrary cancellation violates invariants. Use `CancellationToken` | GAP-002 |\n| Recreates futures in `select!` loops | Use `&mut fut` to resume, not recreate — dropping loses data | GAP-002 |\n| Holds locks across await points | Invariant violations on cancel. Use message passing or synchronous critical sections | GAP-002 |\n| Silently swallows unexpected state | If a condition \"shouldn't happen,\" return an error or assert — don't silently return Ok. Skipping optional/missing data is fine; pretending a bug didn't occur is not | Code quality |\n| Replies to PR review comments as standalone inline comments | Use `gh api repos/.../pulls/{pr}/comments/{codex_comment_id}/replies` (or `in_reply_to_id` in the POST body) so the reply is **threaded under** the original review comment. Standalone inline comments at the same line are NOT replies; they show as separate threads. Verify with the GitHub API that `in_reply_to_id` is set on your reply. | Review hygiene |\n\n## Engineering Priority\n\n**Safety > Performance > Developer Experience**\n\n| Pillar | Location | Purpose |\n|--------|----------|---------|\n| **Code Quality** | [CODE_STYLE.md](CODE_STYLE.md) + this doc | Coding standards & reliability |\n\n> For formal specs (TLA+, Stateright) and DST pillars, see the verification docs below. These describe the target workflow — implementation is in progress.\n\n## Reliability Rules\n\n```rust\n// 1. Use debug_assert! to document invariants\n// (Quickwit CODE_STYLE.md endorses this — helps reviewers proofread)\ndebug_assert!(offset >= HEADER_SIZE, \"offset must include header\");\ndebug_assert!(splits.is_sorted_by_key(|s| s.time_range.end));\n\n// 2. Validate inputs at API boundaries (Result, not debug_assert)\nif duration.as_nanos() == 0 {\n    return Err(Error::InvalidParameter(\"duration must be positive\"));\n}\n\n// 3. Define explicit limits as constants\nconst MAX_SEGMENT_SIZE: usize = 256 * 1024 * 1024;\nif size > MAX_SEGMENT_SIZE {\n    return Err(Error::LimitExceeded(...));\n}\n\n// 4. No unwrap() in library code — propagate errors\nlet timestamp = DateTime::from_timestamp(secs, nsecs)\n    .ok_or_else(|| anyhow!(\"invalid timestamp: {}\", nanos))?;\n```\n\n## Testing Through Production Path\n\n**MUST NOT** claim a feature works unless tested through the actual network stack.\n\n```bash\n# 1. Start quickwit\ncargo run -p quickwit-cli -- run --config ../config/quickwit.yaml\n\n# 2. Ingest via OTLP\n# (send logs/traces to localhost:4317)\n\n# 3. Query via REST API\ncurl http://localhost:7280/api/v1/<index>/search -d '{\"query\": \"*\"}'\n```\n\n**Bypasses to AVOID**: Testing indexing pipeline without the HTTP/gRPC server, testing search without the REST API layer.\n\n## Repository Layout\n\n```\nquickwit/                            # Repository root\n├── quickwit/                        # Main Rust workspace (all crates live here)\n│   ├── Cargo.toml                   # Workspace root\n│   ├── CLAUDE.md                    # Build commands, architecture overview, crate guide\n│   ├── Makefile                     # Build targets (fmt, fix, test-all, build)\n│   ├── clippy.toml                  # Disallowed methods (enforced)\n│   ├── rustfmt.toml                 # Nightly formatter config\n│   ├── rust-toolchain.toml          # Pinned Rust toolchain\n│   ├── scripts/                     # License header checks, log format checks\n│   └── rest-api-tests/              # Python-based REST API integration tests\n├── docs/\n│   └── internals/                   # Architecture docs\n│       ├── adr/                     # Architecture Decision Records\n│       │   ├── README.md            # ADR index\n│       │   ├── gaps/                # Design limitations from incidents\n│       │   └── deviations/          # Intentional divergences from ADR intent\n│       └── specs/\n│           └── tla/                 # TLA+ specs for protocols and state machines\n├── config/                          # Runtime YAML configs (quickwit.yaml, etc.)\n├── Makefile                         # Outer orchestration (delegates to quickwit/)\n└── docker-compose.yml               # Local services (localstack, postgres, kafka, jaeger, etc.)\n```\n\n## Architecture Evolution\n\nQuickwit tracks architectural change through three lenses. See `docs/internals/adr/EVOLUTION.md` for the full process.\n\n```\n                    Architecture Evolution\n                            │\n       ┌────────────────────┼────────────────────┐\n       ▼                    ▼                    ▼\n Characteristics          Gaps              Deviations\n  (Proactive)          (Reactive)          (Pragmatic)\n \"What we need\"      \"What we learned\"   \"What we accepted\"\n```\n\n| Lens | Location | When to Use |\n|------|----------|-------------|\n| **Characteristics** | `docs/internals/adr/` | Track cloud-native requirements |\n| **Gaps** | `docs/internals/adr/gaps/` | Design limitation from incident/production |\n| **Deviations** | `docs/internals/adr/deviations/` | Intentional divergence from ADR intent |\n\n## Common Commands\n\nAll Rust commands run from the `quickwit/` subdirectory.\n\n```bash\n# Build\ncd quickwit && cargo build\n\n# Run all tests (requires Docker services)\n# From repo root:\nmake docker-compose-up\nmake test-all\n# Or from quickwit/:\ncargo nextest run --all-features --retries 5\n\n# Run tests for a specific crate\ncargo nextest run -p quickwit-indexing --all-features\n\n# Run failpoint tests\ncargo nextest run --test failpoints --features fail/failpoints\n\n# Clippy (must pass before commit)\ncargo clippy --workspace --all-features --tests\n\n# Format (requires nightly)\ncargo +nightly fmt --all\n\n# Auto-fix clippy + format\nmake fix    # from quickwit/\n\n# Check license headers\nbash scripts/check_license_headers.sh\n\n# Check log format\nbash scripts/check_log_format.sh\n\n# Spellcheck (from repo root)\nmake typos  # or: typos\n\n# REST API integration tests (Python)\ncd quickwit/rest-api-tests\npipenv shell && pipenv install\n./run_tests.py --engine quickwit\n```\n\n## Testing Strategy\n\n### Unit Tests\n- Run fast, avoid IO when possible\n- Testing private functions is encouraged\n- Property-based tests (`proptest`) are welcome — narrow the search space\n- Not always deterministic — proptests are fine\n\n### Integration Tests\n- `quickwit-integration-tests/`: Rust integration tests exercising the full stack\n- `rest-api-tests/`: Python YAML-driven tests for Elasticsearch API compatibility\n\n### Required for CI\n- `cargo nextest run --all-features --retries 5` (with Docker services running)\n- Failpoint tests: `cargo nextest run --test failpoints --features fail/failpoints`\n- `RUST_MIN_STACK=67108864` is set for test runs (64MB stack)\n\n## Docker Services for Testing\n\n```bash\n# Start all services (localstack, postgres, kafka, jaeger, etc.)\nmake docker-compose-up\n\n# Start specific services\nmake docker-compose-up DOCKER_SERVICES='jaeger,localstack'\n\n# Tear down\nmake docker-compose-down\n```\n\nEnvironment variables set during test-all:\n- `AWS_ACCESS_KEY_ID=ignored`, `AWS_SECRET_ACCESS_KEY=ignored`\n- `QW_S3_ENDPOINT=http://localhost:4566` (localstack)\n- `QW_S3_FORCE_PATH_STYLE_ACCESS=1`\n- `QW_TEST_DATABASE_URL=postgres://quickwit-dev:quickwit-dev@localhost:5432/quickwit-metastore-dev`\n\n## Key Entry Points\n\n| Port | Protocol | Purpose |\n|------|----------|---------|\n| 7280 | HTTP | Quickwit REST API |\n| 7281 | gRPC | Quickwit gRPC services |\n| 4317 | gRPC | OTLP ingest |\n\n## Checklist Before Committing\n\n**MUST** (required for merge):\n- [ ] `cargo clippy --workspace --all-features --tests` passes with no warnings\n- [ ] `cargo +nightly fmt --all -- --check` passes (run `cargo +nightly fmt --all` to fix; applies to **all** changed `.rs` files including tests — CI checks every file, not just lib code)\n- [ ] `debug_assert!` for non-obvious invariants\n- [ ] No `unwrap()` in library code\n- [ ] No silent error ignoring (`let _ =`)\n- [ ] New files under 500 lines (split by responsibility if larger)\n- [ ] No unnecessary `.clone()` (OK in actor/async code for clarity)\n- [ ] Tests through production path (HTTP/gRPC)\n- [ ] License headers present (run `bash quickwit/scripts/check_license_headers.sh` — every `.rs`, `.proto`, and `.py` file needs the Apache 2.0 header)\n- [ ] Log format correct (run `bash quickwit/scripts/check_log_format.sh`)\n- [ ] `typos` passes (spellcheck)\n- [ ] `cargo machete` passes (no unused dependencies in Cargo.toml)\n- [ ] `cargo doc --no-deps` passes (each PR must compile independently, not just the final stack)\n- [ ] Tests pass: `cargo nextest run --all-features`\n\n**SHOULD** (expected unless justified):\n- [ ] Functions under 70 lines\n- [ ] Explanatory variables for complex expressions\n- [ ] Documentation explains \"why\"\n- [ ] Integration test for new API endpoints\n\n## Detailed Documentation\n\n| Topic | Location |\n|-------|----------|\n| Code style (Quickwit) | [CODE_STYLE.md](CODE_STYLE.md) |\n| Rust style patterns | [docs/internals/RUST_STYLE.md](docs/internals/RUST_STYLE.md) |\n| Verification & DST | [docs/internals/VERIFICATION.md](docs/internals/VERIFICATION.md) |\n| Verification philosophy | [docs/internals/VERIFICATION_STACK.md](docs/internals/VERIFICATION_STACK.md) |\n| Simulation workflow | [docs/internals/SIMULATION_FIRST_WORKFLOW.md](docs/internals/SIMULATION_FIRST_WORKFLOW.md) |\n| Benchmarking | [docs/internals/BENCHMARKING.md](docs/internals/BENCHMARKING.md) |\n| Contributing guide | [CONTRIBUTING.md](CONTRIBUTING.md) |\n| ADR index | [docs/internals/adr/README.md](docs/internals/adr/README.md) |\n| Architecture evolution | [docs/internals/adr/EVOLUTION.md](docs/internals/adr/EVOLUTION.md) |\n| Compaction architecture | [docs/internals/compaction-architecture.md](docs/internals/compaction-architecture.md) |\n| Tantivy + Parquet design | [docs/internals/tantivy-parquet-architecture.md](docs/internals/tantivy-parquet-architecture.md) |\n| Locality compaction | [docs/internals/locality-compaction/](docs/internals/locality-compaction/) |\n| Runtime config | [config/quickwit.yaml](config/quickwit.yaml) |\n\n## References\n\n- [Quickwit](https://github.com/quickwit-oss/quickwit)\n- [Tantivy search engine](https://github.com/quickwit-oss/tantivy)\n- [Apache DataFusion](https://datafusion.apache.org/)\n"},"files":{"CLAUDE.md":"# Quickwit Development Guide\n\n## About Quickwit\n\n[Quickwit](https://github.com/quickwit-oss/quickwit) is a cloud-native search engine for observability data (logs, traces, metrics). Key components:\n\n- **Tantivy + Parquet hybrid**: Full-text search via Tantivy, columnar analytics via Parquet\n- **Parquet metrics pipeline** (`quickwit-parquet-engine`): DataFusion/Parquet-based analytics (under active development)\n- **Three observability signals**: Metrics, traces, and logs — architectural decisions must generalize across all three\n\nSee `quickwit/CLAUDE.md` for architecture overview, crate descriptions, and build commands.\n\n## Core Policies\n\n- Execute given tasks fully, avoid TODOs or stubs.\n- If TODOs or stubs are absolutely necessary, ensure user is made aware and they are recorded in any resulting plans, phases, or specs.\n- Produce code and make decisions that are consistent across metrics, traces, and logs. Metrics is the current priority, then traces, then logs — but decisions should generalize to all three.\n- Tests should be holistic: do not work around broken implementations by manipulating tests.\n- Follow [CODE_STYLE.md](CODE_STYLE.md) for all coding conventions.\n\n## Known Pitfalls (Update When Claude Misbehaves)\n\n**Add rules here when Claude makes mistakes. This is a living document.**\n\n| Mistake | Correct Behavior | Bug Reference |\n|---------|------------------|---------------|\n| Adds mock/fallback implementations | Use real dependencies, no error masking | User preference |\n| Claims feature works without integration test | Run through the actual REST/gRPC stack | CLAUDE.md policy |\n| Uses workarounds to avoid proper setup | **NEVER** workaround — follow the rigorous path (clone deps, fix env, run real tests) | User policy |\n| Bypasses production path in tests | **MUST** test through HTTP/gRPC, not internal APIs | CLAUDE.md policy |\n| Uses `Path::exists()` | Disallowed by `clippy.toml` — use fallible alternatives | clippy.toml |\n| Uses `Option::is_some_and`, `is_none_or`, `xor`, `map_or`, `map_or_else` | Disallowed by `clippy.toml` — use explicit match/if-let instead | clippy.toml |\n| Ignores clippy warnings | Run `cargo clippy --workspace --all-features --tests`. Fix warnings or add targeted `#[allow()]` with justification | Code quality |\n| Uses `debug_assert` for user-facing validation | Use `Result` errors — debug_assert is silent in release | Code quality |\n| Uses `unwrap()` in library code | Use `?` operator or proper error types | Quickwit style |\n| File over 500 lines | Split into focused modules by responsibility | Code quality |\n| Unnecessary `.clone()` in non-concurrent code | Return `&self` references or `Arc<T>` — cloning is OK in actor/async code for simplicity | Code quality |\n| Raw String for new domain types | Prefer existing type aliases (`IndexId`, `SplitId`, `SourceId` from `quickwit-proto`) | Quickwit style |\n| Shadowing variable names within a function | Avoid reusing the same variable name (see CODE_STYLE.md) | Quickwit style |\n| Uses chained iterators with complex error handling | Use procedural for-loops when chaining hurts readability | Quickwit style |\n| Uses `tokio::sync::Mutex` | **FORBIDDEN** — causes data corruption on cancel. Use actor model with message passing | GAP-002 |\n| Uses `JoinHandle::abort()` | **FORBIDDEN** — arbitrary cancellation violates invariants. Use `CancellationToken` | GAP-002 |\n| Recreates futures in `select!` loops | Use `&mut fut` to resume, not recreate — dropping loses data | GAP-002 |\n| Holds locks across await points | Invariant violations on cancel. Use message passing or synchronous critical sections | GAP-002 |\n| Silently swallows unexpected state | If a condition \"shouldn't happen,\" return an error or assert — don't silently return Ok. Skipping optional/missing data is fine; pretending a bug didn't occur is not | Code quality |\n| Replies to PR review comments as standalone inline comments | Use `gh api repos/.../pulls/{pr}/comments/{codex_comment_id}/replies` (or `in_reply_to_id` in the POST body) so the reply is **threaded under** the original review comment. Standalone inline comments at the same line are NOT replies; they show as separate threads. Verify with the GitHub API that `in_reply_to_id` is set on your reply. | Review hygiene |\n\n## Engineering Priority\n\n**Safety > Performance > Developer Experience**\n\n| Pillar | Location | Purpose |\n|--------|----------|---------|\n| **Code Quality** | [CODE_STYLE.md](CODE_STYLE.md) + this doc | Coding standards & reliability |\n\n> For formal specs (TLA+, Stateright) and DST pillars, see the verification docs below. These describe the target workflow — implementation is in progress.\n\n## Reliability Rules\n\n```rust\n// 1. Use debug_assert! to document invariants\n// (Quickwit CODE_STYLE.md endorses this — helps reviewers proofread)\ndebug_assert!(offset >= HEADER_SIZE, \"offset must include header\");\ndebug_assert!(splits.is_sorted_by_key(|s| s.time_range.end));\n\n// 2. Validate inputs at API boundaries (Result, not debug_assert)\nif duration.as_nanos() == 0 {\n    return Err(Error::InvalidParameter(\"duration must be positive\"));\n}\n\n// 3. Define explicit limits as constants\nconst MAX_SEGMENT_SIZE: usize = 256 * 1024 * 1024;\nif size > MAX_SEGMENT_SIZE {\n    return Err(Error::LimitExceeded(...));\n}\n\n// 4. No unwrap() in library code — propagate errors\nlet timestamp = DateTime::from_timestamp(secs, nsecs)\n    .ok_or_else(|| anyhow!(\"invalid timestamp: {}\", nanos))?;\n```\n\n## Testing Through Production Path\n\n**MUST NOT** claim a feature works unless tested through the actual network stack.\n\n```bash\n# 1. Start quickwit\ncargo run -p quickwit-cli -- run --config ../config/quickwit.yaml\n\n# 2. Ingest via OTLP\n# (send logs/traces to localhost:4317)\n\n# 3. Query via REST API\ncurl http://localhost:7280/api/v1/<index>/search -d '{\"query\": \"*\"}'\n```\n\n**Bypasses to AVOID**: Testing indexing pipeline without the HTTP/gRPC server, testing search without the REST API layer.\n\n## Repository Layout\n\n```\nquickwit/                            # Repository root\n├── quickwit/                        # Main Rust workspace (all crates live here)\n│   ├── Cargo.toml                   # Workspace root\n│   ├── CLAUDE.md                    # Build commands, architecture overview, crate guide\n│   ├── Makefile                     # Build targets (fmt, fix, test-all, build)\n│   ├── clippy.toml                  # Disallowed methods (enforced)\n│   ├── rustfmt.toml                 # Nightly formatter config\n│   ├── rust-toolchain.toml          # Pinned Rust toolchain\n│   ├── scripts/                     # License header checks, log format checks\n│   └── rest-api-tests/              # Python-based REST API integration tests\n├── docs/\n│   └── internals/                   # Architecture docs\n│       ├── adr/                     # Architecture Decision Records\n│       │   ├── README.md            # ADR index\n│       │   ├── gaps/                # Design limitations from incidents\n│       │   └── deviations/          # Intentional divergences from ADR intent\n│       └── specs/\n│           └── tla/                 # TLA+ specs for protocols and state machines\n├── config/                          # Runtime YAML configs (quickwit.yaml, etc.)\n├── Makefile                         # Outer orchestration (delegates to quickwit/)\n└── docker-compose.yml               # Local services (localstack, postgres, kafka, jaeger, etc.)\n```\n\n## Architecture Evolution\n\nQuickwit tracks architectural change through three lenses. See `docs/internals/adr/EVOLUTION.md` for the full process.\n\n```\n                    Architecture Evolution\n                            │\n       ┌────────────────────┼────────────────────┐\n       ▼                    ▼                    ▼\n Characteristics          Gaps              Deviations\n  (Proactive)          (Reactive)          (Pragmatic)\n \"What we need\"      \"What we learned\"   \"What we accepted\"\n```\n\n| Lens | Location | When to Use |\n|------|----------|-------------|\n| **Characteristics** | `docs/internals/adr/` | Track cloud-native requirements |\n| **Gaps** | `docs/internals/adr/gaps/` | Design limitation from incident/production |\n| **Deviations** | `docs/internals/adr/deviations/` | Intentional divergence from ADR intent |\n\n## Common Commands\n\nAll Rust commands run from the `quickwit/` subdirectory.\n\n```bash\n# Build\ncd quickwit && cargo build\n\n# Run all tests (requires Docker services)\n# From repo root:\nmake docker-compose-up\nmake test-all\n# Or from quickwit/:\ncargo nextest run --all-features --retries 5\n\n# Run tests for a specific crate\ncargo nextest run -p quickwit-indexing --all-features\n\n# Run failpoint tests\ncargo nextest run --test failpoints --features fail/failpoints\n\n# Clippy (must pass before commit)\ncargo clippy --workspace --all-features --tests\n\n# Format (requires nightly)\ncargo +nightly fmt --all\n\n# Auto-fix clippy + format\nmake fix    # from quickwit/\n\n# Check license headers\nbash scripts/check_license_headers.sh\n\n# Check log format\nbash scripts/check_log_format.sh\n\n# Spellcheck (from repo root)\nmake typos  # or: typos\n\n# REST API integration tests (Python)\ncd quickwit/rest-api-tests\npipenv shell && pipenv install\n./run_tests.py --engine quickwit\n```\n\n## Testing Strategy\n\n### Unit Tests\n- Run fast, avoid IO when possible\n- Testing private functions is encouraged\n- Property-based tests (`proptest`) are welcome — narrow the search space\n- Not always deterministic — proptests are fine\n\n### Integration Tests\n- `quickwit-integration-tests/`: Rust integration tests exercising the full stack\n- `rest-api-tests/`: Python YAML-driven tests for Elasticsearch API compatibility\n\n### Required for CI\n- `cargo nextest run --all-features --retries 5` (with Docker services running)\n- Failpoint tests: `cargo nextest run --test failpoints --features fail/failpoints`\n- `RUST_MIN_STACK=67108864` is set for test runs (64MB stack)\n\n## Docker Services for Testing\n\n```bash\n# Start all services (localstack, postgres, kafka, jaeger, etc.)\nmake docker-compose-up\n\n# Start specific services\nmake docker-compose-up DOCKER_SERVICES='jaeger,localstack'\n\n# Tear down\nmake docker-compose-down\n```\n\nEnvironment variables set during test-all:\n- `AWS_ACCESS_KEY_ID=ignored`, `AWS_SECRET_ACCESS_KEY=ignored`\n- `QW_S3_ENDPOINT=http://localhost:4566` (localstack)\n- `QW_S3_FORCE_PATH_STYLE_ACCESS=1`\n- `QW_TEST_DATABASE_URL=postgres://quickwit-dev:quickwit-dev@localhost:5432/quickwit-metastore-dev`\n\n## Key Entry Points\n\n| Port | Protocol | Purpose |\n|------|----------|---------|\n| 7280 | HTTP | Quickwit REST API |\n| 7281 | gRPC | Quickwit gRPC services |\n| 4317 | gRPC | OTLP ingest |\n\n## Checklist Before Committing\n\n**MUST** (required for merge):\n- [ ] `cargo clippy --workspace --all-features --tests` passes with no warnings\n- [ ] `cargo +nightly fmt --all -- --check` passes (run `cargo +nightly fmt --all` to fix; applies to **all** changed `.rs` files including tests — CI checks every file, not just lib code)\n- [ ] `debug_assert!` for non-obvious invariants\n- [ ] No `unwrap()` in library code\n- [ ] No silent error ignoring (`let _ =`)\n- [ ] New files under 500 lines (split by responsibility if larger)\n- [ ] No unnecessary `.clone()` (OK in actor/async code for clarity)\n- [ ] Tests through production path (HTTP/gRPC)\n- [ ] License headers present (run `bash quickwit/scripts/check_license_headers.sh` — every `.rs`, `.proto`, and `.py` file needs the Apache 2.0 header)\n- [ ] Log format correct (run `bash quickwit/scripts/check_log_format.sh`)\n- [ ] `typos` passes (spellcheck)\n- [ ] `cargo machete` passes (no unused dependencies in Cargo.toml)\n- [ ] `cargo doc --no-deps` passes (each PR must compile independently, not just the final stack)\n- [ ] Tests pass: `cargo nextest run --all-features`\n\n**SHOULD** (expected unless justified):\n- [ ] Functions under 70 lines\n- [ ] Explanatory variables for complex expressions\n- [ ] Documentation explains \"why\"\n- [ ] Integration test for new API endpoints\n\n## Detailed Documentation\n\n| Topic | Location |\n|-------|----------|\n| Code style (Quickwit) | [CODE_STYLE.md](CODE_STYLE.md) |\n| Rust style patterns | [docs/internals/RUST_STYLE.md](docs/internals/RUST_STYLE.md) |\n| Verification & DST | [docs/internals/VERIFICATION.md](docs/internals/VERIFICATION.md) |\n| Verification philosophy | [docs/internals/VERIFICATION_STACK.md](docs/internals/VERIFICATION_STACK.md) |\n| Simulation workflow | [docs/internals/SIMULATION_FIRST_WORKFLOW.md](docs/internals/SIMULATION_FIRST_WORKFLOW.md) |\n| Benchmarking | [docs/internals/BENCHMARKING.md](docs/internals/BENCHMARKING.md) |\n| Contributing guide | [CONTRIBUTING.md](CONTRIBUTING.md) |\n| ADR index | [docs/internals/adr/README.md](docs/internals/adr/README.md) |\n| Architecture evolution | [docs/internals/adr/EVOLUTION.md](docs/internals/adr/EVOLUTION.md) |\n| Compaction architecture | [docs/internals/compaction-architecture.md](docs/internals/compaction-architecture.md) |\n| Tantivy + Parquet design | [docs/internals/tantivy-parquet-architecture.md](docs/internals/tantivy-parquet-architecture.md) |\n| Locality compaction | [docs/internals/locality-compaction/](docs/internals/locality-compaction/) |\n| Runtime config | [config/quickwit.yaml](config/quickwit.yaml) |\n\n## References\n\n- [Quickwit](https://github.com/quickwit-oss/quickwit)\n- [Tantivy search engine](https://github.com/quickwit-oss/tantivy)\n- [Apache DataFusion](https://datafusion.apache.org/)\n"},"items":[{"name":"CLAUDE.md","path":"CLAUDE.md","title":"CLAUDE.md","content":"# Quickwit Development Guide\n\n## About Quickwit\n\n[Quickwit](https://github.com/quickwit-oss/quickwit) is a cloud-native search engine for observability data (logs, traces, metrics). Key components:\n\n- **Tantivy + Parquet hybrid**: Full-text search via Tantivy, columnar analytics via Parquet\n- **Parquet metrics pipeline** (`quickwit-parquet-engine`): DataFusion/Parquet-based analytics (under active development)\n- **Three observability signals**: Metrics, traces, and logs — architectural decisions must generalize across all three\n\nSee `quickwit/CLAUDE.md` for architecture overview, crate descriptions, and build commands.\n\n## Core Policies\n\n- Execute given tasks fully, avoid TODOs or stubs.\n- If TODOs or stubs are absolutely necessary, ensure user is made aware and they are recorded in any resulting plans, phases, or specs.\n- Produce code and make decisions that are consistent across metrics, traces, and logs. Metrics is the current priority, then traces, then logs — but decisions should generalize to all three.\n- Tests should be holistic: do not work around broken implementations by manipulating tests.\n- Follow [CODE_STYLE.md](CODE_STYLE.md) for all coding conventions.\n\n## Known Pitfalls (Update When Claude Misbehaves)\n\n**Add rules here when Claude makes mistakes. This is a living document.**\n\n| Mistake | Correct Behavior | Bug Reference |\n|---------|------------------|---------------|\n| Adds mock/fallback implementations | Use real dependencies, no error masking | User preference |\n| Claims feature works without integration test | Run through the actual REST/gRPC stack | CLAUDE.md policy |\n| Uses workarounds to avoid proper setup | **NEVER** workaround — follow the rigorous path (clone deps, fix env, run real tests) | User policy |\n| Bypasses production path in tests | **MUST** test through HTTP/gRPC, not internal APIs | CLAUDE.md policy |\n| Uses `Path::exists()` | Disallowed by `clippy.toml` — use fallible alternatives | clippy.toml |\n| Uses `Option::is_some_and`, `is_none_or`, `xor`, `map_or`, `map_or_else` | Disallowed by `clippy.toml` — use explicit match/if-let instead | clippy.toml |\n| Ignores clippy warnings | Run `cargo clippy --workspace --all-features --tests`. Fix warnings or add targeted `#[allow()]` with justification | Code quality |\n| Uses `debug_assert` for user-facing validation | Use `Result` errors — debug_assert is silent in release | Code quality |\n| Uses `unwrap()` in library code | Use `?` operator or proper error types | Quickwit style |\n| File over 500 lines | Split into focused modules by responsibility | Code quality |\n| Unnecessary `.clone()` in non-concurrent code | Return `&self` references or `Arc<T>` — cloning is OK in actor/async code for simplicity | Code quality |\n| Raw String for new domain types | Prefer existing type aliases (`IndexId`, `SplitId`, `SourceId` from `quickwit-proto`) | Quickwit style |\n| Shadowing variable names within a function | Avoid reusing the same variable name (see CODE_STYLE.md) | Quickwit style |\n| Uses chained iterators with complex error handling | Use procedural for-loops when chaining hurts readability | Quickwit style |\n| Uses `tokio::sync::Mutex` | **FORBIDDEN** — causes data corruption on cancel. Use actor model with message passing | GAP-002 |\n| Uses `JoinHandle::abort()` | **FORBIDDEN** — arbitrary cancellation violates invariants. Use `CancellationToken` | GAP-002 |\n| Recreates futures in `select!` loops | Use `&mut fut` to resume, not recreate — dropping loses data | GAP-002 |\n| Holds locks across await points | Invariant violations on cancel. Use message passing or synchronous critical sections | GAP-002 |\n| Silently swallows unexpected state | If a condition \"shouldn't happen,\" return an error or assert — don't silently return Ok. Skipping optional/missing data is fine; pretending a bug didn't occur is not | Code quality |\n| Replies to PR review comments as standalone inline comments | Use `gh api repos/.../pulls/{pr}/comments/{codex_comment_id}/replies` (or `in_reply_to_id` in the POST body) so the reply is **threaded under** the original review comment. Standalone inline comments at the same line are NOT replies; they show as separate threads. Verify with the GitHub API that `in_reply_to_id` is set on your reply. | Review hygiene |\n\n## Engineering Priority\n\n**Safety > Performance > Developer Experience**\n\n| Pillar | Location | Purpose |\n|--------|----------|---------|\n| **Code Quality** | [CODE_STYLE.md](CODE_STYLE.md) + this doc | Coding standards & reliability |\n\n> For formal specs (TLA+, Stateright) and DST pillars, see the verification docs below. These describe the target workflow — implementation is in progress.\n\n## Reliability Rules\n\n```rust\n// 1. Use debug_assert! to document invariants\n// (Quickwit CODE_STYLE.md endorses this — helps reviewers proofread)\ndebug_assert!(offset >= HEADER_SIZE, \"offset must include header\");\ndebug_assert!(splits.is_sorted_by_key(|s| s.time_range.end));\n\n// 2. Validate inputs at API boundaries (Result, not debug_assert)\nif duration.as_nanos() == 0 {\n    return Err(Error::InvalidParameter(\"duration must be positive\"));\n}\n\n// 3. Define explicit limits as constants\nconst MAX_SEGMENT_SIZE: usize = 256 * 1024 * 1024;\nif size > MAX_SEGMENT_SIZE {\n    return Err(Error::LimitExceeded(...));\n}\n\n// 4. No unwrap() in library code — propagate errors\nlet timestamp = DateTime::from_timestamp(secs, nsecs)\n    .ok_or_else(|| anyhow!(\"invalid timestamp: {}\", nanos))?;\n```\n\n## Testing Through Production Path\n\n**MUST NOT** claim a feature works unless tested through the actual network stack.\n\n```bash\n# 1. Start quickwit\ncargo run -p quickwit-cli -- run --config ../config/quickwit.yaml\n\n# 2. Ingest via OTLP\n# (send logs/traces to localhost:4317)\n\n# 3. Query via REST API\ncurl http://localhost:7280/api/v1/<index>/search -d '{\"query\": \"*\"}'\n```\n\n**Bypasses to AVOID**: Testing indexing pipeline without the HTTP/gRPC server, testing search without the REST API layer.\n\n## Repository Layout\n\n```\nquickwit/                            # Repository root\n├── quickwit/                        # Main Rust workspace (all crates live here)\n│   ├── Cargo.toml                   # Workspace root\n│   ├── CLAUDE.md                    # Build commands, architecture overview, crate guide\n│   ├── Makefile                     # Build targets (fmt, fix, test-all, build)\n│   ├── clippy.toml                  # Disallowed methods (enforced)\n│   ├── rustfmt.toml                 # Nightly formatter config\n│   ├── rust-toolchain.toml          # Pinned Rust toolchain\n│   ├── scripts/                     # License header checks, log format checks\n│   └── rest-api-tests/              # Python-based REST API integration tests\n├── docs/\n│   └── internals/                   # Architecture docs\n│       ├── adr/                     # Architecture Decision Records\n│       │   ├── README.md            # ADR index\n│       │   ├── gaps/                # Design limitations from incidents\n│       │   └── deviations/          # Intentional divergences from ADR intent\n│       └── specs/\n│           └── tla/                 # TLA+ specs for protocols and state machines\n├── config/                          # Runtime YAML configs (quickwit.yaml, etc.)\n├── Makefile                         # Outer orchestration (delegates to quickwit/)\n└── docker-compose.yml               # Local services (localstack, postgres, kafka, jaeger, etc.)\n```\n\n## Architecture Evolution\n\nQuickwit tracks architectural change through three lenses. See `docs/internals/adr/EVOLUTION.md` for the full process.\n\n```\n                    Architecture Evolution\n                            │\n       ┌────────────────────┼────────────────────┐\n       ▼                    ▼                    ▼\n Characteristics          Gaps              Deviations\n  (Proactive)          (Reactive)          (Pragmatic)\n \"What we need\"      \"What we learned\"   \"What we accepted\"\n```\n\n| Lens | Location | When to Use |\n|------|----------|-------------|\n| **Characteristics** | `docs/internals/adr/` | Track cloud-native requirements |\n| **Gaps** | `docs/internals/adr/gaps/` | Design limitation from incident/production |\n| **Deviations** | `docs/internals/adr/deviations/` | Intentional divergence from ADR intent |\n\n## Common Commands\n\nAll Rust commands run from the `quickwit/` subdirectory.\n\n```bash\n# Build\ncd quickwit && cargo build\n\n# Run all tests (requires Docker services)\n# From repo root:\nmake docker-compose-up\nmake test-all\n# Or from quickwit/:\ncargo nextest run --all-features --retries 5\n\n# Run tests for a specific crate\ncargo nextest run -p quickwit-indexing --all-features\n\n# Run failpoint tests\ncargo nextest run --test failpoints --features fail/failpoints\n\n# Clippy (must pass before commit)\ncargo clippy --workspace --all-features --tests\n\n# Format (requires nightly)\ncargo +nightly fmt --all\n\n# Auto-fix clippy + format\nmake fix    # from quickwit/\n\n# Check license headers\nbash scripts/check_license_headers.sh\n\n# Check log format\nbash scripts/check_log_format.sh\n\n# Spellcheck (from repo root)\nmake typos  # or: typos\n\n# REST API integration tests (Python)\ncd quickwit/rest-api-tests\npipenv shell && pipenv install\n./run_tests.py --engine quickwit\n```\n\n## Testing Strategy\n\n### Unit Tests\n- Run fast, avoid IO when possible\n- Testing private functions is encouraged\n- Property-based tests (`proptest`) are welcome — narrow the search space\n- Not always deterministic — proptests are fine\n\n### Integration Tests\n- `quickwit-integration-tests/`: Rust integration tests exercising the full stack\n- `rest-api-tests/`: Python YAML-driven tests for Elasticsearch API compatibility\n\n### Required for CI\n- `cargo nextest run --all-features --retries 5` (with Docker services running)\n- Failpoint tests: `cargo nextest run --test failpoints --features fail/failpoints`\n- `RUST_MIN_STACK=67108864` is set for test runs (64MB stack)\n\n## Docker Services for Testing\n\n```bash\n# Start all services (localstack, postgres, kafka, jaeger, etc.)\nmake docker-compose-up\n\n# Start specific services\nmake docker-compose-up DOCKER_SERVICES='jaeger,localstack'\n\n# Tear down\nmake docker-compose-down\n```\n\nEnvironment variables set during test-all:\n- `AWS_ACCESS_KEY_ID=ignored`, `AWS_SECRET_ACCESS_KEY=ignored`\n- `QW_S3_ENDPOINT=http://localhost:4566` (localstack)\n- `QW_S3_FORCE_PATH_STYLE_ACCESS=1`\n- `QW_TEST_DATABASE_URL=postgres://quickwit-dev:quickwit-dev@localhost:5432/quickwit-metastore-dev`\n\n## Key Entry Points\n\n| Port | Protocol | Purpose |\n|------|----------|---------|\n| 7280 | HTTP | Quickwit REST API |\n| 7281 | gRPC | Quickwit gRPC services |\n| 4317 | gRPC | OTLP ingest |\n\n## Checklist Before Committing\n\n**MUST** (required for merge):\n- [ ] `cargo clippy --workspace --all-features --tests` passes with no warnings\n- [ ] `cargo +nightly fmt --all -- --check` passes (run `cargo +nightly fmt --all` to fix; applies to **all** changed `.rs` files including tests — CI checks every file, not just lib code)\n- [ ] `debug_assert!` for non-obvious invariants\n- [ ] No `unwrap()` in library code\n- [ ] No silent error ignoring (`let _ =`)\n- [ ] New files under 500 lines (split by responsibility if larger)\n- [ ] No unnecessary `.clone()` (OK in actor/async code for clarity)\n- [ ] Tests through production path (HTTP/gRPC)\n- [ ] License headers present (run `bash quickwit/scripts/check_license_headers.sh` — every `.rs`, `.proto`, and `.py` file needs the Apache 2.0 header)\n- [ ] Log format correct (run `bash quickwit/scripts/check_log_format.sh`)\n- [ ] `typos` passes (spellcheck)\n- [ ] `cargo machete` passes (no unused dependencies in Cargo.toml)\n- [ ] `cargo doc --no-deps` passes (each PR must compile independently, not just the final stack)\n- [ ] Tests pass: `cargo nextest run --all-features`\n\n**SHOULD** (expected unless justified):\n- [ ] Functions under 70 lines\n- [ ] Explanatory variables for complex expressions\n- [ ] Documentation explains \"why\"\n- [ ] Integration test for new API endpoints\n\n## Detailed Documentation\n\n| Topic | Location |\n|-------|----------|\n| Code style (Quickwit) | [CODE_STYLE.md](CODE_STYLE.md) |\n| Rust style patterns | [docs/internals/RUST_STYLE.md](docs/internals/RUST_STYLE.md) |\n| Verification & DST | [docs/internals/VERIFICATION.md](docs/internals/VERIFICATION.md) |\n| Verification philosophy | [docs/internals/VERIFICATION_STACK.md](docs/internals/VERIFICATION_STACK.md) |\n| Simulation workflow | [docs/internals/SIMULATION_FIRST_WORKFLOW.md](docs/internals/SIMULATION_FIRST_WORKFLOW.md) |\n| Benchmarking | [docs/internals/BENCHMARKING.md](docs/internals/BENCHMARKING.md) |\n| Contributing guide | [CONTRIBUTING.md](CONTRIBUTING.md) |\n| ADR index | [docs/internals/adr/README.md](docs/internals/adr/README.md) |\n| Architecture evolution | [docs/internals/adr/EVOLUTION.md](docs/internals/adr/EVOLUTION.md) |\n| Compaction architecture | [docs/internals/compaction-architecture.md](docs/internals/compaction-architecture.md) |\n| Tantivy + Parquet design | [docs/internals/tantivy-parquet-architecture.md](docs/internals/tantivy-parquet-architecture.md) |\n| Locality compaction | [docs/internals/locality-compaction/](docs/internals/locality-compaction/) |\n| Runtime config | [config/quickwit.yaml](config/quickwit.yaml) |\n\n## References\n\n- [Quickwit](https://github.com/quickwit-oss/quickwit)\n- [Tantivy search engine](https://github.com/quickwit-oss/tantivy)\n- [Apache DataFusion](https://datafusion.apache.org/)\n","category":"root","tokens":3352}]}