Skip to content

fix(instructions): separate context and rules from template in JSON output#547

Merged
TabishB merged 2 commits intomainfrom
fix/separate-context-rules-from-template
Jan 21, 2026
Merged

fix(instructions): separate context and rules from template in JSON output#547
TabishB merged 2 commits intomainfrom
fix/separate-context-rules-from-template

Conversation

@TabishB
Copy link
Contributor

@TabishB TabishB commented Jan 21, 2026

Summary

  • Fixes a bug where project config context and rules were being prepended to the template field in artifact instructions
  • This caused AI assistants to literally copy <context> and <rules> blocks into generated artifact files
  • Now these are separate JSON fields, making it unambiguous what's a constraint vs what's the output structure

Changes

  • Add context and rules as separate fields in ArtifactInstructions interface
  • Update generateInstructions() to populate these as distinct fields (not prepended to template)
  • Update CLI text output to display context/rules with clear "do not include in output" comments
  • Rename <context> (for dependencies) to <dependencies> to avoid confusion
  • Update tests for new structure

JSON Output Structure

Before:

{
  "template": "<context>\nTech stack...\n</context>\n\n<rules>\n- Rule 1\n</rules>\n\n## Why\n..."
}

After:

{
  "context": "Tech stack...",
  "rules": ["Rule 1"],
  "template": "## Why\n..."
}

Test plan

  • All existing tests pass
  • Updated tests verify separate fields
  • Build completes successfully

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Instructions now show project context and rules as separate, dedicated sections; templates emphasize these are constraints and must not be copied into generated artifacts.
  • Refactor

    • Instruction content is separated from configuration-driven context and rules for clearer output and processing.
  • Documentation

    • Templates and guidance updated with explicit steps and “IMPORTANT” notes on parsing fields, handling dependencies, and writing artifacts.

✏️ Tip: You can customize this high-level summary in your review settings.

…utput

Previously, project config context and rules were prepended to the template
field in artifact instructions. This caused AI assistants to literally copy
these constraint blocks into generated artifact files, rather than treating
them as instructions.

Changes:
- Add `context` and `rules` as separate fields in ArtifactInstructions interface
- Update generateInstructions() to populate these as distinct fields
- Update CLI output to display context/rules with clear "do not include" comments
- Rename <context> (dependencies) to <dependencies> to avoid confusion
- Update tests for new structure

The JSON output from `openspec instructions` now clearly separates:
- `context`: Project background (constraints for AI)
- `rules`: Artifact-specific rules (constraints for AI)
- `template`: The actual structure for the output file
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 21, 2026

📝 Walkthrough

Walkthrough

The PR separates artifact "context" and "rules" out of embedded template text into new optional ArtifactInstructions fields (context?: string, rules?: string[]), updates instruction generation and rendering to expose and validate these fields, and adjusts templates and tests to consume them independently.

Changes

Cohort / File(s) Summary
Instruction loader
src/core/artifact-graph/instruction-loader.ts
Add context?: string and rules?: string[] to ArtifactInstructions; read project config, validate per-artifact rules (emit deduplicated warnings), and return template separately from context/rules.
Artifact workflow / rendering
src/commands/artifact-workflow.ts
Update printing to render context and rules as distinct sections (project_context + rules) before the template; rename dependency <context> block to <dependencies> and add inline guidance comments around template usage.
Templates / skill docs
src/core/templates/skill-templates.ts
Update multiple skill/command templates and examples to parse JSON with fields context, rules, template, instruction, outputPath, dependencies and emphasize that context/rules are constraints not to be copied into artifact output.
Tests
test/core/artifact-graph/instruction-loader.test.ts
Adjust expectations to assert instructions.context and instructions.rules are returned separately and that instructions.template no longer contains embedded context/rules; update cases for multi-line/special chars and rule validation behavior.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant CLI as Artifact CLI
  participant Loader as InstructionLoader
  participant Config as ProjectConfig
  participant Renderer as ArtifactWorkflow
  participant FS as FileSystem

  User->>CLI: request generate artifact
  CLI->>Loader: generateInstructions(artifactId)
  Loader->>Config: read project config
  Config-->>Loader: config (context, rules, dependencies)
  Loader-->>CLI: ArtifactInstructions { template, context?, rules?, dependencies }
  CLI->>Renderer: printInstructionsText(ArtifactInstructions)
  Renderer->>FS: read dependencies (if any)
  Renderer->>FS: write artifact to outputPath using template (apply constraints from context/rules)
  Renderer-->>User: artifact created
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 I hopped through config, nibbling strings,
Pulled rules and context from tangled things.
Templates now tidy, no stray rules to keep,
I guard the constraints while you code and sleep. 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and accurately summarizes the primary change: separating context and rules from the template field in JSON output, which is the core bug fix across all modified files.
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing touches
  • 📝 Generate docstrings

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.

