Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .gemini/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Gemini Code Assist configuration.
#
# Aggressive review posture: surface LOW-severity nits alongside the
# bigger stuff, because in this repo the AI dialog is supposed to
# catch things humans would miss. A maintainer or follow-up bot can
# always dismiss noise; a missed real issue is more expensive.

code_review:
comment_severity_threshold: LOW
max_review_comments: -1
pull_request_opened:
summary: true
code_review: true
include_drafts: true
help: false

# Persistent memory across PRs — improves context recognition over time.
memory_config:
disabled: false

# No path excludes — review everything. Add generated files here only
# if they pollute the review.
ignore_patterns: []
128 changes: 128 additions & 0 deletions .gemini/styleguide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# Gemini Code Assist — WaveHouse style guide

**Conduct a strict code review.** WaveHouse is preparing to go open source, and every merged change on `main` ends up in public history as a squash commit. Treat every diff as a release candidate.

Err on the side of flagging a concern. A false positive is cheap — the author replies with reasoning. A missed real issue is expensive.

## Source of truth

Architectural context, code conventions, and mandatory documentation-sync rules live in [`AGENTS.md`](../AGENTS.md) at the repo root. Read it before reviewing. This file supplements — it does not replace — those conventions.

## Classify every finding

Tag each comment exactly one of:

- **`[MUST]`** — blocks merge. Use for security flaws, data-loss risk, broken invariants, or direct violations of `AGENTS.md` rules.
- **`[SHOULD]`** — strongly recommended. The code is wrong or fragile, but the author can push back with justification.
- **`[MAY]`** — consider. Style, clarity, or future-proofing suggestions.

End every review with a one-line verdict: **`Ship it`** (no MUSTs, few/no SHOULDs), **`Iterate`** (MUSTs or multiple SHOULDs need addressing), or **`Block`** (CRITICAL/HIGH security finding, data-loss risk, or core invariant broken).

## Review priorities (in order)

### 1. Correctness — `[MUST]` territory for real bugs

- Goroutine leaks, data races, missing context propagation, channel leaks
- `sync.Once` / `sync.Map` misuse; HTTP handlers ignoring `r.Context()`
- Error wrapping: `fmt.Errorf("context: %w", err)` — never `%v` for errors that need to be `errors.Is`-checked
- Resource cleanup on every error path
- Schema validation before ClickHouse writes; policy evaluation before responding; dedup check before publish
- Broken invariants listed in `AGENTS.md` §"Key Design Decisions"

### 2. Security — `[MUST]` for anything in the OWASP Top 10

Walk every diff against:

- **SQL injection** in ClickHouse paths (`BindParams`, dynamic table names, user-supplied filters). The `safeIdentifierRe` regex exists for a reason; flag any SQL built without it.
- **Broken auth / authz**: JWT claim handling, role extraction (`auth.role_claim`), policy templating (`{{ jwt.path }}`), raw-SQL access without `raw_sql: true`.
- **Sensitive data exposure**: secrets in logs, full error messages to clients, credentials or JWT payload echoed into responses.
- **Security misconfiguration**: CORS allowlist bypass, TLS downgrade, default credentials, permissive-by-default flags.
- **Input validation gaps**: unvalidated JSON reaching ClickHouse, unbounded request sizes, missing rate limits.
- **Race conditions** in auth / policy / dedup paths (TOCTOU).
- **Hardcoded secrets or API keys** anywhere in the diff.
- **Unsafe deserialization**, SSRF, XXE, prototype-pollution (TS SDK).

Severity-tag every security finding `CRITICAL` / `HIGH` / `MEDIUM` / `LOW`.

### 3. Performance — `[SHOULD]` unless it's catastrophic

- Hot-path allocations in ingest / query / cache
- Unbatched DB work, unbounded goroutine spawns, locks held across I/O
- N+1 query patterns, missing caching where cost is demonstrable, singleflight misuse
- Deliberately flag over-optimization too — premature allocation pools, unneeded mutexes

### 4. Testing — `[MUST]` for critical paths

- New code on auth / ingest / policy / query / cache / dedup without tests
- Missing edge-case coverage (nil inputs, empty batches, cancelled contexts, invalid JWT)
- Mocks where an integration test would catch more (per `AGENTS.md` testing conventions)
- Tests that don't actually exercise the path they claim
- Coverage ≥70% is CI-enforced; flag drops below threshold as `[MUST]`

### 5. Documentation sync — `[MUST]` when missed

