Skip to content

Registry-level trust: skill linking is per-registry but trust is per-pack #234

Description

@saucam

Problem

Trust is modelled per pack{dir, trusted, registry} — but two things are
applied per registry, so the two granularities do not line up:

  • Skill linking links <registryRoot>/skills/* into ~/.claude/skills
    (PackService.#linkSkills), not <packDir>/skills/*.
  • Registries carry no trust at all — {name, url} only.

Today one registry hosts one pack for most users, so the mismatch is invisible.
It stops being invisible the moment a registry hosts several packs at different
trust levels.

Why it matters now

The hardening fix in #233 gates skill linking on pack trust: an untrusted pack's
skills are not linked, since their !…`` frontmatter runs a host shell at
expansion time. That is correct for the common case, but it papers over the
granularity mismatch:

  • Skills live at the registry root and are SHARED across every pack in that
    registry. "Link skills for pack P" actually links the whole registry's skills.
  • So if registry R hosts trusted pack A and untrusted pack B, trusting A links
    R's entire skill set — including skills that B (untrusted) also relies on.
    There is no way to express "trust A's skills but not B's" because at the
    filesystem level they are the same directory.

The current fix is sound ONLY because linking never clobbers and untrusted packs
contribute nothing on their own. It is not a clean trust boundary.

Options

  1. Registry-level trust. Add trusted to the registry entry {name, url, trusted} and gate #linkSkills on the registry's trust, not a pack's. This
    matches where skills actually live (per registry) and is the smallest model
    that is actually consistent. Trust becomes "I trust this source", which is
    also the more intuitive mental model (direnv allow is per-directory, not
    per-file).

  2. Per-pack skill linking. Link <packDir>/skills/* instead of
    <registryRoot>/skills/*, so pack trust maps 1:1 to the skills it governs.
    More precise, but requires packs to physically own their skills (today the
    ai-factory layout shares them at the registry root), i.e. a layout change and
    a migration.

Option 1 is the lower-friction fix and matches the filesystem reality. Option 2
is more precise but is a pack-layout change.

Scope

Touches the config schema (pipeline.registries[]), the install/addRegistry
flow, the wire format (RegistryWire), and the Studio UI that renders trust.
Deliberately kept OUT of the #233 PR, which stays focused on the runtime
expansion-time failure.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions