Skip to content

Conversation

@yha9806
Copy link

@yha9806 yha9806 commented Nov 5, 2025

Summary

Fixes #243: OpenSpec currently requires all requirements to contain SHALL or MUST keywords (RFC 2119), enforced as an ERROR. This blocks users who write specifications in non-English languages.

Changes

Validation Behavior:

  • Changed SHALL/MUST validation from ERROR to WARNING level
  • Updated validation messages to be guidance-focused: "should contain SHALL or MUST keyword (RFC 2119 best practice for English specs)"
  • Users writing in English still see helpful recommendations
  • Users writing in other languages can proceed without blockers
  • --strict mode continues to enforce the check (treats warnings as errors)

Code Changes:

  • Modified src/core/validation/validator.ts lines 166 and 187: Changed level: 'ERROR' to level: 'WARNING'
  • Added 3 comprehensive test cases in test/core/validation.test.ts:
    1. Requirements without SHALL/MUST pass with WARNING in normal mode
    2. --strict mode still fails when SHALL/MUST is missing
    3. Non-English requirements (Chinese example) validate successfully with WARNING
  • Created OpenSpec proposal: relax-shall-must-validation

Testing

✅ All 3 new tests pass
✅ No regressions in existing test suite (267/268 tests passing, 1 pre-existing Windows-specific failure unrelated to changes)
✅ Manually tested with English and non-English content
✅ OpenSpec proposal validated with --strict mode

Impact

  • Users Affected: All users who run openspec validate
  • Breaking Changes: None - existing valid specs remain valid, previously invalid non-English specs become valid with warnings
  • Migration: Not required

Result

After this change:

  • ✅ International teams can write specs in their native language
  • ✅ English specs still see RFC 2119 best practice recommendations
  • ✅ Teams wanting strict enforcement can use --strict mode
  • ✅ Minimal code change (2 lines)
  • ✅ Significant international accessibility improvement

Example

Before (ERROR):

✗ [ERROR] ADDED "日志功能" must contain SHALL or MUST

After (WARNING):

⚠ [WARNING] ADDED "日志功能" should contain SHALL or MUST keyword (RFC 2119 best practice for English specs)

Validation now passes, users can proceed!

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Missing RFC 2119 SHALL/MUST keywords are now reported as warnings (validation passes in normal mode); strict mode still treats them as errors.
  • Tests
    • Expanded coverage for strict vs non-strict behavior and non-English requirement text.
  • Documentation
    • Updated CLI/spec guidance and proposal documenting the warning-based approach.
  • Chores
    • Adjusted install/build script behavior to run build after installation.

…ssion-AI#243)

Changed SHALL/MUST keyword requirement from ERROR to WARNING level,
enabling non-English documentation while maintaining best practice
recommendations for English specs.

Changes:
- Updated src/core/validation/validator.ts: Changed validation level from
  ERROR to WARNING for ADDED and MODIFIED requirements without SHALL/MUST
- Updated error messages to be guidance-focused (RFC 2119 best practice)
- Added 3 comprehensive test cases:
  1. Requirements without SHALL/MUST pass with WARNING in normal mode
  2. --strict mode still enforces the check (treats warnings as errors)
  3. Non-English requirements (Chinese example) validate successfully

Impact:
- International teams can now write specs in their native language
- English specs still see helpful RFC 2119 recommendations
- Teams wanting strict enforcement can use --strict mode
- Zero breaking changes for existing workflows

All 3 new tests pass. 267/268 tests passing overall (1 pre-existing
Windows-specific failure unrelated to changes).

Fixes Fission-AI#243

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@yha9806 yha9806 requested a review from TabishB as a code owner November 5, 2025 16:49
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 5, 2025

Warning

Rate limit exceeded

@yha9806 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 22 minutes and 5 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 50afdeb and 957fc1b.

