Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 8 additions & 1 deletion .agents/skills/mz-commit/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,16 @@ Materialize uses squash merging, so the PR title becomes the commit subject on `

Write a thorough PR description explaining the rationale for the change.
Mention which tests were added or modified in the pull request description, but do not list which tests were run.
To auto-close issues, include `Fixes database-issues#NNNN`.
Add release notes for user-visible changes (should complete "This release will...").

## Issue tracking: Linear only for new issues

New issues are filed in Linear, never in the `database-issues` GitHub repo. `database-issues` is legacy. Its open issues are still valid to read, link, and close, so an existing `database-issues#NNNN` reference in code or a comment stays as it is.

Reference the Linear issue by its its key, e.g. `Closes: SQL-450`. Don't include the full URL containing the issue title.

When a change closes a legacy GitHub issue, `Fixes database-issues#NNNN` works for auto-closing.

## Cargo.lock discipline

Never regenerate the entire Cargo.lock — bare `cargo update` bumps every semver-compatible dep and introduces unrelated breakage (e.g., `os_info` pulling in `objc2` on macOS, `chrono-tz` changing timezone data, `serde_path_to_error` changing error formats).
Expand Down
12 changes: 7 additions & 5 deletions .agents/skills/mz-debug-ci/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,11 @@ Extract from the URL:
**Before diving into logs**, fetch the build annotations. They contain pre-extracted error messages, stack traces, and links to known flaky test issues — this saves significant time compared to grepping through raw logs.

```bash
bk api /pipelines/<PIPELINE>/builds/<BUILD_NUMBER>/annotations --no-pager 2>&1
bk api /pipelines/<PIPELINE>/builds/<BUILD_NUMBER>/annotations --no-pager 2>/dev/null
```

Note that `bk` can't be piped through `2>&1`.

The response is JSON. Each annotation has:
- `style`: `"error"` for failures
- `body_html`: HTML containing the error summary, including:
Expand All @@ -97,12 +99,12 @@ Only fetch full logs when annotations don't provide enough detail. Triage in thi

To fetch a job's log:
```bash
bk job log <JOB_ID> -p <PIPELINE> -b <BUILD_NUMBER> --no-timestamps --no-pager 2>&1 | tail -100
bk job log <JOB_ID> -p <PIPELINE> -b <BUILD_NUMBER> --no-timestamps --no-pager 2>/dev/null | tail -100
```

For large logs, first grep for errors to find the relevant section:
```bash
bk job log <JOB_ID> -p <PIPELINE> -b <BUILD_NUMBER> --no-timestamps --no-pager 2>&1 | grep -B2 -A5 'error\|FAIL\|panicked'
bk job log <JOB_ID> -p <PIPELINE> -b <BUILD_NUMBER> --no-timestamps --no-pager 2>/dev/null | grep -B2 -A5 'error\|FAIL\|panicked'
```

Fetch multiple job logs in parallel when they are independent (e.g., clippy + lint at the same time).
Expand All @@ -114,9 +116,9 @@ Jobs upload artifacts (junit XML, service logs, coredumps, ...). Use the

```bash
# All artifacts of a build (each entry has id, job_id, path)
bk artifacts list <BUILD_NUMBER> -p <PIPELINE> --no-pager 2>&1
bk artifacts list <BUILD_NUMBER> -p <PIPELINE> --no-pager 2>/dev/null
# Artifacts of a single job
bk artifacts list <BUILD_NUMBER> -p <PIPELINE> --job-uuid <JOB_ID> --no-pager 2>&1
bk artifacts list <BUILD_NUMBER> -p <PIPELINE> --job-uuid <JOB_ID> --no-pager 2>/dev/null
# Download one artifact into the current directory
bk artifacts download <ARTIFACT_ID> --build <BUILD_NUMBER> -p <PIPELINE>
```
Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/mz-platform-checks/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ Both manipulate phases always run. validate() may run multiple times.
```python
from materialize.checks.checks import disabled

@disabled(ignore_reason="due to database-issues#12345")
@disabled(ignore_reason="due to SQL-450")
class MyBrokenCheck(Check):
...
```
Expand Down
17 changes: 14 additions & 3 deletions .agents/skills/mz-test/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ Add logging through `log_filter` in the test's `mzcompose.py`:
```python
Materialized(
additional_system_parameter_defaults={
# TODO: Remove when database-issues#NNNN is fixed
# TODO: Remove when SQL-NNN is fixed
"log_filter": "mz_storage::source::postgres=trace"
},
)
Expand All @@ -223,7 +223,6 @@ Determine the right framework based on what you're testing:
* **SQL correctness, types, functions** (no external systems, no concurrency): sqllogictest (`.slt` in `test/sqllogictest/`).
Use `mode cockroach`, test NULLs and edge cases.
Do NOT modify files in `test/sqllogictest/sqlite` or `test/sqllogictest/cockroach` (upstream).
When adding new tests to slt files, prefer adding them to an existing slt file rather than creating new slt files, if you are able to quickly find an existing slt file where the new tests fit naturally.
Do NOT drive data-dependent assertions with a `LOAD GENERATOR COUNTER` source plus `mz_unsafe.mz_sleep(...)` to wait for ingestion: the counter emits rows over wall-clock time, so the check races ingestion and flakes in CI. Use a plain `CREATE TABLE` with deterministic `INSERT`s.
When a statically-monotonic operator needs a `FROM SOURCE` load generator (whose row timing is nondeterministic), split coverage: test the plan shape with `EXPLAIN PHYSICAL PLAN` over the `FROM SOURCE` table (no data, non-flaky), and test runtime row correctness with a one-shot `SELECT` over a plain `CREATE TABLE` + `INSERT`.
* **Sources/sinks, Kafka, catalog, pgwire** (external systems): testdrive (`.td` in `test/testdrive/`).
Expand All @@ -240,7 +239,19 @@ Determine the right framework based on what you're testing:
* **Performance micro-benchmarks**: Feature Benchmark scenarios in `misc/python/materialize/feature_benchmark/scenarios`.
See `doc/developer/feature-benchmark.md`.

In most cases, appending to an existing `.slt` or `.td` file is sufficient.
For functional issues, aim for at least two different test frameworks that can independently detect the regression.

Read `doc/developer/guide-testing.md` for more detail on test frameworks.

### Extend an existing file, do not create a new one

It is preferred to extend an existing mzcompose-based test, a `.td` file or `.slt` file when appropriate. Write the smallest test that fails without the fix.

A panic is caught by CI automatically. Just run the statement that panics. Do not add an assertion on the panic message.

## Prove a regression test is red before you call it done

A regression test that has never failed proves nothing. Whenever the test is meant to demonstrate a bug, verify both directions before reporting:

1. With the fix removed run the test and confirm it fails, for the expected reason. Read the failure output.
2. Restore the fix, run the test again, and confirm it passes.
6 changes: 6 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ Use the `mz-test` skill before running ANY tests, even mid-task — the canonica
commands aren't the obvious ones (e.g. `bin/sqllogictest --optimized`, not
`cargo build --bin sqllogictest`).

Use the `mz-run` skill before building, running, formatting, or linting. `bin/fmt` and `bin/lint` are the canonical entry points, NOT `cargo fmt`, `rustfmt`, or a bare `cargo clippy`. `bin/environmentd`, not `cargo build --bin environmentd`.

Use the `mz-commit` skill before `git commit`, `git push`, or `gh pr create`.

Use the `mz-debug-ci` skill before the first `bk` or `gh pr checks` command, or when handed a Buildkite URL.

## Code navigation

For operation flow tracing, read first:
Expand Down
Loading