Explore support for transitive skill dependencies via nested ai.json
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 8
- Forks
- 0
- Avg merge
- 6h 12m
- Merged PRs (30d)
- 19
Description
Summary
Explore/design support for transitive skill dependencies: allow a skill referenced in ai.json to itself declare an ai.json (at its repo root or skill path), and have spm recursively resolve and vendor those nested dependencies alongside the top-level ones.
This mirrors how Cargo/npm handle transitive deps, but spm's trust model (skills can carry executable agent instructions) means the blast radius of auto-fetching arbitrary git repos is larger, so this needs careful design before implementation.
Proposed mechanism
After resolver::resolve pins a skill to a commit, look inside the store checkout at <path>/ai.json (or the repo-root ai.json). If present, recursively resolve its skills map too, merging everything into one flat ai.lock, deduplicated by (git, commit, path) to avoid re-cloning/re-vendoring the same skill twice.
Open design questions to resolve before coding
- Supply-chain trust — auto-fetching arbitrary git repos transitively is a bigger risk than typical package managers since skills can influence agent behavior. Should this be opt-in (e.g.
spm add --with-deps, or an explicit manifest flag) rather than default-on, at least initially? - Version conflicts — if two skills (directly or transitively) require different tags/commits of the same dependency, what's the resolution policy? Error-on-conflict is safest; "first wins" is more npm-like but can be surprising.
- Cycles — need a visited-set keyed by resolved
(git, commit, path), not just skill name, to detect and safely handle dependency cycles. - Targets — does a transitively-resolved skill inherit the top-level
targets(Claude/Copilot), or can it declare its own subset? Likely should inherit, but needs confirming againstsrc/vendor/mod.rs'sfor_targetdispatch. - Lockfile shape — how does
ai.lock(src/lockfile.rs) represent the dependency graph vs. a flat list? Do we need to preserve "who depends on whom" for diagnostics/spm list?
Relevant code
src/resolver.rs— resolves a skill spec (tag/branch/commit) to an immutable commit SHA + store key.src/manifest.rs— the user-authoredai.jsonmodel.src/lockfile.rs— the generatedai.lockpin file.src/store.rs— global store management (one clone per commit).
Context
Originated from a design discussion in a prior session (2026-08-27, "Handle Skills Transitive Dependencies") exploring whether each skill could carry its own ai.json to declare further dependencies. No implementation has started; this issue tracks the design/decision work per the repo's "no task without a tracked issue" policy.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading src/resolver.rs and the manifest, lockfile, and store models in src/manifest.rs, src/lockfile.rs, and src/store.rs; inspect src/vendor/mod.rs for target dispatch. Compare the existing resolution and lockfile behavior with each open design question. Done means the trust, conflict, cycle, target, and lockfile policies are documented well enough to guide a later implementation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- git, rust
- Domain
- cli, devtools, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100