Skip to content

Conversation

@atman-33
Copy link

@atman-33 atman-33 commented Jan 25, 2026

Overview

Implements comprehensive validation for tasks.md files in OpenSpec changes. Ensures all changes include properly formatted implementation checklists with checkboxes and non-empty descriptions.

What Changed

Implementation (add-tasks-validation)

  • Validator Methods: Added validateTasksFile() and validateTasksContent() in src/core/validation/validator.ts

    • Checks file existence (ERROR if missing)
    • Validates at least one checkboxed task exists (ERROR if none)
    • Detects empty task descriptions (ERROR)
  • CLI Integration: Updated src/commands/validate.ts

    • New helper method validateChangeReports() eliminates code duplication
    • Parallel validation of delta specs and tasks.md
    • Combined error reporting
  • Shared Patterns: Unified checkbox validation with task-progress.ts

    • TASK_CHECKBOX_PATTERN: /^[-*]\s+\[[xX\s]\]/
    • EMPTY_TASK_PATTERN: /^[-*]\s+\[[xX\s]\]\s*$/

Testing

  • All existing tests passing (1198 tests)
  • New test: "fails validation when tasks.md is missing"
  • Fixed missing fixture: test/fixtures/tmp-init/openspec/changes/c1/tasks.md

Documentation

  • Updated openspec/specs/cli-validate/spec.md with 2 new requirements

Validation Rules

File Existence (ERROR)

  • tasks.md must exist in change directory

Checkbox Presence (ERROR)

  • At least one line must have checkbox: - [ ], - [x], - [X]
  • Error if no checkboxes found

Task Descriptions (ERROR)

  • Checkboxed lines must have non-empty descriptions
  • Reports line numbers for empty tasks

Related Issue

Closes #354 - Implement tasks.md checkbox validation

Checklist

  • Implementation complete and tested
  • All tests passing (1198/1198)
  • Code follows project conventions
  • No breaking changes

Notes

  • Minimal Scope: Focused on file existence, checkbox presence, and empty description detection (no format warnings)
  • Error-Level Only: All checks are ERROR-level (required), no WARNINGs to keep validation strict
  • Pattern Reuse: Shares checkbox patterns with existing task-progress.ts to ensure consistency
  • Code Quality: Extracted validateChangeReports() helper to eliminate duplication in CLI integration
  • Backward Compatible: No breaking changes to existing validation system

Summary by CodeRabbit

  • New Features

    • Added validation for tasks.md during the validate command: checks file presence, ensures at least one checkboxed task, and flags empty task descriptions. Errors include line numbers and appear in the validation summary. Validation reuses the existing checkbox detection behavior and aggregates with other validation results.
  • Tests

    • Added tests covering missing files, formatting, empty descriptions, CRLF cases, and integration with change validation.

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

@atman-33 atman-33 requested a review from TabishB as a code owner January 25, 2026 12:48
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 25, 2026

📝 Walkthrough

Walkthrough

Adds validation for tasks.md: checks file presence, requires at least one checkboxed task, and reports empty task descriptions with line numbers. Integrates tasks validation into the openspec validate <change-id> flow alongside spec validation.

Changes