`AGENTS.md` §"Documentation & Consistency Sync (MANDATORY)" lists exactly which docs must update for which code changes. Diff the changed files against that table:

- Handler / router changes → `docs/api.md`, README if user-facing
- Config struct / env var → `docs/configuration.md`, `config.yaml`, compose files, `docs/deployment.md`
- Architecture / package changes → `docs/architecture.md`, `AGENTS.md`
- Notable changes → `CHANGELOG.md` under `[Unreleased]`
- Build / test process → `docs/development.md`, `Makefile`

Flag every missed sync.

### 6. Go idiom — `[SHOULD]` for quality

- `gofumpt` + `goimports` enforced by CI — don't re-flag style
- `log/slog` structured JSON logging, not `fmt.Println` / `log.Printf`
- Chi v5 router patterns
- Constructor injection, no global mutable state
- Interface-at-consumer

## Correct / Incorrect examples

**Go error wrapping:**

```go
// Incorrect — loses the wrapped error for errors.Is / errors.As
return fmt.Errorf("bind params: %v", err)

// Correct
return fmt.Errorf("bind params: %w", err)
```

**ClickHouse table identifier:**

```go
// Incorrect — injection-prone
query := fmt.Sprintf("INSERT INTO %s ...", tableName)

// Correct — validated against safeIdentifierRe first
if !safeIdentifierRe.MatchString(tableName) {
return fmt.Errorf("invalid table name: %q", tableName)
}
```

**Handler context:**

```go
// Incorrect — ignores client disconnect, leaks resources
rows, err := db.Query(sql)

// Correct — honors client cancellation
rows, err := db.QueryContext(r.Context(), sql)
```

## Do NOT comment on

- `gofumpt` / `goimports` / `.golangci.yml`-covered lints — CI catches them
- Missing comments on self-explanatory code — this project prefers named identifiers over commentary
- Diff restatement summaries — summarize insights, not the diff itself

## Dialog

PR authors and maintainers can reply to Gemini's comments by tagging `@gemini-code-assist` or using `/gemini review` / `/gemini summary` / `/gemini <question>` in issue or review comments. When agents are replying to rebuttals, they must address the original concern specifically — don't ignore or re-assert.

## Tone

Rigorous, skeptical, constructive. Staff-engineer energy. If the code is good, say so briefly; don't invent complaints. If it's broken, say exactly what's broken and point at the line.
48 changes: 48 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# CODEOWNERS for WaveHouse

#

# - Lines are matched in order; the LAST matching line wins

# - Listed owners are automatically requested for review on matching PRs

# - No catch-all is intentional: routine code changes pick reviewers manually

# to avoid auto-pinging everyone on every PR. Only governance and

# clearly-owned areas are routed here

#

# See: <https://docs.github.com/repositories/managing-your-repositorys-settings-and-security/customizing-your-repository/about-code-owners>

# Governance, licensing, and security policy — require admin review

/LICENSE @EricAndrechek @taitelee
/SECURITY.md @EricAndrechek @taitelee
/CODE_OF_CONDUCT.md @EricAndrechek @taitelee
/CONTRIBUTING.md @EricAndrechek @taitelee

# AI agent rules and tooling config — require admin review so review /

# triage / agent behavior doesn't change without sign-off

/AGENTS.md @EricAndrechek @taitelee
/CLAUDE.md @EricAndrechek @taitelee
/.gemini/ @EricAndrechek @taitelee

# CI/CD, dependency updates, and repo automation

/.github/CODEOWNERS @EricAndrechek @taitelee
/.github/workflows/ @EricAndrechek @taitelee
/.github/dependabot.yml @EricAndrechek @taitelee
/.github/ISSUE_TEMPLATE/ @EricAndrechek @taitelee
/.github/PULL_REQUEST_TEMPLATE.md @EricAndrechek @taitelee

# Release configuration

/.goreleaser.yaml @EricAndrechek @taitelee

# Docs site — John has been leading this area

/site/ @jfwoods
5 changes: 5 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Security vulnerability
url: https://github.com/Wave-RF/WaveHouse/security/policy
about: Do NOT open a public issue for security vulnerabilities. See SECURITY.md for the private reporting process.
36 changes: 16 additions & 20 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,25 @@
# Pull Request
## Summary

## Description
What changed and why. One or two paragraphs, or a short bulleted list for multi-part PRs.

Brief description of the changes.
## Test plan

## Type of Change

