Agent Development Guidelines¶
Read first¶
- Standards:
docs/DOCUMENTATION_STANDARDS.mddocs/TESTING_STANDARDS.mddocs/CODE_ANALYSIS_STANDARDS.md
Workflow¶
- Understand: read code, trace flows, grep usages, read docs.
- Plan: design around findings.
- Implement: imports at top, types, meaningful docstrings.
- Test:
uv run pytestwith markers. - Configure: add parameters under the correct step in YAML with comments.
- Document: update standards or docstrings when feature‑complete. Avoid standalone reports; strongly focus on integrating findings into existing docs and keeping them up to date.
Collaboration¶
- Present findings in the conversation as Markdown. Do not emit temporary files or heredoc tricks.
- Integrate durable learnings into standards, module comments, or docstrings.
- End each task by archiving insights where future contributors will look.
Package layout¶
- Orchestrator:
pipeline/orchestrator.pyis theviperCLI entry point and coordinates 9 steps. - Steps: Modules are organized by steps 1–9, not by functional themes.
- Templates:
templates/contains default language templates (en_template.py,fr_template.py), Typst config (conf.typ), and assets.phu_templates/is the container for PHU-specific template customizations (gitignored). Templates are loaded dynamically at runtime viabuild_language_renderers()ingenerate_notices.py. The--templateCLI argument expects a template name withinphu_templates/(e.g.,--template wdgph→phu_templates/wdgph/). Template names cannot contain path separators (no nesting). Each template module must define arender_notice()function. Template directory isolation: templates, conf.typ, and assets stay together. Typesetting is separate from orchestration.
Dependencies¶
Single source of truth: uv.lock.
- Code to locked versions. No runtime fallbacks for alternate APIs.
- Upgrades:
pyproject.toml, run uv sync, test, and commit the new lockfile.
Configuration (config/parameters.yaml)¶
- Organize by pipeline step with headers, e.g.,
# Step 3: Generating QR Codes. - Use dot notation and
snake_casekeys, e.g.,qr.enabled,qr.payload_template. - Document inline in YAML.
- Validate quickly:
Code style¶
- Imports at top: future → stdlib → third‑party → local.
- Use type hints, f‑strings, docstrings, dataclasses.
- No wildcard imports.
- Depth and significance guidance lives in
docs/CODE_ANALYSIS_STANDARDS.md.
Quality gates (pre‑commit)¶
One‑time setup:
Manual run:
Hooks (block commits on failure): ruff check --fix then ruff format.
Type checking (ty)¶
Check before tests:
Resolve all type errors or justify with # type: ignore and a short comment.
Command execution discipline¶
Run each shell command once. Investigate before re‑running.
- If you need stderr, include it from the start:
2>&1. - On hangs or failures, inspect state (
git status, file contents) before retrying. - After interruptions, verify outcomes before re‑execution.
Engineering principles¶
Applies at all times. Compatibility posture is noted where behaviour differs before and after 1.0.
- Simplicity first. Prefer straightforward code over abstraction. Use native structures freely. Extract helpers only when they reduce duplication or improve clarity.
- Compatibility note: pre‑1.0 favors rapid simplification with no backward‑compat guarantees. Post‑1.0 preserve public contracts when changing code.
- Clear boundaries and reuse. Colocate helpers with the step that uses them. Extract to
utils.pyonly when reused by ≥2 modules and clarity improves. Prefer pure, side‑effect‑free helpers with action‑oriented names. - Deterministic, step‑isolated pipeline. Steps read inputs from disk and write outputs to disk. Do not pass in‑memory state via the orchestrator. Same input → same output, including ordering and filenames.
- Contracts over defensiveness. Centralize input validation in preprocessing and output checks in dedicated validation steps. Fail fast with precise exceptions. Do not add silent fallbacks.
- Naming and public surface. Functions use
snake_casewith verbs (e.g.,generate_typst_files). Do not rely on leading underscores for privacy; document intent. Only the orchestrator exposes a CLI; no per‑module parsers. - Dependencies are locked. Write to the APIs in
uv.lock. If an API changes, upgrade and re‑lock. Do not branch at runtime to support multiple versions. - Errors and logging. Catch only exceptions you can handle meaningfully. Raise actionable messages. Log at step boundaries and major operations. Informative, not noisy.
- Parallel development without drift. Keep core steps stable (preprocess, notices, compile, validate). Optional steps (encryption, batching, cleanup) may evolve independently if contracts hold. Update tests and docs with any schema or layout change.
- Tests are the spec. Update tests with behavior changes. Use integration tests for quick feedback and E2E tests for coverage. Keep E2E tests project‑root aware.
- Documentation placement. Enduring standards live here and in
docs/. Point‑in‑time analyses and refactor plans live indocs/.- Single canonical working document per initiative. During a feature or refactor effort, maintain one authoritative document (e.g.,
docs/DEFENSIVE_CODE_AND_HELPERS_PLAN.md). Append progress (phases, decisions, status) to that file instead of creating new phase‑specific Markdown files. - Prefer sections like "Status", "Decision Log", and dated "Updates" within the canonical doc over new files such as
PHASE_X_START.mdorPHASE_X_COMPLETION.md. - If interim files were created, integrate their content back into the canonical doc and avoid introducing new ones. Link to historical PRs/commits for provenance rather than duplicating documents.
- Single canonical working document per initiative. During a feature or refactor effort, maintain one authoritative document (e.g.,
Tests: quick reference¶
Setup once:
Run pipeline:
Run tests:
uv run pytest # all
uv run pytest -m unit # unit only (~2s)
uv run pytest -m "not e2e" # skip e2e
uv run pytest tests/e2e/ -v # only e2e
uv run pytest tests/test_file.py::TestClass::test_name -v
Coverage: