Add project-level skills lock file schema package#5892
Open
samuv wants to merge 2 commits into
Open
Conversation
RFC THV-0080 pins every project-scoped skill install to a committed toolhive.lock.yaml so teams get reproducible installs across machines, the same guarantee package-lock.json/Cargo.lock provide elsewhere. This package defines the v1 schema (entries, content digest, requiredBy) with no callers yet; skillsvc wiring follows in a later PR of the stack. Access is confined to the validated project root via os.Root (OS-enforced containment), not string validation alone.
3 tasks
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #5892 +/- ##
==========================================
- Coverage 71.63% 71.61% -0.02%
==========================================
Files 698 701 +3
Lines 71541 71746 +205
==========================================
+ Hits 51245 51383 +138
- Misses 16598 16668 +70
+ Partials 3698 3695 -3 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This was referenced Jul 21, 2026
Path validation rejected traversal but not control characters, so a crafted Path containing an embedded NUL and newline could reproduce the byte stream of an unrelated multi-file tree and collide with its digest. Save also never validated before writing, so a caller bug could persist an invalid lock file with no recovery through the package API. Also normalize repeated "./" prefixes idempotently.
15 tasks
Contributor
Author
|
Tracked in #5899 (RFC THV-0080 stack). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
toolhive.lock.yamlthat pins the exact content of every project-scoped skill install, giving skills the reproducibility guaranteepackage-lock.json/Cargo.lock/go.sumprovide elsewhere. This is the first PR of a stack productionizing the validated POC in Add project-level skills lock file (POC) #5715 into reviewable, independently-tested changes.pkg/skills/lockfile, a new leaf package with no callers yet: the lock file schema (Entry,Lockfile), a deterministic content-hash algorithm (ContentDigest) used for on-disk integrity verification, and load/save/upsert/remove operations. All filesystem access is confined to the validated project root viaos.Root(OS-enforced containment), not string path validation alone — this avoids the CodeQL "uncontrolled data used in path expression" findings that were flagged on the POC.Part of the production stack for #5715 (RFC THV-0080). Stack: 1/6 — lockfile → lock-service → install-hooks → sync → upgrade → cli-exitcodes. This PR has no consuming callers; wiring into
skillsvc.Installlands in PR3 of the stack.Type of change
Test plan
task test)task lint-fix)Table-driven tests cover round-trip load/save, unknown-version hard error, requiredBy cross-reference validation, golden contentDigest vectors (freezing the algorithm), a goroutine-hammer concurrency test against
UpsertEntry, and traversal/escape rejection. 89.9% statement coverage.Does this introduce a user-facing change?
No — this package has no callers yet.
Special notes for reviewers
Entrydeliberately omitsprovenance/unsigned(Sigstore fields) — those land in PR7 of the Sigstore stack, once Stack 1 (this stack) merges.mainbehind an env-var gate introduced in PR3, per the incremental-rollout plan — see that PR's description.contentdigest_test.gofreeze the dirhash algorithm; treat any future change to it as a lock-file format break, not a routine test update.🤖 Generated with Claude Code