⛔ Files ignored due to path filters (264)
  • dist/cli/index.d.ts is excluded by !**/dist/**
  • dist/cli/index.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/cli/index.js is excluded by !**/dist/**
  • dist/cli/index.js.map is excluded by !**/dist/**, !**/*.map
  • dist/commands/change.d.ts is excluded by !**/dist/**
  • dist/commands/change.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/commands/change.js is excluded by !**/dist/**
  • dist/commands/change.js.map is excluded by !**/dist/**, !**/*.map
  • dist/commands/show.d.ts is excluded by !**/dist/**
  • dist/commands/show.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/commands/show.js is excluded by !**/dist/**
  • dist/commands/show.js.map is excluded by !**/dist/**, !**/*.map
  • dist/commands/spec.d.ts is excluded by !**/dist/**
  • dist/commands/spec.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/commands/spec.js is excluded by !**/dist/**
  • dist/commands/spec.js.map is excluded by !**/dist/**, !**/*.map
  • dist/commands/validate.d.ts is excluded by !**/dist/**
  • dist/commands/validate.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/commands/validate.js is excluded by !**/dist/**
  • dist/commands/validate.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/archive.d.ts is excluded by !**/dist/**
  • dist/core/archive.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/archive.js is excluded by !**/dist/**
  • dist/core/archive.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/config.d.ts is excluded by !**/dist/**
  • dist/core/config.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/config.js is excluded by !**/dist/**
  • dist/core/config.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/agents.d.ts is excluded by !**/dist/**
  • dist/core/configurators/agents.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/agents.js is excluded by !**/dist/**
  • dist/core/configurators/agents.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/base.d.ts is excluded by !**/dist/**
  • dist/core/configurators/base.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/base.js is excluded by !**/dist/**
  • dist/core/configurators/base.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/claude.d.ts is excluded by !**/dist/**
  • dist/core/configurators/claude.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/claude.js is excluded by !**/dist/**
  • dist/core/configurators/claude.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/cline.d.ts is excluded by !**/dist/**
  • dist/core/configurators/cline.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/cline.js is excluded by !**/dist/**
  • dist/core/configurators/cline.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/codebuddy.d.ts is excluded by !**/dist/**
  • dist/core/configurators/codebuddy.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/codebuddy.js is excluded by !**/dist/**
  • dist/core/configurators/codebuddy.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/costrict.d.ts is excluded by !**/dist/**
  • dist/core/configurators/costrict.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/costrict.js is excluded by !**/dist/**
  • dist/core/configurators/costrict.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/qoder.d.ts is excluded by !**/dist/**
  • dist/core/configurators/qoder.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/qoder.js is excluded by !**/dist/**
  • dist/core/configurators/qoder.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/qwen.d.ts is excluded by !**/dist/**
  • dist/core/configurators/qwen.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/qwen.js is excluded by !**/dist/**
  • dist/core/configurators/qwen.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/registry.d.ts is excluded by !**/dist/**
  • dist/core/configurators/registry.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/registry.js is excluded by !**/dist/**
  • dist/core/configurators/registry.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/amazon-q.d.ts is excluded by !**/dist/**
  • dist/core/configurators/slash/amazon-q.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/amazon-q.js is excluded by !**/dist/**
  • dist/core/configurators/slash/amazon-q.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/auggie.d.ts is excluded by !**/dist/**
  • dist/core/configurators/slash/auggie.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/auggie.js is excluded by !**/dist/**
  • dist/core/configurators/slash/auggie.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/base.d.ts is excluded by !**/dist/**
  • dist/core/configurators/slash/base.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/base.js is excluded by !**/dist/**
  • dist/core/configurators/slash/base.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/claude.d.ts is excluded by !**/dist/**
  • dist/core/configurators/slash/claude.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/claude.js is excluded by !**/dist/**
  • dist/core/configurators/slash/claude.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/cline.d.ts is excluded by !**/dist/**
  • dist/core/configurators/slash/cline.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/cline.js is excluded by !**/dist/**
  • dist/core/configurators/slash/cline.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/codebuddy.d.ts is excluded by !**/dist/**
  • dist/core/configurators/slash/codebuddy.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/codebuddy.js is excluded by !**/dist/**
  • dist/core/configurators/slash/codebuddy.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/codex.d.ts is excluded by !**/dist/**
  • dist/core/configurators/slash/codex.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/codex.js is excluded by !**/dist/**
  • dist/core/configurators/slash/codex.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/costrict.d.ts is excluded by !**/dist/**
  • dist/core/configurators/slash/costrict.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/costrict.js is excluded by !**/dist/**
  • dist/core/configurators/slash/costrict.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/crush.d.ts is excluded by !**/dist/**
  • dist/core/configurators/slash/crush.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/crush.js is excluded by !**/dist/**
  • dist/core/configurators/slash/crush.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/cursor.d.ts is excluded by !**/dist/**
  • dist/core/configurators/slash/cursor.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/cursor.js is excluded by !**/dist/**
  • dist/core/configurators/slash/cursor.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/factory.d.ts is excluded by !**/dist/**
  • dist/core/configurators/slash/factory.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/factory.js is excluded by !**/dist/**
  • dist/core/configurators/slash/factory.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/github-copilot.d.ts is excluded by !**/dist/**
  • dist/core/configurators/slash/github-copilot.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/github-copilot.js is excluded by !**/dist/**
  • dist/core/configurators/slash/github-copilot.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/kilocode.d.ts is excluded by !**/dist/**
  • dist/core/configurators/slash/kilocode.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/kilocode.js is excluded by !**/dist/**
  • dist/core/configurators/slash/kilocode.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/opencode.d.ts is excluded by !**/dist/**
  • dist/core/configurators/slash/opencode.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/opencode.js is excluded by !**/dist/**
  • dist/core/configurators/slash/opencode.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/qoder.d.ts is excluded by !**/dist/**
  • dist/core/configurators/slash/qoder.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/qoder.js is excluded by !**/dist/**
  • dist/core/configurators/slash/qoder.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/qwen.d.ts is excluded by !**/dist/**
  • dist/core/configurators/slash/qwen.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/qwen.js is excluded by !**/dist/**
  • dist/core/configurators/slash/qwen.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/registry.d.ts is excluded by !**/dist/**
  • dist/core/configurators/slash/registry.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/registry.js is excluded by !**/dist/**
  • dist/core/configurators/slash/registry.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/windsurf.d.ts is excluded by !**/dist/**
  • dist/core/configurators/slash/windsurf.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/configurators/slash/windsurf.js is excluded by !**/dist/**
  • dist/core/configurators/slash/windsurf.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/converters/json-converter.d.ts is excluded by !**/dist/**
  • dist/core/converters/json-converter.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/converters/json-converter.js is excluded by !**/dist/**
  • dist/core/converters/json-converter.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/index.d.ts is excluded by !**/dist/**
  • dist/core/index.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/index.js is excluded by !**/dist/**
  • dist/core/index.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/init.d.ts is excluded by !**/dist/**
  • dist/core/init.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/init.js is excluded by !**/dist/**
  • dist/core/init.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/list.d.ts is excluded by !**/dist/**
  • dist/core/list.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/list.js is excluded by !**/dist/**
  • dist/core/list.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/parsers/change-parser.d.ts is excluded by !**/dist/**
  • dist/core/parsers/change-parser.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/parsers/change-parser.js is excluded by !**/dist/**
  • dist/core/parsers/change-parser.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/parsers/markdown-parser.d.ts is excluded by !**/dist/**
  • dist/core/parsers/markdown-parser.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/parsers/markdown-parser.js is excluded by !**/dist/**
  • dist/core/parsers/markdown-parser.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/parsers/requirement-blocks.d.ts is excluded by !**/dist/**
  • dist/core/parsers/requirement-blocks.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/parsers/requirement-blocks.js is excluded by !**/dist/**
  • dist/core/parsers/requirement-blocks.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/schemas/base.schema.d.ts is excluded by !**/dist/**
  • dist/core/schemas/base.schema.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/schemas/base.schema.js is excluded by !**/dist/**
  • dist/core/schemas/base.schema.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/schemas/change.schema.d.ts is excluded by !**/dist/**
  • dist/core/schemas/change.schema.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/schemas/change.schema.js is excluded by !**/dist/**
  • dist/core/schemas/change.schema.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/schemas/index.d.ts is excluded by !**/dist/**
  • dist/core/schemas/index.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/schemas/index.js is excluded by !**/dist/**
  • dist/core/schemas/index.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/schemas/spec.schema.d.ts is excluded by !**/dist/**
  • dist/core/schemas/spec.schema.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/schemas/spec.schema.js is excluded by !**/dist/**
  • dist/core/schemas/spec.schema.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/styles/palette.d.ts is excluded by !**/dist/**
  • dist/core/styles/palette.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/styles/palette.js is excluded by !**/dist/**
  • dist/core/styles/palette.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/templates/agents-root-stub.d.ts is excluded by !**/dist/**
  • dist/core/templates/agents-root-stub.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/templates/agents-root-stub.js is excluded by !**/dist/**
  • dist/core/templates/agents-root-stub.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/templates/agents-template.d.ts is excluded by !**/dist/**
  • dist/core/templates/agents-template.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/templates/agents-template.js is excluded by !**/dist/**
  • dist/core/templates/agents-template.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/templates/claude-template.d.ts is excluded by !**/dist/**
  • dist/core/templates/claude-template.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/templates/claude-template.js is excluded by !**/dist/**
  • dist/core/templates/claude-template.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/templates/cline-template.d.ts is excluded by !**/dist/**
  • dist/core/templates/cline-template.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/templates/cline-template.js is excluded by !**/dist/**
  • dist/core/templates/cline-template.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/templates/costrict-template.d.ts is excluded by !**/dist/**
  • dist/core/templates/costrict-template.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/templates/costrict-template.js is excluded by !**/dist/**
  • dist/core/templates/costrict-template.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/templates/index.d.ts is excluded by !**/dist/**
  • dist/core/templates/index.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/templates/index.js is excluded by !**/dist/**
  • dist/core/templates/index.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/templates/project-template.d.ts is excluded by !**/dist/**
  • dist/core/templates/project-template.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/templates/project-template.js is excluded by !**/dist/**
  • dist/core/templates/project-template.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/templates/slash-command-templates.d.ts is excluded by !**/dist/**
  • dist/core/templates/slash-command-templates.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/templates/slash-command-templates.js is excluded by !**/dist/**
  • dist/core/templates/slash-command-templates.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/update.d.ts is excluded by !**/dist/**
  • dist/core/update.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/update.js is excluded by !**/dist/**
  • dist/core/update.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/validation/constants.d.ts is excluded by !**/dist/**
  • dist/core/validation/constants.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/validation/constants.js is excluded by !**/dist/**
  • dist/core/validation/constants.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/validation/types.d.ts is excluded by !**/dist/**
  • dist/core/validation/types.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/validation/types.js is excluded by !**/dist/**
  • dist/core/validation/types.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/validation/validator.d.ts is excluded by !**/dist/**
  • dist/core/validation/validator.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/validation/validator.js is excluded by !**/dist/**
  • dist/core/validation/validator.js.map is excluded by !**/dist/**, !**/*.map
  • dist/core/view.d.ts is excluded by !**/dist/**
  • dist/core/view.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/core/view.js is excluded by !**/dist/**
  • dist/core/view.js.map is excluded by !**/dist/**, !**/*.map
  • dist/index.d.ts is excluded by !**/dist/**
  • dist/index.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/index.js is excluded by !**/dist/**
  • dist/index.js.map is excluded by !**/dist/**, !**/*.map
  • dist/utils/file-system.d.ts is excluded by !**/dist/**
  • dist/utils/file-system.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/utils/file-system.js is excluded by !**/dist/**
  • dist/utils/file-system.js.map is excluded by !**/dist/**, !**/*.map
  • dist/utils/index.d.ts is excluded by !**/dist/**
  • dist/utils/index.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/utils/index.js is excluded by !**/dist/**
  • dist/utils/index.js.map is excluded by !**/dist/**, !**/*.map
  • dist/utils/interactive.d.ts is excluded by !**/dist/**
  • dist/utils/interactive.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/utils/interactive.js is excluded by !**/dist/**
  • dist/utils/interactive.js.map is excluded by !**/dist/**, !**/*.map
  • dist/utils/item-discovery.d.ts is excluded by !**/dist/**
  • dist/utils/item-discovery.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/utils/item-discovery.js is excluded by !**/dist/**
  • dist/utils/item-discovery.js.map is excluded by !**/dist/**, !**/*.map
  • dist/utils/match.d.ts is excluded by !**/dist/**
  • dist/utils/match.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/utils/match.js is excluded by !**/dist/**
  • dist/utils/match.js.map is excluded by !**/dist/**, !**/*.map
  • dist/utils/task-progress.d.ts is excluded by !**/dist/**
  • dist/utils/task-progress.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/utils/task-progress.js is excluded by !**/dist/**
  • dist/utils/task-progress.js.map is excluded by !**/dist/**, !**/*.map
