Pull Request Conventions
Before Opening PR or Committing
Run make check to ensure lint, format, ty, verifytypes, and test suites pass.
For significant changes, such as changes to CLI commands, new features, or workflow changes, update the relevant docs in docs/ as needed.
For branch stability and release expectations, see the Development and Release Process. PRs merge into main, which is the active development branch rather than the stable release channel.
While Making PR
If you are an AI, always create PRs as drafts (gh pr create --draft).
Inspect reuse review
For changes involving agents, tools, scoring, logs, datasets, retries, or caching, reviewers should check the pinned Inspect API before accepting a new abstraction. Prefer the existing primitive when it meets the requirement; otherwise explain the missing capability briefly in the PR description. This is a review question, not a blanket ban on custom code.
PR Description
Write detailed pull request descriptions, and keep them accurate as you push new changes.
Describe what the pull request changes, why, and any reviewer-relevant boundaries. When a Linear issue tracks the work, link it, but keep the pull request description sufficient to review the proposed diff. Follow the documentation placement guidance for project state that does not belong in repository documentation.
When your changes involve evaluation runs or trajectories, link them in the description:
- Runs:
https://equistamp.linuxarena.ai/runs/<run_id>(e.g.,https://equistamp.linuxarena.ai/runs/6a429632c3784f538be602f79be822fc) - Trajectories:
https://equistamp.linuxarena.ai/trajectories/<trajectory_id>(e.g.,https://equistamp.linuxarena.ai/trajectories/rate_limiting%3Aeavesdropper%3Ac63195_epoch1_attack_700aa832)
The CI report maintains one collapsed change breakdown in the PR description; keep author-written prose outside its HTML markers. Metric details and workflow timings live in linked job summaries and artifacts (see CI checks and reports).
Successful docs, public viewer, and private viewer preview builds append one line per site to the PR description: <Website> preview deployed to https://control-tower-<site>-pr-<number>.vercel.app, where <site> is docs, public-viewer, or private-viewer. Each URL points at the latest successful preview deployment for that PR, and redeploys update the existing line.
PR Naming
We follow Conventional Commits. We squash-merge, so the PR title becomes the commit subject on main and feeds the auto-generated release notes.
Format: type(scope): description
Type (required) — the kind of change:
| Type | Use for |
|---|---|
feat | A new feature or capability |
fix | A bug fix |
docs | Documentation only |
refactor | A code change that neither fixes a bug nor adds a feature |
perf | A performance improvement |
test | Adding or correcting tests |
chore | Tooling, dependencies, config, maintenance |
ci | CI / workflow changes |
build | Build system or packaging |
revert | Reverting a previous change |
research | Research experiments and analysis (see the blue/red PR templates) |
Append ! after the type or scope to mark a breaking change: feat(eval)!: drop legacy task-set format.
Scope (optional) — the control-tower subsystem the change touches. Omit it for cross-cutting work. Common scopes: cli, eval, monitor, protocols, trajectories, mtgen, sabotage-eval, sandbox, fleet, internet-simulator, environments, viewer, live, safety, hawk. Research PRs use blue or red.
Description — imperative and concise, no trailing period.
Examples:
feat(eval): add --tags option to ct run evalfix(internet-simulator): stream full upstream response through forward proxyfix(trajectories): exclude None-scored side tasks from failure analysisrefactor(fleet): simplify EC2 resume pathdocs: update running-evals guideresearch(blue): side-task visibility experiment
The pr-title-lint workflow validates only the type; any scope is accepted.
Labels: scripts/generate_release_notes.py groups release notes by the commit subject's type(scope), and labels drive filtering, so also add the matching label:
tooling- For tooling/infrastructure changesenvironment- For environment-related changesstraj- For sabotage trajectory PRsmain-task/side-task- For task-related changesbug- For bug fixesdocumentation- For docs-only changes
After Opening a PR
Keep monitoring the PR until it is merged or explicitly handed off to someone else. Poll it periodically for:
- Failed status checks: If CI fails, investigate and fix the issue. Push a new commit to trigger re-runs.
- Review comments: Respond to all comments. Push a fix when one is needed, explain your reasoning when you disagree or need clarification, and reply briefly to acknowledgments.
- Merge conflicts: If the PR falls behind main and has conflicts, rebase and resolve them.