# Contributing Conventions are platform-wide. The full ruleset lives in [`platform/docs/IMPLEMENTATION_PLAN.md §1`](https://gitea.meghsakha.com/platform/docs/src/branch/main/IMPLEMENTATION_PLAN.md). This is the short version. ## Branching - Trunk-based. `main` is always deployable. - Branch from `main`. Name: `feat/`, `fix/`, `chore/`, `docs/`, `refactor/`. - Max 5 days. Longer-lived branches get merge conflicts and stop being trusted. - Never push directly to `main` (branch protection blocks it). ## Commits [Conventional Commits](https://www.conventionalcommits.org/) — enforced by `commitlint` in CI. ``` ()?: [optional body] [optional footer: BREAKING CHANGE: ..., Refs: M5.2] ``` Types: `feat`, `fix`, `chore`, `docs`, `refactor`, `test`, `perf`, `build`, `ci`. Breaking change: append `!` (e.g. `feat!: drop /v0 endpoints`) and add `BREAKING CHANGE:` footer. Examples: ``` feat(api): add POST /v1/tenants/:id/cancel fix(auth): reject JWT when org_id missing docs: link runbook from README refactor!: rename column tenant.kind → tenant.type ``` ## Pull requests 1. Open a PR against `main` using the template (`.gitea/pull_request_template.md` is auto-loaded). 2. Fill **every** section — the template is a checklist, not decoration. 3. Link the milestone in the body: `Linked milestone: M5.2`. 4. Wait for green CI + 1 approving review. **Do not self-merge.** 5. Squash-merge. The PR title becomes the commit message — keep it as a Conventional Commit. ## Tests | Change type | Required tests | |---|---| | New API endpoint | unit + integration (testcontainers, real DB) | | New user-facing flow | Playwright e2e against stage | | Bug fix | regression test FIRST (must fail before fix) | | IaC / Orca manifest | `orca validate` + dry-run plan in PR comment | | Pure refactor | existing suite must stay green | **"Manually tested" is not acceptable** except for IaC, and even there the dry-run plan must be in the PR. ## Secrets - Never commit secrets. `gitleaks` runs in CI and blocks merge. - Local dev: `.env.local` (gitignored); template at `.env.example`. - Stage / prod: Infisical machine identity at `/{env}/{service}/`. ## Code style | Stack | Tools | |---|---| | Go | `go fmt`, `go vet`, `golangci-lint run` — all required clean | | Rust | `cargo fmt --all`, `cargo clippy -- -D warnings` — both required | | TypeScript | `pnpm lint`, `pnpm typecheck` — both required | | Python | `ruff check`, `ruff format`, `mypy` — all required | CI runs these. Pre-commit hooks recommended (`.githooks/pre-commit` in this repo). ## Audit + observability Any state-changing endpoint MUST emit an audit event to Tenant Registry `/audit` in the Retraced-shape schema. See [`PRODUCT_INTEGRATION_SPEC.md §8.4`](https://gitea.meghsakha.com/platform/docs/src/branch/main/PRODUCT_INTEGRATION_SPEC.md). Any service ships OTel SDK from day one (`OTEL_EXPORTER_OTLP_ENDPOINT` injected by Orca). No `fmt.Println` / `console.log` in committed code. ## Reviewer hat When reviewing, check in this order: 1. **Risk** — what could break in prod? Is the rollback clear? 2. **Tests** — do they actually exercise the change? 3. **Security** — secrets, authz, input validation, tenant scoping. 4. **Correctness** — does it do what the PR says it does? 5. **Style** — last; CI already caught the mechanical stuff. ## Questions `#engineering` channel · `oncall@breakpilot.com` · or open a PR with a `[WIP]` prefix and ask in the description.