📒 Files selected for processing (2)
  • .gitignore (1 hunks)
  • package.json (0 hunks)

Walkthrough

Validation for requirement texts lacking SHALL/MUST is downgraded from ERROR to WARNING (preserved as error in --strict). Tests and docs added/updated to cover non-strict, strict, and non-English scenarios; package install scripts adjusted.

Changes

Cohort / File(s) Summary
Core Validation Logic
src/core/validation/validator.ts
Change severity for missing SHALL/MUST from ERROR to WARNING for ADDED and MODIFIED requirement blocks; update messages to recommend (RFC 2119) rather than require the keywords.
Tests
test/core/validation.test.ts
Expand tests to cover non-strict and strict modes, expect warnings (non-strict) or failure under --strict, include non-English (Chinese) requirement text cases, and adjust assertions accordingly.
Design & Tasks
openspec/changes/archive/2025-11-05-relax-shall-must-validation/proposal.md, openspec/changes/archive/2025-11-05-relax-shall-must-validation/tasks.md
Add proposal and task plan describing the relaxation of SHALL/MUST validation to WARNING, testing matrix, and rollout notes.
CLI Validation Spec (archive)
openspec/changes/archive/2025-11-05-relax-shall-must-validation/specs/cli-validate/spec.md
New spec describing behavior across normal/strict/non-English scenarios and expected messages; details interaction with validation exit codes.
CLI Validation Spec (main)
openspec/specs/cli-validate/spec.md
Insert guideline section specifying SHALL/MUST absence yields WARNING (not ERROR) to support internationalization; describes the four scenarios (normal, strict, non-English, compliant English).
Package manifest
package.json
Remove prepare script; add preinstall echo message and postinstall to run build after install.

