Skip to content

refactor: split skill templates into workflow modules#698

Open
TabishB wants to merge 2 commits intomainfrom
codex/split-skill-templates
Open

refactor: split skill templates into workflow modules#698
TabishB wants to merge 2 commits intomainfrom
codex/split-skill-templates

Conversation

@TabishB
Copy link
Contributor

@TabishB TabishB commented Feb 12, 2026

Summary

  • split src/core/templates/skill-templates.ts into workflow-focused modules under src/core/templates/workflows/
  • extract shared template interfaces to src/core/templates/types.ts
  • keep src/core/templates/skill-templates.ts as a compatibility facade re-exporting the existing public API
  • add test/core/templates/skill-templates-parity.test.ts to lock payload and generated-content parity

Validation

  • pnpm build
  • OPENSPEC_TELEMETRY=0 pnpm exec vitest run test/core/templates/skill-templates-parity.test.ts test/core/shared/skill-generation.test.ts

Summary by CodeRabbit

  • New Features

    • Added structured workflow templates for change management: Apply, Archive, Bulk Archive, Continue, Explore, Fast‑Forward, New, Onboard, Sync Specs, Verify, and Feedback.
    • Introduced typed templates for skills and command workflows to standardize template content and metadata.
  • Tests

    • Added parity tests to validate template payloads and generated skill content for consistency.

@1code-async
Copy link
Contributor

1code-async bot commented Feb 12, 2026

Task completed.


