refactor: hard-fork GSD -> MSD (Make Software Done)
Mechanical rename produced by scripts/msd-rename.cjs: gsd/Gsd/GSD -> msd/Msd/MSD across contents and paths, upstream package/repo coordinates -> @golem15/msd-core and golem15com/msd-core. Deep links into upstream history, sibling upstream packages, the GSD-2 import feature, CHANGELOG.md and .changeset/ are kept as-is. Hand edits on top: MSD block-letter banner and logos, LICENSE copyright line, package/plugin identity, regenerated lockfile, install-tree fixtures, derived registries and benchmark baseline; migration checksum baseline re-locked (MSD keeps its own install state, so no install had applied the old sums); sort-order and regex-escaped expectations in tests adjusted.
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
# 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)
|
||||
> **See also:** [How to develop a capability](../how-to/develop-a-capability.md) · [Capability Command Reference](msd-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.
|
||||
Each capability is a folder `capabilities/<id>/` (or an overlay root `~/.msd/capabilities/<id>/` / `.msd/capabilities/<id>/`) containing one `capability.json` declaration.
|
||||
The file is schema-validated JSON with a common **envelope** plus a **role-typed body** (`role: "feature"`, `role: "runtime"`, or `role: "reviewer"`).
|
||||
|
||||
---
|
||||
@@ -14,16 +14,16 @@ These fields are present for `role: "feature"`, `role: "runtime"`, and `role: "r
|
||||
|
||||
| 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. |
|
||||
| `id` | string (kebab-case) | Yes | Unique identifier; **must equal the folder name**. The prefix `msd-`, `msd-core-`, and `anthropic-` are reserved for first-party use. |
|
||||
| `role` | `"feature"` \| `"runtime"` \| `"reviewer"` | Yes | Discriminator that selects the body schema. `"reviewer"` is for lane-only capabilities that ship a `reviewer` body and nothing else — see [Reviewer body](#reviewer-body-role-reviewer-or-on-any-role) below. |
|
||||
| `version` | semver string | Yes (1.6.0+) | Semantic version of this capability. The registry rejects a manifest without one. |
|
||||
| `title` | string | Yes | Short human-readable label. Must be a non-empty string. |
|
||||
| `description` | string | Yes | Longer summary sentence. Must be a non-empty string. |
|
||||
| `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[] | Yes | Capability `id` values this capability depends on. Must be present as an array (use `[]` when there are no dependencies). Each entry 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. |
|
||||
| `engines` | object | No | Host-compatibility constraint. Sub-field: `msd` — 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. |
|
||||
| `runtimeCompat` | object | Yes (`role: "feature"`) | Declares which host runtimes this capability can surface through. Validated for every `role: "feature"` capability (a feature manifest without it fails validation). Sub-fields: `supported` — a **non-empty** array of kebab-case runtime ids, or the single wildcard `["*"]` for a runtime-agnostic capability; `unsupported` — an array of kebab-case runtime ids (the wildcard is **not** permitted here); `notes` — optional object mapping a runtime id (or `"*"`) to a non-empty explanatory string. The wildcard `"*"` may not be mixed with concrete ids in the same array, and the reserved names `__proto__`/`constructor`/`prototype` are rejected. |
|
||||
| `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. |
|
||||
| `compatVersions` | object | No | Graceful-downgrade table mapping `"<capVersion>"` to `"<min msd 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 }`. |
|
||||
@@ -114,7 +114,7 @@ Gates check a condition at a loop extension point and optionally block progressi
|
||||
|
||||
| Form | Shape | Blocking permitted | Notes |
|
||||
|---|---|---|---|
|
||||
| Query | `{ "query": "<gsd_run query>" }` | Yes | Deterministic first-party code. |
|
||||
| Query | `{ "query": "<msd_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. |
|
||||
|
||||
@@ -126,16 +126,16 @@ Declares that this capability resolves per-task content (`<action>`/`<verify>`/
|
||||
one of `steps` / `contributions` / `gates`, and it does not use a `point` value from the closed
|
||||
12-point vocabulary above — it is dispatched directly, once per task, by `execute-plan.md` before
|
||||
that task's `read_first` gate, documented separately in
|
||||
[`loop-hook-dispatch.md`](../../gsd-core/references/loop-hook-dispatch.md#the-executetask-point-a-different-shape).
|
||||
[`loop-hook-dispatch.md`](../../msd-core/references/loop-hook-dispatch.md#the-executetask-point-a-different-shape).
|
||||
See [ADR-3646](../adr/3646-per-task-content-resolution-seam.md) for the full design and
|
||||
[Develop a task-content resolver capability](../how-to/develop-a-task-content-resolver-capability.md)
|
||||
for the authoring walkthrough.
|
||||
|
||||
| Sub-field | Type | Required | Description |
|
||||
|---|---|---|---|
|
||||
| `trackerPrefix` | string (kebab-case) | Yes | Matches the prefix of a task's `<task tracker-id="beads:GSD-42">` attribute — everything before the **first** `:`. Text after the first colon, including further colons, is passed through verbatim as the id. Must be unique across the merged first-party ∪ overlay capability set. |
|
||||
| `trackerPrefix` | string (kebab-case) | Yes | Matches the prefix of a task's `<task tracker-id="beads:MSD-42">` attribute — everything before the **first** `:`. Text after the first colon, including further colons, is passed through verbatim as the id. Must be unique across the merged first-party ∪ overlay capability set. |
|
||||
| `invoke.binary` | string | Yes | Executable name or path for the resolver subprocess. |
|
||||
| `invoke.args` | string[] | Yes | Argv passed to `invoke.binary`. Must contain the `{{id}}` placeholder at least once — GSD substitutes it with the task's tracker id (everything after the first `:`); an `args` array that never carries the placeholder fails validation, since the id could never reach the resolver. |
|
||||
| `invoke.args` | string[] | Yes | Argv passed to `invoke.binary`. Must contain the `{{id}}` placeholder at least once — MSD substitutes it with the task's tracker id (everything after the first `:`); an `args` array that never carries the placeholder fails validation, since the id could never reach the resolver. |
|
||||
| `invoke.timeoutMs` | number | Yes | Bound on the subprocess invocation. Required — an unbounded resolver subprocess is this repo's named Unbounded Subprocesses defect class. A resolver exceeding this bound is killed and `task resolve-content` exits non-zero. |
|
||||
|
||||
`taskContentResolver` is feature-role only (`role: "feature"`); it is not admissible on `role: "runtime"` or `role: "reviewer"` bodies.
|
||||
@@ -169,12 +169,12 @@ A valid point is necessary but not sufficient: each host workflow decides, per p
|
||||
|
||||
## 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).
|
||||
Runtime capabilities describe how MSD 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`. `probeExists` is an optional sub-path applied to probe candidates: for `generic-agents-root` it is a hard filter (a candidate qualifies only if `<candidate>/<probeExists>` exists); for `dot-home-nested` it is a preference that makes probing pick the candidate GSD owns (e.g. `gsd-core/VERSION`) over a bare-existing sibling before falling back — see ADR-1016 and #213/#217. |
|
||||
| Local config dir | `runtime.localConfigDir` | Required dot-prefixed string. The runtime's **local** content-rewrite directory — the `./` target GSD stamps into rewritten artefact bodies (e.g. `./.claude/` → `./<localConfigDir>/`) and the local install dir basename. Backs `getDirName()` (registry-derived, #1679). Usually `.<runtime>` (the runtime's home dot-dir), but **three runtimes diverge** because they read GSD's content from a non-home directory: `copilot` → `.github` (GitHub Copilot reads custom instructions from `.github/copilot-instructions.md` / `.github/instructions/`; see `convertClaudeToCopilotContent` rewrites in `src/runtime-artifact-conversion.cts`), `antigravity` → `.agents` (local agent/workflow dir; see the antigravity rewrites in `src/runtime-artifact-conversion.cts`), `kimi` → `.kimi-code`. Distinct from `configHome.name` (the **global** install home, which for these three is `.copilot` / `antigravity` / `agents`). Byte-parity-proven against the prior hand-maintained mapping by the golden-install-parity harness. |
|
||||
| Config home | `runtime.configHome` | Structured object with `kind` (`dot-home` \| `dot-home-nested` \| `xdg` \| `generic-agents-root`), `name`, optional `parent`, `env[]`, `probe[]`, `probeExists`, `skillsHome`. `probeExists` is an optional sub-path applied to probe candidates: for `generic-agents-root` it is a hard filter (a candidate qualifies only if `<candidate>/<probeExists>` exists); for `dot-home-nested` it is a preference that makes probing pick the candidate MSD owns (e.g. `msd-core/VERSION`) over a bare-existing sibling before falling back — see ADR-1016 and #213/#217. |
|
||||
| Local config dir | `runtime.localConfigDir` | Required dot-prefixed string. The runtime's **local** content-rewrite directory — the `./` target MSD stamps into rewritten artefact bodies (e.g. `./.claude/` → `./<localConfigDir>/`) and the local install dir basename. Backs `getDirName()` (registry-derived, #1679). Usually `.<runtime>` (the runtime's home dot-dir), but **three runtimes diverge** because they read MSD's content from a non-home directory: `copilot` → `.github` (GitHub Copilot reads custom instructions from `.github/copilot-instructions.md` / `.github/instructions/`; see `convertClaudeToCopilotContent` rewrites in `src/runtime-artifact-conversion.cts`), `antigravity` → `.agents` (local agent/workflow dir; see the antigravity rewrites in `src/runtime-artifact-conversion.cts`), `kimi` → `.kimi-code`. Distinct from `configHome.name` (the **global** install home, which for these three is `.copilot` / `antigravity` / `agents`). Byte-parity-proven against the prior hand-maintained mapping by the golden-install-parity harness. |
|
||||
| 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`. |
|
||||
@@ -188,7 +188,7 @@ Runtime capabilities describe how GSD projects its artefacts onto one host CLI.
|
||||
|
||||
### `hostBehaviors`
|
||||
|
||||
`runtime.hostBehaviors` is a **closed vocabulary** of per-host behavior switches consumed directly by installer and runtime-adaptation code. A key outside the vocabulary is **ignored, with a non-fatal warning** naming the capability and the key; it is never a validation error, so a manifest authored against a newer GSD degrades visibly instead of failing the build of a repo that merely reads it.
|
||||
`runtime.hostBehaviors` is a **closed vocabulary** of per-host behavior switches consumed directly by installer and runtime-adaptation code. A key outside the vocabulary is **ignored, with a non-fatal warning** naming the capability and the key; it is never a validation error, so a manifest authored against a newer MSD degrades visibly instead of failing the build of a repo that merely reads it.
|
||||
|
||||
Adding a key is a reviewed first-party change, which is [ADR-1016](../adr/1016-runtime-capability-descriptor.md)'s intended friction rather than an obstacle: the runtime descriptor expresses every per-host difference as a value over a closed vocabulary, and a host needing a new shape gets a named primitive rather than an open escape hatch.
|
||||
|
||||
@@ -202,8 +202,8 @@ The vocabulary holds 59 keys; 39 of them are set by exactly one capability. This
|
||||
| `skipSharedHooksInstall` | 8 |
|
||||
| `frontmatterDialect` | 5 |
|
||||
| `hyphenNameAgentBody` | 3 |
|
||||
| `legacyCommandsGsdInstallMigration` | 3 |
|
||||
| `legacyCommandsGsdUninstall` | 3 |
|
||||
| `legacyCommandsMsdInstallMigration` | 3 |
|
||||
| `legacyCommandsMsdUninstall` | 3 |
|
||||
| `nativePlugin` | 3 |
|
||||
| `skipUpdateBannerCommand` | 3 |
|
||||
| `verificationStyle` | 3 |
|
||||
@@ -220,16 +220,16 @@ For a minimal `role: "runtime"` example, see [ADR-1016 §Decision 8](../adr/1016
|
||||
|
||||
## Reviewer body (`role: "reviewer"`, or on any role)
|
||||
|
||||
[ADR-2782](../adr/2782-reviewer-lane-capability-surface.md) introduces the *reviewer lane*: one external CLI or model endpoint that `/gsd-review` hands a plan to for independent review.
|
||||
[ADR-2782](../adr/2782-reviewer-lane-capability-surface.md) introduces the *reviewer lane*: one external CLI or model endpoint that `/msd-review` hands a plan to for independent review.
|
||||
|
||||
To declare one, follow [Ship a reviewer lane in your capability](../how-to/ship-a-reviewer-lane.md). This section is the field reference behind that guide.
|
||||
|
||||
The `reviewer` body is **optional and absent-safe at every layer**. A capability with no `reviewer` body is simply not a lane — that is never a validation error. This is a normative forward/backward-compatibility invariant, not a nicety: a plugin, a runtime, or a future GSD version may omit `reviewer` entirely with no consequence.
|
||||
The `reviewer` body is **optional and absent-safe at every layer**. A capability with no `reviewer` body is simply not a lane — that is never a validation error. This is a normative forward/backward-compatibility invariant, not a nicety: a plugin, a runtime, or a future MSD version may omit `reviewer` entirely with no consequence.
|
||||
|
||||
The shape is **hybrid**:
|
||||
|
||||
- A `reviewer` body is admissible on `role: "runtime"`, so an existing runtime capability — `codex`, `antigravity` — keeps **one** manifest that is both an installable runtime and a reviewer lane.
|
||||
- A third role, `role: "reviewer"`, exists for lane-only CLIs that GSD never installs into. There are currently 5: `coderabbit`, `gemini`, `llama-cpp`, `lm-studio`, `ollama`.
|
||||
- A third role, `role: "reviewer"`, exists for lane-only CLIs that MSD never installs into. There are currently 5: `coderabbit`, `gemini`, `llama-cpp`, `lm-studio`, `ollama`.
|
||||
|
||||
Current role counts across `capabilities/`: `feature` 20, `runtime` 19, `reviewer` 5.
|
||||
|
||||
@@ -256,7 +256,7 @@ All 12 shipped lane declarations carry all 14 fields below.
|
||||
|
||||
Uniqueness is enforced across the merged first-party ∪ overlay set: duplicate `slug`, duplicate `flags` entry, and duplicate `reviewsSection` are each build-time violations. Two lanes sharing a `reviewsSection` heading would silently merge their output in `REVIEWS.md`, producing apparent consensus that does not exist.
|
||||
|
||||
An unknown field inside a `reviewer` body is a **non-fatal warning on stderr, never a build failure** ([ADR-2782](../adr/2782-reviewer-lane-capability-surface.md) D4), so a manifest built against a newer GSD degrades visibly rather than crashing.
|
||||
An unknown field inside a `reviewer` body is a **non-fatal warning on stderr, never a build failure** ([ADR-2782](../adr/2782-reviewer-lane-capability-surface.md) D4), so a manifest built against a newer MSD degrades visibly rather than crashing.
|
||||
|
||||
### Example — lane-only `role: "reviewer"` capability
|
||||
|
||||
@@ -266,10 +266,10 @@ An unknown field inside a `reviewer` body is a **non-fatal warning on stderr, ne
|
||||
"role": "reviewer",
|
||||
"version": "1.8.0",
|
||||
"title": "CodeRabbit",
|
||||
"description": "CodeRabbit CLI — cross-AI /gsd-review reviewer lane only; not a GSD install target (no runtime body, no artifacts).",
|
||||
"description": "CodeRabbit CLI — cross-AI /msd-review reviewer lane only; not a MSD install target (no runtime body, no artifacts).",
|
||||
"tier": "full",
|
||||
"requires": [],
|
||||
"engines": { "gsd": ">=1.8.0" },
|
||||
"engines": { "msd": ">=1.8.0" },
|
||||
"reviewer": {
|
||||
"slug": "coderabbit",
|
||||
"flags": ["--coderabbit"],
|
||||
@@ -311,9 +311,9 @@ The following invariants are enforced at **build time** by `scripts/gen-capabili
|
||||
- **`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. The published roles are **family-partitioned** (ADR-894 §3, Amendment 2026-09-14): every role belongs to exactly one of orchestration (`orchestrator`), planning (`researcher`, `planner`, `checker`) or execution (`executor`, `verifier`), and each loop step publishes exactly one family. So `execute:*` publishes `executor`/`verifier` and never `orchestrator`, and `discuss:*`/`verify:*`/`ship:*` publish `orchestrator` and never `executor`/`verifier`. The partition is enforced when the host contract is generated, so the role set a point publishes is stable rather than incidental.
|
||||
- **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.
|
||||
- **`engines.msd` is a hard gate.** A capability whose `engines.msd` range does not satisfy the installed MSD 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.
|
||||
- **Reserved namespace.** Capability `id` values beginning with `msd-`, `msd-core-`, or `anthropic-` are reserved; third-party capabilities using these prefixes are rejected.
|
||||
- **`taskContentResolver.trackerPrefix` uniqueness, feature-only.** `trackerPrefix` must be unique across the merged first-party ∪ overlay capability set (mirrors `reviewsSection` uniqueness on the reviewer body above); a collision is a build-time violation. `taskContentResolver` is admissible only on `role: "feature"` bodies.
|
||||
|
||||
---
|
||||
@@ -331,10 +331,10 @@ The following is the canonical UI design-contract capability from ADR-894. It il
|
||||
"description": "UI-SPEC design contract and retrospective UI audit for frontend phases.",
|
||||
"tier": "standard",
|
||||
"requires": [],
|
||||
"engines": { "gsd": ">=1.6.0" },
|
||||
"engines": { "msd": ">=1.6.0" },
|
||||
"runtimeCompat": { "supported": ["*"], "unsupported": [] },
|
||||
"skills": ["ui-phase", "ui-review"],
|
||||
"agents": ["gsd-ui-checker", "gsd-ui-auditor"],
|
||||
"agents": ["msd-ui-checker", "msd-ui-auditor"],
|
||||
"hooks": [],
|
||||
"config": {
|
||||
"workflow.ui_phase": {
|
||||
|
||||
Reference in New Issue
Block a user