Skip to content

chore(package): make validation extensible - #20

Merged
egdev6 merged 5 commits into
egdev6:mainfrom
Reaan06:feat/issue-9-package-validation
Sep 21, 2026
Merged

egdev6 merged 5 commits into
egdev6:mainfrom
Reaan06:feat/issue-9-package-validation

Conversation

@Reaan06

@Reaan06 Reaan06 commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator

Closes #9

Type

  • Bug fix
  • New user-facing capability
  • Maintenance/tooling
  • Documentation only
  • Code refactoring
  • Breaking change

Summary

  • Derive the published package inventory recursively from the canonical skill tree.
  • Preserve an explicit top-level publication allowlist and require one canonical SKILL.md.
  • Add Node built-in unit tests and run them from npm test.

Changes

File Change
scripts/validate-package.mjs Added recursive inventory, canonical manifest enforcement, and testable publication helpers.
tests/validate-package.test.mjs Added seven unit tests for SemVer, release transitions, frontmatter, sections, links, tarball comparison, and inventory boundaries.
package.json Updated npm test to run validation and Node tests.

Test Plan

  • npm test
  • npm run pack:check
  • git diff --check
  • Shellcheck: N/A, no shell scripts changed.
  • Skills tested in an agent: N/A, no skill behavior changed.

Contributor Checklist

  • Linked the approved issue Make package validation extensible and add unit tests #9.
  • Added exactly one type:* label (type:chore).
  • Ran shellcheck where applicable; no shell scripts changed.
  • Skills tested where applicable; no skill behavior changed.
  • Updated the ODD task document with scope and evidence.
  • Used Conventional Commit messages.
  • No Co-Authored-By trailers.

@Reaan06 Reaan06 added the type:chore Maintenance, tooling, and release operations label Sep 17, 2026
@egdev6

egdev6 commented Sep 18, 2026

Copy link
Copy Markdown
Owner

Thanks for this, Reaan. I reviewed it by running it, not only reading it: an isolated copy of the branch on Node 22.14 and Node 24.20, plus the CI logs. The recursive inventory design looks right. Two things need to change before merge.

1. npm test never runs the unit tests (blocker)

package.json:22 uses node --test tests. On Node 22 and on Node 24 the test runner treats a bare directory as a module path, so the run dies immediately:

Error: Cannot find module '<workspace>/tests'   (not ok 1 - tests, exit 1)

That is exactly what CI does in run 35286551212: Package validation passed. followed by that failure, so the job is red. I reproduced it on Node 22.14.0 and Node 24.20.0, and on a neutral temp directory too, so it is the runner's behavior rather than something specific to this repository.

These forms do work (7/7 tests pass, exit 0, verified on Node 22 and Node 24):

"test": "npm run validate && node --test"

or node --test "tests/**/*.test.mjs".

Could you switch to one of those and re-run npm test on Node 22 and Node 24? The npm test checkbox in the test plan and the evidence in odd/tasks/issue-9-package-validation.md also need the Node version used, because the current claim does not reproduce as written.

2. package.json changes without a version bump, so the release workflow fails on main (high)

tag-release.yml only exits early when package.json is untouched (git diff --quiet "$BEFORE" "$GITHUB_SHA" -- package.json). Because this PR edits the test script, that guard no longer applies and the step reaches node scripts/validate-package.mjs --release-transition 0.1.0 0.1.0, which exits 1 with Release version must strictly increase SemVer precedence: 0.1.0 -> 0.1.0 under set -euo pipefail.

This is already the state of main: run 35189816887 failed the same way after #8 merged, which also touched package.json without a version change. So it is not a bug this PR introduces, but merging it adds another occurrence. The guard cannot distinguish "version changed" from "package.json changed", and fixing that is outside #9's scope, so it is my call to make in a separate change. Flagging it so the red run after merge is expected and tracked rather than surprising.

3. The derived inventory does not match what npm actually publishes (medium)

Both directions of the mismatch showed up while I probed the acceptance criteria:

  • A file npm refuses to publish but the walker still sees makes validation fail. With a .DS_Store (already in .gitignore) or a symlink under skills/mobile-agent-orchestrator/, npm run validate reports npm package is missing allowlisted file: .... On macOS that will happen constantly.
  • A file npm will publish but that nobody declared is now accepted: a stray .log under the skill tree passes validation, where the old exact seven-file list rejected it as non-allowlisted. That is the relaxation Make package validation extensible and add unit tests #9 asked for, so I am not treating it as a blocker, but it does mean the published surface is now defined by the filesystem instead of by declaration. A short allowlist of extensions or subdirectories (Markdown only under references/, for example) would keep the guard meaningful.

