You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Tracks the productionized implementation of RFC THV-0080: a project-level toolhive.lock.yaml that pins every project-scoped skill install (source, resolvedReference, digest, contentDigest, Sigstore provenance), plus thv skill sync / thv skill upgrade, signature verification on consume, and signing on push.
This replaces the original POC, PR #5715 (closed), which validated the approach but was too large to review/merge as one diff. The author's follow-up comment proposed a 14-PR split across two stacks; this issue tracks that split end-to-end.
The feature is gated behind TOOLHIVE_SKILLS_LOCK_ENABLED for the whole rollout — it stays inert on main until both stacks land, since the RFC treats reproducible pinning and Sigstore verification as one "v1" trust model, not two independently shippable halves.
Each PR includes its own tests (unit + E2E where applicable) and passes CI independently of the rest of the stack. A local review pass caught and fixed 6 correctness bugs across this stack before human review (digest-forgery via crafted paths, an unvalidated lock-file write path, an incomplete install rollback, inconsistent dependency-cycle keying, a sync-triggered field corruption, and a --fail-on-changes gate that mutated state before failing) — see each PR's commit history for details.
Stack 2 — Sigstore signing/verification (8 of 10 merged)
Current state: verification is fully implemented and released (v0.42.1), but the
feature remains gated on main — pkg/skills/feature_gate.go and six LockFileFeatureEnabled() call sites are still present, so users see nothing unless
they set TOOLHIVE_SKILLS_LOCK_ENABLED. #6139 is what removes that, and it is still
open. #6139 is stacked on #6137's branch, so #6137 lands first.
Validated end-to-end
stacklok/toolhive-skills-lock-example exercises the merged half against the real
catalog: a dockyard-signed skill is installed, its keyless Sigstore signature verified,
the observed identity TOFU-pinned into toolhive.lock.yaml, and a scheduled workflow
detects upstream drift and opens a PR. Building it surfaced four bugs, all fixed and
released in v0.42.1 — #6211, #6212, #6213, plus the thv ai-plugin counterparts of the
first two.
Follow-ups (tracked separately once reached)
Keyless push signing + Sigstore-staging E2E
Catalog-supplied expected identity (needs toolhive-core Provenance on Skill types)
Move pkg/skills/signer into toolhive-core next to the verification exports, so all
Sigstore code lives in one place (decided 2026-07-28, sequenced after PR14 because Sign pushes by default and remove the lock feature gate #6139 still modifies the package). The package imports nothing from toolhive, so the
move is mechanical.
Record the certificate's source ref and runner environment in lock provenance. The
recorded identity currently pins repository + workflow file but not the git ref, so a
signature produced by that workflow on any branch satisfies the policy.
Definition of done
All Stack 1 PRs merged with CI green (including CodeQL).
toolhive-core#176 released and consumed via a go.mod bump.
All Stack 2 PRs merged.
TOOLHIVE_SKILLS_LOCK_ENABLED gate removed in PR14, documented as the user-facing change.
Summary
Tracks the productionized implementation of RFC THV-0080: a project-level
toolhive.lock.yamlthat pins every project-scoped skill install (source, resolvedReference, digest, contentDigest, Sigstore provenance), plusthv skill sync/thv skill upgrade, signature verification on consume, and signing on push.This replaces the original POC, PR #5715 (closed), which validated the approach but was too large to review/merge as one diff. The author's follow-up comment proposed a 14-PR split across two stacks; this issue tracks that split end-to-end.
The feature is gated behind
TOOLHIVE_SKILLS_LOCK_ENABLEDfor the whole rollout — it stays inert onmainuntil both stacks land, since the RFC treats reproducible pinning and Sigstore verification as one "v1" trust model, not two independently shippable halves.Stack 1 — Lock file mechanics (✅ fully merged 2026-07-24)
Branch chain:
skills-lock/01-lockfile→ ... →skills-lock/06-cli-exitcodes, each PR targeting the previous one's branch.thv skill sync: restore project skills from the lock filethv skill upgrade: re-resolve pinned skills to newer contentEach PR includes its own tests (unit + E2E where applicable) and passes CI independently of the rest of the stack. A local review pass caught and fixed 6 correctness bugs across this stack before human review (digest-forgery via crafted paths, an unvalidated lock-file write path, an incomplete install rollback, inconsistent dependency-cycle keying, a sync-triggered field corruption, and a
--fail-on-changesgate that mutated state before failing) — see each PR's commit history for details.Stack 2 — Sigstore signing/verification (8 of 10 merged)
Branch chain:
skills-sig/07-provenance-schema→ ... →skills-sig/14-push-signing-ungate.container/verifier. Implemented in core#192, with core#197 following to reconstruct bundles for key-signed cosign signatures; both released and consumed via a go.mod bump.pkg/skills/verifierthin wrapper (Add skills verifier wrapping toolhive-core Sigstore exports #6091)pkg/skills/signer(cosign--keysigning) (Add Sigstore signer package for skill OCI artifacts #6023)--allow-unsigned(Verify skill signatures at install time #6129)sync --check(Re-verify stored signatures offline during sync #6131)--allow-signer-change(Block upgrades that change the signer identity #6132)skill info/skill install(Display recorded trust state to the user #6137)TOOLHIVE_SKILLS_LOCK_ENABLEDgate (the point the feature is fully "landed") (Sign pushes by default and remove the lock feature gate #6139)Current state: verification is fully implemented and released (v0.42.1), but the
feature remains gated on
main—pkg/skills/feature_gate.goand sixLockFileFeatureEnabled()call sites are still present, so users see nothing unlessthey set
TOOLHIVE_SKILLS_LOCK_ENABLED. #6139 is what removes that, and it is stillopen. #6139 is stacked on #6137's branch, so #6137 lands first.
Validated end-to-end
stacklok/toolhive-skills-lock-exampleexercises the merged half against the realcatalog: a dockyard-signed skill is installed, its keyless Sigstore signature verified,
the observed identity TOFU-pinned into
toolhive.lock.yaml, and a scheduled workflowdetects upstream drift and opens a PR. Building it surfaced four bugs, all fixed and
released in v0.42.1 — #6211, #6212, #6213, plus the
thv ai-plugincounterparts of thefirst two.
Follow-ups (tracked separately once reached)
Provenanceon Skill types)pkg/skills/signerinto toolhive-core next to the verification exports, so allSigstore code lives in one place (decided 2026-07-28, sequenced after PR14 because
Sign pushes by default and remove the lock feature gate #6139 still modifies the package). The package imports nothing from toolhive, so the
move is mechanical.
independently validated; affects the verify path this stack depends on.
recorded identity currently pins repository + workflow file but not the git ref, so a
signature produced by that workflow on any branch satisfies the policy.
Definition of done
TOOLHIVE_SKILLS_LOCK_ENABLEDgate removed in PR14, documented as the user-facing change.