docs(#1464): fix ADR-1244 capability doc set — followable tutorials, overlay-model + install tutorial, set/fragment/runtimeCompat reference, accuracy fixes

This commit is contained in:
Tom Boucher
2026-06-20 11:59:09 -04:00
parent 1c1c31f677
commit 02c6491e61
11 changed files with 860 additions and 142 deletions

View File

@@ -53,6 +53,7 @@ At minimum, a feature Capability declares:
{
"id": "example",
"role": "feature",
"version": "0.1.0",
"title": "Example",
"description": "Adds an example planning step.",
"tier": "standard",

View File

@@ -2,17 +2,21 @@
This guide covers two distinct operations: **removing** a capability (deletes its files and cleans up all shared configuration it wrote) and **disabling** a capability (toggles it off without touching any files). Choose the one that fits your intent.
> **Which one applies depends on where the capability came from.** `disable`/`enable` work **only** on first-party capabilities shipped inside GSD. An **installed third-party overlay** (added with `gsd capability install …`) cannot be disabled — its only off-switch is `remove` (re-install to restore it).
---
## Disable a capability (reversible, files kept)
## Disable a first-party capability (reversible, files kept)
If you want to stop a capability from participating in the loop but may want it back later, disable it:
`disable`/`enable`/`set` are for **first-party** capabilities only — the ones that ship inside GSD (for example `ui`, `code-review`, `research`). They validate `<id>` against GSD's **build-time** capability registry, so an **installed third-party overlay** (anything you added with `gsd capability install …`) is **not** in that registry and is rejected with `unknown capability: "<id>"`. For an installed overlay there is no `disable`; the off-switch is `remove` (and you re-install to bring it back) — see [Remove a capability](#remove-a-capability) below.
If you want to stop a **first-party** capability from participating in the loop but may want it back later, disable it:
```bash
gsd capability disable <id>
```
Disabling is a toggle: no files are deleted, no shared configuration is modified. The capability's hooks stop firing, its skills leave the active surface, and its command modules stop responding. To re-activate it:
Disabling is a toggle: no files are deleted, no shared configuration is modified. It acts on the **runtime surface and hook activation** of a skill-owning first-party capability: the capability's hooks stop firing and its skills leave the active surface. Disabling does **not** unregister first-party command families — those are dispatched from the generated capability registry, which `disable` does not consult, so any commands the capability owns continue to respond. To re-activate the surface and hooks:
```bash
gsd capability enable <id>
@@ -43,7 +47,7 @@ GSD uses the **ledger** — a per-runtime record written at install time (for ex
### What is NOT removed
- **Shared files themselves.** Files such as `settings.json` and `hooks.json` are edited in place, not deleted. Only the capability's specific entries are excised.
- **Persistent capability data.** Any data the capability wrote during use (databases, caches, runtime artefacts stored outside the install root) is **not** auto-deleted. You must pass `--purge-data` to remove it, and GSD will prompt for confirmation before doing so:
- **Persistent capability data.** Any data the capability wrote during use (databases, caches, runtime artefacts stored outside the install root) is **not** auto-deleted by default. Pass `--purge-data` to delete it as part of the removal:
```bash
gsd capability remove <id> --purge-data
@@ -51,16 +55,14 @@ GSD uses the **ledger** — a per-runtime record written at install time (for ex
If you want to keep your data, omit `--purge-data`. The capability's runtime data will remain on disk even after the capability itself is removed.
### Prompts and confirmation
### No prompt — `remove` is non-interactive
`gsd capability remove` will ask you to confirm before proceeding. Pass `--yes` to skip the prompt in scripts or non-interactive contexts:
`gsd capability remove` is **non-interactive**: it does not prompt, and there is no `--yes` flag. It acts immediately on the scope you give it. `--purge-data` likewise deletes the capability's data directly, with no confirmation step — so be sure before you pass it. The full contract is:
```bash
gsd capability remove <id> --yes
gsd capability remove <id> [--purge-data] [--scope global|project]
```
If the capability also ships persistent data and you pass `--purge-data`, GSD prompts once more specifically for the data deletion, regardless of `--yes`, because that action is irreversible.
---
## Troubleshooting
@@ -94,10 +96,11 @@ gsd capability remove <id> --scope project
| | `disable` | `remove` |
|---|---|---|
| Applies to | First-party only | Installed overlays (and reconcile of orphaned first-party state) |
| Files deleted | No | Yes (ledger-recorded files only) |
| Shared config entries removed | No | Yes (capability's entries only) |
| Federated config keys dropped | No | Yes |
| Persistent data deleted | No | Only with `--purge-data` + prompt |
| Persistent data deleted | No | Only with `--purge-data` (deleted directly, no prompt) |
| Reversible without reinstall | Yes (`enable`) | No |
| Use when | You want it back later | You no longer need it |

View File

@@ -2,80 +2,131 @@
This guide shows you how to switch a GSD capability off so it stops taking part in the loop — and stays off — and how to switch off a single feature of a capability without disabling the whole thing.
GSD resolves one capability state from three places: whether the capability is installed, whether it is surfaced, and whether each of its hooks is gated in config. "Off" means off across all three. For why the model works this way, see [Develop a Capability for GSD 1.5+](develop-a-capability.md).
GSD resolves one capability state from three places: whether the capability is installed, whether it is surfaced, and whether each of its hooks is gated in config. "Off" means off across all three. For why the model works this way, see [Develop a Capability for GSD 1.6.0+](develop-a-capability.md).
> **First-party vs. installed: pick the right off-switch.** The path depends on where the capability came from.
>
> - A **first-party** capability — one that ships with GSD (for example `ui`, `code-review`, `research`) — is turned off with `gsd capability disable <id>` or gated with `gsd capability set <id> --gate …`. These verbs validate `<id>` against the built-in capability registry.
> - An **installed third-party overlay** — one you added with `gsd capability install …` — is **not** in that build-time registry, so `disable`/`enable`/`set` reject it with `unknown capability: "<id>"`. The off-switch for an installed overlay is `gsd capability remove <id> --scope <scope>`.
>
> The rest of this guide covers first-party capabilities. For installed overlays, jump to [Turn off an installed third-party capability](#turn-off-an-installed-third-party-capability).
The reliable, fully general way to change first-party capability state is the `capability` command. The `/gsd:surface` and `/gsd:settings` slash commands are convenient interactive front-ends, but they operate on **skill clusters**, not arbitrary capabilities — so reach for the CLI when you want a precise, scriptable, per-capability switch.
---
## Turn a whole capability off
## Turn a whole first-party capability off
Use the runtime surface — the on/off switch. It is reversible and needs no reinstall:
Disable the capability by id:
```
/gsd:surface disable <capability>
```bash
gsd capability disable <id>
```
For example, to stop the UI capability:
```
/gsd:surface disable ui
```bash
gsd capability disable ui
```
The capability's skills leave the surface and all of its hooks go inactive. Check the result with:
This unsurfaces the capability's skills and makes all of its hooks inactive. It is reversible and needs no reinstall — the bundle stays on disk and your hook gates are preserved. `gsd capability disable <id>` is exactly `gsd capability set <id> --off`; re-enable with `gsd capability enable <id>` (i.e. `--on`).
`disable`/`enable`/`set` only accept ids the built-in registry knows about. Run them against an installed third-party overlay and you get `unknown capability: "<id>"` — see [Turn off an installed third-party capability](#turn-off-an-installed-third-party-capability) for that case.
Check the result:
```bash
node gsd-tools.cjs capability state --raw
gsd capability state --raw
```
The capability now reports `enabled: false` and every hook `active: false`. To turn it back on, `/gsd:surface enable ui` — your earlier hook gates are preserved.
The capability now reports `enabled: false` and every hook `active: false`.
---
## Turn off one feature of a capability
To keep a capability on but switch off a single hook, gate that hook instead of disabling the capability. Use `/gsd:settings`, or set the key directly:
To keep a capability on but switch off a single hook, gate that hook instead of disabling the capability. A **gate** is a dotted config key declared in the capability's `config` slice whose boolean value controls whether one of its hooks fires. Set it to `false`:
```bash
node gsd-tools.cjs capability set code-review --gate workflow.code_review=false
gsd capability set code-review --gate workflow.code_review=false
```
The capability stays enabled; only that hook stops firing.
The capability stays enabled; only that hook stops firing. `--gate` is repeatable, so you can set several gates in one call. See the [`set` reference](../reference/gsd-capability-command.md#set) for the full contract.
---
## Capabilities that own no skills
Some capabilities (for example, research) contribute only hooks and agents — they have no skills to unsurface, so `/gsd:surface disable` does not affect them. Switch these off by gating their hooks:
Some capabilities (for example, `research`) contribute only hooks and agents — they have no skills to unsurface, so disabling them via the surface has no effect. Switch these off by gating their hooks instead:
```bash
node gsd-tools.cjs capability set research --gate workflow.research=false
gsd capability set research --gate workflow.research=false
```
If you gate every hook of a capability off while it is still surfaced, `gsd-tools capability state` flags it as surfaced-but-inactive — a sign you probably meant to disable the capability itself.
If you gate every hook of a capability off while it is still surfaced, `gsd capability state` flags it as surfaced-but-inactive — a sign you probably meant to disable the capability itself.
---
## Turn off an installed third-party capability
A capability you added with `gsd capability install …` is an **installed overlay**, not a first-party capability. It is not present in the build-time registry that `disable`/`enable`/`set` validate against, so those verbs reject it:
```bash
gsd capability disable my-overlay
# error: unknown capability: "my-overlay"
```
**Remove it.** This is the deactivation path for an installed overlay — it strips the overlay's files and edits for the chosen scope:
```bash
gsd capability remove my-overlay --scope global # default scope is global
gsd capability remove my-overlay --scope project # for a project-scoped install
```
`--scope` defaults to `global`, so pass `--scope project` for a project install. Add `--purge-data` to also delete the overlay's persisted data. If the id is not installed in the chosen scope you get `capability "my-overlay" is not installed in <scope> scope`. (Trying to `remove` a first-party id instead reports that it cannot be removed here — use the product uninstaller, `gsd --uninstall`.)
> The `/gsd:surface` clusters described below are derived from the **built-in** capability registry, so they cover first-party skill-owning capabilities. For an installed overlay, `remove` is the off-switch.
See [Remove a capability](remove-a-capability.md) for the full removal flow and [`gsd capability remove`](../reference/gsd-capability-command.md#remove) for every flag and output field.
---
## The interactive paths (`/gsd:surface` and `/gsd:settings`)
The slash commands are the interactive equivalents, useful when you are working inside an agent session rather than scripting:
- **`/gsd:surface disable <cluster>`** toggles a whole skill **cluster** on or off and re-stages the surface. Its argument is validated against the fixed set of cluster names — one of `core_loop`, `audit_review`, `milestone`, `research_ideate`, `workspace_state`, `docs`, `ui`, `ai_eval`, `ns_meta`, `utility` (the command rejects anything else and lists these). A few of these names coincide with first-party skill-owning capability ids (for example `ui`), so `/gsd:surface disable ui` works — but the command does **not** accept an arbitrary capability id, including an installed overlay's id. To switch off a specific capability by id, use the CLI (`gsd capability disable <id>` for first-party, `gsd capability remove <id>` for an installed overlay). Reverse a cluster with `/gsd:surface enable <cluster>`.
- **`/gsd:settings`** is the interactive prompt for GSD's workflow toggles (the `workflow.*` config keys that gate hooks). Use it to turn workflow features on or off conversationally; it writes the same config keys that `gsd capability set … --gate` writes.
For anything you want to be exact about — a specific capability id, a single named gate, or a step in a script or CI job — prefer the CLI.
---
## Scripting it
`/gsd:surface` and `/gsd:settings` are the interactive paths. To mutate capability state directly (in scripts or CI), call the underlying command:
To mutate capability state directly (in scripts or CI), call the command non-interactively. The first three verbs work on **first-party** ids; the last works on **installed overlays**:
```bash
# Disable via surface
node gsd-tools.cjs capability set <id> --off
# Disable a whole first-party capability
gsd capability disable <id> # equivalently: gsd capability set <id> --off
# Re-enable
node gsd-tools.cjs capability set <id> --on
gsd capability enable <id> # equivalently: gsd capability set <id> --on
# Toggle one hook gate
node gsd-tools.cjs capability set <id> --gate <key>=<true|false>
gsd capability set <id> --gate <key>=<true|false>
# Deactivate an installed third-party overlay (disable/set would reject it)
gsd capability remove <id> --scope <global|project>
```
See [CLI tools — Capability Commands](../CLI-TOOLS.md#capability-commands) for the full reference.
See the [`gsd capability` command reference](../reference/gsd-capability-command.md) for every subcommand, flag, and output shape.
---
## Related
- [Develop a Capability for GSD 1.5+](develop-a-capability.md)
- [`gsd capability` command reference](../reference/gsd-capability-command.md) — `disable`, `enable`, `set`, and the rest of the family
- [Develop a Capability for GSD 1.6.0+](develop-a-capability.md)
- [Install a minimal GSD and add skills later](install-minimal-and-add-skills.md)
- [CLI tools reference — Capability Commands](../CLI-TOOLS.md#capability-commands)
- [docs index](../README.md)

View File

@@ -80,7 +80,7 @@ npm version 1.2.0
npm publish
```
**New tarball.** Upload the new archive at a URL and communicate the URL to consumers. GSD cannot auto-detect updates for tarball sources — consumers must run `gsd capability update <id> <new-url>` manually after you announce the new URL. If you anticipate frequent updates, consider switching to a git or npm source.
**New tarball.** Upload the new archive at a URL and communicate the URL to consumers. GSD cannot auto-detect updates for tarball sources, and `gsd capability update` only ever re-resolves the URL **already recorded** in the ledger — it takes no new-URL argument. To move a tarball install to a new URL, the consumer **re-installs from the new URL** (`gsd capability install <new-url> …`), which overwrites the recorded source. If you anticipate frequent updates, consider switching to a git or npm source so `gsd capability update <id>` can pick up new versions automatically.
---
@@ -99,11 +99,11 @@ GSD contacts the source of each installed capability and reports which ones have
| Source | Auto-detectable? |
|---|---|
| Git (tags / manifest) | Yes — GSD fetches available tags. |
| Registry | Yes — GSD queries the catalogue. |
| npm | Yes — GSD checks `dist-tags`. |
| Tarball URL | **No** — a tarball exposes one version; updates must be applied manually when the author announces a new URL. |
| Tarball URL | **No** — a tarball exposes one version; updates must be applied manually by re-installing from a new URL. |
| Registry (`<name>@<registry>`) | **Not yet** — the registry source kind is reserved but unimplemented today; `outdated` reports `status: unknown` for it and `update` cannot re-resolve it. |
If a capability is installed from a tarball and the author publishes a new version at a different URL, you will need to run `gsd capability update <id> <new-url>` yourself once the author communicates the new address.
If a capability is installed from a tarball and the author publishes a new version at a different URL, `gsd capability update <id>` will not help — it only re-resolves the URL already recorded at install time, and takes no new-URL argument. Once the author communicates the new address, **re-install from it** with `gsd capability install <new-url> …`; that overwrites the recorded source with the new version.
### Apply an update
@@ -123,11 +123,13 @@ Updates are **atomic**: GSD fully fetches and validates the new version before s
### Consent when the executable surface changes
If the new version adds or removes hooks, MCP server entries, or command modules compared to the version you have installed, GSD will pause and present a summary of the changes before proceeding. You must confirm explicitly; declining leaves the current version in place.
The CLI is **non-interactive** — it never stops to ask a question. If the new version adds or removes hooks, MCP server entries, or command modules compared to the version you have installed, `gsd capability update <id>` **aborts** rather than swapping: it prints the disclosed surface change and instructs you to re-run with `--yes`, leaving the current version fully in place. Re-running with `--yes` grants consent for the new surface and completes the swap:
This re-prompt applies even if you previously consented to auto-update. The consent mechanism is scoped to the declared executable surface of a specific version, so a changed surface is always a fresh decision.
```bash
gsd capability update <id> --yes
```
Auto-update is **off by default** for third-party capabilities. If you enable it, the re-prompt on executable-surface change still applies.
This re-consent is required every time the surface changes, scoped to the declared executable surface of a specific version, so a changed surface is always a fresh `--yes`. (A version whose executable surface is unchanged updates without `--yes`.)
### When `engines.gsd` no longer matches