Group G — markdown tech-debt cleanup (post-audit 2026-05-02).
- 36 SKILL.md files: added "## When to use" section. Was missing across the
catalog; orchestrator routing by keyword could not auto-dispatch.
- 20 code-implementer agent .md files: added Output Footer block prescribing
RULE 0.16 STATUS-TRUTH MARKER schema in agent's final report. Previously only
code-implementer-rust.md had it; other 27 language/role variants were silent
about the marker, breaking RULE 0.16 §3 status-truth aggregation for non-Rust
batches.
- skills/site-create/: added phase-5-preview.md and phase-6-deploy.md skeleton
files. SKILL.md table-of-contents referenced 7 phases; only 5 existed on disk.
- skills/{ai-animation,rag-pipeline}/skill.md: added migration banner comment
noting they should be SKILL.md (canonical filename). Case-rename via git is a
separate orchestrator task (macOS APFS is case-insensitive; Linux deploy needs
explicit rename).
- 3 deprecated skills (site-builder, competitor-analysis, design-inspiration):
added concrete removed-after dates (was vague "before v2").
- docs/CONVERGENCE-PLAN.md:129: TBD on _blocks/evidence-grading.md duplicate
resolved (file exists, not duplicated).
- docs/DNA-INDEX.md: count edits made then overwritten by auto-encyclopedia-refresh
hook during agent run. The .kei-registry-ignore files in test fixtures (Group F)
are the structural fix; kei-registry walker implementation is the follow-up.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
136 lines
6.2 KiB
Markdown
136 lines
6.2 KiB
Markdown
---
|
||
name: vm-provision
|
||
description: End-to-end VPS provisioning — select provider → plan → provision → harden → verify (ssh-check + firewall-diff hard-gate) → handoff. 6 phases, ≥6 AskUserQuestion calls, defensive-only. Stops if either verification primitive fails.
|
||
argument-hint: <optional one-line intent, e.g. "staging api hetzner eu">
|
||
---
|
||
|
||
# /vm-provision — 6-Phase VPS Pipeline (index)
|
||
|
||
## When to use
|
||
|
||
- Provisioning a new VPS from scratch: select provider → plan → provision → harden → verify → handoff.
|
||
- Setting up a hardened production or staging server with firewall verification as a hard gate.
|
||
- Any new VM where the security posture (fail2ban, UFW, non-root SSH) must be verified before handoff.
|
||
|
||
You turn a short intent ("staging API in EU") into a **hardened, verified
|
||
VPS** ready to host an app. Six phases. Every provider choice, plan detail,
|
||
and fix is surfaced as an `AskUserQuestion` click — no silent defaults.
|
||
|
||
This `SKILL.md` is the INDEX. Each phase lives in its own file, executed in
|
||
order. Never skip a phase. Never re-order phases.
|
||
|
||
---
|
||
|
||
## Pipeline overview
|
||
|
||
| Phase | File | Purpose | AskUserQuestion |
|
||
|---|---|---|---|
|
||
| 1 | [phase-1-select-provider.md](phase-1-select-provider.md) | Provider + region + plan + ARM/x86 | 2× |
|
||
| 2 | [phase-2-plan.md](phase-2-plan.md) | Plan Mode doc: ports, TLS, admin user | 1× |
|
||
| 3 | [phase-3-provision.md](phase-3-provision.md) | Provision + SSH first contact | 1× |
|
||
| 4 | [phase-4-harden.md](phase-4-harden.md) | Run `harden-base.sh` over SSH | 1× |
|
||
| 5 | [phase-5-verify.md](phase-5-verify.md) | `ssh-check` + `firewall-diff` **HARD GATE** | 1× |
|
||
| 6 | [phase-6-handoff.md](phase-6-handoff.md) | Artifact list + optional `/web-deploy` | — (final report) |
|
||
|
||
**Minimum AskUserQuestion count across a complete pipeline: 6+** — pure-
|
||
click contract. Only the intent argument and per-port customisations are
|
||
typed.
|
||
|
||
---
|
||
|
||
## Hard-Gate Invariant (LOAD-BEARING)
|
||
|
||
> **No application is deployed onto a VM that has not passed BOTH
|
||
> `ssh-check` (exit 0) and `firewall-diff` (exit 0) in Phase 5.**
|
||
|
||
Enforced by Phase 5:
|
||
|
||
- `ssh-check --config /etc/ssh/sshd_config --drop-in /etc/ssh/sshd_config.d` → exit 0.
|
||
- `ufw status numbered | firewall-diff --intent firewall-intent.yaml --stdin` → exit 0.
|
||
- Any non-zero exit → STOP the pipeline; loop back to Phase 4 after the user
|
||
approves a remediation path.
|
||
|
||
The verify step is DEFENSIVE ONLY (read + parse). It never scans the host
|
||
for open CVEs or probes third-party endpoints.
|
||
|
||
---
|
||
|
||
## Variables the pipeline produces
|
||
|
||
| Name | Set in | Meaning |
|
||
|---|---|---|
|
||
| `INTENT` | arg | 1-line user description of the target VM |
|
||
| `PROVIDER` | Phase 1 | hetzner / vultr / digitalocean / upcloud / linode |
|
||
| `REGION` | Phase 1 | provider-specific region code |
|
||
| `PLAN` | Phase 1 | cx22 / cax11 / vc2-1c-1gb / … |
|
||
| `ARCH` | Phase 1 | x86_64 / arm64 |
|
||
| `ADMIN_USER` | Phase 2 | default `keiadmin` |
|
||
| `SSH_PORT` | Phase 2 | default 22; custom permitted |
|
||
| `APP_PORTS` | Phase 2 | e.g. `[443/tcp, 80/tcp]` |
|
||
| `TLS_HOST` | Phase 2 | optional FQDN for Caddy |
|
||
| `VM_IP` | Phase 3 | IPv4 of the created VM |
|
||
| `VM_NAME` | Phase 3 | provider resource label |
|
||
| `HARDENED` | Phase 4 | true when harden-base.sh exited 0 |
|
||
| `SSH_CHECK_OK` | Phase 5 | exit 0 of `ssh-check` |
|
||
| `FW_DIFF_OK` | Phase 5 | exit 0 of `firewall-diff` |
|
||
| `HANDOFF_TO` | Phase 6 | next skill (e.g. `/web-deploy`) or `none` |
|
||
|
||
---
|
||
|
||
## Final report (emit after Phase 6)
|
||
|
||
```
|
||
=== /VM-PROVISION REPORT ===
|
||
Intent: <first 80 chars of INTENT>
|
||
Provider: <PROVIDER> / region=<REGION> / plan=<PLAN> / arch=<ARCH>
|
||
VM: <VM_NAME> @ <VM_IP>
|
||
Admin: <ADMIN_USER> (ssh port <SSH_PORT>)
|
||
Ports: <APP_PORTS>
|
||
TLS: <TLS_HOST or "none">
|
||
Hardened: <HARDENED>
|
||
Verification: ssh-check=<PASS/FAIL> firewall-diff=<PASS/FAIL>
|
||
Handoff: <HANDOFF_TO>
|
||
Artifacts: <terraform state path | cloud-init.yaml path>
|
||
```
|
||
|
||
---
|
||
|
||
## Rules (enforced at every phase)
|
||
|
||
- **Pure-click contract.** Only `INTENT` (argument) and custom port values
|
||
(Phase 2.c) are typed. Every other decision is an `AskUserQuestion`.
|
||
- **Hard gate (Phase 5).** `ssh-check` AND `firewall-diff` must exit 0
|
||
before Phase 6. Neither can be skipped.
|
||
- **RULE -1 NO DOWNGRADE.** Any phase that fails returns 2-3 constructive
|
||
paths, never "can't be done".
|
||
- **RULE 0.8 Secrets Single Source.** All provider tokens come from
|
||
`~/.claude/secrets/.env` (or per-project `secrets/*.env`). NEVER read
|
||
a token from the conversation, NEVER write one to a file.
|
||
- **RULE 0.4 NO HALLUCINATION.** Provider specifics (prices, region codes,
|
||
plan IDs) must be fetched at time of use, not recalled. Cite source.
|
||
- **RULE 0.5 Plan Mode First.** Phase 2 writes the plan; no provisioning
|
||
happens before the user clicks "approve".
|
||
- **Defensive-only.** No scanning tools, no CVE probes, no third-party
|
||
attack surface analysis. Pure config linting.
|
||
- **Surgical changes.** Harden only the VM being provisioned. Never touch
|
||
the caller's workstation config.
|
||
- **Constructor Pattern (RULE ZERO).** Each phase file ≤ 200 LOC;
|
||
generated cloud-init / Caddyfile artefacts never exceed 200 LOC — split
|
||
into role-specific files if they would.
|
||
|
||
---
|
||
|
||
## References
|
||
|
||
- [phase-1-select-provider.md](phase-1-select-provider.md) · [phase-2-plan.md](phase-2-plan.md) · [phase-3-provision.md](phase-3-provision.md) · [phase-4-harden.md](phase-4-harden.md) · [phase-5-verify.md](phase-5-verify.md) · [phase-6-handoff.md](phase-6-handoff.md)
|
||
- `_blocks/deploy-hetzner-cloud.md` — Hetzner Cloud specifics (Phase 1)
|
||
- `_blocks/deploy-vps-generic.md` — provider-agnostic cloud-init + TF skeleton (Phase 1/3)
|
||
- `_blocks/security-ssh-hardening.md` — sshd drop-in baseline (Phase 4/5)
|
||
- `_blocks/security-firewall-ufw.md` — ufw intent schema (Phase 2/5)
|
||
- `_blocks/security-tls-caddy.md` — TLS (Phase 6 handoff)
|
||
- `_blocks/security-audit-logging.md` — auditd baseline (Phase 4)
|
||
- `_blocks/security-patching.md` — unattended-upgrades (Phase 4)
|
||
- `_primitives/provision-hetzner.sh` · `_primitives/provision-vultr.sh` — provisioners (Phase 3)
|
||
- `_primitives/harden-base.sh` — hardening script (Phase 4)
|
||
- `_primitives/_rust/ssh-check/` · `_primitives/_rust/firewall-diff/` — verify gate (Phase 5)
|
||
- `skills/web-deploy/SKILL.md` — optional Phase 6 handoff
|