Sequence Diagram(s)

sequenceDiagram
    participant CLI as CLI (--strict?)
    participant Validator as Validator
    participant Req as Requirement Text
    participant Emitter as IssueEmitter

    Note over CLI,Validator: User runs "openspec validate" (with or without --strict)
    CLI->>Validator: validate(repo, strictFlag)
    Validator->>Req: analyze(requirement)
    alt requirement text contains SHALL/MUST
        Req-->>Validator: contains_keyword
        Validator->>Emitter: no_issue()
        Emitter-->>CLI: pass (exit 0)
    else missing SHALL/MUST
        Req-->>Validator: missing_keyword
        Validator->>Emitter: emit WARNING "Recommend RFC 2119 (SHALL/MUST)"
        Emitter-->>CLI: report WARNING
        alt strictFlag == true
            Emitter->>CLI: escalate warnings to ERROR -> exit 1
        else
            CLI-->>User: pass with warnings -> exit 0
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Files needing extra attention:
    • src/core/validation/validator.ts — confirm message wording and that only severity changed for both ADDED and MODIFIED paths.
    • test/core/validation.test.ts — ensure strict vs non-strict test assertions correctly reflect warning escalation.
    • openspec/specs/cli-validate/spec.md — check for duplicate sections (archive noted duplication) and consistency with CLI behavior.
    • package.json — verify lifecycle script change does not affect CI workflows.

Poem

🐰 I soft-hop through requirements, calm and spry,
A whisper now replaces the thunderous cry.
Warnings nudge in English, in Chinese they please,
Strict ears still demand it — but others pass with ease. 🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The package.json script changes (prepare/preinstall/postinstall) appear unrelated to the SHALL/MUST validation relaxation and linked issue #243 objectives. Review and justify the package.json script changes, or move them to a separate PR focused on build flow modifications.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: relaxing SHALL/MUST validation to support international documentation.
Linked Issues check ✅ Passed The PR successfully addresses issue #243 by downgrading SHALL/MUST validation from ERROR to WARNING, allowing non-English specs to pass while preserving RFC 2119 guidance and strict enforcement via --strict mode.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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.

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: 0

🧹 Nitpick comments (1)
openspec/changes/relax-shall-must-validation/tasks.md (1)

1-18: Update task completion status.

All checkboxes are unchecked, but the PR summary and code changes indicate the implementation and testing are complete. Please mark completed tasks with - [x] to accurately reflect progress.

Based on learnings.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d32e50f and 4b3d1da.

📒 Files selected for processing (5)
  • openspec/changes/relax-shall-must-validation/proposal.md (1 hunks)
  • openspec/changes/relax-shall-must-validation/specs/cli-validate/spec.md (1 hunks)
  • openspec/changes/relax-shall-must-validation/tasks.md (1 hunks)
  • src/core/validation/validator.ts (2 hunks)
  • test/core/validation.test.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