PR Review: refactor: split skill templates into workflow modules (#698)

Overall Assessment

This is a clean decomposition of a ~3,500 line monolithic file into 11 focused workflow modules. The approach is sound — keeping skill-templates.ts as a re-export facade preserves backward compatibility while making the codebase more navigable. The parity test with SHA-256 hashing is a strong safeguard against accidental content drift.


Issue: Missing exports in index.ts

Severity: Bug

src/core/templates/index.ts does not re-export three functions that the new facade (skill-templates.ts) exposes:

  • getOnboardSkillTemplate
  • getOpsxOnboardCommandTemplate
  • getFeedbackSkillTemplate

The old index.ts on main was also missing these (so this isn't a regression), but since this PR is explicitly updating the export surface, it's worth fixing now. If any consumer later imports from ../templates/index.js instead of ../templates/skill-templates.js, they'll be missing these functions.

Additionally, index.ts doesn't re-export the SkillTemplate or CommandTemplate types, while the facade does via export type { ... } from './types.js'. This is another gap.

Suggested fix — replace index.ts contents with:

export * from './skill-templates.js';

Or explicitly add the missing entries if you prefer named exports for documentation purposes.


Suggestion: File-specific doc comments instead of generic boilerplate

Every workflow file has the identical header:

/**
 * Skill Template Workflow Modules
 *
 * This file is generated by splitting the legacy monolithic
 * templates file into workflow-focused modules.
 */

This comment is inaccurate per-file (each file isn't "workflow modules" plural, it's one specific workflow), and the "generated by splitting" provenance won't be meaningful to future contributors. Consider either:

  1. Removing the boilerplate entirely (the file name + exports are self-documenting), or
  2. Using file-specific one-liners like:
    /** Explore workflow skill and command templates. */

Suggestion: Consider adding workflows/index.ts

There's no barrel file in workflows/. If other parts of the codebase ever need to import individual workflow modules directly (bypassing the facade), a workflows/index.ts would make that cleaner. This is minor — the facade approach works fine as-is — but it's a common pattern for module directories.


Positive: Onboard module uses a helper function well

In workflows/onboard.ts, the getOnboardInstructions() helper is extracted and shared between both getOnboardSkillTemplate() and getOpsxOnboardCommandTemplate(). This avoids duplicating the large onboarding instructions string. Good pattern.


Positive: Parity test is well-designed

The skill-templates-parity.test.ts file hashes both the raw template payloads and the generated skill content using stableStringify + SHA-256. This is an effective approach that:

  • Detects any accidental content changes during the split
  • Uses deterministic key ordering via stableStringify to avoid false positives from object property order differences
  • Tests both the template data layer and the generation layer

One minor note: the hardcoded hashes act as a snapshot. Future template changes will require updating these hashes, which could be confusing without a comment explaining how to regenerate them. Consider adding a brief comment like:

// To regenerate hashes after intentional template changes:
// 1. Change expected hash values to empty strings
// 2. Run the test to see actual hashes in the error output
// 3. Copy the actual hashes here

Observation: CommandTemplate type unused in feedback.ts

feedback.ts only imports SkillTemplate (not CommandTemplate) and only exports getFeedbackSkillTemplate. This is the only workflow module without a corresponding getOpsx*CommandTemplate function. This seems intentional (feedback doesn't need a slash command), but it's worth confirming that this asymmetry is expected.


Summary

Category Finding
Bug index.ts missing 3 exports + type re-exports vs the facade
Suggestion Replace generic boilerplate comments with file-specific ones
Suggestion Consider workflows/index.ts barrel file
Suggestion Add hash regeneration instructions to parity test
Good onboard.ts shared helper avoids duplication
Good Parity test with stable hashing is solid
Good Facade pattern preserves backward compatibility

View full conversation

Powered by 1Code

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 12, 2026

📝 Walkthrough

Walkthrough

This PR adds core template types and splits a monolithic templates file into multiple workflow-specific modules, providing exported factory functions for SkillTemplate and CommandTemplate objects for twelve workflows, updates the templates re-export surface, and adds parity tests to validate template payloads and generated content.

Changes

Cohort / File(s) Summary
Type Definitions
src/core/templates/types.ts
Adds SkillTemplate and CommandTemplate interfaces, including optional license, compatibility, and metadata fields.
Workflow Templates
src/core/templates/workflows/...
src/core/templates/workflows/apply-change.ts, .../archive-change.ts, .../bulk-archive-change.ts, .../continue-change.ts, .../explore.ts, .../feedback.ts, .../ff-change.ts, .../new-change.ts, .../onboard.ts, .../sync-specs.ts, .../verify-change.ts
Adds per-workflow factory functions that return SkillTemplate and/or CommandTemplate objects (e.g., getXSkillTemplate, getOpsxXCommandTemplate) containing extensive instructions, guardrails, metadata, and command variants for each workflow.
Public export surface
src/core/templates/index.ts
Replaces an explicit named re-export list with export * from './skill-templates.js', changing the module's re-export surface to a wildcard facade.
Tests
test/core/templates/skill-templates-parity.test.ts
Adds Vitest parity tests that compute deterministic SHA‑256 hashes of template factory outputs and generated skill content to ensure payload/content stability.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐇 I hopped through code and found a seam,
Split templates clean — a modular dream.
Skills and commands in tidy rows,
Guardrails set where the wind now blows,
Hooray — the rabbit stamped its feet with glee! 🎉

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the primary refactoring change of splitting monolithic skill templates into focused workflow modules, which aligns with the substantial restructuring across multiple files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codex/split-skill-templates

No actionable comments were generated in the recent review. 🎉


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps
Copy link

greptile-apps bot commented Feb 12, 2026

Greptile Overview

Greptile Summary

This PR splits the monolithic skill-templates.ts (~3,500 lines) into focused workflow modules under src/core/templates/workflows/, with each workflow getting its own file. The original file becomes a compatibility facade that re-exports everything, ensuring backward compatibility.

Key changes

  • Extracted shared types (SkillTemplate, CommandTemplate) to types.ts
  • Split 11 workflows into individual modules (explore, new-change, continue-change, apply-change, ff-change, sync-specs, archive-change, bulk-archive-change, verify-change, onboard, feedback)
  • Maintained exact functionality via re-exports from skill-templates.ts
  • Added comprehensive parity test using hash-based validation to verify no behavior changes

Issues found

  • src/core/templates/index.ts is missing three exports that are present in skill-templates.ts: getOnboardSkillTemplate, getOpsxOnboardCommandTemplate, and getFeedbackSkillTemplate. This creates an inconsistency where some consumers importing from index.ts won't have access to these functions.

Benefits

  • Much better organization - each workflow is now independently maintainable
  • Clearer separation of concerns with consistent file structure
  • Easier to navigate and understand individual workflows
  • No breaking changes due to facade pattern

Confidence Score: 4/5

  • Safe to merge after fixing missing exports in index.ts
  • The refactoring is well-executed with excellent test coverage (hash-based parity tests). The facade pattern ensures backward compatibility. However, the missing exports in index.ts represent a logical error that should be fixed before merging to maintain API consistency.
  • Pay attention to src/core/templates/index.ts - needs the missing exports added

Important Files Changed

Filename Overview
src/core/templates/skill-templates.ts Clean facade that re-exports all workflow modules - maintains backward compatibility
src/core/templates/types.ts Extracted shared template interfaces - proper separation of concerns
test/core/templates/skill-templates-parity.test.ts Comprehensive parity test using hash-based validation to ensure refactor preserves exact behavior
src/core/templates/index.ts Re-exports from skill-templates.ts but missing three exports (getOnboardSkillTemplate, getOpsxOnboardCommandTemplate, getFeedbackSkillTemplate)

Sequence Diagram

sequenceDiagram
    participant Consumer
    participant index.ts
    participant skill-templates.ts
    participant workflows/

    Note over Consumer,workflows/: Before: Monolithic File
    Consumer->>skill-templates.ts: import { getExploreSkillTemplate }
    skill-templates.ts-->>Consumer: return template (3500+ lines)

    Note over Consumer,workflows/: After: Modular Architecture
    Consumer->>skill-templates.ts: import { getExploreSkillTemplate }
    skill-templates.ts->>workflows/: re-export from workflows/explore.js
    workflows/-->>skill-templates.ts: template function
    skill-templates.ts-->>Consumer: return template

    Note over Consumer,index.ts: Alternative Import Path
    Consumer->>index.ts: import { getExploreSkillTemplate }
    index.ts->>skill-templates.ts: re-export
    skill-templates.ts->>workflows/: re-export
    workflows/-->>Consumer: template function
Loading

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

14 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

@greptile-apps
Copy link

greptile-apps bot commented Feb 12, 2026

Additional Comments (1)

src/core/templates/index.ts
Missing exports for getOnboardSkillTemplate, getOpsxOnboardCommandTemplate, and getFeedbackSkillTemplate. These are exported from skill-templates.ts but not re-exported here.

// Re-export skill templates for convenience
export {
  getExploreSkillTemplate,
  getNewChangeSkillTemplate,
  getContinueChangeSkillTemplate,
  getApplyChangeSkillTemplate,
  getFfChangeSkillTemplate,
  getSyncSpecsSkillTemplate,
  getArchiveChangeSkillTemplate,
  getBulkArchiveChangeSkillTemplate,
  getVerifyChangeSkillTemplate,
  getOnboardSkillTemplate,
  getFeedbackSkillTemplate,
  getOpsxExploreCommandTemplate,
  getOpsxNewCommandTemplate,
  getOpsxContinueCommandTemplate,
  getOpsxApplyCommandTemplate,
  getOpsxFfCommandTemplate,
  getOpsxSyncCommandTemplate,
  getOpsxArchiveCommandTemplate,
  getOpsxBulkArchiveCommandTemplate,
  getOpsxVerifyCommandTemplate,
  getOpsxOnboardCommandTemplate,
} from './skill-templates.js';

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@src/core/templates/workflows/feedback.ts`:
- Around line 9-111: The getFeedbackSkillTemplate SkillTemplate factory is
missing the standard fields present in other templates (license, compatibility,
metadata); update the object returned by getFeedbackSkillTemplate to include
license: 'MIT', compatibility: 'Requires openspec CLI.', and metadata: { author:
'openspec', version: '1.0' } so it matches
getOnboardSkillTemplate/getArchiveChangeSkillTemplate/getFfChangeSkillTemplate
conventions and remember this will change the
EXPECTED_FUNCTION_HASHES.getFeedbackSkillTemplate parity test.

In `@src/core/templates/workflows/ff-change.ts`:
- Around line 189-201: The command template's "Artifact Creation Guidelines" in
ff-change.ts is missing the guardrail that `context` and `rules` are constraints
and must not be copied into artifact files; add the same sentence used in the
skill template ("`context` and `rules` are constraints for YOU, not content for
the file — Do NOT copy `<context>`, `<rules>`, `<project_context>` blocks into
the artifact.") into the Artifact Creation Guidelines section of the command
template so it matches the guardrail present in continue-change.ts and the skill
template.

In `@test/core/templates/skill-templates-parity.test.ts`:
- Around line 120-142: Add a brief inline comment above the skillFactories array
explaining that getFeedbackSkillTemplate is intentionally excluded from this
generated-content parity test because feedback is not deployed as a generated
skill file (it is covered in the function-payload parity test); mention the
symbols involved (getFeedbackSkillTemplate, skillFactories,
generateSkillContent) so future readers understand the deliberate omission.
🧹 Nitpick comments (3)
src/core/templates/workflows/explore.ts (1)

298-472: Substantial content duplication between getExploreSkillTemplate and getOpsxExploreCommandTemplate.

The content field in the command template is ~90% identical to the instructions field in the skill template. The onboard.ts module demonstrates a cleaner pattern using a shared getOnboardInstructions() helper to avoid this. Consider extracting shared prose into a helper and interpolating the small differences (e.g., the additional "Input" section in the command template).

This isn't blocking since the parity test locks the output, but it increases maintenance burden for future content changes across all workflow modules that follow this pattern.

src/core/templates/workflows/continue-change.ts (2)

1-6: Nit: Header comment is misleading for ongoing maintenance.

The comment says "This file is generated by splitting the legacy monolithic templates file" — this reads as if it's auto-generated. If these modules will be hand-maintained going forward, consider rewording to avoid confusion (e.g., "Extracted from the legacy monolithic templates file"). This same comment appears in all workflow files.


9-239: Significant content duplication between SkillTemplate.instructions and CommandTemplate.content.

The instructions field (Lines 13–119) and the content field (Lines 132–238) are ~95% identical — roughly 100+ lines of duplicated markdown with only minor differences (input format mentioning /opsx:continue, output prompt wording, and the "all complete" suggestion). This pattern repeats across every workflow file in this PR.

Consider extracting the shared instruction body into a helper and composing the small per-variant deltas. For example:

♻️ Sketch of a shared-content approach
// In a shared helper, e.g., src/core/templates/workflows/_continue-change-content.ts

function baseContinueInstructions(opts: {
  inputLine: string;
  allCompleteMsg: string;
  outputPrompt: string;
}): string {
  return `Continue working on a change by creating the next artifact.

${opts.inputLine}

**Steps**
...shared steps...

   **If all artifacts are complete (\`isComplete: true\`)**:
   ...
   - Suggest: "${opts.allCompleteMsg}"
   ...

**Output**
...
- Prompt: "${opts.outputPrompt}"
...`;
}

This would make future instruction edits less error-prone and reduce the risk of the two variants drifting apart. The same pattern applies to every other workflow module in this PR.

Comment on lines +9 to +111
export function getFeedbackSkillTemplate(): SkillTemplate {
return {
name: 'feedback',
description: 'Collect and submit user feedback about OpenSpec with context enrichment and anonymization.',
instructions: `Help the user submit feedback about OpenSpec.

**Goal**: Guide the user through collecting, enriching, and submitting feedback while ensuring privacy through anonymization.

**Process**

1. **Gather context from the conversation**
- Review recent conversation history for context
- Identify what task was being performed
- Note what worked well or poorly
- Capture specific friction points or praise

2. **Draft enriched feedback**
- Create a clear, descriptive title (single sentence, no "Feedback:" prefix needed)
- Write a body that includes:
- What the user was trying to do
- What happened (good or bad)
- Relevant context from the conversation
- Any specific suggestions or requests

3. **Anonymize sensitive information**
- Replace file paths with \`<path>\` or generic descriptions
- Replace API keys, tokens, secrets with \`<redacted>\`
- Replace company/organization names with \`<company>\`
- Replace personal names with \`<user>\`
- Replace specific URLs with \`<url>\` unless public/relevant
- Keep technical details that help understand the issue

4. **Present draft for approval**
- Show the complete draft to the user
- Display both title and body clearly
- Ask for explicit approval before submitting
- Allow the user to request modifications

5. **Submit on confirmation**
- Use the \`openspec feedback\` command to submit
- Format: \`openspec feedback "title" --body "body content"\`
- The command will automatically add metadata (version, platform, timestamp)

**Example Draft**

\`\`\`
Title: Error handling in artifact workflow needs improvement

Body:
I was working on creating a new change and encountered an issue with
the artifact workflow. When I tried to continue after creating the
proposal, the system didn't clearly indicate that I needed to complete
the specs first.

Suggestion: Add clearer error messages that explain dependency chains
in the artifact workflow. Something like "Cannot create design.md
because specs are not complete (0/2 done)."

Context: Using the spec-driven schema with <path>/my-project
\`\`\`

**Anonymization Examples**

Before:
\`\`\`
Working on /Users/john/mycompany/auth-service/src/oauth.ts
Failed with API key: sk_live_abc123xyz
Working at Acme Corp
\`\`\`

After:
\`\`\`
Working on <path>/oauth.ts
Failed with API key: <redacted>
Working at <company>
\`\`\`

**Guardrails**

- MUST show complete draft before submitting
- MUST ask for explicit approval
- MUST anonymize sensitive information
- ALLOW user to modify draft before submitting
- DO NOT submit without user confirmation
- DO include relevant technical context
- DO keep conversation-specific insights

**User Confirmation Required**

Always ask:
\`\`\`
Here's the feedback I've drafted:

Title: [title]

Body:
[body]

Does this look good? I can modify it if you'd like, or submit it as-is.
\`\`\`

Only proceed with submission after user confirms.`
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Inconsistent with other templates: missing license, compatibility, and metadata fields.

Every other SkillTemplate factory (e.g., getOnboardSkillTemplate, getArchiveChangeSkillTemplate, getFfChangeSkillTemplate) includes license: 'MIT', compatibility: 'Requires openspec CLI.', and metadata: { author: 'openspec', version: '1.0' }. This template omits all three. While the fields are optional, the inconsistency looks unintentional.

Proposed fix
     Only proceed with submission after user confirms.`
+    license: 'MIT',
+    compatibility: 'Requires openspec CLI.',
+    metadata: { author: 'openspec', version: '1.0' },
   };
 }

Note: This will change the hash in the parity test (EXPECTED_FUNCTION_HASHES.getFeedbackSkillTemplate), which will need updating.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export function getFeedbackSkillTemplate(): SkillTemplate {
return {
name: 'feedback',
description: 'Collect and submit user feedback about OpenSpec with context enrichment and anonymization.',
instructions: `Help the user submit feedback about OpenSpec.
**Goal**: Guide the user through collecting, enriching, and submitting feedback while ensuring privacy through anonymization.
**Process**
1. **Gather context from the conversation**
- Review recent conversation history for context
- Identify what task was being performed
- Note what worked well or poorly
- Capture specific friction points or praise
2. **Draft enriched feedback**
- Create a clear, descriptive title (single sentence, no "Feedback:" prefix needed)
- Write a body that includes:
- What the user was trying to do
- What happened (good or bad)
- Relevant context from the conversation
- Any specific suggestions or requests
3. **Anonymize sensitive information**
- Replace file paths with \`<path>\` or generic descriptions
- Replace API keys, tokens, secrets with \`<redacted>\`
- Replace company/organization names with \`<company>\`
- Replace personal names with \`<user>\`
- Replace specific URLs with \`<url>\` unless public/relevant
- Keep technical details that help understand the issue
4. **Present draft for approval**
- Show the complete draft to the user
- Display both title and body clearly
- Ask for explicit approval before submitting
- Allow the user to request modifications
5. **Submit on confirmation**
- Use the \`openspec feedback\` command to submit
- Format: \`openspec feedback "title" --body "body content"\`
- The command will automatically add metadata (version, platform, timestamp)
**Example Draft**
\`\`\`
Title: Error handling in artifact workflow needs improvement
Body:
I was working on creating a new change and encountered an issue with
the artifact workflow. When I tried to continue after creating the
proposal, the system didn't clearly indicate that I needed to complete
the specs first.
Suggestion: Add clearer error messages that explain dependency chains
in the artifact workflow. Something like "Cannot create design.md
because specs are not complete (0/2 done)."
Context: Using the spec-driven schema with <path>/my-project
\`\`\`
**Anonymization Examples**
Before:
\`\`\`
Working on /Users/john/mycompany/auth-service/src/oauth.ts
Failed with API key: sk_live_abc123xyz
Working at Acme Corp
\`\`\`
After:
\`\`\`
Working on <path>/oauth.ts
Failed with API key: <redacted>
Working at <company>
\`\`\`
**Guardrails**
- MUST show complete draft before submitting
- MUST ask for explicit approval
- MUST anonymize sensitive information
- ALLOW user to modify draft before submitting
- DO NOT submit without user confirmation
- DO include relevant technical context
- DO keep conversation-specific insights
**User Confirmation Required**
Always ask:
\`\`\`
Here's the feedback I've drafted:
Title: [title]
Body:
[body]
Does this look good? I can modify it if you'd like, or submit it as-is.
\`\`\`
Only proceed with submission after user confirms.`
};
export function getFeedbackSkillTemplate(): SkillTemplate {
return {
name: 'feedback',
description: 'Collect and submit user feedback about OpenSpec with context enrichment and anonymization.',
instructions: `Help the user submit feedback about OpenSpec.
**Goal**: Guide the user through collecting, enriching, and submitting feedback while ensuring privacy through anonymization.
**Process**
1. **Gather context from the conversation**
- Review recent conversation history for context
- Identify what task was being performed
- Note what worked well or poorly
- Capture specific friction points or praise
2. **Draft enriched feedback**
- Create a clear, descriptive title (single sentence, no "Feedback:" prefix needed)
- Write a body that includes:
- What the user was trying to do
- What happened (good or bad)
- Relevant context from the conversation
- Any specific suggestions or requests
3. **Anonymize sensitive information**
- Replace file paths with \`<path>\` or generic descriptions
- Replace API keys, tokens, secrets with \`<redacted>\`
- Replace company/organization names with \`<company>\`
- Replace personal names with \`<user>\`
- Replace specific URLs with \`<url>\` unless public/relevant
- Keep technical details that help understand the issue
4. **Present draft for approval**
- Show the complete draft to the user
- Display both title and body clearly
- Ask for explicit approval before submitting
- Allow the user to request modifications
5. **Submit on confirmation**
- Use the \`openspec feedback\` command to submit
- Format: \`openspec feedback "title" --body "body content"\`
- The command will automatically add metadata (version, platform, timestamp)
**Example Draft**
\`\`\`
Title: Error handling in artifact workflow needs improvement
Body:
I was working on creating a new change and encountered an issue with
the artifact workflow. When I tried to continue after creating the
proposal, the system didn't clearly indicate that I needed to complete
the specs first.
Suggestion: Add clearer error messages that explain dependency chains
in the artifact workflow. Something like "Cannot create design.md
because specs are not complete (0/2 done)."
Context: Using the spec-driven schema with <path>/my-project
\`\`\`
**Anonymization Examples**
Before:
\`\`\`
Working on /Users/john/mycompany/auth-service/src/oauth.ts
Failed with API key: sk_live_abc123xyz
Working at Acme Corp
\`\`\`
After:
\`\`\`
Working on <path>/oauth.ts
Failed with API key: <redacted>
Working at <company>
\`\`\`
**Guardrails**
- MUST show complete draft before submitting
- MUST ask for explicit approval
- MUST anonymize sensitive information
- ALLOW user to modify draft before submitting
- DO NOT submit without user confirmation
- DO include relevant technical context
- DO keep conversation-specific insights
**User Confirmation Required**
Always ask:
\`\`\`
Here's the feedback I've drafted:
Title: [title]
Body:
[body]
Does this look good? I can modify it if you'd like, or submit it as-is.
\`\`\`
Only proceed with submission after user confirms.`,
license: 'MIT',
compatibility: 'Requires openspec CLI.',
metadata: { author: 'openspec', version: '1.0' },
};
}
🤖 Prompt for AI Agents
In `@src/core/templates/workflows/feedback.ts` around lines 9 - 111, The
getFeedbackSkillTemplate SkillTemplate factory is missing the standard fields
present in other templates (license, compatibility, metadata); update the object
returned by getFeedbackSkillTemplate to include license: 'MIT', compatibility:
'Requires openspec CLI.', and metadata: { author: 'openspec', version: '1.0' }
so it matches
getOnboardSkillTemplate/getArchiveChangeSkillTemplate/getFfChangeSkillTemplate
conventions and remember this will change the
EXPECTED_FUNCTION_HASHES.getFeedbackSkillTemplate parity test.

Comment on lines +189 to +201
**Artifact Creation Guidelines**

- Follow the \`instruction\` field from \`openspec instructions\` for each artifact type
- The schema defines what each artifact should contain - follow it
- Read dependency artifacts for context before creating new ones
- Use the \`template\` as a starting point, filling in based on context

**Guardrails**
- Create ALL artifacts needed for implementation (as defined by schema's \`apply.requires\`)
- Always read dependency artifacts before creating a new one
- If context is critically unclear, ask the user - but prefer making reasonable decisions to keep momentum
- If a change with that name already exists, ask if user wants to continue it or create a new one
- Verify each artifact file exists after writing before proceeding to next`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Missing guardrail about context/rules in the command template's Artifact Creation Guidelines.

The skill template (Lines 93–95) includes a critical guardrail:

context and rules are constraints for YOU, not content for the file — Do NOT copy <context>, <rules>, <project_context> blocks into the artifact.

The command template omits this entirely. Other workflow command templates (e.g., continue-change.ts Lines 236–238) consistently include this guardrail. This looks like an accidental content drift — exactly the risk that arises from maintaining near-duplicate text blocks.

Proposed fix
 **Artifact Creation Guidelines**
 
 - Follow the `instruction` field from `openspec instructions` for each artifact type
 - The schema defines what each artifact should contain - follow it
 - Read dependency artifacts for context before creating new ones
-- Use the \`template\` as a starting point, filling in based on context
+- Use \`template\` as the structure for your output file - fill in its sections
+- **IMPORTANT**: \`context\` and \`rules\` are constraints for YOU, not content for the file
+  - Do NOT copy \`<context>\`, \`<rules>\`, \`<project_context>\` blocks into the artifact
+  - These guide what you write, but should never appear in the output
 
 **Guardrails**
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
**Artifact Creation Guidelines**
- Follow the \`instruction\` field from \`openspec instructions\` for each artifact type
- The schema defines what each artifact should contain - follow it
- Read dependency artifacts for context before creating new ones
- Use the \`template\` as a starting point, filling in based on context
**Guardrails**
- Create ALL artifacts needed for implementation (as defined by schema's \`apply.requires\`)
- Always read dependency artifacts before creating a new one
- If context is critically unclear, ask the user - but prefer making reasonable decisions to keep momentum
- If a change with that name already exists, ask if user wants to continue it or create a new one
- Verify each artifact file exists after writing before proceeding to next`
**Artifact Creation Guidelines**
- Follow the \`instruction\` field from \`openspec instructions\` for each artifact type
- The schema defines what each artifact should contain - follow it
- Read dependency artifacts for context before creating new ones
- Use \`template\` as the structure for your output file - fill in its sections
- **IMPORTANT**: \`context\` and \`rules\` are constraints for YOU, not content for the file
- Do NOT copy \`<context>\`, \`<rules>\`, \`<project_context>\` blocks into the artifact
- These guide what you write, but should never appear in the output
**Guardrails**
- Create ALL artifacts needed for implementation (as defined by schema's \`apply.requires\`)
- Always read dependency artifacts before creating a new one
- If context is critically unclear, ask the user - but prefer making reasonable decisions to keep momentum
- If a change with that name already exists, ask if user wants to continue it or create a new one
- Verify each artifact file exists after writing before proceeding to next
🤖 Prompt for AI Agents
In `@src/core/templates/workflows/ff-change.ts` around lines 189 - 201, The
command template's "Artifact Creation Guidelines" in ff-change.ts is missing the
guardrail that `context` and `rules` are constraints and must not be copied into
artifact files; add the same sentence used in the skill template ("`context` and
`rules` are constraints for YOU, not content for the file — Do NOT copy
`<context>`, `<rules>`, `<project_context>` blocks into the artifact.") into the
Artifact Creation Guidelines section of the command template so it matches the
guardrail present in continue-change.ts and the skill template.

@lsmonki
Copy link

lsmonki commented Feb 14, 2026

Hey @TabishB, great refactoring work here.

I wanted to raise something that connects this PR with the discussion happening on #701 (lifecycle hooks). Right now, all 10 skill templates generate identical instructions regardless of the target agent.

This works today, but it breaks down when you consider that each agent defines its own way of handling hooks, tools, and workflows. Claude Code has PreToolUse/PostToolUse/Stop, Cursor has its own system, Windsurf another, and many agents have no hook system at all. There's no shared capability model — each agent is its own world.

Proposal: Agent Skill Profiles

Would you consider designing these workflow modules with an agent-based profile system in mind? The idea:

The current set of workflow modules becomes the default profile — the universal, agent-agnostic baseline that works for any agent.

Specific agents can define their own agent profile that overrides or extends individual workflow modules to leverage agent-specific features (native hooks, custom tool integrations, etc.).

Resolution is simple: agent-specific module if it exists, otherwise fall back to default

Concretely:

src/core/templates/
  types.ts                          # Add SkillProfile interface
  workflows/                        # Default profile (current, unchanged)
    explore.ts
    apply-change.ts
    ...
  profiles/                         # Agent-specific overrides
    claude-code/
      apply-change.ts               # Uses native PreToolUse/PostToolUse hooks
      archive-change.ts
    cursor/
      apply-change.ts               # Uses Cursor's own hook system
    ...

Each agent 's config would map to a profile ID (or 'default'), and the skill generation in update.ts would resolve templates through the profile chain before generating content.

This doesn't need to be implemented now — I'm just suggesting that the module boundaries you're creating here are the perfect foundation for this pattern. The factory functions per workflow module are exactly the right seam. If designed with this extensibility in mind (e.g., factory functions that accept an optional agent context), it would make the evolution much smoother.
This ties into what we've been discussing in #701 — agent profiles would let us take full advantage of native hooks and tools in agents like Claude Code, while keeping the default portable behavior for agents that don't have those features. Best of both worlds.

What do you think?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants