Publish a lifecycle and compatibility policy, checked in CI - #134
Merged
Merged
Conversation
docs/lifecycle.md is the contract for change. It covers: - package SemVer before and after 1.0 (a patch release never removes, deprecates or breaks anything); - skill SemVer with no 0.x exception, and how it meets status/update; - the deprecate -> notice -> remove path for skills, agents and formats (published in a tagged release at least 90 days before removal, 180 from 1.0), renames, and what happens to installed copies; - metadata, catalog, stamp-format and future lockfile evolution; - stable vs human CLI output, and the urgent security path. scripts/check_lifecycle.py, run by the lint job with --base, requires CHANGELOG notes, named in backticks, when compatibility changes: - a removed skill needs a Removed entry, a deprecation at the base and a published, old-enough Deprecated entry (a Security entry skips the last two); - a new deprecation needs a Deprecated entry; - an agent dropped from a skill, or a removed adapter, needs a Removed entry; - a major skill version needs a Changed entry giving the version; - a catalog schema_version change needs a Breaking entry. It also rejects a patch release with removals, deprecations or breaking entries. prepare_release.py now applies that rule before writing anything. Tests walk through a skill rename, an agent removal and a simulated stamp-format migration, pin the v1 stamp byte for byte, and show that the catalog represents every lifecycle state. No new metadata field: the notice clock comes from the CHANGELOG and release tags. Closes #78 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HtiCGzpikMrkDYBkfQG5CX
CHANGELOG: restore the Added bullets that #53 left under Security in [Unreleased], and file the internal get_skill removal under Changed, so Removed means public-surface removals only. check_lifecycle.py: - the urgent security path now needs a Removed entry marked **Security:** plus a Security entry naming the skill; a passing mention no longer exempts a removal; - only sections the PR adds count: [Unreleased], or a dated section the base's CHANGELOG lacks; a published section no longer does; - the notice period comes from release tags reachable from the base: the tag's own meta.yaml and CHANGELOG must deprecate the skill, counted from the later of the section date and the tag date, so it can't be retrofitted or back-dated; - an adapter removal needs a Removed entry of its own naming no skill; - with no release tags it prints a note and skips the notice rules; - an impossible CHANGELOG date is a clean error, here and in prepare_release.py. Policy: - skills keep SemVer's 0.x exception; - new features ship in minor releases; - the 90/180-day notice periods and the 7-day security target are marked as maintainer choices, and SECURITY.md states the target; - eval run records follow their own schema_version; - the lockfile section is trimmed to rules. Tests reuse the reviewer's probes A-E and G as regressions. The catalog schema validator moves to tests/_schema.py. Closes #78 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HtiCGzpikMrkDYBkfQG5CX
richardmhope
added a commit
that referenced
this pull request
Sep 25, 2026
* Define and enforce a skill capability manifest Every skill's meta.yaml now carries a required, versioned `capabilities` block (schema 1): files read (none/diff/repo) and edited (none/repo), commands it may run, network use and why, credentials, agent tools, and files it may create. Anything undeclared is not requested; the declaration is for review, not enforcement. - skilldeck.capabilities validates the block (unknown or missing keys, other schema numbers, commands given as paths or with shell operators, artifact paths that are absolute, name a drive or home, use backslashes or have ./.. components). - The registry enforces the bundle rules: exactly regular meta.yaml and skill.md, rejecting symlinks (including a symlinked skill directory), subdirectories, undeclared executables (script suffix, execute bit, #!, binary headers) and any other file, plus skill.md links to files the skill cannot ship. provenance --verify and catalog apply the same rules. - Every adapter appends a "Declared capabilities" section to a skill that asks for more than reading files; the adapter contract skill declares its `git diff`, so the fixtures pin that section (contract sha256:d8b7d4463e84). - `skilldeck show <skill> --summary` and `skilldeck install --dry-run` preview a skill's source, build, digest check, deprecation and declared capabilities; the dry run also reports what installing would do and writes nothing. - `skilldeck catalog --json` reports `capabilities` (additive; schema_version stays 1). - All 13 bundled skills declare what their instructions ask for, with patch version bumps; plugin tree and content manifests regenerated. Closes #73 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HtiCGzpikMrkDYBkfQG5CX * Address review of the capability manifest (#73) - Render the "Declared capabilities" notice only for skills that ask for more than a read-only review (an edit, a credential, an agent tool, an artifact, or a command beyond read-only git); the ten read-only review skills install byte-for-byte as before. Reword the notice for the agent ("Beyond reading the repository, this skill asks you to: ... It asks for nothing else.") and rename Capabilities.beyond_reading to beyond_review_baseline. The contract skill now declares <the project's test command>, so the fixtures still pin the notice (contract sha256:7c21e0856472). - Loading ignores OS and editor leftovers (.DS_Store, Thumbs.db, desktop.ini, __pycache__, ._*, .#*, *~, #*#, Vim swap files) so one stray file no longer breaks every command; provenance --verify and catalog still report them as unexpected files, with main's wording. .DS_Store is gitignored. - install --dry-run checks the nearest existing folder on the way to each destination and reports the error a real install would hit. - test-review runs a regression test against pre-change code only in a temporary git worktree (declared); dependency-review runs pip-audit only as `pip-audit --disable-pip` on fully pinned files, per pip-audit's security model, and declares reading package registry pages. - The link check matches src/href only inside HTML tags, skips indented code blocks, and checks autolinks. - The structure test knows common CLIs, so a new undeclared scanner, curl or test run is caught; spans a skill only quotes are listed per skill. - Declared commands reject interpreters given a script or inline code; Windows junctions count as links; the catalog docs say a new capability schema is a breaking catalog change; summary wording points to provenance --verify and docs/verifying-releases.md. Part of #73 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HtiCGzpikMrkDYBkfQG5CX * Version the capability changes under the lifecycle policy (#73) docs/lifecycle.md (#134) defines skill SemVer and what is breaking for skill authors; apply it to this branch: - dependency-review goes to 0.5.0, a minor bump: running pip-audit only on fully pinned files and adding registry-page lookups changes how it gathers evidence, which can change what it reports. test-review stays at 0.3.1, a patch: the temporary-worktree step only spells out a safe way to do what it already asked, and what it reports is unchanged. Both CHANGELOG entries say why. - Requiring `capabilities` and limiting a skill directory to meta.yaml and skill.md tightens rules existing metadata could fail, which the policy calls breaking for skill authors: add a **Breaking:** Changed entry. - docs/lifecycle.md's meta.yaml section mentions `capabilities`: its own schema number, and how a declaration change versions a skill. Part of #73 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HtiCGzpikMrkDYBkfQG5CX --------- Co-authored-by: Claude <noreply@anthropic.com>
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.
What & why
Adds
docs/lifecycle.md, one contract for how skilldeck changes. It covers:status,updateanduninstallactually do with installed copies of a removed skill, or of a skill that dropped an agent;meta.yaml, the catalog, install stamps and future lockfiles (Add organization bundles and reproducible skill lockfiles #71) may change;SECURITY.mdnow also states.A new
scripts/check_lifecycle.pyruns in thelintjob with--base origin/<target>. It requires CHANGELOG notes, in sections the PR adds and naming things in backticks, for:meta.yamland CHANGELOG must have shipped the deprecation at least the notice period earlier. The only exception is a Removed bullet marked**Security:**together with a Security entry naming the skill;schema_versionbumps.It also rejects a patch release that removes, deprecates or breaks anything, and
prepare_release.pyapplies the same rule before writing any file. Until the first release is tagged, the check prints a note that the notice-period rules are skipped.This PR also puts back the
### Addedheading that #53 dropped from[Unreleased]. Eleven Added bullets had ended up under### Security, which would have exempted four skills from the deprecation rules. It also moves the internalget_skillbullet from Removed to Changed, since### Removedis now reserved for removals from the public surface.No new metadata field is needed: the notice period is measured from release tags.
Tests:
Closes #78
Tracking: #94
Type of change
Checklist
uv run --extra dev ruff check . && uv run --extra dev ruff format --check . && uv run --extra dev mypy && uv run --extra dev pytest(958 passed, also with-W error::EncodingWarningand--resolution lowest-direct)CHANGELOG.mdentry under## [Unreleased]versioninmeta.yaml(no skill content changed)🤖 Generated with Claude Code
https://claude.ai/code/session_01HtiCGzpikMrkDYBkfQG5CX
Generated by Claude Code