Skip to content

feat(settings): hot-reload the settings directory at boot and runtime - #508

Merged
EricAndrechek merged 26 commits into
mainfrom
settings-reload
Sep 1, 2026
Merged

EricAndrechek merged 26 commits into
mainfrom
settings-reload

Conversation

@taitelee

@taitelee taitelee commented Aug 21, 2026 •

Copy link
Copy Markdown
Member

Summary

The server now consumes the settings directory that #500 only validated. settings.dir / WH_SETTINGS_DIR is required: boot validates and adopts it (missing or invalid refuses to start, same contract as policy.file_path), and a running instance re-validates and re-adopts on a directory watch (fsnotify with debounce; survives a delete-and-recreate), SIGHUP, or admin-gated POST /v1/ops/settings/reload, all through one serialized reload path. A rejected reload, a deleted file, or a vanished directory keeps the previous good snapshot.

  • Tenant tunables move out of boot config into config.json: the ClickHouse wiring (clickhouse.addr / http_port / http_scheme / database / username / query_timeout — chconn.Manager swaps the connection behind one driver.Conn on reload), the auth verifier wiring (auth.jwks_url / auth.role_claim — auth.Authenticator swaps a whole verifier atomically; auth.Middleware is gone), dedupe.enabled (the new dedupe.Managed opens or closes the Pebble store from an AfterAdopt hook) with dedupe.id_field / dedupe.require_id and per-table overrides (Per-table dedupe id_field (+ fix cross-table dedupe keyspace collision) #222), dlq.enabled with per-table overrides, query.default_max_rows / query.timestamp_bucket_seconds, schema.refresh_interval, stream.keepalive_interval / keepalive_buckets (Heartbeater.Reconfigure rebuilds the wheel in place) / gap_window_minutes, and cors.allowed_origins. The YAML/env keys for all of these are removed, and boot config is now strict: an undeclared key refuses to boot, naming it. What stays in boot config is only what can't change under a running process — resource sizing, listeners, observability exporters — and the secrets (clickhouse.password, auth.jwt_secret, auth.operator_key), never in a tracked JSON file.

  • Every config.json key is required and the binary carries no compiled defaults, so the adopted snapshot is what the files say. Defaults live in one checked-in seed (internal/settings/seed/, go:embedded): the new wavehouse bootstrap [dir] writes it (refusing a non-empty directory; resolves dir exactly as validate does — argument, else WH_SETTINGS_DIR), the compose stack bind-mounts a checked-in copy at deployments/compose/settings/ so the quickstart stays up -d, make dev seeds a gitignored ./settings, and the e2e fixture ships its own. The container images ship no settings directory: WH_SETTINGS_DIR=/app/settings is preset and the operator mounts one there — a missing mount refuses to boot rather than running on defaults nobody chose. The seed ships no policy (fail-closed, warned).

  • Consumers take functions instead of values (IngestHandler.DedupeSettings, the structured-query defaultMaxRows / bucketSecs getters, the ingest worker's dlqEnabled, the sweeper's gapWindow, corsMiddleware's origins getter, SchemaRegistry's database and refresh-interval sources) so a reload applies without a restart and internal/api stays testable without a directory.

  • roles.json, policies.json, and pipes.json are the runtime authority for access control and named pipes, read per request off the same adopted snapshot (policy.Source / pipes.Source; settings.Store.Policy() / Pipe() / Pipes()), so a reload applies to the next request. Every adoption runs the full validation (strict JSON, cross-file role references), so there is no stored copy that skips it. Files are the only write path — edited on the host standalone, written by the control plane in cloud — because without NATS KV there is no bundled node sync and a node-local write would let distributed nodes drift. Removed: PUT /v1/ops/policy, PUT/DELETE /v1/ops/pipes/{name}, the WAVEHOUSE_POLICY / WAVEHOUSE_PIPES KV buckets and KV watch, policy.file_path / WH_POLICY_FILE_PATH, pipes.dir / WH_PIPES_DIR and the .sql bootstrap, deployments/compose/dev-policy.yaml (the trial policy now ships in deployments/compose/settings/, which make dev also seeds), /app/pipes in the images, and the SDK wh.policy.set / wh.pipes.set / wh.pipes.delete (replaced by wh.settings.reload()). The reads stay: GET /v1/ops/policy, POST /v1/ops/policy/validate, GET /v1/ops/pipes[/{name}]. The operator key remains the break-glass for a locked-out deployment: it can inspect the adopted policy and trigger a reload after the files are fixed.

  • mq.max_bytes_gb is a config.json key too: a reload updates the ingest and DLQ stream limits in place (DiscardNew, so shrinking backpressures until the worker drains — nothing buffered is dropped).

Related Issues

Closes #229, #33, #461, #514, #460, #363. Advances #48 (reload wiring; reverses the #48-era runtime-settings direction), #214, and #222 (per-table id_field; the keyspace fix stays open there). Follow-up surfaced in review: #510 (distroless digest pin).

@taitelee
taitelee requested review from a team and EricAndrechek August 21, 2026 01:35
@github-actions github-actions Bot added documentation Improvements or additions to documentation dependencies Pull requests that update a dependency file go Pull requests that update go code area/api HTTP handlers, routing, middleware area/query Structured query AST, SQL builder area/docs Documentation, site/, README area/infra CI, build, deploy, Docker, release labels Aug 21, 2026
@coderabbitai

coderabbitai Bot commented Aug 21, 2026 •

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Important

Approval pending

CodeRabbit has no unresolved comments, but it has not reviewed the latest commit.

Use the checkbox below to review the latest commit. CodeRabbit will approve the changes if it finds no blocking issues.

  • 🔍 Trigger review
📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added required settings-directory initialization through wavehouse init-settings.
    • Added hot reload via file changes, SIGHUP, and the admin reload endpoint.
    • Added runtime configuration for CORS, query limits, schema refresh, and deduplication.
    • Added per-table deduplication overrides and safer deduplication lifecycle handling.
  • Bug Fixes

    • Invalid reloads now preserve the last valid settings snapshot.
    • Settings validation now reports missing or invalid required configuration.
  • Documentation

    • Updated setup, deployment, configuration, API, and settings-directory guidance.

Walkthrough

WaveHouse moves tenant tunables into a required JSON settings directory. The application validates and hot-reloads settings from file changes, SIGHUP, or an admin endpoint. Deduplication, query limits, schema refresh, and CORS now use live settings.

Changes

Settings directory runtime

Layer / File(s) Summary
Settings contract and reload store
internal/settings/*, go.mod
Required JSON blocks and fields are validated. Seed files initialize a directory. The store adopts valid snapshots atomically, retains prior settings after rejected reloads, exposes typed accessors, and watches filesystem changes.
Runtime consumers and API reload
internal/api/*, internal/discovery/discovery.go
CORS, query limits, and schema refresh read live settings. The admin reload endpoint reports adoption and validation findings.
Managed deduplication
internal/dedupe/*, internal/api/ingest.go
dedupe.Managed opens and closes Pebble storage as dedupe.enabled changes. Ingest resolves per-table settings and handles disabled or unavailable deduplication states.

Boot, commands, and deployment

Layer / File(s) Summary
Startup and initialization command
cmd/wavehouse/*, internal/config/*
Startup requires a valid settings directory. The init-settings command writes default files and returns distinct usage and operational exit codes. Boot configuration no longer contains tenant-owned settings.
Container and local configuration
config.yaml, deployments/*, Makefile
Container images and Compose provide /app/settings. Configuration comments describe initialization and reload behavior. Local template updates warn when existing files are stale.

Documentation and fixtures

Layer / File(s) Summary
Settings directory documentation
docs/src/content/docs/settings-directory.mdx, docs/src/config/sidebar.ts, docs/src/content/docs/index.mdx
The documentation describes required files, initialization, validation, reload triggers, configuration keys, ownership, CORS, and deduplication.
Configuration and deployment references
docs/src/content/docs/*, README.md, AGENTS.md, CHANGELOG.md
Documentation and project notes replace obsolete YAML and environment settings with settings-directory references.
End-to-end fixtures and coverage
tests/e2e/fixtures/*, .testcoverage.yml
End-to-end fixtures provide the required settings files and tenant configuration. Coverage exclusions document validation-only paths.

Estimated code review effort: 4 (Complex) | ~60 minutes

Merge Risk: 🟠 High · up to cb86a

This PR makes settings reloadable at boot and runtime, but the current head can still silently discard valid cross-table records, leave runtime settings stale after filesystem event overflow, and cause container boot failures when the documented settings path is followed; these correctness, availability, and deployment-readiness risks should be fixed or explicitly accepted before merge.

Sequence Diagram(s)

sequenceDiagram
  participant Operator
  participant WaveHouse
  participant SettingsStore
  participant DedupeManaged
  participant APIConsumers
  Operator->>WaveHouse: Edit settings, send SIGHUP, or call reload endpoint
  WaveHouse->>SettingsStore: TriggerReload(trigger)
  SettingsStore->>SettingsStore: Validate and adopt valid snapshot
  SettingsStore->>DedupeManaged: Apply dedupe.enabled
  SettingsStore-->>APIConsumers: Updated query, schema, and CORS accessors
  WaveHouse-->>Operator: Adoption status and findings
Loading

Suggested reviewers: ericandrechek

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 44.44% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 90 functions across 28 files. (4 skipped:… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly summarizes the primary change: hot-reloading the settings directory during startup and runtime.
Description check ✅ Passed The description is detailed and directly explains the required settings directory, reload triggers, runtime adoption, configuration migration, and related behavior.
Full details: Docstring Coverage

Explanation

Docstring coverage is 44.44% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 90 functions across 28 files. (4 skipped: 4 unsupported.)

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch settings-reload
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch settings-reload

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@taitelee taitelee moved this from Backlog to In progress in WaveHouse Task Board Aug 21, 2026
@github-actions

github-actions Bot commented Aug 21, 2026 •

Copy link
Copy Markdown

📚 Docs preview is live → https://07d15f53-wavehouse-docs.wave-rf.workers.dev

  • Commit — 86d708c: docs: review sweep — drop api.md's dead admin grant, correct the JWKS no-wait comment, fix split godoc comments, seed/checklist wording
  • Author — @taitelee
  • Committed — 2026-08-31 20:02 (UTC-04:00)
  • Deployed — 2026-08-31 20:13 EDT

@github-code-quality

github-code-quality Bot commented Aug 21, 2026 •

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: Go

Go

The overall line coverage in commit 86d708c in the settings-reload branch is 90%. The line coverage in commit 7b3c25e in the main branch is 91%.

Show a line coverage summary of the most impacted files.
File main 7b3c25e settings-reload 86d708c +/-
internal/auth/auth.go 99% 95% -4%
cmd/wavehouse/main.go 65% 66% +1%
internal/chconn/chconn.go 0% 69% +69%
internal/settings/seed.go 0% 69% +69%
internal/settings/watch.go 0% 71% +71%
internal/config/strict.go 0% 87% +87%
internal/api/settings.go 0% 88% +88%
internal/settings/store.go 0% 95% +95%
cmd/wavehouse/bootstrap.go 0% 97% +97%
internal/dedupe/managed.go 0% 100% +100%

Updated September 01, 2026 00:13 UTC

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: e472820d-ea24-4cec-91dd-ebe59cdf26b7

📥 Commits

Reviewing files that changed from the base of the PR and between 9ebd10c and 9ad2d00.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (50)
  • .goreleaser.yaml
  • .testcoverage.yml
  • AGENTS.md
  • CHANGELOG.md
  • cmd/wavehouse/init_settings.go
  • cmd/wavehouse/init_settings_test.go
  • cmd/wavehouse/main.go
  • cmd/wavehouse/validate_test.go
  • config.yaml
  • deployments/Dockerfile
  • deployments/Dockerfile.goreleaser
  • deployments/compose/standalone.yaml
  • docs/src/content/docs/api.md
  • docs/src/content/docs/configuration.mdx
  • docs/src/content/docs/deployment.md
  • docs/src/content/docs/development.md
  • docs/src/content/docs/getting-started.md
  • docs/src/content/docs/reverse-proxy.mdx
  • docs/src/content/docs/sdk/index.mdx
  • go.mod
  • internal/api/ingest.go
  • internal/api/ingest_test.go
  • internal/api/router.go
  • internal/api/router_test.go
  • internal/api/settings.go
  • internal/api/settings_test.go
  • internal/api/structured_query.go
  • internal/api/structured_query_test.go
  • internal/config/config.go
  • internal/config/config_test.go
  • internal/discovery/discovery.go
  • internal/settings/finding.go
  • internal/settings/seed.go
  • internal/settings/seed/config.json
  • internal/settings/seed/pipes.json
  • internal/settings/seed/policies.json
  • internal/settings/seed/roles.json
  • internal/settings/settings.go
  • internal/settings/store.go
  • internal/settings/store_test.go
  • internal/settings/validate.go
  • internal/settings/validate_test.go
  • internal/settings/watch.go
  • internal/settings/watch_test.go
  • tests/e2e/fixtures/config.yaml
  • tests/e2e/fixtures/settings/config.json
  • tests/e2e/fixtures/settings/pipes.json
  • tests/e2e/fixtures/settings/policies.json
  • tests/e2e/fixtures/settings/roles.json
  • tests/integration/query_limits_test.go

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.

📜 Review details
⏰ Context from checks skipped due to timeout. (2)
  • GitHub Check: E2E tests
  • GitHub Check: Coverage
🧰 Additional context used
📓 Path-based instructions (9)
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

**/*.go: - No global state: Dependencies are passed explicitly (constructor injection).

  • Go 1.26, strict formatting (gofumpt, enforced by CI)

Files:

  • tests/integration/query_limits_test.go
  • cmd/wavehouse/validate_test.go
  • internal/settings/finding.go
  • cmd/wavehouse/init_settings.go
  • internal/api/settings_test.go
  • internal/settings/watch_test.go
  • internal/api/structured_query_test.go
  • internal/settings/seed.go
  • internal/api/structured_query.go
  • cmd/wavehouse/init_settings_test.go
  • internal/api/ingest.go
  • internal/settings/watch.go
  • internal/api/settings.go
  • internal/settings/settings.go
  • internal/settings/validate.go
  • internal/discovery/discovery.go
  • internal/settings/validate_test.go
  • internal/api/router.go
  • internal/api/ingest_test.go
  • internal/settings/store_test.go
  • internal/config/config.go
  • internal/settings/store.go
  • internal/api/router_test.go
  • internal/config/config_test.go
  • cmd/wavehouse/main.go
tests/**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

  • Table-driven tests: Use tests := []struct{ name string; ... } with t.Run(tt.name, ...) for test cases.

Files:

  • tests/integration/query_limits_test.go
**/*_test.go

📄 CodeRabbit inference engine (AGENTS.md)

  • Every new function should have corresponding test cases. Run make lint and make test before considering work complete.

Files:

  • tests/integration/query_limits_test.go
  • cmd/wavehouse/validate_test.go
  • internal/api/settings_test.go
  • internal/settings/watch_test.go
  • internal/api/structured_query_test.go
  • cmd/wavehouse/init_settings_test.go
  • internal/settings/validate_test.go
  • internal/api/ingest_test.go
  • internal/settings/store_test.go
  • internal/api/router_test.go
  • internal/config/config_test.go
internal/**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

  • Package naming: Lowercase, single word (or abbreviated). internal/ enforces module privacy.

Files:

  • internal/settings/finding.go
  • internal/api/settings_test.go
  • internal/settings/watch_test.go
  • internal/api/structured_query_test.go
  • internal/settings/seed.go
  • internal/api/structured_query.go
  • internal/api/ingest.go
  • internal/settings/watch.go
  • internal/api/settings.go
  • internal/settings/settings.go
  • internal/settings/validate.go
  • internal/discovery/discovery.go
  • internal/settings/validate_test.go
  • internal/api/router.go
  • internal/api/ingest_test.go
  • internal/settings/store_test.go
  • internal/config/config.go
  • internal/settings/store.go
  • internal/api/router_test.go
  • internal/config/config_test.go
internal/api/**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

  1. Bearer-token-only CORS posture (security) — Bearer JWT on every request, no cookies/sessions; corsMiddleware deliberately never emits Access-Control-Allow-Credentials (not needed, and * + credentials is a spec violation browsers reject).

Files:

  • internal/api/settings_test.go
  • internal/api/structured_query_test.go
  • internal/api/structured_query.go
  • internal/api/ingest.go
  • internal/api/settings.go
  • internal/api/router.go
  • internal/api/ingest_test.go
  • internal/api/router_test.go
**/*.mdx

📄 CodeRabbit inference engine (AGENTS.md)

  • In MDX, leave a blank line between a JSX tag and a code fence.

Files:

  • docs/src/content/docs/sdk/index.mdx
  • docs/src/content/docs/reverse-proxy.mdx
  • docs/src/content/docs/configuration.mdx
docs/src/content/**/*.mdx

📄 CodeRabbit inference engine (AGENTS.md)

docs/src/content/**/*.mdx: - Opt a page into the Cloud CTA with cloudCta frontmatter, not by importing the component.

  • Never hand-write ® or ™ in prose.
  • Never hand-write utm_* params or rel on a link to wavehouse.cloud or wave-rf.com. Use cloudLink() / relFor() from docs/src/config/outbound.ts.

Files:

  • docs/src/content/docs/sdk/index.mdx
  • docs/src/content/docs/reverse-proxy.mdx
  • docs/src/content/docs/configuration.mdx
**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

  • Never hard-wrap prose. One paragraph is one line. No wrapping at 72/80 columns, no "semantic linefeeds" splitting a paragraph at sentence boundaries.

Files:

  • docs/src/content/docs/getting-started.md
  • docs/src/content/docs/development.md
  • AGENTS.md
  • docs/src/content/docs/api.md
  • CHANGELOG.md
  • docs/src/content/docs/deployment.md
**/*.{yml,yaml}

📄 CodeRabbit inference engine (AGENTS.md)

New workflows must follow the same pattern — never @main or floating tags on third-party actions.

Files:

  • deployments/compose/standalone.yaml
  • tests/e2e/fixtures/config.yaml
  • config.yaml
🧠 Learnings (2)
📚 Learning: 2026-06-26T12:23:22.696Z
Learnt from: EricAndrechek
Repo: Wave-RF/WaveHouse PR: 346
File: internal/stream/subscriber_test.go:9-28
Timestamp: 2026-06-26T12:23:22.696Z
Learning: In this Go repository, prefer table-driven tests (e.g., `[]struct{...}` with `t.Run(...)`) only for tests that cover multiple scenarios/inputs and can be cleanly enumerated. Do not artificially rewrite a clear single-scenario sequential behavioral-flow test into a table-driven form just to fit the pattern; if there’s only one meaningful scenario, keep the test as a straightforward linear flow (as in `TestSubscriber_SendDeliversThenDropsWhenFull`).

Applied to files:

  • internal/settings/validate_test.go
  • internal/settings/store_test.go
📚 Learning: 2026-08-13T12:17:52.620Z
Learnt from: EricAndrechek
Repo: Wave-RF/WaveHouse PR: 470
File: docs/src/content/docs/reverse-proxy.mdx:137-144
Timestamp: 2026-08-13T12:17:52.620Z
Learning: For Wave-RF/WaveHouse documentation, verify claims about implementation control flow against the authoritative implementation source (for example, internal/auth/auth.go) rather than relying solely on docs/** content. Documentation may lag behind or paraphrase behavior, so control-flow claims should be confirmed in source code.

Applied to files:

  • docs/src/content/docs/configuration.mdx
🪛 Checkov (3.3.10)
deployments/Dockerfile

[low] 42-42: Ensure the base image uses a non latest version tag

(CKV_DOCKER_7)

🪛 Hadolint (2.15.1)
deployments/Dockerfile

[warning] 42-42: Always tag the version of an image explicitly

(DL3006)


[info] 45-45: Non-numeric user-id may not be resolvable by host system

(DL3066)

🪛 LanguageTool
CHANGELOG.md

[style] ~13-~13: Consider an alternative for the overused word “exactly”.
Context: ...issing one), so the adopted snapshot is exactly what the files say, and once adopted it...

(EXACTLY_PRECISELY)


[style] ~13-~13: Since ownership is already implied, this phrasing may be redundant.
Context: ...et (bare docker run boots; bind-mount your own directory over it), and the dev `config...

(PRP_OWN)

docs/src/content/docs/configuration.mdx

[style] ~188-~188: Consider an alternative for the overused word “exactly”.
Context: ...hey live, and what the server adopts is exactly what the files say. The container image...

(EXACTLY_PRECISELY)


[style] ~188-~188: Since ownership is already implied, this phrasing may be redundant.
Context: ...o a bare docker run boots; bind-mount your own directory over that path to edit. Chec...

(PRP_OWN)


[style] ~204-~204: Consider using the typographical ellipsis character here instead.
Context: ...ttings/reload** (admin-only) — returns {"adopted": bool, "findings": [...]}; 200when adopted,422` when reje...

(ELLIPSIS)

🪛 Trivy (0.73.0)
deployments/Dockerfile

[warning] 42-42: ':latest' tag used

Specify a tag in the 'FROM' statement for image 'gcr.io/distroless/static-debian12'

Rule: DS-0001

Learn more

(IaC/Dockerfile)

🔇 Additional comments (41)
AGENTS.md (2)

61-62: LGTM!

Also applies to: 65-65


57-57: 🗄️ Data Integrity & Integration | 🏗️ Heavy lift

Make the Issue #222 table-isolation contract explicit and executable.

The changes mention per-table id_field selection but do not represent the required table-qualified deduplication keyspace in the invariant or the e2e settings fixture.

  • AGENTS.md#L57-L57: state that deduplication keys include table identity and that writes and lookups use the same namespace.
  • tests/e2e/fixtures/settings/config.json#L1-L16: add table overrides and test equal IDs in different tables, or link an existing test that proves both behaviors.
.testcoverage.yml (1)

75-86: LGTM!

config.yaml (1)

53-55: LGTM!

Also applies to: 85-99

tests/e2e/fixtures/config.yaml (1)

8-14: LGTM!

Also applies to: 31-36

tests/e2e/fixtures/settings/pipes.json (1)

1-1: LGTM!

tests/e2e/fixtures/settings/policies.json (1)

1-3: LGTM!

tests/e2e/fixtures/settings/roles.json (1)

1-3: LGTM!

docs/src/content/docs/api.md (1)

597-597: LGTM!

Also applies to: 799-813

docs/src/content/docs/configuration.mdx (1)

26-27: LGTM!

Also applies to: 42-43, 70-70, 116-116, 131-137, 188-236, 303-304, 328-331, 392-392

docs/src/content/docs/deployment.md (1)

62-62: LGTM!

Also applies to: 157-171, 369-369

docs/src/content/docs/development.md (1)

147-147: LGTM!

Also applies to: 231-238

docs/src/content/docs/getting-started.md (1)

98-98: LGTM!

Also applies to: 116-116

docs/src/content/docs/reverse-proxy.mdx (1)

25-25: LGTM!

Also applies to: 199-199

docs/src/content/docs/sdk/index.mdx (1)

404-404: LGTM!

go.mod (1)

23-23: LGTM!

internal/settings/finding.go (1)

18-24: LGTM!

internal/settings/store_test.go (1)

13-157: LGTM!

cmd/wavehouse/validate_test.go (1)

22-22: LGTM!

.goreleaser.yaml (1)

85-88: LGTM!

internal/api/settings.go (1)

11-51: LGTM!

internal/api/structured_query.go (1)

30-35: LGTM!

Also applies to: 52-52, 122-126

internal/settings/seed.go (1)

1-61: LGTM!

internal/settings/seed/config.json (1)

1-16: LGTM!

internal/settings/seed/pipes.json (1)

1-4: LGTM!

internal/settings/seed/policies.json (1)

1-2: LGTM!

internal/settings/seed/roles.json (1)

1-4: LGTM!

internal/settings/validate_test.go (1)

4-4: LGTM!

Also applies to: 30-64, 96-96, 264-271, 335-335, 358-368, 378-378

tests/integration/query_limits_test.go (1)

102-102: LGTM!

internal/settings/settings.go (1)

63-84: LGTM!

Also applies to: 98-118

internal/settings/validate.go (1)

286-309: LGTM!

Also applies to: 338-362

internal/settings/store.go (1)

10-131: LGTM!

internal/config/config.go (1)

13-32: LGTM!

Also applies to: 45-52, 108-112, 142-147, 222-224

internal/config/config_test.go (1)

14-34: LGTM!

Also applies to: 101-107, 189-190, 203-216, 227-228, 239-241, 263-264, 282-283, 302-303, 319-320, 344-345, 372-373, 391-392, 427-428, 445-446, 458-459, 472-473, 487-488

cmd/wavehouse/init_settings.go (1)

14-50: LGTM!

cmd/wavehouse/main.go (1)

31-31: LGTM!

Also applies to: 102-116, 136-137, 177-188, 295-331, 473-473, 531-537

cmd/wavehouse/init_settings_test.go (1)

12-42: LGTM!

internal/api/ingest.go (1)

39-45: LGTM!

internal/api/router.go (1)

20-43: LGTM!

Also applies to: 196-198, 299-341

internal/api/structured_query_test.go (1)

32-43: LGTM!

Also applies to: 285-298

internal/discovery/discovery.go (1)

49-59: LGTM!

Also applies to: 217-255

Comment thread CHANGELOG.md Outdated
Comment thread deployments/compose/standalone.yaml Outdated
Comment thread deployments/Dockerfile
Comment thread internal/api/ingest_test.go Outdated
Comment thread internal/api/ingest.go Outdated
Comment thread internal/api/router_test.go
Comment thread internal/settings/validate.go
Comment thread internal/settings/watch.go

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
internal/settings/watch.go (1)

80-86: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Reconcile settings after a watcher queue overflow.

fsnotify.ErrEventOverflow indicates that filesystem notifications were lost. When this error occurs, reset the debounce timer so its normal path calls s.TriggerReload("watch"). That reload reparses the complete settings directory.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: b2f6f5c1-0bde-4b64-8caa-cd85c395c4cc

📥 Commits

Reviewing files that changed from the base of the PR and between 9ad2d00 and 5646dab.

📒 Files selected for processing (6)
  • CHANGELOG.md
  • deployments/compose/standalone.yaml
  • docs/src/content/docs/configuration.mdx
  • internal/api/router_test.go
  • internal/settings/watch.go
  • internal/settings/watch_test.go

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.

📜 Review details
⏰ Context from checks skipped due to timeout. (10)
  • GitHub Check: E2E tests
  • GitHub Check: Integration tests
  • GitHub Check: Docs build
  • GitHub Check: Unit tests
  • GitHub Check: Coverage
  • GitHub Check: Validate snapshot build
  • GitHub Check: Lint
  • GitHub Check: Analyze (go)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Analyze (go)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

**/*.go: - Go 1.26, strict formatting (gofumpt, enforced by CI)

  • No global state: Dependencies are passed explicitly (constructor injection).
  • Structured logging with log/slog (JSON handler)

Files:

  • internal/settings/watch.go
  • internal/api/router_test.go
  • internal/settings/watch_test.go
internal/*/**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

  • Package naming: Lowercase, single word (or abbreviated). internal/ enforces module privacy.

Files:

  • internal/settings/watch.go
  • internal/api/router_test.go
  • internal/settings/watch_test.go
**/*_test.go

📄 CodeRabbit inference engine (AGENTS.md)

**/*_test.go: - Table-driven tests: Use tests := []struct{ name string; ... } with t.Run(tt.name, ...) for test cases.

  • Every new function should have corresponding test cases. Run make lint and make test before considering work complete.

Files:

  • internal/api/router_test.go
  • internal/settings/watch_test.go
docs/src/content/docs/**/*.mdx

📄 CodeRabbit inference engine (AGENTS.md)

docs/src/content/docs/**/*.mdx: - Opt a page into the Cloud CTA with cloudCta frontmatter, not by importing the component.

  • Never hand-write ® or ™ in prose.
  • Never hand-write utm_* params or rel on a link to wavehouse.cloud or wave-rf.com. Use cloudLink() / relFor() from docs/src/config/outbound.ts.

Files:

  • docs/src/content/docs/configuration.mdx
**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

Every code change should update the corresponding docs in the same PR. A code change without its doc update is incomplete.

Files:

  • CHANGELOG.md
🧠 Learnings (2)
📚 Learning: 2026-08-13T12:17:52.620Z
Learnt from: EricAndrechek
Repo: Wave-RF/WaveHouse PR: 470
File: docs/src/content/docs/reverse-proxy.mdx:137-144
Timestamp: 2026-08-13T12:17:52.620Z
Learning: For Wave-RF/WaveHouse documentation, verify claims about implementation control flow against the authoritative implementation source (for example, internal/auth/auth.go) rather than relying solely on docs/** content. Documentation may lag behind or paraphrase behavior, so control-flow claims should be confirmed in source code.

Applied to files:

  • docs/src/content/docs/configuration.mdx
📚 Learning: 2026-06-26T12:23:22.696Z
Learnt from: EricAndrechek
Repo: Wave-RF/WaveHouse PR: 346
File: internal/stream/subscriber_test.go:9-28
Timestamp: 2026-06-26T12:23:22.696Z
Learning: In this Go repository, prefer table-driven tests (e.g., `[]struct{...}` with `t.Run(...)`) only for tests that cover multiple scenarios/inputs and can be cleanly enumerated. Do not artificially rewrite a clear single-scenario sequential behavioral-flow test into a table-driven form just to fit the pattern; if there’s only one meaningful scenario, keep the test as a straightforward linear flow (as in `TestSubscriber_SendDeliversThenDropsWhenFull`).

Applied to files:

  • internal/settings/watch_test.go
🪛 LanguageTool
CHANGELOG.md

[style] ~13-~13: Since ownership is already implied, this phrasing may be redundant.
Context: ...et (bare docker run boots; bind-mount your own directory over it), and the dev `config...

(PRP_OWN)

🔇 Additional comments (6)
internal/api/router_test.go (1)

8-8: LGTM!

Also applies to: 160-160, 180-180, 198-198, 217-217, 256-256, 273-273, 291-291, 406-406

CHANGELOG.md (1)

13-13: LGTM!

docs/src/content/docs/configuration.mdx (1)

26-27: LGTM!

Also applies to: 42-43, 70-70, 116-116, 131-137, 188-236, 283-283, 298-304, 315-315, 328-331, 360-360, 373-376, 386-392

deployments/compose/standalone.yaml (1)

42-58: LGTM!

internal/settings/watch.go (1)

6-6: LGTM!

Also applies to: 17-17, 26-79

internal/settings/watch_test.go (1)

56-67: LGTM!

Also applies to: 70-92

Comment thread internal/api/router_test.go
Comment thread internal/settings/watch_test.go Outdated
@taitelee

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 23, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 690b4cec-07ea-43f0-86b2-faf02d9b7696

📥 Commits

Reviewing files that changed from the base of the PR and between 5646dab and 98fb9c1.

📒 Files selected for processing (1)
  • internal/settings/watch_test.go

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.

📜 Review details
🧰 Additional context used
📓 Path-based instructions (2)
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

Return errors, don't panic. Wrap with fmt.Errorf("context: %w", err).

Files:

  • internal/settings/watch_test.go
**/*_test.go

📄 CodeRabbit inference engine (AGENTS.md)

Every new function should have corresponding test cases.

Files:

  • internal/settings/watch_test.go
🔇 Additional comments (3)
internal/settings/watch_test.go (3)

5-5: LGTM!

Also applies to: 18-28, 32-34


36-43: LGTM!

Also applies to: 54-64


76-100: LGTM!

Comment thread internal/settings/watch_test.go Outdated
@taitelee

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 23, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

coderabbitai[bot]
coderabbitai Bot previously approved these changes Aug 23, 2026
…e settings/config.json) in the fresh-clone paths
…eric DateTime64 parsing); docs: seed the settings directory before running the bare binary
@github-actions github-actions Bot added the github_actions Pull requests that update GitHub Actions code label Aug 31, 2026
EricAndrechek
EricAndrechek previously approved these changes Aug 31, 2026

