--- name: openspec-archive description: The post-ship closing step — runs OpenSpec's own archive to fold a shipped change's deltas into the living specs, refreshes the final traceability snapshot, and syncs GSD's STATE.md with what actually shipped. Runs only after ship succeeded; archiving is never a way to make a gate pass. allowed-tools: Read, Write, Edit, Bash, Grep, Glob license: MIT metadata: author: openspec-gsd-integration version: "0.1.0" --- ## Purpose Closing the loop so the *next* change starts from an accurate picture of current truth. An unarchived shipped change leaves `openspec/specs/` describing a system that no longer exists, which silently poisons every later drift audit — class 7 (behavior change without spec delta) is only meaningful if the baseline it diffs against is current. ## Invocation conditions - After `/gsd-ship` has completed successfully — that is, after the `ship:pre` gate passed on `OPENSPEC-VERIFICATION.md` `status: passed` and the ship itself went through. - Directly, `/openspec-archive `, to close out a change shipped before this capability was installed. - **Never** invoked to clear a blocking gate. The gate reads verification status, not archive state, so archiving early cannot unblock anything — but the ordering is stated here explicitly because the brief names "archive before Ship" as a forbidden action. ## Required inputs - The shipped change-id. - Confirmation that ship completed (read from `.planning/STATE.md`, not asserted by the caller). ## Files read - `.planning/STATE.md` (ship record), `.planning/phases/-/-OPENSPEC-VERIFICATION.md` - `.planning/openspec/TRACEABILITY.md`, `EVIDENCE.json` - `openspec/changes//**` ## Files this skill may write - Invokes `openspec archive ` — OpenSpec's own command owns the directory move to `openspec/changes/archive/YYYY-MM-DD-/` and the merge of the change's `ADDED`/`MODIFIED`/`REMOVED` deltas into `openspec/specs/`. This skill never performs that merge by hand. - `.planning/openspec/TRACEABILITY.md` — regenerated one final time via `openspec-traceability` so the archived state has a matching matrix. - `.planning/openspec/EVIDENCE.json` — final entries stamped with the ship commit SHA. - `.planning/STATE.md` — appends which requirement IDs shipped in this release (GSD's own state format; this is the record that answers "what requirements are live in production right now?"). ## Algorithm 1. **Verify ship actually happened.** Read `.planning/STATE.md` for the ship record and `OPENSPEC-VERIFICATION.md` for `status: passed`. If either is missing, stop — this is the guardrail, and it is checked here rather than assumed from the invocation context. 2. **Final traceability refresh.** Run `openspec-traceability` so the matrix reflects the shipped commits, not the pre-ship state. Stamp `EVIDENCE.json` entries with the ship commit SHA — this is what makes the evidence auditable after the working tree moves on. 3. **Archive via OpenSpec.** `openspec archive `. Let OpenSpec's own validation run; if it refuses (e.g. unchecked `tasks.md` items), surface its message verbatim rather than forcing the move. 4. **Sync GSD state.** Append the shipped requirement IDs and their final statuses to `.planning/STATE.md`, and mark the phase's `OPENSPEC-LINK.md` as `archived: true` so a later `discuss:pre` on a new phase does not re-link a closed change. 5. **Report.** What shipped, which requirements it satisfied, where the archived record now lives. ## Outputs - The archived change directory (written by OpenSpec). - Updated living specs under `openspec/specs/` (written by OpenSpec's merge). - Final `TRACEABILITY.md` + `EVIDENCE.json` for the shipped change. - A `.planning/STATE.md` entry naming the requirements now live. ## Failure states - Ship record absent, or verification status is not `passed` → refuse and explain. Archiving is the *consequence* of a successful ship, never a step that manufactures one. - `openspec archive` itself fails validation → report OpenSpec's own error unchanged; do not move directories manually to work around it, and do not check off `tasks.md` items to satisfy it. - Unchecked tasks in `tasks.md` despite a passing verification → this is a genuine inconsistency between the two systems' completion notions; report it as `human_needed` rather than reconciling it silently in either direction. ## Guardrails - Never archives before ship. This is checked, not trusted. - Never edits `tasks.md`, spec text, or verification status to get `openspec archive` to succeed. - Never performs the delta-merge into `openspec/specs/` itself — that is OpenSpec's own logic, and duplicating it here would create exactly the second competing spec system the architecture forbids. - Never deletes evidence on archive. `EVIDENCE.json` is append-only and outlives the change directory precisely so a post-ship audit can still reconstruct what was proven. ## Idempotency Re-running on an already-archived change is a no-op with a clear message (the change directory is gone from `changes/` and present under `changes/archive/`). `STATE.md` entries are keyed by change-id, so a second run does not duplicate the shipped-requirements record. ## Example ``` $ /openspec-archive add-health-check-endpoint [openspec-archive] ship record found (STATE.md, commit a3f91c2) · verification: passed final traceability refresh — 5 rows, 0 unresolved openspec archive add-health-check-endpoint → openspec/changes/archive/2026-07-27-add-health-check-endpoint/ → openspec/specs/health-check/spec.md updated (2 ADDED requirements merged) STATE.md: REQ-HEALTH-001, REQ-HEALTH-002 now live ✓ change closed ```