Code QC
Structured quality control audit for codebases. Delegates static analysis to proper tools (ruff, eslint, gdlint) and focuses on what AI adds: semantic understanding, cross-module consistency, and dynamic smoke test generation.
Quick Start
- 1. Detect project type (read the profile for that language)
- Load
.qc-config.yaml if present (for custom thresholds/exclusions) - Run the 8-phase audit (or subset with
--quick) - Generate report with verdict
- Save baseline for future comparison
Configuration (.qc-config.yaml)
Optional project-level config for monorepos and custom settings:
CODEBLOCK0
Execution Modes
| Mode | Phases Run | Use Case |
|---|
| Full (default) | All 8 phases | Thorough audit |
| INLINECODE3 |
1, 3, 3.5, 6 | Fast sanity check |
|
--changed-only | All, filtered | CI on pull requests |
|
--fail-fast | All, stops early | Find first issue fast |
|
--fix | 3 with autofix | Apply automatic fixes |
Phase Overview
| # | Phase | What | Tools |
|---|
| 1 | Test Suite | Run existing tests + coverage | pytest --cov / jest --coverage |
| 2 |
Import Integrity | Verify all modules load |
scripts/import_check.py |
| 3 | Static Analysis | Lint with proper tools | ruff / eslint / gdlint |
| 3.5 | Type Checking | Static type verification | mypy / tsc --noEmit / (N/A for GDScript) |
| 4 | Smoke Tests | Verify business logic works | AI-generated per project |
| 5 | UI/Frontend | Verify UI components load | Framework-specific |
| 6 | File Consistency | Syntax + git state |
scripts/syntax_check.py + git |
| 7 | Documentation | Docstrings + docs accuracy |
scripts/docstring_check.py |
Phase Details
Phase 1: Test Suite
Run the project's test suite with coverage. Auto-detect the test runner:
CODEBLOCK1
Record: total, passed, failed, errors, skipped, duration, coverage %.
Verdict contribution:
- - No tests found → SKIP (not FAIL; project may be config-only)
- Failure rate = 0% → PASS
- Failure rate ≤ threshold (default 5%) → WARN
- Failure rate > threshold → FAIL
Coverage reporting (Python):
CODEBLOCK2
Phase 2: Import Integrity (Python/GDScript)
Python: Run scripts/import_check.py against the project root.
GDScript: Verify scene/preload references are valid (see gdscript-profile.md).
Critical vs Optional Import Classification
Use these heuristics to classify import failures:
| Pattern | Classification | Rationale |
|---|
INLINECODE11 , main.py, app.py, INLINECODE14 | Critical | Core entry points |
Module in src/, lib/, or top-level package |
Critical | Core functionality |
|
*_test.py,
test_*.py,
conftest.py |
Optional | Test infrastructure |
| Modules in
examples/,
scripts/,
tools/ |
Optional | Auxiliary code |
| Import error mentions
cuml,
triton,
tensorrt |
Optional | Hardware-specific |
| Import error mentions missing system lib |
Optional | Environment-specific |
| Dependency in
[project.optional-dependencies] |
Optional | Declared optional |
Phase 3: Static Analysis
Do NOT use grep. Use the language's standard linter.
Standard Mode
CODEBLOCK3
Fix Mode (--fix)
When
--fix is specified, apply automatic corrections:
CODEBLOCK4
Important: After --fix, re-run the check to report remaining issues that couldn't be auto-fixed.
Phase 3.5: Type Checking (NEW)
Run static type analysis before proceeding to runtime checks.
Python:
CODEBLOCK5
TypeScript:
CODEBLOCK6
GDScript: Godot 4 has built-in static typing but no standalone checker. Estimate type coverage manually:
CODEBLOCK7
Use the estimate_type_coverage() function from gdscript-profile.md to calculate coverage per file:
CODEBLOCK8
Also check for @warning_ignore annotations which may hide type issues.
Record: Total errors, categorized by severity.
Phase 4: Smoke Tests (Business Logic)
Test backend/core functionality — NOT UI components (that's Phase 5).
API Discovery Heuristics:
- 1. Entry points: Look for
main(), cli(), app, create_app(), INLINECODE37 - Service layer: Find classes/modules named
*Service, *Manager, INLINECODE40 - Public API: Check
__all__ exports in INLINECODE42 - FastAPI/Flask: Find route decorators (
@app.get, @router.post) - CLI: Find typer/click
@app.command() decorators - SDK: Look for client classes, public methods without
_ prefix
For each discovered API, generate a minimal test:
CODEBLOCK9
Guidelines:
- - Import + instantiate + call one method with minimal valid input
- Use in-memory/temp resources (
:memory:, tempdir) - Each test < 5 seconds
- Catch exceptions, report clearly
Phase 5: UI/Frontend Verification
Test UI components separately from business logic.
| Framework | Test Method |
|---|
| Gradio | INLINECODE49 (no launch()) |
| Streamlit |
streamlit run app.py --headless exits cleanly |
|
PyQt/PySide | Set
QT_QPA_PLATFORM=offscreen, import widget modules |
|
React |
npm run build succeeds |
|
Vue |
npm run build succeeds |
|
Godot | Scene files parse without error, required scripts exist |
|
CLI |
--help on all subcommands returns 0 |
Boundary: Phase 4 tests "does the logic work?" Phase 5 tests "does the UI render?"
Phase 6: File Consistency
Run scripts/syntax_check.py — compiles all source files to verify no syntax errors.
Note: Phase 2 (Import Integrity) tests runtime import behavior including initialization code. Phase 6 tests static syntax correctness. Both are needed: a file can have valid syntax but fail to import (e.g., missing dependency), or vice versa (syntax error in a module that's never imported).
Check git state:
CODEBLOCK10
Phase 7: Documentation
Run scripts/docstring_check.py (now checks __init__.py by default).
Also verify:
- - README exists and is non-empty
- Key docs (CHANGELOG, CONTRIBUTING) exist if referenced
- No stale TODO markers in docs claiming completion
Verdict Logic
CODEBLOCK11
Baseline Comparison
Save results to .qc-baseline.json:
CODEBLOCK12
On subsequent runs, report delta:
CODEBLOCK13
Report Output
Generate in 3 formats:
- 1. Markdown (
qc-report.md) — full detailed report for humans - JSON (
.qc-baseline.json) — machine-readable for CI/comparison - Summary (chat message) — 10-line digest for Discord/Slack
Summary Format Example
CODEBLOCK14
Language-Specific Profiles
Read the appropriate profile before running:
- - Python: INLINECODE62
- TypeScript: INLINECODE63
- GDScript: INLINECODE64
- General (any language): INLINECODE65
技能名称: code-qc
详细描述:
代码质量审计
针对代码库的结构化质量控制审计。将静态分析委托给合适的工具(ruff、eslint、gdlint),并专注于AI的增值领域:语义理解、跨模块一致性以及动态冒烟测试生成。
快速开始
- 1. 检测项目类型(读取该语言的配置文件)
- 如果存在.qc-config.yaml,则加载它(用于自定义阈值/排除项)
- 运行8阶段审计(或使用--quick运行子集)
- 生成带有判定结果的报告
- 保存基线以便将来比较
配置(.qc-config.yaml)
适用于单体仓库和自定义设置的可选项目级配置:
yaml
.qc-config.yaml
thresholds:
test
failurerate: 0.05 # >5% = 失败, 0-5% = 警告, 0% = 通过
lint
errorsmax: 0 # 超过此数量的lint错误则失败
lint
warningsmax: 50 # 超过此数量的警告则发出警告
type
errorsmax: 0 # 超过此数量的类型错误则失败(默认严格)
exclude:
dirs: [vendor, third_party, generated]
files: [_generated.py, .pb.go]
changed_only: false # 仅检查git变更的文件(CI模式)
fail_fast: false # 遇到第一个失败即停止
quick_mode: false # 仅运行阶段1、3、3.5、6
languages:
python:
min_coverage: 80
ignore_rules: [T201] # 在此项目中允许使用print
typescript:
strict_mode: true # 要求tsconfig strict: true
ignore_rules: [] # 要忽略的eslint规则
gdscript:
godot_version: 4.2
执行模式
| 模式 | 运行的阶段 | 使用场景 |
|---|
| 完整(默认) | 全部8个阶段 | 全面审计 |
| --quick |
1、3、3.5、6 | 快速健康检查 |
| --changed-only | 全部,已过滤 | 拉取请求上的CI |
| --fail-fast | 全部,提前停止 | 快速找到第一个问题 |
| --fix | 阶段3带自动修复 | 应用自动修复 |
阶段概览
| # | 阶段 | 内容 | 工具 |
|---|
| 1 | 测试套件 | 运行现有测试 + 覆盖率 | pytest --cov / jest --coverage |
| 2 |
导入完整性 | 验证所有模块可加载 | scripts/import_check.py |
| 3 | 静态分析 | 使用合适的工具进行lint检查 | ruff / eslint / gdlint |
| 3.5 | 类型检查 | 静态类型验证 | mypy / tsc --noEmit / (GDScript不适用) |
| 4 | 冒烟测试 | 验证业务逻辑是否正常 | 按项目由AI生成 |
| 5 | UI/前端 | 验证UI组件可加载 | 框架特定 |
| 6 | 文件一致性 | 语法 + git状态 | scripts/syntax_check.py + git |
| 7 | 文档 | 文档字符串 + 文档准确性 | scripts/docstring_check.py |
阶段详情
阶段1:测试套件
运行项目的测试套件并收集覆盖率。自动检测测试运行器:
pytest.ini / pyproject.toml [tool.pytest] → pytest --cov
package.json scripts.test → npm test (或 npx vitest --coverage)
Cargo.toml → cargo test
project.godot → (如果存在GUT则使用,否则手动)
记录: 总数、通过、失败、错误、跳过、持续时间、覆盖率百分比。
判定贡献:
- - 未找到测试 → 跳过(不是失败;项目可能仅为配置项目)
- 失败率 = 0% → 通过
- 失败率 ≤ 阈值(默认5%) → 警告
- 失败率 > 阈值 → 失败
覆盖率报告(Python):
bash
pytest --cov=<包名> --cov-report=term-missing --cov-report=json
阶段2:导入完整性(Python/GDScript)
Python: 对项目根目录运行 scripts/import_check.py。
GDScript: 验证场景/预加载引用是否有效(参见 gdscript-profile.md)。
关键导入与可选导入分类
使用以下启发式规则对导入失败进行分类:
| 模式 | 分类 | 理由 |
|---|
| init.py、main.py、app.py、cli.py | 关键 | 核心入口点 |
| src/、lib/或顶级包中的模块 |
关键 | 核心功能 |
|
test.py、test.py、conftest.py |
可选 | 测试基础设施 |
| examples/、scripts/、tools/中的模块 |
可选 | 辅助代码 |
| 导入错误提及cuml、triton、tensorrt |
可选 | 硬件特定 |
| 导入错误提及缺失的系统库 |
可选 | 环境特定 |
| [project.optional-dependencies]中的依赖 |
可选 | 声明为可选 |
阶段3:静态分析
不要使用grep。 使用该语言的标准linter。
标准模式
bash
Python
ruff check --select E722,T201,B006,F401,F841,UP,I --statistics <项目>
TypeScript
npx eslint . --format json
GDScript
gdlint <项目>
修复模式(--fix)
当指定--fix时,应用自动修正:
bash
Python — 安全自动修复
ruff check --fix --select E,F,I,UP <项目>
ruff format <项目>
TypeScript
npx eslint . --fix
GDScript
gdformat <项目>
重要: 在--fix之后,重新运行检查以报告无法自动修复的剩余问题。
阶段3.5:类型检查(新增)
在进行运行时检查之前,运行静态类型分析。
Python:
bash
mypy <包名> --ignore-missing-imports --no-error-summary
或者如果pyproject.toml中有[tool.pyright]:
pyright <包名>
TypeScript:
bash
npx tsc --noEmit
GDScript: Godot 4具有内置静态类型,但没有独立的检查器。手动估算类型覆盖率:
bash
查找未类型化的声明
grep -rn var \w\+ = --include=*.gd . # 未类型化的变量
grep -rn func \w\+( --include=*.gd . | grep -v : # 未类型化的函数
使用gdscript-profile.md中的estimatetypecoverage()函数计算每个文件的覆盖率:
python
来自gdscript-profile.md
def estimate
typecoverage(gd_file: str) -> float:
计算已类型化与未类型化声明的数量。
# 完整实现请参见gdscript-profile.md
同时检查@warning_ignore注解,这些注解可能隐藏类型问题。
记录: 总错误数,按严重性分类。
阶段4:冒烟测试(业务逻辑)
测试后端/核心功能 — 不是UI组件(那是阶段5)。
API发现启发式规则:
- 1. 入口点: 查找main()、cli()、app、createapp()、main.py
- 服务层: 查找名为Service、Manager、*Handler的类/模块
- 公共API: 检查init.py中的all导出
- FastAPI/Flask: 查找路由装饰器(@app.get、@router.post)
- CLI: 查找typer/click @app.command()装饰器
- SDK: 查找客户端类、不带前缀的公共方法
对于每个发现的API,生成一个最小测试:
python
def smoketestuser_service():
测试UserService基本CRUD。
from myproject.services.user import UserService
svc = UserService(db=:memory:)
user = svc.create(name=test)
assert user.id is not None
fetched = svc.get(user.id)
assert fetched.name == test
return 通过
指南