python-code-quality-enforcement
Skill2 starsChanged 5 days agoMITView on GitHub
Python code quality and conventions for forge consumers. Tooling, layouts, coding standards, and security checks for all Python code. Triggers when writing or modifying Python code in a consumer codebase (MCA during coding); NOT for non-Python code or design-level decisions.
- Installs packages
In this repository78 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- adversary-test-planSkill
- api-and-interface-designSkill
- architecture-coherence-reviewSkill
- cavemanSkill
- consistency-checkSkill
- cross-spec-consistency-checkSkill
- deprecation-and-migrationSkill
- documentation-and-adrsSkill
- frontend-design-ttySkill
- frontend-ui-engineeringSkill
- get-api-docsSkill
- impl-plan-reviewSkill
- improve-codebase-architectureSkill
- knowledge-captureSkill
- knowledge-processorSkill
- pre-build-spec-auditSkill
- retroactive-spec-updateSkill
- scopingSkill
- sectional-deep-reviewSkill
- session-diagnosisSkill
- shipping-and-launchSkill
- show-open-tasksSkill
- source-spec-reduceSkill
- spec-authoringSkill
- task-creationSkill
- task-status-updateSkill
- transparency-headerSkill
- ux-authoringSkill
- youtube-subtitlesSkill
- adversary-test-planSkill
- api-and-interface-designSkill
- architecture-coherence-reviewSkill
- bedrock-drillSkill
- bootSkill
- cavemanSkill
- close-retroSkill
- code-review-boardSkill
- consistency-checkSkill
- convergence-loopSkill
- councilSkill
- cross-spec-consistency-checkSkill
- deprecation-and-migrationSkill
- documentation-and-adrsSkill
- frameSkill
- frontend-design-ttySkill
- frontend-ui-engineeringSkill
- get-api-docsSkill
- impl-plan-reviewSkill
- improve-codebase-architectureSkill
- knowledge-captureSkill
- knowledge-processorSkill
- pre-build-spec-auditSkill
- retroactive-spec-updateSkill
- return-summarySkill
- risk-followup-routingSkill
- root-cause-fixSkill
- scopingSkill
- sectional-deep-reviewSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
5 rules. About 0 are common, 1 is distinctive, and 4 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
4
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 17
Read and follow framework/work-principle.md before taking up work.
- Very specific: line 35
Every agent that writes or reviews Python code.
- Distinctive: line 310
No mixing of sync / async in the same module without a clear reason.
- Very specific: line 316
No relative imports (from .models import ...) except in __init__.py.
- Very specific: line 318
Import order (enforced by ruff I):
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Read and follow framework/work-principle.md before taking up work.
Resolve this reference against the framework root; retain the consumer CWD.
Skill: python-code-quality-enforcement
Purpose
Enforce Python code quality and conventions for forge consumers. Defines tooling, layouts, coding standards, and security checks for all Python code in a consumer project.
Inspired by Trail of Bits' modern-python skill. Stack-specific
patterns (broker / DB / multi-tenancy conventions) belong in the
consumer repo's own override files, not in this skill.
Who runs it
Every agent that writes or reviews Python code. Buddy enforces
on delegation (checklist section 8). Primary consumer:
agents/main-code-agent.md.
Triggers
| Trigger | Action |
| New Python code is written | The agent follows these conventions |
| Code review / PR | The reviewer checks against these conventions |
| New package / dependency added | pyproject.toml, no requirements.txt |
1. Project layout
<project>/
pyproject.toml # the only build/dependency definition
src/<project>/ # source root (src layout)
__init__.py
... # consumer-defined package structure
tests/ # tests (mirror of src/<project>/)
unit/
integration/
fixtures/
.venv/ # local virtual environmentRules:
- The
src/layout is required. No flat layout. - One
pyproject.toml— nosetup.py, nosetup.cfg, norequirements.txt. __init__.pyin every package — even when empty.
First-time setup
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"2. Dependency management
pyproject.toml (SoT)
[project]
requires-python = ">=3.12"
dependencies = [...] # runtime deps
[project.optional-dependencies]
dev = [...] # dev/test depsRules
- Every dependency in pyproject.toml. No
requirements.txt, noPipfile. - Version constraints:
>=x.yfor libraries, no==pinning (a lock file owns exact pinning when introduced). - Add a new dependency: under
[project.dependencies]or[project.optional-dependencies.dev]. Then runpip install -e ".[dev]"in the venv. - No global
pip install. Everything in the venv.
Later (when uv is introduced)
uv as a drop-in for pip / venv. Commands:
uv venv .venv # instead of python -m venv
uv pip install -e ".[dev]" # instead of pip install
uv pip compile # generate the lock fileCurrently: standard pip + venv is the baseline. uv when needed (large dependency trees, lock files).
3. Code quality: ruff
ruff is linter + formatter in one. Replaces flake8, black, isort.
Current config (pyproject.toml)
[tool.ruff]
target-version = "py312"
line-length = 120
src = ["src"]
[tool.ruff.lint]
select = ["E", "F", "I", "N", "W", "UP"]Rule sets
| Code | What | Why |
| E | pycodestyle errors | base style |
| F | pyflakes | dead imports, undefined names |
| I | isort | import sorting |
| N | pep8-naming | naming conventions |
| W | pycodestyle warnings | style warnings |
| UP | pyupgrade | use Python 3.12+ syntax |
Extended rules (recommended for service / library code)
select = ["E", "F", "I", "N", "W", "UP", "B", "SIM", "RUF", "ASYNC", "S"]| Code | What | Why |
| B | flake8-bugbear | common bugs (mutable defaults, etc.) |
| SIM | flake8-simplify | constructs that simplify |
| RUF | ruff-specific | ruff's own rules |
| ASYNC | flake8-async | async / await mistakes (relevant for async frameworks) |
| S | bandit (security) | security patterns (eval, exec, hardcoded passwords) |
Caution on activation: existing code can fall foul of stricter
rules (bare except Exception: S110, subprocess.run() in tests
S603/S607). Before activation:
- Run
ruff check --select B,SIM,RUF,ASYNC,S src/ tests/(dry run). - Fix auto-fixable issues:
ruff check --fix --select B,SIM,RUF,ASYNC,S src/. - Review non-auto-fixable issues one by one; if needed,
# noqa: S110with rationale.
Execution
# Lint
.venv/bin/ruff check src/ tests/
# Format
.venv/bin/ruff format src/ tests/
# Fix (auto-fixable issues)
.venv/bin/ruff check --fix src/ tests/ruff runs in the venv (installed via the dev deps). No
global install needed.
4. Testing: pytest
Config (pyproject.toml — SoT)
[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "-n auto --dist loadgroup" # parallel default: skills/testing/lean-suite.md
markers = [
"integration: L3 integration tests (need infra services)",
"e2e: L4 end-to-end tests (need running services)",
"contract: L3 contract tests (need OpenAPI schema)",
"property: L5 property-based tests (hypothesis)",
"smoke: L4 smoke tests (against production endpoints)",
"eval: eval tests (verify hypotheses with code)",
]
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "session"
asyncio_default_test_loop_scope = "session"Note: pyproject.toml is the SoT. When this config and
the real pyproject.toml diverge: adjust pyproject.toml (not
the other way round).
Conventions
- Test files:
test_<module>.py— mirror of the src structure. - Test functions:
test_<what_is_tested>(). - Fixtures: in
conftest.pyat the right level (tests/, tests/unit/, tests/integration/). - Async tests:
async def test_...()— pytest-asyncio in auto mode. - Integration tests: marker
@pytest.mark.integration. Need infra services (DB, broker, etc.). Testcontainers in dev deps when applicable.
Execution
# All unit tests
.venv/bin/pytest tests/unit/
# Integration tests (need Docker)
.venv/bin/pytest tests/integration/ -m integration
# With coverage (src layout: point the path at the package)
.venv/bin/pytest --cov=src/<project> --cov-report=term-missing tests/
# Single test
.venv/bin/pytest tests/unit/test_models.py::test_specific -vTest-pyramid mapping
See skills/testing/SKILL.md for the 6-level pyramid. This
skill defines only the pytest mechanics, not the test
strategy.
5. Security tooling
detect-secrets
Prevents API keys, passwords, tokens from landing in the code.
# Create the baseline
detect-secrets scan > .secrets.baseline
# Audit against the baseline
detect-secrets audit .secrets.baseline.venv/bin/pip install detect-secrets
detect-secrets scan > .secrets.baselinepip-audit
Audits dependencies for known vulnerabilities (CVEs).
.venv/bin/pip-audit.venv/bin/pip install pip-audit6. Stack conventions
Generic Python service patterns. Consumer repos add stack-specific patterns (broker, ORM, multi-tenancy, framework idioms) in their own override files.
Pydantic models
- Shared models in a dedicated package (e.g.
<project>/models/). model_config = ConfigDict(...)instead ofclass Config.- Validators via
@field_validator(Pydantic v2 syntax). - No
from_orm— Pydantic v2 usesmodel_validate.
FastAPI (when used)
- Routers in separate files (one per resource).
- Dependency injection via
Depends(). - Response models explicit:
response_model=.... - No
*imports.
Async / await
- No
asyncio.run()in library code (only in entrypoints). asyncio.to_thread()for blocking I/O (e.g. LLM completion, subprocess).- No mixing of sync / async in the same module without a clear reason.
Imports
- Absolute imports.
- No relative imports (
from .models import ...) except in__init__.py. - Import order (enforced by ruff
I):- stdlib.
- third-party.
- local (
<project>.*).
Logging
structlog(not stdliblogging).- Logger per module:
logger = structlog.get_logger(__name__). - Structured:
logger.info("event_name", key=value)— no f-string in log messages. - Migration: on touching files that still use
import logging, switch tostructlog. No big-bang refactor.
7. What NOT
- No mypy / ty (by default). Pydantic + ruff UP + runtime validation are enough for many service codebases. Evaluate type checkers when the codebase grows. Write type annotations anyway — they serve as documentation and Pydantic uses them at runtime.
- No pre-commit framework. CC hooks are the mechanism for pre-commit checks. A separate pre-commit framework would conflict with that.
- CI / CD optional. Local-first is fine. CI comes when the project needs it.
- No uv (yet). Standard pip + venv is enough at the baseline. uv when needed (large dependency trees, lock files).
8. Checklist on code delegation
Buddy verifies on every code delegation to main-code-agent:
- New code under
src/<project>/(src layout)? - Tests under
tests/(with the right marker)? - Dependencies in
pyproject.toml(not requirements.txt)? ruff check+ruff formatclean?- No secrets in the code (API keys, passwords)?
- Async patterns correct (no
asyncio.runin libraries)? - Structured logging (structlog, not print / logging)?
Common rationalizations
The scan-layer for this discipline skill: the excuses that talk an implementer out of the conventions above. Reject each on sight.
- "It's just a script / one-off — typing and Ruff are overkill." One-offs become imports. Type + lint from line one; the cost is zero, the later retrofit is not.
- "Mypy noise — I'll add
# type: ignoreto move on." An ignore without a code and a reason is silent debt. Narrow it (# type: ignore[code]) or fix the type; never blanket-ignore. - "
printis faster to debug than structlog."printships to prod and loses context. Structured logging is non-negotiable in library/service code. - "Tests later, the feature first." "Later" is the drift the
whole framework exists to prevent. Red test before the fix
(per
adversary_test_plan/testing). - "
asyncio.runinside the library is fine for now." It breaks the moment a caller already has a loop. Libraries expose coroutines; only the entrypoint runs the loop. - "Secret in a constant just for local dev." Local secrets leak
via git history and
--cacheddiffs. Env / secret store only — detect-secrets is a backstop, not a license.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

