Install
openclaw skills install skill-provenanceVersion tracking for Agent Skills bundles and their associated files across sessions, surfaces, and platforms. Use when creating, editing, versioning, valida...
openclaw skills install skill-provenanceSkill projects move between sessions, surfaces (Chat, IDE, CLI, Cowork),
platforms (Claude, Gemini CLI, Codex, Copilot), and local storage
(Obsidian, working directories, git repos). Version identity gets lost
when it lives only in filenames. A file renamed from SKILL_v4.md to
SKILL_v5.md with no internal record of what changed creates ambiguity.
This skill establishes three conventions that prevent that:
A skill bundle is a SKILL.md plus all associated files. Typical contents:
The skill itself (SKILL.md) and evals are the primary versioned artifacts. Scripts and outputs are tracked by the manifest but version with the bundle rather than independently. Handoff notes are optional convenience artifacts.
Files that can safely carry YAML frontmatter begin with a YAML frontmatter block (or extend an existing one) containing these fields:
---
skill_bundle: my-skill # bundle name, stable across versions
file_role: skill # skill | evals | script | output | handoff
version: 5 # integer, monotonically increasing
version_date: 2026-02-10 # date of this version
previous_version: 4 # null for v1
change_summary: >
Rewrote Phase 5 layout rules. Removed per-section page breaks.
Added content flow check. Added validation checklist as standalone final page.
---
version is an integer for per-file tracking. It counts revisions to
that specific file within the bundle. The bundle-level version
(bundle_version in MANIFEST.yaml) uses semver.
change_summary is required for every version after v1. One to three sentences. It must describe what changed, not just that something changed.
previous_version creates a chain. Any session can trace the lineage.
file_role values:
skill — the SKILL.md itselfevals — the evals.json filescript — generation scripts, utility scriptsoutput — rendered artifacts (.docx, .pdf)handoff — session handoff notessource — user-provided source material (tracked, not versioned)reference — documentation in references/ loaded on demandasset — templates, images, fonts in assets/ used in outputagents — platform UI metadata (e.g., Codex's agents/openai.yaml)For files that cannot safely carry YAML frontmatter (binary files and
strict-format files such as .json or executable .sh), the manifest
tracks their version and its version field is authoritative.
SKILL.md frontmatter constraint: The Agent Skills open standard
(agentskills.io) requires name and description. Different platforms
enforce different rules about additional fields:
| Platform | Allowed SKILL.md frontmatter |
|---|---|
| agentskills.io spec | name, description, license, metadata, compatibility, allowed-tools |
| Claude Chat / Settings UI | Same as spec. Claude's settings importer rejects unrecognized fields. |
| Claude Code | Spec fields plus extensions: disable-model-invocation, user-invocable, context, agent, model, hooks, argument-hint. These are Claude Code features, not part of the base spec. |
| Claude API | Skills uploaded via /v1/skills. Validates name and description. Supports metadata. |
| Gemini CLI (Google) | name and description only. Extra fields not officially supported. |
| Codex (OpenAI) | name and description only. Extra fields rejected. |
| GitHub Copilot / VS Code | Follows agentskills.io spec. |
| Cursor, Roo Code, Junie, others | Follows agentskills.io spec. See agentskills.io for the full adopter list (30+). |
For maximum portability, keep SKILL.md frontmatter to name and
description only. If the canonical bundle needs attribution or visible
SKILL.md metadata, use the spec's metadata field there and generate a
derived minimal copy for strict platforms:
---
name: my-skill
description: What the skill does.
metadata:
skill_bundle: my-skill
file_role: skill
version: 3
version_date: 2026-02-10
previous_version: 2
change_summary: >
Added Phase 6 validation step.
---
If targeting Codex or other strict platforms directly, omit metadata
from SKILL.md entirely. The manifest tracks SKILL.md's version either
way, so no version information is lost.
Note on spec support: The agentskills.io spec formally supports
metadata as an arbitrary key-value map, with version shown as an
example use. This means the metadata.version approach is now
spec-blessed, not a Claude-only extension. However, the spec's version
is a static label — it does not address staleness tracking, changelogs,
or bundle integrity. Prefer manifest-based tracking as the default and
use metadata only when you need version info visible in the file
itself.
The manifest is a YAML file named MANIFEST.yaml at the root of the skill
bundle directory — the same level as SKILL.md. When the bundle is
packaged as a .skill ZIP, the manifest lives inside the ZIP. It is the
single source of truth for what the bundle contains.
bundle: my-skill
bundle_version: 5.1.0
bundle_date: 2026-02-10
description: >
Skill for generating professional documents from source material
and user briefs. Handles research, structuring, and formatting.
compatibility:
designed_for:
surfaces:
- chat
- cli
- ide
capabilities:
- minimal SKILL.md frontmatter
- local filesystem access
- optional git workflow
tested_on:
- platform: Anthropic Claude
model: Claude Opus 4.6
surface: Chat
status: pass
date: 2026-02-10
- platform: Anthropic Claude
model: Claude Sonnet 4.5
surface: Chat
status: partial
date: 2026-02-09
notes: Misses staleness detection on complex bundles
spec_version: agentskills.io/1.0
frontmatter_mode: minimal
# minimal = name + description only (Codex, Gemini CLI, max portability)
# metadata = includes metadata block (any platform supporting the spec's metadata field)
dependencies: []
# List skill names this bundle depends on. Omit or leave empty if none.
deployments:
api:
version: 1759178010641129
workspace: docs-prod
claude:
scope: user
perplexity:
package_format: zip
files:
- path: SKILL.md
role: skill
version: 5
hash: sha256:abc123...
note: Canonical skill definition
- path: evals.json
role: evals
version: 3
hash: sha256:def456...
note: 7 evals including real-content synthesis
- path: scripts/generate.js
role: script
version: 4
hash: sha256:ghi789...
note: Generation script for eval 3
- path: outputs/eval3-output.pdf
role: output
version: 4
hash: sha256:jkl012...
note: Rendered eval 3 output, 10 pages, validated
- path: sources/article-1.md
role: source
version: null
hash: sha256:pqr678...
note: Source article 1 (published)
bundle_version uses semver (MAJOR.MINOR.PATCH). Bump MAJOR for
breaking changes to the skill's model or interface, MINOR for new
features or capabilities, PATCH for fixes and documentation updates.
Per-file version fields remain integers — they are revision counters,
not release identifiers.
hash is sha256 of the file contents. This is how a new session verifies that the file it received matches what the manifest claims. Compute on save, verify on load.
deployments is optional. Use it to record deployed or installed copies
of the same bundle when you want traceability across surfaces. Keep
bundle_version as the author-side semver source of truth. Platform-native
versions (for example API timestamps) stay in deployments, not in
bundle_version.
version: null for source files. They are tracked for completeness but not versioned by this system.
Paths are relative to the bundle root. No absolute paths.
MANIFEST.yaml is not listed in files. Self-hashing is recursive. Treat
the manifest as the bundle's control file and verify it via git, transport
checksums, or the surrounding package when needed.
Claude's settings UI exports and imports skills as .skill files. These
are standard ZIP archives containing a directory named after the skill.
The versioning artifacts (MANIFEST.yaml, CHANGELOG.md, README.md)
live inside this directory at the same level as SKILL.md:
skill-name.skill (ZIP)
└── skill-name/
├── SKILL.md
├── MANIFEST.yaml
├── CHANGELOG.md
├── README.md
├── assets/
└── references/
Claude's settings importer only looks for SKILL.md and the directory
structure it expects (references, assets). It ignores files it doesn't
recognize. This means the versioning artifacts travel safely inside the
.skill ZIP without affecting import/export behavior.
When bootstrapping or updating a bundle, always include the versioning
artifacts in the .skill ZIP so they survive round-trips through
Claude's settings UI.
Some uploaders only accept .zip or .md. In those cases, rename the
archive from .skill to .zip without changing its contents.
The spec recommends keeping SKILL.md under 500 lines and moving detailed
reference material to separate files. Provenance artifacts fit naturally
into that model: MANIFEST.yaml and CHANGELOG.md are load-on-demand
resources, not always-loaded instructions.
Claude Code provides a ${CLAUDE_SKILL_DIR} variable for bundle-relative
paths. Other platforms may not. Direct relative paths like
./validate.sh work when the working directory is the bundle root.
The .skill ZIP only carries the skill definition and its references.
Bundles can still track evals, scripts, rendered outputs, and handoff
notes outside the archive. The manifest remains the complete inventory,
not just the package inventory.
The changelog is a file named CHANGELOG.md at the root of the skill
bundle directory, alongside SKILL.md and MANIFEST.yaml. In the
bundle, it carries recent history with newest entries at the top. If the
canonical source lives in git, older entries can be archived in a
repo-level changelog outside the bundle.
# Changelog
## 5.1.0 — 2026-02-10
- SKILL.md: Rewrote Phase 5 layout rules. Removed per-section page breaks.
Added content flow check and a standalone validation checklist.
- evals.json: Not yet updated (stale, needs alignment).
## 5.0.0 — 2026-02-09
- SKILL.md: Reworked body flow rules and added an optional appendix.
- evals.json: Eval 3 expectations updated for content flow.
Each entry names every file that changed and what changed in it.
Files that are stale get called out. If SKILL.md changes but evals.json was not updated to match, the changelog says so. This prevents the silent drift that caused the v4/v5 confusion.
Entries are human-written prose, not auto-generated diffs. The point is to communicate intent, not enumerate line changes. Git diffs are available when the bundle is in git.
Bundle changelogs can be trimmed. Keeping the last 5-15 entries in the bundle is reasonable if the source repository maintains a full append-only changelog elsewhere.
When a skill bundle is loaded into a new session:
MANIFEST.yaml first.validate.sh before uploading
for reliable hash verification without LLM computation.CHANGELOG.md to understand recent changes.deployments clearly show a deployed copy behind the
local bundle, flag it and ask the user whether it needs updating.MANIFEST.yaml is missing, treat the bundle as unversioned. Offer
to create one by inventorying the files and asking the user for version
context.When work is complete and files are being delivered:
Update internal version headers for changed files that use them.
Update MANIFEST.yaml with new versions and hashes for every changed
versioned file, including manifest-only files. If the user deployed or
reinstalled the skill this session, update any relevant deployments
metadata too.
Add a new top entry to CHANGELOG.md.
If any versioned file was changed but another dependent file was not updated (e.g., SKILL.md changed but evals.json was not updated), note the staleness explicitly in the changelog entry.
Deliver the full bundle to the user, or at minimum the changed files plus the updated MANIFEST.yaml and CHANGELOG.md.
If the user indicates the bundle is destined for a git repo, provide a ready-to-use commit message derived from the changelog entry. Format:
skill-name MAJOR.MINOR.PATCH: one-line summary
- file1.md: what changed
- file2.json: what changed
- Stale: file3.js (not updated this session)
Return the message inline by default. Only write a transient
git_commit.txt file if the user explicitly asks for a file or if the
environment makes file output materially more convenient.
A handoff note is a snapshot of project state for the next session. It should include:
Create a handoff note only when crossing a non-persistent boundary or when the user explicitly asks for one. In filesystem-native environments with a current manifest, changelog, and git history, it is usually unnecessary. When created, it replaces the previous handoff note; previous handoffs live in changelog history.
When a session finds version conflicts (e.g., a file claims v5 but the manifest says v4, or two files claim different bundle versions):
Never silently resolve a version conflict. The whole point of this system is to make conflicts visible.
Treat one skill as moving through three states:
MANIFEST.yaml and the active CHANGELOG.md here. This is the
author-side source of truth. If you maintain a full archive in git,
keep it at repo root or another repo-level path outside the bundle.name and description.
Strip the metadata block from SKILL.md, set frontmatter_mode: minimal, recompute hashes in that copy, and leave the canonical bundle
unchanged unless you intentionally promote the derived copy..skill
ZIP or ClawHub upload. It may omit development-only files, but its
MANIFEST.yaml must describe exactly what the package contains. Update
deployments only after a real publish, reinstall, or redeploy.Surface notes:
deployments, not in
bundle_version..agents/skills/ can act as a neutral install path.General principle: the manifest and changelog stay authoritative, and transformed install or publish copies are derived artifacts, not silent edits to the canonical bundle.
Use the manifest, changelog, hashes, and optional deployment metadata to verify what belongs in the bundle, whether files still match their recorded state, what changed, and which installed or deployed copies may now be stale. If a bundle comes from an untrusted source, verify it first.
Versioned files use stable names without version numbers:
SKILL.md (not SKILL_v5.md)evals.json (not evals_v3.json)generate.js (not generate-v4.js)The version lives inside the file (via the header) and in the manifest, not in the filename. Version-numbered filenames are how we got into trouble in the first place.
Exception: if a user's local storage requires version-in-filename for their workflow, the manifest is the tiebreaker for which version is canonical. Internal version identity must still match.
To version an existing unversioned skill bundle:
MANIFEST.yaml with hashes.CHANGELOG.md with a single entry summarizing known history.This is a one-time operation per skill bundle.
Developed for PAICE.work PBC. Canonical source: https://github.com/snapsynapse/skill-provenance