Code Standards
Engineering foundations for consistent, high-quality code.
Contents
- Critical Rules
- Verification
- Quick Reference
- Topics
- Available Checks
- Naming Conventions
- Test Patterns
Critical Rules
Always
- Use type hints on all public functions
- Validate inputs at trust boundaries
- Deliver rideable increments: complete, useful operator journeys whose breadth is narrow without weakening integrity
- Before substantive edits, including ordinary fixes and regression tests, establish and verify a selected native issue. Load the loaf-reference skill's Flow Semantics for the canonical prerequisite and narrow exceptions, then use the project-management skill for provider operations. Honor an existing explicit implementation request without asking for selection again; an issue in Backlog alone is not selected work.
- Before a final response or handoff, load the project-management skill and apply its Capture Deferred Work rule to concrete deferred or out-of-scope findings; do not leave actionable future work only in prose or the journal.
Never
- Use bare
except:clauses - Log sensitive data or stack traces to users
Verification
After Editing Files
Format Checking:
- For Python files: If
blackis available, runblack --check {files} - For TypeScript/JavaScript files: If
prettieris available, runprettier --check {files} - For Ruby files: If
standardrbis available, runstandardrb --format quiet {files}or ifrubocopis available, runrubocop --format quiet {files} - Auto-fix commands:
- Python:
black {files} - TypeScript/JavaScript:
prettier --write {files} - Ruby:
standardrb --fix {files}orrubocop -a {files}
- Python:
TDD Advisory:
- When editing implementation files (not test/spec files):
- Check if corresponding test file exists
- If no test found, consider Test-Driven Development:
- Write a failing test first
- Then implement the feature
- Run tests until green
- Expected test file patterns:
- Python:
test_{name}.pyor{name}_test.py - TypeScript/JavaScript:
{name}.test.{ext}or{name}.spec.{ext} - Ruby:
spec/{name}_spec.rbortest/{name}_test.rb - Go:
{name}_test.go
- Python:
Before Committing
- Run appropriate formatter on all changed files
- Run linter/type checker for the language
- Verify tests exist for new functionality
- Run test suite if tests were modified
- Ensure CHANGELOG.md is updated if needed
Workflow Notes
- Quick fixes with existing test coverage may skip TDD advisory
- Configuration and generated files don't need tests
- Editor format-on-save helps maintain compliance automatically
Quick Reference
| Context | Python | TypeScript |
|---------|--------|------------|
| Files | snake_case.py | PascalCase.tsx (components) |
| Functions | snake_case | camelCase |
| Classes | PascalCase | PascalCase |
| Constants | UPPER_SNAKE | UPPER_SNAKE |
| Tests | test_<unit>_<scenario>_<result> | describe/it blocks |
Topics
| Topic | Reference | Use When | |-------|-----------|----------| | Code Style | references/code-style.md | Writing Python/TypeScript code, naming variables | | TDD | references/tdd.md | Writing tests first, red/green/refactor cycle | | Verification | references/verification.md | Verifying work before claiming done | | Code Review | references/code-review.md | Requesting or receiving code reviews | | Review | references/review.md | Conducting structured code reviews | | Permissions | references/permissions.md | Configuring tool allowlists, sandbox, agent permissions | | Observability | references/observability.md | Instrumenting services, logging, metrics, tracing | | Production Readiness | references/production-readiness.md | Validating services are ready for production | | Rideable Increments | references/rideable-increments.md | Shaping, implementing, reviewing, or sequencing complete operator journeys |
Available Checks
| Check | Command | Notes |
|-------|---------|-------|
| Commit message | loaf check commit-msg <file> or loaf check commit-msg - | File or stdin. Same conventional-commit engine as loaf check --hook validate-commit. Hook JSON is not accepted. |
| Secrets tree scan | loaf check secrets [dir] | Walks a directory for assignment-style secrets, .env files, and key filenames. Different from the hook payload scan. |
| Micro-changelog | loaf check changelog <file.md> | Document ## Changelog schema. validate-push / workflow-pre-pr do not replace this. |
| Compliance checklist | loaf check compliance <file.md> | Requires every - [ ] box to be checked. A file with no boxes passes. |
| Python test naming | loaf check test-naming [dir] | Real gate for file, function, and fixture names. The former script always exited 0. |
| Legacy ADR | loaf kb validate --legacy-adr <file> | Already native. |
Python style
The former check-python-style.py helper walked the Python AST for type hints, docstrings, bare except:, print(), and logger context fields. A faithful Go port needs a Python parser; this checkpoint does not add that dependency and does not ship a regex stand-in. Use project linters, and enable the mapped rules in project ruff and pyright configuration — they are not implied by a default install:
| Former AST check | Mapped tooling |
|------------------|----------------|
| Public function missing return type hints | ruff ANN201 |
| Public function missing parameter type hints | ruff ANN001 or pyright reportMissingParameterType |
| Public function, method, or class missing docstring | ruff D103, D102, D101 |
| Bare except: | ruff E722 |
| print() instead of structured logging | ruff T201 |
| Logger call without keyword context fields | Skill convention only; no standard ruff/pyright rule |
Naming Conventions
| Context | Python | TypeScript |
|---------|--------|------------|
| Files | snake_case.py | PascalCase.tsx (components) |
| Functions | snake_case | camelCase |
| Classes | PascalCase | PascalCase |
| Constants | UPPER_SNAKE | UPPER_SNAKE |
| Tests | test_<unit>_<scenario>_<result> | describe/it blocks |
Artifact Names Never Cite Their Work Unit
Name an artifact for what it is, never for the work unit that produced it. The directory or Change that contains it already records that provenance, so repeating it in the filename inverts the reference and rots the moment the work closes: a work unit points at its artifacts, artifacts never point back.
| Instead of | Write |
|------------|-------|
| u8-claude-smoke.mjs | smoke-claude-code-startup.mjs |
| report-spec-053-taxonomy-signoff.md | taxonomy-signoff.md |
| TASK-074-sidecar-audit-report.md | sidecar-audit.md |
Provenance belongs in a front-matter field such as source:, where it can be read and updated, not in a name that has to be renamed to stay true.
Two look-alikes are correct and stay. A version is identity, not reference: claude-code-2.1.218-plugin-startup-smoke.json. A timestamp records when, not which work unit: 20260620-214448-skills-audit.md. And a numbered record living in the directory that owns it is that entity, so .agents/specs/SPEC-042-slug.md and docs/decisions/ADR-007-slug.md are its own name rather than a citation.
loaf check --hook artifact-names enforces this at commit time over tracked artifacts, grandfathering anything already final or archived.
Test Patterns
Scenario-based fixture naming:
*_perfect- Complete, valid data (happy path)*_degraded- Partial data, quality issues*_chaos- Edge cases, malformed data
Coverage target: 70% minimum across all components.
Scan to join WeChat group