…entation

Update generated skill templates (continue-change, ff-change) to document
that context and rules are separate JSON fields that should NOT be copied
into artifact output files.

Users running `openspec update` will get the updated skill instructions.
@vibe-kanban-cloud
Copy link

Review Complete

Your review story is ready!

View Story

Comment !reviewfast on this PR to re-generate the story.

@greptile-apps
Copy link

greptile-apps bot commented Jan 21, 2026

Greptile Summary

Fixed a bug where project configuration context and rules were being prepended to the template field, causing AI assistants to literally copy constraint blocks into generated artifact files. These are now separate JSON fields with clear semantics.

Key Changes

  • Added context and rules as distinct fields in ArtifactInstructions interface (not embedded in template)
  • Updated generateInstructions() to extract these as separate properties with proper handling of empty values
  • Renamed <context> tag to <dependencies> in CLI output to eliminate ambiguity about file dependencies vs project context
  • Added explicit HTML comments in text output clarifying what should/shouldn't be included in generated files
  • Comprehensive test updates validating the new structure and ensuring template remains clean

Impact

Before: JSON output had constraints embedded in template, making it ambiguous what was structure vs constraints:

{ "template": "<context>\nTech stack...\n</context>\n\n## Why\n..." }

After: Clean separation makes AI behavior unambiguous:

{ "context": "Tech stack...", "rules": ["Rule 1"], "template": "## Why\n..." }

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The changes are well-structured and address a clear bug where AI assistants would literally copy constraint blocks into generated files. The fix properly separates concerns by extracting context and rules into distinct JSON fields. All tests have been updated and validate the new structure correctly. The implementation is backwards-compatible and handles edge cases like empty strings and missing config appropriately.
  • No files require special attention

Important Files Changed

Filename Overview
src/core/artifact-graph/instruction-loader.ts Separated context and rules from template field into distinct JSON properties, preventing AI from including constraints in output files
src/commands/artifact-workflow.ts Updated CLI text output to display context and rules with clear comments, renamed <context> tag to <dependencies> to avoid confusion
test/core/artifact-graph/instruction-loader.test.ts Updated all tests to verify context and rules are separate fields, ensuring template doesn't contain constraint information

Sequence Diagram

sequenceDiagram
    participant User
    participant CLI as artifact-workflow.ts
    participant Gen as generateInstructions()
    participant Config as readProjectConfig()
    participant Template as loadTemplate()

    User->>CLI: openspec create <artifact> --json
    CLI->>Gen: generateInstructions(context, artifactId)
    Gen->>Config: readProjectConfig(projectRoot)
    Config-->>Gen: { context, rules }
    Gen->>Template: loadTemplate(schemaName, templatePath)
    Template-->>Gen: templateContent
    
    Note over Gen: Extract fields separately<br/>(not prepended to template)
    Gen->>Gen: configContext = context?.trim() || undefined
    Gen->>Gen: configRules = rules[artifactId] || undefined
    
    Gen-->>CLI: { context, rules, template, ... }
    
    alt JSON output
        CLI->>User: JSON.stringify({ context, rules, template })
        Note over User: AI sees separate fields<br/>Won't include in output
    else Text output
        CLI->>CLI: printInstructionsText()
        CLI->>User: <project_context>...do not include...</project_context>
        CLI->>User: <rules>...do not include...</rules>
        CLI->>User: <template>...fill in sections...</template>
        Note over User: Clear comments prevent<br/>constraint inclusion
    end
Loading

@TabishB
Copy link
Contributor Author

TabishB commented Jan 21, 2026

Additional commit: Skill template updates

The second commit updates the skill templates in src/core/templates/skill-templates.ts so that users get this fix when they run openspec update.

Updates to skill templates:

  • continue-change skill: Documents separate JSON fields, adds guardrails about not copying context/rules
  • ff-change skill: Same updates

How users get this fix:

  1. New users: openspec init will generate skills with the updated instructions
  2. Existing users: openspec update will regenerate skills with the updated instructions

@TabishB
Copy link
Contributor Author

TabishB commented Jan 21, 2026

Correction: Users get this fix by running openspec artifact-experimental-setup (the experimental workflow setup command), not openspec update.

The skill templates are generated by the experimental workflow setup, so existing users of the experimental workflow need to re-run:

openspec artifact-experimental-setup

This will regenerate the skills in .claude/skills/ with the updated instructions that properly document the separate context, rules, and template JSON fields.

@TabishB TabishB merged commit e2c333e into main Jan 21, 2026
9 checks passed
@TabishB TabishB deleted the fix/separate-context-rules-from-template branch January 21, 2026 04:52
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.

1 participant