Skip to content

fix(validate-module): harden standalone module validation#97

Merged
bmadcode merged 3 commits into
bmad-code-org:mainfrom
armelhbobdad:fix/validate-module-standalone-robustness
Jun 22, 2026
Merged

fix(validate-module): harden standalone module validation#97
bmadcode merged 3 commits into
bmad-code-org:mainfrom
armelhbobdad:fix/validate-module-standalone-robustness

Conversation

@armelhbobdad

@armelhbobdad armelhbobdad commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

What

Three robustness fixes to validate-module.py for standalone single-skill modules.

Why

A correctly-structured, runnable standalone module currently gets false-positive findings when it (a) renames its merge scripts to the importable underscore form, (b) positions itself via bare sibling-module skill names, or (c) is validated by passing its own skill directory.

How

  • Accept either merge-config.py (scaffolder default) or merge_config.py (importable) for the two merge scripts.
  • Skip colon-less preceded-by/followed-by refs (cross-module positional, unresolvable here); still validate intra-module skill:action refs.
  • detect_standalone_module() now also matches when given the skill dir itself; skill-folder and orphan-entry checks resolve in both cases.

Testing

python3 skills/bmad-module-builder/scripts/tests/test-validate-module.py → 20 pass (3 new regression tests added). Targets current main (preceded-by/followed-by); independent of the unmerged fix/validate-module-csv-header branch.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation

    • Updated the module validation guide to clarify standalone validation accepts both dash-form and underscore-form merge script filenames.
  • Improvements

    • Enhanced standalone module checks to accept either merge script naming style.
    • Refined validation behavior for preceded-by/followed-by references and standalone CSV “orphan” reporting.
  • Tests

    • Added coverage for underscore merge scripts, validating a standalone skill directory directly, cross-module reference handling, and ensuring sibling CSV entries don’t mask standalone orphan findings.

Three robustness fixes to validate-module.py for standalone
single-skill modules:

- Accept importable underscore-named merge scripts (merge_config.py)
  in addition to the scaffolder's dash form (merge-config.py). Either
  is valid; a module may rename them to be importable from
  module-setup.md without that being a structural defect.
- Treat colon-less preceded-by/followed-by refs as cross-module
  positional references (bare sibling-module skill names) and skip
  them. Other installed modules aren't visible to the validator, so
  they can't be resolved and aren't defects; intra-module
  skill:action refs are still validated.
- Detect a standalone module when handed the skill directory itself,
  not only its parent folder (as the reference doc already promised).
  Skill-folder and orphan-entry checks now resolve in both cases.

Adds 3 regression tests (20 pass total); updates the reference doc.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 19, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 53e0368a-dbcb-4420-92c7-b3bd022fcd65

📥 Commits

Reviewing files that changed from the base of the PR and between d635a33 and c37c64e.

📒 Files selected for processing (1)
  • skills/bmad-module-builder/scripts/tests/test-validate-module.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • skills/bmad-module-builder/scripts/tests/test-validate-module.py

Walkthrough

validate-module.py is extended to accept either dash-form or underscore-form merge script filenames for standalone modules, to accept the skill directory itself as the validation target, and to skip colon-less preceded-by/followed-by refs. Matching tests and reference documentation are updated accordingly.

Changes

Standalone Module Validation Improvements

Layer / File(s) Summary
Dual merge-script filename acceptance
skills/bmad-module-builder/references/validate-module.md, skills/bmad-module-builder/scripts/validate-module.py
Reference doc updated to list both dash-form and underscore-form merge script names. validate() standalone branch adds a required_any check so either merge-config.py/merge-help-csv.py or merge_config.py/merge_help_csv.py satisfies the structural requirement. detect_standalone_module docstring expanded to document both accepted input shapes.
Skill-dir-as-input and orphan CSV detection
skills/bmad-module-builder/scripts/validate-module.py
skill_folders is set to the standalone directory's name and skill_parent to its parent so the validator accepts the skill directory itself as input. Orphan CSV entry check treats any CSV-referenced skill not in the single allowed skill_folders list as orphaned without filesystem scanning of the parent module directory.
Skip colon-less preceded-by/followed-by refs
skills/bmad-module-builder/scripts/validate-module.py
Reference validation now skips entries in preceded-by/followed-by that contain no :, treating them as cross-module bare skill refs and omitting them from intra-module capability validation.
Test fixture and new test cases
skills/bmad-module-builder/scripts/tests/test-validate-module.py
create_standalone_module gains merge_script_style parameter to emit either dash or underscore filenames. Four new tests cover underscore merge script acceptance, bare before/after ref handling, skill-dir-as-input with info.skill_dir, and sibling orphan CSV regression. __main__ tests list updated.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • bmad-code-org/bmad-builder#50: Previously modified the same standalone-module validation flow in validate-module.py and its tests, including merge script presence checks.
  • bmad-code-org/bmad-builder#92: Modified preceded-by/followed-by validation logic in validate-module.py, directly related to the colon-less ref skip added here.

