返回 CodeWhale
SKILL.md
根目录 / docs / skills / cw-gates / SKILL.md
1 ---
2 name: cw-gates
3 description: "Use before claiming any Codewhale change is done, green, or ready to land: the focused-to-broad verification ladder, the budget checks CI enforces, and the rules for what counts as a passing test."
4 ---
5
6 # cw-gates
7
8 Pick the smallest evidence that answers the actual risk, then quote the real
9 output. This repo has been burned twice by the alternative: an exit code
10 mistaken for a pass, and a harness whose scoring line silently reported
11 unevaluated rows as green. Assertions without command output are not evidence.
12
13 Stage 3 of the loop: [cw-orient](../cw-orient/SKILL.md) →
14 [cw-slice](../cw-slice/SKILL.md) → **gates** →
15 [cw-dogfood](../cw-dogfood/SKILL.md) → [cw-land](../cw-land/SKILL.md) →
16 [cw-handoff](../cw-handoff/SKILL.md).
17
18 ## When to use
19
20 - Before saying "done", "green", "passing", "fixed", or "ready to land".
21 - Before a dogfood build — never install an ungated binary.
22 - When asked to "run the gates" or to prove a change is safe.
23
24 For release work specifically, use
25 [codew-release-qa-sweep](../codew-release-qa-sweep/SKILL.md) instead — it adds
26 the version-drift gate and the manual TUI QA targets on top of this ladder.
27
28 ## Workflow
29
30 Climb only as far as the risk requires. Say where you stopped and what you
31 skipped.
32
33 ### Rung 1 — always, and cheap
34
35 ```bash
36 cargo fmt --all -- --check
37 git diff --check
38 ```
39
40 ### Rung 2 — the area that owns the change
41
42 `scripts/dev-test.sh` maps an area or a source path to the fastest correct
43 invocation, and applies the isolated build-dir topology
44 (`docs/BUILD_PERFORMANCE.md`):
45
46 ```bash
47 scripts/dev-test.sh --list
48 scripts/dev-test.sh crates/tui/src/elapsed.rs # path → area + filter
49 scripts/dev-test.sh tui tools:: # area + filter
50 scripts/dev-test.sh config
51 ```
52
53 It uses `cargo nextest run` when nextest is on PATH (`.config/nextest.toml`);
54 `CODEWHALE_DEV_NEXTEST=0` forces libtest. For the TUI crate, `--lib` and
55 `--tests` are disjoint — choose the target that owns the behavior rather than
56 running both by reflex.
57
58 `cargo test --no-run` answers a compile question without executing unrelated
59 cases. `cargo test --doc` covers doc examples, and is only worth running when
60 those examples changed.
61
62 ### Rung 3 — the budgets and drift checks CI enforces
63
64 Run the ones your change can move. Each fails the build in CI:
65
66 ```bash
67 python3 scripts/check-dead-code-budget.py # #[allow(dead_code)] ceiling
68 python3 scripts/check-runtime-contract-budget.py
69 python3 scripts/check-persistence-backlog-budget.py
70 python3 scripts/check-provider-registry.py # provider registry drift
71 python3 scripts/check-command-crate-boundaries.py # command-contract boundary
72 python3 scripts/check-command-migration-manifest.py
73 python3 scripts/check-tui-locale-parity.py # touched crates/tui/locales/
74 sh scripts/check-tui-product-vocabulary.sh
75 python3 scripts/check-readme-translations.py # touched README*.md
76 ./scripts/release/check-versions.sh # touched a version anywhere
77 ```
78
79 The dead-code budget may go **down** freely; raising it needs a reviewer to be
80 told why. Lock in a win with `python3 scripts/check-dead-code-budget.py --update`.
81
82 ### Rung 4 — cross-cutting or release risk only
83
84 ```bash
85 cargo clippy --workspace --all-targets --all-features --locked -- \
86 -D warnings \
87 -A clippy::uninlined_format_args \
88 -A clippy::too_many_arguments \
89 -A clippy::unnecessary_map_or
90 cargo nextest run --workspace --all-features --locked --profile ci
91 cargo test --workspace --all-features --locked --doc
92 git diff --exit-code -- Cargo.lock # lockfile drift guard
93 ```
94
95 `--all-targets` matters: without it, clippy never lints test code, and the
96 v0.9.10 release gate opened with four clippy failures on a green `main`, three
97 of them in test targets.
98
99 ### Rung 5 — website, when `web/` changed
100
101 ```bash
102 cd web && npm ci && npm test && npm run check
103 ```
104
105 ## Claiming a test passed
106
107 - Quote the real `test result: N passed; M failed` line, and confirm `N > 0`
108 **for the tests that cover your change**. `cargo test <filter>` exits 0 having
109 run zero tests when the filter matches nothing; an exit code alone has already
110 been mistaken for a pass here.
111 - Prefer proving a regression test fails without the fix. A test that passes
112 either way pins the implementation, not the defect.
113 - Audit any harness before trusting its score. `ok = ok and X or True` parses as
114 `(ok and X) or True` and once reported twelve unevaluated rows as passing.
115 - A focused rerun of a failing test distinguishes flake from regression in
116 seconds. Do that before calling anything a flake, and root-cause anything that
117 fails outside a known-flaky name — check for unisolated config-path reads or
118 global timeout knobs first.
119
120 ## Red flags / don't
121
122 - Don't say "tests pass" without the count line. Don't say "CI will catch it".
123 - Don't run the full workspace suite as ritual for a leaf change, and don't
124 re-run an unchanged suite to feel more confident.
125 - Don't weaken a safety or data-integrity behavior to make a gate go green.
126 - Don't call a failure a flake without a focused rerun and a named cause.
127 - Don't skip the budget checks because they are "not really tests" — they are
128 required CI contexts, and they encode migrations this repo has already paid for.
129 - Don't report a green gate as permission. A passing sweep is readiness
130 evidence; landing, tagging, and publishing need their own approval.
131
132 ## Output
133
134 A checklist: each command, pass/fail, and the salient line (test counts, budget
135 numbers, the `check-versions.sh` verdict). Name explicitly what you did **not**
136 run and why. If a step could not run in this environment, say so rather than
137 implying coverage you do not have.
138
138 lines MARKDOWN