Code style
OpenPerf rules for code and tests, on top of the shared rules in AGENTS.md.
Code
- Write code for cases that occur. No fallbacks, duplicate checks or values without a consumer.
- Make each decision in one place: the layer that owns it. Others rely on it.
- An arrow function whose body doesn’t fit on one line gets a block with
return. Components returning JSX are the exception. - Document what a published package exports from its entry points, such as
@openperf/sdk/node, only where the name and type don’t tell the whole story: defaults, limits, value formats, errors and when it does nothing. Skip a JSDoc that restates the name. Write one or two plain sentences, state each fact once where it applies, put defaults in@defaultand errors in@throws. Types, interfaces and classes get no JSDoc; document their properties instead. Internal code stays without comments.
Tests
- Test logic that can break on its own: branching, parsing, edge cases, security checks. Don’t test code that only restates itself, such as templates, lookup tables or config.
- A test that needs live stores is
*.integration.test.ts. Everything else is*.test.tswith mocks.
ClickHouse migrations
- One statement per file, and every statement can run twice (
IF NOT EXISTS, no unguarded backfills): dbmate may run a file again after a partial failure. - Retention is a
TTLin the table DDL; change it withALTER TABLE … MODIFY TTLin a new migration.
ClickHouse reads
- Lists, summaries and charts read hourly rollups through
buildRollupSource: full hours come from the rollup, the edges of the window from the raw table. Raw tables answer drill-downs by a selective key: a trace, a fingerprint, a log page, the hours a rollup picked for samples. - Each rollup in
telemetry/libs/rollupsmirrors its materialized view.rollups.integration.test.tsfails when the two drift. - Keep aggregate states bounded:
quantilesTDigestfor durations,uniqCombined(12)for unique counts. - Measure a read change with
bun run bench --project <id> --from <iso> --to <iso>on a dense dataset. It reports time, rows, bytes and peak memory per scenario with caches off.