* docs(#3247): record the capability instruction-surface trust model ADR-2363 records the trust posture for third-party capability SKILL.md bodies, which #2322/#2340 made agent-invocable without any content-level control. The path-level protections that fix shipped are all present; no content scanner exists, and external-descriptor-trust.cts never had one. Nothing was bypassed - the control did not exist and the boundary was never written down. D1 records the posture: skill bodies are trusted, unscanned agent instructions. D2 rejects content scanning on Kerckhoffs (a shipped rule set is readable by the adversary who installs it), on threat-model non-transfer from ADR-1577 (there, instructions are anomalous inside data; here they are the payload's legitimate form), and on Goodhart (a scanned-OK line displaces the judgment the consent prompt exists to provoke). D3 replaces the executable/non-executable binary with three classes, adding instruction surface. D4 keeps instruction surfaces out of the v1 disclosureSignature. The signature is NOT the activation binding - hasProjectConsent compares contentHash only, and a global install carries no consent record at all. What re-encoding would do is perturb the signature of every skill-bearing capability and fire a spurious re-consent prompt on its next upgrade, which is what ADR-2782 D4 rule 5 already forbids. If instruction surfaces ever need to be signature-bound, that lands as a versioned v2 signature with a migration, never an in-place re-encoding. Corrects capability-trust-model.md, which claimed skills get lighter consent because they do not execute code - true, and not the relevant property, since the agent is the interpreter. Adds the author-side boundary to develop-a-capability.md and links it from publish-a-capability.md. Both state that per-skill disclosure at the consent prompt lands with #3248 and does not happen today. Docs-only. No behavior change; no consent record perturbed. D5's mechanism is Phase 1 (#3248), which is why the ADR is Proposed. Refs #2363 * chore(#3247): backfill changeset pr number to 3249 --------- Co-authored-by: sim <sim@local>
6.3 KiB
How to publish a capability so others can install it
This guide is for capability authors who want to distribute their work so other GSD users can install it with gsd capability install. It covers preparing the manifest, validating locally, and releasing through each supported distribution channel.
Before publishing, make sure your capability works locally by following Develop a Capability.
Add the required publishing fields
Open your capabilities/<id>/capability.json and add these fields if they are not already present.
version (required)
"version": "1.0.0"
Use Semantic Versioning. Every published capability must carry a version; GSD will reject installation of a manifest that omits it.
engines.gsd (required)
"engines": {
"gsd": ">=1.6.0"
}
Declare the minimum GSD version your capability requires. GSD checks this constraint at both install time and load time and refuses to activate the capability on an incompatible installation. Be as permissive as correctness allows — a tighter range blocks more users.
If you need to offer a graceful downgrade path for users on older GSD versions, you can also declare compatVersions:
"compatVersions": {
"1.0.0": ">=1.6.0",
"0.9.0": ">=1.5.0"
}
compatVersions is only meaningful when your distribution channel enumerates available versions (a registry or a package feed). For Git and tarball releases, the installer downloads the version you point to directly.
Author and provenance fields (recommended)
These fields are displayed in the pre-install summary that users see before they consent to installation. Filling them in builds trust.
"author": {
"name": "Your Name",
"email": "you@example.com",
"url": "https://example.com"
},
"homepage": "https://github.com/your-org/gsd-cap-example",
"repository": "https://github.com/your-org/gsd-cap-example",
"license": "MIT"
license must be a valid SPDX expression. keywords is optional but helps discoverability on registries.
For the full list of manifest fields and their validation rules, see Capability manifest.
Namespace reservation
The prefixes gsd-, gsd-core-, and anthropic- are reserved for first-party capabilities. Do not use them as the id or package name of a third-party capability.
Validate locally before publishing
Run the registry check to confirm the manifest is well-formed:
node scripts/gen-capability-registry.cjs --check
If you are developing outside the core repo, use the standalone validator when it is available, or install your capability locally and check that gsd capability list shows it without errors:
gsd capability install ./path/to/your-capability --scope project
gsd capability list
Fix any validation errors before proceeding.
Validation checks the manifest's shape. It does not read your skill bodies — nothing does. If your capability ships skills, re-read them before you publish: they are copied verbatim into every installing user's agent instruction surface and are never content-scanned. See Ship skills — and know what you are shipping for the author's side of that boundary, and ADR-2363 for why it is drawn there.
Choose a distribution channel
Git repository (recommended for open-source capabilities)
Push your capability to a public Git host. Tag each release:
git tag v1.0.0
git push origin v1.0.0
Consumers install by pointing at the tag:
gsd capability install https://github.com/your-org/gsd-cap-example.git#v1.0.0
For a reproducible pin that cannot be moved, consumers can use a commit SHA instead:
gsd capability install https://github.com/your-org/gsd-cap-example.git#sha:abc123def456...
Publish release notes on your Git host so users know what changed between versions.
npm package
Publish your capability as an npm package. The package name becomes the npm spec consumers use. Use a scoped package name to make the origin clear:
npm publish
Consumers install using the npm: prefix:
gsd capability install npm:@your-org/gsd-cap-example@1.0.0
A version range is also accepted:
gsd capability install npm:@your-org/gsd-cap-example@^1.0.0
Tarball release
Build a tarball of the capability directory and attach it to a GitHub release or host it on any HTTPS URL:
tar -czf gsd-cap-example-1.0.0.tgz capabilities/example/
Consumers install using the tarball URL:
gsd capability install https://github.com/your-org/gsd-cap-example/releases/download/v1.0.0/gsd-cap-example-1.0.0.tgz
For tarball releases, publishing an integrity hash is strongly recommended (see below).
Compute and publish an integrity hash (recommended for tarballs)
An sha512 integrity hash lets consumers verify the download has not been tampered with. Compute it with:
openssl dgst -sha512 -binary gsd-cap-example-1.0.0.tgz | openssl base64 -A | sed 's/^/sha512-/'
Publish the resulting string in your release notes. Consumers pass it at install time:
gsd capability install https://example.com/gsd-cap-example-1.0.0.tgz \
--integrity sha512-<hash>
GSD verifies the hash before extracting the archive and aborts if it does not match.
Add provenance (optional)
If your release process produces a provenance record — for example, a GitHub Actions attestation — you can embed it in the manifest so that audit tools can surface it:
"provenance": {
"sourceRepo": "https://github.com/your-org/gsd-cap-example",
"commit": "abc123def456..."
}
This is optional metadata. It does not change the install-time trust model.
Next steps
- Import a capability from a URL — walk through installation from the consumer's perspective.
- Version and update a capability — manage
version,engines.gsd, andcompatVersionsacross releases. - Capability manifest — full field reference.
- Capability trust model — how GSD treats third-party capabilities at install time.