Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/fix-core-workflow-handoffs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@fission-ai/openspec": patch
---

Remove optional continue/new workflow handoffs from update and apply guidance. Missing artifacts now point directly to the existing status/instructions CLI, and intent changes use new change without requiring an installed skill. Preserve update's planning-only scope, store selection, and the core workflow set.

Remove the same unavailable workflow recommendations from runtime apply instructions, including text output. Distinguish missing planning artifacts from missing or empty tracking files so recovery does not require a ready artifact when planning is already complete.
5 changes: 4 additions & 1 deletion skills/openspec-apply-change/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,12 @@ Implement tasks from an OpenSpec change.
- Dynamic instruction based on current state
- Optional `context`: current required project instruction input from the selected root
- Optional `operationGuidance`: current advisory guidance for apply
- `missingArtifacts` (when present): required artifact ids with no output

**Handle states:**
- If `state: "blocked"` (missing artifacts): show message, suggest using `/openspec-continue-change` (if it is not installed, run `openspec status --change "<name>" --json` to see the next artifact and `openspec instructions <artifact-id> --change "<name>" --json` for how to create it)
- If `state: "blocked"`: show the message and pause implementation.
- If `missingArtifacts` is non-empty: suggest completing the missing artifacts. Run `openspec status --change "<name>" --json`, select the next `ready` artifact (not `skipped` or `blocked`), and use `openspec instructions "<artifact-id>" --change "<name>" --json` for its rules and template. Keep the selected `--store <id>` on both commands.
- Otherwise, follow the CLI instruction to create or repair the schema-configured tracking file from existing planning artifacts. Do not assume another artifact is ready or start implementation while blocked.
- If `state: "all_done"`: congratulate, suggest archive
- Otherwise: proceed to implementation

Expand Down
18 changes: 8 additions & 10 deletions skills/openspec-update-change/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ Revise a change's existing planning artifacts and keep them coherent. Never edit

**Input**: Optionally specify a change name. If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.

`/openspec-continue-change` is an optional workflow and may not be installed. Before suggesting it anywhere below, verify that it is available. If it is unavailable, `openspec status --change "<name>" --json` shows the next artifact and `openspec instructions "<artifact-id>" --change "<name>" --json` explains how to create it.

**Steps**

1. **Select the change**
Expand Down Expand Up @@ -58,7 +56,7 @@ Revise a change's existing planning artifacts and keep them coherent. Never edit
- Read the artifact(s) the request touches and the change's other existing artifacts.
- Apply the requested edit. Then check every other existing artifact against it - in ANY direction: an edit to a later artifact may require revising an earlier one, not only the other way around. Build order is a useful reading order, not a constraint on which artifacts may be revised.
- Note everything that is now inconsistent, missing, or contradictory.
- Revise only files that already exist (`existingOutputPaths`). Do NOT create artifacts that don't exist yet, and do NOT invent new files under a glob artifact - note them and point the user to `/openspec-continue-change` to create them.
- Revise only files that already exist (`existingOutputPaths`). Do NOT create artifacts that don't exist yet, and do NOT invent new files under a glob artifact - note them for a separate artifact-creation step using `openspec instructions "<artifact-id>" --change "<name>" --json` for the schema's rules and template.
- If the change is already coherent, say so and make no edits.

