diff --git a/.changeset/explore-explicit-write-confirmation.md b/.changeset/explore-explicit-write-confirmation.md new file mode 100644 index 0000000000..cc07a77e23 --- /dev/null +++ b/.changeset/explore-explicit-write-confirmation.md @@ -0,0 +1,5 @@ +--- +'@fission-ai/openspec': patch +--- + +explore: require explicit, scope-bound confirmation before the skill uses any command or tool that can create, edit, move, or delete a file. The explore skill's guardrails let "if the user asks" cover answers to its own clarifying questions, so an agent could treat a design discussion as a go-ahead and start creating schemas or editing `openspec/config.yaml` uninvited. The skill and the `/opsx:explore` command now instruct the agent to name the proposed artifacts or files, ask a direct yes/no question, and wait for confirmation in a separate message before writing. Read-only commands and tools remain available without confirmation, and expanding the confirmed scope requires another confirmation. diff --git a/.changeset/plain-ascii-explore-diagrams.md b/.changeset/plain-ascii-explore-diagrams.md new file mode 100644 index 0000000000..4b6638f960 --- /dev/null +++ b/.changeset/plain-ascii-explore-diagrams.md @@ -0,0 +1,5 @@ +--- +'@fission-ai/openspec': patch +--- + +Draw explore-mode diagrams with plain ASCII. The worked examples in the explore skill and `/opsx:explore` command used Unicode box-drawing, arrow, and marker glyphs, whose display width varies across terminals, fonts, and locales. Agents copied the style, causing padded boxes and aligned tables to drift. diff --git a/skills/openspec-explore/SKILL.md b/skills/openspec-explore/SKILL.md index 327c261489..1e651af4a3 100644 --- a/skills/openspec-explore/SKILL.md +++ b/skills/openspec-explore/SKILL.md @@ -11,7 +11,7 @@ metadata: Enter explore mode. Think deeply. Visualize freely. Follow the conversation wherever it goes. -**IMPORTANT: Explore mode is for thinking, not implementing.** You may read files, search code, and investigate the codebase, but you must NEVER write code or implement features. If the user asks you to implement something, remind them to exit explore mode first and create a change proposal. You MAY create OpenSpec artifacts (proposals, designs, specs) if the user asks—that's capturing thinking, not implementing. For a new change, scaffold it first as described below. +**IMPORTANT: Explore mode is for thinking, not implementing.** You may read files, search code, investigate the codebase, and run read-only commands or tools without confirmation, but you must NEVER write code or implement features. If the user asks you to implement something, remind them to exit explore mode first and create a change proposal. You MAY create or update OpenSpec change artifacts (proposals, designs, specs) within a confirmed scope—that's capturing thinking, not implementing. Answering design or clarifying questions is never consent to write. Before the first write-capable action, name the artifacts or files you would change and what you would do, ask a direct yes/no question, and wait for the user's confirmation in a separate message. Confirmation covers only the scope you described; ask again before expanding it. For a new change, scaffold it first as described below. **This is a stance, not a workflow.** There are no fixed steps, no required sequence, no mandatory outputs. You're a thinking partner helping the user explore. @@ -54,22 +54,25 @@ Depending on what the user brings, you might: **Visualize** ``` -┌─────────────────────────────────────────┐ -│ Use ASCII diagrams liberally │ -├─────────────────────────────────────────┤ -│ │ -│ ┌────────┐ ┌────────┐ │ -│ │ State │────────▶│ State │ │ -│ │ A │ │ B │ │ -│ └────────┘ └────────┘ │ -│ │ -│ System diagrams, state machines, │ -│ data flows, architecture sketches, │ -│ dependency graphs, comparison tables │ -│ │ -└─────────────────────────────────────────┘ ++------------------------------------------+ +| Use ASCII diagrams liberally | ++------------------------------------------+ +| | +| [State A] -------> [State B] | +| | | +| v | +| [State C] | +| | +| System diagrams, state machines, | +| data flows, architecture sketches, | +| dependency graphs, comparison tables | +| | ++------------------------------------------+ ``` +**Draw with plain ASCII only** — borders `+` `-` `|`, arrows `-->` `<--` `^` `v`, markers `*` `x`. +Unicode diagram glyphs can render at different widths across terminals, fonts, and locales, so padded boxes and aligned tables can drift. Keep every diagram character ASCII. + **Surface risks and unknowns** - Identify what could go wrong - Find gaps in understanding @@ -170,17 +173,17 @@ User: I'm thinking about adding real-time collaboration You: Real-time collab is a big space. Let me think about this... COLLABORATION SPECTRUM - ════════════════════════════════════════════ + ============================================ Awareness Coordination Sync - │ │ │ - ▼ ▼ ▼ - ┌────────┐ ┌────────┐ ┌────────┐ - │Presence│ │Cursors │ │ CRDT │ - │ "3 │ │ Multi │ │Conflict│ - │online" │ │ select │ │ free │ - └────────┘ └────────┘ └────────┘ - │ │ │ + | | | + v v v + +--------+ +--------+ +--------+ + |Presence| |Cursors | | CRDT | + | "3 | | Multi | |Conflict| + |online" | | select | | free | + +--------+ +--------+ +--------+ + | | | trivial moderate complex Where's your head at? @@ -192,27 +195,27 @@ User: The auth system is a mess You: [reads codebase] - ┌─────────────────────────────────────────────┐ - │ CURRENT AUTH FLOW │ - └─────────────────────────────────────────────┘ - │ - ┌─────────────┼─────────────┐ - ▼ ▼ ▼ - ┌─────────┐ ┌─────────┐ ┌─────────┐ - │ Google │ │ GitHub │ │ Email │ - │ OAuth │ │ OAuth │ │ Magic │ - └────┬────┘ └────┬────┘ └────┬────┘ - │ │ │ - └─────────────┼─────────────┘ - ▼ - ┌───────────┐ - │ Session │ - └─────┬─────┘ - │ - ▼ - ┌───────────┐ - │ Perms │ - └───────────┘ + +---------------------------------------------+ + | CURRENT AUTH FLOW | + +---------------------------------------------+ + | + +-------------+-------------+ + v v v + +---------+ +---------+ +---------+ + | Google | | GitHub | | Email | + | OAuth | | OAuth | | Magic | + +----+----+ +----+----+ +----+----+ + | | | + +-------------+-------------+ + v + +-----------+ + | Session | + +-----+-----+ + | + v + +-----------+ + | Perms | + +-----------+ I see three tangles. Which one's burning? ``` @@ -244,19 +247,19 @@ User: A CLI tool that tracks local dev environments You: That changes everything. - ┌─────────────────────────────────────────────────┐ - │ CLI TOOL DATA STORAGE │ - └─────────────────────────────────────────────────┘ + +-------------------------------------------------+ + | CLI TOOL DATA STORAGE | + +-------------------------------------------------+ Key constraints: - • No daemon running - • Must work offline - • Single user + - No daemon running + - Must work offline + - Single user SQLite Postgres - Deployment embedded ✓ needs server ✗ - Offline yes ✓ no ✗ - Single file yes ✓ no ✗ + Deployment embedded needs server + Offline yes no + Single file yes no SQLite. Not even close. @@ -296,11 +299,11 @@ But this summary is optional. Sometimes the thinking IS the value. ## Guardrails -- **Don't implement** - Never write code or implement features. Creating OpenSpec artifacts is fine, writing application code is not. +- **Don't implement** - Never write code or implement features. Workflow configuration counts too: creating or editing schemas, templates, or `openspec/config.yaml` is a change, not thinking. Creating or updating OpenSpec change artifacts within the confirmed scope is fine, writing anything else is not. - **Don't fake understanding** - If something is unclear, dig deeper - **Don't rush** - Discovery is thinking time, not task time - **Don't force structure** - Let patterns emerge naturally -- **Don't auto-capture** - Offer to save insights, don't just do it +- **Don't auto-capture** - Offer to save insights, don't just do it. Read-only commands and tools need no confirmation. Before the first write-capable action—including `openspec new change` or another command that writes files—name the artifacts or files and proposed changes, ask a direct yes/no question, and wait for explicit confirmation in a separate user message. That confirmation covers only the described scope; ask again before expanding it. Answers to design or clarifying questions are never consent to write. - **Don't manually scaffold changes** - Never create a new change directory under `openspec/changes/` by hand. Always use `openspec new change ""` (with `--store ` when applicable) so required metadata such as `.openspec.yaml` is created before writing artifacts. - **Do visualize** - A good diagram is worth many paragraphs - **Do explore the codebase** - Ground discussions in reality diff --git a/src/core/templates/workflows/explore.ts b/src/core/templates/workflows/explore.ts index 211de65646..0810ce38fb 100644 --- a/src/core/templates/workflows/explore.ts +++ b/src/core/templates/workflows/explore.ts @@ -13,7 +13,7 @@ export function getExploreSkillTemplate(): SkillTemplate { description: 'Enter explore mode - a thinking partner for exploring ideas, investigating problems, and clarifying requirements. Use when the user wants to think through something before or during a change.', instructions: `Enter explore mode. Think deeply. Visualize freely. Follow the conversation wherever it goes. -**IMPORTANT: Explore mode is for thinking, not implementing.** You may read files, search code, and investigate the codebase, but you must NEVER write code or implement features. If the user asks you to implement something, remind them to exit explore mode first and create a change proposal. You MAY create OpenSpec artifacts (proposals, designs, specs) if the user asks—that's capturing thinking, not implementing. For a new change, scaffold it first as described below. +**IMPORTANT: Explore mode is for thinking, not implementing.** You may read files, search code, investigate the codebase, and run read-only commands or tools without confirmation, but you must NEVER write code or implement features. If the user asks you to implement something, remind them to exit explore mode first and create a change proposal. You MAY create or update OpenSpec change artifacts (proposals, designs, specs) within a confirmed scope—that's capturing thinking, not implementing. Answering design or clarifying questions is never consent to write. Before the first write-capable action, name the artifacts or files you would change and what you would do, ask a direct yes/no question, and wait for the user's confirmation in a separate message. Confirmation covers only the scope you described; ask again before expanding it. For a new change, scaffold it first as described below. **This is a stance, not a workflow.** There are no fixed steps, no required sequence, no mandatory outputs. You're a thinking partner helping the user explore. @@ -56,22 +56,25 @@ Depending on what the user brings, you might: **Visualize** \`\`\` -┌─────────────────────────────────────────┐ -│ Use ASCII diagrams liberally │ -├─────────────────────────────────────────┤ -│ │ -│ ┌────────┐ ┌────────┐ │ -│ │ State │────────▶│ State │ │ -│ │ A │ │ B │ │ -│ └────────┘ └────────┘ │ -│ │ -│ System diagrams, state machines, │ -│ data flows, architecture sketches, │ -│ dependency graphs, comparison tables │ -│ │ -└─────────────────────────────────────────┘ ++------------------------------------------+ +| Use ASCII diagrams liberally | ++------------------------------------------+ +| | +| [State A] -------> [State B] | +| | | +| v | +| [State C] | +| | +| System diagrams, state machines, | +| data flows, architecture sketches, | +| dependency graphs, comparison tables | +| | ++------------------------------------------+ \`\`\` +**Draw with plain ASCII only** — borders \`+\` \`-\` \`|\`, arrows \`-->\` \`<--\` \`^\` \`v\`, markers \`*\` \`x\`. +Unicode diagram glyphs can render at different widths across terminals, fonts, and locales, so padded boxes and aligned tables can drift. Keep every diagram character ASCII. + **Surface risks and unknowns** - Identify what could go wrong - Find gaps in understanding @@ -172,17 +175,17 @@ User: I'm thinking about adding real-time collaboration You: Real-time collab is a big space. Let me think about this... COLLABORATION SPECTRUM - ════════════════════════════════════════════ + ============================================ Awareness Coordination Sync - │ │ │ - ▼ ▼ ▼ - ┌────────┐ ┌────────┐ ┌────────┐ - │Presence│ │Cursors │ │ CRDT │ - │ "3 │ │ Multi │ │Conflict│ - │online" │ │ select │ │ free │ - └────────┘ └────────┘ └────────┘ - │ │ │ + | | | + v v v + +--------+ +--------+ +--------+ + |Presence| |Cursors | | CRDT | + | "3 | | Multi | |Conflict| + |online" | | select | | free | + +--------+ +--------+ +--------+ + | | | trivial moderate complex Where's your head at? @@ -194,27 +197,27 @@ User: The auth system is a mess You: [reads codebase] - ┌─────────────────────────────────────────────┐ - │ CURRENT AUTH FLOW │ - └─────────────────────────────────────────────┘ - │ - ┌─────────────┼─────────────┐ - ▼ ▼ ▼ - ┌─────────┐ ┌─────────┐ ┌─────────┐ - │ Google │ │ GitHub │ │ Email │ - │ OAuth │ │ OAuth │ │ Magic │ - └────┬────┘ └────┬────┘ └────┬────┘ - │ │ │ - └─────────────┼─────────────┘ - ▼ - ┌───────────┐ - │ Session │ - └─────┬─────┘ - │ - ▼ - ┌───────────┐ - │ Perms │ - └───────────┘ + +---------------------------------------------+ + | CURRENT AUTH FLOW | + +---------------------------------------------+ + | + +-------------+-------------+ + v v v + +---------+ +---------+ +---------+ + | Google | | GitHub | | Email | + | OAuth | | OAuth | | Magic | + +----+----+ +----+----+ +----+----+ + | | | + +-------------+-------------+ + v + +-----------+ + | Session | + +-----+-----+ + | + v + +-----------+ + | Perms | + +-----------+ I see three tangles. Which one's burning? \`\`\` @@ -246,19 +249,19 @@ User: A CLI tool that tracks local dev environments You: That changes everything. - ┌─────────────────────────────────────────────────┐ - │ CLI TOOL DATA STORAGE │ - └─────────────────────────────────────────────────┘ + +-------------------------------------------------+ + | CLI TOOL DATA STORAGE | + +-------------------------------------------------+ Key constraints: - • No daemon running - • Must work offline - • Single user + - No daemon running + - Must work offline + - Single user SQLite Postgres - Deployment embedded ✓ needs server ✗ - Offline yes ✓ no ✗ - Single file yes ✓ no ✗ + Deployment embedded needs server + Offline yes no + Single file yes no SQLite. Not even close. @@ -298,11 +301,11 @@ But this summary is optional. Sometimes the thinking IS the value. ## Guardrails -- **Don't implement** - Never write code or implement features. Creating OpenSpec artifacts is fine, writing application code is not. +- **Don't implement** - Never write code or implement features. Workflow configuration counts too: creating or editing schemas, templates, or \`openspec/config.yaml\` is a change, not thinking. Creating or updating OpenSpec change artifacts within the confirmed scope is fine, writing anything else is not. - **Don't fake understanding** - If something is unclear, dig deeper - **Don't rush** - Discovery is thinking time, not task time - **Don't force structure** - Let patterns emerge naturally -- **Don't auto-capture** - Offer to save insights, don't just do it +- **Don't auto-capture** - Offer to save insights, don't just do it. Read-only commands and tools need no confirmation. Before the first write-capable action—including \`openspec new change\` or another command that writes files—name the artifacts or files and proposed changes, ask a direct yes/no question, and wait for explicit confirmation in a separate user message. That confirmation covers only the described scope; ask again before expanding it. Answers to design or clarifying questions are never consent to write. - **Don't manually scaffold changes** - Never create a new change directory under \`openspec/changes/\` by hand. Always use \`openspec new change ""\` (with \`--store \` when applicable) so required metadata such as \`.openspec.yaml\` is created before writing artifacts. - **Do visualize** - A good diagram is worth many paragraphs - **Do explore the codebase** - Ground discussions in reality @@ -321,7 +324,7 @@ export function getOpsxExploreCommandTemplate(): CommandTemplate { tags: ['workflow', 'explore', 'experimental', 'thinking'], content: `Enter explore mode. Think deeply. Visualize freely. Follow the conversation wherever it goes. -**IMPORTANT: Explore mode is for thinking, not implementing.** You may read files, search code, and investigate the codebase, but you must NEVER write code or implement features. If the user asks you to implement something, remind them to exit explore mode first and create a change proposal. You MAY create OpenSpec artifacts (proposals, designs, specs) if the user asks—that's capturing thinking, not implementing. For a new change, scaffold it first as described below. +**IMPORTANT: Explore mode is for thinking, not implementing.** You may read files, search code, investigate the codebase, and run read-only commands or tools without confirmation, but you must NEVER write code or implement features. If the user asks you to implement something, remind them to exit explore mode first and create a change proposal. You MAY create or update OpenSpec change artifacts (proposals, designs, specs) within a confirmed scope—that's capturing thinking, not implementing. Answering design or clarifying questions is never consent to write. Before the first write-capable action, name the artifacts or files you would change and what you would do, ask a direct yes/no question, and wait for the user's confirmation in a separate message. Confirmation covers only the scope you described; ask again before expanding it. For a new change, scaffold it first as described below. **This is a stance, not a workflow.** There are no fixed steps, no required sequence, no mandatory outputs. You're a thinking partner helping the user explore. @@ -371,22 +374,25 @@ Depending on what the user brings, you might: **Visualize** \`\`\` -┌─────────────────────────────────────────┐ -│ Use ASCII diagrams liberally │ -├─────────────────────────────────────────┤ -│ │ -│ ┌────────┐ ┌────────┐ │ -│ │ State │────────▶│ State │ │ -│ │ A │ │ B │ │ -│ └────────┘ └────────┘ │ -│ │ -│ System diagrams, state machines, │ -│ data flows, architecture sketches, │ -│ dependency graphs, comparison tables │ -│ │ -└─────────────────────────────────────────┘ ++------------------------------------------+ +| Use ASCII diagrams liberally | ++------------------------------------------+ +| | +| [State A] -------> [State B] | +| | | +| v | +| [State C] | +| | +| System diagrams, state machines, | +| data flows, architecture sketches, | +| dependency graphs, comparison tables | +| | ++------------------------------------------+ \`\`\` +**Draw with plain ASCII only** — borders \`+\` \`-\` \`|\`, arrows \`-->\` \`<--\` \`^\` \`v\`, markers \`*\` \`x\`. +Unicode diagram glyphs can render at different widths across terminals, fonts, and locales, so padded boxes and aligned tables can drift. Keep every diagram character ASCII. + **Surface risks and unknowns** - Identify what could go wrong - Find gaps in understanding @@ -495,11 +501,11 @@ When things crystallize, you might offer a summary - but it's optional. Sometime ## Guardrails -- **Don't implement** - Never write code or implement features. Creating OpenSpec artifacts is fine, writing application code is not. +- **Don't implement** - Never write code or implement features. Workflow configuration counts too: creating or editing schemas, templates, or \`openspec/config.yaml\` is a change, not thinking. Creating or updating OpenSpec change artifacts within the confirmed scope is fine, writing anything else is not. - **Don't fake understanding** - If something is unclear, dig deeper - **Don't rush** - Discovery is thinking time, not task time - **Don't force structure** - Let patterns emerge naturally -- **Don't auto-capture** - Offer to save insights, don't just do it +- **Don't auto-capture** - Offer to save insights, don't just do it. Read-only commands and tools need no confirmation. Before the first write-capable action—including \`openspec new change\` or another command that writes files—name the artifacts or files and proposed changes, ask a direct yes/no question, and wait for explicit confirmation in a separate user message. That confirmation covers only the described scope; ask again before expanding it. Answers to design or clarifying questions are never consent to write. - **Don't manually scaffold changes** - Never create a new change directory under \`openspec/changes/\` by hand. Always use \`openspec new change ""\` (with \`--store \` when applicable) so required metadata such as \`.openspec.yaml\` is created before writing artifacts. - **Do visualize** - A good diagram is worth many paragraphs - **Do explore the codebase** - Ground discussions in reality diff --git a/test/core/templates/explore.test.ts b/test/core/templates/explore.test.ts index 280077da83..feacf81d7e 100644 --- a/test/core/templates/explore.test.ts +++ b/test/core/templates/explore.test.ts @@ -29,6 +29,25 @@ function occurrenceCount(body: string, value: string): number { return body.split(value).length - 1; } +const NON_ASCII = /[^\x00-\x7F]/; + +function fencedBlockLines(body: string): Array<[number, string]> { + const lines: Array<[number, string]> = []; + let inFence = false; + + body.split('\n').forEach((line, index) => { + if (line.trimStart().startsWith('```')) { + inFence = !inFence; + return; + } + if (inFence) { + lines.push([index + 1, line]); + } + }); + + return lines; +} + describe('explore templates', () => { // Regression for #696: explore never loaded the project's declared // context, so it reasoned without the tech stack, conventions, and @@ -80,6 +99,38 @@ describe('explore templates', () => { } }); + it('requires separate confirmation before any file-writing action (#1715)', () => { + for (const [label, body] of bodies) { + expect(body, label).toContain( + 'Before the first write-capable action' + ); + expect(body, label).toContain('name the artifacts or files you would change'); + expect(body, label).toContain('ask a direct yes/no question'); + expect(body, label).toContain("wait for the user's confirmation in a separate message"); + expect(body, label).toContain( + 'Answering design or clarifying questions is never consent to write' + ); + expect(body, label).toContain('run read-only commands or tools without confirmation'); + expect(body, label).toContain( + 'Confirmation covers only the scope you described; ask again before expanding it' + ); + } + }); + + it('treats workflow configuration and write-capable commands as changes (#1715)', () => { + for (const [label, body] of bodies) { + expect(body, label).toContain( + 'creating or editing schemas, templates, or `openspec/config.yaml` is a change' + ); + expect(body, label).toContain( + 'including `openspec new change` or another command that writes files' + ); + expect(body, label).toContain( + 'Creating or updating OpenSpec change artifacts within the confirmed scope is fine, writing anything else is not' + ); + } + }); + it('scaffolds a new change before capturing exploration artifacts (#668, #720)', () => { for (const [label, body] of bodies) { const transition = newChangeTransition(body, label); @@ -191,6 +242,28 @@ describe('explore templates', () => { } }); + // Regression for #983: the worked examples drew boxes and tables with + // Unicode box-drawing, arrow, and marker glyphs. Agents copy those + // examples verbatim, and on terminals that render the glyphs + // double-width the right border of every padded box drifted loose. + it('draws every fenced example with plain ASCII only (#983)', () => { + for (const [label, body] of bodies) { + const offenders = fencedBlockLines(body) + .filter(([, line]) => NON_ASCII.test(line)) + .map(([lineNumber, line]) => `${lineNumber}: ${line}`); + + expect(offenders, `${label} fenced examples must be pure ASCII`).toEqual([]); + } + }); + + it('tells the agent to draw with ASCII and says why (#983)', () => { + for (const [label, body] of bodies) { + expect(body, label).toContain('**Draw with plain ASCII only**'); + expect(body, label).toContain('render at different widths'); + expect(body, label).toContain('Keep every diagram character ASCII'); + } + }); + it('stops after scaffolding when the user requests only a new change (#668)', () => { for (const [label, body] of bodies) { const transition = newChangeTransition(body, label); diff --git a/test/core/templates/skill-templates-parity.test.ts b/test/core/templates/skill-templates-parity.test.ts index 3860a62eda..c7a8b44b5c 100644 --- a/test/core/templates/skill-templates-parity.test.ts +++ b/test/core/templates/skill-templates-parity.test.ts @@ -38,14 +38,14 @@ import { import { STORE_SELECTION_GUIDANCE } from '../../../src/core/templates/workflows/store-selection.js'; const EXPECTED_FUNCTION_HASHES: Record = { - getExploreSkillTemplate: '3efc37cddf342318ac37be7bb4ff5915f454b4c5bb127294ebdc7534ee21aa23', + getExploreSkillTemplate: 'ecaa0bea4c1cd14eee9dbfcfe4b5808fff4ff808cba0a46789b37c1df3048d9a', getNewChangeSkillTemplate: 'eabd1e895c5881dcb17dcbaa3fb26098dd59e8eacb318e400820b4dc811ef781', getContinueChangeSkillTemplate: '012136f6411a99c8fa228e2f9444cb64b0a89e0f56fdeac2fe03b2f5bee0c5d7', getApplyChangeSkillTemplate: 'd1e7d5ceb85193c0964057dbb88e9651526754bd33f84020e2440ff0621d5dbb', getFfChangeSkillTemplate: '5501740e7ec36ab23ab8c3a0d6dd0655a5e2f35433c7b90e82904fef5e7a326a', getSyncSpecsSkillTemplate: 'b099e2ff31859c9b10d928066e662524f9aad9ecf2be12fceacb732d718c4146', getOnboardSkillTemplate: '3a836faae463d88c289a1c129cb7ee556a563b7e53e1a52a4711ff152a3b51f7', - getOpsxExploreCommandTemplate: 'd2f70d11588f902c15c1e5ce9908cc4124c6b82fe78dc766ac5c3599c9e2a6f1', + getOpsxExploreCommandTemplate: '1460fcb4fbdf22244e9e76608102e611db598cd4cca8c5dbd001292854bcba6e', getOpsxNewCommandTemplate: 'f2d30e569798a4c92ba932859d6ba4e0ad10e18feccbade1cfee0957597b3463', getOpsxContinueCommandTemplate: 'e50e50266efa1b8e64ff9b6274ee8254f0a240d6adc1b862d126e2f1c9d3a559', getOpsxApplyCommandTemplate: 'e3579ac78f2e2c75fa3d3a7ac7dc3e49c395e96f7323398f0f041d94f8de9bb0', @@ -66,7 +66,7 @@ const EXPECTED_FUNCTION_HASHES: Record = { }; const EXPECTED_GENERATED_SKILL_CONTENT_HASHES: Record = { - 'openspec-explore': '4d9736372cc1faf8a5d8a66395a95bf77b9f3fcd2cda40411ad1db6927e8066a', + 'openspec-explore': '886680e71f2900378bd12bb9ff25c888a41a8f851e0bb3ec056affcc18d07ca8', 'openspec-new-change': 'ec4529beef978e34634a6f7286fab55d68fad8fb374dceb45691d52caab33fbb', 'openspec-continue-change': 'bb6194a16c54891cdb253678e8f70ce53b2af86735243980f366ce551d37e42e', 'openspec-apply-change': '81ea96d9fa6ec8536cd23c1fe561ed28e1cc1cad0a8ceb700588e08974cc0e49',