fix: detect hidden requirements in main specs#966
Conversation
|
Task completed. I'll review this PR by examining the changes. Let me start by understanding the codebase and the diff. Powered by 1Code |
📝 WalkthroughWalkthroughAdds code-fence-aware Markdown parsing and a new spec-structure checker that detects stray delta headers and requirement headers outside the main "## Requirements" region; integrates these structural checks into validation and spec-apply/archive paths and adds tests covering positive and fenced-code negative cases. (48 words) Changes
Sequence Diagram(s)mermaid Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/core/parsers/markdown-parser.ts`:
- Around line 26-60: buildCodeFenceMask currently treats any line that starts
with a fence marker as a closing fence; change the closing-fence detection so
that only a line consisting solely of the fence marker (optionally surrounded by
whitespace) closes the active fence. In practice, keep getFenceMarker for
opening detection but when activeFence is set, validate the candidate closing
line with a stricter check (e.g., test the full line against a regex that
matches only whitespace + matching marker repeated >= activeFence.length +
optional trailing whitespace) before clearing activeFence; update
buildCodeFenceMask to use this stricter test so fenced blocks with trailing
content don't prematurely re-enable header parsing.
In `@src/core/parsers/spec-structure.ts`:
- Around line 1-4: Update the four header regexes to allow 0–3 leading spaces
(Markdown-valid indentation) and avoid matching 4+ space indented code blocks by
prefixing each pattern with a non-capturing optional-space group like (?:
{0,3}), e.g. change REQUIREMENTS_SECTION_HEADER, TOP_LEVEL_SECTION_HEADER,
DELTA_HEADER and REQUIREMENT_HEADER to start with /^(?: {0,3}).../ while keeping
the rest of each pattern (the header text, case-insensitivity and end anchors)
unchanged so headings are recognized when indented up to 3 spaces but not
mistaken for 4-space code fences.
In `@test/specs/source-specs-normalization.test.ts`:
- Around line 42-56: The test counts requirement headers from the raw markdown
(rawRequirementCount) which incorrectly includes headers inside fenced code
examples; update the test to compute rawRequirementCount from content with
fenced code blocks removed or ignored before applying REQUIREMENT_HEADER_PATTERN
(e.g., strip triple-backtick/tilde fences or use a helper to remove fenced
blocks), so that rawRequirementCount matches the visible headers the
MarkdownParser (parser.parseSpec / MarkdownParser) actually parses and keeps the
existing assertion comparing spec.requirements.length to rawRequirementCount.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 60737c7a-f139-4a13-ab4e-928abe08cca0
📒 Files selected for processing (11)
openspec/specs/cli-update/spec.mdopenspec/specs/openspec-conventions/spec.mdsrc/core/parsers/change-parser.tssrc/core/parsers/markdown-parser.tssrc/core/parsers/spec-structure.tssrc/core/specs-apply.tssrc/core/validation/validator.tstest/core/archive.test.tstest/core/parsers/markdown-parser.test.tstest/core/validation.test.tstest/specs/source-specs-normalization.test.ts
| const REQUIREMENTS_SECTION_HEADER = /^##\s+Requirements\s*$/i; | ||
| const TOP_LEVEL_SECTION_HEADER = /^##\s+/; | ||
| const DELTA_HEADER = /^##\s+(ADDED|MODIFIED|REMOVED|RENAMED)\s+Requirements\s*$/i; | ||
| const REQUIREMENT_HEADER = /^###\s+Requirement:\s*(.+)\s*$/; |
There was a problem hiding this comment.
Support Markdown-valid indentation bounds for headings/fences.
Current patterns can miss valid indented headings (1–3 spaces) and can over-match 4-space-indented fence-like lines.
💡 Proposed fix
-const REQUIREMENTS_SECTION_HEADER = /^##\s+Requirements\s*$/i;
-const TOP_LEVEL_SECTION_HEADER = /^##\s+/;
-const DELTA_HEADER = /^##\s+(ADDED|MODIFIED|REMOVED|RENAMED)\s+Requirements\s*$/i;
-const REQUIREMENT_HEADER = /^###\s+Requirement:\s*(.+)\s*$/;
+const REQUIREMENTS_SECTION_HEADER = /^\s{0,3}##\s+Requirements\s*$/i;
+const TOP_LEVEL_SECTION_HEADER = /^\s{0,3}##\s+/;
+const DELTA_HEADER = /^\s{0,3}##\s+(ADDED|MODIFIED|REMOVED|RENAMED)\s+Requirements\s*$/i;
+const REQUIREMENT_HEADER = /^\s{0,3}###\s+Requirement:\s*(.+)\s*$/;
- const fenceMatch = line.match(/^\s*(`{3,}|~{3,})(.*)$/);
+ const fenceMatch = line.match(/^\s{0,3}(`{3,}|~{3,})(.*)$/);Also applies to: 82-82
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/core/parsers/spec-structure.ts` around lines 1 - 4, Update the four
header regexes to allow 0–3 leading spaces (Markdown-valid indentation) and
avoid matching 4+ space indented code blocks by prefixing each pattern with a
non-capturing optional-space group like (?: {0,3}), e.g. change
REQUIREMENTS_SECTION_HEADER, TOP_LEVEL_SECTION_HEADER, DELTA_HEADER and
REQUIREMENT_HEADER to start with /^(?: {0,3}).../ while keeping the rest of each
pattern (the header text, case-insensitivity and end anchors) unchanged so
headings are recognized when indented up to 3 spaces but not mistaken for
4-space code fences.
alfred-openspec
left a comment
There was a problem hiding this comment.
Looks good. This closes the hidden-requirement parsing gap cleanly, adds the right guardrails in validation/archive, and covers the fenced-code edge case with solid tests.
alfred-openspec
left a comment
There was a problem hiding this comment.
Re-approving per request.
There was a problem hiding this comment.
♻️ Duplicate comments (1)
src/core/parsers/spec-structure.ts (1)
1-4:⚠️ Potential issue | 🟡 MinorSupport Markdown-valid indentation bounds for headings and fences.
Current patterns still require column-0 headings and allow 4+ space-indented fence-like lines. This can miss valid indented headings and over-match indented code blocks.
💡 Proposed fix
-const REQUIREMENTS_SECTION_HEADER = /^##\s+Requirements\s*$/i; -const TOP_LEVEL_SECTION_HEADER = /^##\s+/; -const DELTA_HEADER = /^##\s+(ADDED|MODIFIED|REMOVED|RENAMED)\s+Requirements\s*$/i; -const REQUIREMENT_HEADER = /^###\s+Requirement:\s*(.+)\s*$/; +const REQUIREMENTS_SECTION_HEADER = /^\s{0,3}##\s+Requirements\s*$/i; +const TOP_LEVEL_SECTION_HEADER = /^\s{0,3}##\s+/; +const DELTA_HEADER = /^\s{0,3}##\s+(ADDED|MODIFIED|REMOVED|RENAMED)\s+Requirements\s*$/i; +const REQUIREMENT_HEADER = /^\s{0,3}###\s+Requirement:\s*(.+)\s*$/; - const fenceMatch = line.match(/^\s*(`{3,}|~{3,})(.*)$/); + const fenceMatch = line.match(/^\s{0,3}(`{3,}|~{3,})(.*)$/); - const fenceMatch = line.match(/^\s*(`{3,}|~{3,})\s*$/); + const fenceMatch = line.match(/^\s{0,3}(`{3,}|~{3,})\s*$/);Also applies to: 82-82, 111-111
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/core/parsers/spec-structure.ts` around lines 1 - 4, The heading and fence regexes (REQUIREMENTS_SECTION_HEADER, TOP_LEVEL_SECTION_HEADER, DELTA_HEADER, REQUIREMENT_HEADER) currently require column-0 anchors and allow overly-indented fence-like lines; update each to accept up to three leading spaces per Markdown spec by changing the start anchor to allow 0–3 spaces (e.g., use a ^ {0,3} prefix) and also adjust any fence-detection regexes elsewhere to limit allowed indentation to at most three spaces (not four or more) so indented code blocks aren't over-matched while still recognizing valid indented headings.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@src/core/parsers/spec-structure.ts`:
- Around line 1-4: The heading and fence regexes (REQUIREMENTS_SECTION_HEADER,
TOP_LEVEL_SECTION_HEADER, DELTA_HEADER, REQUIREMENT_HEADER) currently require
column-0 anchors and allow overly-indented fence-like lines; update each to
accept up to three leading spaces per Markdown spec by changing the start anchor
to allow 0–3 spaces (e.g., use a ^ {0,3} prefix) and also adjust any
fence-detection regexes elsewhere to limit allowed indentation to at most three
spaces (not four or more) so indented code blocks aren't over-matched while
still recognizing valid indented headings.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 7019ab7b-5bc2-4e3b-9e33-4ca7be8cbbde
📒 Files selected for processing (4)
src/core/parsers/markdown-parser.tssrc/core/parsers/spec-structure.tstest/core/parsers/markdown-parser.test.tstest/specs/source-specs-normalization.test.ts
✅ Files skipped from review due to trivial changes (1)
- test/specs/source-specs-normalization.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- test/core/parsers/markdown-parser.test.ts
- src/core/parsers/markdown-parser.ts
- Update skill template parity hashes for rebased content - Move requirements outside ## Requirements section to fix findMainSpecStructureIssues validation (upstream Fission-AI#966) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Closes #954
Summary
### Requirement:blocks outside the parsed## Requirementssection in main specsTesting
Summary by CodeRabbit
Documentation
Bug Fixes
Tests