capabilities.lock
When you run capa install, CAPA resolves every GitHub or GitLab skill and plugin to an exact commit SHA and writes those SHAs into a lockfile next to your capabilities file. The next install reuses those SHAs so the build is reproducible and (usually) offline-fast.
Why a Lockfile?
Without a lockfile, every install asks Git or GitLab "what does main point to right now?" The answer drifts between teammates and between CI runs. The lockfile pins each declared source to the exact commit you installed last time, which buys you three things:
- Reproducibility: every
capa installacross machines and CI hits the same upstream commit until you intentionally update the lock. - Speed: if a locked SHA is already in the on-disk cache, CAPA skips the clone.
- Auditability: the locked SHA is the answer to "what code did we actually install?"
File Location and Format
The lockfile sits next to your capabilities file and matches its format, so diffs stay readable in version control:
capabilities.yaml→capabilities.lock(YAML body)capabilities.json→capabilities.lock(JSON body)
version: 1
generator: capa@1.7.1
generatedAt: 2026-05-14T18:50:00.000Z
skills:
- id: web-researcher
source: github
repo: vercel-labs/agent-skills
skillName: web-researcher
requestedVersion: null
requestedRef: null
resolvedRef: 9a3f1cb0e7d4e9f2c8a7b6d5c4b3a2918e7f6d5c
resolvedVersion: v1.4.2
plugins:
- id: notion-tools-7f9c1ab
source: github
repo: my-org/notion-plugin
uri: github:my-org/notion-plugin:v2.0.0
requestedVersion: v2.0.0
requestedRef: null
resolvedRef: 7f9c1ab3e8d2c4b5a6e7f8d9c0b1a2e3f4d5c6b7
resolvedVersion: v2.0.0
manifestName: notion-tools
manifestVersion: 2.0.0 {
"version": 1,
"generator": "capa@1.7.1",
"generatedAt": "2026-05-14T18:50:00.000Z",
"skills": [
{
"id": "web-researcher",
"source": "github",
"repo": "vercel-labs/agent-skills",
"skillName": "web-researcher",
"requestedVersion": null,
"requestedRef": null,
"resolvedRef": "9a3f1cb0e7d4e9f2c8a7b6d5c4b3a2918e7f6d5c",
"resolvedVersion": "v1.4.2"
}
],
"plugins": [
{
"id": "notion-tools-7f9c1ab",
"source": "github",
"repo": "my-org/notion-plugin",
"uri": "github:my-org/notion-plugin:v2.0.0",
"requestedVersion": "v2.0.0",
"requestedRef": null,
"resolvedRef": "7f9c1ab3e8d2c4b5a6e7f8d9c0b1a2e3f4d5c6b7",
"resolvedVersion": "v2.0.0",
"manifestName": "notion-tools",
"manifestVersion": "2.0.0"
}
]
} Fields
Top level
version: lockfile schema version (currently1).generator: capa version that wrote the file (e.g.capa@1.7.1).generatedAt: ISO 8601 timestamp of the last write.skills: array of locked github/gitlab skill entries.plugins: array of locked remote plugin entries.
Skill entry
id: skill ID from your capabilities file.source:githuborgitlab.repo:owner/repopath.skillName: the right-hand side of the repo string (the basename or path).requestedVersion: version or tag you asked for in capabilities, ornull.requestedRef: commit SHA you asked for, ornull.resolvedRef: the full commit SHA actually installed.resolvedVersion: tag the resolved SHA corresponds to (when discoverable), ornull.
Plugin entry
Same fields as skills, plus:
uri: plugin URI as written in capabilities (e.g.github:owner/repo:v1.0.0).manifestName: plugin name from the manifest.manifestVersion: version from the manifest, when present.
Lifecycle
- First install. Run
capa install. For each remote source, CAPA clones the repo, resolves the requested ref to a SHA, and writes the lockfile. - Subsequent installs. CAPA reads the lockfile, looks up the resolved SHA for each entry, and reuses the cached snapshot. No
git fetchneeded when the cache already has that SHA. - You change a version. If you bump the version in capabilities (e.g.
my-org/repo@skill:v1.2.0tomy-org/repo@skill:v1.3.0), the requested fields no longer match the lock entry and CAPA re-resolves. - You add a new entry. CAPA resolves it normally and appends to the lockfile.
- You remove an entry. CAPA prunes the dropped entry on the next install. If the file ends up empty, CAPA deletes it for you.
Updating to the Latest Code
To pull the latest commit for unpinned (or floating-ref) sources, bypass the lockfile with --no-cache:
capa install --no-cache CAPA re-resolves every remote source, rewrites the lockfile, and refreshes cache snapshots. Use this when you want to upgrade dependencies tracking main or any other moving ref.
Committing the Lockfile
Commit capabilities.lock to version control. It is what makes teammates and CI install the same code you did. Treat it like package-lock.json or poetry.lock:
- Commit it alongside changes to
capabilities.{yaml,json}. - Resolve lockfile merge conflicts by re-running
capa install. - Read lockfile diffs in PRs. A bumped SHA is an explicit signal that you upgraded a dependency.
Related Documentation
- capa install: writes the lockfile.
--no-cacheignores it. - capa cache: the on-disk snapshot store keyed by lockfile SHAs.
- Capabilities File: the companion file the lockfile pins.