@EricAndrechek EricAndrechek left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok three small missing doc things, 2 in git diff and one not so I put it here:

  • deployments/compose/standalone.yaml:3 is still clickhouse/clickhouse-server:latest, but you pinned 26.6.3.62 in the two ci.yml prefetches, dependencies.yaml, scripts/orchestrator/main.go and tests/integration/setup_test.go.

Going to approve though so that you can fix them and just merge and be done without another PR review

Comment thread docs/src/content/docs/configuration.mdx Outdated
Comment thread docs/src/content/docs/development.md
EricAndrechek
EricAndrechek previously approved these changes Aug 31, 2026
@taitelee

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 31, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Review skipped: 120 files exceed the limit of 100.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

… no-wait comment, fix split godoc comments, seed/checklist wording
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/api HTTP handlers, routing, middleware area/dedupe Deduplication (Pebble, ScyllaDB) area/docs Documentation, site/, README area/infra CI, build, deploy, Docker, release area/ingest Ingest pipeline (Bento, batching, DLQ) area/pipes Named query pipes area/policy Access control policies (Hasura-style) area/query Structured query AST, SQL builder area/sdk TypeScript SDK (clients/ts/) dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation github_actions Pull requests that update GitHub Actions code go Pull requests that update go code

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

Policy/pipes bootstrap file is a seed, not a synced source of truth (document + optional reconcile-on-boot)

2 participants