The reproducibility model
GSKILL’s central promise is that a skill environment can be reproduced byte-for-byte on any
machine, agent, or CI runner. This page explains how the two committed files that make that work
divide the job: skills.toml says what you want, skills-lock.json records what you got.
Intent vs reality — two files, one contract
Section titled “Intent vs reality — two files, one contract”-
Intent lives in
skills.toml, the file you edit: which source, which tracking constraint (a range like^2.0.0, an exact version, a tag, a branch, or a commit), which agents, which install mode, which overrides.install,update, andupgradeall read intent from here. -
Reality is everything resolution produced, recorded in
skills-lock.json: the sharedcomputedHash, and — under the per-entrygskillblock — the exact commit, resolved version, content hash, per-agent targets, and a projection of the intent it resolved from (requestedVersion,requestedRef,requestedCommit,declarationKind). It is machine-generated, deterministic, and never hand-edited. The projection exists so a lock can reproduce without the manifest and so a manifest can be generated for a project written before one existed; it is never read as intent when the manifest is present.
You commit both. The intent stays flexible (^2.0.0 lets update pick up 2.1.3 later); the
resolved reality pins the exact outcome so everyone on the team gets the same 2.1.3 today.
Moving is always an explicit act: gskill update re-resolves within the declared intent and
rewrites only the resolution, gskill upgrade changes the intent and then resolves it. See
the package lifecycle.
Interoperability
Section titled “Interoperability”The file is the shared project-level v1 format also written by compatible external tooling (such as
npx skills). GSKILL co-owns it losslessly: unknown fields and other tools’ entries survive every
rewrite byte-for-byte, and everything gskill-specific stays inside the per-entry gskill block.
Restore order: committed → cache → fetch
Section titled “Restore order: committed → cache → fetch”Because skill content is committed in the repository, a fresh clone
already is the reproduced environment. When gskill install does run, it reproduces from
skills-lock.json alone, cheapest layer first: committed content whose hash matches the lock is up
to date (zero network); missing content restores from the clone cache by the recorded commit; a
cold cache fetches exactly once from the recorded source.
What --frozen-lockfile guarantees
Section titled “What --frozen-lockfile guarantees”gskill install --frozen-lockfile is the reproducible-restore command:
- It restores exactly what the lockfile records.
- It never modifies the lockfile.
- It fails closed (exit
4) if an entry lacks thegskillmetadata a restore needs, or if an explicit--agentconflicts with the locked agents; integrity mismatches fail that skill closed (exit6) — without touching any agent directory.
That combination is what lets CI and teammates trust a restore: either they get precisely the locked environment, or they get a clear failure — never a silent, subtly-different install.
Determinism
Section titled “Determinism”For the lockfile to be worth committing, it must serialise the same way every time. GSKILL keeps key order stable, fixes indentation, and keeps non-reproducible data (timestamps, map iteration order, ambient environment) out of the fields that define content. Mutable references (like a branch) are resolved to an immutable commit before being written.