preflight

GitHub

验证PR的前置检查技能,涵盖前端脚本、后端测试、Clippy、格式及架构审查。确保本地通过不代表CI必过,强调不修改代码且严格报告结果。

.claude/skills/preflight/SKILL.md openfootmanager/openfootmanager

Trigger Scenarios

提交Pull Request前 需要执行代码质量门禁检查时

Install

npx skills add openfootmanager/openfootmanager --skill preflight -g -y
More Options

Non-standard path

npx skills add https://github.com/openfootmanager/openfootmanager/tree/develop/.claude/skills/preflight -g -y

Use without installing

npx skills use openfootmanager/openfootmanager@preflight

指定 Agent (Claude Code)

npx skills add openfootmanager/openfootmanager --skill preflight -a claude-code -g -y

安装 repo 全部 skill

npx skills add openfootmanager/openfootmanager --all -g -y

预览 repo 内 skill

npx skills add openfootmanager/openfootmanager --list

SKILL.md

Frontmatter
{
    "name": "preflight",
    "description": "Verify a pull request with the frontend scripts, default and MCP backend tests and clippy, formatting, architecture checks and review evidence. Report results and unrun checks without claiming a local pass guarantees CI.",
    "when_to_use": "Before opening or updating a pull request or asking for review.",
    "allowed-tools": "Read, Grep, Glob, Bash(npm ci), Bash(npm test*), Bash(npm run*), Bash(cargo test*), Bash(cargo clippy*), Bash(cargo fmt*), Bash(cargo mutants*), Bash(scripts\/mutants-in-diff.sh*), Bash(git status*), Bash(git diff*), Bash(git log*), Bash(git branch*), Bash(git rev-parse*)"
}

Preflight

Read the root Code quality section first. It names the limits and which gates are live. Verify without mutating formatting or weakening tests. Stop on a failure, fix within scope, then resume from that step; disclose unrelated blockers. Never report an unrun check as passing.

1. Scope and install

git branch --show-current
git status --short
git diff --stat upstream/develop...HEAD
npm ci

Work on a branch off current upstream/develop, targeting develop. Check for unrelated files, exported worlds, local settings and formatting churn. npm ci precedes frontend commands in a fresh checkout. Use npm run <script>, never npx: a cached namesake can silently run the wrong tool.

2. Frontend gates

npm run preflight

package.json defines this frontend sequence: format check, lint, knip, build, tests. npm run build already does tsc && vite build; do not repeat a separate type check. For a scoped test while iterating, use npm test -- <path> -t '<scenario>' after installing dependencies; the full suite is still required before the PR. Locale and literal-key coverage tests are part of it. A local pass is evidence for these commands, not a guarantee that every CI job passes.

3. Backend gates, default and MCP

cargo fmt --manifest-path src-tauri/Cargo.toml --all -- --check
cargo test --locked --manifest-path src-tauri/Cargo.toml --workspace
cargo test --locked --manifest-path src-tauri/Cargo.toml --lib --features mcp
cargo clippy --locked --manifest-path src-tauri/Cargo.toml --workspace --all-targets -- -D warnings
cargo clippy --locked --manifest-path src-tauri/Cargo.toml --workspace --all-targets --features mcp -- -D warnings

Default workspace tests include command lib tests. The second test command actually executes MCP lib tests; building the feature alone does not. cargo test --bin may run zero tests. Verify that the expected named tests ran. --locked matches CI; if a dependency edit needs a lockfile update, resolve it deliberately and commit the resulting lockfile alongside the manifest.

The pinned rust-toolchain.toml is authoritative. Do not override it with cargo +<toolchain>. No new #[allow]: use the root constraint/owner suppression policy. Do not raise a threshold to fit code. fmt --check reports changes without writing them.

The workspace run includes src-tauri/tests/architecture.rs and, as the programme lands, its crate-matrix, application-import, engine-input and command-size checks, plus file-size and instruction-sync integration tests. Frontend architecture/file-size tests join npm test in programme PR 8. Until each exists, inspect those rules manually and mark them review-only; do not run a missing target or count a zero-test selection as a pass.

3a. Mutants on the diff (trial until 27 Oct 2026)

Coverage says a line ran; it does not say a test would notice the line being wrong. On 13 Oct 2026 contracts/renewals.rs had 89% line coverage and a 29% mutation score. This step mutates only the Rust production lines your branch changes and reports which mutants your tests miss. It is a two-week trial, from 13 to 27 Oct 2026: there is no baseline file and no CI gate. On 27 Oct the results pasted in PR bodies decide whether it stays.

Run it on any branch that touches src-tauri/. Use cargo-mutants 25.3.1, the version mutation-tests.yml pins (cargo install --locked cargo-mutants@25.3.1). From the repository root, with everything under src-tauri/ committed:

scripts/mutants-in-diff.sh                        # base defaults to upstream/develop

On a machine shared with other agents, wrap the whole run in one lock of its own, and do not pass a build-slot wrapper as CARGO. A run lasts from twenty minutes to hours, and a build-slot wrapper would hold one of the machine's build slots for all of it: two such runs at once starved every other build on 13 Oct 2026. One mutants run at a time, with few build jobs, leaves the build slots to everyone else.