5. **Confirm and apply, one artifact at a time**
Expand All @@ -70,21 +68,21 @@ Revise a change's existing planning artifacts and keep them coherent. Never edit
```

6. **Point to the next step (guidance only - NEVER act on it)**
- Artifacts still missing -> suggest `/openspec-continue-change` to create them.
- Change already implemented (tasks checked off / already applied) -> the code may no longer match the revised plan; suggest `/openspec-apply-change` to carry the delta into code.
- Everything done and implemented -> suggest `/openspec-archive-change`.
- Artifacts still missing -> suggest completing them in a separate artifact-creation step: run `openspec status --change "<name>" --json`, select the next `ready` artifact (not `skipped` or `blocked`), and use `openspec instructions "<artifact-id>" --change "<name>" --json` for its rules and template. Keep the selected `--store <id>` on both commands.
- Change already implemented (tasks checked off / already applied) -> the code may no longer match the revised plan; suggest implementing the revised plan in a separate implementation step.
- Everything done and implemented -> suggest archiving the change.

**Output**

After each invocation, show:
- Which artifacts were revised (and which proposed revisions were rejected)
- Anything deferred to `/openspec-continue-change` (not-yet-created artifacts or files)
- Anything deferred to separate artifact creation (not-yet-created artifacts or files)
- Where the change stands and the recommended next command

**Guardrails**
- Planning artifacts only - NEVER edit implementation code. If the revised plan implies code changes, stop and point to `/openspec-apply-change`.
- Planning artifacts only - NEVER edit implementation code. If the revised plan implies code changes, stop and suggest a separate implementation step.
- Use the artifact ids and paths reported by `openspec status`; never branch on hardcoded artifact names.
- Edit only the concrete files in `existingOutputPaths`; never write to a glob `resolvedOutputPath`.
- Do not advance the build frontier: no new artifacts, no new files under glob artifacts - that is `/openspec-continue-change`'s job.
- Do not advance the build frontier: no new artifacts, no new files under glob artifacts - defer them to the separate artifact-creation step described above.
- Confirm every edit with the user before writing.
- If the request changes the change's *intent* rather than refining it, first verify whether the optional `/openspec-new-change` workflow is available. If it is, recommend starting fresh with `/openspec-new-change` (the "Update vs. Start Fresh" heuristic). If it is unavailable, ask for a distinct unused change name and recommend `openspec new change "<new-change-name>"` instead.
- If the request changes the change's *intent* rather than refining it, recommend starting a separate change (the "Update vs. Start Fresh" heuristic). Ask for a distinct unused change name and recommend `openspec new change "<new-change-name>"`; keep the current change unchanged.
10 changes: 4 additions & 6 deletions src/commands/workflow/instructions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -437,18 +437,16 @@ export async function generateApplyInstructions(

if (missingArtifacts.length > 0) {
state = 'blocked';
instruction = `Cannot apply this change yet. Missing artifacts: ${missingArtifacts.join(', ')}.\nUse the openspec-continue-change skill to create the missing artifacts first.`;
instruction = `Cannot apply this change yet. Missing artifacts: ${missingArtifacts.join(', ')}.\nComplete the missing planning artifacts before starting implementation.`;
} else if (tracksFile && !tracksFileExists) {
// Tracking file configured but doesn't exist yet
const tracksFilename = path.basename(tracksFile);
state = 'blocked';
instruction = `The ${tracksFilename} file is missing and must be created.\nUse openspec-continue-change to generate the tracking file.`;
instruction = `The ${tracksFile} tracking file is missing and must be created.\nCreate actionable task checkboxes from the existing planning artifacts before starting implementation.`;
} else if (tracksFile && tracksFileExists && tasks.length === 0) {
// Tracking file exists but lists nothing an agent can work on: either no
// checkboxes at all, or only checkboxes with no text after them.
const tracksFilename = path.basename(tracksFile);
state = 'blocked';
instruction = `The ${tracksFilename} file exists but contains no tasks to work on.\nAdd tasks to ${tracksFilename} or regenerate it with openspec-continue-change.`;
instruction = `The ${tracksFile} tracking file exists but contains no tasks to work on.\nAdd actionable task checkboxes from the existing planning artifacts before starting implementation.`;
} else if (tracksFile && remaining === 0 && total > 0) {
state = 'all_done';
instruction = 'All tasks are complete! This change is ready to be archived.\nConsider running tests and reviewing the changes before archiving.';
Expand Down Expand Up @@ -540,7 +538,7 @@ export function printApplyInstructionsText(instructions: ApplyInstructions): voi
console.log('### ⚠️ Blocked');
console.log();
console.log(`Missing artifacts: ${missingArtifacts.join(', ')}`);
console.log('Use the openspec-continue-change skill to create these first.');
console.log('Complete the missing planning artifacts before starting implementation.');
console.log();
}

Expand Down
5 changes: 4 additions & 1 deletion src/core/templates/workflows/apply-change.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,12 @@ ${STORE_SELECTION_GUIDANCE}
- Dynamic instruction based on current state
- Optional \`context\`: current required project instruction input from the selected root
- Optional \`operationGuidance\`: current advisory guidance for apply
- \`missingArtifacts\` (when present): required artifact ids with no output

**Handle states:**
- If \`state: "blocked"\` (missing artifacts): show message, suggest using \`/opsx:continue\` (if it is not installed, run \`openspec status --change "<name>" --json\` to see the next artifact and \`openspec instructions <artifact-id> --change "<name>" --json\` for how to create it)
- If \`state: "blocked"\`: show the message and pause implementation.
- If \`missingArtifacts\` is non-empty: suggest completing the missing artifacts. Run \`openspec status --change "<name>" --json\`, select the next \`ready\` artifact (not \`skipped\` or \`blocked\`), and use \`openspec instructions "<artifact-id>" --change "<name>" --json\` for its rules and template. Keep the selected \`--store <id>\` on both commands.
- Otherwise, follow the CLI instruction to create or repair the schema-configured tracking file from existing planning artifacts. Do not assume another artifact is ready or start implementation while blocked.
- If \`state: "all_done"\`: congratulate, suggest archive
- Otherwise: proceed to implementation

Expand Down
36 changes: 16 additions & 20 deletions src/core/templates/workflows/update-change.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ ${STORE_SELECTION_GUIDANCE}

**Input**: Optionally specify a change name. If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.

\`/opsx:continue\` is an optional workflow and may not be installed. Before suggesting it anywhere below, verify that it is available. If it is unavailable, \`openspec status --change "<name>" --json\` shows the next artifact and \`openspec instructions "<artifact-id>" --change "<name>" --json\` explains how to create it.

**Steps**

1. **Select the change**
Expand Down Expand Up @@ -60,7 +58,7 @@ ${STORE_SELECTION_GUIDANCE}
- Read the artifact(s) the request touches and the change's other existing artifacts.
- Apply the requested edit. Then check every other existing artifact against it - in ANY direction: an edit to a later artifact may require revising an earlier one, not only the other way around. Build order is a useful reading order, not a constraint on which artifacts may be revised.
- Note everything that is now inconsistent, missing, or contradictory.
- Revise only files that already exist (\`existingOutputPaths\`). Do NOT create artifacts that don't exist yet, and do NOT invent new files under a glob artifact - note them and point the user to \`/opsx:continue\` to create them.
- Revise only files that already exist (\`existingOutputPaths\`). Do NOT create artifacts that don't exist yet, and do NOT invent new files under a glob artifact - note them for a separate artifact-creation step using \`openspec instructions "<artifact-id>" --change "<name>" --json\` for the schema's rules and template.
- If the change is already coherent, say so and make no edits.

5. **Confirm and apply, one artifact at a time**
Expand All @@ -72,24 +70,24 @@ ${STORE_SELECTION_GUIDANCE}
\`\`\`

6. **Point to the next step (guidance only - NEVER act on it)**
- Artifacts still missing -> suggest \`/opsx:continue\` to create them.
- Change already implemented (tasks checked off / already applied) -> the code may no longer match the revised plan; suggest \`/opsx:apply\` to carry the delta into code.
- Everything done and implemented -> suggest \`/opsx:archive\`.
- Artifacts still missing -> suggest completing them in a separate artifact-creation step: run \`openspec status --change "<name>" --json\`, select the next \`ready\` artifact (not \`skipped\` or \`blocked\`), and use \`openspec instructions "<artifact-id>" --change "<name>" --json\` for its rules and template. Keep the selected \`--store <id>\` on both commands.
- Change already implemented (tasks checked off / already applied) -> the code may no longer match the revised plan; suggest implementing the revised plan in a separate implementation step.
- Everything done and implemented -> suggest archiving the change.

**Output**

After each invocation, show:
- Which artifacts were revised (and which proposed revisions were rejected)
- Anything deferred to \`/opsx:continue\` (not-yet-created artifacts or files)
- Anything deferred to separate artifact creation (not-yet-created artifacts or files)
- Where the change stands and the recommended next command

**Guardrails**
- Planning artifacts only - NEVER edit implementation code. If the revised plan implies code changes, stop and point to \`/opsx:apply\`.
- Planning artifacts only - NEVER edit implementation code. If the revised plan implies code changes, stop and suggest a separate implementation step.
- Use the artifact ids and paths reported by \`openspec status\`; never branch on hardcoded artifact names.
- Edit only the concrete files in \`existingOutputPaths\`; never write to a glob \`resolvedOutputPath\`.
- Do not advance the build frontier: no new artifacts, no new files under glob artifacts - that is \`/opsx:continue\`'s job.
- Do not advance the build frontier: no new artifacts, no new files under glob artifacts - defer them to the separate artifact-creation step described above.
- Confirm every edit with the user before writing.
- If the request changes the change's *intent* rather than refining it, first verify whether the optional \`/opsx:new\` workflow is available. If it is, recommend starting fresh with \`/opsx:new\` (the "Update vs. Start Fresh" heuristic). If it is unavailable, ask for a distinct unused change name and recommend \`openspec new change "<new-change-name>"\` instead.`,
- If the request changes the change's *intent* rather than refining it, recommend starting a separate change (the "Update vs. Start Fresh" heuristic). Ask for a distinct unused change name and recommend \`openspec new change "<new-change-name>"\`; keep the current change unchanged.`,
license: 'MIT',
compatibility: 'Requires openspec CLI.',
metadata: { author: 'openspec', version: '1.0' },
Expand All @@ -108,8 +106,6 @@ ${STORE_SELECTION_GUIDANCE}

