# Spec-Driven Development ## Overview Every change starts with a spec. No spec, no code. No code, no PR. The spec is a markdown file at `docs/specs/.md` in the repo. It contains structured requirements (REQ-IDs) and acceptance criteria (AC checklist) that CI validates before merge. ## Workflow 1. **Create Vikunja task** — `make create-task -- --title "Title" --description "..."` 2. **Write spec** — Create `docs/specs/.md` (see template below) 3. **Create branch** — `git checkout -b -N-short-description` 4. **Implement** — Write code with `# Implements: REQ-N` comments 5. **Check ACs** — Tick all acceptance criteria checkboxes in the spec 6. **Push and create PR** — `make push-with-pr` 7. **CI validates** — Spec validation, PR size check, fast molecule, lint, tests 8. **Auto-merge** — Add `ready-to-merge` label after review 9. **Auto-deploy** — Post-merge deploys to staging (if nightly gate is green) ## Spec Template ```markdown # : ## Problem <What is broken or missing? Why does this change exist?> ## Approach <How will you solve it? What are the key design decisions?> REQ-1: <First requirement description> REQ-2: <Second requirement description> REQ-3: <Third requirement description> ## Test Plan - <How will you verify each REQ is implemented correctly?> - <Include unit tests, molecule scenarios, integration tests> ## Deploy Plan - <How will this change be deployed?> - <What order do components need to deploy in?> - <Are there migrations or one-time operations?> ## Rollback Plan - <How do you revert if something goes wrong?> - <What data/state changes are irreversible?> ## Acceptance Criteria - [ ] REQ-1: <criterion that proves REQ-1 is done> - [ ] REQ-2: <criterion that proves REQ-2 is done> - [ ] REQ-3: <criterion that proves REQ-3 is done> ``` ## CI Validation The `devx.ci.validate_spec` module checks: 1. **Spec file exists** at `docs/specs/<TASK-ID>.md` (TASK-ID from branch name) 2. **Required sections present**: Problem, Approach, Test Plan, Deploy Plan, Rollback Plan, Acceptance Criteria 3. **At least one REQ-ID** line (format: `REQ-N: <description>`) 4. **All AC checkboxes checked** (`- [x]`, not `- [ ]`) If any check fails, CI blocks the PR before expensive jobs run. ## PR Size Limits CI enforces max 500 lines / 10 files changed (excluding CHANGELOG.md, README.md, badges, lock files). Oversized PRs are rejected. Split your work into smaller PRs. ## Code-to-Spec Linking Each function, task, or template that implements a requirement should have a comment: ```python # Implements: REQ-1 def install_sso_bridge(): ... ``` ```yaml # Implements: REQ-2 - name: Clone infra repo git: ... ``` ## Fast Molecule (Pre-merge) CI runs molecule only for **changed roles** (detected via git diff), with converge + verify only, single platform. This gives quick feedback (~5-10 min) without the full molecule suite. ## Full Molecule (Nightly) The complete molecule suite (all scenarios, all platforms) runs nightly at 02:00 CET on master. If it fails: - A Gitea issue is created with the `feedback` label - The `NIGHTLY_STATUS` repo variable is set to `failed:<run_id>` - All staging deploys are blocked until nightly passes again ## Auto-Deploy on Merge Every merged PR auto-deploys to staging (if nightly gate is green). No manual trigger needed. The deploy runs the full pipeline: provision → deploy-observability → deploy-customer → configure-oidc. For grm/sso-bridge: post-merge publishes the package, then auto-creates an infra PR to bump the pinned version. That infra PR auto-deploys when merged. ## Key Commands ```bash # Validate spec locally (before pushing) python -m devx.ci.validate_spec --branch <PREFIX>-N-description # Check PR size locally python -m devx.ci.check_pr_size --base origin/master --head HEAD # See which roles need fast molecule python -m devx.ci.fast_molecule --base origin/master --head HEAD # Check nightly gate status python -m devx.ci.nightly_gate --repo oblachno/infra --action check ```