The script prints the counts line and one line per missed or timed-out mutant; that output is what goes in the PR body. What it does, and why:

  • It refuses every way of passing without testing anything. cargo-mutants matches the diff's paths against the workspace in src-tauri/. A diff rooted at the repository (src-tauri/crates/…) matches nothing, and cargo-mutants prints No mutants to filter and exits 0. The script takes the diff with --relative=src-tauri and refuses a patch whose paths are not under src-tauri/. scripts/mutation-outcome.sh then refuses a run that wrote no report or tested no mutant.
  • Zero is a real answer for a branch that changes no Rust production line. A test-only Rust PR (an integration test, or a #[cfg(test)] module), a docs PR and a frontend PR all list 0 mutants: cargo-mutants never mutates test code. The script then prints Mutants on the diff: 0 mutants and runs nothing. Paste that line too.
  • --in-place edits your working tree while it runs, one mutant at a time, restoring each file afterwards. That is why the script refuses uncommitted changes under src-tauri/, and why it restores src-tauri/ from HEAD if an interrupted run leaves a mutant behind. In-place reuses your build; a copied tree would rebuild every dependency from scratch.
  • --profile mutants and CARGO_INCREMENTAL=1 are the two settings that brought an ofm_core mutant from 115 s to 34 s in CI; mutation-tests.yml explains both. --timeout 300 stops a mutant that loops forever. cargo-mutants reports it as a timeout, not as caught, and it costs the full five minutes; triage it like a survivor (usually "a loop that never ends"). MUTANTS_TIMEOUT (default 180m) caps the whole run.
  • Expect about a minute per mutant, plus five to six minutes for the unmutated baseline (measured on a loaded 8-core machine with two build jobs; see the PR that added this step). The script prints the count before it starts; run it while you do something else.
  • Each mutant is tested with its own crate's tests. Exit 2 (some missed) and exit 3 (some timed out) are results; the script exits 0 for both and lists the survivors. Any other failure means no evidence: report the step as not run.

Paste the result into the PR body, with a triage after each surviving or timed-out mutant:

Mutants on the diff: 14 caught, 2 missed, 0 timed out, 1 unviable (6 min)
- [missed] crates/ofm_core/src/aging.rs:85:9: delete match arm 35 in retirement_chance: real gap, test added (`the_retirement_chance_rises_with_each_year_from_33`)
- [missed] crates/ofm_core/src/finances/journal.rs:202:15: replace < with <= in credit_opening_cash: equivalent, because 0 already returned two lines above

"Real gap, test added" means you wrote the test and re-ran it with the mutant applied by hand, and it failed. "Equivalent" needs a reason a reviewer can check. A survivor you cannot place in either category is a finding: say so rather than leaving it out.

4. Review evidence

Use ofm-architecture-reviewer for architecture and SOLID, ofm-dedup-reviewer for authoritative homes and reachable reuse, and ofm-test-reviewer for any test change and every bug fix. Map each named GWT scenario to one independently reported test; quote observed red/fix-removal failure and the green command. Use a disposable copy for fix removal. Do not claim "would fail" as observed evidence. Identify uncovered routes and exceptions.

i18n-auditor and ui-accessibility-reviewer are mandatory when their surfaces change. Read the heuristic report if text changed:

npm run audit:i18n

It always exits 0; it is advisory and cannot replace locale tests or review. New mechanical quality checks must fail required CI at zero findings; this existing heuristic is not such a gate.

Record a compact evidence table in the PR body:

Check / scenario Command / test name Observed result Limit or exception

Include the canonical rule owner and layer, reviewer results, and every unrun check. Documentation changes have no runtime red/green claim; verify links, identical instruction blocks and scope.

5. Merge hygiene and collisions

  • Conventional commit, fresh develop base, PR target develop, linked issue where applicable.
  • AI-assisted disclosure box completed per CONTRIBUTING.md.
  • Search every other open PR diff for uses of public items/fields/variants removed or changed here, and for removals of items this branch uses. Agree merge order with the owner on a collision. The second PR stays draft with ⛔ Merge after #<first> as its body's first line. Once the first merges, merge upstream/develop, adapt, rerun gates, then mark ready.
  • Recheck when a merge touches your surfaces. The develop merge queue reruns required checks; local evidence does not replace the queue. Do not alter repository settings.

Version History

  • c3d8002 Current 2026-10-18 19:49

    新增突变测试步骤以验证Rust代码变更,增强对空diff的防护及超时处理逻辑。

  • 6917db7 2026-09-27 13:46

    将前端命令从npx改为npm exec;新增Clippy lint检查步骤;增加对Tauri lib目标和MCP特性代码的测试说明。

  • 01624df 2026-09-11 20:36
  • 35cbddc 2026-09-08 21:09

    后端测试命令增加--locked参数以匹配CI环境;新增MCP功能代码的编译与Clippy lint检查步骤;强调Clippy工具链版本需与CI保持一致。

  • 9d401d6 2026-07-30 22:45

Same Skill Collection

.claude/skills/add-domain-field/SKILL.md
.claude/skills/add-mcp-tool/SKILL.md
.claude/skills/add-tauri-command/SKILL.md
.claude/skills/add-ui-string/SKILL.md
.claude/skills/new-ui-surface/SKILL.md
.claude/skills/refactor-to-rules/SKILL.md
.claude/skills/write-tests/SKILL.md

Metadata

Files
0
Version
c3d8002
Hash
796c2df0
Indexed
2026-07-30 22:45

Home - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-10-21 12:42
浙ICP备14020137号-1