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. The ss-create-pr skill calls it automatically before opening a
pull request.
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:
- List directories under
openspec/changes/, excludingarchive/. - If none exist, report a no-op.
- If exactly one exists, use it.
- 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: Sync With Git
Check the working tree status.
- If there are uncommitted changes: continue only if they are the intended OpenSpec delta/code changes for this branch. Stop if unrelated files are dirty — never stash, discard, or rewrite the user's work.
- Don't rebase-pull while the worktree is dirty.
- If the worktree is clean, sync first (fetch and rebase against upstream).
- If the worktree is dirty but only contains the intended change, perform the archive merge and commit first, then rebase-pull only if needed before pushing.
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: MODIFIEDentries copy a matching source-of-truth Requirement in fullREMOVEDentries include a Reason and a Migration noteRENAMEDentries useFROM: <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:
- Read the delta file.
- Read
openspec/specs/<cap>/spec.md; if it doesn't exist, create a new source-of-truth spec. - 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.
- 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-plan` skill's Phase 0,
> 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:
- Create
openspec/changes/archive/if it doesn't exist. - Move the change directory to
openspec/changes/archive/<YYYY-MM-DD>-<change-id>/, preserving history if your version control supports move-tracking. - Stage and commit:
chore(spec): archive <change-id>.
Push only if the current branch already has an upstream. If the push fails, report the local commit and leave the retry to the user.
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.