Skip to content

Reject or explicitly model descendant SKILL.md files in skillset members #43

Description

@jon-devlapaz

Problem

Tink validates each declared member root, then recursively copies the entire member tree. If that tree contains another SKILL.md, the descendant is copied and covered by the digest but is not:

  • validated as a skill;
  • listed or counted;
  • collision-checked;
  • represented in the receipt as a member.

The descendant becomes opaque payload even though runtimes may discover or interpret it as a skill.

Relevant code: source_member_root and installed-tree validation in src/skillsets.rs, plus recursive tree copy in src/skills.rs.

Proposed change

For the current flat member schema, recursively detect and reject any descendant SKILL.md below a declared member root. Return an actionable error explaining that the source must be split at a different sourceRoot or requires a future nested-member contract.

Do not partially publish the project or library on failure.

A later design may introduce explicit nested member paths, but nested skills must not remain invisible.

Acceptance

  • A normal member tree without descendant skills installs unchanged.
  • A member containing child/SKILL.md fails before publication.
  • Failure leaves neither a project root nor a library deposit.
  • The error identifies both the declared member and descendant path.
  • Receipt/check/list counts cannot silently omit a copied skill root.

Priority

P0 — managed-content integrity.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingskillset-auditFindings from the 2026-08-09 skillset library audit

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions