Apply
Implement tasks from an OpenSpec change. Enforces the pre-apply review gate, creates the feature branch, marks tasks complete, an…
---
name: 'OPSX: Apply'
description: Implement tasks from an OpenSpec change. Enforces the pre-apply review gate, creates the feature branch, marks tasks complete, and updates .opsx-state.json.
category: Workflow
tags: [workflow, artifacts, experimental]
---
Implement tasks from an OpenSpec change. Before touching any code, the command enforces the pre-apply review gate (auto-invoking `/osx:review` on unreviewed changes) so artifacts are known-good before implementation starts.
**Input**: Optionally specify a change name (e.g., `/opsx:apply add-auth`). Infer from context if omitted; prompt via `AskUserQuestion` if ambiguous.
**Steps**
1. **Select the change**
If a name is provided, use it. Otherwise:
- Infer from conversation context if the user mentioned a change
- Auto-select if exactly one active change exists
- If ambiguous, run `openspec list --json` and use **AskUserQuestion** to let the user choose
Always announce: "Using change: <name>".
2. **Check status + load state**
```bash
openspec status --change "<name>" --json
openspec instructions apply --change "<name>" --json
node scripts/opsx/state.mjs read "openspec/changes/<name>"
Parse the CLI outputs for schemaName, contextFiles, and the task list. Read .opsx-state.json for reviewedAt, reviewWaived, appliedAt.
Handle states:
state: "blocked"(missing artifacts) → suggest/opsx:continue, stop.state: "all_done"→ congratulate, suggest/opsx:verify+/opsx:archive, stop.- Otherwise → proceed to the review gate.
Missing .opsx-state.json (legacy change): initialize one via node scripts/opsx/state.mjs init openspec/changes/<name> <name> and continue. Leave reviewedAt: null, reviewWaived: false so the review gate runs.
Enforce the pre-apply review gate
Read
openspec/project.mdverify.archive.require_review_before_applyvianode scripts/opsx/project-config.mjs get verify.archive.require_review_before_apply. Iffalse, skip to step 4.Gate logic:
If
.opsx-state.json.reviewedAtis a non-null ISO timestamp → gate satisfied, skip to step 4.If
.opsx-state.json.reviewWaived === truewithreviewWaiveReasonset → gate waived, log"Pre-apply review waived: <reason>"in chat and skip to step 4.Otherwise → auto-invoke
/osx:reviewon the change artifacts:- Use the
Skilltool withosx-review-artifacts(orosx:review), passing the change name. - Copy
openspec/templates/review-report.mdtoopenspec/changes/<name>/review-report.mdif missing. - Fill the report with the review output (Scorecard, Artifact Findings by severity, Fixes Applied During Review, Deferred Artifact Work, Readiness, Next Step).
- Run
node scripts/opsx/review-report-lint.mjs openspec/changes/<name>/review-report.md. Abort on lint failure with the diagnostic. - Patch state:
node scripts/opsx/state.mjs set "openspec/changes/<name>" '{ "reviewedAt": "<ISO-8601 now>" }'
- Use the
Blocking on CRITICAL review findings: if the resulting
review-report.mdhas one or more CRITICAL entries under## Artifact Findings, refuse to proceed, print the findings, and suggest/osx:modify <name>to address them. Do NOT mark tasks complete, do NOT create a branch.Create the feature branch (only on first-time apply — detect by
.opsx-state.json.appliedAt === nullAND current branch ismain)git fetch origin git checkout -b "feat/<change-name>" --no-track origin/mainUpstream is NOT set here —
/opsx:archivesets it viagit push -u origin <branch>at archive time.Read context files and show progress
Read every file in
contextFilesfrom the apply instructions. Display:- Schema
- Progress:
N/M tasks complete - Remaining task titles
- Dynamic instruction from CLI
Implement tasks (loop until done or blocked)
For each pending task:
- Announce which task is next
- Make the minimum code change the task calls for
- Mark
- [ ]→- [x]intasks.mdimmediately after the edits land - Continue
On the first
[x]flip in this session, patch state:node scripts/opsx/state.mjs set "openspec/changes/<name>" '{ "appliedAt": "<ISO-8601 now>" }'Only do this if
appliedAtis currently null (don't overwrite a real timestamp from a prior session).Pause if:
- Task wording is unclear → ask for clarification.
- Implementation reveals a design issue → suggest updating artifacts.
- Any error or unexpected state → report and wait for guidance.
- User interrupts.
Commit and push — mandatory on completion, skip on pause
When the last task flips to
[x](all 44/44 complete or however the total lands) AND the working tree is in a clean, runnable state, the apply flow MUST commit and push. Do not ask the user — this is the default, the user can revert if they disagree. Only skip on pause (blocker, unclear requirement, user interrupt).Sequence:
- Run
git status+git diffvia the Bash tool to see the full set of changes. - Run the code-reviewer subagent on the full diff (per project CLAUDE.md and user feedback-memory "Code reviewer mandatory"). Surface findings in chat.
- If reviewer returns CRITICAL or HIGH: address inline, then re-run reviewer on the updated diff.
- MEDIUM / LOW: include in commit body or defer to verify-report — do NOT block the commit for them.
- Stage files explicitly by path (never
git add -A/git add .— per user feedback-memory "Clean tree before PR"). Include the change-directory edits (tasks.md, review-report.md,.opsx-state.json), all source/manifest/workflow/docs edits, and any ancillary files touched (e.g., ADR index updates, manual-check recipes, lint script updates). - Compose a Conventional Commit (per repo convention: `type(scope): desc
- Run
Maintain Apply?
Let people know it's listed here — add the badge (live metrics, light/dark aware) or a plain link to your README or docs.
[Apply on getagentictools](https://getagentictools.com/loops/igonzalezespi-apply?ref=badge)