Preflight
Run these in order. Each is cheaper than the one after it, so a failure costs you the least possible time. Stop at the first failure, fix it, restart from that step.
1. Scope check (seconds)
git branch --show-current
git status --short
git diff --stat develop...HEAD
- Not on
develop. If you are, branch now — never commit todevelopdirectly. - No stray files: no
exported_world.json, no.ofmbuild output, no*.local, no editor cruft. - The diff is the change you meant to make. Unrelated reformatting is noise that hides the real edit; drop it.
2. Types (fast)
npx tsc --noEmit
3. Frontend tests
npm test
Iterate on one area first — npx vitest run src/components/squad — then run the full suite
before pushing. Around 150 test files; the whole run takes a few minutes.
If you touched any user-facing text, this is where src/i18n/localeCoverage.test.ts and
src/i18n/frontendKeyCoverage.test.ts catch missing locales. They run as part of npm test.
4. Frontend build
npm run build
tsc && vite build. This is the exact command CI runs, so a green local build means a green CI
frontend job.
5. Backend tests
cargo test --locked --manifest-path src-tauri/Cargo.toml --workspace
--locked is what CI passes, so a lockfile you forgot to commit fails here rather than twenty
minutes into a CI run. If it stops with cannot update the lock file, re-run without the flag
and commit the resulting src-tauri/Cargo.lock with your manifest change.
If you changed a Tauri command, also run the lib target explicitly:
cargo test --locked --manifest-path src-tauri/Cargo.toml --lib
cargo test --bin matches zero tests and exits 0. It looks like a pass and checks nothing.
Touched MCP server code? That is behind a feature flag and is not compiled by default:
cargo build --locked --manifest-path src-tauri/Cargo.toml --features mcp
6. Clippy
cargo clippy --locked --manifest-path src-tauri/Cargo.toml --workspace --all-targets -- -D warnings
Clippy must be clean before a PR (CONTRIBUTING.md has always asked for this; check
.github/workflows/build-check.yml for whether CI enforces it yet). Fix warnings rather than
adding #[allow]; if an #[allow] is genuinely right — a Tauri command whose long argument list
is the IPC signature, say — put a comment above it explaining why.
Match CI's toolchain. CI pins the version named in .github/workflows/build-check.yml
(dtolnay/rust-toolchain@…). Clippy gains lints between releases, so a newer local Rust reports
findings CI doesn't have — and an older one misses findings CI will catch. If your results
disagree with CI, run cargo +<pinned-version> clippy … before chasing anything.
Touched MCP code? CI lints it separately, because the feature isn't on by default:
cargo clippy --locked --manifest-path src-tauri/Cargo.toml --workspace --all-targets --features mcp -- -D warnings
7. Formatting
cargo fmt --manifest-path src-tauri/Cargo.toml --all
Format the files you touched. A repo-wide sweep is still outstanding, so cargo fmt --check
reports pre-existing diffs across the tree and is not a CI gate yet — don't let unrelated
formatting churn into your diff.
8. Lint (advisory)
npm run lint
Biome is installed and configured but not a CI gate: the codebase has a large pre-existing backlog. Read the findings for the files you touched and fix those. Don't start the repo-wide sweep here.
9. i18n audit (advisory)
npm run audit:i18n
Always exits 0. It is a heuristic reporter over src/ and src-tauri/ that lists candidate
hardcoded strings. Read the output and check whether anything it lists came from your change. The
real gate was step 3.
PR hygiene
- Branched from
develop, PR targetsdevelop - Conventional commit subject —
fix(ui):,feat(world-cup):,test(training):,refactor(...),chore(...)— matching the existing history - Linked to an issue, or an issue opened first if the change is a new feature
(
CONTRIBUTING.mdasks for this) - Commit message explains why, not just what
- Tests added for new behaviour, written before the code
- Every locale updated if any user-facing text changed
- AI-assisted work disclosed in the PR description — this is a GPLv3 project and provenance matters
Consider a reviewer agent
For anything non-trivial, run the relevant read-only reviewer over your diff before a human sees
it: ofm-architecture-reviewer (crate boundaries, layering, SOLID), i18n-auditor (untranslated
strings), ui-accessibility-reviewer (contrast, focus, keyboard, labelling).