Suggested reviewers

  • bmadcode

Poem

🐇 A dash or underscore, both paths lead home,
The skill dir itself may now freely roam.
Bare refs before and after? Just let them be,
No colon, no quarrel — validation runs free!
Hoppy little scripts, now flexible and bright ✨

🚥 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 title 'fix(validate-module): harden standalone module validation' directly reflects the main objective of the changeset, which is to fix robustness issues in standalone module validation.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
skills/bmad-module-builder/scripts/validate-module.py (1)

328-330: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

CLI help text is now stale for accepted input shape

Line 329 still says only “module’s skills folder”, but validation now also supports passing a standalone skill directory directly.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skills/bmad-module-builder/scripts/validate-module.py` around lines 328 -
330, The help text for the "module_dir" argument in the CLI parser is outdated
and only describes the module's skills folder scenario. Update the help string
to accurately reflect that the argument now accepts both a module's skills
folder (containing the setup skill and other skills) and a standalone skill
directory. This ensures users understand all accepted input shapes for the
module_dir parameter.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@skills/bmad-module-builder/scripts/validate-module.py`:
- Around line 232-239: The issue is that when validating a skill directory
directly (standalone_dir mode), setting skill_parent to standalone_dir.parent
makes the parent directory the reference point for validating in-module skills.
This causes sibling skill directories to be incorrectly treated as in-module
skills during orphan CSV validation, making the validation too permissive. Fix
this by setting skill_parent to standalone_dir itself instead of
standalone_dir.parent when in standalone mode, so that the orphan validation at
lines 249-254 only considers the specific skill directory being validated and
properly identifies true orphan CSV skill entries.

---

Outside diff comments:
In `@skills/bmad-module-builder/scripts/validate-module.py`:
- Around line 328-330: The help text for the "module_dir" argument in the CLI
parser is outdated and only describes the module's skills folder scenario.
Update the help string to accurately reflect that the argument now accepts both
a module's skills folder (containing the setup skill and other skills) and a
standalone skill directory. This ensures users understand all accepted input
shapes for the module_dir parameter.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c8570b1b-4c3f-48e8-a9e6-51c61968280c

📥 Commits

Reviewing files that changed from the base of the PR and between 4156901 and e9e257d.

📒 Files selected for processing (3)
  • skills/bmad-module-builder/references/validate-module.md
  • skills/bmad-module-builder/scripts/tests/test-validate-module.py
  • skills/bmad-module-builder/scripts/validate-module.py

Comment thread skills/bmad-module-builder/scripts/validate-module.py Outdated
Addresses CodeRabbit review on bmad-code-org#97: in direct skill-dir mode the
orphan check resolved CSV skills against the parent folder, so an
unrelated sibling skill directory could mask a true orphan entry.

For a standalone module, skill_folders already enumerates every valid
skill (just the standalone skill), so any other CSV skill is an orphan
— drop the parent-folder filesystem lookup entirely. The multi-skill
path still re-checks the filesystem for the setup skill.

Adds a regression test (sibling dir must not mask the orphan); 21 tests
pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@skills/bmad-module-builder/scripts/tests/test-validate-module.py`:
- Line 389: The variable `code` is unpacked from the return value of
`run_validate(skill_dir)` on line 389 but is never used in the test. Replace the
unused `code` variable with an underscore `_` to follow Python convention for
intentionally discarded values and to resolve the Ruff linter warning.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 55663afe-95c0-4179-9cdb-98cce84fae98

📥 Commits

Reviewing files that changed from the base of the PR and between e9e257d and d635a33.

📒 Files selected for processing (2)
  • skills/bmad-module-builder/scripts/tests/test-validate-module.py
  • skills/bmad-module-builder/scripts/validate-module.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • skills/bmad-module-builder/scripts/validate-module.py

Comment thread skills/bmad-module-builder/scripts/tests/test-validate-module.py
Addresses CodeRabbit nit on bmad-code-org#97: the orphan regression test unpacked
`code` without using it. Assert `code == 1` (the orphan makes
validation fail), which also strengthens the test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@bmadcode bmadcode merged commit fdda74f into bmad-code-org:main Jun 22, 2026
4 checks passed
@bmadcode

Copy link
Copy Markdown
Contributor

thanks @armelhbobdad - merged

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants