Contributing
Branch naming
Section titled “Branch naming”Use a prefix that describes the type of change:
| Prefix | Use 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.
Commit messages
Section titled “Commit messages”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 limitfeat(dashboard): add org-level risk trend chartchore(ci): pin golangci-lint to v1.62Pull requests
Section titled “Pull requests”- 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.
Code style
Section titled “Code style”Go — golangci-lint enforces style. Run it locally before pushing:
cd apps/api && golangci-lint run ./...TypeScript — ESLint handles linting across all frontend apps:
pnpm lintTesting
Section titled “Testing”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:
pnpm testSee the Testing page for details on each test layer.
Security
Section titled “Security”- Never commit secrets, tokens, or credentials.
- Validate all external input at system boundaries.
- Use parameterized queries — never concatenate user input into SQL.
Review process
Section titled “Review process”All PRs require at least one review before merging. Reviewers check for correctness, test coverage, and adherence to project conventions.
Before opening a PR
Section titled “Before opening a PR”Run through this checklist locally:
pnpm lintpassespnpm testpassespnpm buildsucceeds- No secrets or credentials in the diff