Phase 0 of the Capability Ecosystem epic (#1244): the design record and the third-party-author documentation set, with no runtime or code changes. - docs/adr/1244-capability-ecosystem.md — architecture decision record (amends/extends ADR-857 Decisions 7 & 8) - docs/prd/1244-capability-ecosystem.md — product requirements - Diataxis docs: tutorial, how-to (publish/import/version/remove), reference (manifest schema, /gsd:capability command, capability matrix), explanation (trust model); cross-links added to develop-a-capability.md Refs #1244 Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
244
docs/reference/capability-manifest.md
Normal file
244
docs/reference/capability-manifest.md
Normal file
@@ -0,0 +1,244 @@
|
||||
# Capability Manifest Reference (`capability.json`)
|
||||
|
||||
> **Canonical ADRs:** [ADR-1244](../adr/1244-capability-ecosystem.md) · [ADR-894](../adr/894-capability-declaration-format.md) · [ADR-1016](../adr/1016-runtime-capability-descriptor.md)
|
||||
> **See also:** [How to develop a capability](../how-to/develop-a-capability.md) · [Capability Command Reference](gsd-capability-command.md)
|
||||
|
||||
Each capability is a folder `capabilities/<id>/` (or an overlay root `~/.gsd/capabilities/<id>/` / `.gsd/capabilities/<id>/`) containing one `capability.json` declaration.
|
||||
The file is schema-validated JSON with a common **envelope** plus a **role-typed body** (`role: "feature"` or `role: "runtime"`).
|
||||
|
||||
---
|
||||
|
||||
## Envelope fields
|
||||
|
||||
These fields are present for both `role: "feature"` and `role: "runtime"` capabilities.
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|---|---|---|---|
|
||||
| `id` | string (kebab-case) | Yes | Unique identifier; **must equal the folder name**. The prefix `gsd-`, `gsd-core-`, and `anthropic-` are reserved for first-party use. |
|
||||
| `role` | `"feature"` \| `"runtime"` | Yes | Discriminator that selects the body schema. |
|
||||
| `version` | semver string | Yes (1.6.0+) | Semantic version of this capability. The registry rejects a manifest without one. |
|
||||
| `title` | string | No | Short human-readable label. |
|
||||
| `description` | string | No | Longer summary sentence. |
|
||||
| `tier` | `"core"` \| `"standard"` \| `"full"` | Yes | **Source of truth** for install-profile membership and surface cluster assignment. `tier` propagates via the `requires`-closure; install profiles are generated from it. |
|
||||
| `requires` | string[] | No | Capability `id` values this capability depends on. Must exist in the registry, be acyclic, and be tier-monotone (a `core` capability may not require a `standard` or `full` capability; a `standard` capability may not require a `full` capability). |
|
||||
| `engines` | object | No | Host-compatibility constraint. Sub-field: `gsd` — semver range string (e.g. `">=1.6.0 <3.0.0"`). Acts as a hard gate at install **and** at load; a mismatch blocks installation and causes the overlay to be skipped with a warning at load time. |
|
||||
| `compatVersions` | object | No | Graceful-downgrade table mapping `"<capVersion>"` to `"<min gsd version>"`. Only meaningful for sources that enumerate versions (git tags, registry, npm); a bare tarball URL carries one version and simply blocks on incompatibility. |
|
||||
| `integrity` | string | No | `sha512-<base64>` hash of the capability bundle. Verified before extraction when present; mismatch aborts install. |
|
||||
| `provenance` | object | No | `{ sourceRepo: string, commit: string }`. Emitted in CI for first-party and curated capabilities. |
|
||||
| `author` | object | No | `{ name: string, email?: string, url?: string }`. |
|
||||
| `homepage` | string | No | URL. |
|
||||
| `repository` | string | No | URL. |
|
||||
| `license` | string | No | SPDX licence identifier (e.g. `"MIT"`). |
|
||||
| `keywords` | string[] | No | Arbitrary search tags. |
|
||||
|
||||
---
|
||||
|
||||
## Feature body (`role: "feature"`)
|
||||
|
||||
Feature capabilities declare owned artefacts, lifecycle hooks, a federated configuration slice, and loop extension registrations.
|
||||
|
||||
### `skills` and `agents`
|
||||
|
||||
| Sub-field | Type | Description |
|
||||
|---|---|---|
|
||||
| `skills` | string[] | Owned skill stems. Exactly one capability may own each stem across the entire merged registry (first-party ∪ overlay). |
|
||||
| `agents` | string[] | Owned agent stems. Same uniqueness constraint as skills. |
|
||||
|
||||
### `hooks`
|
||||
|
||||
Non-loop lifecycle hooks.
|
||||
|
||||
| Sub-field | Type | Description |
|
||||
|---|---|---|
|
||||
| `event` | string | Hook event name (host-runtime specific). |
|
||||
| `script` | string | Path to the hook script, relative to the capability root. |
|
||||
|
||||
### `config` — federated config-key schema slice
|
||||
|
||||
The `config` field is an object whose keys are federated configuration keys contributed by this capability. Each key must be absent from the central `config-schema` and absent from every other capability's `config` object (collision fails the build gate). Each entry has the following shape:
|
||||
|
||||
| Property | Type | Description |
|
||||
|---|---|---|
|
||||
| `type` | `"boolean"` \| `"string"` \| `"number"` \| `"enum"` | Value type. |
|
||||
| `default` | (type-consistent) | Default value; must be consistent with `type`. |
|
||||
| `description` | string | Human-readable explanation of the key's effect. |
|
||||
| `values` | string[] | **`enum` only.** Exhaustive list of permitted string values. |
|
||||
|
||||
### `steps`
|
||||
|
||||
Steps run at a loop extension point as independent units. Ordering within a point is derived from `produces`/`consumes` (topological sort; capability-id is the tiebreak).
|
||||
|
||||
| Sub-field | Type | Description |
|
||||
|---|---|---|
|
||||
| `point` | string | One of the 12 valid loop extension point identifiers (see table below). |
|
||||
| `ref` | object | Either `{ "skill": "<stem>" }` or `{ "agent": "<stem>" }`. |
|
||||
| `produces` | string[] | Artefact names this step produces. No two capability steps may produce the same artefact at the same point. |
|
||||
| `consumes` | string[] | Artefact names this step consumes. |
|
||||
| `when` | string | Dotted config key; the step is active only when the key is truthy. Evaluated deterministically at render time; phase-context applicability is the skill's own responsibility. |
|
||||
| `onError` | `"skip"` \| `"halt"` | Behaviour on failure. `"skip"` is the default. Steps are purely additive — they never halt or redirect the host workflow on their own; a blocking precondition is expressed as a `gate`. |
|
||||
|
||||
### `contributions`
|
||||
|
||||
Contributions inject a fragment into a named agent role's prompt at a loop extension point. Multiple contributions into the same agent role render as ordered labelled blocks (`<contribution from="<id>">…</contribution>`).
|
||||
|
||||
| Sub-field | Type | Description |
|
||||
|---|---|---|
|
||||
| `point` | string | One of the 12 valid loop extension point identifiers. |
|
||||
| `into` | string | Agent role name. Must be a role published by that loop extension point in the host contract. |
|
||||
| `fragment` | object | Either `{ "path": "<relative path>" }` (file content) or `{ "inline": "<string>" }` (literal text). |
|
||||
| `when` | string | Dotted config key; activates the contribution conditionally. |
|
||||
| `onError` | `"skip"` \| `"halt"` | Behaviour on failure. |
|
||||
|
||||
### `gates`
|
||||
|
||||
Gates check a condition at a loop extension point and optionally block progression.
|
||||
|
||||
| Sub-field | Type | Description |
|
||||
|---|---|---|
|
||||
| `point` | string | One of the 12 valid loop extension point identifiers. |
|
||||
| `check` | object | One of three forms (see table below). |
|
||||
| `when` | string | Dotted config key; activates the gate conditionally. |
|
||||
| `blocking` | boolean | When `true`, a failed check halts the loop at this point. |
|
||||
| `onError` | `"skip"` \| `"halt"` | Behaviour when the check itself errors. |
|
||||
|
||||
**`check` forms:**
|
||||
|
||||
| Form | Shape | Blocking permitted | Notes |
|
||||
|---|---|---|---|
|
||||
| Query | `{ "query": "<gsd_run query>" }` | Yes | Deterministic first-party code. |
|
||||
| Predicate | `{ "predicate": { "kind": "artifact-exists" \| "config-equals" \| …, … } }` | Yes | Declarative; no code path. |
|
||||
| Agent verdict | `{ "agentVerdict": { "ref": …, "prompt": … } }` | No (forced advisory) | LLM evaluation; non-deterministic checks may not halt the loop. |
|
||||
|
||||
---
|
||||
|
||||
## Valid `point` values
|
||||
|
||||
The 12 loop extension points are a **closed, additive-only vocabulary**. Every `steps`, `contributions`, and `gates` entry must use one of these identifiers exactly.
|
||||
|
||||
| Point | Phase | Position |
|
||||
|---|---|---|
|
||||
| `discuss:pre` | Discuss | Before the discuss step executes |
|
||||
| `discuss:post` | Discuss | After the discuss step completes |
|
||||
| `plan:pre` | Plan | Before the plan step executes |
|
||||
| `plan:post` | Plan | After the plan step completes |
|
||||
| `execute:pre` | Execute | Before the execute phase begins |
|
||||
| `execute:wave:pre` | Execute | Before each execution wave |
|
||||
| `execute:wave:post` | Execute | After each execution wave |
|
||||
| `execute:post` | Execute | After the execute phase completes |
|
||||
| `verify:pre` | Verify | Before the verify step executes |
|
||||
| `verify:post` | Verify | After the verify step completes |
|
||||
| `ship:pre` | Ship | Before the ship step executes |
|
||||
| `ship:post` | Ship | After the ship step completes |
|
||||
|
||||
---
|
||||
|
||||
## Runtime body (`role: "runtime"`)
|
||||
|
||||
Runtime capabilities describe how GSD projects its artefacts onto one host CLI. The body is a closed 8-axis (plus 4 install-surface) vocabulary; no feature-only fields (`skills`, `agents`, `steps`, `contributions`, `gates`, `hooks`) are permitted. Full semantic specifications, the closed enum values for each axis, and the 16-runtime worked examples are in [ADR-1016](../adr/1016-runtime-capability-descriptor.md).
|
||||
|
||||
| Axis | Field | Type summary |
|
||||
|---|---|---|
|
||||
| Config home | `runtime.configHome` | Structured object with `kind` (`dot-home` \| `dot-home-nested` \| `xdg` \| `generic-agents-root`), `name`, optional `parent`, `env[]`, `probe[]`, `probeExists`, `skillsHome`. |
|
||||
| Config format | `runtime.configFormat` | Closed enum: `settings-json` \| `toml` \| `markdown` \| `markdown-dir` \| `none`. |
|
||||
| Artefact layout | `runtime.artifactLayout` | Object with `global` and `local` arrays of `ArtifactKind` (`kind`, `destSubpath`, `prefix`, `nesting`, `recursive`, `stage`). |
|
||||
| Command style | `runtime.commandStyle` | Closed enum: `slash-hyphen` \| `shell-var`. |
|
||||
| Hooks surface | `runtime.hooksSurface` | Closed enum: `settings-json` \| `codex-hooks-json` \| `cursor-hooks-json` \| `copilot-inline` \| `cline-rules` \| `none`. |
|
||||
| Sandbox tier | `runtime.sandboxTier` | Closed enum: `none` \| `codex-agent-sandbox`. |
|
||||
| Support tier | `runtime.supportTier` | Integer: `1` (fully tested first-party) \| `2` (shipped, lower coverage). |
|
||||
| Install surface | `runtime.installSurface` | Closed enum: `settings-json` \| `codex-toml` \| `copilot-instructions` \| `cline-rules` \| `cursor-hooks-json` \| `profile-marker-only`. |
|
||||
| Shared settings | `runtime.writesSharedSettings` | boolean. Whether the runtime writes a shared `settings.json`. |
|
||||
| Permission writer | `runtime.permissionWriter` | `null` \| `"opencode"` \| `"kilo"`. The finish-time permissions-sidecar writer. |
|
||||
| Extended hook events | `runtime.extendedHookEvents` | string[] over a closed vocabulary: `SubagentStop`, `Stop`, `PreCompact`, `FileChanged`, `BeforeAgent`, `AfterAgent`, `BeforeModel`. |
|
||||
|
||||
For a minimal `role: "runtime"` example, see [ADR-1016 §Decision 8](../adr/1016-runtime-capability-descriptor.md).
|
||||
|
||||
---
|
||||
|
||||
## Conformance invariants
|
||||
|
||||
The following invariants are enforced at **build time** by `scripts/gen-capability-registry.cjs` and at **install time** by the runtime-callable `validateCapability()` / `validateCrossCapability()` over the merged first-party ∪ overlay set.
|
||||
|
||||
- **`version` is required.** The registry rejects any manifest without a semver `version` field.
|
||||
- **`id` uniqueness.** No two capabilities may share an `id`. An overlay whose `id` collides with a first-party `id` is rejected; first-party always wins.
|
||||
- **Skill and agent stem uniqueness.** Exactly one capability may own each skill or agent stem across the entire merged registry.
|
||||
- **`requires` exist and are acyclic.** Every `id` listed in `requires` must exist in the registry; the dependency graph must be acyclic.
|
||||
- **`requires` is tier-monotone.** A `core` capability may not require a `standard` or `full` capability. A `standard` capability may not require a `full` capability.
|
||||
- **`point` values are from the closed set.** Every `point` in `steps`, `contributions`, and `gates` must be one of the 12 identifiers above.
|
||||
- **`contribution.into` is a published agent role.** The `into` value must be an agent role declared by the host contract for that loop extension point.
|
||||
- **Config key exclusivity.** A federated config key must be owned by exactly one capability and absent from the central `config-schema`. Presence in both is a collision; a half-migrated key fails the build gate.
|
||||
- **Artefact production uniqueness per point.** No two capability steps may `produces` the same artefact name at the same loop extension point.
|
||||
- **`engines.gsd` is a hard gate.** A capability whose `engines.gsd` range does not satisfy the installed GSD version is blocked at install and skipped (with a warning) at load time.
|
||||
- **Path confinement.** Declared module paths may not use parent-directory traversal (`../`); modules are `require()`'d only from the capability's own install root.
|
||||
- **Reserved namespace.** Capability `id` values beginning with `gsd-`, `gsd-core-`, or `anthropic-` are reserved; third-party capabilities using these prefixes are rejected.
|
||||
|
||||
---
|
||||
|
||||
## Example — complete `role: "feature"` capability
|
||||
|
||||
The following is the canonical UI design-contract capability from ADR-894. It illustrates all major body sections.
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "ui",
|
||||
"role": "feature",
|
||||
"version": "1.0.0",
|
||||
"title": "UI design contracts",
|
||||
"description": "UI-SPEC design contract and retrospective UI audit for frontend phases.",
|
||||
"tier": "standard",
|
||||
"requires": [],
|
||||
"engines": { "gsd": ">=1.6.0" },
|
||||
"skills": ["ui-phase", "ui-review"],
|
||||
"agents": ["gsd-ui-checker", "gsd-ui-auditor"],
|
||||
"hooks": [],
|
||||
"config": {
|
||||
"workflow.ui_phase": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"description": "Enable the UI design-contract gate during planning."
|
||||
},
|
||||
"workflow.ui_review": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"description": "Enable the retrospective UI audit."
|
||||
},
|
||||
"workflow.ui_safety_gate": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"description": "Block execution on unmet UI-SPEC contracts."
|
||||
}
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"point": "plan:pre",
|
||||
"ref": { "skill": "ui-phase" },
|
||||
"produces": ["UI-SPEC.md"],
|
||||
"consumes": ["CONTEXT.md"],
|
||||
"when": "workflow.ui_phase",
|
||||
"onError": "skip"
|
||||
},
|
||||
{
|
||||
"point": "verify:post",
|
||||
"ref": { "skill": "ui-review" },
|
||||
"produces": ["UI-REVIEW.md"],
|
||||
"consumes": ["UI-SPEC.md"],
|
||||
"when": "workflow.ui_review",
|
||||
"onError": "skip"
|
||||
}
|
||||
],
|
||||
"contributions": [],
|
||||
"gates": [
|
||||
{
|
||||
"point": "execute:wave:post",
|
||||
"check": { "query": "ui.safety-gate" },
|
||||
"when": "workflow.ui_safety_gate",
|
||||
"blocking": true,
|
||||
"onError": "halt"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Notes on this example:
|
||||
- `when` on each hook references its own config key; whether the phase is actually a frontend phase is decided inside `ui-phase` (self-gate).
|
||||
- The `plan:pre` step self-skips on non-frontend phases, producing no `UI-SPEC.md`; the `execute:wave:post` gate's `ui.safety-gate` query passes gracefully when no `UI-SPEC.md` exists.
|
||||
- A `contribution` follows this shape: `{ "point": "plan:pre", "into": "planner", "fragment": { "path": "loop/threat-model.md" }, "when": "workflow.security_enforcement" }`.
|
||||
155
docs/reference/capability-matrix.md
Normal file
155
docs/reference/capability-matrix.md
Normal file
@@ -0,0 +1,155 @@
|
||||
# Capability matrix reference
|
||||
|
||||
> **Generated file — do not edit by hand.**
|
||||
> This matrix is generated from the capability registry by
|
||||
> `scripts/gen-capability-matrix.cjs` (introduced in 1.6.0) and kept honest
|
||||
> by a drift guard in CI. Any manual edit will be overwritten on the next
|
||||
> generation run. To change a capability's declared metadata, edit the
|
||||
> corresponding `capabilities/<id>/capability.json` and rebuild.
|
||||
|
||||
See also: [ADR-1244](../adr/1244-capability-ecosystem.md) —
|
||||
[Capability manifest fields](#manifest-field-reference) —
|
||||
[Trust model explanation](../explanation/capability-trust-model.md)
|
||||
|
||||
---
|
||||
|
||||
## Column definitions
|
||||
|
||||
| Column | Description |
|
||||
|---|---|
|
||||
| **id** | Canonical capability identifier; must be unique across first- and third-party capabilities. Reserved prefixes: `gsd-`, `gsd-core-`, `anthropic-`. |
|
||||
| **role** | `feature` — extends what the loop does; `runtime` — adapts GSD to a specific AI runtime/IDE. |
|
||||
| **tier** | `core` — always active; `standard` — active when the runtime supports it; `full` — opt-in or runtime-specific. |
|
||||
| **version** | Semver version of the capability. Values shown are placeholders; the generator stamps exact per-capability versions from `capability.json` at release. |
|
||||
| **engines.gsd** | Semver range expressing host-version compatibility. A hard gate at install and at load. |
|
||||
| **extension points** | Loop extension points this capability registers into. See [the phase loop](../explanation/the-phase-loop.md) for the full ordered list. `see capability.json` means the generator would emit the precise set; only well-known registrations are listed here. |
|
||||
| **hook kinds** | Subset of `step`, `contribution`, `gate` that the capability's hooks use. |
|
||||
| **source** | `first-party` — ships with GSD Core; `third-party` — installed from an external source via `gsd capability install`. |
|
||||
|
||||
---
|
||||
|
||||
## Native (first-party) capabilities
|
||||
|
||||
First-party capabilities are implicitly trusted: they ship as part of the GSD
|
||||
Core package and are stamped with the package version at release (per
|
||||
ADR-1244 D6). They are not subject to the consent or integrity-pin flow
|
||||
applied to third-party capabilities.
|
||||
|
||||
### Feature capabilities (role: feature)
|
||||
|
||||
Feature capabilities extend what the five-step loop does — contributing
|
||||
research, planning, execution, verification, or ship artefacts.
|
||||
|
||||
| id | role | tier | version | engines.gsd | extension points | hook kinds | source |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| `research` | feature | standard | 1.6.0 | `>=1.6.0` | `discuss:pre`, `plan:pre` | step, contribution | first-party |
|
||||
| `ui` | feature | standard | 1.6.0 | `>=1.6.0` | see capability.json | step | first-party |
|
||||
| `ai-integration` | feature | standard | 1.6.0 | `>=1.6.0` | see capability.json | step, gate | first-party |
|
||||
| `security` | feature | full | 1.6.0 | `>=1.6.0` | `execute:pre`, `verify:pre` | gate | first-party |
|
||||
| `code-review` | feature | standard | 1.6.0 | `>=1.6.0` | `verify:pre`, `verify:post` | step, gate | first-party |
|
||||
| `schema-gate` | feature | standard | 1.6.0 | `>=1.6.0` | `execute:pre` | gate | first-party |
|
||||
| `pattern-mapper` | feature | standard | 1.6.0 | `>=1.6.0` | see capability.json | contribution | first-party |
|
||||
| `nyquist` | feature | full | 1.6.0 | `>=1.6.0` | see capability.json | step, gate | first-party |
|
||||
| `validation` | feature | standard | 1.6.0 | `>=1.6.0` | `verify:pre`, `verify:post` | step, gate | first-party |
|
||||
| `graphify` | feature | full | 1.6.0 | `>=1.6.0` | see capability.json | step | first-party |
|
||||
| `intel` | feature | standard | 1.6.0 | `>=1.6.0` | see capability.json | step, contribution | first-party |
|
||||
| `audit` | feature | standard | 1.6.0 | `>=1.6.0` | see capability.json | step, gate | first-party |
|
||||
|
||||
> **Note:** version `1.6.0` is the placeholder the generator replaces with the
|
||||
> actual per-capability `version` field from each `capability.json`. The 12
|
||||
> loop extension points available to feature capabilities are, in order:
|
||||
> `discuss:pre`, `discuss:post`, `plan:pre`, `plan:post`, `execute:pre`,
|
||||
> `execute:wave:pre`, `execute:wave:post`, `execute:post`, `verify:pre`,
|
||||
> `verify:post`, `ship:pre`, `ship:post`. A capability registers into the
|
||||
> subset it needs; registration of all 12 is unusual.
|
||||
|
||||
### Runtime capabilities (role: runtime)
|
||||
|
||||
Runtime capabilities adapt GSD to a specific AI runtime or IDE — emitting
|
||||
skills, agents, hooks configuration, and surface files appropriate for that
|
||||
host environment.
|
||||
|
||||
| id | role | tier | version | engines.gsd | extension points | hook kinds | source |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| `claude` | runtime | core | 1.6.0 | `>=1.6.0` | see capability.json | step | first-party |
|
||||
| `codex` | runtime | core | 1.6.0 | `>=1.6.0` | see capability.json | step | first-party |
|
||||
| `gemini` | runtime | standard | 1.6.0 | `>=1.6.0` | see capability.json | step | first-party |
|
||||
| `antigravity` | runtime | standard | 1.6.0 | `>=1.6.0` | see capability.json | step | first-party |
|
||||
| `cline` | runtime | standard | 1.6.0 | `>=1.6.0` | see capability.json | step | first-party |
|
||||
| `cursor` | runtime | standard | 1.6.0 | `>=1.6.0` | see capability.json | step | first-party |
|
||||
| `opencode` | runtime | standard | 1.6.0 | `>=1.6.0` | see capability.json | step | first-party |
|
||||
| `kilo` | runtime | standard | 1.6.0 | `>=1.6.0` | see capability.json | step | first-party |
|
||||
| `copilot` | runtime | full | 1.6.0 | `>=1.6.0` | see capability.json | step | first-party |
|
||||
| `augment` | runtime | standard | 1.6.0 | `>=1.6.0` | see capability.json | step | first-party |
|
||||
| `trae` | runtime | standard | 1.6.0 | `>=1.6.0` | see capability.json | step | first-party |
|
||||
| `qwen` | runtime | standard | 1.6.0 | `>=1.6.0` | see capability.json | step | first-party |
|
||||
|
||||
> **Note:** runtime capabilities typically do not register into the 12 loop
|
||||
> extension points in the same way feature capabilities do — their primary
|
||||
> responsibility is surface emission (skills, agents, config). Exact hook
|
||||
> registrations, where they exist, are emitted by the generator into the
|
||||
> `extension points` cell.
|
||||
|
||||
---
|
||||
|
||||
## Third-party capabilities
|
||||
|
||||
Once a user installs a third-party capability via `gsd capability install
|
||||
<spec>`, it enters the **runtime registry overlay** (ADR-1244 D2) and appears
|
||||
in this matrix on their machine alongside native capabilities. Third-party
|
||||
rows use the same column schema as first-party rows.
|
||||
|
||||
### How a third-party row is produced
|
||||
|
||||
The generator reads the capability's `capability.json` from the per-scope
|
||||
install root (`~/.gsd/capabilities/<id>/` for global installs;
|
||||
`.gsd/capabilities/<id>/` for project-scoped installs), validates it against
|
||||
the same conformance rules applied to native manifests, and emits a row
|
||||
identical in shape to the native rows above. The only difference is the
|
||||
`source` column, which shows `third-party`.
|
||||
|
||||
### Column values for third-party rows
|
||||
|
||||
| Column | Value |
|
||||
|---|---|
|
||||
| **id** | As declared in `capability.json`. Must not use reserved prefixes (`gsd-`, `gsd-core-`, `anthropic-`). |
|
||||
| **role** | `feature` or `runtime`, as declared. |
|
||||
| **tier** | `core`, `standard`, or `full`, as declared. |
|
||||
| **version** | Semver from `capability.json`; the value recorded in the ledger at install time. |
|
||||
| **engines.gsd** | Range from `capability.json`; verified at install and at each load. |
|
||||
| **extension points** | As declared in `capability.json`. Validated against the known 12 extension-point identifiers. |
|
||||
| **hook kinds** | `step`, `contribution`, and/or `gate` as declared. Disclosed in the consent summary at install. |
|
||||
| **source** | `third-party` |
|
||||
|
||||
### Community registry
|
||||
|
||||
Whether GSD operates or advertises a central community registry of third-party
|
||||
capabilities is **TBD/TBA** (see [PRD-1244 §8](../prd/1244-capability-ecosystem.md#8-open-questions--decisions-deferred)).
|
||||
The matrix mechanic and all manifest fields ship in 1.6.0 regardless of that
|
||||
decision. URL/git/npm/tarball import does not depend on a central registry.
|
||||
|
||||
---
|
||||
|
||||
## Manifest field reference
|
||||
|
||||
The fields below are defined in `capability.json` and govern how a capability
|
||||
appears in this matrix. For the full schema, see [ADR-1244 D1](../adr/1244-capability-ecosystem.md#d1--versioned-capability-manifest).
|
||||
|
||||
| Field | Required | Type | Purpose |
|
||||
|---|---|---|---|
|
||||
| `version` | **Yes** | semver string | Capability version. The registry rejects manifests without this field. |
|
||||
| `engines.gsd` | Recommended | semver range | Host-version compatibility gate. Enforced at install and load. |
|
||||
| `compatVersions` | No | object: cap-version → min-gsd-version | Graceful downgrade table for sources that enumerate versions (git tags, registry, npm). |
|
||||
| `integrity` | No | `sha512-<base64>` | SHA-512 digest of the capability bundle. Verified before extraction when present; mismatch aborts. |
|
||||
| `provenance` | No | `{ sourceRepo, commit }` | Source provenance. SHOULD be present for first-party and curated capabilities; populated in CI. |
|
||||
|
||||
---
|
||||
|
||||
## Related documents
|
||||
|
||||
- [ADR-1244 — Capability Ecosystem](../adr/1244-capability-ecosystem.md)
|
||||
- [Capability trust model](../explanation/capability-trust-model.md) — why the trust rules are structured the way they are
|
||||
- [The phase loop](../explanation/the-phase-loop.md) — the 12 loop extension points in context
|
||||
- [ADR-857](../adr/857-capability-system.md) — the original capability architecture; D7 and D8 extended by ADR-1244
|
||||
- [ADR-894](../adr/894-capability-declaration-format.md) — capability declaration format
|
||||
- [ADR-1016](../adr/1016-runtime-capability-descriptor.md) — runtime capability descriptor
|
||||
256
docs/reference/gsd-capability-command.md
Normal file
256
docs/reference/gsd-capability-command.md
Normal file
@@ -0,0 +1,256 @@
|
||||
# `gsd capability` Command Reference
|
||||
|
||||
> **Slash form:** `gsd:capability` (surfaced as a slash command on slash-command runtimes)
|
||||
> **CLI form:** `gsd capability`
|
||||
> **Canonical ADR:** [ADR-1244](../adr/1244-capability-ecosystem.md)
|
||||
> **See also:** [Capability Manifest Reference](capability-manifest.md) · [How to develop a capability](../how-to/develop-a-capability.md)
|
||||
|
||||
The `capability` family manages the installation, upgrade, removal, and inspection of GSD capabilities — both first-party and third-party overlays. A row for this command also appears in [docs/COMMANDS.md](../COMMANDS.md) (that file is not edited here).
|
||||
|
||||
---
|
||||
|
||||
## Subcommands
|
||||
|
||||
### `install`
|
||||
|
||||
**Synopsis**
|
||||
|
||||
```
|
||||
gsd capability install <spec> [--integrity sha512-<hash>] [--scope global|project] [--yes]
|
||||
```
|
||||
|
||||
**Arguments**
|
||||
|
||||
| Argument | Description |
|
||||
|---|---|
|
||||
| `<spec>` | Source specification (see [Source specifications](#source-specifications) below). |
|
||||
|
||||
**Flags**
|
||||
|
||||
| Flag | Type | Default | Description |
|
||||
|---|---|---|---|
|
||||
| `--integrity` | `sha512-<base64>` | — | SHA-512 bundle hash to verify before extraction. When supplied, a mismatch aborts the install. When the source registry or `capability.json` already carries an `integrity` field, both must agree. |
|
||||
| `--scope` | `global` \| `project` | `global` | Installation root. `global` writes to `~/.gsd/capabilities/<id>/`; `project` writes to `.gsd/capabilities/<id>/` in the current working directory. |
|
||||
| `--yes` | flag | off | Suppress the interactive consent prompt. The executable-surface disclosure is still printed; consent is taken as granted. |
|
||||
|
||||
**Behaviour**
|
||||
|
||||
Resolves `<spec>` to a versioned, staged capability bundle. The pipeline is: fetch → verify integrity or SHA pin → check `engines.gsd` against the installed GSD version → disclose executable surfaces (hooks, command modules) → obtain consent (unless `--yes`) → validate the incoming manifest against conformance invariants over the merged first-party ∪ existing-overlay ∪ new set → extract to the scope root → write the ledger entry atomically.
|
||||
|
||||
An overlay whose `id` collides with a first-party capability `id`, or that claims a skill or agent stem already owned, is rejected before extraction. Install never executes capability code; staging is copy-only.
|
||||
|
||||
The ledger file (`~/.claude/.gsd-capabilities.json` for the global scope on the Claude runtime, and analogues per runtime) records the installed version, source, integrity hash, owned files, and any fragments written into shared files (e.g. hook registrations in `settings.json`).
|
||||
|
||||
---
|
||||
|
||||
### `update`
|
||||
|
||||
**Synopsis**
|
||||
|
||||
```
|
||||
gsd capability update [<id> | --all]
|
||||
```
|
||||
|
||||
**Arguments**
|
||||
|
||||
| Argument | Description |
|
||||
|---|---|
|
||||
| `<id>` | Capability identifier to update. Omitting both `<id>` and `--all` is an error. |
|
||||
|
||||
**Flags**
|
||||
|
||||
| Flag | Description |
|
||||
|---|---|
|
||||
| `--all` | Update every installed overlay capability that has a newer version available from its original source. |
|
||||
|
||||
**Behaviour**
|
||||
|
||||
Fetches the latest version (or the newest version satisfying `engines.gsd`) from the capability's recorded source. Follows the atomic stage-then-swap pattern: the new bundle is fully staged, verified, and validated before the ledger write commits the swap. A crash during staging leaves the previous version intact. A crash after the ledger write leaves the new version intact; a reconciliation sweep on next run resolves any orphaned files.
|
||||
|
||||
When `--all` is used, update availability is source-dependent:
|
||||
|
||||
| Source kind | Update detection |
|
||||
|---|---|
|
||||
| `<name>@<registry>` | Registry catalogue query |
|
||||
| git (`https://…/repo.git#<tag>`) | Remote tag fetch |
|
||||
| npm (`npm:@org/pkg@<range>`) | `npm dist-tags` query |
|
||||
| tarball (`https://…/cap-x.y.z.tgz`) | Not auto-detectable; requires manual `install` with the new URL |
|
||||
| local (`./local/path`) | Not auto-detectable |
|
||||
|
||||
For third-party capabilities, auto-update is **off** by default. When auto-update is enabled, a version whose executable set (hooks, command modules) differs from the previously consented version triggers a re-prompt before the swap completes.
|
||||
|
||||
---
|
||||
|
||||
### `outdated`
|
||||
|
||||
**Synopsis**
|
||||
|
||||
```
|
||||
gsd capability outdated
|
||||
```
|
||||
|
||||
**Flags**
|
||||
|
||||
| Flag | Description |
|
||||
|---|---|
|
||||
| `--json` | Emit a JSON array instead of the default table. |
|
||||
|
||||
**Behaviour**
|
||||
|
||||
Queries the source of each installed overlay capability and reports those for which a newer version is available. Capabilities installed from tarball or local-path sources are listed as `"unknown"` for latest version.
|
||||
|
||||
**`--json` output shape**
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": "string",
|
||||
"current": "semver",
|
||||
"latest": "semver | \"unknown\"",
|
||||
"source": "string",
|
||||
"scope": "global | project"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `remove`
|
||||
|
||||
**Synopsis**
|
||||
|
||||
```
|
||||
gsd capability remove <id> [--purge-data]
|
||||
```
|
||||
|
||||
**Arguments**
|
||||
|
||||
| Argument | Description |
|
||||
|---|---|
|
||||
| `<id>` | Identifier of the installed overlay capability to remove. |
|
||||
|
||||
**Flags**
|
||||
|
||||
| Flag | Description |
|
||||
|---|---|
|
||||
| `--purge-data` | Also remove any data files created by the capability at runtime (artefacts under the capability's declared paths that are not part of the install bundle itself). |
|
||||
|
||||
**Behaviour**
|
||||
|
||||
Reads the ledger entry for `<id>` and removes exactly: the owned files listed in `files`, and the fragments written into shared files listed in `sharedEdits` (e.g. hook registrations spliced into `settings.json`). Shared files are not deleted; only the capability's fragments are stripped. The ledger entry is removed atomically after all file operations complete.
|
||||
|
||||
First-party capabilities (shipped with GSD) cannot be removed via this subcommand; the entire product uninstall path (`gsd --uninstall`) handles first-party removal.
|
||||
|
||||
---
|
||||
|
||||
### `disable`
|
||||
|
||||
**Synopsis**
|
||||
|
||||
```
|
||||
gsd capability disable <id>
|
||||
```
|
||||
|
||||
**Arguments**
|
||||
|
||||
| Argument | Description |
|
||||
|---|---|
|
||||
| `<id>` | Identifier of an installed capability to disable. |
|
||||
|
||||
**Behaviour**
|
||||
|
||||
Marks the capability as disabled in the ledger. A disabled capability is present on disk but excluded from the runtime overlay; it is skipped by the registry loader and contributes no hooks, config keys, or loop extension registrations. The ledger entry is preserved; `enable` reverses the operation without re-fetching.
|
||||
|
||||
---
|
||||
|
||||
### `enable`
|
||||
|
||||
**Synopsis**
|
||||
|
||||
```
|
||||
gsd capability enable <id>
|
||||
```
|
||||
|
||||
**Arguments**
|
||||
|
||||
| Argument | Description |
|
||||
|---|---|
|
||||
| `<id>` | Identifier of a previously disabled capability to enable. |
|
||||
|
||||
**Behaviour**
|
||||
|
||||
Clears the disabled flag in the ledger entry for `<id>`. On the next GSD invocation, the capability is included in the runtime overlay subject to its `engines.gsd` range. If the GSD version has changed since the capability was disabled, the `engines.gsd` check is re-evaluated at load time; an incompatible capability is skipped with a warning.
|
||||
|
||||
---
|
||||
|
||||
### `list`
|
||||
|
||||
**Synopsis**
|
||||
|
||||
```
|
||||
gsd capability list [--json]
|
||||
```
|
||||
|
||||
**Flags**
|
||||
|
||||
| Flag | Description |
|
||||
|---|---|
|
||||
| `--json` | Emit a JSON array instead of the default table. |
|
||||
|
||||
**Behaviour**
|
||||
|
||||
Lists all capabilities visible to the current GSD session: first-party capabilities (shipped with GSD) and installed overlay capabilities in both global and project scopes. Disabled capabilities are included with a `disabled` status.
|
||||
|
||||
**`--json` output shape**
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": "string",
|
||||
"role": "feature | runtime",
|
||||
"version": "semver",
|
||||
"tier": "core | standard | full",
|
||||
"source": "first-party | string",
|
||||
"scope": "first-party | global | project",
|
||||
"status": "active | disabled | incompatible",
|
||||
"title": "string"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
`status` values:
|
||||
|
||||
| Value | Meaning |
|
||||
|---|---|
|
||||
| `active` | Loaded and contributing to the current session. |
|
||||
| `disabled` | Present in the ledger but excluded via `gsd capability disable`. |
|
||||
| `incompatible` | `engines.gsd` range does not satisfy the current GSD version; skipped with a warning at load time. |
|
||||
|
||||
---
|
||||
|
||||
## Source specifications
|
||||
|
||||
The `install` subcommand accepts the following source specification forms.
|
||||
|
||||
| Form | Example | Adapter |
|
||||
|---|---|---|
|
||||
| Registry name | `my-cap@gsd-registry` | Registry — fetches the capability bundle from the named registry; `integrity` is populated from the registry catalogue. |
|
||||
| Git URL with tag | `https://github.com/org/repo.git#v1.2.0` | Git — clones/fetches at the specified tag; `#sha:<40-hex>` pins a specific commit. |
|
||||
| npm package | `npm:@org/gsd-capability-foo@^1.0.0` | npm — resolves via `npm dist-tags` / semver range; installs with `--ignore-scripts`. |
|
||||
| Tarball URL | `https://host/path/cap-x.y.z.tgz` | Tarball — fetches over HTTPS, verifies SHA-512 when `--integrity` is supplied. |
|
||||
| Local path | `./local/path` | Local — copies from the filesystem path relative to the current working directory. Auto-update and `outdated` detection are not available for this form. |
|
||||
|
||||
All forms pass through the same pipeline: fetch → verify integrity or SHA pin → check `engines.gsd` → obtain consent → validate → extract → record ledger.
|
||||
|
||||
---
|
||||
|
||||
## Install layout
|
||||
|
||||
Installed overlay capabilities are written to one of two roots, depending on `--scope`:
|
||||
|
||||
| Scope | Root path | Ledger file |
|
||||
|---|---|---|
|
||||
| `global` | `~/.gsd/capabilities/<id>/` | Per-runtime, e.g. `~/.claude/.gsd-capabilities.json` |
|
||||
| `project` | `.gsd/capabilities/<id>/` (CWD) | Per-runtime, adjacent to project root |
|
||||
|
||||
The ledger is the commit point for installs and upgrades. Its entries record the installed version, original source URL, integrity hash, owned files, and shared-file edits. A reconciliation sweep on the next GSD run resolves crash orphans (files on disk without a ledger entry, or ledger entries with missing files).
|
||||
Reference in New Issue
Block a user