ss-archive

Merges an active OpenSpec change's delta specs into the authoritative openspec/specs/ tree and moves the change directory into the dated archive. Idempotent; the ss-create-pr skill calls it automatica

SKILL.md

GitHub

Archive OpenSpec Change

Merge OpenSpec delta specs from openspec/changes/<change-id>/specs/ into openspec/specs/, then move the change directory to openspec/changes/archive/YYYY-MM-DD-<change-id>/.

This skill is idempotent. Read delta timing. Archive is authorized pre-review preparation, never a late publication action. --dry-run reports only. A standalone invocation must explicitly authorize mutation. Preserve the stable change-id and gate binding; archive semantic drift invalidates approval/review/tests and returns to the affected gate.

Inputs

Optional: a specific <change-id>, and/or --dry-run to validate and report without writing anything.

Process

Step 1: Discover the Active Change

If a <change-id> was given, use it. Otherwise:

  1. List directories under openspec/changes/, excluding archive/.
  2. If none exist, report a no-op.
  3. If exactly one exists, use it.
  4. If multiple exist, ask the user which one to archive.

If openspec/changes/<change-id>/specs/ has no delta files, report a zero-spec no-op.

Step 2: Verify Workspace and Permission

Inspect intended and unrelated dirty/untracked/ignored files and submodule state. Never stash/reset/discard user work. Materialize identical approved deltas and validate current gate binding before archive. Required rebase is a separately permitted workspace action before review; this skill never fetches/rebases/pushes or commits as a ritual. Unknown ownership or semantic conflicts block archive.

Step 3: Validate Delta Format

For every openspec/changes/<change-id>/specs/<cap>/spec.md:

  • section headings are only ADDED / MODIFIED / REMOVED / RENAMED Requirements
  • every section heading is followed by at least one ### Requirement: entry — remove empty sections entirely
  • every Requirement has at least one #### Scenario:
  • MODIFIED entries copy a matching source-of-truth Requirement in full
  • REMOVED entries include a Reason and a Migration note
  • RENAMED entries use FROM: <old> → TO: <new>

If validation fails, stop and list the exact files and fixes needed.

Step 4: Merge Deltas Into Source-of-Truth Specs

This is a semantic merge, not a mechanical patch — read and understand each delta before writing. For each capability:

  1. Read the delta file.
  2. Read openspec/specs/<cap>/spec.md; if it doesn't exist, create a new source-of-truth spec.
  3. Apply the delta:
    • ADDED: append the new Requirements.
    • MODIFIED: replace the matching Requirement with its full modified content.
    • REMOVED: remove the Requirement, keeping the rationale in the archived delta.
    • RENAMED: rename the Requirement heading, preserving content unless the delta also changes it.
  4. Maintain the source-of-truth header:
# Capability: <capability>

> Source of truth - auto-generated by the `ss-archive` skill from delta merges.
> Do not hand-edit this file. Create a new delta via the `ss-write-spec` skill,
> then merge it with `ss-archive`.

**Last archived change:** <change-id> (<YYYY-MM-DD>)
**Last sync commit:** <sha>

If the file still carries a baseline reverse-spec header (from ss-reverse-spec), remove it after the first successful delta merge.

Step 5: Move to Archive

Unless --dry-run was given:

  1. Create openspec/changes/archive/ if it doesn't exist.
  2. Move the change directory to openspec/changes/archive/<YYYY-MM-DD>-<change-id>/, preserving history if your version control supports move-tracking.
  3. Verify the merged authoritative requirements/scenarios and archived source path; record exact output paths/current bytes in the checkpoint. Commit/push are not archive side effects and require the invoking workflow's explicit permissions.

Output

Report:

  • the archived change path
  • capabilities merged
  • Requirements added / modified / removed / renamed
  • the commit SHA, if committed

No-op cases must be reported explicitly and treated as success.