Smaller notes

  • The canonical SKILL.md error prints twice, because discoverPackageInventory() runs both standalone (scripts/validate-package.mjs:417) and inside validateTarball.
  • The new tests cover the duplicate and misplaced SKILL.md cases, but not the missing one (found none has no test).
  • readDirectory on walk and on discoverPackageInventory, the validatePublishedInventory pass-through, the exported parseYamlScalar, and the path === "SKILL.md" branch have no consumer yet.
  • package.json has no engines field, so the test invocation stays unconstrained by the manifest.

What I verified as working

Every acceptance criterion except the test-running one: adding references/nested/extra.md passes without touching the validator, an unexpected top-level path is rejected as non-allowlisted, duplicate and missing SKILL.md fail validation, pi.skills enforcement is intact, the seven unit tests pass 7/7 when invoked correctly, npm run pack:check succeeds, and git diff --check is clean. Commits are conventional, there are no Co-Authored-By trailers, and the ODD task document records scope and non-goals honestly.

Nothing else is blocking from your side. Ping me when npm test is green on Node 22 and Node 24 and I will take another pass.

@Reaan06

Reaan06 commented Sep 18, 2026

Copy link
Copy Markdown
Collaborator Author

Fixed in commits 3d70c06 and 8edb14b.

The PR is ready for another review and merge decision.

Copilot AI 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.

🔵 Needs a closer look

Allowlisted directory roots are omitted from the derived inventory, which can reject legitimate package contents.

Pull request overview

This maintenance PR extends package validation with recursive inventory checks, canonical skill enforcement, and Node unit tests.

Changes:

  • Added recursive publication inventory validation.
  • Added seven validation tests.
  • Updated npm test to run validation and tests.
  • Documented scope and verification evidence.
File summaries
File Summary
tests/validate-package.test.mjs Adds validation helper and boundary tests.
scripts/validate-package.mjs Implements recursive inventory and publication validation.
package.json Runs package validation and Node tests.
odd/tasks/issue-9-package-validation.md Records task scope and verification evidence.
Review details

Suppressed comments (1)

scripts/validate-package.mjs:245

  • This drops every allowlisted directory entry from the derived inventory instead of expanding it. It works for skills/ only because skillFiles is added separately above, but adding the bin/, lib/, or test directories called out in issue #9 to publishedTopLevelPaths would leave their files out of expectedFiles, causing compareTarballFiles to reject the legitimate package contents. Expand allowlisted directory roots when deriving the inventory (while keeping the canonical-skill check separate), or represent those roots through an equivalent recursive mechanism.
  return [...publishedTopLevelPaths.filter((path) => !path.endsWith("/")), ...skillFiles];
  • Files reviewed: 4/4 changed files
  • Comments generated: 0
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@Reaan06

Reaan06 commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator Author

Addressed the review feedback about allowlisted directory roots.

The package inventory now recursively expands every allowlisted directory while preserving direct file entries and canonical skill validation. Added a regression test for bin/tool.js. npm test passes, including package validation and 8 Node tests.

@egdev6 egdev6 added the status:approved Approved for implementation and review label Sep 21, 2026
@egdev6

egdev6 commented Sep 21, 2026

Copy link
Copy Markdown
Owner

Approved, go ahead. I re-verified head 8dda2ac by running it: npm test is green on Node 22 and Node 24 and now executes all 8 tests, so the acceptance criteria in #9 are met end to end.

Two follow-ups I am tracking outside this PR, so there is nothing to change here: the derived inventory still disagrees with npm's ignore rules (a .DS_Store under the skill tree blocks validation), and the new allowlisted-directory branch stays unreachable until the files check is relaxed for the installer work.

Nice work on the fix, and thanks for turning it around quickly.

@egdev6
egdev6 merged commit 176bf27 into egdev6:main Sep 21, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status:approved Approved for implementation and review type:chore Maintenance, tooling, and release operations

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make package validation extensible and add unit tests

3 participants