refactor(validate-skills): extract lint rules into a shared lib#379
refactor(validate-skills): extract lint rules into a shared lib#379nucliweb wants to merge 2 commits into
Conversation
…lint.js Split the skill validation rules out of the validate-skills.js CLI into a shared, importable scripts/lib/skill-lint.js: a pure lintSkillContent() with no I/O plus a thin lintSkill() file wrapper. validate-skills.js becomes a thin CLI over the lib. No behavior change to the validator's output or exit codes; this only makes the rules unit-testable for a follow-up test battery.
|
Hi @addyosmani @federicobartoli, could you take a look when you have a moment? |
|
I like where this is headed. A pure lintSkillContent() with no I/O is the right shape and makes the rules testable on their own. My one hesitation is timing: this touches the same file as a couple of other in-flight script PRs (the naming/description enforcement, the draft test battery), so I want to sequence it rather than rebase three ways. Can you hold while I clear those, or rebase once they land? |
|
Thanks, and that sequencing instinct is exactly why I split this out, so let me give you the current state, because I think the collision you are guarding against is already gone:
So this is already the sequenced, on-top-of-merged-work small piece, not one of three racing edits. PR-B (the Happy to hold if you would still rather clear the decks first, but there is nothing left for it to collide with that I can see. Shout if I am missing an in-flight PR you are tracking. |
|
Thanks for splitting this out, @nucliweb !! I took a deeper pass and I agree with the overall direction. The extraction is clean, the I/O boundary is much better, and the current CLI behavior is preserved.
|
Per review: the policy collections (REQUIRED_SECTIONS, SECTION_EXEMPT_SKILLS, SKILL_REF_PATTERNS, regexes) were exported by reference, so a consumer could mutate shared state and change lint results process-wide. Export only the linting functions; keep the policy collections private. No behavior change (validator output byte-identical).
|
Thanks for the deep pass. Encapsulated the exported policy state in On the heuristic limitations (YAML-subset frontmatter, substring section matching plus the recommended-vs-required contract question, missed or over-broad cross-ref patterns, and "Do not use when..." satisfying the positive trigger): agreed these are pre-existing validator behavior, not regressions from the extraction, and agreed they should be settled before PR-B's tests lock the current heuristics in as the contract. I'll capture them in a linked follow-up issue so PR-B references it and we decide bug-vs-intended per case first. Will link it here. |
|
Captured as #387. |
What
Extracts the skill validation rules out of the
validate-skills.jsCLI into a sharedscripts/lib/skill-lint.js: a purelintSkillContent()(no I/O) plus a thinlintSkill()file wrapper.validate-skills.jsbecomes a thin CLI over the lib.Why
The rules were only reachable by spawning the CLI, so they could not be unit-tested directly. Extracting a pure function makes them importable and testable, which unblocks a follow-up test battery (linter self-tests + per-skill checks). This PR is the small, behavior-preserving first half of that split, kept separate to avoid a large refactor of a hot file landing together with new test code.
No behavior change
node scripts/validate-skills.jsproduces byte-identical output and the same exit codes as before, verified against all 24 skills. One intentional string update: the exemption-guard error now points contributors toscripts/lib/skill-lint.js(where theSECTION_EXEMPT_SKILLSallowlist now lives); that path only fires on an exemption-bypass attempt, so no real skill output changes.Follow-up
PR-B will add the
node:testbattery, linter self-tests, and length metrics on top of this lib (supersedes the now-closed #324).