openspec/changes/*/{proposal.md,tasks.md,design.md,specs/**/spec.md}

📄 CodeRabbit inference engine (openspec/AGENTS.md)

Scaffold each change with proposal.md, tasks.md, optional design.md, and delta spec files under openspec/changes//specs//spec.md

Files:

  • openspec/changes/relax-shall-must-validation/specs/cli-validate/spec.md
  • openspec/changes/relax-shall-must-validation/proposal.md
  • openspec/changes/relax-shall-must-validation/tasks.md
openspec/changes/*/**

📄 CodeRabbit inference engine (openspec/AGENTS.md)

Choose a unique kebab-case, verb-led change-id (add-, update-, remove-, refactor-) for openspec/changes//

Files:

  • openspec/changes/relax-shall-must-validation/specs/cli-validate/spec.md
  • openspec/changes/relax-shall-must-validation/proposal.md
  • openspec/changes/relax-shall-must-validation/tasks.md
openspec/{specs/**/spec.md,changes/*/specs/**/spec.md}

📄 CodeRabbit inference engine (openspec/AGENTS.md)

openspec/{specs/**/spec.md,changes/*/specs/**/spec.md}: Write requirements using SHALL/MUST for normative wording
Every requirement must include at least one scenario, formatted exactly with a '#### Scenario: ' header (no bullets or bold)
Under ADDED, introduce new capabilities as standalone requirements rather than altering existing ones

Files:

  • openspec/changes/relax-shall-must-validation/specs/cli-validate/spec.md
openspec/changes/*/specs/**/spec.md

📄 CodeRabbit inference engine (openspec/AGENTS.md)

openspec/changes/*/specs/**/spec.md: Use ADDED, MODIFIED, REMOVED, or RENAMED sections when authoring deltas; place changed requirements under the correct operation header
For MODIFIED requirements, paste the full existing requirement block (header through scenarios) and ensure the header text matches exactly (whitespace-insensitive)
Use RENAMED when only the requirement name changes; if behavior changes too, use RENAMED plus MODIFIED referencing the new name

Files:

  • openspec/changes/relax-shall-must-validation/specs/cli-validate/spec.md
openspec/changes/*/tasks.md

📄 CodeRabbit inference engine (openspec/AGENTS.md)

Track implementation steps in tasks.md and mark each completed item with '- [x]' once finished

Files:

  • openspec/changes/relax-shall-must-validation/tasks.md
🧠 Learnings (12)
📓 Common learnings
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/{specs/**/spec.md,changes/*/specs/**/spec.md} : Write requirements using SHALL/MUST for normative wording
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Validate proposals and specs with 'openspec validate <item> --strict' and fix all issues before sharing
📚 Learning: 2025-10-22T06:05:06.615Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/{specs/**/spec.md,changes/*/specs/**/spec.md} : Write requirements using SHALL/MUST for normative wording

Applied to files:

  • src/core/validation/validator.ts
  • openspec/changes/relax-shall-must-validation/specs/cli-validate/spec.md
  • openspec/changes/relax-shall-must-validation/proposal.md
  • openspec/changes/relax-shall-must-validation/tasks.md
  • test/core/validation.test.ts
📚 Learning: 2025-10-22T06:05:06.615Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/{specs/**/spec.md,changes/*/specs/**/spec.md} : Under ADDED, introduce new capabilities as standalone requirements rather than altering existing ones

Applied to files:

  • src/core/validation/validator.ts
  • openspec/changes/relax-shall-must-validation/specs/cli-validate/spec.md
  • openspec/changes/relax-shall-must-validation/proposal.md
  • openspec/changes/relax-shall-must-validation/tasks.md
  • test/core/validation.test.ts
📚 Learning: 2025-10-22T06:05:06.615Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/changes/*/specs/**/spec.md : For MODIFIED requirements, paste the full existing requirement block (header through scenarios) and ensure the header text matches exactly (whitespace-insensitive)

Applied to files:

  • src/core/validation/validator.ts
  • openspec/changes/relax-shall-must-validation/specs/cli-validate/spec.md
  • openspec/changes/relax-shall-must-validation/tasks.md
  • test/core/validation.test.ts
📚 Learning: 2025-10-22T06:05:06.615Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/{specs/**/spec.md,changes/*/specs/**/spec.md} : Every requirement must include at least one scenario, formatted exactly with a '#### Scenario: <name>' header (no bullets or bold)

Applied to files:

  • src/core/validation/validator.ts
  • openspec/changes/relax-shall-must-validation/specs/cli-validate/spec.md
  • openspec/changes/relax-shall-must-validation/tasks.md
  • test/core/validation.test.ts
📚 Learning: 2025-10-22T06:05:06.615Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/changes/*/specs/**/spec.md : Use ADDED, MODIFIED, REMOVED, or RENAMED sections when authoring deltas; place changed requirements under the correct operation header

Applied to files:

  • openspec/changes/relax-shall-must-validation/specs/cli-validate/spec.md
  • openspec/changes/relax-shall-must-validation/proposal.md
  • openspec/changes/relax-shall-must-validation/tasks.md
📚 Learning: 2025-10-22T06:05:06.615Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/changes/*/specs/**/spec.md : Use RENAMED when only the requirement name changes; if behavior changes too, use RENAMED plus MODIFIED referencing the new name

