Problem
The body-load path checks realpath containment, but discovery parses SKILL.md frontmatter before applying an equivalent package-boundary check.
Evidence
A package's SKILL.md symlink pointed to an audit-owned file outside the package. listIntentSkills() returned the external file's description; loadIntentSkill() rejected the same skill with skill-path-outside-package.
Sources: metadata read, existing load protection.
Verified against main at 206e987 (@tanstack/intent 0.3.8), Node v24.12.0 on macOS arm64. Tests used installed dependencies and synthetic local fixtures.
Acceptance criteria
Scope and priority
Priority: Medium. Type: bug.
Recommended before v0.4.0 alongside #231 in a scoped discovery-safety change. This finding establishes metadata exposure, not arbitrary full-file disclosure. Preserve the existing load containment check.
Delivery group
Grouped with #231 as a discovery-safety fix: validate untrusted identifiers before emitting runnable commands and check package containment before reading skill metadata. Installer picker and permission-review work in #243 stays separate.
Problem
The body-load path checks realpath containment, but discovery parses SKILL.md frontmatter before applying an equivalent package-boundary check.
Evidence
A package's SKILL.md symlink pointed to an audit-owned file outside the package.
listIntentSkills()returned the external file's description;loadIntentSkill()rejected the same skill withskill-path-outside-package.Sources: metadata read, existing load protection.
Verified against
mainat206e987(@tanstack/intent0.3.8), Node v24.12.0 on macOS arm64. Tests used installed dependencies and synthetic local fixtures.Acceptance criteria
Scope and priority
Priority: Medium. Type: bug.
Recommended before v0.4.0 alongside #231 in a scoped discovery-safety change. This finding establishes metadata exposure, not arbitrary full-file disclosure. Preserve the existing load containment check.
Delivery group
Grouped with #231 as a discovery-safety fix: validate untrusted identifiers before emitting runnable commands and check package containment before reading skill metadata. Installer picker and permission-review work in #243 stays separate.