Skip to content

Contributing

Use a prefix that describes the type of change:

PrefixUse for
feat/New features
fix/Bug fixes
refactor/Code restructuring without behavior change
chore/Maintenance, dependencies, CI

Example: feat/slack-thread-replies, fix/risk-score-overflow.

Follow the conventional commit format:

<type>(<scope>): <summary>

Types: fix, feat, refactor, docs, chore, ci, test.

Write messages that explain why, not just what. Keep the summary under 72 characters.

fix(evaluation): cap risk score at 100 when weight sum exceeds limit
feat(dashboard): add org-level risk trend chart
chore(ci): pin golangci-lint to v1.62
  • Keep PRs small and focused — one logical change per PR.
  • The PR title should mirror the main commit message.
  • Include a summary of what changed and why.
  • Include a test plan describing how the change was verified.
  • CI must pass before requesting review.

Go — golangci-lint enforces style. Run it locally before pushing:

Terminal window
cd apps/api && golangci-lint run ./...

TypeScript — ESLint handles linting across all frontend apps:

Terminal window
pnpm lint

All changes must include tests. Unit tests at minimum; integration or E2E tests when the change touches API endpoints or user-facing flows. Run the full suite from the repo root:

Terminal window
pnpm test

See the Testing page for details on each test layer.

  • Never commit secrets, tokens, or credentials.
  • Validate all external input at system boundaries.
  • Use parameterized queries — never concatenate user input into SQL.

All PRs require at least one review before merging. Reviewers check for correctness, test coverage, and adherence to project conventions.

Run through this checklist locally:

  1. pnpm lint passes
  2. pnpm test passes
  3. pnpm build succeeds
  4. No secrets or credentials in the diff