Capabilities
Code Quality & Architecture
Catch architecture drift, low-quality new code and performance regressions in every release, and let the gate decide what they do.
Code that passes tests can still erode your architecture and performance; these checks flag drift, low-quality AI code and slowdowns, for tech leads and architects.
Beta, early access. A workspace without access gets
403 FEATURE_EARLY_ACCESSand a link to request it.
Bumpkit compares the base and head of a release and reports three kinds of problems in the code the release adds:
| Analysis | Finding kind | Flag |
|---|---|---|
| Architecture drift: new dependency cycles, layer violations, coupling and complexity growth | architecture_drift |
architecture_drift |
| AI code quality: copied code, needless abstractions, dead code, oversized functions, comment noise | code_quality |
slop_tracker |
| Performance diff: queries in loops, blocking IO on request paths, unbounded work, benchmark regressions | performance |
performance_diff |
Each analysis runs only when its flag is on for your workspace. The analyses read all 15 languages Bumpkit supports; see Supported Languages. The request-path checks of the performance diff find HTTP handlers in Go, Python, TypeScript and JavaScript. Generated files, such as *_templ.go, *.pb.go, *.sql.go, *.min.js and *.d.ts, are skipped.
How it runs
The analysis runs on your machine or CI runner, inside the bumpkit CLI. It reads both versions from your local Git history and sends Bumpkit the findings and a summary of metrics.
| Command | What happens |
|---|---|
bumpkit quality |
Prints the report for a range of commits. Nothing is gated. |
bumpkit gate |
Sends the findings with the release. gate.quality in bumpkit.yml decides whether they hold it. |
bumpkit check |
Lists the findings with the rest of the check. |
The CLI asks GET /v1/features which analyses are on for your workspace. To run it in CI, install the CLI in the job and set BUMPKIT_API_KEY; see Install the CLI.
bumpkit quality
bumpkit quality --base v1.4.0Code quality of v1.4.0..HEAD
Modules 42 → 44, dependencies 118 → 125, cycles 0 → 1, instability 0.48 → 0.50
Mean complexity 3.10 → 3.24 (max 21 → 27) over 612 functions
New code: 840 lines, 6.2% duplicated, low-value code score 4.8 per 100 new lines
Claude: 610 lines, 9 findings, low-value code score 6.1
No agent signals: 230 lines, 2 findings, low-value code score 1.3
Architecture drift
MEDIUM New dependency cycle: services/billing → services/users → services/billing services/users/plan.go:14| Flag | Default | Description |
|---|---|---|
--base |
latest tag | Version or ref the change starts from. |
--head |
HEAD |
Commit being released. |
--policy |
bumpkit.yml at the base |
Policy file to read limits and layers from. |
--bench-base |
none | go test -bench output, or JSON, measured at the base. |
--bench-head |
none | go test -bench output, or JSON, measured at the head. |
--json |
off | Print the full report as JSON. |
The command exits with an error if all three analyses are off for your workspace.
Architecture drift
Beta, early access. A workspace without access gets
403 FEATURE_EARLY_ACCESSand a link to request it. Flag:architecture_drift.
Bumpkit builds the module dependency graph of each version. A module is a directory. Each finding points at the file and line of the new dependency.
| Checker | Reports | Severity |
|---|---|---|
cycles |
A new dependency cycle between modules, with each hop and the dependency that closed it. | medium |
layers |
A new dependency that breaks architecture.layers or architecture.forbidden. |
high |
layers |
Without declared layers: a new dependency that reverses the direction between two areas seen at the base. | medium |
coupling |
A module that picked up several new module dependencies, with its fan-out and instability before and after. | low |
complexity |
A changed function whose cyclomatic complexity rises above gate.quality.max_complexity. Medium at twice the limit. |
low or medium |
Declare layers
architecture is a top-level key in bumpkit.yml, next to gate. List layers from the top down. A layer may depend on layers listed after it, never on layers listed before it.
architecture:
layers:
- name: cmd
paths: [cmd]
- name: api
paths: [services/api, services/web]
- name: domain
paths: [services/orders, services/payments]
- services/db
forbidden:
- from: services/web
to: services/db| Key | Description |
|---|---|
layers[].name |
A unique name for the layer. |
layers[].paths |
Directory prefixes in the layer. A trailing /** is allowed. Defaults to the name. |
layers[] as a string |
Shorthand for a layer whose name is also its path. |
forbidden[].from, forbidden[].to |
A layer name or directory prefix. Any new dependency from from to to is reported. |
Paths are relative to the repository root. If you declare no layers, Bumpkit infers the intended direction from the base and reports dependencies that reverse it. See architecture in the bumpkit.yml reference.
AI code quality
Beta, early access. A workspace without access gets
403 FEATURE_EARLY_ACCESSand a link to request it. Flag:slop_tracker.
Bumpkit looks only at lines the release adds, outside tests.
| Checker | Reports |
|---|---|
duplication |
New lines that repeat existing code, names and literals aside. The minimum match is gate.quality.clone_tokens tokens. |
abstraction |
A new interface with a single implementation. |
wrappers |
A new function that only forwards its arguments to another. |
dead_code |
A new symbol nothing in the repository references, tests included. |
function_size |
A changed function longer than gate.quality.max_function_lines. |
comment_noise |
A file where much of the new code is comments. |
All code_quality findings are low severity.
Low-value code score
The low-value code score rates code_quality findings per 100 new lines of code, from 0 to 100. Bumpkit splits new lines, findings and the score by author: each coding agent it detected, and "No agent signals" for the rest. This lets you compare what agents add with what people add.
Performance diff
Beta, early access. A workspace without access gets
403 FEATURE_EARLY_ACCESSand a link to request it. Flag:performance_diff.
Bumpkit finds the code reached from HTTP handlers, up to gate.quality.hot_path_depth calls deep, and reviews new code on those paths.
| Checker | Reports | Severity |
|---|---|---|
n_plus_one |
A query inside a loop. High when the loop is on a request path. | medium or high |
blocking_io |
A blocking network, file or process call on a request path. | medium |
hot_path_complexity |
A function on a request path whose complexity grew. Medium above max_complexity. |
low or medium |
unbounded |
An allocation or loop sized by request input. | medium |
benchmarks |
A benchmark that got slower, compared between versions. | medium, or high at 4 times the threshold |
Request-path findings name the handler chain that reaches the code.
Compare benchmarks
Run your Go benchmarks at least 4 times on each version, then pass both outputs:
git checkout v1.4.0 && go test -bench . -count 10 ./... > old.txt
git checkout main && go test -bench . -count 10 ./... > new.txt
bumpkit quality --base v1.4.0 --bench-base old.txt --bench-head new.txtbumpkit gate takes the same --bench-base and --bench-head flags. Bumpkit compares each benchmark's runs between versions and reports a change when it's statistically clear and the median moved by at least gate.quality.bench_threshold percent. Improvements and benchmarks with too few runs are reported at info severity.
Instead of go test output, you can pass a JSON array:
[
{"name": "BenchmarkParse", "samples": [1210, 1198, 1225, 1203]},
{"name": "BenchmarkRender", "ns_per_op": 5400}
]Gate policy
Under gate.quality in bumpkit.yml, set what each finding kind does in the Release Gate:
gate:
quality:
architecture_drift: block
code_quality:
action: approve
severity: low
when: agent
performance: approve
max_function_lines: 80
max_complexity: 15Each rule is either an action, or an object with these keys:
| Key | Values | Default | Description |
|---|---|---|---|
action |
warn, approve, block |
warn |
warn only reports. approve needs an approval. block fails the gate. |
severity |
high, medium, low |
medium |
The lowest severity that triggers the action. |
when |
always, agent, agent_or_unknown |
always |
agent and agent_or_unknown apply to any release not confirmed as written by a person. A block fails only on a declared or verified agent change, and needs an approval otherwise. |
All code_quality findings are low severity, and so are coupling findings. With the default severity: medium, a code_quality rule never triggers. Set severity: low to act on them.
Limits:
| Key | Default | Range | Used by |
|---|---|---|---|
max_function_lines |
80 | 1 to 10000 | function_size |
max_complexity |
15 | 1 to 1000 | complexity, hot_path_complexity |
clone_tokens |
40 | 10 to 1000 | duplication |
hot_path_depth |
4 | 1 to 10 | performance checkers |
bench_threshold |
5 | 0 to 1000 (percent) | benchmarks |
Suppressed findings don't trigger a rule. When a rule triggers, the gate reason is named quality.<kind>: <action> and lists up to five findings. See quality in the bumpkit.yml reference.
Quality dashboard
Every bumpkit gate run sends a snapshot of the metrics with the release. The Quality tab on the dashboard's Insights page charts the last 30 releases of each repository:
- Low-value code score
- Duplicated new code (%)
- Mean cyclomatic complexity
- Dependency cycles
- Mean instability
API
bumpkit gate sends the findings and the snapshot in the POST /v1/gate request. Stored trends are at GET /v1/quality/history (bumpkit quality history). The gate request fields:
| Field | Description |
|---|---|
findings |
Findings with kind architecture_drift, code_quality or performance. Bumpkit keeps up to 50 per kind. |
quality |
The metrics snapshot: base and head commit SHAs, before and after module metrics, release totals for the new code, and authors. |
Findings for a kind whose flag is off are ignored. Agents use the quality and quality_history MCP tools. See the API Reference for the full gate request.