Skip to content

Pull Request Guide

This guide covers the pull request workflow for HoloMUSH, including creation, review, and merge processes.

All code changes go through pull requests. This ensures:

  • Code quality through automated and manual review
  • Knowledge sharing across the team
  • Traceable history of changes and decisions
Requirement Description
Tests pass Run task test locally
Linting passes Run task lint to catch issues early
Follow commit format Use conventional commits (see Commits)
Keep PRs focused One logical change per PR

Before creating a PR, verify:

  • Tests pass locally (task test)
  • Linting passes (task lint)
  • Code is formatted (task fmt)
  • New code has appropriate test coverage (codecov targets 80% on changed lines)
  • Documentation updated if behavior changed
  • No debug code or commented-out code left behind
  • Code is as simple as possible

Before pushing to a PR branch, run task pr-prep to mirror every CI job locally. The gate is serialized via a lockfile under ${TMPDIR:-/tmp}/holomush-pr-prep/ — on macOS this is typically per-user (because $TMPDIR is user-scoped); on Linux it is typically machine-global (because /tmp is shared). If you see an “another pr-prep is running” error, wait for the holder to finish or kill its process tree (see Pre-Push Quality Gate for details — note that kill <pid> alone is insufficient because descendants inherit the lock fd).

Use descriptive branch names:

Name the branch after the contribution type and the issue it closes:

Pattern Example Contribution type
feature/<issue#>-<slug> feature/1234-scene-transcript Feature
fix/<issue#>-<slug> fix/1234-login-redirect Fix
enhancement/<issue#>-<slug> enhancement/1234-exit-locks Enhancement
chore/<issue#>-<slug> chore/1234-ace-test-naming Chore
docs/<slug> docs/api-reference Docs-only (exempt)

Follow conventional commit format for PR titles:

<type>(<scope>): <description>

Examples:

  • feat(plugin): add Lua script hot reload
  • fix(telnet): handle connection reset gracefully
  • docs(api): add authentication examples

PR bodies come from a typed template — fix, enhancement, feature, or chore. GitHub offers the list when you open the PR; pick the one that matches your change and fill it in. Each template requires a linked, approved issue.

Dependency-only, repo-config-only (.github/**), and documentation-only PRs are exempt from the typed template and the issue-first gate. See CONTRIBUTING.md for the full process and the exempt path list.

All PRs automatically trigger:

  1. CI Pipeline - Tests, linting, formatting checks
  2. Coverage Analysis - Ensures coverage thresholds met
Area Focus
Correctness Does the code do what it’s supposed to?
Testing Are there adequate tests?
Clarity Is the code easy to understand?
Patterns Does it follow project conventions?
Security Are there any security concerns?
Performance Any obvious performance issues?

When addressing review comments:

  1. Fix the issue - Make the requested change
  2. Explain if declining - Provide reasoning if not making a change
  3. Ask for clarification - If feedback is unclear, ask questions
  4. Don’t argue - If you disagree, discuss constructively
<type>(<scope>): <description>
[optional body]
[optional footer]
Type Description
feat New feature
fix Bug fix
docs Documentation changes
style Formatting (no code change)
refactor Code change without feature/fix
perf Performance improvement
test Adding or updating tests
build Build system or dependencies
ci CI configuration
chore Other changes (e.g., .gitignore)
Requirement Description
Be atomic One logical change per commit
Have clear message Describe what and why, not how
Never include secrets No credentials, tokens, or keys
Reference issues Use Closes #123 or Related to #456

Before merging, ensure:

Requirement Description
CI passing All automated checks green
Review approval At least one approving review
Up to date Rebased on latest main
Squash merge All merges to main are squash merges

All merges to main use squash merge to maintain a clean, linear history:

  • Each PR becomes one atomic commit on main
  • Easier to bisect, revert, and understand history
  • WIP commits and fixups don’t clutter the main branch
  • Commit message can be refined at merge time
Issue Solution
Test failures Run task test locally, fix failing tests
Lint errors Run task lint, address each error
Format issues Run task fmt, commit formatted files
Coverage drop Add tests for new code paths

If your PR isn’t getting reviewed:

  1. Ensure CI is passing
  2. Check PR description is complete
  3. Keep PR size reasonable (< 500 lines ideal)
Terminal window
# Run before creating PR
task test # Run tests
task lint # Run linters
task fmt # Format code
# Create PR
gh pr create --title "type(scope): description" --body "..."
# View PR status
gh pr view
# Request review
gh pr edit --add-reviewer username
1. Create feature branch
2. Make changes with atomic commits
3. Run tests and lints locally
4. Create PR with clear description
5. Address CI failures
6. Get review and address findings
7. Get approval and merge

Three adversarial read-only sub-agents (design-reviewer, plan-reviewer, code-reviewer, plus crypto-reviewer / abac-reviewer when applicable) gate hand-offs BEFORE the PR surface. They complement pr-review-toolkit:review-pr (which runs on the PR itself) by providing an earlier, in-session review pass. The gate tables (which agent fires when, and the READY / NOT READY contract) live in the root CLAUDE.md under “Pre-Push Review Gates”.

Agent definitions live in .claude/agents/; slash commands in .claude/commands/; persistent memory in .claude/agent-memory/ (checked into VCS).