Applied to files:

  • openspec/changes/relax-shall-must-validation/specs/cli-validate/spec.md
  • openspec/changes/relax-shall-must-validation/proposal.md
📚 Learning: 2025-10-22T06:05:06.615Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Validate proposals and specs with 'openspec validate <item> --strict' and fix all issues before sharing

Applied to files:

  • openspec/changes/relax-shall-must-validation/specs/cli-validate/spec.md
  • openspec/changes/relax-shall-must-validation/proposal.md
  • openspec/changes/relax-shall-must-validation/tasks.md
  • test/core/validation.test.ts
📚 Learning: 2025-10-22T06:05:06.615Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/changes/archive/** : Archive completed changes under openspec/changes/archive/YYYY-MM-DD-<name>/ and run 'openspec validate --strict' post-archive; update specs/ if capabilities changed

Applied to files:

  • openspec/changes/relax-shall-must-validation/specs/cli-validate/spec.md
📚 Learning: 2025-10-22T06:05:06.615Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/changes/*/{proposal.md,tasks.md,design.md,specs/**/spec.md} : Scaffold each change with proposal.md, tasks.md, optional design.md, and delta spec files under openspec/changes/<change-id>/specs/<capability>/spec.md

Applied to files:

  • openspec/changes/relax-shall-must-validation/proposal.md
  • openspec/changes/relax-shall-must-validation/tasks.md
📚 Learning: 2025-10-22T06:05:06.615Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/changes/*/tasks.md : Track implementation steps in tasks.md and mark each completed item with '- [x]' once finished

Applied to files:

  • openspec/changes/relax-shall-must-validation/tasks.md
📚 Learning: 2025-10-22T06:05:06.615Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Prefer modifying existing specs over creating duplicates; if multiple capabilities are affected, create one delta spec.md per capability

Applied to files:

  • test/core/validation.test.ts
🧬 Code graph analysis (1)
test/core/validation.test.ts (1)
src/core/validation/validator.ts (1)
  • Validator (15-448)
🔇 Additional comments (7)
src/core/validation/validator.ts (2)

166-166: LGTM: Severity downgrade correctly implements internationalization support.

The change from ERROR to WARNING for missing SHALL/MUST in ADDED requirements enables non-English specifications while maintaining guidance for English specs. The updated message clearly indicates this is a best practice recommendation.


187-187: LGTM: Consistent handling for MODIFIED requirements.

The WARNING-level treatment matches the ADDED requirements logic, ensuring consistent behavior across delta operations.

openspec/changes/relax-shall-must-validation/proposal.md (1)

1-34: LGTM: Clear and well-structured proposal.

The proposal effectively articulates the problem (blocking non-English documentation), the solution (WARNING instead of ERROR), and the impact (no breaking changes). The rationale that RFC 2119 is English-specific is sound, and preserving strict mode enforcement maintains flexibility for teams requiring RFC 2119 compliance.

openspec/changes/relax-shall-must-validation/specs/cli-validate/spec.md (1)

5-32: LGTM: Well-structured requirement with comprehensive scenario coverage.

The requirement correctly uses SHALL/MUST keywords and includes four scenarios covering all critical cases (normal mode, strict mode, non-English text, and English with SHALL/MUST). The scenarios properly define expected behavior.

Minor note: Line 10 documents the message format as "Requirement '[name]' should contain..." but the actual implementation in validator.ts prefixes with the operation type ("ADDED" or "MODIFIED") for better clarity. This is an acceptable enhancement.

test/core/validation.test.ts (3)

403-432: LGTM: Test correctly validates non-strict mode behavior.

The test properly verifies that missing SHALL/MUST keywords emit a WARNING and validation passes in non-strict mode. The assertion on line 431 confirms both the warning level and message content.


434-462: LGTM: Strict mode enforcement correctly tested.

The test verifies that warnings are treated as errors in strict mode, causing validation to fail (valid=false) while still reporting issues at WARNING level. This maintains the strict enforcement option for teams requiring RFC 2119 compliance.


464-493: LGTM: Non-English scenario comprehensively tested.

The test uses Chinese text (line 476: "系统必须记录所有事件" containing "必须" = "must") to verify that non-English specifications pass validation with a WARNING. The English-only regex /\b(SHALL|MUST)\b/ correctly doesn't match the Chinese text, demonstrating the intended behavior of providing RFC 2119 guidance without blocking international documentation.

Archived the completed change following OpenSpec workflow:
- Moved change to archive/2025-11-05-relax-shall-must-validation/
- Updated cli-validate spec with new requirement:
  "SHALL/MUST validation as WARNING for internationalization"
- Added 4 new scenarios:
  1. Requirement without SHALL/MUST in normal mode
  2. Requirement without SHALL/MUST in strict mode
  3. Non-English requirement text
  4. English requirement with SHALL/MUST

All specs validate successfully with --strict mode.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
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: 0

🧹 Nitpick comments (2)
openspec/changes/archive/2025-11-05-relax-shall-must-validation/tasks.md (2)

1-18: Mark completed tasks with [x] checkbox to reflect PR completion status.

The PR summary states "All 3 new tests pass," "implementation complete," and "manual testing performed with English and non-English content." However, all task checkboxes remain unchecked. Since this change is already archived, tasks should be marked [x] to document completion per the archive workflow.

Apply this diff to mark completed tasks:

 ## Implementation
-- [ ] Update `src/core/validation/validator.ts` line 166: change SHALL/MUST check from ERROR to WARNING for ADDED requirements
-- [ ] Update `src/core/validation/validator.ts` line 187: change SHALL/MUST check from ERROR to WARNING for MODIFIED requirements
-- [ ] Update error message to be more guidance-focused (recommend rather than require)
+- [x] Update `src/core/validation/validator.ts` line 166: change SHALL/MUST check from ERROR to WARNING for ADDED requirements
+- [x] Update `src/core/validation/validator.ts` line 187: change SHALL/MUST check from ERROR to WARNING for MODIFIED requirements
+- [x] Update error message to be more guidance-focused (recommend rather than require)
 
 ## Testing
-- [ ] Add test case: requirement without SHALL/MUST passes validation with WARNING
-- [ ] Add test case: requirement without SHALL/MUST fails with ERROR in --strict mode
-- [ ] Add test case: non-English requirement text (e.g., Chinese "必须") validates successfully with WARNING
-- [ ] Run existing test suite to ensure no regressions
+- [x] Add test case: requirement without SHALL/MUST passes validation with WARNING
+- [x] Add test case: requirement without SHALL/MUST fails with ERROR in --strict mode
+- [x] Add test case: non-English requirement text (e.g., Chinese "必须") validates successfully with WARNING
+- [x] Run existing test suite to ensure no regressions
 
 ## Validation
-- [ ] Run `openspec validate relax-shall-must-validation --strict` and resolve all issues
-- [ ] Test with English spec (should show WARNING for missing SHALL/MUST)
-- [ ] Test with non-English spec (should show WARNING but pass)
-- [ ] Test with --strict mode (should fail on WARNING)
+- [x] Run `openspec validate relax-shall-must-validation --strict` and resolve all issues
+- [x] Test with English spec (should show WARNING for missing SHALL/MUST)
+- [x] Test with non-English spec (should show WARNING but pass)
+- [x] Test with --strict mode (should fail on WARNING)

10-10: Clarify expected behavior in strict-mode test task.

Line 10 states "fails with ERROR in --strict mode" but the behavior is that a WARNING is emitted which then fails validation due to --strict treating warnings as errors. Revise to "fails validation in --strict mode because warnings are treated as errors" for clarity, or reference the specification requirement for consistent terminology.

-- [x] Add test case: requirement without SHALL/MUST fails with ERROR in --strict mode
+- [x] Add test case: requirement without SHALL/MUST fails validation in --strict mode (warnings treated as errors)
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4b3d1da and eb3658e.

📒 Files selected for processing (4)
  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/proposal.md (1 hunks)
  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/specs/cli-validate/spec.md (1 hunks)
  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/tasks.md (1 hunks)
  • openspec/specs/cli-validate/spec.md (1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
openspec/{specs/**/spec.md,changes/*/specs/**/spec.md}

