Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Use before committing or creating a PR for EmbodiChain to select proportional validation and verify affected code style, tests, headers, annotations, exports, and docstrings
.claude/skills/dexforce-pre-commit-check/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-05 | ✗→✓ | ▲ Improved | 178% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 132% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 94% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 158% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 49% | 0% |
Run proportional local checks for the files being changed, catching relevant issues before pushing without defaulting to the full test suite.
.py filesbashgit diff --name-only HEAD git diff --name-only --cached git status --short
Collect all changed/added .py files.
Classify the change by affected area: workflow, docs, packaging, isolated Python module, package-wide behavior, or cross-cutting infrastructure.
This is the first CI gate and will cause immediate failure:
bashblack --check --diff --color ./
If it fails, run black . and review the formatting changes.
Run the same read-only gate used by CI:
bashpython docs/scripts/check_api_docs.py
If it reports missing exports, use $update-api-docs to add useful Sphinx entries and descriptions. Do not change __all__ solely to make this check pass.
Every .py file must begin with the 15-line copyright block. For each changed/new .py file, verify the first line is:
# ----------------------------------------------------------------------------The full header template:
python# ---------------------------------------------------------------------------- # Copyright (c) 2021-2026 DexForce Technology Co., Ltd. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ----------------------------------------------------------------------------
from __future__ import annotationsEvery .py file must have this import (after the header, before other imports). This enables A | B syntax and forward references.
__all__ in Public ModulesFor any new or modified module under embodichain/, verify it defines __all__ listing all public symbols. Example:
python__all__ = ["MyClass", "my_function"]
Skip this check for __init__.py files that only re-export via from . import *.
For any new public function, class, or method:
Args: section if it takes parametersReturns: section if it returns a value.. attention:: or .. tip:: directives for non-obvious behaviorFor any new public API:
A | B over Union[A, B]TYPE_CHECKING guard for imports that would cause circular dependencies@configclass UsageFor any new configuration class:
@configclass decorator (not bare @dataclass)from dataclasses import MISSING for required fieldsembodichain.utils import configclassDo not treat the CI test job as a requirement to run pytest tests locally for every change. Choose the smallest command set that exercises the affected behavior:
| Change scope | Default validation | |---|---| | .github/workflows/** only | actionlint on changed workflows; run related script tests only when workflow scripts changed | | Docs content only | Relevant Sphinx build or docs-specific tests | | One Python module | Matching tests/**/test_<module>.py | | One package/subsystem | Tests for that package plus focused integration tests | | Packaging/release code | Package build and artifact validation | | Shared core, global test config, or multiple subsystems | Broader affected tests; full suite only when narrow coverage is not credible |
Skip runtime tests when no executable behavior is affected, but still run the appropriate syntax or configuration validator. Run the full suite only when:
Before starting a command likely to take more than two minutes, report the selected scope and why narrower validation is insufficient. Honor explicit user instructions to skip or narrow tests.
For any new public module or function:
tests/<subpackage>/test_<module>.pyOutput a pass/fail summary:
Pre-Commit Check Results
========================
[PASS] Black formatting
[PASS] Public API docs coverage
[PASS] Apache 2.0 headers (5/5 files)
[FAIL] from __future__ import annotations — missing in: foo.py
[PASS] __all__ exports
[PASS] Docstrings on public APIs
[PASS] Type annotations
[PASS] @configclass usage
[PASS] Targeted tests — tests/foo/test_bar.py
[N/A] Full test suite — isolated change covered by targeted tests
[WARN] Missing tests for: bar.py
Fix the above issues before committing.The project's CI pipeline (.github/workflows/main.yml) runs:
black --check --diff --color ./python docs/scripts/check_api_docs.pyThis skill always covers the relevant lint and structural checks, then selects tests proportionally. It does not require reproducing the entire CI pipeline for every local change.
| Mistake | Fix | |---------|-----| | Running black on only one file | Run black . on the whole project — CI checks everything | | Forgetting test Apache header | Test files also need the 15-line copyright block | | Using Union[A, B] | Use A \| B (with from __future__ import annotations) | | Using bare @dataclass | Use @configclass from embodichain.utils | | Missing __all__ in new module | Add __all__ with all public symbols |
| Check | Command/Method | |-------|---------------| | Black formatting | black --check --diff --color ./ | | Auto-fix formatting | black . | | Public API docs | python docs/scripts/check_api_docs.py | | Header check | Verify first line is # ---...--- | | __future__ import | Grep for from __future__ import annotations | | __all__ export | Grep for __all__ in module | | Run targeted tests | pytest tests/<affected-path> | | Run full tests | pytest tests only when the full-suite criteria above apply |
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-06 | pass→pass | 17,771 | 25,500 | +43% | 1 | 1 | 0% | 2,866 | 6,141 | +114% | 0 | 0 | — |
case-01 | fail→fail | 33,875 | 4,650 | -86% | 1 | 1 | 0% | 382 | 2,209 | +478% | 0 | 0 | — |
case-02 | fail→fail | 6,302 | 5,427 | -14% | 1 | 1 | 0% | 264 | 2,182 | +727% | 0 | 0 | — |
case-03 | fail→fail | 5,169 | 3,692 | -29% | 1 | 1 | 0% | 288 | 1,971 | +584% | 0 | 0 | — |
case-04 | pass→fail | 5,224 | 5,554 | +6% | 1 | 1 | 0% | 1,135 | 2,073 | +83% | 0 | 0 | — |
case-05 | fail→pass | 8,922 | 18,667 | +109% | 1 | 1 | 0% | 1,656 | 4,611 | +178% | 0 | 0 | — |
case-07 | fail→pass | 5,538 | 3,643 | -34% | 1 | 1 | 0% | 1,075 | 2,496 | +132% | 0 | 0 | — |
case-08 | fail→pass | 6,438 | 2,537 | -61% | 1 | 1 | 0% | 1,167 | 2,263 | +94% | 0 | 0 | — |
case-09 | fail→pass | 5,614 | 2,831 | -50% | 1 | 1 | 0% | 902 | 2,326 | +158% | 0 | 0 | — |
case-10 | pass→pass | 4,002 | 1,737 | -57% | 1 | 1 | 0% | 692 | 2,073 | +200% | 0 | 0 | — |
case-11 | fail→pass | 8,141 | 2,482 | -70% | 1 | 1 | 0% | 1,510 | 2,248 | +49% | 0 | 0 | — |
case-12 | fail→pass | 5,588 | 3,311 | -41% | 1 | 1 | 0% | 1,042 | 2,316 | +122% | 0 | 0 | — |
case-13 | pass→pass | 6,075 | 4,072 | -33% | 1 | 1 | 0% | 898 | 2,560 | +185% | 0 | 0 | — |
case-14 | pass→pass | 6,013 | 2,254 | -63% | 1 | 1 | 0% | 991 | 2,133 | +115% | 0 | 0 | — |
case-15 | pass→pass | 11,659 | 4,848 | -58% | 1 | 1 | 0% | 1,664 | 2,368 | +42% | 0 | 0 | — |
case-16 | pass→pass | 13,014 | 5,759 | -56% | 1 | 1 | 0% | 2,238 | 2,877 | +29% | 0 | 0 | — |
case-17 | fail→pass | 8,679 | 2,435 | -72% | 1 | 1 | 0% | 1,323 | 2,202 | +66% | 0 | 0 | — |
case-18 | fail→pass | 8,429 | 4,241 | -50% | 1 | 1 | 0% | 1,441 | 2,726 | +89% | 0 | 0 | — |
case-19 | fail→pass | 7,749 | 2,839 | -63% | 1 | 1 | 0% | 1,343 | 2,349 | +75% | 0 | 0 | — |
case-20 | fail→pass | 9,556 | 5,528 | -42% | 1 | 1 | 0% | 1,690 | 2,469 | +46% | 0 | 0 | — |
case-21 | fail→pass | 14,086 | 33,147 | +135% | 1 | 1 | 0% | 2,462 | 2,356 | -4% | 0 | 0 | — |
case-22 | fail→pass | 17,245 | 4,049 | -77% | 1 | 1 | 0% | 2,978 | 2,443 | -18% | 0 | 0 | — |
case-23 | fail→pass | 10,035 | 5,787 | -42% | 1 | 1 | 0% | 1,831 | 2,675 | +46% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted, and 19 counted toward the lift figure. The other 4 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +52 percentage points is the difference between those two pass rates over the 19 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
| Model | Method | Date | Lift |
|---|---|---|---|
| gemini-3.6-flash | verified | 8/22/2026 | +50% |
Other measured skills in the registry, with their headline benchmark lift.