Cohort / File(s) Summary
Core Validation Logic
src/core/validation/validator.ts
Adds validateTasksFile() and private validateTasksContent() to enforce tasks.md presence, detect checkboxed tasks, and report empty descriptions with line numbers. Introduces TASK_CHECKBOX_PATTERN / EMPTY_TASK_PATTERN.
Validation Command Integration
src/commands/validate.ts
Adds validateChangeReports() to run/merge delta-spec and tasks validation; replaces direct spec-only validation calls in per-item and bulk flows.
Pattern Exports
src/utils/task-progress.ts
Exports TASK_PATTERN and COMPLETED_TASK_PATTERN regex constants for reuse by the validator.
Unit Tests
test/core/validation.test.ts
Adds suites for validateTasksContent (3 tests: valid, missing checkbox tasks, empty descriptions) and validateTasksFile (2 tests: missing file, valid file).
Integration Tests & Fixtures
test/commands/validate.test.ts, test/fixtures/.../openspec/changes/*/tasks.md
Adds fixtures with tasks.md (c1, dup, CRLF variants) and a CLI test asserting failure when tasks.md is missing.
Documentation & Specs
openspec/changes/archive/2026-01-25-add-tasks-validation/*, openspec/specs/cli-validate/spec.md
Adds proposal, spec delta, implementation notes, and updates main spec with scenarios and checkbox pattern requirements.

Sequence Diagram(s)

sequenceDiagram
    participant CLI as "CLI (openspec validate)"
    participant Validator as "Validator"
    participant FS as "Filesystem"
    participant Reporter as "Report Merger"

    CLI->>Validator: request validate change <id>
    Validator->>FS: read change delta/spec files
    Validator->>FS: read `tasks.md`
    alt tasks.md present
        Validator->>Validator: validateTasksContent()
    else tasks.md missing
        Validator->>Validator: emit missing-file issue
    end
    Validator->>Reporter: send spec validation report
    Validator->>Reporter: send tasks validation report
    Reporter->>CLI: merged validation summary & issues
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • TabishB

Poem

🐰 A checkboxed task in every change,
No empty lines—we rearrange!
Validation hops across the flow,
From files to specs, the tests now show.
Tasks.md is checked with bunny flair! 🐇✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the main change: adding tasks.md validation with checkbox and content checks, which is the primary focus of this changeset.
Linked Issues check ✅ Passed The PR fully addresses issue #354 by implementing checkbox format detection via TASK_CHECKBOX_PATTERN and validation that rejects non-checkbox task entries.
Out of Scope Changes check ✅ Passed All changes are directly related to tasks.md validation requirements: validator methods, pattern exports, CLI integration, tests, and spec documentation with no unrelated modifications.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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


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 Jan 25, 2026

Greptile Overview

Greptile Summary

This PR adds comprehensive validation for tasks.md files in OpenSpec changes, ensuring all changes include properly formatted implementation checklists.

Key Changes:

  • Added validateTasksFile() and validateTasksContent() methods to Validator class that check for file existence, checkbox presence, and empty descriptions
  • Integrated tasks.md validation into CLI via new validateChangeReports() helper that runs delta and tasks validation in parallel
  • Reused existing TASK_PATTERN from task-progress.ts for consistency across the codebase
  • Added comprehensive test coverage with both unit tests for the validation logic and integration tests for the CLI flow
  • Updated specification to document the new validation requirements

Validation Rules Enforced:

  1. File existence (ERROR if missing)
  2. At least one checkboxed task present (ERROR if none)
  3. No empty task descriptions (ERROR with line numbers)

Code Quality:

  • Eliminated code duplication by extracting validateChangeReports() helper method
  • Proper error handling for file system operations
  • All 1198 tests passing
  • Backward compatible - no breaking changes to existing validation system

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The implementation is well-tested with comprehensive unit and integration tests (1198 passing), follows existing patterns (reuses TASK_PATTERN from task-progress.ts), includes proper error handling, eliminates code duplication with the validateChangeReports() helper, and adds valuable validation to prevent incomplete tasks.md files. The changes are backward compatible and only add new validation checks without modifying existing behavior.
  • No files require special attention

Important Files Changed

Filename Overview
src/core/validation/validator.ts Added validateTasksFile() and validateTasksContent() methods for tasks.md validation with proper error handling
src/commands/validate.ts Added validateChangeReports() helper to combine delta and tasks validation, eliminating code duplication
src/utils/task-progress.ts Exported existing TASK_PATTERN and COMPLETED_TASK_PATTERN for reuse in validator
test/core/validation.test.ts Added comprehensive unit tests for tasks.md validation covering all scenarios
test/commands/validate.test.ts Added integration test for missing tasks.md file and updated fixtures with tasks.md files

Sequence Diagram

sequenceDiagram
    participant User
    participant CLI as ValidateCommand
    participant Val as Validator
    participant FS as FileSystem
    
    User->>CLI: openspec validate <change-id>
    CLI->>CLI: validateByType('change', id)
    CLI->>CLI: validateChangeReports(changeDir, validator)
    
    par Parallel Validation
        CLI->>Val: validateChangeDeltaSpecs(changeDir)
        Val->>FS: Read spec delta files
        FS-->>Val: Delta content
        Val-->>CLI: Delta report
    and
        CLI->>Val: validateTasksFile(changeDir)
        Val->>FS: readFile(tasks.md)
        alt File exists
            FS-->>Val: tasks.md content
            Val->>Val: validateTasksContent(content)
            Val->>Val: Check TASK_CHECKBOX_PATTERN
            Val->>Val: Check EMPTY_TASK_PATTERN
            Val-->>CLI: Tasks report (valid/errors)
        else File missing
            FS-->>Val: ENOENT error
            Val-->>CLI: Tasks report (ERROR: required)
        end
    end
    
    CLI->>CLI: Combine reports
    CLI->>User: Display validation results
    CLI->>User: Set exit code (0 or 1)
Loading

@vibe-kanban-cloud
Copy link

Review Complete

Your review story is ready!

View Story

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

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

🤖 Fix all issues with AI agents
In `@openspec/specs/cli-validate/spec.md`:
- Around line 231-233: Update the spec's regex to match the implementation's
exported TASK_PATTERN used in task-progress.ts: change `/^[-*]\s+\[[xX\s]\]/` to
`/^[-*]\s+\[[\sx]\]/i` so the documented pattern and the TASK_PATTERN constant
(and its case-insensitive behavior) are identical.

In `@src/core/validation/validator.ts`:
- Around line 305-334: The checkbox regexes in validateTasksContent do not allow
leading whitespace so nested tasks like "  - [ ] Subtask" are missed; update the
TASK_CHECKBOX_PATTERN and EMPTY_TASK_PATTERN to accept optional leading
whitespace (e.g., prepend \s* to the existing patterns) so validateTasksContent
correctly detects and validates indented checkbox lines (refer to
TASK_CHECKBOX_PATTERN, EMPTY_TASK_PATTERN and the validateTasksContent method).
🧹 Nitpick comments (1)
test/commands/validate.test.ts (1)

138-161: Good test coverage for missing tasks.md scenario.

The test properly validates the error condition. Consider adding integration tests for other spec scenarios (empty task descriptions, no checkboxed tasks) for comprehensive coverage, though unit tests in validation.test.ts may already cover these.

Comment on lines +305 to +334
private validateTasksContent(content: string): ValidationIssue[] {
const issues: ValidationIssue[] = [];
const lines = content.split(/\r?\n/);
let hasCheckbox = false;

lines.forEach((line, index) => {
if (TASK_CHECKBOX_PATTERN.test(line)) {
hasCheckbox = true;
if (EMPTY_TASK_PATTERN.test(line)) {
const lineNumber = index + 1;
issues.push({
level: 'ERROR',
path: `tasks.md:${lineNumber}`,
message: 'Empty task description',
line: lineNumber,
});
}
}
});

if (!hasCheckbox) {
issues.push({
level: 'ERROR',
path: 'tasks.md',
message: 'tasks.md must contain at least one checkboxed task',
});
}

return issues;
}
Copy link
Contributor

@coderabbitai coderabbitai bot Jan 25, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, let's find where TASK_CHECKBOX_PATTERN and EMPTY_TASK_PATTERN are defined
rg -n 'TASK_CHECKBOX_PATTERN|EMPTY_TASK_PATTERN' src/core/validation/validator.ts -A 1 -B 1

Repository: Fission-AI/OpenSpec

Length of output: 392


🏁 Script executed:

#!/bin/bash
# Check if any tasks.md files exist and contain nested checkboxes
find . -name 'tasks.md' -type f | head -20

Repository: Fission-AI/OpenSpec

Length of output: 1443


🏁 Script executed:

#!/bin/bash
# Search for nested checkbox patterns in the codebase
rg -n '^\s+[-*]\s+\[' --glob '*.md' | head -50

Repository: Fission-AI/OpenSpec

Length of output: 7348


🏁 Script executed:

#!/bin/bash
# Look for test files related to validator
fd -e test.ts -e spec.ts -e test.js validator

Repository: Fission-AI/OpenSpec

Length of output: 45


🏁 Script executed:

#!/bin/bash
# Find TASK_PATTERN definition
rg -n 'const TASK_PATTERN' src/core/validation/validator.ts -A 1 -B 1

Repository: Fission-AI/OpenSpec

Length of output: 45


🏁 Script executed:

#!/bin/bash
# Search for test files related to validator in the codebase
fd -type f -name '*validator*' | grep -E '\.(test|spec)\.'

Repository: Fission-AI/OpenSpec

Length of output: 233


🏁 Script executed:

#!/bin/bash
# Check if there are any tests that validate nested tasks
rg -l 'validateTasksContent|TASK_CHECKBOX_PATTERN|nested.*task' --glob '*.test.ts' --glob '*.spec.ts'

Repository: Fission-AI/OpenSpec

Length of output: 91


🏁 Script executed:

#!/bin/bash
# Get more context around TASK_PATTERN definition in validator.ts
head -25 src/core/validation/validator.ts

Repository: Fission-AI/OpenSpec

Length of output: 1020


🏁 Script executed:

#!/bin/bash
# Check test file for nested task test cases
cat test/core/validation.test.ts

Repository: Fission-AI/OpenSpec

Length of output: 17346


🏁 Script executed:

#!/bin/bash
# Find the definition of TASK_PATTERN in task-progress.js
find . -name 'task-progress.js' -o -name 'task-progress.ts' | head -5

Repository: Fission-AI/OpenSpec

Length of output: 91


🏁 Script executed:

#!/bin/bash
# Get TASK_PATTERN definition
rg -n 'TASK_PATTERN' src/utils/ -B 2 -A 2

Repository: Fission-AI/OpenSpec

Length of output: 793


Support nested checkbox tasks in validation patterns.

The current patterns (/^[-*]\s+\[[\sx]\]/i and /^[-*]\s+\[[xX\s]\]\s*$/) only match checkboxes at the line start. Nested tasks with leading whitespace (e.g., - [ ] Subtask) are actively used in the repository (e.g., openspec/changes/archive/2025-08-13-add-archive-command/tasks.md) but will not be detected or validated.

Update both patterns to allow optional leading whitespace:

Suggested changes
-export const TASK_PATTERN = /^[-*]\s+\[[\sx]\]/i;
-export const COMPLETED_TASK_PATTERN = /^[-*]\s+\[x\]/i;
+export const TASK_PATTERN = /^\s*[-*]\s+\[[\sx]\]/i;
+export const COMPLETED_TASK_PATTERN = /^\s*[-*]\s+\[x\]/i;

And in validator.ts:

-const EMPTY_TASK_PATTERN = /^[-*]\s+\[[xX\s]\]\s*$/;
+const EMPTY_TASK_PATTERN = /^\s*[-*]\s+\[[xX\s]\]\s*$/;
🤖 Prompt for AI Agents
In `@src/core/validation/validator.ts` around lines 305 - 334, The checkbox
regexes in validateTasksContent do not allow leading whitespace so nested tasks
like "  - [ ] Subtask" are missed; update the TASK_CHECKBOX_PATTERN and
EMPTY_TASK_PATTERN to accept optional leading whitespace (e.g., prepend \s* to
the existing patterns) so validateTasksContent correctly detects and validates
indented checkbox lines (refer to TASK_CHECKBOX_PATTERN, EMPTY_TASK_PATTERN and
the validateTasksContent method).

Copy link
Author

Choose a reason for hiding this comment

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

Since this regular expression is already used in existing code, the change will be put on hold for now. 🤔

Copy link
Contributor

Choose a reason for hiding this comment

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

@atman-33, understood! Since TASK_PATTERN is shared across the codebase (including task-progress.ts), changing it would have broader implications. It makes sense to evaluate the impact on all consumers before making that adjustment.

Feel free to revisit this when you're ready to handle nested tasks uniformly across the validation and progress tracking features.

@atman-33
Copy link
Author

Thanks for reviewing! Let me know if you have any questions.

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.

Tasks not always formatted as checkboxes

1 participant