**Input**: Optionally specify a change name after \`/opsx:update\` (e.g., \`/opsx:update add-auth\`). If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.

\`/opsx:continue\` is an optional workflow and may not be installed. Before suggesting it anywhere below, verify that it is available. If it is unavailable, \`openspec status --change "<name>" --json\` shows the next artifact and \`openspec instructions "<artifact-id>" --change "<name>" --json\` explains how to create it.

**Steps**

1. **Select the change**
Expand Down Expand Up @@ -151,7 +147,7 @@ ${STORE_SELECTION_GUIDANCE}
- Read the artifact(s) the request touches and the change's other existing artifacts.
- Apply the requested edit. Then check every other existing artifact against it - in ANY direction: an edit to a later artifact may require revising an earlier one, not only the other way around. Build order is a useful reading order, not a constraint on which artifacts may be revised.
- Note everything that is now inconsistent, missing, or contradictory.
- Revise only files that already exist (\`existingOutputPaths\`). Do NOT create artifacts that don't exist yet, and do NOT invent new files under a glob artifact - note them and point the user to \`/opsx:continue\` to create them.
- Revise only files that already exist (\`existingOutputPaths\`). Do NOT create artifacts that don't exist yet, and do NOT invent new files under a glob artifact - note them for a separate artifact-creation step using \`openspec instructions "<artifact-id>" --change "<name>" --json\` for the schema's rules and template.
- If the change is already coherent, say so and make no edits.

5. **Confirm and apply, one artifact at a time**
Expand All @@ -163,23 +159,23 @@ ${STORE_SELECTION_GUIDANCE}
\`\`\`

6. **Point to the next step (guidance only - NEVER act on it)**
- Artifacts still missing -> suggest \`/opsx:continue\` to create them.
- Change already implemented (tasks checked off / already applied) -> the code may no longer match the revised plan; suggest \`/opsx:apply\` to carry the delta into code.
- Everything done and implemented -> suggest \`/opsx:archive\`.
- Artifacts still missing -> suggest completing them in a separate artifact-creation step: run \`openspec status --change "<name>" --json\`, select the next \`ready\` artifact (not \`skipped\` or \`blocked\`), and use \`openspec instructions "<artifact-id>" --change "<name>" --json\` for its rules and template. Keep the selected \`--store <id>\` on both commands.
- Change already implemented (tasks checked off / already applied) -> the code may no longer match the revised plan; suggest implementing the revised plan in a separate implementation step.
- Everything done and implemented -> suggest archiving the change.

**Output**

After each invocation, show:
- Which artifacts were revised (and which proposed revisions were rejected)
- Anything deferred to \`/opsx:continue\` (not-yet-created artifacts or files)
- Anything deferred to separate artifact creation (not-yet-created artifacts or files)
- Where the change stands and the recommended next command

**Guardrails**
- Planning artifacts only - NEVER edit implementation code. If the revised plan implies code changes, stop and point to \`/opsx:apply\`.
- Planning artifacts only - NEVER edit implementation code. If the revised plan implies code changes, stop and suggest a separate implementation step.
- Use the artifact ids and paths reported by \`openspec status\`; never branch on hardcoded artifact names.
- Edit only the concrete files in \`existingOutputPaths\`; never write to a glob \`resolvedOutputPath\`.
- Do not advance the build frontier: no new artifacts, no new files under glob artifacts - that is \`/opsx:continue\`'s job.
- Do not advance the build frontier: no new artifacts, no new files under glob artifacts - defer them to the separate artifact-creation step described above.
- Confirm every edit with the user before writing.
- If the request changes the change's *intent* rather than refining it, first verify whether the optional \`/opsx:new\` workflow is available. If it is, recommend starting fresh with \`/opsx:new\` (the "Update vs. Start Fresh" heuristic). If it is unavailable, ask for a distinct unused change name and recommend \`openspec new change "<new-change-name>"\` instead.`
- If the request changes the change's *intent* rather than refining it, recommend starting a separate change (the "Update vs. Start Fresh" heuristic). Ask for a distinct unused change name and recommend \`openspec new change "<new-change-name>"\`; keep the current change unchanged.`
};
}
Loading
Loading