## Branch Strategy

We use short-lived topic branches, Conventional Commits, and PRs into `main`.

### Branch prefixes
Create branches using one of:
- `feat/<scope>-<short-desc>` – new features (e.g., `feat/runner-do-timeouts`)
- `fix/<scope>-<short-desc>` – bug fixes
- `docs/<scope>-<short-desc>` – docs only
- `chore/<scope>-<short-desc>` – tooling, config, non-product changes
- `refactor/<scope>-<short-desc>` – no behavior change
- `test/<scope>-<short-desc>` – test-only changes

### Examples
```bash
git checkout -b feat/ssh-timeout-handler
git checkout -b fix/scoring-edge-case
git checkout -b docs/adr-durable-objects
git checkout -b chore/update-deps
```

### Commit messages
Follow [Conventional Commits](https://www.conventionalcommits.org/):
```
<type>(<scope>): <subject>

<body>

<footer>
```

**Required:**
- `<type>`: feat, fix, docs, chore, refactor, test
- `<subject>`: imperative mood, lowercase, no period

**Optional:**
- `<scope>`: module or area affected (e.g., runner, scoring, ui)
- `<body>`: detailed explanation
- `<footer>`: references (e.g., `Fixes #123`, `BREAKING CHANGE: ...`)

### Pull Request flow
1. Create feature branch from `main`
2. Make changes with conventional commits
3. Push to origin
4. Open PR with filled template
5. Address review feedback
6. Squash-merge to `main` (title must follow convention)

### Code Quality
Before opening a PR:
```bash
cd bandit-runner-app
pnpm install
pnpm lint          # ESLint
npx tsc --noEmit   # TypeScript check
pnpm build         # Verify builds
```
