Documentation
¶
Overview ¶
Package skilllock owns `.agent-layer/skills.lock.json`, the machine-managed record of what Agent Layer actually imported from each configured Git source.
The lockfile is the canonical merge base for every skill import operation: it records the resolved source ref, commit, and upstream tree hash for each imported skill so pull and push can reconcile local edits without inferring state. It is schema-versioned, stable-sorted, strictly decoded, and written atomically so a partially written file can never be mistaken for valid state.
Index ¶
Constants ¶
const ( // TrackingTracked follows the configured branch on `al skills pull`. TrackingTracked = "tracked" // TrackingPinned holds the locked commit until an explicit retarget. TrackingPinned = "pinned" )
Tracking modes recorded for an imported skill. They are declared here because the lockfile is where they are persisted; internal/config exposes the same values as its configuration vocabulary.
const ( // RefKindBranch marks a ref resolved to refs/heads/<name>. RefKindBranch = "branch" // RefKindTag marks a ref resolved to refs/tags/<name>. RefKindTag = "tag" // RefKindCommit marks a ref given directly as an object id. RefKindCommit = "commit" )
Ref kinds recorded from remote resolution evidence. Offline code paths read these instead of guessing whether a configured ref names a branch.
const Version = 1
Version is the current lockfile schema version. A file recording a different version is rejected rather than guessed at.
Variables ¶
var ErrMalformed = errors.New("skill lock file is malformed")
ErrMalformed reports that a lockfile exists but cannot be trusted. Import operations preserve local content and fail the affected imports instead of inventing a merge base.
var ErrMissing = errors.New("skill lock file does not exist")
ErrMissing reports that no lockfile exists yet. Callers distinguish this from a malformed lockfile because an absent file is the normal state of a project with no imports, while a malformed one must fail loudly.
Functions ¶
func ValidateRepository ¶
ValidateRepository rejects a repository reference that embeds a literal credential, while accepting one that references a secret by placeholder.
A repository URL is written into config.toml, copied into this lockfile, and printed in status output and Git command errors. A literal secret would be published to all three, so it is refused. A `${AL_*}` placeholder is not a secret: the placeholder text is what stays canonical everywhere, and the value it names is resolved only at the Git access boundary. That mirrors how MCP server URLs and headers reference secrets.
A literal credential can reach a URL three ways, and all three are refused: a password component, userinfo on any scheme that is not a known identity-only transport, and a value under a secret-like query key. Only the scp-like `user@host:path` form and an `ssh://user@host/path` or `git://user@host/path` username are ordinary identifiers rather than secrets, so only those stay accepted literally.
Types ¶
type Entry ¶
type Entry struct {
// Name is the validated skill name and the local directory name under
// .agent-layer/skills-imported/.
Name string `json:"name"`
// Repository is the configured source repository.
Repository string `json:"repository"`
// Selector is the positive configuration selector that produced this entry.
// Repository and selector together identify exactly one configured block.
Selector string `json:"selector"`
// SelectedPath is the repository-relative skill root path.
SelectedPath string `json:"selected_path"`
// ConfiguredRef is the block's configured ref, empty when the default branch
// is requested. A change here is a retarget, not a removal plus addition.
ConfiguredRef string `json:"configured_ref"`
// ResolvedRef is the actual ref resolved from the remote: a branch name, a
// tag name, or the commit id when the configured ref was an object id.
ResolvedRef string `json:"resolved_ref"`
// RefKind is remote-resolved evidence of what ResolvedRef names.
RefKind string `json:"ref_kind"`
// Tracking is the resolved tracking mode, RefKindBranch sources may track.
Tracking string `json:"tracking"`
// Commit is the resolved source commit that TreeHash was taken from.
Commit string `json:"commit"`
// TreeHash is the canonical hash of the upstream skill tree at Commit. It is
// the immutable merge base; local edits never replace it.
TreeHash string `json:"tree_hash"`
}
Entry is one imported skill's recorded upstream state.
type File ¶
File is the complete on-disk lock document.
func Load ¶
Load reads and strictly validates the lockfile at path.
A missing file returns ErrMissing so callers can distinguish "no imports yet" from corruption. Any structural problem returns an error wrapping ErrMalformed.
func Parse ¶
Parse decodes lock data, rejecting unknown fields, unknown schema versions, and entries that are missing required identity or merge-base state. source is used for error context.
func (*File) Clone ¶
Clone returns a deep copy so an operation can build its next state without mutating the snapshot it was planned against.
func (*File) Marshal ¶
Marshal renders the deterministic serialized form written to disk.
The same invariants Parse enforces are checked here, so a producer bug can never persist state that the next Load would reject as malformed.