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,6 +1,6 @@
|
||||
# The capability trust model
|
||||
|
||||
> **Explanation** — This document describes *why* GSD draws its trust
|
||||
> **Explanation** — This document describes *why* MSD draws its trust
|
||||
> boundaries where it does, and *what the trade-offs are*. It is not a
|
||||
> step-by-step guide to installing capabilities; for that, see the how-to
|
||||
> guides for [importing a capability](../how-to/import-a-capability-from-a-url.md) and
|
||||
@@ -13,9 +13,9 @@
|
||||
|
||||
## The central thesis: artifact parity is not trust parity
|
||||
|
||||
GSD 1.6.0 opens the capability platform to third-party authors with **full
|
||||
MSD 1.6.0 opens the capability platform to third-party authors with **full
|
||||
artifact parity**: a third-party capability may ship the same executable
|
||||
surfaces that GSD Core ships — hooks, MCP servers, command modules, and
|
||||
surfaces that MSD Core ships — hooks, MCP servers, command modules, and
|
||||
reviewer lanes. This is a deliberate product choice, and it carries real
|
||||
security weight.
|
||||
|
||||
@@ -31,9 +31,9 @@ line between two things that are often conflated:
|
||||
- **Trust posture** — the evidence and consent required before that capability
|
||||
*executes* on your machine.
|
||||
|
||||
GSD grants full artifact parity. It does not grant symmetric trust. First-party
|
||||
MSD grants full artifact parity. It does not grant symmetric trust. First-party
|
||||
capabilities are implicitly trusted because they *are* the shipped package —
|
||||
their provenance is the GSD Core release process itself. Third-party
|
||||
their provenance is the MSD Core release process itself. Third-party
|
||||
capabilities require explicit, informed, revocable consent plus SHA-pinned
|
||||
integrity before any executable surface is activated. These two things are
|
||||
structurally separate, and keeping them separate is what makes full parity
|
||||
@@ -43,7 +43,7 @@ defensible.
|
||||
|
||||
## What the ecosystem learnt the hard way
|
||||
|
||||
GSD's trust model is not designed in isolation. It is informed by failures in
|
||||
MSD's trust model is not designed in isolation. It is informed by failures in
|
||||
four ecosystems that tackled the same problem — and each one paid tuition.
|
||||
|
||||
### VS Code: auto-update + stolen publisher credentials
|
||||
@@ -57,13 +57,13 @@ a liability when credentials can be compromised, because the user's last
|
||||
explicit act of trust was for *version N* — not for whatever version N+1
|
||||
contains.
|
||||
|
||||
GSD's response: auto-update is **off by default** for third-party capabilities.
|
||||
MSD's response: auto-update is **off by default** for third-party capabilities.
|
||||
When it is enabled, a change to the *executable set* (the set of hooks, MCP
|
||||
servers, command modules, or reviewer lanes the capability declares) triggers a
|
||||
re-consent prompt before the update applies. Updating a non-executable
|
||||
capability (documentation, agents, skills) does not require re-consent.
|
||||
|
||||
VS Code also has no signature check on VSIX packages. GSD requires an
|
||||
VS Code also has no signature check on VSIX packages. MSD requires an
|
||||
`integrity` SHA-512 pin in the ledger, verified before extraction.
|
||||
|
||||
### npm: the supply-chain attack surface
|
||||
@@ -74,7 +74,7 @@ attackers have exploited in the s1ngularity attack class (a malicious package
|
||||
is published under a name a legitimate package depends on). npm's own
|
||||
recommendation for sensitive environments is `--ignore-scripts`.
|
||||
|
||||
GSD takes a stronger position: **install never executes capability code**,
|
||||
MSD takes a stronger position: **install never executes capability code**,
|
||||
full stop. Installation is a copy-only staging operation. There is no
|
||||
`postinstall`-equivalent. A capability's hooks, MCP server, command
|
||||
modules, and reviewer lanes are not invoked during install; they are first
|
||||
@@ -85,13 +85,13 @@ has a window between install and first use to verify what they consented to.
|
||||
### The reviewer lane: the one surface that *receives* data
|
||||
|
||||
Three of the four disclosure classes are about code the capability gets to
|
||||
**run**. A reviewer lane — one external CLI or model endpoint that `/gsd-review`
|
||||
**run**. A reviewer lane — one external CLI or model endpoint that `/msd-review`
|
||||
hands a plan to — is different in kind, and the difference is the reason it is
|
||||
disclosed at all.
|
||||
|
||||
A lane is piped the plan text, the requirements, the research findings, and the
|
||||
`CONTEXT.md` decisions, and its output is read back into `REVIEWS.md`. That is an
|
||||
**egress channel for the most sensitive artifacts GSD produces**. Making lanes
|
||||
**egress channel for the most sensitive artifacts MSD produces**. Making lanes
|
||||
pluggable without a disclosure class would have opened a data-exfiltration path
|
||||
behind a manifest field, which is why the trust work gates the feature rather
|
||||
than following it.
|
||||
@@ -130,10 +130,10 @@ destination is detectable rather than silent.
|
||||
|
||||
SLSA provenance (the `provenance` field in `capability.json`) provides a
|
||||
machine-checkable link from a capability bundle back to a specific commit in a
|
||||
specific source repository. GSD emits provenance for first-party capabilities
|
||||
specific source repository. MSD emits provenance for first-party capabilities
|
||||
in CI and recommends it for curated capabilities; whether to require it for
|
||||
community-listed third-party capabilities is an open question tied to whether
|
||||
GSD operates a central registry (see the PRD).
|
||||
MSD operates a central registry (see the PRD).
|
||||
|
||||
### Obsidian: no sandbox, stated honestly
|
||||
|
||||
@@ -144,17 +144,17 @@ on by default — no community plugins run until the user deliberately disables
|
||||
restricted mode — plus a human-curated plugin directory that requires a
|
||||
maintainer review PR for each new plugin.
|
||||
|
||||
GSD borrows two things from Obsidian. First, the honesty: **there is no
|
||||
MSD borrows two things from Obsidian. First, the honesty: **there is no
|
||||
sandbox**, and this document says so directly rather than implying one. Second,
|
||||
the principle that explicit opt-in per capability is better than a blanket "all
|
||||
community plugins are safe" message. GSD does not use restricted mode, but its
|
||||
community plugins are safe" message. MSD does not use restricted mode, but its
|
||||
consent gate at install serves the same function: executable surfaces are
|
||||
disclosed and consented to before they activate, not discovered after the fact.
|
||||
|
||||
GSD does not borrow Obsidian's centralised review model. Requiring a
|
||||
MSD does not borrow Obsidian's centralised review model. Requiring a
|
||||
maintainer-review PR for every third-party capability is the bottleneck that
|
||||
makes the Obsidian system painful for authors and creates a PR-queue burden
|
||||
for maintainers. GSD ships decentralised URL import precisely to avoid that.
|
||||
for maintainers. MSD ships decentralised URL import precisely to avoid that.
|
||||
|
||||
### Claude Code: trust prompt + marketplace
|
||||
|
||||
@@ -163,9 +163,9 @@ elevated trust, lists the permissions the extension requests, and maintains a
|
||||
`strictKnownMarketplaces` allowlist for managed environments where only
|
||||
reviewed sources are permitted. Claude Code's SHA-pinning mechanic (pinning to
|
||||
a specific version hash rather than floating on `latest`) is the direct model
|
||||
for GSD's integrity field.
|
||||
for MSD's integrity field.
|
||||
|
||||
GSD mirrors the allowlist mechanic as `strictKnownRegistries`, and mirrors the
|
||||
MSD mirrors the allowlist mechanic as `strictKnownRegistries`, and mirrors the
|
||||
SHA-pin as the `integrity` field in `capability.json` and the capability
|
||||
ledger.
|
||||
|
||||
@@ -175,7 +175,7 @@ ledger.
|
||||
|
||||
### Install never runs code
|
||||
|
||||
The most powerful thing GSD can say to a user about a third-party capability
|
||||
The most powerful thing MSD can say to a user about a third-party capability
|
||||
is: "downloading and staging this capability will not execute any of its code."
|
||||
That guarantee makes the consent step meaningful. If install could run code, a
|
||||
malicious capability could bypass consent entirely — the install step would be
|
||||
@@ -194,7 +194,7 @@ the point at which a hook would fire for the first time is not a prompt
|
||||
opportunity; it is already inside a running tool invocation. This means the
|
||||
consent window is install, not first use.
|
||||
|
||||
GSD presents a pre-install summary that names every executable surface the
|
||||
MSD presents a pre-install summary that names every executable surface the
|
||||
capability declares (hooks, MCP servers, command modules), their kinds (`step`,
|
||||
`contribution`, `gate`), and the loop extension points they register into. For
|
||||
each MCP server the summary also shows the `env` it would be spawned with (each
|
||||
@@ -285,7 +285,7 @@ Two things worth stating so you do not infer them:
|
||||
### Integrity pinning
|
||||
|
||||
An `integrity` field in `capability.json` carries a `sha512-<base64>` digest
|
||||
of the capability bundle. When present, GSD verifies this digest before
|
||||
of the capability bundle. When present, MSD verifies this digest before
|
||||
extracting any files. A mismatch aborts the install.
|
||||
|
||||
When NO pin is supplied, the consent prompt says so plainly: a
|
||||
@@ -360,11 +360,11 @@ code it does not own — whether by accident or by design.
|
||||
|
||||
### Reserved namespace
|
||||
|
||||
The `gsd-`, `gsd-core-`, and `anthropic-` id prefixes are reserved for
|
||||
The `msd-`, `msd-core-`, and `anthropic-` id prefixes are reserved for
|
||||
first-party use. A third-party capability that claims one of these prefixes is
|
||||
rejected at the conformance gate. This prevents impersonation: a malicious
|
||||
actor cannot publish a capability called `gsd-security` and exploit a user's
|
||||
implicit trust in the GSD namespace.
|
||||
actor cannot publish a capability called `msd-security` and exploit a user's
|
||||
implicit trust in the MSD namespace.
|
||||
|
||||
### `capabilities.strict_known_registries` for managed environments
|
||||
|
||||
@@ -389,7 +389,7 @@ with the consent prompt as the default barrier and lockdown one config key away.
|
||||
### Command dispatch: where third-party code runs (1.6.0)
|
||||
|
||||
A capability may declare a **command family** (`commands: [{ family, module,
|
||||
router }]`); `gsd-tools <family>` dispatches it by `require()`-ing the router.
|
||||
router }]`); `msd-tools <family>` dispatches it by `require()`-ing the router.
|
||||
This is the one place a third-party capability's own code executes, so it is
|
||||
gated twice. **Consent:** a third-party family is dispatchable only if the
|
||||
capability is *active* under the activation gate below — for a project-scoped
|
||||
@@ -403,20 +403,20 @@ command can never be shadowed by a third-party one.
|
||||
|
||||
#### The project-scope trust boundary
|
||||
|
||||
Capabilities install **globally** (`$GSD_HOME/.gsd/capabilities/`) or
|
||||
**project-scoped** (`<projectRoot>/.gsd/capabilities/`). The authoritative
|
||||
Capabilities install **globally** (`$MSD_HOME/.msd/capabilities/`) or
|
||||
**project-scoped** (`<projectRoot>/.msd/capabilities/`). The authoritative
|
||||
consent signal is **not** the in-repo ledger but a **user-owned consent store**
|
||||
that lives **outside any repository**, at
|
||||
`${GSD_HOME||homedir()}/.gsd/consent.json`. Each project-scope consent record is
|
||||
`${MSD_HOME||homedir()}/.msd/consent.json`. Each project-scope consent record is
|
||||
keyed by `(realpath(projectRoot), capability id)` and binds the bundle's
|
||||
`integrity` and its disclosure signature; GSD writes one only when *you* install
|
||||
`integrity` and its disclosure signature; MSD writes one only when *you* install
|
||||
or upgrade that project-scoped capability through the lifecycle on this machine,
|
||||
and removes it when you uninstall.
|
||||
|
||||
Before activating a project-scoped overlay — for **both** its declarative loop
|
||||
surfaces (steps, gates, contributions, federated config) **and** its command
|
||||
dispatch — the loader requires a matching record in this store. With no match the
|
||||
capability is *discovered but inactive*: it shows up in `gsd capability list`
|
||||
capability is *discovered but inactive*: it shows up in `msd capability list`
|
||||
with `status: inactive` and a reason, but contributes nothing and runs nothing.
|
||||
|
||||
This closes the previous bypass: a repo you check out could ship a capability
|
||||
@@ -426,14 +426,14 @@ you consent on this machine — and because the consent binds the integrity and
|
||||
the disclosure signature, tampering with the bundle (including changing an MCP
|
||||
server's `env` or `cwd`) deactivates it until you re-consent. A **global**
|
||||
install (under your own home) is trusted without a per-project record, as before.
|
||||
You can audit and revoke project consents with `gsd capability trust list` and
|
||||
`gsd capability trust revoke <id>`.
|
||||
You can audit and revoke project consents with `msd capability trust list` and
|
||||
`msd capability trust revoke <id>`.
|
||||
|
||||
---
|
||||
|
||||
## The honest limitation: there is no sandbox
|
||||
|
||||
GSD does not sandbox third-party capability code. The honest reason: Node-level
|
||||
MSD does not sandbox third-party capability code. The honest reason: Node-level
|
||||
sandboxing that meaningfully restricts a `require()`'d module — limiting
|
||||
filesystem access, network access, subprocess spawning — would require either
|
||||
a separate process with IPC overhead or a VM context that strips the Node
|
||||
@@ -442,7 +442,7 @@ network for MCP, subprocess for hook shell commands). Full artifact parity and
|
||||
meaningful sandboxing are in tension. The maintainer chose full parity.
|
||||
|
||||
What this means in practice: a third-party capability, once consented to and
|
||||
installed, runs with the same permissions GSD Core itself runs with. It is not
|
||||
installed, runs with the same permissions MSD Core itself runs with. It is not
|
||||
isolated. A capability that wants to exfiltrate data, or modify files outside
|
||||
its declared scope, can — exactly as a malicious npm package can.
|
||||
|
||||
@@ -452,7 +452,7 @@ The barrier is not a technical wall. It is:
|
||||
capability declares before they ran.
|
||||
2. **Integrity** — the bundle you consented to is the bundle that ran (SHA
|
||||
verified).
|
||||
3. **Reversibility** — `gsd capability remove <id>` removes exactly what the
|
||||
3. **Reversibility** — `msd capability remove <id>` removes exactly what the
|
||||
ledger recorded, including entries in shared config files, leaving no
|
||||
orphaned state.
|
||||
|
||||
@@ -475,24 +475,24 @@ instructions from the agent's context. What there is no sandbox for is not only
|
||||
|
||||
The safer alternative considered in ADR-1244 was declarative-only third-party
|
||||
capabilities: skills, agents, and workflow files, but no hooks, MCP servers, or
|
||||
command modules. A third-party author could extend *what GSD describes* but not
|
||||
command modules. A third-party author could extend *what MSD describes* but not
|
||||
*what it executes*.
|
||||
|
||||
The maintainer rejected this. A deploy gate capability, a house-style
|
||||
verification step, a domain-specific planning contribution — all of these
|
||||
require hook registration to have any effect on the loop. Declarative-only
|
||||
third-party capabilities would be second-class citizens, unable to participate
|
||||
in the parts of GSD where participation matters most. Full parity was the
|
||||
in the parts of MSD where participation matters most. Full parity was the
|
||||
explicit scope.
|
||||
|
||||
The cost of that choice is a permanently elevated security responsibility: URL
|
||||
import with executable surfaces is the highest-maintenance, highest-risk part
|
||||
of GSD. The trust model is a forever commitment, not a one-time effort.
|
||||
of MSD. The trust model is a forever commitment, not a one-time effort.
|
||||
|
||||
### Centralised-registry-only distribution
|
||||
|
||||
The alternative to decentralised URL/git import is requiring all third-party
|
||||
capabilities to go through a GSD-operated curated registry — one PR per
|
||||
capabilities to go through a MSD-operated curated registry — one PR per
|
||||
capability, reviewed by the maintainer before listing.
|
||||
|
||||
This would meaningfully reduce supply-chain risk (a human reviews every listed
|
||||
@@ -503,7 +503,7 @@ capabilities, and replicates exactly the bottleneck that makes Obsidian's
|
||||
plugin system painful.
|
||||
|
||||
The compromise: URL/git/npm/tarball import ships in 1.6.0 without a curated
|
||||
registry. Whether GSD later operates or advertises a community registry is an
|
||||
registry. Whether MSD later operates or advertises a community registry is an
|
||||
open question (PRD-1244 §8). If it does, the intent is to separate "official"
|
||||
(curated) from "community" (consented-but-not-reviewed) tiers, mirroring the
|
||||
split Claude Code uses for its marketplace.
|
||||
@@ -514,10 +514,10 @@ split Claude Code uses for its marketplace.
|
||||
|
||||
The capability trust model rests on a single conceptual move: separating
|
||||
artifact parity from trust posture. Because those two things are kept separate,
|
||||
GSD can offer authors the full power of the platform while making users'
|
||||
MSD can offer authors the full power of the platform while making users'
|
||||
security obligations clear and auditable. You consent to executable surfaces
|
||||
before they run, you can verify the bundle's integrity, and you can remove a
|
||||
capability completely. GSD does not pretend this is the same as not running
|
||||
capability completely. MSD does not pretend this is the same as not running
|
||||
the code at all.
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user