- [ ] Bug fix (non-breaking change that fixes an issue)
- [ ] New feature (non-breaking change that adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
- [ ] Documentation update

## Checklist

- [ ] My code follows the project's code style (`make lint` passes)
- [ ] I have added tests that prove my fix/feature works
- [ ] All existing tests pass (`make test`)
- [ ] All binaries compile (`make build`)
- [ ] I have updated the documentation accordingly
- [ ] I have updated the CHANGELOG.md (if applicable)
- [ ] ...

## Related Issues

Closes #

## Screenshots / Logs
<!--
Checklist for the author (not kept in the squash commit message):

- `make ci` passes locally
- Docs updated per AGENTS.md "Documentation & Consistency Sync" rules
- CHANGELOG.md [Unreleased] entry added
- Tests cover new / changed behavior (70 % minimum, 80 %+ preferred)

If applicable, add screenshots or log output to help explain the change.
The PR title is the squash commit subject — use Conventional Commits
(`feat:`, `fix:`, `docs:`, `refactor:`, `test:`, `chore:`, `ci:`,
`deps:`, `build:`, `perf:`, `revert:`, `style:`). The PR body below is
the squash commit message, so keep it tight.
-->
24 changes: 24 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,27 @@ updates:
day: monday
commit-message:
prefix: "ci"

# TypeScript SDK
- package-ecosystem: npm
directory: /clients/ts
schedule:
interval: weekly
day: monday
groups:
sdk-deps:
patterns: ["*"]
commit-message:
prefix: "deps(sdk)"

# E2E test harness (runs against the SDK)
- package-ecosystem: npm
directory: /tests/sdk
schedule:
interval: weekly
day: monday
groups:
e2e-deps:
patterns: ["*"]
commit-message:
prefix: "deps(tests)"
113 changes: 113 additions & 0 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# File-path-to-label map for actions/labeler. Keeps area/* labels on
# PRs in sync with what files they touch — no manual label picking.
# Rule of thumb: match the `internal/<pkg>/` → `area/<pkg>` convention
# established in AGENTS.md.

"area/api":
- changed-files:
- any-glob-to-any-file:
- "internal/api/**"
- "cmd/wavehouse-api/**"

"area/ingest":
- changed-files:
- any-glob-to-any-file:
- "internal/ingest/**"
- "cmd/wavehouse-worker/**"

"area/query":
- changed-files:
- any-glob-to-any-file:
- "internal/query/**"
- "internal/discovery/**"

"area/cache":
- changed-files:
- any-glob-to-any-file:
- "internal/cache/**"

"area/dedupe":
- changed-files:
- any-glob-to-any-file:
- "internal/dedupe/**"

"area/policy":
- changed-files:
- any-glob-to-any-file:
- "internal/policy/**"

"area/pipes":
- changed-files:
- any-glob-to-any-file:
- "internal/pipes/**"

"area/sdk":
- changed-files:
- any-glob-to-any-file:
- "clients/ts/**"
- "tests/sdk/**"

"area/docs":
- changed-files:
- any-glob-to-any-file:
- "docs/**"
- "site/**"
- "README.md"
- "CONTRIBUTING.md"
- "CHANGELOG.md"
- "AGENTS.md"
- "CLAUDE.md"
- "SECURITY.md"
- "CODE_OF_CONDUCT.md"

"area/infra":
- changed-files:
- any-glob-to-any-file:
- ".github/**"
- "Makefile"
- "Dockerfile*"
- ".goreleaser.yaml"
- "deployments/**"
- "tests/compose.yaml"
- ".golangci.yml"
- ".air.toml"
- ".markdownlint.json"
- "go.mod"
- "go.sum"

"area/observability":
- changed-files:
- any-glob-to-any-file:
- "internal/**/observability/**"
- "internal/**/metrics*.go"
- "internal/**/tracing*.go"

dependencies:
- changed-files:
- any-glob-to-any-file:
- "go.mod"
- "go.sum"
- "**/package.json"
- "**/pnpm-lock.yaml"
- "**/package-lock.json"

github_actions:
- changed-files:
- any-glob-to-any-file:
- ".github/workflows/**"
- ".github/actions/**"

go:
- changed-files:
- any-glob-to-any-file:
- "**/*.go"

documentation:
- changed-files:
- any-glob-to-any-file:
- "docs/**"
- "site/**"
- "README.md"
- "CONTRIBUTING.md"
- "SECURITY.md"
- "CODE_OF_CONDUCT.md"
Loading
Loading