--- name: spec-driven-infra description: >- OpenSpec spec-driven workflow for infrastructure tasks. category: software-development tags: - openspec - spec-driven - infrastructure - hermata - planning - sdlc --- # Spec-Driven Infrastructure Configuration (OpenSpec for Infra) ## When to Use This Skill - User wants to build/configure infrastructure (homelab, VPS, systemd units, docker-compose services, /opt/ layout) and wants a **spec-first** workflow: decide WHAT before changing anything - User references OpenSpec (https://openspec.dev, repo Fission-AI/OpenSpec) and wants to apply it to infra tasks rather than code tasks - Need: proposal → design → specs (delta) → tasks → implement → archive loop, with the source of truth being main specs - Hermes is the AI assistant driving the workflow (OpenSpec natively supports Hermes) ## Core Concepts OpenSpec = CLI (terminal) + AI assistant skills (chat). The AI does the plan/design/implementation; the CLI validates, lists, archives, and merges delta specs. - `openspec init --tools hermes` → writes 6 skills to `.hermes/skills/openspec-*/SKILL.md` (propose, explore, apply, update, sync, archive). No command adapter for Hermes — invoke by skill name (`/openspec-propose` etc.) - Hermes loads skills from `~/.hermes/skills/` by default. For project-local OpenSpec skills, add the project's `.hermes/skills/` to `skills.external_dirs` in `~/.hermes/config.yaml`: ```bash hermes config set skills.external_dirs '["/opt/hermes/openspec-lab/.hermes/skills"]' ``` - Structure: ``` openspec/ specs//spec.md # source of truth (current behavior) changes// # one folder per proposed change proposal.md # why & what specs//spec.md # DELTA: ADDED / MODIFIED / REMOVED requirements design.md # how (files, commands, rollback) tasks.md # implementation checklist (checkboxes) config.yaml # context + rules injected into AI prompts ``` ## The Loop (proven on infra) ``` /openspec-propose "your infra idea" → creates change + 4 artifacts /openspec-apply-change → implements tasks (checkboxes) /openspec-archive-change → merges delta into main specs, moves to changes/archive/-/ ``` Terminal commands: ```bash openspec init --tools hermes --force --no-animation # or: openspec init --tools hermes openspec new change "" # scaffold a change openspec status --change "" --json # artifact graph, applyRequires, actionContext openspec instructions --change "" --json # per-artifact template + context + rules openspec validate # must pass before archiving openspec archive --yes # merge + move to archive openspec list # active changes openspec schemas --json # available workflow schemas ``` ## Making It Infra-Specific (config.yaml) The default `spec-driven` schema works for infra, but tune `openspec/config.yaml` so the AI produces infra-flavored artifacts: ```yaml schema: spec-driven context: | Домен: self-hosted инфраструктура (homelab / VPS), Linux (Ubuntu/Debian), Docker (docker compose), systemd. Управление: systemd-юниты, docker-compose.yml, конфиги в /opt//; рестарт сервисов — только извне (SSH sudo systemctl restart). Соглашения: отдельный каталог /opt// на сервис; секреты в .env; порты фиксируются в README.md; апдейты через git. rules: proposal: - Указывать затронутые сервисы и порты - Включать план отката (rollback) specs: - Требования в формате MUST/SHOULD/MAY - Сценарии проверки: GIVEN/WHEN/THEN с конкретными командами верификации (systemctl status, curl, docker ps) design: - Указывать конкретные файлы конфигов и юнитов - Включать команды применения и проверки tasks: - Каждая задача — проверяемый шаг с командой верификации ``` - `context` is injected into every artifact instruction (`...`), `rules` per-artifact - The GIVEN/WHEN/THEN + verification-command pattern maps perfectly onto infra: e.g. "WHEN checking connectivity through 127.0.0.1:1080 → THEN curl returns HTTP 200" ## Pitfalls - **Artifact `specs` rules warning:** OpenSpec CLI 1.12.0 prints `Rules for 'specs' must be an array of strings, ignoring this artifact's rules` even when rules are a list of strings. The `specs` artifact is special (multi-file dir); the warning is harmless and context/rules for proposal/design/tasks still work. Don't chase it. - **`archive` requires completed tasks:** `openspec archive ` refuses with incomplete tasks unless `--yes` (and even then warns). Finish/check tasks first: `sed -i 's/^- \[ \]/- [x]/' tasks.md`. - **`--no-init-git` is not a CLI flag** in `openspec init` (v1.12.0). Use `openspec init --tools hermes --force --no-animation` (git init happens by default; acceptable in a lab). - **JSON pipes:** `openspec ... --json` may print warnings to stderr; redirect separately (`> out.json 2> err.txt`). Don't pipe straight into python without checking stderr. - **Skill autocomplete:** skills-only tools (Hermes) never show `/opsx` autocomplete; invoke by full skill name. - **Existing changes:** `openspec new change` with an existing name → ask user whether to continue or create new. - **`skip_specs: true`** in `.openspec.yaml` for pure refactor/docs changes with no behavior delta — `openspec validate` rejects zero-delta changes otherwise. ## Verification Checklist (after a change) ```bash openspec status --change "" # all 4 artifacts done openspec validate "" # valid openspec list # shows active change with task count # after archive: cat openspec/specs//spec.md # delta merged into main spec ls openspec/changes/archive/ # dated archive folder ``` ## Hermes Integration Notes - Install CLI: `npm install -g @fission-ai/openspec@latest` (node 22 present); binary lands at `/opt/hermes/.hermes/node/bin/openspec` - Generated skills have `allowed-tools: Bash(openspec:*)` — the agent runs `openspec ...` in terminal; it does NOT call the CLI as a library - The AI reads per-artifact instructions via `openspec instructions --change --json` and writes files to `resolvedOutputPath` - Test full cycle in a lab dir first (`/opt/hermes/openspec-lab`) before production - Hermes supported Tools table (docs/supported-tools.md) lists Hermes under "skills only" delivery: `.hermes/skills/openspec-*/SKILL.md` ## References & Templates - See `references/openspec-infra-test-2026-09.md` for the full hands-on validation transcript (add-vpn-tunnel-proxy example, config.yaml, commands, outputs) - See `templates/infra-config.yaml` for a ready-to-copy infraOpenSpec config