Appearance
Code Review Checklist
The bar for shipping a PR. Every reviewer reads through this list. The intent isn't bureaucratic friction — it's that the workspace touches money, encrypted compute, and 15 cross-linked repos, and a missed concern in one PR can create cascading bugs across surfaces.
Sections are ordered by blast radius: protocol > SDK > apps > docs.
Universal (every PR)
- [ ] Scope is the diff. No unrelated refactors hiding in the same PR.
- [ ] Commit message describes why, not just what. No Claude / AI co-author lines (project policy).
- [ ] Tests at the appropriate tier exist and pass. See Testing Strategy →.
- [ ] No secrets in the diff. Search the diff for
password,secret,key,token,Bearer, raw private keys,.envcontents. - [ ] No
dotenv. Bun auto-loads.env. - [ ] No
console.login production paths. Use the structured logger. - [ ] No emojis in code, comments, or commit messages (workspace convention).
- [ ] Wiki updated if this PR changes any of: program IDs, SDK public API, repo stack, deployment target, or operational procedure.
- [ ] Wiki maintenance triggers at Wiki Maintenance → reviewed.
Protocol PRs (vela-protocol)
Highest bar. Mistakes here either let merchants steal or break legitimate billing.
- [ ] Account validation is explicit on every account in every instruction. No relying on default
Account<'info, T>without thinking through the constraint set. - [ ] Signer constraints are correct (
Signer<'info>,mut, ownership checks). - [ ] PDA seeds are derived through
PDAFactory(TS) and the matchingseeds = […]macro (Rust). Seeds match across program + SDK exactly. - [ ] Math uses
checked_*for any arithmetic that touches user funds, periods, or accrual.u128intermediates nearu64::MAXboundaries. - [ ] Settle-then-mutate invariant is preserved for any stream-state change (no path mutates
StreamMandatewithout first calling the settle helper). - [ ] Transfer hook minimality. No new business logic added to
vela-transfer-hook. New constraints go invela-protocol's pre-pull validation, not the hook. - [ ] Errors are typed. New failure paths return a typed
VelaErrorvariant. Re-using a generic error masks operator triage. - [ ] LiteSVM unit test for every new instruction path — happy path + at least one fail-closed path.
- [ ] TS integration test for SDK consumers of the new instruction.
- [ ] IDL diff reviewed. Does the IDL change require a bumped SDK version? If so, bump.
- [ ] Account version bump if the account layout changed. Migration path documented.
- [ ] Threat model review. What new attack surface does this introduce? Who's been added to the allow-list of authorities?
SDK PRs (vela-sdk)
Touches every consumer (vela-dashboard, vela-checkout, vela-portal, vela-widget, vela-webhook, vela-mail, vela-synthetic).
- [ ] Public API changes are additive when possible. Removals or renames require a major version bump.
- [ ] Subpath exports updated (
@velapay/sdk/{browser,errors,events,…}) if a new module category was added. - [ ] Browser barrel safety. New code that lands in
@velapay/sdk/browserdoes not import Node-only deps (fs,node:crypto). - [ ] Instruction byte stability test added for any new instruction builder.
- [ ] Error class added if a new typed error was introduced.
- [ ] Zod event schema updated if a new event type was added. CI schema-diff gate must pass (additive only).
- [ ] PDAFactory is the single source of derivation — no new in-line
findProgramAddressSynccalls. - [ ] Anchor IDL pin matches the deployed program (
@coral-xyz/anchor0.32.1 exact). - [ ] CLI (
bin/vela) updated if the new functionality is operator-relevant.
App PRs (dashboard, portal, checkout, admin, widget)
- [ ] Brand tokens used; no hardcoded colors, font names, easings. Import from
@vela/brand. - [ ] Auth-gated routes verified (Better Auth session, SIWS for admin).
- [ ] D1 batch atomicity for any multi-row write that must commit or rollback as a unit.
- [ ] Drizzle migration generated and committed if the schema changed.
- [ ] TanStack Router type-safety preserved (no
as anyon params). - [ ] Playwright E2E for new user-facing flows.
- [ ] Accessibility: keyboard nav works, focus rings visible, no color-only signal.
- [ ] Webhook handlers verify signature via
@velapay/webhookbefore trusting payload. - [ ] Service binding boundary respected (admin → dashboard worker → D1, never admin → D1 directly).
Support Repos
vela-brand
- [ ] CSS layer ordering preserved —
base.cssrules stay inside@layer base. - [ ] Light + dark resolved via
theme.css, not via component-level branching. - [ ] Token names are semantic (
--color-text-primary), not literal (--color-blue-500). - [ ] Consumer matrix in vela-brand → updated if a new export was added.
vela-webhook
- [ ] Schema additive-only (CI gate enforces this).
- [ ] Test fixtures regenerated for any signature-format change.
- [ ] Stripe wire-format compatibility preserved.
vela-mail
- [ ] Template rendering tested at unit tier.
- [ ]
vela-mail-smokeexercises the new template before deploy. - [ ] Allowed-sender bindings updated in consumer Workers if a new sender domain is required.
- [ ] Copy reviewed (touch
COPY-REVIEW.md).
vela-synthetic
- [ ] New funnel step paged on failure with the typed error class name.
- [ ] D1 binding still points at the dashboard's database (or operator-overridden equivalent).
Docs PRs (vela-docs)
- [ ] No leakage of internal-only operational details (
vela-docsis public). - [ ] Mermaid diagrams render in Starlight preview.
- [ ] Code samples actually run (use the demo's reference patterns).
- [ ] Cross-linked from the right Starlight section.
Internal Wiki PRs (internal-wiki)
- [ ] Frontmatter / sidebar entry added if a new top-level page was created.
- [ ] No factual claims that contradict the codebase. Spot-check version numbers, paths, IDs.
- [ ] No raw secrets, even old ones.
- [ ] Cross-references resolve (no 404s in
bun run build).
Reviewer Discipline
- Block on protocol, SDK, or auth issues. No "I'll trust the tests."
- Suggest on style, naming, micro-refactors. The author decides.
- Approve only when every box that applies is checked. If you're not the right reviewer for a section (e.g., you don't know the protocol well), pull in someone who is.