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
-
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).
-
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
Problem
Trust is modelled per pack —
{dir, trusted, registry}— but two things areapplied per registry, so the two granularities do not line up:
<registryRoot>/skills/*into~/.claude/skills(
PackService.#linkSkills), not<packDir>/skills/*.{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 atexpansion time. That is correct for the common case, but it papers over the
granularity mismatch:
registry. "Link skills for pack P" actually links the whole registry's skills.
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
Registry-level trust. Add
trustedto the registry entry{name, url, trusted}and gate#linkSkillson the registry's trust, not a pack's. Thismatches 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 allowis per-directory, notper-file).
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/addRegistryflow, 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
this falls out of.