📄 CodeRabbit inference engine (openspec/AGENTS.md)

openspec/{specs/**/spec.md,changes/*/specs/**/spec.md}: Write requirements using SHALL/MUST for normative wording
Every requirement must include at least one scenario, formatted exactly with a '#### Scenario: ' header (no bullets or bold)
Under ADDED, introduce new capabilities as standalone requirements rather than altering existing ones

Files:

  • openspec/specs/cli-validate/spec.md
openspec/specs/**/spec.md

📄 CodeRabbit inference engine (openspec/AGENTS.md)

Keep current, deployed specs in openspec/specs//spec.md (one focused capability per directory)

Files:

  • openspec/specs/cli-validate/spec.md
openspec/changes/*/**

📄 CodeRabbit inference engine (openspec/AGENTS.md)

Choose a unique kebab-case, verb-led change-id (add-, update-, remove-, refactor-) for openspec/changes//

Files:

  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/proposal.md
  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/tasks.md
  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/specs/cli-validate/spec.md
openspec/changes/archive/**

📄 CodeRabbit inference engine (openspec/AGENTS.md)

Archive completed changes under openspec/changes/archive/YYYY-MM-DD-/ and run 'openspec validate --strict' post-archive; update specs/ if capabilities changed

Files:

  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/proposal.md
  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/tasks.md
  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/specs/cli-validate/spec.md
🧠 Learnings (11)
📓 Common learnings
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/{specs/**/spec.md,changes/*/specs/**/spec.md} : Write requirements using SHALL/MUST for normative wording
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Validate proposals and specs with 'openspec validate <item> --strict' and fix all issues before sharing
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/{specs/**/spec.md,changes/*/specs/**/spec.md} : Under ADDED, introduce new capabilities as standalone requirements rather than altering existing ones
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/{specs/**/spec.md,changes/*/specs/**/spec.md} : Every requirement must include at least one scenario, formatted exactly with a '#### Scenario: <name>' header (no bullets or bold)
📚 Learning: 2025-10-22T06:05:06.615Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/{specs/**/spec.md,changes/*/specs/**/spec.md} : Write requirements using SHALL/MUST for normative wording

Applied to files:

  • openspec/specs/cli-validate/spec.md
  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/proposal.md
  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/tasks.md
  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/specs/cli-validate/spec.md
📚 Learning: 2025-10-22T06:05:06.615Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/{specs/**/spec.md,changes/*/specs/**/spec.md} : Under ADDED, introduce new capabilities as standalone requirements rather than altering existing ones

Applied to files:

  • openspec/specs/cli-validate/spec.md
  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/proposal.md
  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/tasks.md
  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/specs/cli-validate/spec.md
