Architecture decision ADR-017

Development lifecycle on OpenSpec, shared across agent tools

Accepted · 2026-10-19

Historical decision text is preserved. Accepted describes the decision, not deployment of every capability discussed. Consult the Architecture and Infrastructure tabs for the verified running system.

Supersedes or amends: ADR-011, ADR-013

Status: Accepted Date: 2026-10-19 Deciders: Daniel Meza Supersedes: the skill-based SDLC portions of ADR-011 and ADR-013. ADR-013's environment and promotion model stays in force. Related: AGENTS.md, openspec/config.yaml, legacy SDLC archive

Context

From May to October 2026 the lifecycle ran on eleven custom Claude Code skills: /feature-creator → /spec-generator → /feature-implementor, bug and hotfix planner/implementor pairs, /code-reviewer, and others. Plans lived in plan/features/ and docs/specs/FEAT-*-plan.md, and each step created or moved a card on an Obsidian Kanban board. Project rules lived in CLAUDE.md, and guardrails were Claude Code hooks.

That worked only in Claude Code. The maintainer now also works in GitHub Copilot, Codex, and OpenCode, none of which can run those skills, read CLAUDE.md, or reach the Obsidian vault.

Decision

Use OpenSpec (spec-driven schema) as the only change workflow, with one shared instruction file and tool-neutral guardrails.

  1. OpenSpec in every tool. The integration files generated by openspec init for Claude Code, Copilot, Codex, and OpenCode are committed and not hand-edited. Project customization lives in openspec/config.yaml (context, per-artifact rules, operations guidance), which every generated workflow reads.
  2. AGENTS.md is the instruction file. CLAUDE.md only imports it (@AGENTS.md).
  3. Change kind by name prefix: hotfix-* → hotfix/<name> from production, fix-* → bug/<name> from main, and anything else → feature/<name> from main. Defect changes start with a failing reproduction test. Hotfixes get a cherry-pick PR to main.
  4. Archive before merge. /opsx:archive runs on the change branch, so one PR carries the code and the openspec/specs/ update. For hotfixes, the cherry-pick carries the spec update to main.
  5. Baseline specs are written lazily. Shipped features have no capability specs yet. The first change that touches an area writes that area's baseline spec.
  6. Guardrails in git and in each tool. husky installs commit-msg (commitlint with the project's nine types) and pre-commit (lint-staged: Prettier, plus ruff when available) on pnpm install. Per-tool permissions: Claude Code hooks and deny rules (unchanged), opencode.json, .codex/config.toml + .codex/rules/safety.rules. Copilot relies on AGENTS.md and its cloud sandbox.
  7. Retired, not deleted. The old skills, plans, handbook, and review checklist moved to docs/archive/legacy-sdlc/. Living contracts (openapi.yaml, schema.sql, interfaces/) stay in docs/specs/.
  8. Dropped: Obsidian Kanban tracking (openspec list is the board) and the code-review step (no replacement for now). Obsidian infra runbooks are unaffected.
  9. copilot-setup-steps.yml is the only GitHub Actions workflow. It only installs the OpenSpec CLI for Copilot's cloud agent and is not a CI gate, so the no-CI stance of ADR-013 holds.

Considered alternatives

Consequences

Positive

Negative / follow-ups