Commit files related to a specific Spectra change.
This is a utility skill (not a workflow step). It reads source file tracking data and artifact changes to stage and commit only the files belonging to one change — useful when multiple changes are in progress simultaneously.
Input: Optionally specify a change name after /spectra-commit (e.g., /spectra-commit add-auth). If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.
Prerequisites: This skill requires git. Run git --version. If git is not available (command not found or similar error), inform the user to install git and STOP.
Steps
Select the change
If a name is provided, use it. Otherwise:
- Infer from conversation context if the user mentioned a change
- Auto-select if only one active change exists
- If ambiguous, run
spectra list --json to get available changes. Use the AskUserQuestion tool to let the user select
Always announce: "Committing for change: "
Read tracking file
Check for .spectra/touched/<change-name>.json. If it exists, parse it to get source files grouped by task.
Expected format:
{
"change": "<change-name>",
"touched": [
{
"task_id": "1",
"task_desc": "Task description",
"files": ["src/file1.ts", "src/file2.ts"]
}
]
}
If the file does not exist, proceed without source file data — only artifact files will be included.
Collect artifact files
Run git status --porcelain and filter the output to files under openspec/changes/<name>/. These are the change's artifact files (proposal, design, tasks, specs, etc.).
Identify unrelated dirty files
From the full git status --porcelain output, any dirty files NOT in the artifact set and NOT in the tracking file are "unrelated changes."
Display commit plan
Show the file list grouped into sections:
## Commit Plan: <change-name>
### Change Artifacts
- M openspec/changes/<name>/proposal.md
- M openspec/changes/<name>/tasks.md
### Source Files
**Task 1: <task description>**
- M src/lib/components/search.svelte
- A src/lib/stores/search.ts
**Task 3: <task description>**
- M src/routes/+page.svelte
### Unrelated Changes (not included)
- M src/lib/utils/format.ts
- ?? tmp/scratch.js
If no tracking file was found, show a warning instead of the Source Files section:
### Source Files
⚠ No source file tracking data found.
Only artifact files will be committed. Use `spectra task done` during apply to enable source file tracking.
If there are no artifact files AND no tracked source files, inform the user that there is nothing to commit and STOP.
User confirmation
Use the AskUserQuestion tool to ask the user how to proceed.
Options:
- Commit as shown: Proceed with the displayed artifact + source files
- Include all dirty files: Add all unrelated files to the commit as well
- Customize: Let the user add or remove specific files from the commit set
- Archive first, then commit together: Run archive before committing — archive file moves will be included in this commit
If the user selects "Customize":
- Show a numbered list of all dirty files (included and excluded)
- Ask which files to add or remove
- Re-display the updated commit plan for confirmation
If the user selects "Archive first, then commit together":
- Proceed to step 6a (Archive sub-flow) before continuing to step 7
6a. Archive sub-flow (only when the user selected "Archive first, then commit together")
This sub-flow executes three checks in sequence before returning to the main commit flow.
**6a-i. Incomplete task handling**
If `openspec/changes/<name>/tasks.md` exists, read it and count `- [x]`
(complete) and `- [ ]` (incomplete) checkboxes. If it does not exist, set
the task count to `0/0` and skip to 6a-ii; do not fail the archive flow.
- If **all tasks are complete or no tasks file exists**: skip to 6a-ii.
- If **incomplete tasks exist**:
- Display the list of incomplete tasks
- Use the **AskUserQuestion tool** to ask: "These tasks are still incomplete. Mark all as complete before archiving?"
- **Yes**: set a flag to pass `--mark-tasks-complete` to `spectra archive`
- **No**: proceed without the flag (archive will continue with a warning)
If **AskUserQuestion tool** is not available, ask the same question as plain text and wait for the user's response.
**6a-ii. Delta spec sync check**
Check whether delta specs exist at `openspec/changes/<name>/specs/`.
- If **no delta specs exist** (directory is empty or absent): skip to 6a-iii.
- If **delta specs exist**:
- Use the **AskUserQuestion tool** to ask: "Delta specs found. Sync to main specs before archiving?"
- **Yes**: invoke the repository's `openspec-sync-specs` Skill for
`<name>`, wait for successful synchronization, then archive with
`--skip-specs`
- **No**: archive with `--skip-specs` without syncing
- **Cancel**: stop the workflow immediately; do not archive
If **AskUserQuestion tool** is not available, ask the same question as plain text and wait for the user's response.
**6a-iii. Capture commit metadata before archive**
Before moving the change, read the proposal's Why/Problem/Summary sentence
and count completed and total tasks. Retain those values for step 7; the
active proposal path will no longer exist after a successful archive.
**6a-iv. Archive execution and file collection**
Execute the archive:
```bash
spectra archive <name> --skip-specs # without --mark-tasks-complete
spectra archive <name> --skip-specs --mark-tasks-complete # if user chose to mark tasks complete in 6a-i
```
After archive completes successfully:
1. Re-run `git status --porcelain` to capture all file changes produced by the archive (deletions from `openspec/changes/<name>/`, additions in `openspec/changes/archive/YYYY-MM-DD-<name>/`)
2. Add these archive-related file changes to the commit set
3. Display an **updated commit plan** showing all sections:
```
## Updated Commit Plan: <change-name> (with archive)
### Change Artifacts (archived)
- D openspec/changes/<name>/proposal.md
- D openspec/changes/<name>/tasks.md
- ...
### Archived Files
- A openspec/changes/archive/YYYY-MM-DD-<name>/proposal.md
- A openspec/changes/archive/YYYY-MM-DD-<name>/tasks.md
- ...
### Source Files
(same as before)
### Spec Sync Changes (if sync was performed)
- M openspec/specs/<capability>/spec.md
- ...
```
4. After archive succeeds, remove `.spectra/touched/<change-name>.json` if it exists.
Preserve it when archive fails so the tracking data remains available.
Then continue to step 7.
Generate commit message
Use the proposal summary and task counts captured before archive. Do not read
openspec/changes/<name>/proposal.md after archiving; it has been moved.
Determine one allowed commit type from the change's scope:
feat for new or materially expanded behavior, fix for incorrect behavior
or information, docs for documentation/specification-only changes, and
chore for other maintenance. If the type is genuinely ambiguous, ask the
user to choose. Never use spectra as a commit type.
Generate a message in this format:
<type>: <summary>
Change: <change-name>
Tasks: <completed>/<total> complete
If the archive sub-flow was executed (user selected "Archive first, then commit together"), add Archived: yes to the message body:
<type>: <summary>
Change: <change-name>
Tasks: <completed>/<total> complete
Archived: yes
Task progress comes from reading the tasks file and counting - [x] vs - [ ] checkboxes.
Show the generated message to the user and allow editing before proceeding.
Selective staging
Stage each confirmed file individually:
git add <file1>
git add <file2>
...
NEVER use git add . or git add -A. Each file must be staged explicitly.
Secret preflight
Before committing, run the repository-approved secret scanner described by
the engineering-delivery secret-scanning contract. It must inspect the staged tree
and every commit, tree, and blob that the branch will push relative to the
refreshed remote main; if the scanner lacks a history/range mode, enumerate
each commit patch and its added or modified text/binary content, plus the
complete committed diff and explicitly supplied instruction files. A scanner
failure, missing scanner, or finding stops the workflow before git commit.
Never print credential values.
Commit
git commit -m "<message>"
Show result
git log --oneline -1
Display the commit hash and message to confirm.
Output On Success
## Committed: <change-name>
**Commit:** <short-hash> <type>: <summary>
**Files:** <N> files committed (<A> artifacts, <S> source files)
**Tasks:** <completed>/<total> complete
Output On Nothing To Commit
## Nothing to Commit
**Change:** <change-name>
No dirty files found for this change (no modified artifacts, no tracked source files).
Guardrails
- NEVER use
git add . or git add -A — every file must be staged individually with git add <file>
- NEVER commit files the user hasn't confirmed — always show the file list and get explicit confirmation first
- Always show the full file list before committing — no silent staging
- If the tracking file is missing, warn but don't block — artifact-only commits are valid
- The "Unrelated Changes" section is informational only — these files are excluded by default
- If AskUserQuestion tool is not available, ask the same questions as plain text and wait for the user's response
1---2name: spectra-commit3description: Commit files related to a specific Spectra change4license: MIT5---67Commit files related to a specific Spectra change.89This is a **utility skill** (not a workflow step). It reads source file tracking data and artifact changes to stage and commit only the files belonging to one change — useful when multiple changes are in progress simultaneously.1011**Input**: Optionally specify a change name after `/spectra-commit` (e.g., `/spectra-commit add-auth`). If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.1213**Prerequisites**: This skill requires `git`. Run `git --version`. If git is not available (command not found or similar error), inform the user to install git and STOP.1415**Steps**16171. **Select the change**1819 If a name is provided, use it. Otherwise:20 - Infer from conversation context if the user mentioned a change21 - Auto-select if only one active change exists22 - If ambiguous, run `spectra list --json` to get available changes. Use the **AskUserQuestion tool** to let the user select2324 Always announce: "Committing for change: <name>"25262. **Read tracking file**2728 Check for `.spectra/touched/<change-name>.json`. If it exists, parse it to get source files grouped by task.2930 Expected format:3132 ```json33 {34 "change": "<change-name>",35 "touched": [36 {37 "task_id": "1",38 "task_desc": "Task description",39 "files": ["src/file1.ts", "src/file2.ts"]40 }41 ]42 }43 ```4445 If the file does not exist, proceed without source file data — only artifact files will be included.46473. **Collect artifact files**4849 Run `git status --porcelain` and filter the output to files under `openspec/changes/<name>/`. These are the change's artifact files (proposal, design, tasks, specs, etc.).50514. **Identify unrelated dirty files**5253 From the full `git status --porcelain` output, any dirty files NOT in the artifact set and NOT in the tracking file are "unrelated changes."54555. **Display commit plan**5657 Show the file list grouped into sections:5859 ```60 ## Commit Plan: <change-name>6162 ### Change Artifacts63 - M openspec/changes/<name>/proposal.md64 - M openspec/changes/<name>/tasks.md6566 ### Source Files67 **Task 1: <task description>**68 - M src/lib/components/search.svelte69 - A src/lib/stores/search.ts7071 **Task 3: <task description>**72 - M src/routes/+page.svelte7374 ### Unrelated Changes (not included)75 - M src/lib/utils/format.ts76 - ?? tmp/scratch.js77 ```7879 If no tracking file was found, show a warning instead of the Source Files section:8081 ```82 ### Source Files83 ⚠ No source file tracking data found.84 Only artifact files will be committed. Use `spectra task done` during apply to enable source file tracking.85 ```8687 If there are no artifact files AND no tracked source files, inform the user that there is nothing to commit and STOP.88896. **User confirmation**9091 Use the **AskUserQuestion tool** to ask the user how to proceed.9293 Options:94 - **Commit as shown**: Proceed with the displayed artifact + source files95 - **Include all dirty files**: Add all unrelated files to the commit as well96 - **Customize**: Let the user add or remove specific files from the commit set97 - **Archive first, then commit together**: Run archive before committing — archive file moves will be included in this commit9899 If the user selects "Customize":100 - Show a numbered list of all dirty files (included and excluded)101 - Ask which files to add or remove102 - Re-display the updated commit plan for confirmation103104 If the user selects "Archive first, then commit together":105 - Proceed to step 6a (Archive sub-flow) before continuing to step 71061076a. **Archive sub-flow** (only when the user selected "Archive first, then commit together")108109 This sub-flow executes three checks in sequence before returning to the main commit flow.110111 **6a-i. Incomplete task handling**112113 If `openspec/changes/<name>/tasks.md` exists, read it and count `- [x]`114 (complete) and `- [ ]` (incomplete) checkboxes. If it does not exist, set115 the task count to `0/0` and skip to 6a-ii; do not fail the archive flow.116117 - If **all tasks are complete or no tasks file exists**: skip to 6a-ii.118 - If **incomplete tasks exist**:119 - Display the list of incomplete tasks120 - Use the **AskUserQuestion tool** to ask: "These tasks are still incomplete. Mark all as complete before archiving?"121 - **Yes**: set a flag to pass `--mark-tasks-complete` to `spectra archive`122 - **No**: proceed without the flag (archive will continue with a warning)123124 If **AskUserQuestion tool** is not available, ask the same question as plain text and wait for the user's response.125126 **6a-ii. Delta spec sync check**127128 Check whether delta specs exist at `openspec/changes/<name>/specs/`.129130 - If **no delta specs exist** (directory is empty or absent): skip to 6a-iii.131 - If **delta specs exist**:132 - Use the **AskUserQuestion tool** to ask: "Delta specs found. Sync to main specs before archiving?"133 - **Yes**: invoke the repository's `openspec-sync-specs` Skill for134 `<name>`, wait for successful synchronization, then archive with135 `--skip-specs`136 - **No**: archive with `--skip-specs` without syncing137 - **Cancel**: stop the workflow immediately; do not archive138139 If **AskUserQuestion tool** is not available, ask the same question as plain text and wait for the user's response.140141 **6a-iii. Capture commit metadata before archive**142143 Before moving the change, read the proposal's Why/Problem/Summary sentence144 and count completed and total tasks. Retain those values for step 7; the145 active proposal path will no longer exist after a successful archive.146147 **6a-iv. Archive execution and file collection**148149 Execute the archive:150151 ```bash152 spectra archive <name> --skip-specs # without --mark-tasks-complete153 spectra archive <name> --skip-specs --mark-tasks-complete # if user chose to mark tasks complete in 6a-i154 ```155156 After archive completes successfully:157158 1. Re-run `git status --porcelain` to capture all file changes produced by the archive (deletions from `openspec/changes/<name>/`, additions in `openspec/changes/archive/YYYY-MM-DD-<name>/`)159 2. Add these archive-related file changes to the commit set160 3. Display an **updated commit plan** showing all sections:161162 ```163 ## Updated Commit Plan: <change-name> (with archive)164165 ### Change Artifacts (archived)166 - D openspec/changes/<name>/proposal.md167 - D openspec/changes/<name>/tasks.md168 - ...169170 ### Archived Files171 - A openspec/changes/archive/YYYY-MM-DD-<name>/proposal.md172 - A openspec/changes/archive/YYYY-MM-DD-<name>/tasks.md173 - ...174175 ### Source Files176 (same as before)177178 ### Spec Sync Changes (if sync was performed)179 - M openspec/specs/<capability>/spec.md180 - ...181 ```182183 4. After archive succeeds, remove `.spectra/touched/<change-name>.json` if it exists.184 Preserve it when archive fails so the tracking data remains available.185186 Then continue to step 7.1871887. **Generate commit message**189190 Use the proposal summary and task counts captured before archive. Do not read191 `openspec/changes/<name>/proposal.md` after archiving; it has been moved.192193 Determine one allowed commit type from the change's scope:194 `feat` for new or materially expanded behavior, `fix` for incorrect behavior195 or information, `docs` for documentation/specification-only changes, and196 `chore` for other maintenance. If the type is genuinely ambiguous, ask the197 user to choose. Never use `spectra` as a commit type.198199 Generate a message in this format:200201 ```202 <type>: <summary>203204 Change: <change-name>205 Tasks: <completed>/<total> complete206 ```207208 If the archive sub-flow was executed (user selected "Archive first, then commit together"), add `Archived: yes` to the message body:209210 ```211 <type>: <summary>212213 Change: <change-name>214 Tasks: <completed>/<total> complete215 Archived: yes216 ```217218 Task progress comes from reading the tasks file and counting `- [x]` vs `- [ ]` checkboxes.219220 Show the generated message to the user and allow editing before proceeding.2212228. **Selective staging**223224 Stage each confirmed file individually:225226 ```bash227 git add <file1>228 git add <file2>229 ...230 ```231232 **NEVER use `git add .` or `git add -A`.** Each file must be staged explicitly.2332349. **Secret preflight**235236 Before committing, run the repository-approved secret scanner described by237 the `engineering-delivery` secret-scanning contract. It must inspect the staged tree238 and every commit, tree, and blob that the branch will push relative to the239 refreshed remote `main`; if the scanner lacks a history/range mode, enumerate240 each commit patch and its added or modified text/binary content, plus the241 complete committed diff and explicitly supplied instruction files. A scanner242 failure, missing scanner, or finding stops the workflow before `git commit`.243 Never print credential values.24424510. **Commit**246247 ```bash248 git commit -m "<message>"249 ```25025111. **Show result**252253 ```bash254 git log --oneline -1255 ```256257 Display the commit hash and message to confirm.258259**Output On Success**260261```262## Committed: <change-name>263264**Commit:** <short-hash> <type>: <summary>265**Files:** <N> files committed (<A> artifacts, <S> source files)266**Tasks:** <completed>/<total> complete267```268269**Output On Nothing To Commit**270271```272## Nothing to Commit273274**Change:** <change-name>275276No dirty files found for this change (no modified artifacts, no tracked source files).277```278279**Guardrails**280281- **NEVER use `git add .` or `git add -A`** — every file must be staged individually with `git add <file>`282- **NEVER commit files the user hasn't confirmed** — always show the file list and get explicit confirmation first283- **Always show the full file list before committing** — no silent staging284- If the tracking file is missing, warn but don't block — artifact-only commits are valid285- The "Unrelated Changes" section is informational only — these files are excluded by default286- If **AskUserQuestion tool** is not available, ask the same questions as plain text and wait for the user's response