📚 Learning: 2025-10-22T06:05:06.615Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/changes/*/specs/**/spec.md : Use ADDED, MODIFIED, REMOVED, or RENAMED sections when authoring deltas; place changed requirements under the correct operation header

Applied to files:

  • openspec/specs/cli-validate/spec.md
  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/proposal.md
  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/tasks.md
  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/specs/cli-validate/spec.md
📚 Learning: 2025-10-22T06:05:06.615Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/{specs/**/spec.md,changes/*/specs/**/spec.md} : Every requirement must include at least one scenario, formatted exactly with a '#### Scenario: <name>' header (no bullets or bold)

Applied to files:

  • openspec/specs/cli-validate/spec.md
  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/tasks.md
  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/specs/cli-validate/spec.md
📚 Learning: 2025-10-22T06:05:06.615Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/changes/*/specs/**/spec.md : For MODIFIED requirements, paste the full existing requirement block (header through scenarios) and ensure the header text matches exactly (whitespace-insensitive)

Applied to files:

  • openspec/specs/cli-validate/spec.md
  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/tasks.md
  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/specs/cli-validate/spec.md
📚 Learning: 2025-10-22T06:05:06.615Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/changes/*/specs/**/spec.md : Use RENAMED when only the requirement name changes; if behavior changes too, use RENAMED plus MODIFIED referencing the new name

Applied to files:

  • openspec/specs/cli-validate/spec.md
  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/proposal.md
  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/tasks.md
  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/specs/cli-validate/spec.md
📚 Learning: 2025-10-22T06:05:06.615Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Validate proposals and specs with 'openspec validate <item> --strict' and fix all issues before sharing

Applied to files:

  • openspec/specs/cli-validate/spec.md
  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/proposal.md
  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/tasks.md
  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/specs/cli-validate/spec.md
📚 Learning: 2025-10-22T06:05:06.615Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/changes/archive/** : Archive completed changes under openspec/changes/archive/YYYY-MM-DD-<name>/ and run 'openspec validate --strict' post-archive; update specs/ if capabilities changed

Applied to files:

  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/proposal.md
  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/tasks.md
  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/specs/cli-validate/spec.md
📚 Learning: 2025-10-22T06:05:06.615Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/changes/*/{proposal.md,tasks.md,design.md,specs/**/spec.md} : Scaffold each change with proposal.md, tasks.md, optional design.md, and delta spec files under openspec/changes/<change-id>/specs/<capability>/spec.md

Applied to files:

  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/proposal.md
  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/specs/cli-validate/spec.md
📚 Learning: 2025-10-22T06:05:06.615Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/changes/*/tasks.md : Track implementation steps in tasks.md and mark each completed item with '- [x]' once finished

Applied to files:

  • openspec/changes/archive/2025-11-05-relax-shall-must-validation/tasks.md
🔇 Additional comments (3)
openspec/changes/archive/2025-11-05-relax-shall-must-validation/proposal.md (1)

1-34: Well-articulated proposal with clear problem statement and solution.

The proposal effectively communicates the international accessibility goal and the pragmatic approach of downgrading to WARNING while preserving --strict enforcement. Structure and rationale are sound.

openspec/changes/archive/2025-11-05-relax-shall-must-validation/specs/cli-validate/spec.md (1)

1-32: Requirement is well-structured with comprehensive scenario coverage.

The requirement properly uses SHALL for normative wording and all four scenarios have correct #### Scenario: headers covering the key cases: normal validation, strict mode, non-English text, and English with SHALL/MUST keywords.

Per the AI summary, this file contains duplicate scenario sections. Please verify there is no redundant content within this file that should be deduplicated.

openspec/specs/cli-validate/spec.md (1)

219-247: New requirement is correctly formatted and properly positioned in the spec.

The requirement uses SHALL for normative wording and all four scenarios follow the correct #### Scenario: header format. The content appropriately completes the CLI validation specification with guidance for international support.

The AI summary mentions this file contains duplicate identical SHALL/MUST validation sections. Please verify there is no unintended duplication of the requirement+scenarios block elsewhere in this file that should be removed for clarity.

The prepare script runs before dependencies are installed, causing
build failures when installing from GitHub. Changed to postinstall
which runs after pnpm install completes.

This allows: npm install -g git+https://github.com/yha9806/OpenSpec.git
Enable direct installation from GitHub by committing built dist files:
- Uncommented dist/ in .gitignore to allow tracking build output
- Removed prepare script (causes build failures during git install)
- Kept prepublishOnly for npm registry releases

This allows users to install directly from GitHub:
npm install -g git+https://github.com/yha9806/OpenSpec.git

Build artifacts are now included so no compilation is needed during install.
Fixes npm/pnpm interaction issues on Windows.
Copy link
Contributor

@TabishB TabishB left a comment

Choose a reason for hiding this comment

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

I'm fine with this change, but like mentioned in the other PR, not too keen in checking in the /dist files.

For example this PR itself has an outdated dist that contains the old ERROR instead of the new WARNING. This will be too confusing to keep doing and very hard to check and review in the PR's itself. It adds a lot of clutter for not enough benefit.

Happy to get this change merged in otherwise though once those changes are removed. i.e reverting the .gitignore so /dist is not tracked anymore as well as reverting the package.json too

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.

Files for proposal in non-English will prevent the openspec tools validation.

2 participants