| name | pre-review |
| description | Self-review checklist to run BEFORE opening or updating a PR against Amber. Use it whenever you (or an AI assistant) are about to push a branch and open or refresh a pull request — it grades your own change against the Amber Review Rubric so CI is green and a maintainer's first pass finds nothing avoidable. Use when about to open a PR, update an existing PR, or check whether a change is ready to submit. |
Pre-review: grade your own PR before a maintainer does
You are about to open or update a PR against Amber. Run this procedure first. The
cheapest review note is the one you never trigger. The rubric below is the source
of truth — this skill is just the contributor lens on it.
- Severity framework, per-type bars, enhancement-vs-feature values: REVIEW_RUBRIC.md (canonical — do not duplicate it here).
- Intentional trade-offs you should NOT "fix": DESIGN_DECISIONS.md. Scan it before touching anything that looks like a bug — you may be undoing a settled decision.
Work the steps in order. Don't skip a checkbox because it "looks obvious" — that
is exactly where the 2026-06-15 wave failed.
1. Classify your PR type
Pick exactly one and write it in the PR description. The type sets your bar (rubric §3).
If it's an enhancement vs a new feature, decide which (rubric §4). A new feature
(new pipe, CLI command, config knob, template default) should usually start as an
issue/discussion for design buy-in before you build it — not a drive-by PR.
2. Make the description match the code
This is the single most common wave failure: the PR text describes intent, not the diff.
3. One concern, minimal diff
4. Meet your per-type bar (rubric §3)
State which bar you're submitting against, then clear it with evidence, not vibes.
Bugfix — a spec that's red before the fix, green after; fix the root cause, not the symptom; note what else calls this path.
Refactor — the existing suite passes unchanged. If you had to edit a spec's
assertions, it is not a pure refactor — reclassify it. No public-API/default changes ride along.
Performance — perf is the highest-risk "looks fine" category. You must prove it's
behavior-identical. Fill in a differential edge-case table in the PR description and
verify each row with a real spec — green happy-path specs tell you nothing about edges:
| Input | Old behavior | New behavior | Same? |
|---|
normal path /users/1 | route key users/1 | route key users/1 | yes |
dotfile /.well-known/x | … | … | must verify |
trailing slash /users/ | … | … | must verify |
| empty / extension-only segment | … | … | must verify |
(The wave's perf PR swapped an anchored regex for File.extname; dotfiles and trailing
slashes diverged and built a corrupted route key, but CI stayed green on happy-path specs.)
Include a before/after benchmark (method + hardware) justifying the change.
Security — clear all of these and write an honest severity self-assessment
using the three levers (rubric §2): (a) reachability — name the real
attacker-reachable sink AND state whether a caller rescue or top-level Pipe::Error
already mitigates it; (b) threat model — local dev CLI (operator is the attacker → Low)
vs network-facing; (c) environment gating — production path vs development?-only.
Don't over-state: the wave's "DoS" was already rescued at every reachable caller, and the
encrypt.cr command injection was a Low local-CLI issue.
Feature / default-change — tests for the new behavior and its edges; docs/changelog
updated. Default/behavior changes get extra scrutiny (rubric §4): they hit every app on
upgrade. App defaults belong in the CLI app template (e.g. config/routes.cr.ecr), not
bolted onto core; a new pipe must be plugged into a pipeline or it's inert dead code; and
"on by default" needs an explicit safety argument (the wave shipped HSTS-on-by-default — dangerous).
5. Add tests, including the edge cases assistants skip
6. Don't duplicate a recently-merged PR
7. Run the local checks so CI is green the first time
CI is CircleCI and runs lint + the full spec suite + the postgres-backed granite build spec
on every PR (rubric §7). Match it locally before you push.
Final gate