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:
@@ -2,7 +2,7 @@
|
||||
|
||||
**Goal:** Get a red differential-attribution check to green when the ripple it found is deliberate — by declaring it in a commit trailer on your own branch, so nothing is left behind in the tree once your PR merges.
|
||||
|
||||
**Prerequisites:** A branch whose CI failed with an unattributable emitted-artifact delta, or with growth in a `gsd-core/workflows/*.md` or `agents/gsd-*.md` file. The failure output names the key and the space; you do not need to work either out yourself.
|
||||
**Prerequisites:** A branch whose CI failed with an unattributable emitted-artifact delta, or with growth in a `msd-core/workflows/*.md` or `agents/msd-*.md` file. The failure output names the key and the space; you do not need to work either out yourself.
|
||||
|
||||
For why the acknowledgment lives in a commit rather than a file, see [ADR-3942](../adr/3942-emitted-drift-ack-commit-trailer.md). For the conservation law it is an escape hatch from, see [ADR-2719](../adr/2719-emitted-artifact-attribution.md). This guide covers only how to *declare* one.
|
||||
|
||||
@@ -15,7 +15,7 @@ There are two, and they are separate namespaces. A trailer in the wrong one will
|
||||
| Your failure says | Trailer | Key |
|
||||
|---|---|---|
|
||||
| an emitted path's hash moved and your diff cannot explain it | `Emitted-Drift-Ack-Hash:` | the emitted path exactly as printed — always contains a `/` |
|
||||
| a workflow or agent file grew | `Emitted-Drift-Ack-Growth:` | the **bare filename** as it appears under `gsd-core/workflows/` or `agents/` |
|
||||
| a workflow or agent file grew | `Emitted-Drift-Ack-Growth:` | the **bare filename** as it appears under `msd-core/workflows/` or `agents/` |
|
||||
|
||||
The failure output tells you which applies. If you are guessing, you have the wrong one.
|
||||
|
||||
@@ -32,7 +32,7 @@ git commit --trailer "Emitted-Drift-Ack-Growth: explore.md — new dispatch sect
|
||||
On a commit you already made:
|
||||
|
||||
```bash
|
||||
git commit --amend --trailer "Emitted-Drift-Ack-Hash: skills/gsd-add-tests/SKILL.md — converter rewrote every skill header"
|
||||
git commit --amend --trailer "Emitted-Drift-Ack-Hash: skills/msd-add-tests/SKILL.md — converter rewrote every skill header"
|
||||
```
|
||||
|
||||
Amending is the intended route, not a workaround. The trailer cannot drift out of sync with the diff it explains, because changing either changes the sha and re-runs the gate.
|
||||
@@ -66,4 +66,4 @@ Use `Emitted-Drift-Ack-Hash:` instead if the fragment's key contained a `/`. A f
|
||||
| a key was declared twice with different reasons | two commits in your range declare the same key and disagree | keep one. Identical repeats are deduplicated silently; conflicting ones are ambiguous and refused |
|
||||
| an invalid key | your key contains whitespace, `<`, or `>` | you probably pasted a placeholder from documentation. Use the real path or filename |
|
||||
| the range is structurally uncomputable | the checkout has no common ancestor — typically a shallow clone | this is a CI configuration problem, not something a trailer fixes. The gate fails loudly here rather than reading your branch as having no acknowledgments |
|
||||
| a new file over the size cap | `NEW_FILE_CAP` is deliberately **not** acknowledgeable | extract content instead — lazily, via `gsd-core/references/`. An eager `@`-import shrinks the file without shrinking loaded context, which games the guard while making the real cost worse |
|
||||
| a new file over the size cap | `NEW_FILE_CAP` is deliberately **not** acknowledgeable | extract content instead — lazily, via `msd-core/references/`. An eager `@`-import shrinks the file without shrinking loaded context, which games the guard while making the real cost worse |
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
**Goal:** Turn on the complexity-triggered refactor hook, understand the proposals it surfaces after a phase, and dispose of each one — so a function that grew a branch per phase gets refactored while it is still one function, instead of becoming a rewrite nobody noticed accumulating.
|
||||
|
||||
**Prerequisites:** A GSD project on v1.10.0 or later. Nothing else — the hook has no external dependency and needs no indexer. It is **off by default**; a project that never enables it is completely unaffected.
|
||||
**Prerequisites:** A MSD project on v1.10.0 or later. Nothing else — the hook has no external dependency and needs no indexer. It is **off by default**; a project that never enables it is completely unaffected.
|
||||
|
||||
For what the metric measures, why the anchor moves only on disposition, and the metric's known biases, see [Complexity-Triggered Refactor](../FEATURES.md#159-complexity-triggered-refactor) and [ADR-1953](../adr/1953-complexity-triggered-refactor.md). This guide covers only how to *use* it.
|
||||
|
||||
@@ -11,15 +11,15 @@ For what the metric measures, why the anchor moves only on disposition, and the
|
||||
## Turn it on
|
||||
|
||||
```bash
|
||||
gsd config-set refactor.trigger_enabled true
|
||||
msd config-set refactor.trigger_enabled true
|
||||
```
|
||||
|
||||
That is the whole setup. From the next `/gsd-execute-phase`, an `execute:post` step measures the files that phase touched and writes a proposal only if something crosses a line. Nothing else about the loop changes: the hook never edits code, never picks a refactor, and never blocks.
|
||||
That is the whole setup. From the next `/msd-execute-phase`, an `execute:post` step measures the files that phase touched and writes a proposal only if something crosses a line. Nothing else about the loop changes: the hook never edits code, never picks a refactor, and never blocks.
|
||||
|
||||
To check it without running a phase:
|
||||
|
||||
```bash
|
||||
node gsd-tools.cjs refactor evaluate --phase 3 --raw
|
||||
node msd-tools.cjs refactor evaluate --phase 3 --raw
|
||||
```
|
||||
|
||||
---
|
||||
@@ -44,8 +44,8 @@ Both thresholds are **strictly greater** — a score of exactly 15 against a thr
|
||||
A proposal stays untriaged until you disposition it. There are exactly two ways, and **both** clear it:
|
||||
|
||||
```bash
|
||||
node gsd-tools.cjs refactor accept --phase 3
|
||||
node gsd-tools.cjs refactor decline --phase 3 --reason "flat dispatch table — branchy by construction, not a hotspot"
|
||||
node msd-tools.cjs refactor accept --phase 3
|
||||
node msd-tools.cjs refactor decline --phase 3 --reason "flat dispatch table — branchy by construction, not a hotspot"
|
||||
```
|
||||
|
||||
**Accept** when you intend to refactor. The anchor re-anchors to the function's current score, so after you do the work the next evaluation measures growth from the new, lower baseline.
|
||||
@@ -57,7 +57,7 @@ node gsd-tools.cjs refactor decline --phase 3 --reason "flat dispatch table —
|
||||
To see what is outstanding across the project:
|
||||
|
||||
```bash
|
||||
node gsd-tools.cjs refactor status
|
||||
node msd-tools.cjs refactor status
|
||||
```
|
||||
|
||||
---
|
||||
@@ -67,8 +67,8 @@ node gsd-tools.cjs refactor status
|
||||
If proposals feel like noise, raise the threshold rather than turning the hook off:
|
||||
|
||||
```bash
|
||||
gsd config-set refactor.complexity_threshold 20 # ESLint's own default
|
||||
gsd config-set refactor.complexity_jump_delta 8
|
||||
msd config-set refactor.complexity_threshold 20 # ESLint's own default
|
||||
msd config-set refactor.complexity_jump_delta 8
|
||||
```
|
||||
|
||||
Defaults are 15 (SonarSource's default) and 5. For reference, radon's rank C — "moderate, slightly complex" — begins at 11, and ESLint's `complexity` rule defaults to 20. There is no universally correct number; start at the default and raise it once you have seen a few proposals you disagreed with.
|
||||
@@ -80,8 +80,8 @@ Defaults are 15 (SonarSource's default) and 5. For reference, radon's rank C —
|
||||
Advisory mode surfaces proposals and tracks nothing. To make an untriaged proposal a task that must be resolved before shipping, you need **two** settings, not one:
|
||||
|
||||
```bash
|
||||
gsd config-set refactor.trigger_strict true # 1. record proposals in the ledger
|
||||
gsd config-set workflow.windows_enforce true # 2. make the ledger block /gsd-ship
|
||||
msd config-set refactor.trigger_strict true # 1. record proposals in the ledger
|
||||
msd config-set workflow.windows_enforce true # 2. make the ledger block /msd-ship
|
||||
```
|
||||
|
||||
Why two: `refactor.trigger_strict` records an untriaged proposal as an open `deviation` entry in the [broken-windows ledger](../FEATURES.md#158-broken-windows-ledger). The *blocking* is that capability's existing `ship:pre` gate, which is separately opt-in. Setting only the first gives you tracking without enforcement — which is a reasonable place to stop, but it will not stop a ship.
|
||||
@@ -92,7 +92,7 @@ If you enable only `refactor.trigger_strict`, every `refactor evaluate` that tri
|
||||
"warnings": [
|
||||
{
|
||||
"reason": "refactor_strict_not_enforcing",
|
||||
"message": "refactor.trigger_strict is on, but workflow.windows_enforce is off, so ship will not actually be blocked. Run: gsd config-set workflow.windows_enforce true"
|
||||
"message": "refactor.trigger_strict is on, but workflow.windows_enforce is off, so ship will not actually be blocked. Run: msd config-set workflow.windows_enforce true"
|
||||
}
|
||||
]
|
||||
```
|
||||
@@ -110,7 +110,7 @@ The hook is deliberately silent in several situations. If you expected a proposa
|
||||
| You see | What happened |
|
||||
|---|---|
|
||||
| `refactor_no_touched_files` | The phase changed nothing the analyzer looks at. |
|
||||
| `refactor_analyzer_unsupported` | The file's language or path is out of scope. Only `.js .cjs .mjs .ts .cts .mts` are analyzed; `tests/` and generated `gsd-core/bin/lib/` paths are excluded by design. |
|
||||
| `refactor_analyzer_unsupported` | The file's language or path is out of scope. Only `.js .cjs .mjs .ts .cts .mts` are analyzed; `tests/` and generated `msd-core/bin/lib/` paths are excluded by design. |
|
||||
| `refactor_analyzer_unparseable` | An unterminated string, template, or block comment. The analyzer **refuses to emit a score** it cannot defend rather than guessing — a silently wrong number is worse than none. |
|
||||
| `refactor_git_unavailable` | Not a git repository, `git` missing, the call timed out, or the phase has no committed `PLAN.md` to anchor against. Degrades quietly, exit 0. |
|
||||
| `refactor_file_unreadable` | One file could not be read, or resolved outside the project root. That file is skipped; the rest of the run continues. |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# How to add or update a host's integration capabilities
|
||||
|
||||
This guide is for GSD maintainers adding a new host CLI, or updating an existing host's
|
||||
This guide is for MSD maintainers adding a new host CLI, or updating an existing host's
|
||||
host-integration axes (ADR-1239 Phase A). It covers the **documentation-sourcing rule**, the
|
||||
nine `runtime.hostIntegration` axes, the `undocumented` sentinel, and how to validate.
|
||||
|
||||
@@ -62,7 +62,7 @@ axis. It validates, but `negotiateHostCapabilities` **fail-closes** on it (degra
|
||||
restrictive known value) — so it is always safe and never a silent capability claim. A dispatch
|
||||
boolean, `maxDepth`, `isolation`, or `maxConcurrency` may also be `"undocumented"`.
|
||||
|
||||
**Do not conflate the orthogonal axes:** `commandStyle` (GSD's emission style) is *not*
|
||||
**Do not conflate the orthogonal axes:** `commandStyle` (MSD's emission style) is *not*
|
||||
`commandSurface` (the host's surface type); the `hookEvents` dialect is *not* `hookBus` (bus
|
||||
ownership); `runtimeCompat` (which features run on a host) is independent of these runtime→engine
|
||||
axes.
|
||||
@@ -82,14 +82,14 @@ npm run gen:capability-registry # validateRuntimeBody runs on every descriptor
|
||||
```
|
||||
|
||||
`gen:capability-registry` must succeed with zero errors. The validator
|
||||
(`gsd-core/bin/lib/capability-validator.cjs`) rejects out-of-vocabulary values, malformed dispatch
|
||||
(`msd-core/bin/lib/capability-validator.cjs`) rejects out-of-vocabulary values, malformed dispatch
|
||||
structs, and reserved keys (`__proto__`/`constructor`/`prototype`).
|
||||
|
||||
Then run the host-integration tests and the full cross-platform suite:
|
||||
|
||||
```bash
|
||||
node --test tests/host-integration-descriptors.test.cjs # asserts every descriptor validates + profiles
|
||||
gsd-test-both # Mac + Linux Docker (run before any PR)
|
||||
msd-test-both # Mac + Linux Docker (run before any PR)
|
||||
```
|
||||
|
||||
## 6. If you need a vocabulary value that does not exist yet
|
||||
@@ -121,7 +121,7 @@ yields the same truth value**, so behavior is unchanged and only the brittle cou
|
||||
2. **Declare the behaviors on the descriptor.** Add a `runtime.hostBehaviors` object to the host's
|
||||
`capability.json`. Each key names one behavior the branches gated on — e.g. for `claude`:
|
||||
`permissionsSchema: "claude"`, `settingsFileByScope: { local: "settings.local.json", global: "settings.json" }`,
|
||||
`sourceMarkerFile: ".gsd-source"`, `agentFrontmatterExtensions: ["effort"]`, `localInstallStyle: "legacy-flat"`,
|
||||
`sourceMarkerFile: ".msd-source"`, `agentFrontmatterExtensions: ["effort"]`, `localInstallStyle: "legacy-flat"`,
|
||||
`authorsCanonicalWorkflow: true`, `ownsClaudePaths: true`, `nativeModelAliases: true`,
|
||||
`skillsGlobalOnboarding: true`, `attributionSource: "settings-json-commit"`. The validator
|
||||
(`validateRuntimeBody`) is lenient toward these host-behavior keys; they carry install policy, not the
|
||||
@@ -144,7 +144,7 @@ yields the same truth value**, so behavior is unchanged and only the brittle cou
|
||||
from your branch against `next`'s recorded state and requires every moved hash to be
|
||||
attributable to a path your PR changed — no fixture to regenerate by hand. Confirm the
|
||||
host's install is unchanged for **global and local** scopes. Exclude only genuinely
|
||||
volatile / platform-varying files (`settings.json`, `settings.local.json`, `.gsd-source`).
|
||||
volatile / platform-varying files (`settings.json`, `settings.local.json`, `.msd-source`).
|
||||
|
||||
6. **Guard against regression.** Add a `*-imperative-reference.test.cjs` asserting the adapter classifies
|
||||
the host correctly, negotiation fails closed on a corrupted descriptor, and — with a source-grep behind
|
||||
@@ -178,7 +178,7 @@ upgrades (multi-event hook bus; negotiated `dispatch.background`) this PR adds.
|
||||
> `capability.json`, not hardcoded). All three exist because the descriptor pipeline lacked one
|
||||
> thing: per-agent resolution context (`targetDir` + `agentName`).
|
||||
>
|
||||
> Declaring an `agents` entry also takes effect on the **surface** path (`/gsd-surface --materialize`)
|
||||
> Declaring an `agents` entry also takes effect on the **surface** path (`/msd-surface --materialize`)
|
||||
> immediately, not only on install — the two paths are intentionally converged.
|
||||
|
||||
---
|
||||
@@ -186,5 +186,5 @@ upgrades (multi-event hook bus; negotiated `dispatch.background`) this PR adds.
|
||||
## Related
|
||||
|
||||
- Reference: [`docs/reference/host-integration-capability-matrix.md`](../reference/host-integration-capability-matrix.md) — the per-CLI sourced values.
|
||||
- ADR: [`docs/adr/1239-gsd-embeddable-orchestration-engine.md`](../adr/1239-gsd-embeddable-orchestration-engine.md) — why the interface exists and the Phase A amendment.
|
||||
- ADR: [`docs/adr/1239-msd-embeddable-orchestration-engine.md`](../adr/1239-msd-embeddable-orchestration-engine.md) — why the interface exists and the Phase A amendment.
|
||||
- The closed-vocabulary runtime descriptor it extends: [ADR-1016](../adr/1016-runtime-capability-descriptor.md).
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# How to adopt the v2 exit contract
|
||||
|
||||
`gsd-tools` runs, by default, under exit-contract **`v1`** — every observable exit code is
|
||||
`msd-tools` runs, by default, under exit-contract **`v1`** — every observable exit code is
|
||||
byte-identical to every prior release. **`v2`** is an opt-in projection, per
|
||||
[ADR-3889](../adr/3889-process-exit-contract.md) §4, that turns a small set of previously
|
||||
same-looking outcomes into distinct, non-zero exit codes a CI gate can branch on without parsing
|
||||
@@ -9,7 +9,7 @@ today treats "any non-zero exit" as fatal.
|
||||
|
||||
## Should you turn this on?
|
||||
|
||||
Turn it on if a script or CI gate wraps `gsd-tools` and needs to tell "ran fine", "you called it
|
||||
Turn it on if a script or CI gate wraps `msd-tools` and needs to tell "ran fine", "you called it
|
||||
wrong", "there was nothing to find", "a prerequisite was missing", "it crashed", and "it ran but is
|
||||
reporting a condition in its payload" apart **from the exit code alone**, instead of parsing JSON on
|
||||
stdout to find out. If your caller only ever needs pass/fail, `v1` already gives you that — there is
|
||||
@@ -22,14 +22,14 @@ given in the same invocation.
|
||||
|
||||
```bash
|
||||
# Per-invocation (preferred in test code and one-off scripts):
|
||||
node gsd-tools.cjs --exit-contract=v2 state validate --strict
|
||||
node msd-tools.cjs --exit-contract=v2 state validate --strict
|
||||
|
||||
# Process-wide (preferred for CI and shell wrappers):
|
||||
export GSD_EXIT_CONTRACT=v2
|
||||
gsd-tools state validate --strict
|
||||
export MSD_EXIT_CONTRACT=v2
|
||||
msd-tools state validate --strict
|
||||
```
|
||||
|
||||
The flag works in any argv position — before the subcommand or after it — and `gsd-tools` strips
|
||||
The flag works in any argv position — before the subcommand or after it — and `msd-tools` strips
|
||||
it before dispatch, exactly as it already does for `--json-errors`.
|
||||
|
||||
Only the exact lowercase tokens `v1`/`v2` are accepted. Anything else present — a typo, `V2`,
|
||||
@@ -38,13 +38,13 @@ a selector for a contract whose whole point is "nothing fails with success" must
|
||||
open. That throw surfaces as a stack trace at exit `1`, not as a tidy `USAGE` `64`, and that is
|
||||
deliberate: the failure is *the version being unresolvable*, so there is no contract version yet
|
||||
under which to project a code. Loud and coarse beats quiet and wrong. An empty
|
||||
`GSD_EXIT_CONTRACT=` (nothing after the `=`) reads as **unset**, not as an explicit selection, so a
|
||||
`MSD_EXIT_CONTRACT=` (nothing after the `=`) reads as **unset**, not as an explicit selection, so a
|
||||
shell that exports it empty still gets `v1`.
|
||||
|
||||
## Step 2 — read the code table
|
||||
|
||||
`v2` projects a declared outcome through one generated registry
|
||||
(`gsd-core/bin/lib/exit-code-registry.cjs`). Every code below is stable and machine-checked; do not
|
||||
(`msd-core/bin/lib/exit-code-registry.cjs`). Every code below is stable and machine-checked; do not
|
||||
hardcode the integers in your own scripts — call `exitCodeFor(name)` if you are writing Node, or
|
||||
just compare against the number after reading it here once.
|
||||
|
||||
@@ -58,14 +58,14 @@ just compare against the number after reading it here once.
|
||||
| `70` | `INTERNAL` | Self-failure — the run itself broke (crash, timeout, killed subprocess), not its inputs. |
|
||||
| `80` | `DEGRADED` | Ran to completion and is **reporting a condition through its result payload**, not failing as a process. |
|
||||
|
||||
`2` is reserved to the Claude Code hook-protocol deny and is never produced by `gsd-tools` itself —
|
||||
`2` is reserved to the Claude Code hook-protocol deny and is never produced by `msd-tools` itself —
|
||||
you will not see it from a CLI invocation.
|
||||
|
||||
## Step 3 — understand `80` specifically
|
||||
|
||||
`80` (`DEGRADED`) is the one code most CI authors get wrong, because it is the one code where "ran
|
||||
to completion" and "found a problem" are the same event. It fires when a command's JSON payload
|
||||
carries a **serializable** `error` key — for example `gsd-tools state-snapshot` in a project with
|
||||
carries a **serializable** `error` key — for example `msd-tools state-snapshot` in a project with
|
||||
no `STATE.md` returns `{"error": "STATE.md not found"}`. Under `v1` that exits `0`; under `v2` it
|
||||
exits `80`.
|
||||
|
||||
@@ -82,8 +82,8 @@ diagnosed.
|
||||
The naive shell form,
|
||||
|
||||
```sh
|
||||
if ! gsd-tools state-snapshot > snap.json; then
|
||||
echo "gsd-tools failed" >&2
|
||||
if ! msd-tools state-snapshot > snap.json; then
|
||||
echo "msd-tools failed" >&2
|
||||
exit 1
|
||||
fi
|
||||
```
|
||||
@@ -95,7 +95,7 @@ still hard-fail on `USAGE`/`UNAVAILABLE`/`INTERNAL`":
|
||||
|
||||
```sh
|
||||
set +e
|
||||
gsd-tools --exit-contract=v2 state-snapshot > snap.json
|
||||
msd-tools --exit-contract=v2 state-snapshot > snap.json
|
||||
code=$?
|
||||
set -e
|
||||
|
||||
@@ -103,10 +103,10 @@ case "$code" in
|
||||
0) ;; # PASS
|
||||
80) echo "degraded result — inspect snap.json" >&2 ;; # ran, reported a condition — your call whether this gates the pipeline
|
||||
64|66|69|70)
|
||||
echo "gsd-tools failed (exit $code)" >&2
|
||||
echo "msd-tools failed (exit $code)" >&2
|
||||
exit 1
|
||||
;;
|
||||
*) echo "gsd-tools failed (unrecognized exit $code)" >&2
|
||||
*) echo "msd-tools failed (unrecognized exit $code)" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Run a long-running job asynchronously with the SLURM adapter
|
||||
|
||||
> **How-To** (Diátaxis). When a GSD execute task is legitimately long-running
|
||||
> **How-To** (Diátaxis). When a MSD execute task is legitimately long-running
|
||||
> (HPC solver, model training, large simulation — over ~30–60 min), externalize
|
||||
> it instead of blocking the agent turn. This guide uses the default-off
|
||||
> `external-job` Capability's SLURM adapter (#1164 / #1105).
|
||||
@@ -16,7 +16,7 @@ see the [operation policy reference](../reference/long-running-operations.md).
|
||||
- The `external-job` capability is enabled (`external_job.enabled: true` in
|
||||
`.planning/config.json`). It is **default-off**.
|
||||
- A SLURM cluster is reachable (`sbatch`, `squeue`, `sacct` on PATH).
|
||||
- You are inside a GSD project (a `.planning/` directory is present).
|
||||
- You are inside a MSD project (a `.planning/` directory is present).
|
||||
|
||||
## 1. Submit the job
|
||||
|
||||
@@ -29,13 +29,13 @@ node scripts/slurm-adapter.cjs submit \
|
||||
--plan 3.1 --phase 3 \
|
||||
--expected Artifacts/jobs/12345/result.h5,Artifacts/jobs/12345/metrics.json \
|
||||
--verify "python -m verify.py 12345" \
|
||||
--resume "/gsd-execute-phase 3" \
|
||||
--resume "/msd-execute-phase 3" \
|
||||
-- sbatch --parsable --output=Artifacts/jobs/%j/out.log ./train.sh
|
||||
```
|
||||
|
||||
What happens:
|
||||
- `sbatch` runs with a **bounded** subprocess timeout
|
||||
(`GSD_SLURM_SUBMIT_TIMEOUT_MS`, default 30 s).
|
||||
(`MSD_SLURM_SUBMIT_TIMEOUT_MS`, default 30 s).
|
||||
- The `--parsable` output is parsed for the job id.
|
||||
- A versioned manifest is written to `.planning/async-jobs/<job_id>.json`.
|
||||
- The adapter **refuses** to create a second non-terminal manifest for a
|
||||
@@ -87,7 +87,7 @@ node scripts/slurm-adapter.cjs show --job 12345
|
||||
`show` prints the status and lists `submit_command`, `verification_command`,
|
||||
and `resume_command` for explicit confirmation. After you run the verification
|
||||
command yourself and confirm the `expected_artifacts` exist, write `SUMMARY.md`
|
||||
and close the plan (`/gsd-execute-phase 3` reconciles and lifts the deferral).
|
||||
and close the plan (`/msd-execute-phase 3` reconciles and lifts the deferral).
|
||||
|
||||
## 5. Handle terminal failure
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# How to attach a plugin-provided skill to a GSD agent
|
||||
# How to attach a plugin-provided skill to a MSD agent
|
||||
|
||||
Use this guide when you have a Claude Code plugin that ships a skill and you want GSD agents to load it automatically at spawn time. The `global:<plugin>:<skill>` entry form makes GSD emit a Skill-tool load directive so the agent picks up the plugin skill alongside any project-local or personal global skills.
|
||||
Use this guide when you have a Claude Code plugin that ships a skill and you want MSD agents to load it automatically at spawn time. The `global:<plugin>:<skill>` entry form makes MSD emit a Skill-tool load directive so the agent picks up the plugin skill alongside any project-local or personal global skills.
|
||||
|
||||
**This feature works on the Claude runtime only.** On other runtimes (Codex, Antigravity, Cursor, etc.) the entry is skipped with a warning. Plan accordingly if your team uses multiple runtimes.
|
||||
|
||||
@@ -8,7 +8,7 @@ Use this guide when you have a Claude Code plugin that ships a skill and you wan
|
||||
|
||||
## 1. Install the plugin in Claude Code
|
||||
|
||||
GSD does not install or manage Claude Code plugins. Install the plugin first:
|
||||
MSD does not install or manage Claude Code plugins. Install the plugin first:
|
||||
|
||||
```
|
||||
/plugin install <plugin-source>
|
||||
@@ -43,11 +43,11 @@ Open `.planning/config.json` and add the namespaced skill to the array for the a
|
||||
```json
|
||||
{
|
||||
"agent_skills": {
|
||||
"gsd-executor": [
|
||||
"msd-executor": [
|
||||
"skills/project-conventions",
|
||||
"global:coderabbit:code-review"
|
||||
],
|
||||
"gsd-verifier": [
|
||||
"msd-verifier": [
|
||||
"global:coderabbit:code-review"
|
||||
]
|
||||
}
|
||||
@@ -59,7 +59,7 @@ You can mix all three entry forms freely within the same array — project-relat
|
||||
Or set it from the CLI:
|
||||
|
||||
```bash
|
||||
gsd-tools query config-set agent_skills.gsd-executor '["skills/project-conventions","global:coderabbit:code-review"]'
|
||||
msd-tools query config-set agent_skills.msd-executor '["skills/project-conventions","global:coderabbit:code-review"]'
|
||||
```
|
||||
|
||||
---
|
||||
@@ -84,15 +84,15 @@ If you see `[agent-skills] WARNING: Plugin-namespaced skill "global:coderabbit:c
|
||||
|
||||
## Notes
|
||||
|
||||
- **Plugin must be pre-installed.** GSD only references the skill by namespaced name. If the plugin is not installed in Claude Code, the Skill tool call will fail at agent runtime — GSD cannot validate plugin presence at configuration time.
|
||||
- **Which agents support it.** All 22 GSD agent types that consume `agent_skills` carry the `Skill` tool, so any of them can load plugin-provided skills. See [Agent Skills Injection — Supported Agent Types](../CONFIGURATION.md#supported-agent-types) for the full list.
|
||||
- **Plugin must be pre-installed.** MSD only references the skill by namespaced name. If the plugin is not installed in Claude Code, the Skill tool call will fail at agent runtime — MSD cannot validate plugin presence at configuration time.
|
||||
- **Which agents support it.** All 22 MSD agent types that consume `agent_skills` carry the `Skill` tool, so any of them can load plugin-provided skills. See [Agent Skills Injection — Supported Agent Types](../CONFIGURATION.md#supported-agent-types) for the full list.
|
||||
- **Non-Claude runtimes.** The `global:<plugin>:<skill>` entry is silently skipped with a warning on non-Claude runtimes. Project-relative and `global:<name>` entries work on all runtimes.
|
||||
- **Security boundary.** Plugin skill content is resolved entirely by Claude Code at agent runtime. GSD does not read, cache, or validate the plugin's files.
|
||||
- **Security boundary.** Plugin skill content is resolved entirely by Claude Code at agent runtime. MSD does not read, cache, or validate the plugin's files.
|
||||
|
||||
---
|
||||
|
||||
## Related
|
||||
|
||||
- [Configuration — Agent Skills Injection](../CONFIGURATION.md#agent-skills-injection)
|
||||
- [Install a minimal GSD and add skills later](install-minimal-and-add-skills.md)
|
||||
- [Install a minimal MSD and add skills later](install-minimal-and-add-skills.md)
|
||||
- [Import a capability from a URL](import-a-capability-from-a-url.md)
|
||||
@@ -1,14 +1,14 @@
|
||||
# How to author a host-plugin for GSD
|
||||
# How to author a host-plugin for MSD
|
||||
|
||||
This guide is for **external tool authors** who want to embed GSD's orchestration
|
||||
This guide is for **external tool authors** who want to embed MSD's orchestration
|
||||
loop (dispatch + hooks + model + state) into a new host — a CLI, IDE, or agent
|
||||
runtime GSD does not special-case — by writing a **host-plugin** against the
|
||||
published Host-Integration SDK, **without modifying gsd-core source**.
|
||||
runtime MSD does not special-case — by writing a **host-plugin** against the
|
||||
published Host-Integration SDK, **without modifying msd-core source**.
|
||||
|
||||
The contract is the SDK entry (`src/host-integration-sdk.cts` →
|
||||
`gsd-core/bin/lib/host-integration-sdk.cjs`): import only from it. Everything it
|
||||
`msd-core/bin/lib/host-integration-sdk.cjs`): import only from it. Everything it
|
||||
re-exports is public and versioned (`PROTOCOL_VERSION`); everything else in
|
||||
gsd-core is internal and may change. A smoke test
|
||||
msd-core is internal and may change. A smoke test
|
||||
(`tests/sdk-smoke.test.cjs`) proves a third-party host can be built from this
|
||||
surface alone.
|
||||
|
||||
@@ -36,7 +36,7 @@ Declare the nine negotiated axes (`embeddingMode`, `commandSurface`, `dispatch`,
|
||||
## 3. Compose the engine adapters
|
||||
|
||||
```js
|
||||
const SDK = require('@opengsd/gsd-core/sdk'); // the published entry
|
||||
const SDK = require('@golem15/msd-core/sdk'); // the published entry
|
||||
|
||||
// Engine-owned hook bus (for hosts with no event bus, e.g. VS Code):
|
||||
const hookBus = SDK.createHookBus({ bus: 'engine' });
|
||||
@@ -70,10 +70,10 @@ Map the six interface points (command, dispatch, model, hooks, state, artifact)
|
||||
to your host's primitives (palette/chat, plugin API, provider calls, etc.). The
|
||||
reference host-plugins (OpenCode, Antigravity, pi, VS Code — see Phase 5) are
|
||||
canonical examples to mirror. Your host-plugin is now a self-contained artifact;
|
||||
no gsd-core source change is required.
|
||||
no msd-core source change is required.
|
||||
|
||||
## See also
|
||||
|
||||
- **Tutorial:** `docs/tutorials/embed-gsd-in-a-new-host.md` — a complete end-to-end embedding.
|
||||
- **Tutorial:** `docs/tutorials/embed-msd-in-a-new-host.md` — a complete end-to-end embedding.
|
||||
- **Reference:** `docs/reference/host-integration-interface.md` — every axis, adapter, and the handshake.
|
||||
- **Versioning:** `docs/explanation/interface-versioning-policy.md` — what evolves additively vs. breaking.
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
# How to batch quick tasks
|
||||
|
||||
`/gsd-quick-batch` runs several `/gsd-quick`-shaped tasks together as ONE
|
||||
`/msd-quick-batch` runs several `/msd-quick`-shaped tasks together as ONE
|
||||
coordinated run: one coordinator parses the task list, plans and dispatches
|
||||
each item (planner, and optionally researcher/plan-checker/verifier leaves),
|
||||
merges them in a deterministic order, and owns every shared write
|
||||
(`BATCH.json`, `STATE.md`, worktree create/merge/cleanup) so the leaves never
|
||||
race each other (ADR-1239 "Quick-batch binding").
|
||||
|
||||
Use it instead of running `/gsd-quick` N separate times when you have several
|
||||
Use it instead of running `/msd-quick` N separate times when you have several
|
||||
independent (or lightly interdependent) small tasks you want planned and
|
||||
executed together, with parallelism where the tasks allow it.
|
||||
|
||||
@@ -21,7 +21,7 @@ Pass an inline task list — a bulleted or numbered list, at least 2 items,
|
||||
one per line:
|
||||
|
||||
```bash
|
||||
/gsd-quick-batch
|
||||
/msd-quick-batch
|
||||
- Fix the login timeout on mobile Safari
|
||||
- Add a retry banner when the API call fails
|
||||
- Update the README's setup instructions
|
||||
@@ -30,12 +30,12 @@ one per line:
|
||||
Or point at a file containing the list:
|
||||
|
||||
```bash
|
||||
/gsd-quick-batch --file .planning/my-tasks.md
|
||||
/msd-quick-batch --file .planning/my-tasks.md
|
||||
```
|
||||
|
||||
Each item gets its own quick id, its own directory under
|
||||
`.planning/quick/`, and (when isolation is available) its own worktree — the
|
||||
same artifact shape a standalone `/gsd-quick` task produces, just planned and
|
||||
same artifact shape a standalone `/msd-quick` task produces, just planned and
|
||||
dispatched together.
|
||||
|
||||
---
|
||||
@@ -45,18 +45,18 @@ dispatched together.
|
||||
| Flag | What it does |
|
||||
|------|-------------|
|
||||
| `--jobs auto\|N` | `auto` (default) uses the negotiated dispatch capacity as-is. `N` caps effective concurrency at `min(task count, N, capacity)` — never more than the number of tasks, never more than what the runtime negotiated. A non-numeric or non-positive `N` is rejected before any dispatch. |
|
||||
| `--validate` | Enables the per-item plan-checker loop (max 2 iterations, same cap as `/gsd-quick --validate`) and post-merge verification. |
|
||||
| `--validate` | Enables the per-item plan-checker loop (max 2 iterations, same cap as `/msd-quick --validate`) and post-merge verification. |
|
||||
| `--research` | Dispatches a focused researcher per item before planning. |
|
||||
| `--resume <batch-id>` | Skips task-list parsing and batch creation entirely — loads the existing batch and dispatches only its still-eligible items. |
|
||||
|
||||
**Not supported in v1:** `--discuss` and `--full` are rejected with a usage
|
||||
error before any dispatch. If a task genuinely needs a discussion phase, run
|
||||
it through `/gsd-quick --discuss` on its own instead of including it in a
|
||||
it through `/msd-quick --discuss` on its own instead of including it in a
|
||||
batch.
|
||||
|
||||
```bash
|
||||
/gsd-quick-batch --jobs 2 --validate --research # research, up to 2 concurrent, plan-checked + verified
|
||||
/gsd-quick-batch --resume 260101-abc # resume an interrupted batch
|
||||
/msd-quick-batch --jobs 2 --validate --research # research, up to 2 concurrent, plan-checked + verified
|
||||
/msd-quick-batch --resume 260101-abc # resume an interrupted batch
|
||||
```
|
||||
|
||||
---
|
||||
@@ -88,7 +88,7 @@ in, never in whichever order an executor happens to finish first.
|
||||
|
||||
## Dependencies and file overlap
|
||||
|
||||
Before planning, `/gsd-quick-batch` has no signal about which items depend
|
||||
Before planning, `/msd-quick-batch` has no signal about which items depend
|
||||
on each other or touch the same files — every item starts in the same wave.
|
||||
Each item's planner is shown the full batch's task catalog (every item's id
|
||||
and description) and is required to declare, in its plan's frontmatter,
|
||||
@@ -154,7 +154,7 @@ it, so you can inspect exactly what the executor did:
|
||||
recognizes the on-disk `SUMMARY.md` and routes the item straight to
|
||||
the merge step on its own; it will not re-dispatch a second executor
|
||||
for it.
|
||||
5. **Re-run** `/gsd-quick-batch --resume <batch-id>` once you're done. A
|
||||
5. **Re-run** `/msd-quick-batch --resume <batch-id>` once you're done. A
|
||||
`failed`/`merge_failed`/`scope_violation` item you resolved manually
|
||||
(merged and cleaned up yourself) is picked up as already-merged on the
|
||||
next resume; an item you decided to abandon stays `failed` and is
|
||||
|
||||
@@ -36,14 +36,14 @@ npm run regen:derived
|
||||
```
|
||||
|
||||
**The order matters and getting it wrong fails quietly.** The generator reads the *compiled*
|
||||
`gsd-core/bin/lib/state-md-schema.cjs`, not the TypeScript source. Regenerating before building
|
||||
`msd-core/bin/lib/state-md-schema.cjs`, not the TypeScript source. Regenerating before building
|
||||
regenerates against the previous schema, produces artifacts that look plausible, and commits a
|
||||
document that disagrees with the code you just wrote. If you are ever unsure whether the build is
|
||||
current, run `npm run build:lib` again — it is cheap and idempotent.
|
||||
|
||||
**3. Commit the regenerated artifacts.** They are generated *and committed*:
|
||||
|
||||
- `gsd-core/templates/state.md`
|
||||
- `msd-core/templates/state.md`
|
||||
- `docs/reference/state-md.md` and its `ja-JP`, `zh-CN`, `ko-KR`, `pt-BR` siblings
|
||||
|
||||
**4. Add the human-facing rows by hand.** Two tables in the reference documents are deliberately
|
||||
|
||||
@@ -30,7 +30,7 @@ the project root as its cwd and the inherited process environment.
|
||||
|
||||
```bash
|
||||
# Example: a bundled check script shipped with the capability
|
||||
node "${GSD_CAP_DIR}/checks/pre-ship.js"
|
||||
node "${MSD_CAP_DIR}/checks/pre-ship.js"
|
||||
```
|
||||
|
||||
You may interpolate three loop-context placeholders directly into the command:
|
||||
@@ -58,7 +58,7 @@ config key with `when`:
|
||||
"check": {
|
||||
"predicate": {
|
||||
"kind": "command-exit-zero",
|
||||
"command": "node \"${GSD_CAP_DIR}/checks/pre-ship.js\" \"${PHASE_DIR}\"",
|
||||
"command": "node \"${MSD_CAP_DIR}/checks/pre-ship.js\" \"${PHASE_DIR}\"",
|
||||
"timeout": 30
|
||||
}
|
||||
},
|
||||
@@ -95,7 +95,7 @@ You can run the evaluator standalone to verify your predicate before wiring it
|
||||
into a loop point:
|
||||
|
||||
```bash
|
||||
gsd_run check predicate \
|
||||
msd_run check predicate \
|
||||
--predicate '{"kind":"command-exit-zero","command":"node checks/pre-ship.js \"${PHASE_DIR}\"","timeout":30}' \
|
||||
--phase-dir ".planning/phases/03-my-phase" \
|
||||
--phase-number "03" \
|
||||
@@ -122,7 +122,7 @@ at your chosen point. The workflow gate-dispatch (`execute:wave:post`,
|
||||
dispatches the evaluator automatically — no further wiring needed.
|
||||
|
||||
```bash
|
||||
gsd_run loop render-hooks ship:pre --raw
|
||||
msd_run loop render-hooks ship:pre --raw
|
||||
```
|
||||
|
||||
## Gotchas
|
||||
@@ -136,7 +136,7 @@ gsd_run loop render-hooks ship:pre --raw
|
||||
- **Output is trimmed.** Only the last 2000 chars of stderr/stdout surface in
|
||||
the gate `message`. Emit a concise diagnostic; don't rely on grepping long
|
||||
output downstream.
|
||||
- **Env is inherited.** The command sees the full GSD process environment. Do
|
||||
- **Env is inherited.** The command sees the full MSD process environment. Do
|
||||
not put secrets in the command string; read them from env or a file like any
|
||||
shell script.
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ Choose the right model tier strategy for your project, then tune individual agen
|
||||
|
||||
## The four profiles (plus `adaptive` and `inherit`)
|
||||
|
||||
Set `model_profile` in `.planning/config.json` or via `/gsd-config --profile <name>`:
|
||||
Set `model_profile` in `.planning/config.json` or via `/msd-config --profile <name>`:
|
||||
|
||||
| Profile | Planner | Executor | Researchers | Verifier | Use when |
|
||||
|---------|---------|----------|-------------|----------|----------|
|
||||
@@ -16,15 +16,15 @@ Set `model_profile` in `.planning/config.json` or via `/gsd-config --profile <na
|
||||
| `adaptive` | Opus | Sonnet | Sonnet | Sonnet | Resolves the same way as the other tiers under runtime-aware profiles; use when switching between runtimes frequently |
|
||||
| `inherit` | (session model) | (session model) | (session model) | (session model) | Non-Anthropic providers (OpenRouter, local models) — all agents follow your current session model |
|
||||
|
||||
The table above shows a representative subset. All 33 shipped agents have explicit per-profile tier assignments in `gsd-core/bin/shared/model-catalog.json`. For the full table see [Model Profiles](../CONFIGURATION.md#model-profiles) in the configuration reference.
|
||||
The table above shows a representative subset. All 33 shipped agents have explicit per-profile tier assignments in `msd-core/bin/shared/model-catalog.json`. For the full table see [Model Profiles](../CONFIGURATION.md#model-profiles) in the configuration reference.
|
||||
|
||||
**Quick switch via command:**
|
||||
|
||||
```bash
|
||||
/gsd-config --profile balanced # Normal development
|
||||
/gsd-config --profile budget # Prototyping or high-cost phases
|
||||
/gsd-config --profile quality # Production release
|
||||
/gsd-config --profile inherit # OpenRouter, local models
|
||||
/msd-config --profile balanced # Normal development
|
||||
/msd-config --profile budget # Prototyping or high-cost phases
|
||||
/msd-config --profile quality # Production release
|
||||
/msd-config --profile inherit # OpenRouter, local models
|
||||
```
|
||||
|
||||
**Or edit `.planning/config.json` directly:**
|
||||
@@ -45,25 +45,25 @@ If a single agent needs a different tier without changing the whole profile, use
|
||||
{
|
||||
"model_profile": "balanced",
|
||||
"model_overrides": {
|
||||
"gsd-executor": "opus",
|
||||
"gsd-codebase-mapper": "haiku"
|
||||
"msd-executor": "opus",
|
||||
"msd-codebase-mapper": "haiku"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Valid values: `opus`, `sonnet`, `haiku`, `fable`, `inherit`, or any fully-qualified model ID (e.g. `"openai/o3"`, `"google/gemini-2.5-pro"`).
|
||||
|
||||
On the Claude runtime, fully-qualified Claude model IDs act as explicit generation pins (#4192): an ID naming the current tier default (e.g. `"claude-sonnet-5"`) resolves to its tier alias — the same model in the form Claude Code's Agent tool always accepts — while any other ID (e.g. `"claude-opus-4-7"`) resolves verbatim, with a warn-once stderr note that setups accepting only tier aliases will not honor a full ID. `fable` is a Claude Code Agent-tool alias, not a GSD profile tier: valid here, but it has no column in the profile table. To pin a generation for a whole tier instead of one agent, use `model_profile_overrides` (see below).
|
||||
On the Claude runtime, fully-qualified Claude model IDs act as explicit generation pins (#4192): an ID naming the current tier default (e.g. `"claude-sonnet-5"`) resolves to its tier alias — the same model in the form Claude Code's Agent tool always accepts — while any other ID (e.g. `"claude-opus-4-7"`) resolves verbatim, with a warn-once stderr note that setups accepting only tier aliases will not honor a full ID. `fable` is a Claude Code Agent-tool alias, not a MSD profile tier: valid here, but it has no column in the profile table. To pin a generation for a whole tier instead of one agent, use `model_profile_overrides` (see below).
|
||||
|
||||
`model_overrides` can be set per-project in `.planning/config.json` or globally in `~/.gsd/defaults.json`. Per-project entries win on conflict; non-conflicting global entries are preserved.
|
||||
`model_overrides` can be set per-project in `.planning/config.json` or globally in `~/.msd/defaults.json`. Per-project entries win on conflict; non-conflicting global entries are preserved.
|
||||
|
||||
**Important for Codex and OpenCode:** Those runtimes embed the model into each agent's static config at install time rather than choosing it per spawn, so after editing `model_overrides` you must re-run the installer for the change to take effect:
|
||||
|
||||
```bash
|
||||
npx @opengsd/gsd-core@latest --codex --global # or --opencode, --kilo, etc.
|
||||
npx @golem15/msd-core@latest --codex --global # or --opencode, --kilo, etc.
|
||||
```
|
||||
|
||||
GSD will also warn you if you forget: workflow entry commands (`gsd init plan-phase`, `gsd init execute-phase`, etc.) detect when `.planning/config.json` or `~/.gsd/defaults.json` is newer than your installed agent files and print a one-line stderr reminder naming the changed file and the re-install command. The check is read-only and runs only on `codex` and `opencode`; Claude Code resolves models at spawn time and is unaffected. (#1688)
|
||||
MSD will also warn you if you forget: workflow entry commands (`msd init plan-phase`, `msd init execute-phase`, etc.) detect when `.planning/config.json` or `~/.msd/defaults.json` is newer than your installed agent files and print a one-line stderr reminder naming the changed file and the re-install command. The check is read-only and runs only on `codex` and `opencode`; Claude Code resolves models at spawn time and is unaffected. (#1688)
|
||||
|
||||
---
|
||||
|
||||
@@ -89,11 +89,11 @@ Phase types and their agents:
|
||||
|
||||
| Phase type | Agents covered |
|
||||
|---|---|
|
||||
| `planning` | `gsd-planner`, `gsd-roadmapper`, `gsd-pattern-mapper` |
|
||||
| `research` | `gsd-phase-researcher`, `gsd-project-researcher`, `gsd-research-synthesizer`, `gsd-codebase-mapper`, `gsd-ui-researcher` |
|
||||
| `execution` | `gsd-executor`, `gsd-debugger`, `gsd-doc-writer` |
|
||||
| `verification` | `gsd-verifier`, `gsd-plan-checker`, `gsd-integration-checker`, `gsd-nyquist-auditor`, `gsd-ui-checker`, `gsd-ui-auditor`, `gsd-doc-verifier`, `gsd-code-reviewer` |
|
||||
| `discuss` | `gsd-assumptions-analyzer` |
|
||||
| `planning` | `msd-planner`, `msd-roadmapper`, `msd-pattern-mapper` |
|
||||
| `research` | `msd-phase-researcher`, `msd-project-researcher`, `msd-research-synthesizer`, `msd-codebase-mapper`, `msd-ui-researcher` |
|
||||
| `execution` | `msd-executor`, `msd-debugger`, `msd-doc-writer` |
|
||||
| `verification` | `msd-verifier`, `msd-plan-checker`, `msd-integration-checker`, `msd-nyquist-auditor`, `msd-ui-checker`, `msd-ui-auditor`, `msd-doc-verifier`, `msd-code-reviewer` |
|
||||
| `discuss` | `msd-assumptions-analyzer` |
|
||||
| `completion` | Reserved — no subagent today; accepted by schema for forward compatibility |
|
||||
|
||||
The `models` block accepts tier aliases only (`opus`, `sonnet`, `haiku`, `inherit`). For a fully-qualified model ID, use `model_overrides` per agent instead.
|
||||
@@ -107,12 +107,12 @@ The `models` block accepts tier aliases only (`opus`, `sonnet`, `haiku`, `inheri
|
||||
"research": "sonnet"
|
||||
},
|
||||
"model_overrides": {
|
||||
"gsd-codebase-mapper": "haiku"
|
||||
"msd-codebase-mapper": "haiku"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
All five research agents resolve to `sonnet` *except* `gsd-codebase-mapper`, which is pinned to `haiku`.
|
||||
All five research agents resolve to `sonnet` *except* `msd-codebase-mapper`, which is pinned to `haiku`.
|
||||
|
||||
---
|
||||
|
||||
@@ -135,7 +135,7 @@ If you want to pay for cheaper tiers by default and only escalate when an agent
|
||||
}
|
||||
```
|
||||
|
||||
Each agent has a default tier (`light`, `standard`, or `heavy`). On the first attempt, GSD picks `tier_models[default_tier]`. If the orchestrator detects a soft failure (verification inconclusive, plan-check flagged, etc.), it re-spawns the agent one tier up. `max_escalations` caps the total retries.
|
||||
Each agent has a default tier (`light`, `standard`, or `heavy`). On the first attempt, MSD picks `tier_models[default_tier]`. If the orchestrator detects a soft failure (verification inconclusive, plan-check flagged, etc.), it re-spawns the agent one tier up. `max_escalations` caps the total retries.
|
||||
|
||||
Agents that already sit at `heavy` cannot escalate further.
|
||||
|
||||
@@ -172,10 +172,10 @@ instead of stopping for a manual restart:
|
||||
}
|
||||
```
|
||||
|
||||
When an executor dies on a rate limit, GSD classifies the error body, switches to the next
|
||||
When an executor dies on a rate limit, MSD classifies the error body, switches to the next
|
||||
model in the list, logs the swap (`sonnet → gpt-5`), and waits out any `Retry-After` the
|
||||
provider sent. The walk is capped at `min(max_escalations, provider_escalation.length)`.
|
||||
Once the list is spent, GSD names every model it tried and hands you the normal recovery
|
||||
Once the list is spent, MSD names every model it tried and hands you the normal recovery
|
||||
prompt — it never silently retries the exhausted one.
|
||||
|
||||
This is most useful on providers without a guaranteed SLA (Nvidia NIM, OpenRouter, and
|
||||
@@ -185,13 +185,13 @@ quota / rate-limit failures; other failures keep the tier ladder. Leaving
|
||||
|
||||
---
|
||||
|
||||
## Using GSD on non-Anthropic runtimes
|
||||
## Using MSD on non-Anthropic runtimes
|
||||
|
||||
If you installed GSD for Codex, OpenCode, Antigravity CLI, or Kilo, the installer already set `resolve_model_ids: "omit"` in the shared config. This prevents unresolved Anthropic model IDs from leaking into those runtimes. Your install's recorded runtime identity (the `.gsd-runtime` marker) tells GSD which runtime tier map to resolve instead, so runtime-native profile resolution still supplies any model and effort that the runtime adapter can transport. No manual setup is needed for the basic case.
|
||||
If you installed MSD for Codex, OpenCode, Antigravity CLI, or Kilo, the installer already set `resolve_model_ids: "omit"` in the shared config. This prevents unresolved Anthropic model IDs from leaking into those runtimes. Your install's recorded runtime identity (the `.msd-runtime` marker) tells MSD which runtime tier map to resolve instead, so runtime-native profile resolution still supplies any model and effort that the runtime adapter can transport. No manual setup is needed for the basic case.
|
||||
|
||||
### Codex routes tiers at spawn time when supported
|
||||
|
||||
GSD deliberately writes no profile-resolved `model` line into
|
||||
MSD deliberately writes no profile-resolved `model` line into
|
||||
`~/.codex/agents/<agent>.toml` ([ADR-2313](../adr/2313-codex-passive-model-posture.md)).
|
||||
Instead, each Codex skill inspects the visible `spawn_agent` schema. When that schema advertises
|
||||
`model` and `reasoning_effort`, the skill passes the model and effort resolved from
|
||||
@@ -199,7 +199,7 @@ Instead, each Codex skill inspects the visible `spawn_agent` schema. When that s
|
||||
the skill omits that field and the child inherits the session or static agent configuration.
|
||||
|
||||
This keeps compatibility with older Codex schemas while allowing newer installations to route
|
||||
`gsd-planner`, `gsd-executor`, and other roles to their configured tiers. The fields are detected
|
||||
`msd-planner`, `msd-executor`, and other roles to their configured tiers. The fields are detected
|
||||
independently; support for typed `agent_type` dispatch does not imply support for either routing
|
||||
field.
|
||||
|
||||
@@ -209,8 +209,8 @@ field.
|
||||
{
|
||||
"runtime": "codex",
|
||||
"model_overrides": {
|
||||
"gsd-planner": "gpt-5.6-sol",
|
||||
"gsd-executor": "gpt-5.6-terra"
|
||||
"msd-planner": "gpt-5.6-sol",
|
||||
"msd-executor": "gpt-5.6-terra"
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -220,14 +220,14 @@ schemas that do not advertise inline `model` (see above).
|
||||
|
||||
Two rules apply to what you can put there:
|
||||
|
||||
- **It must be a real Codex model id.** A GSD tier alias (`opus`, `sonnet`, `haiku`, `fable`) or a
|
||||
- **It must be a real Codex model id.** A MSD tier alias (`opus`, `sonnet`, `haiku`, `fable`) or a
|
||||
`claude-*` id is dropped with a warning rather than written, because Codex rejects them.
|
||||
- **Your account must actually expose it.** GSD cannot check this — if you pin `gpt-5.6-sol` on an
|
||||
- **Your account must actually expose it.** MSD cannot check this — if you pin `gpt-5.6-sol` on an
|
||||
account that does not have it, you get the same 400. When in doubt, omit the pin and let the
|
||||
session model apply.
|
||||
|
||||
`model_reasoning_effort` follows the model: with no pin, GSD writes no effort line either, so the
|
||||
Codex UI drives both rather than one following GSD and the other following your session.
|
||||
`model_reasoning_effort` follows the model: with no pin, MSD writes no effort line either, so the
|
||||
Codex UI drives both rather than one following MSD and the other following your session.
|
||||
|
||||
> **Upgrading from v1.10 or earlier?** Codex installs used to embed a per-tier model
|
||||
> (`opus→gpt-5.6-sol`, `sonnet→gpt-5.6-terra`, `haiku→gpt-5.6-luna`). If you were on an API-key
|
||||
@@ -237,14 +237,14 @@ Codex UI drives both rather than one following GSD and the other following your
|
||||
|
||||
### Allocating for execution-heavy workflows on Codex
|
||||
|
||||
Execution and verification account for most of the model calls in a long GSD run — planning happens
|
||||
Execution and verification account for most of the model calls in a long MSD run — planning happens
|
||||
once per phase, execution happens per plan, and verification runs over everything produced. On
|
||||
2026-07-30 OpenAI cut GPT-5.6 Luna API pricing by 80% and Terra by 20%, and reduced how many credits
|
||||
both consume against Codex paid-plan quotas while leaving subscription prices and quota budgets
|
||||
unchanged. Sol was unchanged. That makes the cheaper models materially cheaper for exactly the
|
||||
high-volume half of a workflow.
|
||||
|
||||
GSD does not add a routing surface for this — the levers below already express it, and
|
||||
MSD does not add a routing surface for this — the levers below already express it, and
|
||||
[#2935](https://github.com/open-gsd/gsd-core/issues/2935) was closed as already-implemented on
|
||||
precisely that basis. Keep Sol where the reasoning is worth the spend, and put the volume on Terra
|
||||
or Luna:
|
||||
@@ -253,10 +253,10 @@ or Luna:
|
||||
{
|
||||
"runtime": "codex",
|
||||
"model_overrides": {
|
||||
"gsd-planner": "gpt-5.6-sol",
|
||||
"gsd-debugger": "gpt-5.6-sol",
|
||||
"gsd-executor": "gpt-5.6-terra",
|
||||
"gsd-verifier": "gpt-5.6-luna"
|
||||
"msd-planner": "gpt-5.6-sol",
|
||||
"msd-debugger": "gpt-5.6-sol",
|
||||
"msd-executor": "gpt-5.6-terra",
|
||||
"msd-verifier": "gpt-5.6-luna"
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -286,9 +286,9 @@ Two things worth knowing before you tune this:
|
||||
{
|
||||
"resolve_model_ids": "omit",
|
||||
"model_overrides": {
|
||||
"gsd-planner": "o3",
|
||||
"gsd-executor": "o4-mini",
|
||||
"gsd-debugger": "o3"
|
||||
"msd-planner": "o3",
|
||||
"msd-executor": "o4-mini",
|
||||
"msd-debugger": "o3"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
# How to connect a host to the GSD companion MCP server
|
||||
# How to connect a host to the MSD companion MCP server
|
||||
|
||||
This guide shows you how to make a MCP-capable host (Claude Code, Codex,
|
||||
OpenCode, VS Code, Antigravity CLI, Cursor, Cline, Hermes, Augment Code) drive
|
||||
GSD — run GSD
|
||||
MSD — run MSD
|
||||
commands and read/write `.planning/` state — through the companion MCP server,
|
||||
with no bespoke plugin.
|
||||
|
||||
Once connected, three tools appear in the host alongside its others:
|
||||
`gsd_invoke_command`, `gsd_read_state`, `gsd_write_state`. The server also
|
||||
serves a read-only **catalog** of GSD's own content — workflows and
|
||||
references as MCP resources, and the `/gsd-*` commands as MCP prompts — so a
|
||||
`msd_invoke_command`, `msd_read_state`, `msd_write_state`. The server also
|
||||
serves a read-only **catalog** of MSD's own content — workflows and
|
||||
references as MCP resources, and the `/msd-*` commands as MCP prompts — so a
|
||||
host can browse and pull that content directly instead of shelling out to the
|
||||
CLI. (For the tool contracts, see the reference section below; for *why* this
|
||||
server exists and its trust model, see
|
||||
[ADR-1239](../adr/1239-gsd-embeddable-orchestration-engine.md) and the
|
||||
[ADR-1239](../adr/1239-msd-embeddable-orchestration-engine.md) and the
|
||||
[capability trust model](../explanation/capability-trust-model.md).)
|
||||
|
||||
## 1. Add the server to your host's MCP config
|
||||
@@ -23,9 +23,9 @@ host.
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"gsd": {
|
||||
"msd": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "@opengsd/gsd-core", "gsd-mcp-server"],
|
||||
"args": ["-y", "@golem15/msd-core", "msd-mcp-server"],
|
||||
"cwd": "/abs/path/to/your/project"
|
||||
}
|
||||
}
|
||||
@@ -36,14 +36,14 @@ host.
|
||||
- **Augment Code** — under the `mcpServers` block of its own
|
||||
`settings.json` (not a standalone MCP config file, unlike Antigravity)
|
||||
— global at `~/.augment/settings.json`, project-local at
|
||||
`.augment/settings.json`. GSD's installer configures this entry
|
||||
`.augment/settings.json`. MSD's installer configures this entry
|
||||
automatically (`--augment` installs).
|
||||
- **VS Code** — in the workspace MCP servers list.
|
||||
- **Antigravity** — under the `mcpServers` block of its standalone
|
||||
`mcp_config.json` profile (not embedded in `settings.json`) — global at
|
||||
`~/.gemini/antigravity/mcp_config.json` (or the sibling
|
||||
`antigravity-ide`/`antigravity-cli` dir GSD resolved into), project-local at
|
||||
`.agents/mcp_config.json`. GSD's installer configures this entry
|
||||
`antigravity-ide`/`antigravity-cli` dir MSD resolved into), project-local at
|
||||
`.agents/mcp_config.json`. MSD's installer configures this entry
|
||||
automatically (`--antigravity` installs).
|
||||
- **OpenCode** — under the `mcp` key (**not** `mcpServers`), in
|
||||
`~/.config/opencode/opencode.jsonc` (global) or `./opencode.json`
|
||||
@@ -52,7 +52,7 @@ host.
|
||||
`mcpServers`), in `~/.config/kilo/opencode.jsonc` (global) or
|
||||
`./opencode.json` (project). Same entry shape as OpenCode.
|
||||
|
||||
Set `cwd` to the project whose `.planning/` you want GSD to manage — the server
|
||||
Set `cwd` to the project whose `.planning/` you want MSD to manage — the server
|
||||
resolves state paths against it.
|
||||
|
||||
### OpenCode / Kilo entry shape
|
||||
@@ -64,9 +64,9 @@ OpenCode (and Kilo, which shares OpenCode's config schema) use a
|
||||
```jsonc
|
||||
{
|
||||
"mcp": {
|
||||
"gsd": {
|
||||
"msd": {
|
||||
"type": "local",
|
||||
"command": ["npx", "-y", "@opengsd/gsd-core", "gsd-mcp-server"],
|
||||
"command": ["npx", "-y", "@golem15/msd-core", "msd-mcp-server"],
|
||||
"timeout": 10000
|
||||
}
|
||||
}
|
||||
@@ -76,7 +76,7 @@ OpenCode (and Kilo, which shares OpenCode's config schema) use a
|
||||
## 2. Restart the host
|
||||
|
||||
On startup the host performs the MCP `initialize` handshake. The response
|
||||
advertises `tools`, `resources`, and `prompts` capabilities, so the three GSD
|
||||
advertises `tools`, `resources`, and `prompts` capabilities, so the three MSD
|
||||
tools become callable and the host can also list the served catalog
|
||||
(resources and prompts) described below. The server never advertises
|
||||
`resources.subscribe` or `listChanged` — the catalog is fixed for the life of
|
||||
@@ -87,17 +87,17 @@ the server process, so there is nothing to subscribe to.
|
||||
Ask the host to read an existing planning file:
|
||||
|
||||
```jsonc
|
||||
{ "name": "gsd_read_state", "arguments": { "path": "/abs/path/to/your/project/.planning/STATE.md" } }
|
||||
{ "name": "msd_read_state", "arguments": { "path": "/abs/path/to/your/project/.planning/STATE.md" } }
|
||||
```
|
||||
|
||||
It returns the file's contents. `gsd_invoke_command` takes
|
||||
It returns the file's contents. `msd_invoke_command` takes
|
||||
`{family, subcommand, args}` and returns the command-routing hub's structured
|
||||
result (the same shape `gsd-tools` produces).
|
||||
result (the same shape `msd-tools` produces).
|
||||
|
||||
## 4. Browse the catalog (resources and prompts)
|
||||
|
||||
The server also exposes GSD's own content tree as MCP resources and the
|
||||
`commands/gsd/*.md` command set as MCP prompts. This is additive: the
|
||||
The server also exposes MSD's own content tree as MCP resources and the
|
||||
`commands/msd/*.md` command set as MCP prompts. This is additive: the
|
||||
file-copy install (the default for every runtime) is unchanged, and the
|
||||
catalog only adds a way for an MCP-capable host to read the same content
|
||||
directly over the protocol.
|
||||
@@ -111,16 +111,16 @@ until it is absent):
|
||||
{ "name": "resources/list", "arguments": { "cursor": null } }
|
||||
```
|
||||
|
||||
Each entry has a `gsd://<segment>/<relpath>` URI, where `<segment>` is
|
||||
Each entry has a `msd://<segment>/<relpath>` URI, where `<segment>` is
|
||||
`workflows`, `references`, or `commands`, and `<relpath>` is the file's path
|
||||
within that segment (for example, `gsd://workflows/plan-phase.md`,
|
||||
`gsd://references/untrusted-input-boundary.md`, or
|
||||
`gsd://commands/plan-phase.md`). Commands appear in both surfaces: read one as
|
||||
within that segment (for example, `msd://workflows/plan-phase.md`,
|
||||
`msd://references/untrusted-input-boundary.md`, or
|
||||
`msd://commands/plan-phase.md`). Commands appear in both surfaces: read one as
|
||||
a resource to get its raw markdown, or get it as a prompt to have the host
|
||||
treat it as an invocable message. Read one by URI:
|
||||
|
||||
```jsonc
|
||||
{ "name": "resources/read", "arguments": { "uri": "gsd://workflows/plan-phase.md" } }
|
||||
{ "name": "resources/read", "arguments": { "uri": "msd://workflows/plan-phase.md" } }
|
||||
```
|
||||
|
||||
An unknown or unrecognized URI (including any path-traversal or absolute-path
|
||||
@@ -145,31 +145,31 @@ injected arguments today.
|
||||
|
||||
### Composed vs. verbatim content
|
||||
|
||||
Workflow resources (`gsd://workflows/…`) are served **composed** — with
|
||||
`<!-- gsd:section -->` markers stripped — exactly as the installed file tree
|
||||
Workflow resources (`msd://workflows/…`) are served **composed** — with
|
||||
`<!-- msd:section -->` markers stripped — exactly as the installed file tree
|
||||
gets them, while reference and command content is served **verbatim**, because
|
||||
some reference and command docs use that marker syntax as a documented example
|
||||
rather than a real marker.
|
||||
|
||||
## If something does not work
|
||||
|
||||
- **`command not found: gsd-mcp-server`** — invoke via `npx` as shown above, or
|
||||
install the package globally first (`npm i -g @opengsd/gsd-core`).
|
||||
- **`gsd_read_state` fails with ENOENT** — the path is resolved literally; pass
|
||||
- **`command not found: msd-mcp-server`** — invoke via `npx` as shown above, or
|
||||
install the package globally first (`npm i -g @golem15/msd-core`).
|
||||
- **`msd_read_state` fails with ENOENT** — the path is resolved literally; pass
|
||||
an absolute path under the project's `.planning/`.
|
||||
- **The host lists no GSD tools** — confirm the server starts in isolation:
|
||||
`npx @opengsd/gsd-core gsd-mcp-server` then send an `initialize` request on
|
||||
- **The host lists no MSD tools** — confirm the server starts in isolation:
|
||||
`npx @golem15/msd-core msd-mcp-server` then send an `initialize` request on
|
||||
stdin; it writes a `protocolVersion` response and exits on EOF.
|
||||
- **You manage multiple projects** — register one `gsd` entry per project with a
|
||||
- **You manage multiple projects** — register one `msd` entry per project with a
|
||||
distinct name and `cwd`; the server is stateless across projects.
|
||||
|
||||
## Reference — the three tools
|
||||
|
||||
| Tool | Arguments | Returns |
|
||||
|------|-----------|---------|
|
||||
| `gsd_invoke_command` | `{family: string, subcommand: string, args?: unknown[]}` | the command-routing hub result (`{ok, …}`) as JSON text |
|
||||
| `gsd_read_state` | `{path: string}` | the file contents as text |
|
||||
| `gsd_write_state` | `{path: string, content: string}` | `{ok: true, path}` as JSON text |
|
||||
| `msd_invoke_command` | `{family: string, subcommand: string, args?: unknown[]}` | the command-routing hub result (`{ok, …}`) as JSON text |
|
||||
| `msd_read_state` | `{path: string}` | the file contents as text |
|
||||
| `msd_write_state` | `{path: string, content: string}` | `{ok: true, path}` as JSON text |
|
||||
|
||||
Errors from a tool are returned as MCP tool errors (`isError: true`), not as
|
||||
JSON-RPC protocol errors — the host surfaces them in its normal tool-failure UX.
|
||||
@@ -1,6 +1,6 @@
|
||||
# Consume the planning snapshot
|
||||
|
||||
You are building something that needs to know where a GSD project stands —
|
||||
You are building something that needs to know where a MSD project stands —
|
||||
a dashboard, a status page, a harness UI, a bot that comments on a pull request.
|
||||
`planning inspect` gives you that as one JSON document, so you never have to
|
||||
parse `ROADMAP.md`, `REQUIREMENTS.md`, `*-PLAN.md`, or `*-SUMMARY.md` yourself.
|
||||
@@ -11,30 +11,30 @@ apart from **"could not look."**
|
||||
|
||||
## Before you start
|
||||
|
||||
You need `gsd-tools` on the machine, and a project directory containing
|
||||
You need `msd-tools` on the machine, and a project directory containing
|
||||
`.planning/`. Nothing has to be enabled or configured — the command is read-only
|
||||
and always available.
|
||||
|
||||
## 1. Get a snapshot
|
||||
|
||||
```bash
|
||||
gsd-tools query planning inspect
|
||||
msd-tools query planning inspect
|
||||
```
|
||||
|
||||
The dotted form is identical, if that reads better in your code:
|
||||
|
||||
```bash
|
||||
gsd-tools query planning.inspect
|
||||
msd-tools query planning.inspect
|
||||
```
|
||||
|
||||
The command takes no arguments. If you pass one, it fails loudly rather than
|
||||
ignoring it — see [Troubleshooting](#troubleshooting).
|
||||
|
||||
To inspect a project other than your current directory, use the global `--cwd`
|
||||
flag, which every `gsd-tools` command accepts:
|
||||
flag, which every `msd-tools` command accepts:
|
||||
|
||||
```bash
|
||||
gsd-tools query planning inspect --cwd /path/to/project
|
||||
msd-tools query planning inspect --cwd /path/to/project
|
||||
```
|
||||
|
||||
## 2. Check the schema version first
|
||||
@@ -167,9 +167,9 @@ An empty `diagnostics[]` means every value in the snapshot is a real answer.
|
||||
|
||||
## 8. Handle a large payload
|
||||
|
||||
On a big project the JSON can exceed the ~50 KB console limit. `gsd-tools`
|
||||
On a big project the JSON can exceed the ~50 KB console limit. `msd-tools`
|
||||
handles this for you: it writes to a temp file and resolves the reference before
|
||||
writing to stdout, so you always receive JSON. If you are invoking `gsd-tools`
|
||||
writing to stdout, so you always receive JSON. If you are invoking `msd-tools`
|
||||
through a shell wrapper that captures stdout directly, no special handling is
|
||||
needed.
|
||||
|
||||
@@ -184,7 +184,7 @@ ignoring them — silently returning an unscoped snapshot to a caller who asked
|
||||
for a scoped one would be worse. Filter the `phases[]` array on your side.
|
||||
|
||||
**Everything is `unknown` and `diagnostics[0].code` is `planning_root_absent`**
|
||||
You are not in a GSD project directory. Use `--cwd`, or `cd` first.
|
||||
You are not in a MSD project directory. Use `--cwd`, or `cd` first.
|
||||
|
||||
**A phase you expect is missing from `phases[]`**
|
||||
Check `orphan_phase_dirs[]`. `phases[]` is scoped to the phases the current
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Consume the state contract
|
||||
|
||||
You are building something that shows where a GSD project stands — a workbench,
|
||||
You are building something that shows where a MSD project stands — a workbench,
|
||||
a dashboard, a status bar, an editor extension. `.planning/state.json` gives you
|
||||
that as one small JSON file that GSD refreshes on its own, so you never have to
|
||||
that as one small JSON file that MSD refreshes on its own, so you never have to
|
||||
parse `STATE.md` or `ROADMAP.md` heuristically.
|
||||
|
||||
This guide covers the whole path from *nothing* to *reading a value you can
|
||||
@@ -13,7 +13,7 @@ from "I could not look."**
|
||||
## Before you start
|
||||
|
||||
Nothing. There is no command to run, no config key to set, and no flag to pass.
|
||||
GSD writes the file itself at every step boundary — beginning or completing a
|
||||
MSD writes the file itself at every step boundary — beginning or completing a
|
||||
phase, advancing a plan, adding, inserting, removing or completing a phase, and
|
||||
switching or completing a milestone.
|
||||
|
||||
@@ -22,7 +22,7 @@ Two consequences worth internalizing before you write any code:
|
||||
- **The file may legitimately not exist yet.** A project that has not reached a
|
||||
step boundary since it was created has never published one. That is normal, not
|
||||
an error.
|
||||
- **You are a reader, never a writer.** GSD owns this file and overwrites it
|
||||
- **You are a reader, never a writer.** MSD owns this file and overwrites it
|
||||
wholesale. Anything you write into it is lost at the next boundary.
|
||||
|
||||
## 1. Find the file
|
||||
@@ -60,7 +60,7 @@ Best-effort-parsing a shape you were not written against is how an integration
|
||||
starts silently reporting wrong numbers after an upgrade. A hard failure is the
|
||||
kinder outcome.
|
||||
|
||||
`flavor` is `"core"` and tells you which GSD edition produced the file.
|
||||
`flavor` is `"core"` and tells you which MSD edition produced the file.
|
||||
|
||||
## 3. Read the values
|
||||
|
||||
@@ -70,10 +70,10 @@ never omitted, so `"milestone" in snapshot` is not a meaningful test.
|
||||
| Key | Type | Meaning |
|
||||
|---|---|---|
|
||||
| `contract` | string | Semver of this schema. Check it first. |
|
||||
| `flavor` | string | The GSD edition. `"core"`. |
|
||||
| `flavor` | string | The MSD edition. `"core"`. |
|
||||
| `milestone` | string \| null | Display string for the current milestone, e.g. `"v1.1 — Hardening"`, or just `"v1.1"` when the roadmap carries no name for it. `null` when no milestone is established. |
|
||||
| `phases` | array | Every phase the roadmap knows, in roadmap order. |
|
||||
| `next` | object \| null | The recommended next action — the same one `/gsd-next` would offer. |
|
||||
| `next` | object \| null | The recommended next action — the same one `/msd-next` would offer. |
|
||||
| `updated_at` | string | ISO-8601 timestamp of this publish. |
|
||||
|
||||
Each entry in `phases` has exactly three keys:
|
||||
@@ -88,7 +88,7 @@ Each entry in `phases` has exactly three keys:
|
||||
|
||||
| Key | Type | Meaning |
|
||||
|---|---|---|
|
||||
| `command` | string | The command to run, e.g. `"/gsd-progress --next"`. |
|
||||
| `command` | string | The command to run, e.g. `"/msd-progress --next"`. |
|
||||
| `label` | string | A short human label for it, e.g. `"Advance to the next step"`. |
|
||||
| `reason` | string | One line explaining the current situation, e.g. `"Phase 2 of 3 · 50% · executing"`. |
|
||||
|
||||
@@ -105,7 +105,7 @@ A complete example:
|
||||
{ "number": "3", "name": "Polish", "status": "pending" }
|
||||
],
|
||||
"next": {
|
||||
"command": "/gsd-progress --next",
|
||||
"command": "/msd-progress --next",
|
||||
"label": "Advance to the next step",
|
||||
"reason": "Phase 2 of 3 · 50% · executing"
|
||||
},
|
||||
@@ -115,7 +115,7 @@ A complete example:
|
||||
|
||||
### Treat `status` as a closed set
|
||||
|
||||
The three values above are the whole vocabulary, and GSD will never emit a
|
||||
The three values above are the whole vocabulary, and MSD will never emit a
|
||||
fourth under `1.x`. Write your switch with a default arm anyway — a `2.0`
|
||||
contract could widen it, and your version check should be what rejects that, not
|
||||
a crash three layers down.
|
||||
@@ -130,7 +130,7 @@ to distinguish deferred work, read the roadmap.
|
||||
`name`, `milestone` and `reason` come from a project's own markdown. They can
|
||||
contain anything a person typed — quotes, newlines, right-to-left text, markup,
|
||||
or text that looks like an instruction. **Escape them for your output surface and
|
||||
never interpret them as commands.** GSD passes them through verbatim as data; it
|
||||
never interpret them as commands.** MSD passes them through verbatim as data; it
|
||||
does not sanitize them for you.
|
||||
|
||||
## 4. Tell "nothing to show" from "could not look"
|
||||
@@ -140,7 +140,7 @@ not plan for them.
|
||||
|
||||
| What you observe | What it means | What to do |
|
||||
|---|---|---|
|
||||
| File does not exist | The project has never reached a step boundary, or it is not a GSD project at all | Fall back to reading the markdown, or show "not started". **Do not** report an error |
|
||||
| File does not exist | The project has never reached a step boundary, or it is not a MSD project at all | Fall back to reading the markdown, or show "not started". **Do not** report an error |
|
||||
| File exists, `phases: []` | **Ambiguous.** Either the roadmap has no phases, or there is no `ROADMAP.md`, or the roadmap could not be read | Show "no phases yet" — do not claim the project has zero phases. See below |
|
||||
| File exists, `next: null` | The recommended action could not be determined | Show the project state without a call to action |
|
||||
| File exists, `milestone: null` | No milestone is established | Show phases without a milestone header |
|
||||
@@ -156,7 +156,7 @@ The rule of thumb: `state.json` is for *"show me where this project is"*;
|
||||
|
||||
## 5. Stay fresh
|
||||
|
||||
The file changes only when GSD reaches a step boundary, so polling it hard buys
|
||||
The file changes only when MSD reaches a step boundary, so polling it hard buys
|
||||
you nothing. Watch it instead — `fs.watch`, `chokidar`, or your editor's own file
|
||||
watcher — and re-read on change. Debounce briefly: a single boundary command
|
||||
produces one write, but a workflow may cross several boundaries in quick
|
||||
@@ -165,27 +165,27 @@ succession.
|
||||
## Troubleshooting
|
||||
|
||||
**The file never appears.** Confirm `.planning/` exists in the directory you are
|
||||
watching. GSD deliberately does **not** create `.planning/` in order to publish —
|
||||
a directory that is not a GSD project stays untouched. Then run any boundary
|
||||
command (`gsd-tools phase complete 1`, say) and check again.
|
||||
watching. MSD deliberately does **not** create `.planning/` in order to publish —
|
||||
a directory that is not a MSD project stays untouched. Then run any boundary
|
||||
command (`msd-tools phase complete 1`, say) and check again.
|
||||
|
||||
**The file appears somewhere I did not expect.** You are probably in a workstream
|
||||
project; see the path in step 1. `GSD_WORKSTREAM` selects which planning root is
|
||||
project; see the path in step 1. `MSD_WORKSTREAM` selects which planning root is
|
||||
current.
|
||||
|
||||
**A phase I can see in `ROADMAP.md` is missing from `phases`.** Phases numbered
|
||||
`0.x` and `999.x` are sentinels — backlog and icebox — and are excluded by
|
||||
design, consistently with every other GSD surface. A row whose `Phase` cell does
|
||||
design, consistently with every other MSD surface. A row whose `Phase` cell does
|
||||
not begin with a digit is also skipped.
|
||||
|
||||
**`phases` disagrees with what the roadmap shows.** It should not: phase status
|
||||
is read from the roadmap's `## Progress` table, the same source GSD's own
|
||||
is read from the roadmap's `## Progress` table, the same source MSD's own
|
||||
progress counters use. If the roadmap has no `## Progress` table, the `## Phases`
|
||||
checkbox list is used instead, and a checkbox can only say complete or not — the
|
||||
in-progress phase is identified from `STATE.md`. Regenerating the progress table
|
||||
resolves most disagreements.
|
||||
|
||||
**Should I commit `state.json`?** Your call. GSD does not add it to
|
||||
**Should I commit `state.json`?** Your call. MSD does not add it to
|
||||
`.gitignore`. It is a derived cache — safe to delete, regenerated at the next
|
||||
boundary — so committing it mostly creates merge noise. If you keep `.planning/`
|
||||
out of your repo entirely, see
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
# How to control which host runtime GSD reports
|
||||
# How to control which host runtime MSD reports
|
||||
|
||||
**Goal:** Make `agent_runtime` — the runtime GSD reports it is running under, and the one it checks for installed agents — say what you actually want, and know *why* it says what it says.
|
||||
**Goal:** Make `agent_runtime` — the runtime MSD reports it is running under, and the one it checks for installed agents — say what you actually want, and know *why* it says what it says.
|
||||
|
||||
**Prerequisites:** A project with a `.planning/` directory. Read the current answer with:
|
||||
|
||||
```bash
|
||||
node gsd-tools.cjs init plan-phase 1 --raw
|
||||
node msd-tools.cjs init plan-phase 1 --raw
|
||||
```
|
||||
|
||||
The JSON carries `agent_runtime`, plus the `agents_dir` / `agents_installed` / `missing_agents` triple derived from it. For the config key itself, see [`runtime`](../CONFIGURATION.md#runtime-aware-profiles-2517).
|
||||
@@ -14,16 +14,16 @@ The JSON carries `agent_runtime`, plus the `agents_dir` / `agents_installed` / `
|
||||
|
||||
## The ladder, in order
|
||||
|
||||
GSD answers "which runtime am I?" from the first of these that produces a value:
|
||||
MSD answers "which runtime am I?" from the first of these that produces a value:
|
||||
|
||||
| # | Source | Set it by | Wins over |
|
||||
|---|---|---|---|
|
||||
| 1 | `GSD_RUNTIME` environment variable | `GSD_RUNTIME=opencode` in the environment | everything below |
|
||||
| 1 | `MSD_RUNTIME` environment variable | `MSD_RUNTIME=opencode` in the environment | everything below |
|
||||
| 2 | `runtime` in `.planning/config.json` | `"runtime": "codex"` | detection and the default |
|
||||
| 3 | **Host detection** (added in v1.11) | nothing — it is automatic | the default only |
|
||||
| 4 | Default | — | — (`claude`) |
|
||||
|
||||
Rungs 1 and 2 are *explicit* — you stated an intent, and GSD does not second-guess it. Rung 3 only ever runs when **both** are unset. This is what preserves the behavior of every existing config: if you have ever set `runtime`, nothing about your setup changes.
|
||||
Rungs 1 and 2 are *explicit* — you stated an intent, and MSD does not second-guess it. Rung 3 only ever runs when **both** are unset. This is what preserves the behavior of every existing config: if you have ever set `runtime`, nothing about your setup changes.
|
||||
|
||||
---
|
||||
|
||||
@@ -33,7 +33,7 @@ Detection answers a narrow question — *is this process running inside a Codex
|
||||
|
||||
| Signal | Where it comes from | Why it is trusted |
|
||||
|---|---|---|
|
||||
| `CODEX_SANDBOX` is set and non-empty | Codex injects it into child processes it spawns via Seatbelt | Documented in Codex's own `AGENTS.md`; present in exactly the processes Codex runs, which is where GSD runs |
|
||||
| `CODEX_SANDBOX` is set and non-empty | Codex injects it into child processes it spawns via Seatbelt | Documented in Codex's own `AGENTS.md`; present in exactly the processes Codex runs, which is where MSD runs |
|
||||
| `CODEX_SANDBOX_NETWORK_DISABLED` is set and non-empty | Codex injects it when running the shell tool with the network sandbox on | same source |
|
||||
| `CODEX_HOME` is set **and** `$CODEX_HOME/config.toml` exists | you exported it | Exporting `CODEX_HOME` is you designating a Codex state root; the `config.toml` check confirms the directory is a real one |
|
||||
|
||||
@@ -49,12 +49,12 @@ Work down the ladder:
|
||||
|
||||
| Check | What to do |
|
||||
|---|---|
|
||||
| Is `GSD_RUNTIME` set to something else? | `echo $GSD_RUNTIME` — it outranks everything. Unset it, or set it to `codex`. |
|
||||
| Is `MSD_RUNTIME` set to something else? | `echo $MSD_RUNTIME` — it outranks everything. Unset it, or set it to `codex`. |
|
||||
| Does `.planning/config.json` have a `runtime`? | An explicit `"runtime": "claude"` wins over detection, by design. Change it or remove the key. |
|
||||
| Is your Codex sandbox off? | With `sandbox_mode = "danger-full-access"`, Codex sets **neither** sandbox variable, so there is nothing for GSD to detect. This is the most common cause. |
|
||||
| Is your Codex sandbox off? | With `sandbox_mode = "danger-full-access"`, Codex sets **neither** sandbox variable, so there is nothing for MSD to detect. This is the most common cause. |
|
||||
| Still nothing? | Set it explicitly. Detection is a convenience, not a contract — `"runtime": "codex"` in `.planning/config.json` is the supported, permanent answer. |
|
||||
|
||||
Detection is deliberately conservative: when it cannot tell, it reports the old default rather than guessing. A wrong `agent_runtime` sends GSD looking for agents in the wrong directory, so silence is the safer failure.
|
||||
Detection is deliberately conservative: when it cannot tell, it reports the old default rather than guessing. A wrong `agent_runtime` sends MSD looking for agents in the wrong directory, so silence is the safer failure.
|
||||
|
||||
### "It says `codex` and I am not using Codex"
|
||||
|
||||
@@ -62,7 +62,7 @@ One cause, and it is benign:
|
||||
|
||||
> `CODEX_HOME` is exported in your shell profile, and `$CODEX_HOME/config.toml` exists.
|
||||
|
||||
GSD treats an explicitly-exported `CODEX_HOME` as you designating a Codex root. If you keep it exported globally but work in another runtime, pin the runtime for that project:
|
||||
MSD treats an explicitly-exported `CODEX_HOME` as you designating a Codex root. If you keep it exported globally but work in another runtime, pin the runtime for that project:
|
||||
|
||||
```json
|
||||
{ "runtime": "claude" }
|
||||
@@ -70,7 +70,7 @@ GSD treats an explicitly-exported `CODEX_HOME` as you designating a Codex root.
|
||||
|
||||
in `.planning/config.json`. Rung 2 outranks detection, so this settles it permanently.
|
||||
|
||||
Note what is **not** a cause: simply having Codex installed. GSD never probes the default `~/.codex/config.toml`. That file exists on every machine that has ever run Codex, so treating it as a signal would misreport every other runtime's sessions — which is precisely why the check requires you to have exported `CODEX_HOME` yourself.
|
||||
Note what is **not** a cause: simply having Codex installed. MSD never probes the default `~/.codex/config.toml`. That file exists on every machine that has ever run Codex, so treating it as a signal would misreport every other runtime's sessions — which is precisely why the check requires you to have exported `CODEX_HOME` yourself.
|
||||
|
||||
---
|
||||
|
||||
@@ -79,5 +79,5 @@ Note what is **not** a cause: simply having Codex installed. GSD never probes th
|
||||
Detection moves the **reported** runtime and the agent-installation check that hangs off it. It deliberately does not touch:
|
||||
|
||||
- **Model resolution.** Runtime-aware tier resolution still reads the explicit `runtime` config key only. A detected-Codex session does not gain or lose model pins — see [Runtime-aware profiles](../CONFIGURATION.md#runtime-aware-profiles-2517) and [ADR-2313](../adr/2313-codex-passive-model-posture.md).
|
||||
- **Slash-command style.** GSD still emits `/gsd-<cmd>` unless the runtime was set explicitly; a detected-Codex session does not switch to the `$gsd-<cmd>` shell-var form. Set `runtime` explicitly if you want that.
|
||||
- **Any file.** Detection reads environment variables and checks for one file's existence. It never writes `~/.gsd/defaults.json`, never edits `.planning/config.json`, and never shells out.
|
||||
- **Slash-command style.** MSD still emits `/msd-<cmd>` unless the runtime was set explicitly; a detected-Codex session does not switch to the `$msd-<cmd>` shell-var form. Set `runtime` explicitly if you want that.
|
||||
- **Any file.** Detection reads environment variables and checks for one file's existence. It never writes `~/.msd/defaults.json`, never edits `.planning/config.json`, and never shells out.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
**Goal:** Recover when a phase execution fails, stalls, or produces incomplete work — and resume cleanly without losing progress or repeating work that already succeeded.
|
||||
|
||||
**Prerequisites:** You have run `/gsd-execute-phase N` and the execution stopped before writing `VERIFICATION.md`, or you see unexpected output, missing files, or a stalled spinner.
|
||||
**Prerequisites:** You have run `/msd-execute-phase N` and the execution stopped before writing `VERIFICATION.md`, or you see unexpected output, missing files, or a stalled spinner.
|
||||
|
||||
---
|
||||
|
||||
@@ -12,15 +12,15 @@ Before taking any recovery action, determine what actually happened.
|
||||
|
||||
### If you see "Spawning…" with no output after 1–5 minutes
|
||||
|
||||
This is normal, not a freeze. GSD subagents run in an isolated context window. The liveness note on the spawn line confirms this. Do not interrupt the session.
|
||||
This is normal, not a freeze. MSD subagents run in an isolated context window. The liveness note on the spawn line confirms this. Do not interrupt the session.
|
||||
|
||||
If it has been more than 10 minutes with no result, check the Claude Code sidebar. If the agent task shows as completed but no output appeared, the result may have been lost in a context switch — re-run the same command:
|
||||
|
||||
```bash
|
||||
/gsd-execute-phase 1
|
||||
/msd-execute-phase 1
|
||||
```
|
||||
|
||||
GSD checks for `SUMMARY.md` files before dispatching executors. Plans that already have one are skipped automatically.
|
||||
MSD checks for `SUMMARY.md` files before dispatching executors. Plans that already have one are skipped automatically.
|
||||
|
||||
### If execution stopped mid-wave with an error message
|
||||
|
||||
@@ -34,7 +34,7 @@ Plans that committed their work will have an entry such as `feat(01-02): …`. P
|
||||
|
||||
### If the executor committed code but did not write SUMMARY.md
|
||||
|
||||
GSD detects this at the next run and surfaces a safe-resume gate with three options:
|
||||
MSD detects this at the next run and surfaces a safe-resume gate with three options:
|
||||
|
||||
- **Close out manually** — inspect the commits yourself, write `SUMMARY.md`, then re-run.
|
||||
- **Re-execute from scratch** — revert or supersede the partial commits before dispatching a new executor.
|
||||
@@ -43,11 +43,11 @@ GSD detects this at the next run and surfaces a safe-resume gate with three opti
|
||||
### If you see a "frontmatter opens with `---` but never closes" warning
|
||||
|
||||
```
|
||||
gsd: warning — /path/.planning/STATE.md: frontmatter opens with "---" but never closes; metadata was NOT applied. (#1879)
|
||||
msd: warning — /path/.planning/STATE.md: frontmatter opens with "---" but never closes; metadata was NOT applied. (#1879)
|
||||
```
|
||||
|
||||
The named file was written only partly — typically a crash, a full disk, or a killed process
|
||||
between the opening fence and the closing one. GSD read it as having **no** metadata and carried
|
||||
between the opening fence and the closing one. MSD read it as having **no** metadata and carried
|
||||
on, so any phase, plan, or state value that file was supposed to supply is missing from this run.
|
||||
|
||||
1. Open the named file and check whether its frontmatter block is closed by a `---` line of its
|
||||
@@ -60,7 +60,7 @@ on, so any phase, plan, or state value that file was supposed to supply is missi
|
||||
The warning cannot be turned off, and it never changes what a command returns or its exit code —
|
||||
it only tells you a file could not be used.
|
||||
|
||||
**A file can still be truncated without this warning.** GSD stays silent when the partial block
|
||||
**A file can still be truncated without this warning.** MSD stays silent when the partial block
|
||||
carries fewer than two fields, or when the text after the opening `---` reads as prose rather than
|
||||
frontmatter, because a Markdown document that opens with a horizontal rule is indistinguishable
|
||||
from one of those. If a run behaves as though metadata is missing and you see no warning, inspect
|
||||
@@ -70,12 +70,12 @@ the file anyway.
|
||||
|
||||
## Diagnose the root cause
|
||||
|
||||
### Run `/gsd-debug --diagnose`
|
||||
### Run `/msd-debug --diagnose`
|
||||
|
||||
If execution produced wrong output, stubbed code, or a verification failure, use the diagnosis-only mode to investigate without applying any fixes:
|
||||
|
||||
```bash
|
||||
/gsd-debug --diagnose "Phase 2 executor produced stubs instead of real code"
|
||||
/msd-debug --diagnose "Phase 2 executor produced stubs instead of real code"
|
||||
```
|
||||
|
||||
`--diagnose` stops at root cause without touching your files. It creates a session file at `.planning/debug/<slug>.md` so you can pick up the investigation later if needed.
|
||||
@@ -83,36 +83,36 @@ If execution produced wrong output, stubbed code, or a verification failure, use
|
||||
To start a full debug session that also applies a fix:
|
||||
|
||||
```bash
|
||||
/gsd-debug "Login middleware not handling 401 correctly after phase 3"
|
||||
/msd-debug "Login middleware not handling 401 correctly after phase 3"
|
||||
```
|
||||
|
||||
GSD gathers symptoms, runs a structured investigation using the scientific method, and proposes a fix. If `tdd_mode: true` is set in your config, it requires a failing test before applying any fix.
|
||||
MSD gathers symptoms, runs a structured investigation using the scientific method, and proposes a fix. If `tdd_mode: true` is set in your config, it requires a failing test before applying any fix.
|
||||
|
||||
### Check active debug sessions
|
||||
|
||||
```bash
|
||||
/gsd-debug list
|
||||
/msd-debug list
|
||||
```
|
||||
|
||||
Shows all open sessions with their current hypothesis and next action. To resume a specific session:
|
||||
|
||||
```bash
|
||||
/gsd-debug continue <slug>
|
||||
/msd-debug continue <slug>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Run a post-mortem with `/gsd-forensics`
|
||||
## Run a post-mortem with `/msd-forensics`
|
||||
|
||||
If the cause is not clear from the error output — for example, plans reference nonexistent files, execution produced unexpected results, or state seems corrupted — run a forensic investigation:
|
||||
|
||||
```bash
|
||||
/gsd-forensics "Phase 3 execution stalled after wave 1"
|
||||
/msd-forensics "Phase 3 execution stalled after wave 1"
|
||||
```
|
||||
|
||||
GSD analyses git history, `.planning/` artifact completeness, STATE.md consistency, uncommitted work, and orphaned worktrees. It writes a structured report to `.planning/forensics/report-<timestamp>.md` and surfaces recommended remediation steps.
|
||||
MSD analyses git history, `.planning/` artifact completeness, STATE.md consistency, uncommitted work, and orphaned worktrees. It writes a structured report to `.planning/forensics/report-<timestamp>.md` and surfaces recommended remediation steps.
|
||||
|
||||
`/gsd-forensics` is read-only — it never modifies your project files.
|
||||
`/msd-forensics` is read-only — it never modifies your project files.
|
||||
|
||||
**What it detects:**
|
||||
|
||||
@@ -129,46 +129,46 @@ GSD analyses git history, `.planning/` artifact completeness, STATE.md consisten
|
||||
Once the underlying issue is resolved, re-run the execute command:
|
||||
|
||||
```bash
|
||||
/gsd-execute-phase 1
|
||||
/msd-execute-phase 1
|
||||
```
|
||||
|
||||
GSD skips plans whose `SUMMARY.md` already exists and dispatches executors only for the remaining plans.
|
||||
MSD skips plans whose `SUMMARY.md` already exists and dispatches executors only for the remaining plans.
|
||||
|
||||
If you need to re-execute only a specific wave:
|
||||
|
||||
```bash
|
||||
/gsd-execute-phase 1 --wave 2
|
||||
/msd-execute-phase 1 --wave 2
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Roll back with `/gsd-undo`
|
||||
## Roll back with `/msd-undo`
|
||||
|
||||
If execution produced code you want to discard entirely, roll back using the plan manifest rather than manual `git revert`:
|
||||
|
||||
### Roll back a single plan
|
||||
|
||||
```bash
|
||||
/gsd-undo --plan 03-02
|
||||
/msd-undo --plan 03-02
|
||||
```
|
||||
|
||||
Reverts all commits for plan `02` of phase `3`. GSD shows a confirmation gate before writing any change.
|
||||
Reverts all commits for plan `02` of phase `3`. MSD shows a confirmation gate before writing any change.
|
||||
|
||||
### Roll back an entire phase
|
||||
|
||||
```bash
|
||||
/gsd-undo --phase 03
|
||||
/msd-undo --phase 03
|
||||
```
|
||||
|
||||
Reverts all commits for phase `3`. GSD checks whether any subsequent phases depend on this phase and warns you before proceeding.
|
||||
Reverts all commits for phase `3`. MSD checks whether any subsequent phases depend on this phase and warns you before proceeding.
|
||||
|
||||
### Pick interactively from recent commits
|
||||
|
||||
```bash
|
||||
/gsd-undo --last 5
|
||||
/msd-undo --last 5
|
||||
```
|
||||
|
||||
Shows the five most recent GSD commits and lets you select which to revert.
|
||||
Shows the five most recent MSD commits and lets you select which to revert.
|
||||
|
||||
---
|
||||
|
||||
@@ -177,7 +177,7 @@ Shows the five most recent GSD commits and lets you select which to revert.
|
||||
If you have returned to the project after a context reset or a new session:
|
||||
|
||||
```bash
|
||||
/gsd-resume-work
|
||||
/msd-resume-work
|
||||
```
|
||||
|
||||
Restores your full session context from the last handoff, including the current phase, blockers, and where execution stopped.
|
||||
@@ -185,7 +185,7 @@ Restores your full session context from the last handoff, including the current
|
||||
Alternatively, to see your current position and auto-advance to the correct next step:
|
||||
|
||||
```bash
|
||||
/gsd-progress --next
|
||||
/msd-progress --next
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Declare a hook's crash policy
|
||||
|
||||
A GSD enforcement hook (`hooks/*.js`, `hooks/*.sh`) ends every run by terminating
|
||||
A MSD enforcement hook (`hooks/*.js`, `hooks/*.sh`) ends every run by terminating
|
||||
the process — but "terminate" is not one decision, it is at least three: pass
|
||||
the tool call, block it, or explain what happens when the hook's *own* code
|
||||
breaks. Before ADR-3889 Phase 7 (#3911), each hook answered the third question
|
||||
@@ -58,7 +58,7 @@ block it?**
|
||||
- **`ALLOW`** — the hook is advisory, or its enforcement is not the last line
|
||||
of defense. A crash here should not stop legitimate work. This is every
|
||||
migrated hook's policy today (19 of 19) — including the two hard-blocking
|
||||
guards (`gsd-write-guard.js`, `gsd-worktree-path-guard.js`): their threat
|
||||
guards (`msd-write-guard.js`, `msd-worktree-path-guard.js`): their threat
|
||||
model is a confused agent overwriting a file it can already reach by other
|
||||
means, not a determined adversary, so a hook bug is not treated as worse
|
||||
than the thing it protects against.
|
||||
@@ -88,7 +88,7 @@ Write the trade-off, not the translation.
|
||||
## A deny needing a distinct stderr payload
|
||||
|
||||
Most callers never pass `stderrPayload` — fd 2 gets the same bytes as fd 1,
|
||||
unchanged from before this migration. One shape needs it: `gsd-write-guard.js`
|
||||
unchanged from before this migration. One shape needs it: `msd-write-guard.js`
|
||||
guards a curated `.planning/` artifact, but Kimi's native hook bus reads
|
||||
**stderr verbatim back to the model** on exit 2. A full JSON object on stderr
|
||||
would show the model a data structure instead of a sentence, so this call
|
||||
@@ -113,13 +113,13 @@ plain text on stderr — most hooks have no such reader and should leave
|
||||
decision. Two shipped hooks have a different contract, where the decision
|
||||
lives in the **JSON response body** and the process still exits 0:
|
||||
|
||||
- **`gsd-read-injection-scanner.js`** (PostToolUse) — Claude Code's
|
||||
- **`msd-read-injection-scanner.js`** (PostToolUse) — Claude Code's
|
||||
PostToolUse protocol reads `{ decision: "block", ... }` from stdout, not
|
||||
from the exit code; the tool call already completed by the time this hook
|
||||
runs, so there is no exit-code channel to block it through. It calls
|
||||
`process.stdout.write(JSON.stringify(output))` directly for its verdict,
|
||||
and uses `allow()`/`crash()` only for its true no-op and crash paths.
|
||||
- **`gsd-cursor-subagent-start.js`** (Cursor `subagentStart`) — Cursor's own
|
||||
- **`msd-cursor-subagent-start.js`** (Cursor `subagentStart`) — Cursor's own
|
||||
hook protocol reads `{ permission: "deny", user_message, ... }` from the
|
||||
JSON body at exit 0; `"ask"` is not even a supported value, and there is no
|
||||
exit-2 convention here at all. Same split: `process.stdout.write(...)` for
|
||||
@@ -135,7 +135,7 @@ block into an unexplained crash.
|
||||
`crash()` covers your hook's own bugs. It does not cover the more common
|
||||
defect: a check inside a *working* hook that silently reads "could not run"
|
||||
as if it were "ran, found nothing" — passing every case it should have
|
||||
inspected. #3838 is the worked example: `gsd-validate-commit.sh` had three
|
||||
inspected. #3838 is the worked example: `msd-validate-commit.sh` had three
|
||||
swallow-and-pass sites (the opt-in config read, JSON command extraction, and
|
||||
its `isGitSubcommand` classifier) where a failure and a genuine negative both
|
||||
fell through to the same `exit 0`, silently disabling commit validation on
|
||||
@@ -148,7 +148,7 @@ CONFIG_STATUS=${CONFIG_STATUS:-0}
|
||||
if [ "$CONFIG_STATUS" != "0" ]; then
|
||||
# Could not determine the opt-in flag at all — distinct from
|
||||
# ".planning/config.json exists and legitimately disables the hook".
|
||||
echo "gsd-validate-commit.sh: could not read .planning/config.json (opt-in check) — validator disabled for this call. $(cat "$ENABLED_ERR")" >&2
|
||||
echo "msd-validate-commit.sh: could not read .planning/config.json (opt-in check) — validator disabled for this call. $(cat "$ENABLED_ERR")" >&2
|
||||
rm -f "$ENABLED_ERR"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
**Goal:** Produce a locked UI design contract (`UI-SPEC.md`) that fixes spacing, color, typography, and copywriting decisions before the planner writes tasks, preventing visual inconsistency caused by ad-hoc styling choices during execution.
|
||||
|
||||
**Prerequisites:** `.planning/ROADMAP.md` exists. The phase must have frontend or UI work. Running `/gsd-discuss-phase N` first is strongly recommended — the UI researcher reads `CONTEXT.md` to avoid re-asking decisions you have already made.
|
||||
**Prerequisites:** `.planning/ROADMAP.md` exists. The phase must have frontend or UI work. Running `/msd-discuss-phase N` first is strongly recommended — the UI researcher reads `CONTEXT.md` to avoid re-asking decisions you have already made.
|
||||
|
||||
---
|
||||
|
||||
## Decide whether this phase needs a UI contract
|
||||
|
||||
Not all phases need `/gsd-ui-phase`. Use it when:
|
||||
Not all phases need `/msd-ui-phase`. Use it when:
|
||||
|
||||
- The phase introduces new UI surfaces (pages, flows, layouts)
|
||||
- Multiple components will be built and visual consistency matters
|
||||
@@ -20,22 +20,22 @@ Skip it when:
|
||||
- The phase is purely backend, infrastructure, or data work with no user-facing output
|
||||
- A UI-SPEC.md already exists for an earlier phase and this phase builds on identical visual patterns without introducing new surfaces
|
||||
|
||||
If you are unsure, the safety gate will prompt you: when `workflow.ui_safety_gate` is enabled (default), `/gsd-plan-phase` warns when it detects frontend work but no UI-SPEC.md and asks whether to run `/gsd-ui-phase` first.
|
||||
If you are unsure, the safety gate will prompt you: when `workflow.ui_safety_gate` is enabled (default), `/msd-plan-phase` warns when it detects frontend work but no UI-SPEC.md and asks whether to run `/msd-ui-phase` first.
|
||||
|
||||
---
|
||||
|
||||
## Run the UI design contract
|
||||
|
||||
```bash
|
||||
/gsd-ui-phase 2
|
||||
/msd-ui-phase 2
|
||||
```
|
||||
|
||||
If no phase number is given, GSD Core targets the current phase.
|
||||
If no phase number is given, MSD Core targets the current phase.
|
||||
|
||||
The command runs in two stages:
|
||||
|
||||
1. **`gsd-ui-researcher`** — reads `CONTEXT.md`, `RESEARCH.md`, and `REQUIREMENTS.md` for existing decisions, detects the design system state (shadcn `components.json`, Tailwind config, existing tokens), and asks only the unanswered design questions across five areas: spacing, color, typography, copywriting, and registry safety.
|
||||
2. **`gsd-ui-checker`** — validates the resulting `UI-SPEC.md` across seven dimensions. If issues are found, a revision loop reruns the researcher (up to two iterations) targeting only the flagged items.
|
||||
1. **`msd-ui-researcher`** — reads `CONTEXT.md`, `RESEARCH.md`, and `REQUIREMENTS.md` for existing decisions, detects the design system state (shadcn `components.json`, Tailwind config, existing tokens), and asks only the unanswered design questions across five areas: spacing, color, typography, copywriting, and registry safety.
|
||||
2. **`msd-ui-checker`** — validates the resulting `UI-SPEC.md` across seven dimensions. If issues are found, a revision loop reruns the researcher (up to two iterations) targeting only the flagged items.
|
||||
|
||||
**Output:** `{padded_phase}-UI-SPEC.md` in `.planning/phases/{phase-dir}/`.
|
||||
|
||||
@@ -54,7 +54,7 @@ The researcher locks decisions across five areas:
|
||||
| **Registry safety** | shadcn component inspection protocol (see below) |
|
||||
| **Component inventory** | What the design system actually provides, plus the command that enumerated it (see below) |
|
||||
|
||||
The checker validates the spec against its seven dimensions — Copywriting, Visuals, Color, Typography, Spacing, Registry Safety, and Inventory Provenance — returning PASS, FLAG or BLOCK for each. (The scored 1–4 six-pillar rubric belongs to `/gsd-ui-review`'s retroactive audit, not to this checker.)
|
||||
The checker validates the spec against its seven dimensions — Copywriting, Visuals, Color, Typography, Spacing, Registry Safety, and Inventory Provenance — returning PASS, FLAG or BLOCK for each. (The scored 1–4 six-pillar rubric belongs to `/msd-ui-review`'s retroactive audit, not to this checker.)
|
||||
|
||||
---
|
||||
|
||||
@@ -70,7 +70,7 @@ For React, Next.js, and Vite projects, the researcher offers to initialize shadc
|
||||
npx shadcn init --preset <paste>
|
||||
```
|
||||
|
||||
The preset string becomes a first-class GSD Core planning artifact that is reproducible across phases and milestones.
|
||||
The preset string becomes a first-class MSD Core planning artifact that is reproducible across phases and milestones.
|
||||
|
||||
---
|
||||
|
||||
@@ -83,7 +83,7 @@ npx shadcn view <component> # inspect source before installing
|
||||
npx shadcn diff <component> # compare against the official registry
|
||||
```
|
||||
|
||||
The checker will flag the spec as BLOCKED if registry safety is not addressed. Disable the gate via `/gsd-settings` if your project does not use shadcn or you have an alternative vetting process.
|
||||
The checker will flag the spec as BLOCKED if registry safety is not addressed. Disable the gate via `/msd-settings` if your project does not use shadcn or you have an alternative vetting process.
|
||||
|
||||
---
|
||||
|
||||
@@ -92,7 +92,7 @@ The checker will flag the spec as BLOCKED if registry safety is not addressed. D
|
||||
If your project has a design system, the UI-SPEC lists the components it provides — and the
|
||||
planner and executor read that list as the design surface they are allowed to build from. A list
|
||||
written from the model's recall looks identical to one enumerated from the installed package, so
|
||||
`gsd-ui-checker` Dimension 7 requires the spec to say which it was.
|
||||
`msd-ui-checker` Dimension 7 requires the spec to say which it was.
|
||||
|
||||
The section carries one provenance line, directly above its table:
|
||||
|
||||
@@ -132,7 +132,7 @@ Could not enumerate: package ships no exports map and no CLI.
|
||||
| Command and count, no version or date | **FLAG** | Accepted, but staleness is invisible. Add the missing part. |
|
||||
| A complete line, but below the table instead of above it | **FLAG** | Accepted. Move it up — a caveat has to be read before the list it qualifies. |
|
||||
| `Could not enumerate: <reason>` | **FLAG** | Honest and accepted. The list is explicitly non-exhaustive. |
|
||||
| An inventory with no provenance line | **BLOCK** | Enumerate and re-run `/gsd-ui-phase`. |
|
||||
| An inventory with no provenance line | **BLOCK** | Enumerate and re-run `/msd-ui-phase`. |
|
||||
| A count with no command, or a bare `Could not enumerate:` | **BLOCK** | Nothing falsifiable was recorded. |
|
||||
| No inventory section at all | **PASS** | Not applicable — including every spec written before this dimension existed, and any project with `Tool: none`. Nothing to enumerate is not a defect. |
|
||||
|
||||
@@ -155,7 +155,7 @@ Worth knowing before you rely on it, because the check is narrower than it looks
|
||||
- **It cannot tell a stale inventory from a current one.** That is what the recorded
|
||||
`<package>@<version>` is for: compare it against what is installed now. A spec reused after an
|
||||
upgrade looks exactly like a fresh one apart from that string.
|
||||
- **Enforcement is applied by an agent, not by a parser.** Dimension 7 is a rule `gsd-ui-checker`
|
||||
- **Enforcement is applied by an agent, not by a parser.** Dimension 7 is a rule `msd-ui-checker`
|
||||
follows, the same as the other six dimensions. It is not a schema check that runs over your
|
||||
spec, so treat a PASS as "the reviewer found a provenance line", not as a machine guarantee.
|
||||
- **"The checker never runs the recorded command" is an instruction, not a sandbox.** See
|
||||
@@ -169,7 +169,7 @@ a sourced one, and now it is not. But it is a record you can audit, not a proof.
|
||||
|
||||
## Use sketch findings as a head start
|
||||
|
||||
If you have already run `/gsd-sketch --wrap-up`, the UI researcher loads `.claude/skills/sketch-findings-[project]/` automatically. Pre-validated decisions (layout, palette, typography, spacing) are treated as locked — the researcher does not re-ask them. You see a note at the start of the run:
|
||||
If you have already run `/msd-sketch --wrap-up`, the UI researcher loads `.claude/skills/sketch-findings-[project]/` automatically. Pre-validated decisions (layout, palette, typography, spacing) are treated as locked — the researcher does not re-ask them. You see a note at the start of the run:
|
||||
|
||||
```text
|
||||
⚡ Sketch findings detected: .claude/skills/sketch-findings-[project]/SKILL.md
|
||||
@@ -177,20 +177,20 @@ If you have already run `/gsd-sketch --wrap-up`, the UI researcher loads `.claud
|
||||
as locked — not re-asked.
|
||||
```
|
||||
|
||||
This is the main reason to run `/gsd-sketch --wrap-up` before `/gsd-ui-phase`: it turns the conversational design exploration into binding contract input.
|
||||
This is the main reason to run `/msd-sketch --wrap-up` before `/msd-ui-phase`: it turns the conversational design exploration into binding contract input.
|
||||
|
||||
---
|
||||
|
||||
## Retroactive visual audit with `/gsd-ui-review`
|
||||
## Retroactive visual audit with `/msd-ui-review`
|
||||
|
||||
`/gsd-ui-review` runs after execution, not before. Use it to audit the implemented frontend against the UI-SPEC (or against abstract 6-pillar standards when no spec exists).
|
||||
`/msd-ui-review` runs after execution, not before. Use it to audit the implemented frontend against the UI-SPEC (or against abstract 6-pillar standards when no spec exists).
|
||||
|
||||
```bash
|
||||
/gsd-ui-review # audit the current phase
|
||||
/gsd-ui-review 3 # audit phase 3 specifically
|
||||
/msd-ui-review # audit the current phase
|
||||
/msd-ui-review 3 # audit phase 3 specifically
|
||||
```
|
||||
|
||||
It works on any project with frontend code — GSD project initialization is not required.
|
||||
It works on any project with frontend code — MSD project initialization is not required.
|
||||
|
||||
**What it checks (6 pillars, scored 1–4 each):**
|
||||
|
||||
@@ -201,24 +201,24 @@ It works on any project with frontend code — GSD project initialization is not
|
||||
5. Spacing — grid alignment, token consistency
|
||||
6. Experience Design — loading, error, and empty state coverage
|
||||
|
||||
**Output:** `{padded_phase}-UI-REVIEW.md` with scores and top three priority fixes. When a browser MCP server such as `gsd-browser` is configured, the audit also captures screenshots with visual evidence.
|
||||
**Output:** `{padded_phase}-UI-REVIEW.md` with scores and top three priority fixes. When a browser MCP server such as `msd-browser` is configured, the audit also captures screenshots with visual evidence.
|
||||
|
||||
**Screenshot storage:** Screenshots are saved to `.planning/ui-reviews/`. A `.gitignore` is created automatically to prevent binary files from reaching git. Screenshots are cleaned up during `/gsd-complete-milestone`.
|
||||
**Screenshot storage:** Screenshots are saved to `.planning/ui-reviews/`. A `.gitignore` is created automatically to prevent binary files from reaching git. Screenshots are cleaned up during `/msd-complete-milestone`.
|
||||
|
||||
---
|
||||
|
||||
## Recommended position in the phase lifecycle
|
||||
|
||||
```text
|
||||
/gsd-discuss-phase N ← lock implementation preferences
|
||||
/gsd-ui-phase N ← lock design contract (frontend phases)
|
||||
/gsd-plan-phase N ← research + plan (reads UI-SPEC.md as context)
|
||||
/gsd-execute-phase N ← parallel execution
|
||||
/gsd-verify-work N ← manual UAT
|
||||
/gsd-ui-review N ← retroactive visual audit (optional but recommended)
|
||||
/msd-discuss-phase N ← lock implementation preferences
|
||||
/msd-ui-phase N ← lock design contract (frontend phases)
|
||||
/msd-plan-phase N ← research + plan (reads UI-SPEC.md as context)
|
||||
/msd-execute-phase N ← parallel execution
|
||||
/msd-verify-work N ← manual UAT
|
||||
/msd-ui-review N ← retroactive visual audit (optional but recommended)
|
||||
```
|
||||
|
||||
`/gsd-ui-phase` sits between discuss and plan because the planner reads `UI-SPEC.md` as design context — tasks in `PLAN.md` reference spacing tokens, color variables, and copywriting decisions that the spec locked.
|
||||
`/msd-ui-phase` sits between discuss and plan because the planner reads `UI-SPEC.md` as design context — tasks in `PLAN.md` reference spacing tokens, color variables, and copywriting decisions that the spec locked.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Develop a Capability for GSD 1.5+
|
||||
# Develop a Capability for MSD 1.5+
|
||||
|
||||
This guide shows you how to add or change a first-party GSD Capability after the ADR-857 cutover. In GSD terms, the extension unit is a **Capability**. A plugin is a packaging or host-runtime term, for example a Claude Code plugin, not the unit that owns a GSD feature.
|
||||
This guide shows you how to add or change a first-party MSD Capability after the ADR-857 cutover. In MSD terms, the extension unit is a **Capability**. A plugin is a packaging or host-runtime term, for example a Claude Code plugin, not the unit that owns a MSD feature.
|
||||
|
||||
A Capability is right when the feature can be toggled as one unit and owns its own skills, agents, hooks, config keys, or command family. Keep verifier predicate contracts, the five-step loop spine, and shared infrastructure in core unless the ADRs explicitly move that boundary.
|
||||
|
||||
@@ -60,13 +60,13 @@ At minimum, a feature Capability declares:
|
||||
"requires": [],
|
||||
"runtimeCompat": { "supported": ["*"], "unsupported": [] },
|
||||
"skills": [],
|
||||
"agents": ["gsd-example-agent"],
|
||||
"agents": ["msd-example-agent"],
|
||||
"hooks": [],
|
||||
"config": {},
|
||||
"steps": [
|
||||
{
|
||||
"point": "plan:pre",
|
||||
"ref": { "agent": "gsd-example-agent" },
|
||||
"ref": { "agent": "msd-example-agent" },
|
||||
"fragment": { "path": "fragments/plan-pre.md" },
|
||||
"produces": ["EXAMPLE.md"],
|
||||
"consumes": ["CONTEXT.md"],
|
||||
@@ -82,7 +82,7 @@ The registry generator validates the shape, ownership, and cross-capability cont
|
||||
|
||||
## Declare runtime compatibility
|
||||
|
||||
Every feature Capability must declare `runtimeCompat`. This is part of the GSD 1.5+ developer contract: a Capability says which runtime descriptors it can surface through, and the generator validates that declaration before the central registry is written.
|
||||
Every feature Capability must declare `runtimeCompat`. This is part of the MSD 1.5+ developer contract: a Capability says which runtime descriptors it can surface through, and the generator validates that declaration before the central registry is written.
|
||||
|
||||
Use the wildcard when the Capability is runtime-agnostic:
|
||||
|
||||
@@ -113,7 +113,7 @@ Loop Extension Points are the stable sites where Capabilities attach to the host
|
||||
|
||||
Choose the hook kind that matches the behaviour:
|
||||
|
||||
- `steps` add a sequenced unit of work, such as running `gsd-phase-researcher` or `gsd-pattern-mapper`.
|
||||
- `steps` add a sequenced unit of work, such as running `msd-phase-researcher` or `msd-pattern-mapper`.
|
||||
- `contributions` add labelled context to a host prompt.
|
||||
- `gates` check a condition and may block when `blocking` is true.
|
||||
|
||||
@@ -131,7 +131,7 @@ and rejects a manifest that declares a kind the point does not dispatch. You fin
|
||||
capability "demo" steps[0].point "ship:pre" registers a step hook, but the host call site's
|
||||
dispatch text never covers `kind == "step"` (it covers: gate). A hand-rolled single-kind consumer
|
||||
silently never dispatches the other kinds — dispatch every registered kind per
|
||||
gsd-core/references/loop-hook-dispatch.md.
|
||||
msd-core/references/loop-hook-dispatch.md.
|
||||
```
|
||||
|
||||
That error is the answer, not a bug to route around. Either pick a point that dispatches your kind,
|
||||
@@ -148,7 +148,7 @@ or failed never drops a deliverable and never blocks UAT.
|
||||
|
||||
## Ship skills — and know what you are shipping
|
||||
|
||||
A skill your Capability declares is not an inert asset. Its `SKILL.md` body is copied **verbatim** into the user's runtime skills directory at install, where it becomes an agent-invocable instruction file. GSD does **not** scan it: there is no content inspection of any kind, at install or at any later point. What you write is what reaches the agent.
|
||||
A skill your Capability declares is not an inert asset. Its `SKILL.md` body is copied **verbatim** into the user's runtime skills directory at install, where it becomes an agent-invocable instruction file. MSD does **not** scan it: there is no content inspection of any kind, at install or at any later point. What you write is what reaches the agent.
|
||||
|
||||
That makes a skill body an **instruction surface**, and it carries author responsibility that an inert artifact does not:
|
||||
|
||||
@@ -192,18 +192,18 @@ node scripts/gen-capability-registry.cjs --check
|
||||
For a planning hook, verify the rendered output:
|
||||
|
||||
```bash
|
||||
node gsd-core/bin/gsd-tools.cjs loop render-hooks plan:pre --raw
|
||||
node msd-core/bin/msd-tools.cjs loop render-hooks plan:pre --raw
|
||||
```
|
||||
|
||||
In installed workflow prose, the same resolver surface appears as `gsd-tools loop render-hooks plan:pre`.
|
||||
In installed workflow prose, the same resolver surface appears as `msd-tools loop render-hooks plan:pre`.
|
||||
|
||||
The rendered JSON should include the active hook, the declared `ref`, and the materialised `fragment.inline`.
|
||||
|
||||
To verify a runtime-specific surface, pass the same config directory that the runtime installation uses:
|
||||
|
||||
```bash
|
||||
node gsd-core/bin/gsd-tools.cjs loop render-hooks plan:pre --config-dir ~/.claude --raw
|
||||
node gsd-core/bin/gsd-tools.cjs capability state --config-dir ~/.claude --raw
|
||||
node msd-core/bin/msd-tools.cjs loop render-hooks plan:pre --config-dir ~/.claude --raw
|
||||
node msd-core/bin/msd-tools.cjs capability state --config-dir ~/.claude --raw
|
||||
```
|
||||
|
||||
`capability state` is the diagnostic view for the same state that workflow dispatch consumes. For each Capability, `enabled` is true only when the Capability is both installed by the active profile and surfaced by the runtime surface. A hook's `configured` field reflects the `when` config key; `active` is true only when the Capability is enabled and the hook is configured on.
|
||||
@@ -234,7 +234,7 @@ Declare feature config keys in the Capability manifest:
|
||||
}
|
||||
```
|
||||
|
||||
Do not add migrated Capability keys to `gsd-core/bin/shared/config-schema.manifest.json`. The central schema remains for host/core keys; Capability-owned keys validate through the generated registry and are merged into `loadConfig` by the federated config overlay. Existing nested `.planning/config.json` values such as `{ "workflow": { "example_enabled": false } }` continue to override the Capability default.
|
||||
Do not add migrated Capability keys to `msd-core/bin/shared/config-schema.manifest.json`. The central schema remains for host/core keys; Capability-owned keys validate through the generated registry and are merged into `loadConfig` by the federated config overlay. Existing nested `.planning/config.json` values such as `{ "workflow": { "example_enabled": false } }` continue to override the Capability default.
|
||||
|
||||
## Wire the workflow through the registry
|
||||
|
||||
@@ -242,9 +242,9 @@ Host workflows should ask the resolver for active hooks and then dispatch from t
|
||||
|
||||
The Phase 6 migrations follow this pattern:
|
||||
|
||||
- `research` registers a `plan:pre` step that invokes `gsd-phase-researcher`.
|
||||
- `research` registers a `plan:pre` step that invokes `msd-phase-researcher`.
|
||||
- `ai-integration` owns the AI-SPEC planning activation and config key.
|
||||
- `pattern-mapper` registers a `plan:pre` step that invokes `gsd-pattern-mapper`.
|
||||
- `pattern-mapper` registers a `plan:pre` step that invokes `msd-pattern-mapper`.
|
||||
- `plan-phase.md` reads the resolved `PLAN_PRE_HOOKS_JSON` and dispatches `ref.agent` or `ref.skill` from that data.
|
||||
- `code-review` registers an `execute:post` step and review workflows dispatch from the active hook's `ref.skill`.
|
||||
- `security` registers a `plan:pre` contribution, a `verify:post` step, and a blocking `ship:pre` gate.
|
||||
@@ -278,15 +278,15 @@ Every Phase 6 slice that changes capability behaviour must update the relevant d
|
||||
|
||||
## The capability ecosystem (1.6.0)
|
||||
|
||||
From GSD 1.6.0, capabilities are versioned (the `version` field is required in `capability.json`) and can be installed directly from a URL, a git ref, an npm package, or a local path — without modifying the core repo.
|
||||
From MSD 1.6.0, capabilities are versioned (the `version` field is required in `capability.json`) and can be installed directly from a URL, a git ref, an npm package, or a local path — without modifying the core repo.
|
||||
|
||||
- **Tutorial** — [Build your first capability](../tutorials/build-your-first-capability.md): scaffold and install a declarative capability end-to-end in under ten minutes.
|
||||
- **How-to** — [Publish a capability](../how-to/publish-a-capability.md): package and distribute a capability via a URL or registry.
|
||||
- **How-to** — [Import a capability from a URL](../how-to/import-a-capability-from-a-url.md): install a third-party capability from a git URL, tarball, or npm package.
|
||||
- **How-to** — [Version and update a capability](../how-to/version-a-capability.md): manage `version`, `engines.gsd`, and `compatVersions`; use `gsd capability update`.
|
||||
- **How-to** — [Remove a capability](../how-to/remove-a-capability.md): uninstall cleanly with `gsd capability remove`, including the `--purge-data` option.
|
||||
- **How-to** — [Ship a reviewer lane in your capability](../how-to/ship-a-reviewer-lane.md): declare a `reviewer` body (GSD 1.9.0+) so `/gsd-review` discovers and invokes your external review CLI or model endpoint.
|
||||
- **How-to** — [List your reviewer lane in the registry](../how-to/list-your-reviewer-lane.md): publish a lane to the Reviewer Lane Registry (GSD 1.9.1+) so other people can find and install it.
|
||||
- **How-to** — [Version and update a capability](../how-to/version-a-capability.md): manage `version`, `engines.msd`, and `compatVersions`; use `msd capability update`.
|
||||
- **How-to** — [Remove a capability](../how-to/remove-a-capability.md): uninstall cleanly with `msd capability remove`, including the `--purge-data` option.
|
||||
- **How-to** — [Ship a reviewer lane in your capability](../how-to/ship-a-reviewer-lane.md): declare a `reviewer` body (MSD 1.9.0+) so `/msd-review` discovers and invokes your external review CLI or model endpoint.
|
||||
- **How-to** — [List your reviewer lane in the registry](../how-to/list-your-reviewer-lane.md): publish a lane to the Reviewer Lane Registry (MSD 1.9.1+) so other people can find and install it.
|
||||
- **Reference** — [Capability manifest](../reference/capability-manifest.md): all fields and validation rules for `capability.json`.
|
||||
- **Reference** — [Capability matrix](../reference/capability-matrix.md): which first-party capabilities exist, their extension points, and their compatibility matrix.
|
||||
- **Explanation** — [Capability trust model](../explanation/capability-trust-model.md): how declarative and executable capabilities are treated differently at install time.
|
||||
|
||||
@@ -5,8 +5,8 @@ a task's `<action>`/`<verify>`/`<acceptance_criteria>`/`<read_first>`/`<done>` c
|
||||
external issue tracker instead of reading it inline from `PLAN.md`.
|
||||
|
||||
**Prerequisites:** You already have a capability (`capability.json`), or you are creating one —
|
||||
see [Develop a Capability for GSD 1.5+](develop-a-capability.md) first if this is your first one.
|
||||
GSD 1.28 or later ([ADR-3646](../adr/3646-per-task-content-resolution-seam.md)).
|
||||
see [Develop a Capability for MSD 1.5+](develop-a-capability.md) first if this is your first one.
|
||||
MSD 1.28 or later ([ADR-3646](../adr/3646-per-task-content-resolution-seam.md)).
|
||||
|
||||
---
|
||||
|
||||
@@ -58,10 +58,10 @@ Add a `taskContentResolver` block to your capability's manifest body (`role: "fe
|
||||
Two fields decide whether the seam works at all:
|
||||
|
||||
- **`trackerPrefix`** must match the prefix of a task's `tracker-id` attribute — everything
|
||||
before the **first** `:`. Given `<task tracker-id="beads:GSD-42">`, the prefix is `beads` and
|
||||
the id passed to your resolver is `GSD-42`. If a tracker's own ids contain colons, that is fine:
|
||||
only the first colon splits prefix from id, so `beads:team:GSD-42` resolves to id `team:GSD-42`.
|
||||
- **`invoke.args`** must contain the `{{id}}` placeholder at least once — GSD substitutes it with
|
||||
before the **first** `:`. Given `<task tracker-id="beads:MSD-42">`, the prefix is `beads` and
|
||||
the id passed to your resolver is `MSD-42`. If a tracker's own ids contain colons, that is fine:
|
||||
only the first colon splits prefix from id, so `beads:team:MSD-42` resolves to id `team:MSD-42`.
|
||||
- **`invoke.args`** must contain the `{{id}}` placeholder at least once — MSD substitutes it with
|
||||
the task's id before spawning your binary. A declaration whose `args` never carries the
|
||||
placeholder fails validation at install time, because the id could never reach your resolver.
|
||||
|
||||
@@ -105,23 +105,23 @@ JSON parse outcome decide success.
|
||||
## What happens on failure
|
||||
|
||||
A resolver that is declared, invoked, and fails — non-zero exit, timeout, or malformed JSON —
|
||||
makes `gsd_run task resolve-content` itself exit non-zero. `execute-plan.md` treats that as a
|
||||
makes `msd_run task resolve-content` itself exit non-zero. `execute-plan.md` treats that as a
|
||||
**hard halt**: it stops before doing any work on the task, surfaces the tracker-id, the tracker
|
||||
prefix, and your resolver's stderr, and never proceeds to read the task's inline `PLAN.md` content
|
||||
as a substitute. See [ADR-3646](../adr/3646-per-task-content-resolution-seam.md) for why this is
|
||||
the load-bearing safety property of the whole feature, and
|
||||
[`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)
|
||||
for how this call site differs from the twelve prose-dispatched loop extension points.
|
||||
|
||||
---
|
||||
|
||||
## Worked example: a `bd`/beads-shaped resolver
|
||||
|
||||
Suppose `bd show GSD-42 --json` already returns:
|
||||
Suppose `bd show MSD-42 --json` already returns:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "GSD-42",
|
||||
"id": "MSD-42",
|
||||
"title": "Add rate-limit check to login",
|
||||
"status": "open",
|
||||
"description": "Add a rate-limit check to processLogin using the existing RateLimiter.",
|
||||
@@ -155,7 +155,7 @@ node -e '
|
||||
|
||||
Declare it as the `invoke.binary`/`invoke.args` pair (or point `invoke.binary` at `bd` directly if
|
||||
its own `--json` output already matches the expected field names — no adapter needed in that
|
||||
case). Either way, `invoke.args` must carry `{{id}}` so GSD can substitute the task's tracker id
|
||||
case). Either way, `invoke.args` must carry `{{id}}` so MSD can substitute the task's tracker id
|
||||
before spawning it.
|
||||
|
||||
---
|
||||
@@ -166,7 +166,7 @@ before spawning it.
|
||||
alternatives
|
||||
- [Capability manifest → `taskContentResolver`](../reference/capability-manifest.md#taskcontentresolver) —
|
||||
the full field table
|
||||
- [`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) —
|
||||
how `execute:task` differs from the twelve loop extension points
|
||||
- [Develop a Capability for GSD 1.5+](develop-a-capability.md) — manifests, registry generation,
|
||||
- [Develop a Capability for MSD 1.5+](develop-a-capability.md) — manifests, registry generation,
|
||||
and federated config
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
# How to diagnose which `gsd-tools` is running
|
||||
# How to diagnose which `msd-tools` is running
|
||||
|
||||
Two packages publish a binary called `gsd-tools`: this one, and the predecessor
|
||||
Two packages publish a binary called `msd-tools`: this one, and the predecessor
|
||||
`get-shit-done-cc`. They answer some of the same verb names with **different** behavior.
|
||||
This guide tells you which one you have and how to fix a bad resolution.
|
||||
|
||||
Use it when:
|
||||
|
||||
- a workflow behaves unlike its documentation,
|
||||
- a workflow stops with `gsd-tools.cjs not found … and no identity-proving gsd_run is on PATH`,
|
||||
- a workflow stops with `msd-tools.cjs not found … and no identity-proving msd_run is on PATH`,
|
||||
- or you simply want to confirm which tool a project is running against.
|
||||
|
||||
## Why this matters
|
||||
@@ -17,20 +17,20 @@ Use it when:
|
||||
under the predecessor. Both print success-shaped output, and `.planning/` is gitignored by
|
||||
default, so the difference is invisible until the directories are gone.
|
||||
|
||||
Shipped workflows no longer resolve `gsd-tools` from `PATH` at all — they resolve `gsd_run`,
|
||||
Shipped workflows no longer resolve `msd-tools` from `PATH` at all — they resolve `msd_run`,
|
||||
which only this package publishes. That closes the path that caused #3129. The resolver
|
||||
prefers its path-based branches — a project-local install, then a runtime config directory —
|
||||
and only falls back to a `gsd_run` found on `PATH` when that binary proves it is
|
||||
`@opengsd/gsd-core` (#4834): a foreign or too-old `gsd_run` on `PATH` is passed over, not
|
||||
and only falls back to a `msd_run` found on `PATH` when that binary proves it is
|
||||
`@golem15/msd-core` (#4834): a foreign or too-old `msd_run` on `PATH` is passed over, not
|
||||
used with a warning. The path-based branches are still checked by assertion after
|
||||
resolution: the launcher probes whatever it resolved and warns when the tool cannot prove
|
||||
it is `@opengsd/gsd-core`.
|
||||
it is `@golem15/msd-core`.
|
||||
|
||||
If you got here from that warning, it looks like this:
|
||||
|
||||
```text
|
||||
WARNING: "/some/path/gsd-tools.cjs" did not prove it is @opengsd/gsd-core - it is either a
|
||||
different package or an @opengsd/gsd-core older than the runtime-identity verb.
|
||||
WARNING: "/some/path/msd-tools.cjs" did not prove it is @golem15/msd-core - it is either a
|
||||
different package or an @golem15/msd-core older than the runtime-identity verb.
|
||||
```
|
||||
|
||||
The two causes need opposite fixes, and the warning cannot tell them apart — the sections
|
||||
@@ -40,14 +40,14 @@ resolver refuses outright.
|
||||
## Ask the tool what it is
|
||||
|
||||
```bash
|
||||
gsd-tools runtime-identity
|
||||
msd-tools runtime-identity
|
||||
```
|
||||
|
||||
A healthy GSD runtime prints:
|
||||
A healthy MSD runtime prints:
|
||||
|
||||
```json
|
||||
{
|
||||
"packageName": "@opengsd/gsd-core",
|
||||
"packageName": "@golem15/msd-core",
|
||||
"version": "1.12.0"
|
||||
}
|
||||
```
|
||||
@@ -57,24 +57,24 @@ Three other outcomes are possible, and they mean different things:
|
||||
| What you see | What it means |
|
||||
|---|---|
|
||||
| The JSON above | This is our tool. Nothing to do. |
|
||||
| A usage screen mentioning `gsd-sdk`, exit 1 | This is the **predecessor's** binary. See [A different package owns it](#a-different-package-owns-it). |
|
||||
| `Error: Unknown command: runtime-identity` | This is our tool, but **older than the verb**. See [It is an old gsd-core](#it-is-an-old-gsd-core). |
|
||||
| Nothing runs at all | Nothing named `gsd-tools` is on your `PATH`. That is fine — workflows do not need it. |
|
||||
| A usage screen mentioning `msd-sdk`, exit 1 | This is the **predecessor's** binary. See [A different package owns it](#a-different-package-owns-it). |
|
||||
| `Error: Unknown command: runtime-identity` | This is our tool, but **older than the verb**. See [It is an old msd-core](#it-is-an-old-msd-core). |
|
||||
| Nothing runs at all | Nothing named `msd-tools` is on your `PATH`. That is fine — workflows do not need it. |
|
||||
|
||||
Then find out which package owns the file:
|
||||
|
||||
```bash
|
||||
readlink -f "$(command -v gsd-tools)"
|
||||
readlink -f "$(command -v msd-tools)"
|
||||
```
|
||||
|
||||
## A different package owns it
|
||||
|
||||
The resolved path contains `get-shit-done-cc`, or the identity probe printed a `gsd-sdk`
|
||||
The resolved path contains `get-shit-done-cc`, or the identity probe printed a `msd-sdk`
|
||||
usage screen.
|
||||
|
||||
Workflows will not reach it — they resolve `gsd_run`, which that package does not publish —
|
||||
Workflows will not reach it — they resolve `msd_run`, which that package does not publish —
|
||||
so this is no longer dangerous. It is still worth resolving, because *you* invoking
|
||||
`gsd-tools` by hand will reach the wrong tool.
|
||||
`msd-tools` by hand will reach the wrong tool.
|
||||
|
||||
If you no longer use the predecessor:
|
||||
|
||||
@@ -88,15 +88,15 @@ If you need both installed, put this package's bin directory first on `PATH`:
|
||||
export PATH="$(npm prefix -g)/bin:$PATH"
|
||||
```
|
||||
|
||||
Re-run `gsd-tools runtime-identity` and confirm it reports `@opengsd/gsd-core`.
|
||||
Re-run `msd-tools runtime-identity` and confirm it reports `@golem15/msd-core`.
|
||||
|
||||
## It is an old gsd-core
|
||||
## It is an old msd-core
|
||||
|
||||
The resolved path is inside `@opengsd/gsd-core`, but `runtime-identity` is not a known
|
||||
The resolved path is inside `@golem15/msd-core`, but `runtime-identity` is not a known
|
||||
command. That version predates the verb. Nothing is wrong beyond being out of date:
|
||||
|
||||
```bash
|
||||
npm install -g @opengsd/gsd-core@latest
|
||||
npm install -g @golem15/msd-core@latest
|
||||
```
|
||||
|
||||
Since #4834, a copy this old on your `PATH` can no longer be picked up by a workflow's
|
||||
@@ -104,29 +104,29 @@ launcher — the resolver requires the identity proof the verb provides, so the
|
||||
is passed over in favor of a project-local or config-directory install. You can still
|
||||
reach it by hand, which is why upgrading matters.
|
||||
|
||||
## A workflow says `gsd_run is not on PATH`
|
||||
## A workflow says `msd_run is not on PATH`
|
||||
|
||||
The resolver found nothing it could use: no project-local or config-directory install
|
||||
matched, and either nothing named `gsd_run` is on `PATH` or the only entry could not prove
|
||||
it is `@opengsd/gsd-core`. It stops rather than guessing — falling back to an arbitrary
|
||||
`gsd-tools` is exactly the behavior that caused #3129.
|
||||
matched, and either nothing named `msd_run` is on `PATH` or the only entry could not prove
|
||||
it is `@golem15/msd-core`. It stops rather than guessing — falling back to an arbitrary
|
||||
`msd-tools` is exactly the behavior that caused #3129.
|
||||
|
||||
This is expected in one specific case: an installation old enough to predate the `gsd_run`
|
||||
This is expected in one specific case: an installation old enough to predate the `msd_run`
|
||||
binary ([#381](https://github.com/open-gsd/gsd-core/issues/381)). Upgrade:
|
||||
|
||||
```bash
|
||||
npm install -g @opengsd/gsd-core@latest
|
||||
npm install -g @golem15/msd-core@latest
|
||||
```
|
||||
|
||||
Confirm the binary is now present:
|
||||
|
||||
```bash
|
||||
command -v gsd_run
|
||||
command -v msd_run
|
||||
```
|
||||
|
||||
If you deliberately pin an old version, invoke workflows from a project or config directory
|
||||
where the path-based resolution branches apply — a local install under
|
||||
`gsd-core/bin/gsd-tools.cjs`, or your runtime's config directory — rather than relying on
|
||||
`msd-core/bin/msd-tools.cjs`, or your runtime's config directory — rather than relying on
|
||||
`PATH`.
|
||||
|
||||
## Tell "not installed" apart from "wrong one installed"
|
||||
@@ -134,13 +134,13 @@ where the path-based resolution branches apply — a local install under
|
||||
These two look similar and have opposite fixes:
|
||||
|
||||
```bash
|
||||
command -v gsd_run || echo "gsd_run: NOT FOUND"
|
||||
command -v gsd-tools || echo "gsd-tools: NOT FOUND"
|
||||
command -v msd_run || echo "msd_run: NOT FOUND"
|
||||
command -v msd-tools || echo "msd-tools: NOT FOUND"
|
||||
```
|
||||
|
||||
- **`gsd_run` found** — workflows resolve correctly, whatever `gsd-tools` says.
|
||||
- **`gsd_run` missing, `gsd-tools` present** — the likely collision case. Run
|
||||
`readlink -f "$(command -v gsd-tools)"` and follow the matching section above.
|
||||
- **`msd_run` found** — workflows resolve correctly, whatever `msd-tools` says.
|
||||
- **`msd_run` missing, `msd-tools` present** — the likely collision case. Run
|
||||
`readlink -f "$(command -v msd-tools)"` and follow the matching section above.
|
||||
- **Both missing** — nothing is installed globally; workflows will use a local or
|
||||
config-directory install if one exists.
|
||||
|
||||
@@ -150,10 +150,10 @@ Inside a workflow shell — that is, after the launcher preamble has run — the
|
||||
variable, not just a message:
|
||||
|
||||
```bash
|
||||
printf '%s\n' "$GSD_IDENTITY_STATUS"
|
||||
printf '%s\n' "$MSD_IDENTITY_STATUS"
|
||||
```
|
||||
|
||||
- `ok` — the resolved tool proved it is `@opengsd/gsd-core`. Nothing to do.
|
||||
- `ok` — the resolved tool proved it is `@golem15/msd-core`. Nothing to do.
|
||||
- `unverified` — it did not. Work the two sections above, in that order: rule out a foreign
|
||||
package first, then upgrade an old one.
|
||||
|
||||
@@ -162,7 +162,7 @@ so treat it as something to fix now rather than something to live with.
|
||||
|
||||
## Related
|
||||
|
||||
- [Runtime identity](../FEATURES.md#168-runtime-identity) — why the launcher resolves `gsd_run`,
|
||||
- [Runtime identity](../FEATURES.md#168-runtime-identity) — why the launcher resolves `msd_run`,
|
||||
and why it also asserts identity on the branches that resolution alone cannot make safe
|
||||
- [`runtime-identity`](../COMMANDS.md#runtime-identity) — the verb's exact output
|
||||
- [#3129](https://github.com/open-gsd/gsd-core/issues/3129) — the incident this prevents
|
||||
@@ -2,18 +2,18 @@
|
||||
|
||||
**Goal:** Gather the implementation decisions a phase needs before planning begins — so the researcher and planner can act without asking you again.
|
||||
|
||||
**Prerequisites:** `.planning/ROADMAP.md` exists. If not, run `/gsd-new-project` first.
|
||||
**Prerequisites:** `.planning/ROADMAP.md` exists. If not, run `/msd-new-project` first.
|
||||
|
||||
---
|
||||
|
||||
## Choose your discuss mode
|
||||
|
||||
GSD Core offers two modes. Choose based on how well-understood the codebase is.
|
||||
MSD Core offers two modes. Choose based on how well-understood the codebase is.
|
||||
|
||||
**If you want to express your own implementation preferences upfront** (interview mode, the default):
|
||||
|
||||
```bash
|
||||
/gsd-discuss-phase 2
|
||||
/msd-discuss-phase 2
|
||||
```
|
||||
|
||||
Claude identifies grey areas in the phase scope, lets you select which to discuss, then works through approximately four questions per area.
|
||||
@@ -21,8 +21,8 @@ Claude identifies grey areas in the phase scope, lets you select which to discus
|
||||
**If the codebase already has clear patterns and you find most questions obvious** (assumptions mode):
|
||||
|
||||
```bash
|
||||
node gsd-tools.cjs config-set workflow.discuss_mode assumptions
|
||||
/gsd-discuss-phase 2
|
||||
node msd-tools.cjs config-set workflow.discuss_mode assumptions
|
||||
/msd-discuss-phase 2
|
||||
```
|
||||
|
||||
Claude reads 5–15 relevant codebase files via a subagent, forms assumptions with evidence and confidence levels, and presents them for confirmation or correction. Typically 2–4 interactions rather than 15–20.
|
||||
@@ -30,7 +30,7 @@ Claude reads 5–15 relevant codebase files via a subagent, forms assumptions wi
|
||||
To switch back:
|
||||
|
||||
```bash
|
||||
node gsd-tools.cjs config-set workflow.discuss_mode discuss
|
||||
node msd-tools.cjs config-set workflow.discuss_mode discuss
|
||||
```
|
||||
|
||||
See [Discuss modes explained](../workflow-discuss-mode.md) for a full comparison, including when each mode is likely to save time.
|
||||
@@ -42,7 +42,7 @@ See [Discuss modes explained](../workflow-discuss-mode.md) for a full comparison
|
||||
By default, Claude presents grey areas and asks which you want to cover. If you want to work through all of them without that selection prompt:
|
||||
|
||||
```bash
|
||||
/gsd-discuss-phase 2 --all
|
||||
/msd-discuss-phase 2 --all
|
||||
```
|
||||
|
||||
---
|
||||
@@ -52,7 +52,7 @@ By default, Claude presents grey areas and asks which you want to cover. If you
|
||||
**If the phase is well-understood and you want Claude to pick the recommended defaults without prompting you:**
|
||||
|
||||
```bash
|
||||
/gsd-discuss-phase 3 --auto
|
||||
/msd-discuss-phase 3 --auto
|
||||
```
|
||||
|
||||
Claude selects the recommended answer for every question and logs the choices. Use this for phases where the decisions are low-stakes or already implied by prior phases.
|
||||
@@ -60,7 +60,7 @@ Claude selects the recommended answer for every question and logs the choices. U
|
||||
**If you have remote-session constraints (no TUI menus):**
|
||||
|
||||
```bash
|
||||
/gsd-discuss-phase 2 --text
|
||||
/msd-discuss-phase 2 --text
|
||||
```
|
||||
|
||||
All prompts are rendered as plain-text numbered lists instead of interactive selectors.
|
||||
@@ -72,7 +72,7 @@ All prompts are rendered as plain-text numbered lists instead of interactive sel
|
||||
If you prefer to answer several questions at once rather than one at a time:
|
||||
|
||||
```bash
|
||||
/gsd-discuss-phase 2 --batch
|
||||
/msd-discuss-phase 2 --batch
|
||||
```
|
||||
|
||||
Claude groups 2–5 questions per turn.
|
||||
@@ -84,7 +84,7 @@ Claude groups 2–5 questions per turn.
|
||||
If you want a comparison table of the options before committing:
|
||||
|
||||
```bash
|
||||
/gsd-discuss-phase 2 --analyze
|
||||
/msd-discuss-phase 2 --analyze
|
||||
```
|
||||
|
||||
---
|
||||
@@ -94,7 +94,7 @@ If you want a comparison table of the options before committing:
|
||||
If you have a prepared answers file and want to push all decisions in one pass:
|
||||
|
||||
```bash
|
||||
/gsd-discuss-phase 1 --power
|
||||
/msd-discuss-phase 1 --power
|
||||
```
|
||||
|
||||
---
|
||||
@@ -104,7 +104,7 @@ If you have a prepared answers file and want to push all decisions in one pass:
|
||||
**If you want to see what Claude would assume and do before any interactive session** — useful for validating alignment before investing discussion time:
|
||||
|
||||
```bash
|
||||
/gsd-discuss-phase 3 --assumptions
|
||||
/msd-discuss-phase 3 --assumptions
|
||||
```
|
||||
|
||||
Claude outputs its assumptions (with codebase evidence and confidence levels) and exits. No CONTEXT.md is written. Review the output, then run a normal discuss or assumptions-mode session if anything needs correcting.
|
||||
@@ -132,9 +132,9 @@ See [CONTEXT.md schema](../reference/context-md.md) for the full field reference
|
||||
|
||||
## How decisions feed into planning
|
||||
|
||||
When you run `/gsd-plan-phase` next, the planner reads CONTEXT.md to know which decisions are locked. It will not re-ask questions already answered here. The researcher reads it first to know what to investigate.
|
||||
When you run `/msd-plan-phase` next, the planner reads CONTEXT.md to know which decisions are locked. It will not re-ask questions already answered here. The researcher reads it first to know what to investigate.
|
||||
|
||||
**If CONTEXT.md is missing when you run `/gsd-plan-phase`**, you will be offered the choice to continue without context (plans use research and requirements only, without your design preferences) or to run `/gsd-discuss-phase` first.
|
||||
**If CONTEXT.md is missing when you run `/msd-plan-phase`**, you will be offered the choice to continue without context (plans use research and requirements only, without your design preferences) or to run `/msd-discuss-phase` first.
|
||||
|
||||
---
|
||||
|
||||
@@ -143,7 +143,7 @@ When you run `/gsd-plan-phase` next, the planner reads CONTEXT.md to know which
|
||||
Skip discuss-phase entirely and go straight to planning:
|
||||
|
||||
```bash
|
||||
/gsd-plan-phase 1 --prd path/to/prd.md
|
||||
/msd-plan-phase 1 --prd path/to/prd.md
|
||||
```
|
||||
|
||||
The planner synthesises CONTEXT.md from the PRD and treats all requirements as locked decisions.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# How to drive GSD Core from a tracker issue
|
||||
# How to drive MSD Core from a tracker issue
|
||||
|
||||
**Goal:** Take a single well-scoped GitHub, Linear, or Jira issue through the full GSD pipeline — from isolated workspace to merged PR — using only commands that already exist in GSD Core, with no custom scripts or tracker integrations.
|
||||
**Goal:** Take a single well-scoped GitHub, Linear, or Jira issue through the full MSD pipeline — from isolated workspace to merged PR — using only commands that already exist in MSD Core, with no custom scripts or tracker integrations.
|
||||
|
||||
**Prerequisites:** GSD Core is installed. The issue has bounded scope, observable acceptance criteria, and no upstream blockers.
|
||||
**Prerequisites:** MSD Core is installed. The issue has bounded scope, observable acceptance criteria, and no upstream blockers.
|
||||
|
||||
For the concepts and design rationale behind this pattern, see [Issue-driven orchestration explained](../issue-driven-orchestration.md).
|
||||
|
||||
@@ -16,13 +16,13 @@ Open your tracker issue and decide how it maps onto `ROADMAP.md`:
|
||||
- **Issue is standalone new work** → add a phase:
|
||||
|
||||
```bash
|
||||
/gsd-phase "Description matching the issue title"
|
||||
/msd-phase "Description matching the issue title"
|
||||
```
|
||||
|
||||
- **Issue is urgent and must slot between existing phases** → insert a decimal phase:
|
||||
|
||||
```bash
|
||||
/gsd-phase --insert 3 "Fix: description from issue"
|
||||
/msd-phase --insert 3 "Fix: description from issue"
|
||||
```
|
||||
|
||||
Copy the tracker issue URL. You will paste it into `CONTEXT.md` in Step 3 so traceability survives context compaction.
|
||||
@@ -34,13 +34,13 @@ Copy the tracker issue URL. You will paste it into `CONTEXT.md` in Step 3 so tra
|
||||
Every issue gets its own workspace — a git worktree with an independent `.planning/` directory. Partial work, aborted plans, and exploratory commits stay outside `main`.
|
||||
|
||||
```bash
|
||||
/gsd-workspace --new --name my-issue-slug --repos . --strategy worktree
|
||||
/msd-workspace --new --name my-issue-slug --repos . --strategy worktree
|
||||
```
|
||||
|
||||
Switch into the workspace directory before continuing:
|
||||
|
||||
```bash
|
||||
cd ~/gsd-workspaces/my-issue-slug
|
||||
cd ~/msd-workspaces/my-issue-slug
|
||||
```
|
||||
|
||||
---
|
||||
@@ -50,15 +50,15 @@ cd ~/gsd-workspaces/my-issue-slug
|
||||
Run discuss-phase to lock in implementation decisions before any planning happens. When the session opens, paste the tracker issue URL into the discussion so it is captured in `CONTEXT.md`.
|
||||
|
||||
```bash
|
||||
/gsd-discuss-phase N
|
||||
/msd-discuss-phase N
|
||||
```
|
||||
|
||||
GSD asks about ambiguities in the issue scope — error handling, edge cases, interface contracts, technology choices. Your answers shape the plan that follows.
|
||||
MSD asks about ambiguities in the issue scope — error handling, edge cases, interface contracts, technology choices. Your answers shape the plan that follows.
|
||||
|
||||
If you already know all the answers and want to move quickly:
|
||||
|
||||
```bash
|
||||
/gsd-discuss-phase N --auto
|
||||
/msd-discuss-phase N --auto
|
||||
```
|
||||
|
||||
---
|
||||
@@ -66,22 +66,22 @@ If you already know all the answers and want to move quickly:
|
||||
## Step 4: Plan the phase
|
||||
|
||||
```bash
|
||||
/gsd-plan-phase N
|
||||
/msd-plan-phase N
|
||||
```
|
||||
|
||||
GSD spawns research agents, reads your `CONTEXT.md` decisions (including the issue URL), and produces atomic `PLAN.md` files. A plan-checker validates each plan before saving.
|
||||
MSD spawns research agents, reads your `CONTEXT.md` decisions (including the issue URL), and produces atomic `PLAN.md` files. A plan-checker validates each plan before saving.
|
||||
|
||||
If you want peer review from external AI CLIs before execution (recommended for significant changes):
|
||||
|
||||
```bash
|
||||
/gsd-review --phase N
|
||||
/gsd-plan-phase N --reviews
|
||||
/msd-review --phase N
|
||||
/msd-plan-phase N --reviews
|
||||
```
|
||||
|
||||
Or run the full plan–review–converge loop until no HIGH concerns remain:
|
||||
|
||||
```bash
|
||||
/gsd-plan-review-convergence N
|
||||
/msd-plan-review-convergence N
|
||||
```
|
||||
|
||||
---
|
||||
@@ -91,19 +91,19 @@ Or run the full plan–review–converge loop until no HIGH concerns remain:
|
||||
For interactive, phase-at-a-time execution:
|
||||
|
||||
```bash
|
||||
/gsd-execute-phase N
|
||||
/msd-execute-phase N
|
||||
```
|
||||
|
||||
For a hands-off run through all remaining phases:
|
||||
|
||||
```bash
|
||||
/gsd-autonomous
|
||||
/msd-autonomous
|
||||
```
|
||||
|
||||
For an interactive dashboard where you can watch progress and dispatch work across phases:
|
||||
|
||||
```bash
|
||||
/gsd-manager
|
||||
/msd-manager
|
||||
```
|
||||
|
||||
All three approaches update `STATE.md`, commit each task atomically, and run the post-phase verifier.
|
||||
@@ -113,10 +113,10 @@ All three approaches update `STATE.md`, commit each task atomically, and run the
|
||||
## Step 6: Verify the work
|
||||
|
||||
```bash
|
||||
/gsd-verify-work N
|
||||
/msd-verify-work N
|
||||
```
|
||||
|
||||
GSD walks you through the acceptance criteria from the phase goal (which reflects your tracker issue) one at a time. If anything fails, GSD diagnoses the root cause and creates a fix plan. Re-run execute and re-verify until all checks pass.
|
||||
MSD walks you through the acceptance criteria from the phase goal (which reflects your tracker issue) one at a time. If anything fails, MSD diagnoses the root cause and creates a fix plan. Re-run execute and re-verify until all checks pass.
|
||||
|
||||
Treat `verification_failed` as a blocker even when the code looks correct — the failure usually surfaces a missed acceptance criterion from the original issue.
|
||||
|
||||
@@ -127,17 +127,17 @@ Treat `verification_failed` as a blocker even when the code looks correct — th
|
||||
Run a code review before opening the PR:
|
||||
|
||||
```bash
|
||||
/gsd-code-review N
|
||||
/gsd-code-review N --fix
|
||||
/msd-code-review N
|
||||
/msd-code-review N --fix
|
||||
```
|
||||
|
||||
Then create the PR:
|
||||
|
||||
```bash
|
||||
/gsd-ship N
|
||||
/msd-ship N
|
||||
```
|
||||
|
||||
GSD assembles the PR body from your planning artifacts: phase goal, changes summary, requirements addressed, verification status, and key decisions. Include `Closes #NNN` or `Fixes #NNN` in the PR body (or set it via `/gsd-config`) so the tracker issue closes automatically when the PR merges.
|
||||
MSD assembles the PR body from your planning artifacts: phase goal, changes summary, requirements addressed, verification status, and key decisions. Include `Closes #NNN` or `Fixes #NNN` in the PR body (or set it via `/msd-config`) so the tracker issue closes automatically when the PR merges.
|
||||
|
||||
---
|
||||
|
||||
@@ -146,12 +146,12 @@ GSD assembles the PR body from your planning artifacts: phase goal, changes summ
|
||||
As you work through the issue you will often discover related work. Capture it without losing context:
|
||||
|
||||
```bash
|
||||
/gsd-capture "Follow-up: description of discovered work" # Add as a todo
|
||||
/gsd-capture --seed "Idea worth a future phase" # Preserve for the next milestone
|
||||
/gsd-capture --backlog "Not urgent but worth tracking" # Park in the backlog
|
||||
/msd-capture "Follow-up: description of discovered work" # Add as a todo
|
||||
/msd-capture --seed "Idea worth a future phase" # Preserve for the next milestone
|
||||
/msd-capture --backlog "Not urgent but worth tracking" # Park in the backlog
|
||||
```
|
||||
|
||||
GSD does not post to your tracker automatically. Creating a tracker issue from captured follow-ups is a separate manual step — this keeps human review in the loop.
|
||||
MSD does not post to your tracker automatically. Creating a tracker issue from captured follow-ups is a separate manual step — this keeps human review in the loop.
|
||||
|
||||
---
|
||||
|
||||
@@ -159,12 +159,12 @@ GSD does not post to your tracker automatically. Creating a tracker issue from c
|
||||
|
||||
| Situation | What to do |
|
||||
|-----------|-----------|
|
||||
| Issue is very small (typo, config change) | Skip workspace + discuss + plan; use `/gsd-quick` instead |
|
||||
| Issue has multiple independent sub-tasks | Use `/gsd-manager` to parallelise execution across plans |
|
||||
| Issue is blocked on another issue | Do not start until the upstream blocker is resolved; GSD has no automatic dependency poller |
|
||||
| Issue scope turns out larger than expected mid-execution | Stop, run `/gsd-phase --insert N` to add sub-phases, continue |
|
||||
| You want to skip the interactive discussion | Use `--auto` flag with `/gsd-discuss-phase`, or set `workflow.skip_discuss: true` for project-wide automation |
|
||||
| Multiple issues form a coherent release | Run `/gsd-new-milestone` to group them and `/gsd-autonomous` to execute in sequence |
|
||||
| Issue is very small (typo, config change) | Skip workspace + discuss + plan; use `/msd-quick` instead |
|
||||
| Issue has multiple independent sub-tasks | Use `/msd-manager` to parallelise execution across plans |
|
||||
| Issue is blocked on another issue | Do not start until the upstream blocker is resolved; MSD has no automatic dependency poller |
|
||||
| Issue scope turns out larger than expected mid-execution | Stop, run `/msd-phase --insert N` to add sub-phases, continue |
|
||||
| You want to skip the interactive discussion | Use `--auto` flag with `/msd-discuss-phase`, or set `workflow.skip_discuss: true` for project-wide automation |
|
||||
| Multiple issues form a coherent release | Run `/msd-new-milestone` to group them and `/msd-autonomous` to execute in sequence |
|
||||
|
||||
---
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
# How to enable and use the Claude orchestration backend (BETA)
|
||||
|
||||
Run GSD's execute-phase waves through Claude Code's Workflow tool (`/effort ultracode`, Agent SDK ≥ v0.3.149) instead of the default one-agent-per-message dispatch, and fold the `gsd-ultraplan-phase` plan-offload under the same gate. On Claude Code this restores the wave parallelism that backgrounded-agent nesting (#853) otherwise forces inline.
|
||||
Run MSD's execute-phase waves through Claude Code's Workflow tool (`/effort ultracode`, Agent SDK ≥ v0.3.149) instead of the default one-agent-per-message dispatch, and fold the `msd-ultraplan-phase` plan-offload under the same gate. On Claude Code this restores the wave parallelism that backgrounded-agent nesting (#853) otherwise forces inline.
|
||||
|
||||
> **BETA.** This capability tracks a Claude Code preview surface. It is default-off, fail-closed, and Claude-only. Every detection miss degrades silently to today's inline behaviour — enabling it can never break the loop. See the [explanation doc](../explanation/claude-orchestration-capability.md) for the why, and [ADR-1143](../adr/1143-claude-orchestration-capability.md) for the design.
|
||||
|
||||
**What you need:**
|
||||
- GSD installed with the `full` profile (the capability is `tier: full`).
|
||||
- MSD installed with the `full` profile (the capability is `tier: full`).
|
||||
- **Claude Code** with the Workflow tool available (Agent SDK ≥ `0.3.149`). On any other runtime the capability is an explicit no-op — you can flip the switch safely, nothing happens.
|
||||
- A GSD project with at least one planned phase (you need a wave/plan manifest to emit a script for).
|
||||
- A MSD project with at least one planned phase (you need a wave/plan manifest to emit a script for).
|
||||
|
||||
---
|
||||
|
||||
## Step 1 — Enable the capability
|
||||
|
||||
The capability ships disabled. Turn on the master switch inside your GSD project:
|
||||
The capability ships disabled. Turn on the master switch inside your MSD project:
|
||||
|
||||
```bash
|
||||
gsd-tools query config-set claude_orchestration.enabled true
|
||||
msd-tools query config-set claude_orchestration.enabled true
|
||||
```
|
||||
|
||||
That single key gates everything — both the Workflow-backend hook at `execute:wave:post` and the ultraplan ownership declaration at `plan:post`. All other `claude_orchestration.*` keys are optional refinements.
|
||||
@@ -24,7 +24,7 @@ That single key gates everything — both the Workflow-backend hook at `execute:
|
||||
Verify it took:
|
||||
|
||||
```bash
|
||||
gsd-tools query config-get claude_orchestration.enabled
|
||||
msd-tools query config-get claude_orchestration.enabled
|
||||
# → true
|
||||
```
|
||||
|
||||
@@ -35,7 +35,7 @@ gsd-tools query config-get claude_orchestration.enabled
|
||||
Detection is fail-closed: the Workflow backend activates only when **every** gate opens. Before relying on it, confirm your runtime reports as capable:
|
||||
|
||||
```bash
|
||||
gsd-tools claude-orchestration detect-backend \
|
||||
msd-tools claude-orchestration detect-backend \
|
||||
--runtime claude \
|
||||
--agent-sdk-version 1.2.0
|
||||
```
|
||||
@@ -63,7 +63,7 @@ Work through the `reason`:
|
||||
If you want to gate the BETA behind a newer Agent SDK than the default:
|
||||
|
||||
```bash
|
||||
gsd-tools query config-set claude_orchestration.min_agent_sdk_version 1.0.0
|
||||
msd-tools query config-set claude_orchestration.min_agent_sdk_version 1.0.0
|
||||
```
|
||||
|
||||
---
|
||||
@@ -81,7 +81,7 @@ gsd-tools query config-set claude_orchestration.min_agent_sdk_version 1.0.0
|
||||
Switch with:
|
||||
|
||||
```bash
|
||||
gsd-tools query config-set claude_orchestration.execution_backend workflow
|
||||
msd-tools query config-set claude_orchestration.execution_backend workflow
|
||||
```
|
||||
|
||||
---
|
||||
@@ -107,35 +107,35 @@ With the capability enabled and detection passing, generate the Workflow script
|
||||
Emit the script:
|
||||
|
||||
```bash
|
||||
gsd-tools claude-orchestration emit-workflow \
|
||||
msd-tools claude-orchestration emit-workflow \
|
||||
--waves .planning/phases/01-foo/waves.json \
|
||||
--run-id phase-01-foo \
|
||||
--phase-dir .planning/phases/01-foo \
|
||||
--budget 500000
|
||||
```
|
||||
|
||||
The output is a generated Workflow script that maps GSD's model 1:1 onto Workflow primitives:
|
||||
The output is a generated Workflow script that maps MSD's model 1:1 onto Workflow primitives:
|
||||
|
||||
- an `export const meta = { name, description, phases }` block as the **first statement** (the Workflow tool rejects any script without it),
|
||||
- **waves → a `phase("Wave <id>")` group and a sequential `await parallel([...])` barrier** (split into separate stages within a wave when `files_modified` overlap),
|
||||
- **plans → `() => agent(brief, { agentType: "gsd-executor", isolation: "worktree" })`** — the **same** executor agent and worktree isolation the inline path uses, each wrapped in a thunk because `parallel()` takes an **array of functions**,
|
||||
- **plans → `() => agent(brief, { agentType: "msd-executor", isolation: "worktree" })`** — the **same** executor agent and worktree isolation the inline path uses, each wrapped in a thunk because `parallel()` takes an **array of functions**,
|
||||
- the phase run id in **`summary.resumeRunId`**, and the intended token pool in **`summary.budgetTokens`**.
|
||||
|
||||
`resumeFromRunId` and `budget` are **not** emitted as calls (#2590). `resumeFromRunId` is a Workflow **tool input**, and `budget` is a read-only object (`{ total, spent(), remaining() }`) fed by the caller's token directive — calling either from a script throws and the whole script is rejected.
|
||||
|
||||
Because the script composes the same `gsd-executor` agent + worktree isolation + `SUMMARY.md` artifact as the inline path, the artifacts and commits it produces are identical — only the execution vehicle differs.
|
||||
Because the script composes the same `msd-executor` agent + worktree isolation + `SUMMARY.md` artifact as the inline path, the artifacts and commits it produces are identical — only the execution vehicle differs.
|
||||
|
||||
### Run the emitted script
|
||||
|
||||
Feed the emitted script to Claude Code's Workflow tool (`/effort ultracode`, or an Agent SDK `Workflow` invocation), **passing `summary.resumeRunId` as the tool's `resumeFromRunId` input**. The orchestrator runs it; each `agent()` call spawns a `gsd-executor` in its own worktree, and waves barrier between each other. Omitting that input silently regresses phase-resume to a no-op — an interrupted phase re-runs completed plans.
|
||||
Feed the emitted script to Claude Code's Workflow tool (`/effort ultracode`, or an Agent SDK `Workflow` invocation), **passing `summary.resumeRunId` as the tool's `resumeFromRunId` input**. The orchestrator runs it; each `agent()` call spawns a `msd-executor` in its own worktree, and waves barrier between each other. Omitting that input silently regresses phase-resume to a no-op — an interrupted phase re-runs completed plans.
|
||||
|
||||
---
|
||||
|
||||
## Step 5 — Ultraplan plan-offload
|
||||
|
||||
Enabling the capability also folds `gsd-ultraplan-phase` under the same runtime gate. When the capability is on, the planner may offer the `/gsd-ultraplan-phase` path (offload plan-phase to Claude Code's ultraplan cloud) as an alternative to local `/gsd-plan-phase`. This is advisory — the stable local planner remains the default.
|
||||
Enabling the capability also folds `msd-ultraplan-phase` under the same runtime gate. When the capability is on, the planner may offer the `/msd-ultraplan-phase` path (offload plan-phase to Claude Code's ultraplan cloud) as an alternative to local `/msd-plan-phase`. This is advisory — the stable local planner remains the default.
|
||||
|
||||
If the capability is off, or the runtime is not Claude Code, ultraplan offload is not surfaced and `/gsd-plan-phase` runs as normal.
|
||||
If the capability is off, or the runtime is not Claude Code, ultraplan offload is not surfaced and `/msd-plan-phase` runs as normal.
|
||||
|
||||
---
|
||||
|
||||
@@ -144,13 +144,13 @@ If the capability is off, or the runtime is not Claude Code, ultraplan offload i
|
||||
To turn the capability off and return to byte-identical inline behaviour:
|
||||
|
||||
```bash
|
||||
gsd-tools query config-set claude_orchestration.enabled false
|
||||
msd-tools query config-set claude_orchestration.enabled false
|
||||
```
|
||||
|
||||
Or force inline dispatch while leaving the capability otherwise on:
|
||||
|
||||
```bash
|
||||
gsd-tools query config-set claude_orchestration.execution_backend inline
|
||||
msd-tools query config-set claude_orchestration.execution_backend inline
|
||||
```
|
||||
|
||||
Either step is sufficient — no uninstall or resurface needed. The federated config keys live only in the capability registry, so they vanish cleanly if the capability is ever removed.
|
||||
@@ -160,14 +160,14 @@ Either step is sufficient — no uninstall or resurface needed. The federated co
|
||||
## What is and is not wired in BETA v1
|
||||
|
||||
**Working today:**
|
||||
- Detection (`detectWorkflowBackend` / `gsd-tools claude-orchestration detect-backend`) — fail-closed, tested across every gate.
|
||||
- Emission (`emitWorkflowScript` / `gsd-tools claude-orchestration emit-workflow`) — waves→barriers, overlap→stages, resume, budget, anti-injection.
|
||||
- Detection (`detectWorkflowBackend` / `msd-tools claude-orchestration detect-backend`) — fail-closed, tested across every gate.
|
||||
- Emission (`emitWorkflowScript` / `msd-tools claude-orchestration emit-workflow`) — waves→barriers, overlap→stages, resume, budget, anti-injection.
|
||||
- The contribution fragments at `execute:wave:post` and `plan:post` (gated, `onError: skip`).
|
||||
- Inline fallback on every non-capable combination (regression-tested).
|
||||
|
||||
**Not yet wired (follow-ups):**
|
||||
- `execute-phase.md` does not yet auto-branch to emit-and-run the Workflow script. Today you emit the script explicitly (Step 4) and run it via the Workflow tool. Automatic dispatch inside the loop is the next milestone.
|
||||
- The plan-checker and verifier still run inline — this capability delivers the parallel-execution backend, not those gates.
|
||||
- Full install-profile migration of the `gsd-ultraplan-phase` skill into the capability's `skills[]` (it is currently declared in the manifest; the skill's own runtime gate continues to no-op on non-Claude runtimes).
|
||||
- Full install-profile migration of the `msd-ultraplan-phase` skill into the capability's `skills[]` (it is currently declared in the manifest; the skill's own runtime gate continues to no-op on non-Claude runtimes).
|
||||
|
||||
If a preview-API change breaks detection, the capability degrades to inline; it cannot destabilise the core loop.
|
||||
|
||||
@@ -8,14 +8,14 @@ the same time instead of one after another.
|
||||
## Before you start
|
||||
|
||||
This only matters if you already use chunked mode (`workflow.plan_chunked: true`, or
|
||||
`/gsd-plan-phase {N} --chunked`). Chunked mode splits planning into a short outline Task followed
|
||||
`/msd-plan-phase {N} --chunked`). Chunked mode splits planning into a short outline Task followed
|
||||
by one short Task per plan, committing each plan individually so an interrupted run resumes from
|
||||
the last committed plan. By default those per-plan Tasks still run one at a time.
|
||||
|
||||
## Enable it
|
||||
|
||||
```bash
|
||||
gsd config-set planning.chunked_parallel true
|
||||
msd config-set planning.chunked_parallel true
|
||||
```
|
||||
|
||||
```json
|
||||
@@ -29,7 +29,7 @@ gsd config-set planning.chunked_parallel true
|
||||
Then run chunked planning as usual:
|
||||
|
||||
```bash
|
||||
/gsd-plan-phase {N} --chunked
|
||||
/msd-plan-phase {N} --chunked
|
||||
```
|
||||
|
||||
That's it — no other setting to touch, and no other capability's config is involved.
|
||||
@@ -44,7 +44,7 @@ commit before starting, so cross-Wave ordering is unaffected.
|
||||
## Whether it actually does anything on your runtime
|
||||
|
||||
This setting is gated on the runtime's own negotiated concurrency ceiling
|
||||
(`gsd-tools query dispatch-capacity`), not on the config value alone:
|
||||
(`msd-tools query dispatch-capacity`), not on the config value alone:
|
||||
|
||||
- **Claude Code** declares a capacity above 1, so turning this on has a real effect there.
|
||||
- **Every other runtime today** (Codex, Cursor, OpenCode, ...) declares no concurrency ceiling and
|
||||
@@ -72,7 +72,7 @@ If either of those matters more to you than the speed-up, leave this setting at
|
||||
## Turn it off again
|
||||
|
||||
```bash
|
||||
gsd config-set planning.chunked_parallel false
|
||||
msd config-set planning.chunked_parallel false
|
||||
```
|
||||
|
||||
Or just remove the key from `.planning/config.json` — `false` is the default.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# How to enable cross-session memory with MemPalace
|
||||
|
||||
Give GSD durable memory across sessions and projects. When MemPalace is connected, GSD recalls prior decisions and patterns before you plan, and captures phase artifacts verbatim at each phase boundary.
|
||||
Give MSD durable memory across sessions and projects. When MemPalace is connected, MSD recalls prior decisions and patterns before you plan, and captures phase artifacts verbatim at each phase boundary.
|
||||
|
||||
**What you need:** [MemPalace](https://github.com/MemPalace/mempalace) installed locally. GSD never installs MemPalace for you — `pip install mempalace` is your action. A working MemPalace install is not required to complete GSD work; the capability is `onError: skip` at every hook, so an absent or unreachable MemPalace leaves the loop unchanged.
|
||||
**What you need:** [MemPalace](https://github.com/MemPalace/mempalace) installed locally. MSD never installs MemPalace for you — `pip install mempalace` is your action. A working MemPalace install is not required to complete MSD work; the capability is `onError: skip` at every hook, so an absent or unreachable MemPalace leaves the loop unchanged.
|
||||
|
||||
---
|
||||
|
||||
@@ -22,10 +22,10 @@ For interactive use (Claude Code), MemPalace's MCP server must be running so `me
|
||||
|
||||
## Step 2 — Enable the capability
|
||||
|
||||
Inside your GSD project:
|
||||
Inside your MSD project:
|
||||
|
||||
```bash
|
||||
gsd-tools query config-set mempalace.enabled true
|
||||
msd-tools query config-set mempalace.enabled true
|
||||
```
|
||||
|
||||
That is the only required step — `mempalace.enabled` is the master switch that gates all loop hooks. All other `mempalace.*` keys are optional refinements of the enabled behavior; they are honored at runtime by the skills, curator, and fragments.
|
||||
@@ -34,7 +34,7 @@ That is the only required step — `mempalace.enabled` is the master switch that
|
||||
|
||||
## Step 3 — Choose a memory mode
|
||||
|
||||
The `mempalace.memory_mode` key controls how authoritative MemPalace is during recall and capture — how tightly it couples to GSD's native memory (`.planning/graphs/`, STATE, learnings). All three modes are wired. Every mode is `onError: skip` and default-resilient: an unreachable palace degrades to native memory, and GSD keeps writing `.planning/graphs/`, so no mode risks memory loss.
|
||||
The `mempalace.memory_mode` key controls how authoritative MemPalace is during recall and capture — how tightly it couples to MSD's native memory (`.planning/graphs/`, STATE, learnings). All three modes are wired. Every mode is `onError: skip` and default-resilient: an unreachable palace degrades to native memory, and MSD keeps writing `.planning/graphs/`, so no mode risks memory loss.
|
||||
|
||||
| Mode | What it does | When to use it |
|
||||
|------|-------------|----------------|
|
||||
@@ -46,7 +46,7 @@ Set the mode with:
|
||||
|
||||
```bash
|
||||
# augment is the default; most users need no change.
|
||||
gsd-tools query config-set mempalace.memory_mode kg_backend # or: replace
|
||||
msd-tools query config-set mempalace.memory_mode kg_backend # or: replace
|
||||
```
|
||||
|
||||
> **Note — cross-mode migration.** Switching an established project to `kg_backend` or `replace` changes how *new* recall and capture resolve; it does **not** retro-migrate memory already written to `.planning/graphs/` into the palace. Backfilling existing native memory into the palace is a separate, not-yet-implemented concern — choose the mode you want at the start of a project for the cleanest result.
|
||||
@@ -57,21 +57,21 @@ gsd-tools query config-set mempalace.memory_mode kg_backend # or: replace
|
||||
|
||||
With `mempalace.enabled: true`, here is what you will see at each loop point:
|
||||
|
||||
**Discuss phase (`/gsd-discuss-phase`):**
|
||||
**Discuss phase (`/msd-discuss-phase`):**
|
||||
1. At `discuss:pre` — MemPalace recall fires: prior decisions, patterns, and surprises are surfaced as context before the discussion begins.
|
||||
2. At `discuss:post` — `CONTEXT.md` is filed into the `decisions` room in MemPalace.
|
||||
|
||||
**Plan phase (`/gsd-plan-phase`):**
|
||||
**Plan phase (`/msd-plan-phase`):**
|
||||
3. At `plan:pre` — a `MEMORY-RECALL.md` file appears in the phase directory containing prior decisions, patterns, and surprises retrieved from the palace.
|
||||
4. At `plan:post` — `PLAN.md` is filed into the `planning` room.
|
||||
|
||||
**Verify phase (`/gsd-verify-work`):**
|
||||
**Verify phase (`/msd-verify-work`):**
|
||||
5. At `verify:post` — `SUMMARY.md` is filed into `milestones` in MemPalace.
|
||||
|
||||
**Ship phase (`/gsd-ship`):**
|
||||
6. At `ship:post` — the `gsd-mempalace-curator` agent writes a diary entry and (if enabled) proposes cross-project tunnels.
|
||||
**Ship phase (`/msd-ship`):**
|
||||
6. At `ship:post` — the `msd-mempalace-curator` agent writes a diary entry and (if enabled) proposes cross-project tunnels.
|
||||
|
||||
**Execute phase (`/gsd-execute-phase`, each wave):**
|
||||
**Execute phase (`/msd-execute-phase`, each wave):**
|
||||
7. At `execute:wave:post` — confirmed problem→fix pairs are captured into the `problems` room via the `capture-problems` fragment.
|
||||
|
||||
If MemPalace is unreachable at any step, a skip-notice is written and the loop continues normally.
|
||||
@@ -84,13 +84,13 @@ If MemPalace is unreachable at any step, a skip-notice is written and the loop c
|
||||
|
||||
```bash
|
||||
# Disable recall injection at discuss:pre (keeps capture)
|
||||
gsd-tools query config-set mempalace.recall_on_discuss false
|
||||
msd-tools query config-set mempalace.recall_on_discuss false
|
||||
|
||||
# Disable the MEMORY-RECALL.md step at plan:pre
|
||||
gsd-tools query config-set mempalace.recall_on_plan false
|
||||
msd-tools query config-set mempalace.recall_on_plan false
|
||||
|
||||
# Disable artifact capture at phase boundaries
|
||||
gsd-tools query config-set mempalace.capture_artifacts false
|
||||
msd-tools query config-set mempalace.capture_artifacts false
|
||||
```
|
||||
|
||||
### Cross-project tunnels
|
||||
@@ -98,7 +98,7 @@ gsd-tools query config-set mempalace.capture_artifacts false
|
||||
Enable tunnel proposals at `ship:post` to connect related rooms across projects:
|
||||
|
||||
```bash
|
||||
gsd-tools query config-set mempalace.cross_project_tunnels true
|
||||
msd-tools query config-set mempalace.cross_project_tunnels true
|
||||
```
|
||||
|
||||
The curator agent will call `mempalace_find_tunnels` and propose connections to the wings it finds semantically related to this project's wing.
|
||||
@@ -109,7 +109,7 @@ The curator agent will call `mempalace_find_tunnels` and propose connections to
|
||||
|
||||
```bash
|
||||
# Not yet functional — reserved for a future release
|
||||
# gsd-tools query config-set mempalace.auto_capture_hooks true
|
||||
# msd-tools query config-set mempalace.auto_capture_hooks true
|
||||
```
|
||||
|
||||
### Override the wing name
|
||||
@@ -117,7 +117,7 @@ The curator agent will call `mempalace_find_tunnels` and propose connections to
|
||||
By default, the wing name derives from `project_code` or the project directory. Override it:
|
||||
|
||||
```bash
|
||||
gsd-tools query config-set mempalace.wing my-project-name
|
||||
msd-tools query config-set mempalace.wing my-project-name
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# How to enable live-DOM verification
|
||||
|
||||
Let GSD open a real browser and check a phase's UI acceptance criteria against the live DOM —
|
||||
Let MSD open a real browser and check a phase's UI acceptance criteria against the live DOM —
|
||||
during execution, not only after it — without widening what the plan executor can reach.
|
||||
|
||||
> **Default-off, and deliberately so.** A browser MCP server you configured for unrelated work
|
||||
@@ -10,7 +10,7 @@ during execution, not only after it — without widening what the plan executor
|
||||
|
||||
**What you need:**
|
||||
|
||||
- GSD installed with the `full` profile (the capability is `tier: full`).
|
||||
- MSD installed with the `full` profile (the capability is `tier: full`).
|
||||
- A browser MCP server registered in your runtime — either
|
||||
[`chrome-devtools-mcp`](https://github.com/ChromeDevTools/chrome-devtools-mcp) (exposes
|
||||
`mcp__chrome-devtools__*`) or Claude-in-Chrome (exposes `mcp__claude-in-chrome__*`).
|
||||
@@ -22,17 +22,17 @@ during execution, not only after it — without widening what the plan executor
|
||||
## Step 1 — Turn the key on
|
||||
|
||||
```bash
|
||||
gsd-tools query config-set workflow.live_dom_uat true
|
||||
msd-tools query config-set workflow.live_dom_uat true
|
||||
```
|
||||
|
||||
Verify it took:
|
||||
|
||||
```bash
|
||||
gsd-tools query config-get workflow.live_dom_uat
|
||||
msd-tools query config-get workflow.live_dom_uat
|
||||
# → true
|
||||
```
|
||||
|
||||
That one key gates both halves: the `gsd-dom-verifier` step that runs after each execution
|
||||
That one key gates both halves: the `msd-dom-verifier` step that runs after each execution
|
||||
wave, and the extra browser families the orchestrator's own UI-verification step will consider.
|
||||
With it off, neither reaches a browser.
|
||||
|
||||
@@ -47,9 +47,9 @@ With it off, neither reaches a browser.
|
||||
The browser is already running for <dir>. Use --isolated to run multiple browser instances.
|
||||
```
|
||||
|
||||
GSD runs execution waves in parallel, so two verifiers can reach for one profile. **GSD cannot
|
||||
MSD runs execution waves in parallel, so two verifiers can reach for one profile. **MSD cannot
|
||||
fix this for you** — `--isolated` is a flag on *your* MCP server registration, not something
|
||||
GSD passes. Add it there:
|
||||
MSD passes. Add it there:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
@@ -72,7 +72,7 @@ lost the race, never a failed wave.
|
||||
|
||||
## Step 3 — Run a phase and read the report
|
||||
|
||||
Execute normally. After each wave, `gsd-dom-verifier` writes
|
||||
Execute normally. After each wave, `msd-dom-verifier` writes
|
||||
`.planning/phases/<phase>/<n>-DOM-VERIFY.md`:
|
||||
|
||||
```markdown
|
||||
@@ -114,8 +114,8 @@ found nothing to check.
|
||||
|
||||
- **It never blocks.** The step is advisory by construction — it cannot fail a task, fail a
|
||||
wave, or stop a phase. Findings are findings; the executor still owns task outcomes.
|
||||
- **It does not widen the executor.** `gsd-executor` carries no browser tools in any
|
||||
configuration. The browser reach lives in `gsd-dom-verifier` alone.
|
||||
- **It does not widen the executor.** `msd-executor` carries no browser tools in any
|
||||
configuration. The browser reach lives in `msd-dom-verifier` alone.
|
||||
- **It does not sandbox the browser.** Once the key is on there is no domain allowlist and
|
||||
nothing inspects what a page fetched. Turn it on for projects where that is acceptable.
|
||||
- **It observes the DOM only.** No screenshot diffing, no accessibility audit, no performance
|
||||
@@ -126,7 +126,7 @@ found nothing to check.
|
||||
## Turning it back off
|
||||
|
||||
```bash
|
||||
gsd-tools query config-set workflow.live_dom_uat false
|
||||
msd-tools query config-set workflow.live_dom_uat false
|
||||
```
|
||||
|
||||
The capability resolves inactive immediately and the hook stops rendering. See
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# How to enable parallel reviewer lanes
|
||||
|
||||
Cut the wall-clock cost of a multi-reviewer `/gsd-review` pass from the sum of its lanes toward
|
||||
Cut the wall-clock cost of a multi-reviewer `/msd-review` pass from the sum of its lanes toward
|
||||
its slowest lane — without losing the rate-limit protection the sequential default exists to
|
||||
provide.
|
||||
|
||||
@@ -23,7 +23,7 @@ provide.
|
||||
Parallelism only helps if several lanes are selected. Confirm the set first:
|
||||
|
||||
```bash
|
||||
gsd config-get review.default_reviewers
|
||||
msd config-get review.default_reviewers
|
||||
```
|
||||
|
||||
If that returns `Key not found`, no-flag runs use every detected reviewer and `--all` is
|
||||
@@ -34,13 +34,13 @@ redundant. If it names a single reviewer, stop here — enabling the key would c
|
||||
## Step 2 — Turn the key on
|
||||
|
||||
```bash
|
||||
gsd config-set review.parallel_lanes true
|
||||
msd config-set review.parallel_lanes true
|
||||
```
|
||||
|
||||
Verify it took:
|
||||
|
||||
```bash
|
||||
gsd config-get review.parallel_lanes --raw
|
||||
msd config-get review.parallel_lanes --raw
|
||||
# → true
|
||||
```
|
||||
|
||||
@@ -54,13 +54,13 @@ rate-limited provider. If `config-get` shows anything other than `true`, the set
|
||||
## Step 3 — Run a review and read the result
|
||||
|
||||
```bash
|
||||
/gsd-review --phase 3 --all
|
||||
/msd-review --phase 3 --all
|
||||
```
|
||||
|
||||
or, for the convergence loop:
|
||||
|
||||
```bash
|
||||
/gsd-plan-review-convergence 3 --all
|
||||
/msd-plan-review-convergence 3 --all
|
||||
```
|
||||
|
||||
Open `{phase_dir}/{padded_phase}-REVIEWS.md` and check the `reviewers:` frontmatter list. Every
|
||||
@@ -76,7 +76,7 @@ non-empty `.err` file are preserved beside the phase's artifacts before the run'
|
||||
so a missing `REVIEWS.md` is diagnosable, not silent — see the table below for what a *partial*
|
||||
failure (some, not all, lanes down) looks like instead.
|
||||
|
||||
Section order in `REVIEWS.md`, and line order in the run's `gsd-review-lane-results.jsonl`, are
|
||||
Section order in `REVIEWS.md`, and line order in the run's `msd-review-lane-results.jsonl`, are
|
||||
unchanged from sequential dispatch. They follow reviewer-selection order, not completion order,
|
||||
so a diff of two runs shows no reordering churn.
|
||||
|
||||
@@ -106,7 +106,7 @@ review by its header. It is not silently dropped and it does not abort its sibli
|
||||
## Turning it back off
|
||||
|
||||
```bash
|
||||
gsd config-set review.parallel_lanes false
|
||||
msd config-set review.parallel_lanes false
|
||||
```
|
||||
|
||||
The next pass dispatches sequentially again. Nothing else changes: no artifact written under the
|
||||
@@ -116,7 +116,7 @@ parallel setting needs migrating, because the output layout is identical in both
|
||||
|
||||
## What this does not speed up
|
||||
|
||||
**Convergence cycles stay sequential.** `/gsd-plan-review-convergence` runs
|
||||
**Convergence cycles stay sequential.** `/msd-plan-review-convergence` runs
|
||||
`plan-phase → review → replan → re-review`, and each cycle genuinely depends on the previous
|
||||
one's output. Enabling this key makes each *review pass* inside a cycle faster; it does not
|
||||
reduce the number of cycles, and it does not overlap planning with reviewing. A three-cycle
|
||||
@@ -127,13 +127,13 @@ means eleven concurrent requests. If that is more than you want, the control is
|
||||
selected set — `review.default_reviewers` or explicit flags — not a throttle on this setting.
|
||||
|
||||
**Reviewer instances sharing an adapter are not grouped.** Two
|
||||
[`review.reviewer_instances`](../CONFIGURATION.md#reviewer-instances-for-gsd-review-1517) entries
|
||||
[`review.reviewer_instances`](../CONFIGURATION.md#reviewer-instances-for-msd-review-1517) entries
|
||||
backed by the same CLI dispatch concurrently against that one provider. If you run several
|
||||
same-provider instances, you are the most likely configuration to hit a limit, and this setting
|
||||
gives you no way to serialize just those.
|
||||
|
||||
---
|
||||
|
||||
**See also:** [Configuration reference](../CONFIGURATION.md#parallel-reviewer-lanes-for-gsd-review-3034)
|
||||
· [Reviewer instances](../CONFIGURATION.md#reviewer-instances-for-gsd-review-1517)
|
||||
· [`/gsd-review` command reference](../COMMANDS.md)
|
||||
**See also:** [Configuration reference](../CONFIGURATION.md#parallel-reviewer-lanes-for-msd-review-3034)
|
||||
· [Reviewer instances](../CONFIGURATION.md#reviewer-instances-for-msd-review-1517)
|
||||
· [`/msd-review` command reference](../COMMANDS.md)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# How to enable UI interaction capture
|
||||
|
||||
Let `/gsd-ui-review`'s auditor capture what a page looks like *after* an interaction — a hover
|
||||
Let `/msd-ui-review`'s auditor capture what a page looks like *after* an interaction — a hover
|
||||
state, a focus ring, an open menu, a filled form's validation state — instead of only the first
|
||||
paint, without configuring an MCP server or widening the agent's tool surface.
|
||||
|
||||
@@ -34,17 +34,17 @@ paint, without configuring an MCP server or widening the agent's tool surface.
|
||||
## Step 1 — Turn the key on
|
||||
|
||||
```bash
|
||||
gsd-tools query config-set workflow.ui_interaction_capture true
|
||||
msd-tools query config-set workflow.ui_interaction_capture true
|
||||
```
|
||||
|
||||
Verify it took:
|
||||
|
||||
```bash
|
||||
gsd-tools query config-get workflow.ui_interaction_capture
|
||||
msd-tools query config-get workflow.ui_interaction_capture
|
||||
# → true
|
||||
```
|
||||
|
||||
`/gsd-ui-review` reads the key and passes `interaction_capture: true` in the auditor's
|
||||
`/msd-ui-review` reads the key and passes `interaction_capture: true` in the auditor's
|
||||
`<config>` block — the auditor itself never reads config.
|
||||
|
||||
---
|
||||
@@ -52,7 +52,7 @@ gsd-tools query config-get workflow.ui_interaction_capture
|
||||
## Step 2 — Run a review and read the report
|
||||
|
||||
```bash
|
||||
/gsd-ui-review 3
|
||||
/msd-ui-review 3
|
||||
```
|
||||
|
||||
The audit's static captures land where they always did. With the key on and a Chrome
|
||||
@@ -88,7 +88,7 @@ Experience Design pillar says when its findings are code-derived.
|
||||
the three viewport shots; it has `--wait-for-selector`, `--device`, `--color-scheme` and
|
||||
cross-engine `-b firefox|webkit`, none of which the CLI driver offers. Firefox and WebKit needs
|
||||
stay on Playwright.
|
||||
- **It does not touch `gsd-dom-verifier` or `workflow.live_dom_uat`.** That capability drives a
|
||||
- **It does not touch `msd-dom-verifier` or `workflow.live_dom_uat`.** That capability drives a
|
||||
browser MCP server at execute time; this one drives a CLI from Bash at review time. They are
|
||||
independent keys.
|
||||
- **It does not share the `chrome-devtools-mcp` browser profile.** The auditor starts the daemon
|
||||
@@ -105,7 +105,7 @@ Experience Design pillar says when its findings are code-derived.
|
||||
## Turning it back off
|
||||
|
||||
```bash
|
||||
gsd-tools query config-set workflow.ui_interaction_capture false
|
||||
msd-tools query config-set workflow.ui_interaction_capture false
|
||||
```
|
||||
|
||||
The next review runs the Playwright-only path and reports `**Interaction captures:** off`.
|
||||
|
||||
@@ -2,19 +2,19 @@
|
||||
|
||||
**Goal:** Run a planned phase through wave-based parallel execution and land every plan as an atomic git commit.
|
||||
|
||||
**Prerequisites:** The phase has at least one `PLAN.md` file. If planning is not yet done, run `/gsd-plan-phase N` first — see [Plan a phase](plan-a-phase.md).
|
||||
**Prerequisites:** The phase has at least one `PLAN.md` file. If planning is not yet done, run `/msd-plan-phase N` first — see [Plan a phase](plan-a-phase.md).
|
||||
|
||||
---
|
||||
|
||||
## Run the full phase
|
||||
|
||||
```bash
|
||||
/gsd-execute-phase 1
|
||||
/msd-execute-phase 1
|
||||
```
|
||||
|
||||
GSD reads the phase's plan files, groups them into dependency waves, and spawns a fresh executor agent per plan. Each executor commits its work atomically before the next wave begins.
|
||||
MSD reads the phase's plan files, groups them into dependency waves, and spawns a fresh executor agent per plan. Each executor commits its work atomically before the next wave begins.
|
||||
|
||||
Before any agents are dispatched, GSD prints a wave table:
|
||||
Before any agents are dispatched, MSD prints a wave table:
|
||||
|
||||
```
|
||||
## Execution Plan
|
||||
@@ -38,24 +38,24 @@ For the underlying agent coordination model, see [Multi-agent orchestration](../
|
||||
If you want to execute only one wave — for example, to inspect Wave 1 output before committing to Wave 2 — use `--wave N`:
|
||||
|
||||
```bash
|
||||
/gsd-execute-phase 1 --wave 2
|
||||
/msd-execute-phase 1 --wave 2
|
||||
```
|
||||
|
||||
GSD executes only Wave 2 plans. It first checks that all earlier waves are complete; if any Wave 1 plan is still marked incomplete, it stops and tells you to finish earlier waves first.
|
||||
MSD executes only Wave 2 plans. It first checks that all earlier waves are complete; if any Wave 1 plan is still marked incomplete, it stops and tells you to finish earlier waves first.
|
||||
|
||||
---
|
||||
|
||||
## Resume a stalled execution
|
||||
|
||||
If execution stops partway through — a quota error, a network drop, or a crashed session — the wave-level progress is preserved. GSD checks for a `SUMMARY.md` file for each plan; plans that have one are skipped automatically when you re-run:
|
||||
If execution stops partway through — a quota error, a network drop, or a crashed session — the wave-level progress is preserved. MSD checks for a `SUMMARY.md` file for each plan; plans that have one are skipped automatically when you re-run:
|
||||
|
||||
```bash
|
||||
/gsd-execute-phase 1
|
||||
/msd-execute-phase 1
|
||||
```
|
||||
|
||||
GSD will skip plans where `SUMMARY.md` already exists and pick up from the first incomplete plan.
|
||||
MSD will skip plans where `SUMMARY.md` already exists and pick up from the first incomplete plan.
|
||||
|
||||
**If commits exist but `SUMMARY.md` is missing** (the executor committed but did not write its summary before the session died), GSD surfaces a safe-resume gate and offers three options:
|
||||
**If commits exist but `SUMMARY.md` is missing** (the executor committed but did not write its summary before the session died), MSD surfaces a safe-resume gate and offers three options:
|
||||
|
||||
- `close out manually` — inspect the commits, write `SUMMARY.md`, then re-run.
|
||||
- `re-execute from scratch` — revert or supersede the partial commits before dispatching a new executor.
|
||||
@@ -88,13 +88,13 @@ Git history will show one commit per task (from each executor), followed by trac
|
||||
To delegate execution to an external AI CLI (Codex, Antigravity, etc.) configured in `workflow.cross_ai_command`:
|
||||
|
||||
```bash
|
||||
/gsd-execute-phase 2 --cross-ai
|
||||
/msd-execute-phase 2 --cross-ai
|
||||
```
|
||||
|
||||
To force local execution even when cross-AI is enabled in config:
|
||||
|
||||
```bash
|
||||
/gsd-execute-phase 2 --no-cross-ai
|
||||
/msd-execute-phase 2 --no-cross-ai
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
# How to fix the worktree base-mismatch (exit 42) error
|
||||
|
||||
**Goal:** Understand why `/gsd-execute-phase` or `/gsd-quick` halts with `FATAL: worktree base mismatch` / exit 42 when your branch is ahead of the default branch, and choose the right fix to restore normal — or parallel — execution.
|
||||
**Goal:** Understand why `/msd-execute-phase` or `/msd-quick` halts with `FATAL: worktree base mismatch` / exit 42 when your branch is ahead of the default branch, and choose the right fix to restore normal — or parallel — execution.
|
||||
|
||||
**Prerequisites:** GSD Core is installed and you have an active project. You have run `/gsd-execute-phase` or `/gsd-quick` and either seen the exit-42 error or the one-line `⚠ Worktree base mismatch` warning.
|
||||
**Prerequisites:** MSD Core is installed and you have an active project. You have run `/msd-execute-phase` or `/msd-quick` and either seen the exit-42 error or the one-line `⚠ Worktree base mismatch` warning.
|
||||
|
||||
---
|
||||
|
||||
## What you will see
|
||||
|
||||
When you run `/gsd-execute-phase` or `/gsd-quick` on a branch that is ahead of the repository's default branch (for example, an unmerged milestone branch, a long-lived feature branch, or a branch with commits not yet in `origin/HEAD`), you may see one of two messages:
|
||||
When you run `/msd-execute-phase` or `/msd-quick` on a branch that is ahead of the repository's default branch (for example, an unmerged milestone branch, a long-lived feature branch, or a branch with commits not yet in `origin/HEAD`), you may see one of two messages:
|
||||
|
||||
**Automatic-degrade warning (phase or quick task still completes):**
|
||||
|
||||
@@ -17,10 +17,10 @@ When you run `/gsd-execute-phase` or `/gsd-quick` on a branch that is ahead of t
|
||||
Running this phase sequentially on the main working tree. Parallel worktrees
|
||||
return once HEAD is merged/pushed so origin/HEAD matches it, or set
|
||||
worktree.baseRef:"head" to fork worktrees from HEAD instead (honored by
|
||||
GSD-created worktrees and by the Claude Code harness; #683, #4588).
|
||||
MSD-created worktrees and by the Claude Code harness; #683, #4588).
|
||||
```
|
||||
|
||||
The phase or quick task runs to completion sequentially; nothing is blocked. This is the runtime mitigation (`/gsd-execute-phase`: #683/#1369; `/gsd-quick`: #1941).
|
||||
The phase or quick task runs to completion sequentially; nothing is blocked. This is the runtime mitigation (`/msd-execute-phase`: #683/#1369; `/msd-quick`: #1941).
|
||||
|
||||
**Exit-42 halt (older installs or misconfigured environments):**
|
||||
|
||||
@@ -34,7 +34,7 @@ All worktree-isolated executors halt immediately. Zero progress is made.
|
||||
|
||||
## Why this happens
|
||||
|
||||
Unless `worktree.baseRef` is set to `"head"`, Claude Code's `isolation="worktree"` forks executor worktrees from the repository's default branch (`origin/HEAD`), not from your current `HEAD`. When your branch contains commits that `origin/HEAD` does not have — plan files, new source files, anything added since the branch diverged — those files are absent inside each worktree. GSD's `worktree-branch-check` safety guard correctly refuses to act on a worktree that does not match the orchestrator's state, and exits with code 42.
|
||||
Unless `worktree.baseRef` is set to `"head"`, Claude Code's `isolation="worktree"` forks executor worktrees from the repository's default branch (`origin/HEAD`), not from your current `HEAD`. When your branch contains commits that `origin/HEAD` does not have — plan files, new source files, anything added since the branch diverged — those files are absent inside each worktree. MSD's `worktree-branch-check` safety guard correctly refuses to act on a worktree that does not match the orchestrator's state, and exits with code 42.
|
||||
|
||||
This is the guard working as designed: it prevents silent data loss or phantom edits in the wrong tree. The error is a branch-state condition, not an OS-specific or hardware issue.
|
||||
|
||||
@@ -42,7 +42,7 @@ This is the guard working as designed: it prevents silent data loss or phantom e
|
||||
|
||||
## Option 1 — Do nothing (you are already unblocked)
|
||||
|
||||
If you saw the `⚠ Worktree base mismatch` warning rather than an exit-42 halt, GSD has already automatically degraded to sequential execution on the main working tree for this run. The phase will complete. No action is required.
|
||||
If you saw the `⚠ Worktree base mismatch` warning rather than an exit-42 halt, MSD has already automatically degraded to sequential execution on the main working tree for this run. The phase will complete. No action is required.
|
||||
|
||||
Use this option when:
|
||||
|
||||
@@ -56,24 +56,24 @@ Use this option when:
|
||||
|
||||
**What this setting does (#3659, #4588):** it makes new worktrees fork from your current `HEAD`
|
||||
instead of `origin/HEAD`, so the files your branch added are present inside each executor
|
||||
worktree and the wave can run in parallel. It is honored by GSD-created worktrees by construction
|
||||
worktree and the wave can run in parallel. It is honored by MSD-created worktrees by construction
|
||||
and, as measured, by Claude Code's harness:
|
||||
|
||||
- **Runtimes where GSD itself runs `git worktree add <path> <start-point>`** (Codex, OpenCode,
|
||||
- **Runtimes where MSD itself runs `git worktree add <path> <start-point>`** (Codex, OpenCode,
|
||||
Kimi, Kimi Code) — by construction; the check suppresses on it (`reason: "baseref-head"`).
|
||||
- **Claude Code's `Agent(isolation="worktree")`** — because the harness reads the setting and
|
||||
forks from `HEAD`. This was measured on current Claude Code from the project-local,
|
||||
project-shared and user/global settings layers on macOS, Windows and Linux (#4588). Cursor,
|
||||
the other runtime whose harness creates the worktree, has not been measured — see below. An earlier finding that the harness did *not* read it (#48,
|
||||
verified against the Claude Code of the time; upstream claude-code#44965) was fixed upstream in
|
||||
claude-code#54940, but until #4588 GSD's pre-dispatch check still assumed it and degraded every
|
||||
claude-code#54940, but until #4588 MSD's pre-dispatch check still assumed it and degraded every
|
||||
wave on an unmerged branch regardless of the setting — the `baseref-head-ignored-by-harness`
|
||||
reason you may have seen on older installs.
|
||||
|
||||
Run the convenience command from your project root:
|
||||
|
||||
```bash
|
||||
node "$HOME/.claude/gsd-core/bin/gsd-tools.cjs" worktree set-baseref
|
||||
node "$HOME/.claude/msd-core/bin/msd-tools.cjs" worktree set-baseref
|
||||
```
|
||||
|
||||
This writes `worktree.baseRef: "head"` into `.claude/settings.local.json` in your project root. It is no-clobber: if you already have an explicit `baseRef` set to something else, it leaves your value in place and tells you.
|
||||
@@ -81,7 +81,7 @@ This writes `worktree.baseRef: "head"` into `.claude/settings.local.json` in you
|
||||
To verify the result, pass the dispatch mode the runtime uses:
|
||||
|
||||
```bash
|
||||
node "$HOME/.claude/gsd-core/bin/gsd-tools.cjs" worktree base-check --mode harness-worktree
|
||||
node "$HOME/.claude/msd-core/bin/msd-tools.cjs" worktree base-check --mode harness-worktree
|
||||
```
|
||||
|
||||
The output is JSON. With the setting in place expect `shouldDegrade: false` with
|
||||
@@ -111,7 +111,7 @@ inside a freshly created isolated worktree, before any commit — the full sha,
|
||||
pass it and the check evaluates that instead of inferring:
|
||||
|
||||
```bash
|
||||
node "$HOME/.claude/gsd-core/bin/gsd-tools.cjs" worktree base-check --observed-fork-base <sha>
|
||||
node "$HOME/.claude/msd-core/bin/msd-tools.cjs" worktree base-check --observed-fork-base <sha>
|
||||
```
|
||||
|
||||
A match returns `reason: "observed-fork-matches-head"`; a mismatch with `"head"` set returns
|
||||
@@ -134,7 +134,7 @@ Alternatively, set the value by hand in `.claude/settings.local.json`:
|
||||
}
|
||||
```
|
||||
|
||||
**Note:** Fresh installs and upgrades of GSD Core both set `worktree.baseRef:"head"` automatically in `.claude/settings.local.json` (no-clobber) when `workflow.use_worktrees` is enabled (the default). If you see the degrade warning on a fresh install, check that the key is still present — a hand-edited `settings.local.json` is the usual reason it is not.
|
||||
**Note:** Fresh installs and upgrades of MSD Core both set `worktree.baseRef:"head"` automatically in `.claude/settings.local.json` (no-clobber) when `workflow.use_worktrees` is enabled (the default). If you see the degrade warning on a fresh install, check that the key is still present — a hand-edited `settings.local.json` is the usual reason it is not.
|
||||
|
||||
Use this option when:
|
||||
|
||||
@@ -171,7 +171,7 @@ See also: [`workflow.use_worktrees`](../CONFIGURATION.md#workflow-toggles) in th
|
||||
|
||||
## The exit-42 backstop
|
||||
|
||||
The `worktree-branch-check` guard (exit 42) remains active in all execution modes as a safety backstop. It fires only when an executor worktree's branch does not match the expected orchestrator state — a condition that should not arise once you have applied one of the options above. It is also the observation-based check behind Option 2: with `worktree.baseRef: "head"` set, the pre-dispatch check trusts the setting and does not compare, so a host that does *not* honor it is caught here — the mismatched executors of that dispatch halt (every one of them, in a concurrent wave), and nothing is merged. If you continue to see exit 42 after setting `worktree.baseRef: "head"`, your runtime is forking from somewhere other than `HEAD`; run `/gsd-forensics` to investigate, and pass the SHA the halted executor printed as `--observed-fork-base` to `worktree base-check` to see the verdict GSD would reach with that measurement.
|
||||
The `worktree-branch-check` guard (exit 42) remains active in all execution modes as a safety backstop. It fires only when an executor worktree's branch does not match the expected orchestrator state — a condition that should not arise once you have applied one of the options above. It is also the observation-based check behind Option 2: with `worktree.baseRef: "head"` set, the pre-dispatch check trusts the setting and does not compare, so a host that does *not* honor it is caught here — the mismatched executors of that dispatch halt (every one of them, in a concurrent wave), and nothing is merged. If you continue to see exit 42 after setting `worktree.baseRef: "head"`, your runtime is forking from somewhere other than `HEAD`; run `/msd-forensics` to investigate, and pass the SHA the halted executor printed as `--observed-fork-base` to `worktree base-check` to see the verdict MSD would reach with that measurement.
|
||||
|
||||
---
|
||||
|
||||
@@ -182,7 +182,7 @@ The `worktree-branch-check` guard (exit 42) remains active in all execution mode
|
||||
| Saw the warning, phase completed | Nothing — degrade handled it automatically |
|
||||
| Regularly on diverged branches, want parallel execution | `worktree set-baseref` (Option 2) |
|
||||
| Worktrees consistently problematic | Set `workflow.use_worktrees: false` (Option 3) |
|
||||
| Still seeing exit 42 after fixes | Run `/gsd-forensics "exit 42 after fix"` |
|
||||
| Still seeing exit 42 after fixes | Run `/msd-forensics "exit 42 after fix"` |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# How to handle quick and fast tasks
|
||||
|
||||
Not every piece of work fits inside a phase. GSD provides two lightweight commands for work that does not need the full discuss → plan → execute → verify loop.
|
||||
Not every piece of work fits inside a phase. MSD provides two lightweight commands for work that does not need the full discuss → plan → execute → verify loop.
|
||||
|
||||
For context on when the full phase pipeline is worth its overhead, see [Context engineering](../explanation/context-engineering.md).
|
||||
|
||||
@@ -10,30 +10,30 @@ For context on when the full phase pipeline is worth its overhead, see [Context
|
||||
|
||||
| Situation | Command |
|
||||
|-----------|---------|
|
||||
| Fixing a bug, adding a small feature, or any task you cannot summarise as a single trivial edit | `/gsd-quick` |
|
||||
| Fixing a typo, updating a config value, adding a `.gitignore` entry, or any change that touches ≤ 3 files and takes under a minute | `/gsd-fast` |
|
||||
| The task has unknowns, needs research, or will touch more than a handful of files | `/gsd-quick` with `--research` |
|
||||
| Fixing a bug, adding a small feature, or any task you cannot summarise as a single trivial edit | `/msd-quick` |
|
||||
| Fixing a typo, updating a config value, adding a `.gitignore` entry, or any change that touches ≤ 3 files and takes under a minute | `/msd-fast` |
|
||||
| The task has unknowns, needs research, or will touch more than a handful of files | `/msd-quick` with `--research` |
|
||||
|
||||
**The rule of thumb:** if you hesitate for even a moment about whether the task is trivial, use `/gsd-quick`. `/gsd-fast` redirects you to `/gsd-quick` automatically if the scope looks non-trivial.
|
||||
**The rule of thumb:** if you hesitate for even a moment about whether the task is trivial, use `/msd-quick`. `/msd-fast` redirects you to `/msd-quick` automatically if the scope looks non-trivial.
|
||||
|
||||
---
|
||||
|
||||
## `/gsd-quick` — ad-hoc tasks with GSD guarantees
|
||||
## `/msd-quick` — ad-hoc tasks with MSD guarantees
|
||||
|
||||
`/gsd-quick` runs a planner and executor with the same atomic-commit and STATE.md tracking guarantees as a full phase, but without the phase overhead (no ROADMAP entry, no discuss-phase, no wave coordination across multiple plans).
|
||||
`/msd-quick` runs a planner and executor with the same atomic-commit and STATE.md tracking guarantees as a full phase, but without the phase overhead (no ROADMAP entry, no discuss-phase, no wave coordination across multiple plans).
|
||||
|
||||
### Basic use
|
||||
|
||||
```bash
|
||||
/gsd-quick
|
||||
/msd-quick
|
||||
```
|
||||
|
||||
GSD prompts you for a task description, then plans and executes it. Artifacts land in `.planning/quick/`.
|
||||
MSD prompts you for a task description, then plans and executes it. Artifacts land in `.planning/quick/`.
|
||||
|
||||
You can also pass the description directly:
|
||||
|
||||
```bash
|
||||
/gsd-quick "Fix the login button not responding on mobile Safari"
|
||||
/msd-quick "Fix the login button not responding on mobile Safari"
|
||||
```
|
||||
|
||||
### Flags
|
||||
@@ -50,9 +50,9 @@ Add flags to bring in more of the quality pipeline when the task warrants it.
|
||||
Flags compose freely:
|
||||
|
||||
```bash
|
||||
/gsd-quick --research --validate # research + plan-checking + verification, no discuss
|
||||
/gsd-quick --discuss # just surface grey areas before planning
|
||||
/gsd-quick --full # the complete quality pipeline
|
||||
/msd-quick --research --validate # research + plan-checking + verification, no discuss
|
||||
/msd-quick --discuss # just surface grey areas before planning
|
||||
/msd-quick --full # the complete quality pipeline
|
||||
```
|
||||
|
||||
### When to add flags
|
||||
@@ -65,38 +65,38 @@ Flags compose freely:
|
||||
### Listing and resuming quick tasks
|
||||
|
||||
```bash
|
||||
/gsd-quick list # show all quick tasks with status
|
||||
/gsd-quick status my-task-slug # show status of a specific task
|
||||
/gsd-quick resume my-task-slug # resume an interrupted task
|
||||
/msd-quick list # show all quick tasks with status
|
||||
/msd-quick status my-task-slug # show status of a specific task
|
||||
/msd-quick resume my-task-slug # resume an interrupted task
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## `/gsd-fast` — inline trivial edits
|
||||
## `/msd-fast` — inline trivial edits
|
||||
|
||||
`/gsd-fast` does the work directly in the current context. There are no subagents, no `PLAN.md`, and no research. It is suitable only for changes you could make yourself in under a minute.
|
||||
`/msd-fast` does the work directly in the current context. There are no subagents, no `PLAN.md`, and no research. It is suitable only for changes you could make yourself in under a minute.
|
||||
|
||||
```bash
|
||||
/gsd-fast "fix typo in README"
|
||||
/gsd-fast "add .env to .gitignore"
|
||||
/msd-fast "fix typo in README"
|
||||
/msd-fast "add .env to .gitignore"
|
||||
```
|
||||
|
||||
If you omit the description, GSD prompts you for it.
|
||||
If you omit the description, MSD prompts you for it.
|
||||
|
||||
`/gsd-fast` checks whether the task is actually trivial before proceeding. If it judges the scope too large it stops and redirects you:
|
||||
`/msd-fast` checks whether the task is actually trivial before proceeding. If it judges the scope too large it stops and redirects you:
|
||||
|
||||
```text
|
||||
This looks like it needs planning. Use /gsd-quick instead:
|
||||
/gsd-quick "your task description"
|
||||
This looks like it needs planning. Use /msd-quick instead:
|
||||
/msd-quick "your task description"
|
||||
```
|
||||
|
||||
After making the change, `/gsd-fast` commits atomically and, if a `Quick Tasks Completed` table exists in `.planning/STATE.md`, appends a row to it.
|
||||
After making the change, `/msd-fast` commits atomically and, if a `Quick Tasks Completed` table exists in `.planning/STATE.md`, appends a row to it.
|
||||
|
||||
---
|
||||
|
||||
## What `/gsd-quick` does that `/gsd-fast` does not
|
||||
## What `/msd-quick` does that `/msd-fast` does not
|
||||
|
||||
| Capability | `/gsd-fast` | `/gsd-quick` |
|
||||
| Capability | `/msd-fast` | `/msd-quick` |
|
||||
|------------|------------|--------------|
|
||||
| Subagent planner | No | Yes |
|
||||
| Subagent executor | No | Yes |
|
||||
@@ -109,19 +109,19 @@ After making the change, `/gsd-fast` commits atomically and, if a `Quick Tasks C
|
||||
| STATE.md tracking | Row appended if table exists | Always updated |
|
||||
| `.planning/quick/` artifacts | No | Yes |
|
||||
|
||||
The key distinction is subagent isolation. `/gsd-quick` spawns a fresh planner and executor in separate context windows, which means the work is planned properly, commits are atomic per task, and the orchestrator can verify results. `/gsd-fast` uses only the current context window and is intentionally limited to changes trivial enough not to need any of that.
|
||||
The key distinction is subagent isolation. `/msd-quick` spawns a fresh planner and executor in separate context windows, which means the work is planned properly, commits are atomic per task, and the orchestrator can verify results. `/msd-fast` uses only the current context window and is intentionally limited to changes trivial enough not to need any of that.
|
||||
|
||||
---
|
||||
|
||||
## Archiving quick tasks
|
||||
|
||||
`.planning/quick/` accumulates one directory per `/gsd-quick` task forever unless you archive it. Archival is **opt-in** (#2142) — it deliberately does not mirror phase-directory archival, which is default-ON. Do nothing and `.planning/quick/` stays exactly as it is.
|
||||
`.planning/quick/` accumulates one directory per `/msd-quick` task forever unless you archive it. Archival is **opt-in** (#2142) — it deliberately does not mirror phase-directory archival, which is default-ON. Do nothing and `.planning/quick/` stays exactly as it is.
|
||||
|
||||
There are two paths in, depending on when you archive:
|
||||
|
||||
### Forward path — archive at milestone close-out
|
||||
|
||||
When you run `/gsd-complete-milestone` and `.planning/quick/` has at least one directory, you are asked:
|
||||
When you run `/msd-complete-milestone` and `.planning/quick/` has at least one directory, you are asked:
|
||||
|
||||
```text
|
||||
Archive completed quick tasks into this milestone too?
|
||||
@@ -129,11 +129,11 @@ Archive completed quick tasks into this milestone too?
|
||||
Skip
|
||||
```
|
||||
|
||||
Choosing "Yes" folds `--archive-quick` into the same `gsd-tools milestone complete` call that archives `ROADMAP.md`/`REQUIREMENTS.md` and phase directories — one command, one `STATE.md` write. "Skip" (or an empty `.planning/quick/`) leaves everything untouched.
|
||||
Choosing "Yes" folds `--archive-quick` into the same `msd-tools milestone complete` call that archives `ROADMAP.md`/`REQUIREMENTS.md` and phase directories — one command, one `STATE.md` write. "Skip" (or an empty `.planning/quick/`) leaves everything untouched.
|
||||
|
||||
### Retroactive path — archive an already-completed milestone
|
||||
|
||||
`/gsd-complete-milestone` only runs once per milestone, so if quick tasks piled up after you already closed one out, use `/gsd-cleanup` instead. When it finds `.planning/quick/` non-empty, it offers to sweep it into the most recent completed milestone that doesn't yet have a `-quick` archive:
|
||||
`/msd-complete-milestone` only runs once per milestone, so if quick tasks piled up after you already closed one out, use `/msd-cleanup` instead. When it finds `.planning/quick/` non-empty, it offers to sweep it into the most recent completed milestone that doesn't yet have a `-quick` archive:
|
||||
|
||||
```text
|
||||
Archive ALL {N} quick-task directories into v{X.Y} — {Milestone Name}?
|
||||
@@ -143,7 +143,7 @@ there is no way to split them per-milestone.
|
||||
Skip
|
||||
```
|
||||
|
||||
Under the hood this calls the narrower `gsd-tools milestone archive-quick <version>` command — the same move/index/reset logic as `--archive-quick`, but without touching `ROADMAP.md`, `REQUIREMENTS.md`, `MILESTONES.md`, or milestone-completion guards, so it is safe to run against a milestone that's already closed.
|
||||
Under the hood this calls the narrower `msd-tools milestone archive-quick <version>` command — the same move/index/reset logic as `--archive-quick`, but without touching `ROADMAP.md`, `REQUIREMENTS.md`, `MILESTONES.md`, or milestone-completion guards, so it is safe to run against a milestone that's already closed.
|
||||
|
||||
### What both paths do
|
||||
|
||||
@@ -160,15 +160,15 @@ Four cases look similar from the outside but mean different things:
|
||||
| What you see | Meaning |
|
||||
|---|---|
|
||||
| No archive prompt at all | `.planning/quick/` is absent or empty — nothing to archive, nothing reported |
|
||||
| Archive prompt appears, directories move, but `STATE.md` doesn't change | Your `STATE.md` has no `### Quick Tasks Completed` section yet — normal, since `/gsd-quick` creates that section lazily on first completion, not the project template. This is a silent no-op, not a failure |
|
||||
| Directories move, but you see a `warnings` entry naming `quick_tasks_table` | Your `### Quick Tasks Completed` table has a column set that matches neither registered variant. The reset is **refused** — every row is preserved untouched rather than risk destroying data under a schema GSD doesn't recognize |
|
||||
| Archive prompt appears, directories move, but `STATE.md` doesn't change | Your `STATE.md` has no `### Quick Tasks Completed` section yet — normal, since `/msd-quick` creates that section lazily on first completion, not the project template. This is a silent no-op, not a failure |
|
||||
| Directories move, but you see a `warnings` entry naming `quick_tasks_table` | Your `### Quick Tasks Completed` table has a column set that matches neither registered variant. The reset is **refused** — every row is preserved untouched rather than risk destroying data under a schema MSD doesn't recognize |
|
||||
| Fewer directories moved than existed in `.planning/quick/` | A rename failed partway through. The result's `archived` count reflects exactly what succeeded — never a false full count — and the directories that didn't move are still in `.planning/quick/` for a retry |
|
||||
|
||||
---
|
||||
|
||||
## Related
|
||||
|
||||
- [Batch quick tasks](batch-quick-tasks.md) — run several `/gsd-quick`-shaped tasks together with `/gsd-quick-batch`
|
||||
- [Batch quick tasks](batch-quick-tasks.md) — run several `/msd-quick`-shaped tasks together with `/msd-quick-batch`
|
||||
- [The phase loop](../explanation/the-phase-loop.md)
|
||||
- [Context engineering](../explanation/context-engineering.md)
|
||||
- [Commands](../COMMANDS.md)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# How to import a capability from a URL
|
||||
|
||||
This guide is for GSD users who want to install a published capability — from a git repository, an npm package, a tarball, or a local path. It covers running the install command, understanding the pre-install summary, consenting to executable surfaces, verifying integrity, and choosing a scope.
|
||||
This guide is for MSD users who want to install a published capability — from a git repository, an npm package, a tarball, or a local path. It covers running the install command, understanding the pre-install summary, consenting to executable surfaces, verifying integrity, and choosing a scope.
|
||||
|
||||
Before installing a third-party capability, read [Capability trust model](../explanation/capability-trust-model.md) to understand how GSD treats external code.
|
||||
Before installing a third-party capability, read [Capability trust model](../explanation/capability-trust-model.md) to understand how MSD treats external code.
|
||||
|
||||
---
|
||||
|
||||
@@ -13,46 +13,46 @@ The `install` subcommand accepts several source spec forms. Use whichever matche
|
||||
**Git repository at a tag:**
|
||||
|
||||
```bash
|
||||
gsd capability install https://github.com/some-org/gsd-cap-example.git#v1.0.0
|
||||
msd capability install https://github.com/some-org/msd-cap-example.git#v1.0.0
|
||||
```
|
||||
|
||||
**Git repository pinned to a commit SHA (fully reproducible):**
|
||||
|
||||
```bash
|
||||
gsd capability install https://github.com/some-org/gsd-cap-example.git#sha:abc123def456...
|
||||
msd capability install https://github.com/some-org/msd-cap-example.git#sha:abc123def456...
|
||||
```
|
||||
|
||||
**npm package:**
|
||||
|
||||
```bash
|
||||
gsd capability install npm:@some-org/gsd-cap-example@1.0.0
|
||||
msd capability install npm:@some-org/msd-cap-example@1.0.0
|
||||
```
|
||||
|
||||
**Tarball at an HTTPS URL:**
|
||||
|
||||
```bash
|
||||
gsd capability install https://example.com/releases/gsd-cap-example-1.0.0.tgz
|
||||
msd capability install https://example.com/releases/msd-cap-example-1.0.0.tgz
|
||||
```
|
||||
|
||||
**Local path (for testing a capability you are developing):**
|
||||
|
||||
```bash
|
||||
gsd capability install ./path/to/capability
|
||||
msd capability install ./path/to/capability
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Read the pre-install summary
|
||||
|
||||
Before asking for confirmation, GSD fetches the manifest and displays a summary:
|
||||
Before asking for confirmation, MSD fetches the manifest and displays a summary:
|
||||
|
||||
```
|
||||
Capability: Example Planning Step
|
||||
Version: 1.0.0
|
||||
Author: Some Org <hello@some-org.example>
|
||||
Homepage: https://github.com/some-org/gsd-cap-example
|
||||
Homepage: https://github.com/some-org/msd-cap-example
|
||||
License: MIT
|
||||
engines.gsd: >=1.6.0
|
||||
engines.msd: >=1.6.0
|
||||
|
||||
Artefacts: 3 files (skills: 1, agents: 1, fragments: 1)
|
||||
|
||||
@@ -62,24 +62,24 @@ Executable surfaces:
|
||||
command modules: none
|
||||
```
|
||||
|
||||
If the capability declares hooks, MCP servers, or command modules, these are listed under **Executable surfaces**. These surfaces run as part of the GSD loop on your machine. Review them carefully.
|
||||
If the capability declares hooks, MCP servers, or command modules, these are listed under **Executable surfaces**. These surfaces run as part of the MSD loop on your machine. Review them carefully.
|
||||
|
||||
---
|
||||
|
||||
## Consent to executable surfaces
|
||||
|
||||
If the capability declares any executable surface — hooks, MCP servers, or command modules — GSD displays a consent prompt:
|
||||
If the capability declares any executable surface — hooks, MCP servers, or command modules — MSD displays a consent prompt:
|
||||
|
||||
```
|
||||
This capability registers executable hooks that will run during your GSD sessions.
|
||||
This capability registers executable hooks that will run during your MSD sessions.
|
||||
Do you consent to installing it? [y/N]
|
||||
```
|
||||
|
||||
If you do not trust the source, type `N` or press Enter to cancel. The capability will not be installed and nothing will be written to disk.
|
||||
|
||||
If the capability declares no executable surfaces (skills, agents, and prompt fragments only), GSD installs without a consent prompt.
|
||||
If the capability declares no executable surfaces (skills, agents, and prompt fragments only), MSD installs without a consent prompt.
|
||||
|
||||
After initial consent, if you later run `gsd capability update` and the updated version adds new executable surfaces that were not present when you first consented, GSD will prompt for consent again before applying the update.
|
||||
After initial consent, if you later run `msd capability update` and the updated version adds new executable surfaces that were not present when you first consented, MSD will prompt for consent again before applying the update.
|
||||
|
||||
---
|
||||
|
||||
@@ -88,11 +88,11 @@ After initial consent, if you later run `gsd capability update` and the updated
|
||||
If the capability author has published an `sha512` integrity hash, pass it with `--integrity` to verify the download before extraction:
|
||||
|
||||
```bash
|
||||
gsd capability install https://example.com/releases/gsd-cap-example-1.0.0.tgz \
|
||||
msd capability install https://example.com/releases/msd-cap-example-1.0.0.tgz \
|
||||
--integrity sha512-AbCdEf...
|
||||
```
|
||||
|
||||
If the computed hash does not match the value you provide, GSD aborts the install. Nothing is written to disk. This protects against a tampered or corrupted download.
|
||||
If the computed hash does not match the value you provide, MSD aborts the install. Nothing is written to disk. This protects against a tampered or corrupted download.
|
||||
|
||||
For Git and npm installs, the hosting platform provides its own transport-layer assurance. The `--integrity` flag is most important for tarball URLs hosted outside a verified registry.
|
||||
|
||||
@@ -100,16 +100,16 @@ For Git and npm installs, the hosting platform provides its own transport-layer
|
||||
|
||||
## Choose a scope
|
||||
|
||||
Use `--scope project` to install the capability for the current project only. The files land in `.gsd/capabilities/<id>/` relative to the project root, and the ledger entry goes into the project's local config.
|
||||
Use `--scope project` to install the capability for the current project only. The files land in `.msd/capabilities/<id>/` relative to the project root, and the ledger entry goes into the project's local config.
|
||||
|
||||
```bash
|
||||
gsd capability install <spec> --scope project
|
||||
msd capability install <spec> --scope project
|
||||
```
|
||||
|
||||
Use `--scope global` (the default) to install for all your projects on this machine. The files land in `~/.gsd/capabilities/<id>/` and the ledger is written per runtime (for example, `~/.claude/.gsd-capabilities.json`).
|
||||
Use `--scope global` (the default) to install for all your projects on this machine. The files land in `~/.msd/capabilities/<id>/` and the ledger is written per runtime (for example, `~/.claude/.msd-capabilities.json`).
|
||||
|
||||
```bash
|
||||
gsd capability install <spec> --scope global
|
||||
msd capability install <spec> --scope global
|
||||
```
|
||||
|
||||
Project-scoped capabilities take precedence over global ones when both are present. Use project scope when the capability is specific to one codebase, or when you want to pin a version independently of your global install.
|
||||
@@ -118,16 +118,16 @@ Project-scoped capabilities take precedence over global ones when both are prese
|
||||
|
||||
## Handle a version mismatch
|
||||
|
||||
If the capability's `engines.gsd` requirement is not satisfied by your installed GSD version, the install will be blocked:
|
||||
If the capability's `engines.msd` requirement is not satisfied by your installed MSD version, the install will be blocked:
|
||||
|
||||
```
|
||||
Error: Capability requires gsd >=1.7.0 but you have 1.6.2.
|
||||
Error: Capability requires msd >=1.7.0 but you have 1.6.2.
|
||||
```
|
||||
|
||||
In this case, either upgrade GSD with `gsd update` and retry, or ask the capability author whether an older compatible version is available. If the capability publishes `compatVersions`, GSD may offer to install the newest version compatible with your current GSD:
|
||||
In this case, either upgrade MSD with `msd update` and retry, or ask the capability author whether an older compatible version is available. If the capability publishes `compatVersions`, MSD may offer to install the newest version compatible with your current MSD:
|
||||
|
||||
```
|
||||
A compatible older version (0.9.0, requires gsd >=1.6.0) is available.
|
||||
A compatible older version (0.9.0, requires msd >=1.6.0) is available.
|
||||
Install that instead? [y/N]
|
||||
```
|
||||
|
||||
@@ -135,10 +135,10 @@ Install that instead? [y/N]
|
||||
|
||||
## Handle a blocked install (strictKnownRegistries)
|
||||
|
||||
If your organisation has set `strictKnownRegistries` to a non-empty allowlist in your GSD config, installs from sources outside that allowlist will be refused:
|
||||
If your organisation has set `strictKnownRegistries` to a non-empty allowlist in your MSD config, installs from sources outside that allowlist will be refused:
|
||||
|
||||
```
|
||||
Error: Source is not in the known-registries allowlist. Contact your GSD administrator.
|
||||
Error: Source is not in the known-registries allowlist. Contact your MSD administrator.
|
||||
```
|
||||
|
||||
To install the capability, either ask your administrator to add the source to the allowlist, or install from an approved source.
|
||||
@@ -150,7 +150,7 @@ To install the capability, either ask your administrator to add the source to th
|
||||
If you are running in a script or CI context and have already inspected the manifest, pass `--yes` to proceed without interactive prompts. Use this only when you are certain about what you are installing.
|
||||
|
||||
```bash
|
||||
gsd capability install <spec> --yes
|
||||
msd capability install <spec> --yes
|
||||
```
|
||||
|
||||
---
|
||||
@@ -160,10 +160,10 @@ gsd capability install <spec> --yes
|
||||
After a successful install, verify the capability is active:
|
||||
|
||||
```bash
|
||||
gsd capability list
|
||||
msd capability list
|
||||
```
|
||||
|
||||
The output shows each installed capability, its version, scope, and enabled status. If the capability did not activate as expected, check that your GSD version satisfies `engines.gsd` and that the capability is not disabled.
|
||||
The output shows each installed capability, its version, scope, and enabled status. If the capability did not activate as expected, check that your MSD version satisfies `engines.msd` and that the capability is not disabled.
|
||||
|
||||
---
|
||||
|
||||
@@ -172,9 +172,9 @@ The output shows each installed capability, its version, scope, and enabled stat
|
||||
[`projects-sync`](https://github.com/The-Artificer-of-Ciphers-LLC/projects-sync-capability) is a reference third-party capability — it mirrors a project's `.planning/ROADMAP.md` to GitHub Issues, Milestones, and Projects v2. Install it the same way as any URL spec:
|
||||
|
||||
```bash
|
||||
gsd capability install https://github.com/The-Artificer-of-Ciphers-LLC/projects-sync-capability.git#v0.1.0 --scope project
|
||||
gsd-tools config-set projects-sync.enabled true # opt-in, default off
|
||||
gsd-tools projects-sync status # dry run
|
||||
msd capability install https://github.com/The-Artificer-of-Ciphers-LLC/projects-sync-capability.git#v0.1.0 --scope project
|
||||
msd-tools config-set projects-sync.enabled true # opt-in, default off
|
||||
msd-tools projects-sync status # dry run
|
||||
```
|
||||
|
||||
It is a `role: feature` capability that registers an `execute:pre` step and a `ship:post` contribution (both `onError: skip`) and contributes the `projects-sync` command family — a concrete model for the manifest shape, hook registration, and command-router conventions described in [Develop a capability](./develop-a-capability.md).
|
||||
@@ -183,7 +183,7 @@ It is a `role: feature` capability that registers an `execute:pre` step and a `s
|
||||
|
||||
## Next steps
|
||||
|
||||
- [Version and update a capability](./version-a-capability.md) — check for updates with `gsd capability outdated` and apply them with `gsd capability update`.
|
||||
- [Remove a capability](./remove-a-capability.md) — uninstall with `gsd capability remove`, including the `--purge-data` option.
|
||||
- [Capability trust model](../explanation/capability-trust-model.md) — the full explanation of how GSD handles trust for first-party and third-party capabilities.
|
||||
- [Version and update a capability](./version-a-capability.md) — check for updates with `msd capability outdated` and apply them with `msd capability update`.
|
||||
- [Remove a capability](./remove-a-capability.md) — uninstall with `msd capability remove`, including the `--purge-data` option.
|
||||
- [Capability trust model](../explanation/capability-trust-model.md) — the full explanation of how MSD handles trust for first-party and third-party capabilities.
|
||||
- [Capability manifest](../reference/capability-manifest.md) — field reference for `capability.json`.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# How to install a minimal GSD and add skills later
|
||||
# How to install a minimal MSD and add skills later
|
||||
|
||||
Install GSD Core with a small skill footprint to keep cold-start context low, then grow the surface — live or on reinstall — only when you need more. Use this when context budget matters: large existing projects, constrained models, or runtimes where every description token counts.
|
||||
Install MSD Core with a small skill footprint to keep cold-start context low, then grow the surface — live or on reinstall — only when you need more. Use this when context budget matters: large existing projects, constrained models, or runtimes where every description token counts.
|
||||
|
||||
**What you need:** A supported runtime and the standard installer prerequisites (Node.js 18+ and npx). If you have not installed GSD at all yet, read [Install on your runtime](install-on-your-runtime.md) first — this guide covers the *profile* choice that layers on top of any runtime install.
|
||||
**What you need:** A supported runtime and the standard installer prerequisites (Node.js 18+ and npx). If you have not installed MSD at all yet, read [Install on your runtime](install-on-your-runtime.md) first — this guide covers the *profile* choice that layers on top of any runtime install.
|
||||
|
||||
---
|
||||
|
||||
@@ -11,14 +11,14 @@ Install GSD Core with a small skill footprint to keep cold-start context low, th
|
||||
To install only the core main-loop skills, add `--minimal` to the installer:
|
||||
|
||||
```bash
|
||||
npx @opengsd/gsd-core@latest --claude --global --minimal
|
||||
npx @golem15/msd-core@latest --claude --global --minimal
|
||||
```
|
||||
|
||||
`--minimal` has two aliases — use whichever reads best to you; they are identical:
|
||||
|
||||
```bash
|
||||
npx @opengsd/gsd-core@latest --claude --global --core-only
|
||||
npx @opengsd/gsd-core@latest --claude --global --profile=core
|
||||
npx @golem15/msd-core@latest --claude --global --core-only
|
||||
npx @golem15/msd-core@latest --claude --global --profile=core
|
||||
```
|
||||
|
||||
A minimal install gives you the eight skills needed to run the core phase loop:
|
||||
@@ -32,7 +32,7 @@ A minimal install gives you the eight skills needed to run the core phase loop:
|
||||
- `update`
|
||||
- `surface`
|
||||
|
||||
No sub-agents are installed, and the skill-description tokens the model carries at cold start drop to roughly 130, against roughly 1,200 for a full install. The chosen profile is recorded in the `.gsd-profile` marker in your runtime config directory and is reapplied automatically every time you run `/gsd-update`, so you stay minimal across upgrades until you decide otherwise.
|
||||
No sub-agents are installed, and the skill-description tokens the model carries at cold start drop to roughly 130, against roughly 1,200 for a full install. The chosen profile is recorded in the `.msd-profile` marker in your runtime config directory and is reapplied automatically every time you run `/msd-update`, so you stay minimal across upgrades until you decide otherwise.
|
||||
|
||||
> Do not combine `--minimal` with `--profile=` — the installer treats that as a conflict and exits.
|
||||
|
||||
@@ -50,14 +50,14 @@ If `core` is too small, pick a wider profile instead. Pass it with `--profile=<n
|
||||
|
||||
```bash
|
||||
# Standard: the core loop plus everyday management commands
|
||||
npx @opengsd/gsd-core@latest --claude --global --profile=standard
|
||||
npx @golem15/msd-core@latest --claude --global --profile=standard
|
||||
```
|
||||
|
||||
If you want a named profile plus one extra cluster, compose them with a comma. The installer writes the union of both:
|
||||
|
||||
```bash
|
||||
# Core loop plus the audit/review skills, nothing else
|
||||
npx @opengsd/gsd-core@latest --claude --global --profile=core,audit
|
||||
npx @golem15/msd-core@latest --claude --global --profile=core,audit
|
||||
```
|
||||
|
||||
---
|
||||
@@ -67,7 +67,7 @@ npx @opengsd/gsd-core@latest --claude --global --profile=core,audit
|
||||
From inside your runtime, list the current surface, the disabled clusters, and the token cost of each:
|
||||
|
||||
```bash
|
||||
/gsd-surface list
|
||||
/msd-surface list
|
||||
```
|
||||
|
||||
The skills are grouped into clusters you can toggle as a unit:
|
||||
@@ -78,25 +78,25 @@ The skills are grouped into clusters you can toggle as a unit:
|
||||
|
||||
## Add skills later without reinstalling
|
||||
|
||||
If you installed minimal and now need more, you do not have to re-run the installer. `/gsd-surface` changes the live surface and persists the change in a separate `.gsd-surface.json` file, leaving your install-time profile marker untouched.
|
||||
If you installed minimal and now need more, you do not have to re-run the installer. `/msd-surface` changes the live surface and persists the change in a separate `.msd-surface.json` file, leaving your install-time profile marker untouched.
|
||||
|
||||
To switch to a wider profile in place:
|
||||
|
||||
```bash
|
||||
/gsd-surface profile standard
|
||||
/msd-surface profile standard
|
||||
```
|
||||
|
||||
To turn on just one cluster while keeping your base profile:
|
||||
|
||||
```bash
|
||||
/gsd-surface enable audit_review
|
||||
/msd-surface enable audit_review
|
||||
```
|
||||
|
||||
To turn a cluster back off, or to discard all your live changes and return to the profile you installed:
|
||||
|
||||
```bash
|
||||
/gsd-surface disable utility
|
||||
/gsd-surface reset
|
||||
/msd-surface disable utility
|
||||
/msd-surface reset
|
||||
```
|
||||
|
||||
Surface changes take effect in your next session — restart the runtime to pick them up.
|
||||
@@ -105,23 +105,23 @@ Surface changes take effect in your next session — restart the runtime to pick
|
||||
|
||||
## Add skills by reinstalling
|
||||
|
||||
`/gsd-surface` is the right tool for occasional, reversible adjustments. If you have decided you want the wider surface permanently, change the install-time profile instead so every future `/gsd-update` keeps it:
|
||||
`/msd-surface` is the right tool for occasional, reversible adjustments. If you have decided you want the wider surface permanently, change the install-time profile instead so every future `/msd-update` keeps it:
|
||||
|
||||
```bash
|
||||
# Re-run the installer without --minimal to record `full` as your profile
|
||||
npx @opengsd/gsd-core@latest --claude --global
|
||||
npx @golem15/msd-core@latest --claude --global
|
||||
|
||||
# ...or pin a specific profile
|
||||
npx @opengsd/gsd-core@latest --claude --global --profile=standard
|
||||
npx @golem15/msd-core@latest --claude --global --profile=standard
|
||||
```
|
||||
|
||||
Running `/gsd-update` re-reads the `.gsd-profile` marker and reinstalls at that profile, so a one-off reinstall at a new profile is all you need — subsequent updates follow it automatically.
|
||||
Running `/msd-update` re-reads the `.msd-profile` marker and reinstalls at that profile, so a one-off reinstall at a new profile is all you need — subsequent updates follow it automatically.
|
||||
|
||||
---
|
||||
|
||||
## Related
|
||||
|
||||
- [Install on your runtime](install-on-your-runtime.md)
|
||||
- [Update GSD](update-gsd.md)
|
||||
- [Update MSD](update-msd.md)
|
||||
- [Configuration](../CONFIGURATION.md)
|
||||
- [Docs index](../README.md)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# How to install GSD Core on your runtime
|
||||
# How to install MSD Core on your runtime
|
||||
|
||||
Install GSD Core (`@opengsd/gsd-core`) into the AI coding runtime you use every day. This guide gives you the standard installer path for each supported runtime, then covers the manual path for machines without Node.js.
|
||||
Install MSD Core (`@golem15/msd-core`) into the AI coding runtime you use every day. This guide gives you the standard installer path for each supported runtime, then covers the manual path for machines without Node.js.
|
||||
|
||||
**What you need:** Node.js 18+ and npm (or npx). If you do not have Node.js, jump to [Installing without Node.js](#installing-without-nodejs).
|
||||
|
||||
@@ -8,7 +8,7 @@ Install GSD Core (`@opengsd/gsd-core`) into the AI coding runtime you use every
|
||||
|
||||
## Why the installer is required
|
||||
|
||||
GSD Core ships agent and command files in Claude Code's native frontmatter format. Each supported runtime expects a different schema, directory layout, and command-invocation syntax. The installer performs the necessary transformations — for example, converting tool lists and colour values for OpenCode and writing TOML agent entries for Codex.
|
||||
MSD Core ships agent and command files in Claude Code's native frontmatter format. Each supported runtime expects a different schema, directory layout, and command-invocation syntax. The installer performs the necessary transformations — for example, converting tool lists and colour values for OpenCode and writing TOML agent entries for Codex.
|
||||
|
||||
**Do not copy files from `agents/` or `commands/` directly.** Doing so bypasses the transformations and produces schema-validation errors or missing commands.
|
||||
|
||||
@@ -19,7 +19,7 @@ GSD Core ships agent and command files in Claude Code's native frontmatter forma
|
||||
Run the installer from any directory. It prompts for your runtime and whether to install globally (all projects) or locally (this project only).
|
||||
|
||||
```bash
|
||||
npx @opengsd/gsd-core@latest
|
||||
npx @golem15/msd-core@latest
|
||||
```
|
||||
|
||||
That is the only command you need for a fresh install or to re-run the installer after switching runtimes.
|
||||
@@ -31,32 +31,32 @@ That is the only command you need for a fresh install or to re-run the installer
|
||||
### Claude Code
|
||||
|
||||
```bash
|
||||
npx @opengsd/gsd-core@latest --claude --global
|
||||
npx @golem15/msd-core@latest --claude --global
|
||||
```
|
||||
|
||||
Skills land in `~/.claude/`. Commands appear as `/gsd-*` slash commands in your next Claude Code session. Restart Claude Code to pick them up.
|
||||
Skills land in `~/.claude/`. Commands appear as `/msd-*` slash commands in your next Claude Code session. Restart Claude Code to pick them up.
|
||||
|
||||
**Installing at both `--global` and `--local`.** This is a supported configuration (different projects sometimes need different customizations), but Claude Code's own trigger-resolution rules — personal scope overrides project scope, and a skill overrides a same-named command — both point the same direction: the global skill always wins the `/gsd-<name>` trigger over the local command. GSD Core detects this and prints which scope is winning right after install completes (and surfaces the identical fact from `/gsd-health` as diagnostic `W028`); it is an advisory, not a failure — the install itself still succeeds. At **global** scope, the winning skill's workflow-spec reference resolves at runtime against your working directory first, so a project with its own `.claude/gsd-core/` still gets its own specs even though the global skill is what Claude Code invokes — see [Interpret install-shadow warnings](interpret-install-shadow-warnings.md) for what the warning means, how to read which scope wins, and the limits of that resolution (it does not extend to the skill's `references/`/`templates/` includes).
|
||||
**Installing at both `--global` and `--local`.** This is a supported configuration (different projects sometimes need different customizations), but Claude Code's own trigger-resolution rules — personal scope overrides project scope, and a skill overrides a same-named command — both point the same direction: the global skill always wins the `/msd-<name>` trigger over the local command. MSD Core detects this and prints which scope is winning right after install completes (and surfaces the identical fact from `/msd-health` as diagnostic `W028`); it is an advisory, not a failure — the install itself still succeeds. At **global** scope, the winning skill's workflow-spec reference resolves at runtime against your working directory first, so a project with its own `.claude/msd-core/` still gets its own specs even though the global skill is what Claude Code invokes — see [Interpret install-shadow warnings](interpret-install-shadow-warnings.md) for what the warning means, how to read which scope wins, and the limits of that resolution (it does not extend to the skill's `references/`/`templates/` includes).
|
||||
|
||||
**Override the install directory:**
|
||||
|
||||
```bash
|
||||
CLAUDE_CONFIG_DIR=~/.claude-alt npx @opengsd/gsd-core@latest --claude --global
|
||||
CLAUDE_CONFIG_DIR=~/.claude-alt npx @golem15/msd-core@latest --claude --global
|
||||
```
|
||||
|
||||
**Hook coverage**
|
||||
|
||||
GSD registers the following Claude Code hook events automatically on install:
|
||||
MSD registers the following Claude Code hook events automatically on install:
|
||||
|
||||
| Event | Hook | Purpose |
|
||||
|---|---|---|
|
||||
| `SessionStart` | `gsd-check-update.js`, `gsd-session-state.sh` | Update check, session orientation |
|
||||
| `PostToolUse` | `gsd-context-monitor.js`, `gsd-read-injection-scanner.js`, `gsd-phase-boundary.sh`, `gsd-graphify-update.sh` | Context monitoring, read-time scan, phase boundary detection |
|
||||
| `PreToolUse` | `gsd-prompt-guard.js`, `gsd-read-guard.js`, `gsd-workflow-guard.js`, `gsd-worktree-path-guard.js`, `gsd-agent-isolation-guard.js`, `gsd-secret-read-guard.js`, `gsd-validate-commit.sh` | Prompt guard, read-before-edit, workflow + worktree safety, agent-dispatch isolation, secret-file read protection, commit validation |
|
||||
| `SubagentStop` | `gsd-context-monitor.js` | Context headroom tracking after subagent completion |
|
||||
| `Stop` | `gsd-context-monitor.js` | Context headroom tracking before model stop |
|
||||
| `PreCompact` | `gsd-context-monitor.js` | Context awareness before conversation compaction |
|
||||
| `FileChanged` (matcher: `config.json`) | `gsd-config-reload.js` | Hot-reloads `.planning/config.json` context mid-session when you edit your GSD config — no session restart required |
|
||||
| `SessionStart` | `msd-check-update.js`, `msd-session-state.sh` | Update check, session orientation |
|
||||
| `PostToolUse` | `msd-context-monitor.js`, `msd-read-injection-scanner.js`, `msd-phase-boundary.sh`, `msd-graphify-update.sh` | Context monitoring, read-time scan, phase boundary detection |
|
||||
| `PreToolUse` | `msd-prompt-guard.js`, `msd-read-guard.js`, `msd-workflow-guard.js`, `msd-worktree-path-guard.js`, `msd-agent-isolation-guard.js`, `msd-secret-read-guard.js`, `msd-validate-commit.sh` | Prompt guard, read-before-edit, workflow + worktree safety, agent-dispatch isolation, secret-file read protection, commit validation |
|
||||
| `SubagentStop` | `msd-context-monitor.js` | Context headroom tracking after subagent completion |
|
||||
| `Stop` | `msd-context-monitor.js` | Context headroom tracking before model stop |
|
||||
| `PreCompact` | `msd-context-monitor.js` | Context awareness before conversation compaction |
|
||||
| `FileChanged` (matcher: `config.json`) | `msd-config-reload.js` | Hot-reloads `.planning/config.json` context mid-session when you edit your MSD config — no session restart required |
|
||||
|
||||
The `FileChanged` hook is always-on and a no-op when `.planning/config.json` does not exist in the project. Editing that file while a session is running injects an `additionalContext` summary of the new configuration so the agent picks up model overrides, workflow toggles, and hook settings immediately.
|
||||
|
||||
@@ -64,7 +64,7 @@ The `FileChanged` hook is always-on and a no-op when `.planning/config.json` doe
|
||||
|
||||
### Claude Code — native plugin install
|
||||
|
||||
GSD Core ships a `.claude-plugin/plugin.json` manifest, which enables installation and lifecycle management through the Claude Code plugin system. This path is **additive** — the npm installer above remains fully supported, and the two approaches differ in namespace and lifecycle.
|
||||
MSD Core ships a `.claude-plugin/plugin.json` manifest, which enables installation and lifecycle management through the Claude Code plugin system. This path is **additive** — the npm installer above remains fully supported, and the two approaches differ in namespace and lifecycle.
|
||||
|
||||
**Install-time config does not apply here.** The native plugin path (this section, the skills-dir load below, and marketplace discovery) materializes the repository tree directly — there is no install step. Install-time config that the npm installer bakes into generated artifact files at install time (confirmed for `agent_tools`; the same applies architecturally to `model_overrides` and other install-time-only keys) is never applied on this path, and running `claude plugin update` does not change that. If your setup relies on install-time config, use the npm installer above.
|
||||
|
||||
@@ -73,47 +73,47 @@ GSD Core ships a `.claude-plugin/plugin.json` manifest, which enables installati
|
||||
*Option A — marketplace or git install (once listed):*
|
||||
|
||||
```bash
|
||||
claude plugin install gsd-core
|
||||
claude plugin install msd-core
|
||||
```
|
||||
|
||||
*Option B — zero-friction skills-dir load:* Claude Code automatically discovers any directory under `~/.claude/skills/` that contains a `.claude-plugin/plugin.json` as a plugin. To use gsd-core this way, place (or symlink) the gsd-core package directory there:
|
||||
*Option B — zero-friction skills-dir load:* Claude Code automatically discovers any directory under `~/.claude/skills/` that contains a `.claude-plugin/plugin.json` as a plugin. To use msd-core this way, place (or symlink) the msd-core package directory there:
|
||||
|
||||
```bash
|
||||
# Example: place the package under ~/.claude/skills/gsd-core/
|
||||
# Claude Code loads it as gsd-core@skills-dir on the next session start.
|
||||
# Example: place the package under ~/.claude/skills/msd-core/
|
||||
# Claude Code loads it as msd-core@skills-dir on the next session start.
|
||||
# No explicit install step required.
|
||||
```
|
||||
|
||||
**Command namespace**
|
||||
|
||||
Plugin commands are namespaced as `/gsd-core:<command>` — for example, `/gsd-core:plan-phase`. This is distinct from the classic npm/file-copy installer, which exposes commands as `/gsd:<command>`. Use whichever namespace corresponds to your install method.
|
||||
Plugin commands are namespaced as `/msd-core:<command>` — for example, `/msd-core:plan-phase`. This is distinct from the classic npm/file-copy installer, which exposes commands as `/msd:<command>`. Use whichever namespace corresponds to your install method.
|
||||
|
||||
**Lifecycle**
|
||||
|
||||
```bash
|
||||
claude plugin enable gsd-core
|
||||
claude plugin disable gsd-core
|
||||
claude plugin update gsd-core
|
||||
claude plugin enable msd-core
|
||||
claude plugin disable msd-core
|
||||
claude plugin update msd-core
|
||||
```
|
||||
|
||||
**Hooks**
|
||||
|
||||
The plugin wires gsd-core's always-on guard and update hooks automatically via `hooks/hooks.json`. No manual hook registration is required.
|
||||
The plugin wires msd-core's always-on guard and update hooks automatically via `hooks/hooks.json`. No manual hook registration is required.
|
||||
|
||||
**Prerequisites**
|
||||
|
||||
The `gsd-tools` binary (installed as part of the `@opengsd/gsd-core` npm package) must be available on your `PATH` for gsd commands to execute their backing logic. The plugin delivers the command, agent, and hook surface; the npm package delivers the runtime CLI.
|
||||
The `msd-tools` binary (installed as part of the `@golem15/msd-core` npm package) must be available on your `PATH` for msd commands to execute their backing logic. The plugin delivers the command, agent, and hook surface; the npm package delivers the runtime CLI.
|
||||
|
||||
Node.js (`node`) must also be available on your `PATH`. The plugin's always-on guard hooks (wired in `hooks/hooks.json`) are invoked as `node "${CLAUDE_PLUGIN_ROOT}/hooks/<script>"`. Some Claude Code distributions ship as a standalone binary and do not expose a `node` executable on `PATH`; in those environments the plugin's hooks will not run. Verify with `node --version` before relying on the plugin hooks.
|
||||
|
||||
**Runtime build (self-healing).** The runtime CLI's compiled modules under `gsd-core/bin/lib/*.cjs` are build artifacts (ADR-457): they are compiled from `src/*.cts` by `npm run build:lib` and shipped prebuilt in the npm tarball. A plugin-marketplace or git-clone install materializes the repository tree directly and never runs that build step, so those files are initially absent. The CLI heals this automatically: the first `gsd-tools` invocation detects the missing output and compiles it once (using the bundled `typescript` devDependency), then proceeds normally. You may see a one-time `gsd: runtime library not built — compiling once…` notice on stderr; subsequent commands are unaffected. If auto-build cannot run (for example `node_modules` was pruned to production-only and `typescript` is unavailable), the CLI prints an actionable message telling you to run `npm install && npm run build:lib` in the plugin directory.
|
||||
**Runtime build (self-healing).** The runtime CLI's compiled modules under `msd-core/bin/lib/*.cjs` are build artifacts (ADR-457): they are compiled from `src/*.cts` by `npm run build:lib` and shipped prebuilt in the npm tarball. A plugin-marketplace or git-clone install materializes the repository tree directly and never runs that build step, so those files are initially absent. The CLI heals this automatically: the first `msd-tools` invocation detects the missing output and compiles it once (using the bundled `typescript` devDependency), then proceeds normally. You may see a one-time `msd: runtime library not built — compiling once…` notice on stderr; subsequent commands are unaffected. If auto-build cannot run (for example `node_modules` was pruned to production-only and `typescript` is unavailable), the CLI prints an actionable message telling you to run `npm install && npm run build:lib` in the plugin directory.
|
||||
|
||||
#### Claude plugin marketplace discovery (ZCODE and compatible runtimes)
|
||||
|
||||
GSD Core also ships a `.claude-plugin/marketplace.json` marketplace manifest (sibling to `plugin.json`). Runtimes that implement the Claude plugin marketplace contract — such as ZCODE — can discover and install GSD Core from a custom marketplace source without a manual clone:
|
||||
MSD Core also ships a `.claude-plugin/marketplace.json` marketplace manifest (sibling to `plugin.json`). Runtimes that implement the Claude plugin marketplace contract — such as ZCODE — can discover and install MSD Core from a custom marketplace source without a manual clone:
|
||||
|
||||
1. In your runtime's plugin UI, add a custom marketplace source pointing at `open-gsd/gsd-core` (GitHub `owner/repo` form).
|
||||
2. GSD Core appears in the catalog and can be installed directly from the UI.
|
||||
1. In your runtime's plugin UI, add a custom marketplace source pointing at `golem15com/msd-core` (GitHub `owner/repo` form).
|
||||
2. MSD Core appears in the catalog and can be installed directly from the UI.
|
||||
|
||||
This path is **additive** and changes nothing about the Claude Code plugin install above (`.claude-plugin/plugin.json` is unchanged). The marketplace entry's `source` is `./`, so it reuses `plugin.json`'s `commands` / `skills` / `hooks` mapping. The catalog version tracks `package.json` (it lives at `plugins[0].version` and is stamped by the release version-sync), so the version you see in the marketplace matches the npm release.
|
||||
|
||||
@@ -122,23 +122,23 @@ This path is **additive** and changes nothing about the Claude Code plugin insta
|
||||
### OpenCode
|
||||
|
||||
```bash
|
||||
npx @opengsd/gsd-core@latest --opencode --global
|
||||
npx @golem15/msd-core@latest --opencode --global
|
||||
```
|
||||
|
||||
The installer writes four surfaces under `~/.config/opencode/` (XDG) or `~/.opencode/`: flat slash commands in `commands/` (plural — the directory OpenCode discovers slash commands from, #2329), file-based subagents in `agents/`, on-demand skills in `skills/<name>/SKILL.md`, and a native plugin in `plugins/gsd-core.js`. It converts agent frontmatter to OpenCode's schema — removing the `tools:` field and converting colour values to hex — and emits each skill with spec-compliant frontmatter (`name` matching the skill directory plus a `description`). Skills are loaded on demand via OpenCode's native skill tool; commands remain invokable as `/gsd-*`. See [Installing without Node.js — OpenCode transformations](#opencode--required-transformations) if you need to understand what changes.
|
||||
The installer writes four surfaces under `~/.config/opencode/` (XDG) or `~/.opencode/`: flat slash commands in `commands/` (plural — the directory OpenCode discovers slash commands from, #2329), file-based subagents in `agents/`, on-demand skills in `skills/<name>/SKILL.md`, and a native plugin in `plugins/msd-core.js`. It converts agent frontmatter to OpenCode's schema — removing the `tools:` field and converting colour values to hex — and emits each skill with spec-compliant frontmatter (`name` matching the skill directory plus a `description`). Skills are loaded on demand via OpenCode's native skill tool; commands remain invokable as `/msd-*`. See [Installing without Node.js — OpenCode transformations](#opencode--required-transformations) if you need to understand what changes.
|
||||
|
||||
**GSD safety hooks on OpenCode.** OpenCode does not register lifecycle hooks the way Claude Code does (its `hooksSurface` is `none`), so GSD's prompt-injection guard, read-before-edit guard, injection scanner, and context monitor would otherwise be inert. The bundled plugin (`plugins/gsd-core.js`) closes that gap: OpenCode auto-discovers `plugins/*.{ts,js}` files under its config directory at startup and the adapter bridges OpenCode's event bus (`tool.execute.before`/`after`, `session.created`, `file.edited`) onto GSD's existing hook scripts, spawning them as subprocesses. No `opencode.json` entry is needed — the plugin is loaded by directory auto-discovery (the config `plugin` array is for npm packages only). A blocking hook aborts the tool call; an advisory hook surfaces its message without blocking.
|
||||
**MSD safety hooks on OpenCode.** OpenCode does not register lifecycle hooks the way Claude Code does (its `hooksSurface` is `none`), so MSD's prompt-injection guard, read-before-edit guard, injection scanner, and context monitor would otherwise be inert. The bundled plugin (`plugins/msd-core.js`) closes that gap: OpenCode auto-discovers `plugins/*.{ts,js}` files under its config directory at startup and the adapter bridges OpenCode's event bus (`tool.execute.before`/`after`, `session.created`, `file.edited`) onto MSD's existing hook scripts, spawning them as subprocesses. No `opencode.json` entry is needed — the plugin is loaded by directory auto-discovery (the config `plugin` array is for npm packages only). A blocking hook aborts the tool call; an advisory hook surfaces its message without blocking.
|
||||
|
||||
**Your plugin directory is pinned to CommonJS (accepted trade-off, #2544).** GSD's adapter is a CommonJS `.js` file, and Node decides a `.js` file's module type by walking up for the nearest `package.json`. So the installer writes a minimal `{"type":"commonjs"}` marker into the plugin directory itself — `plugins/package.json` on OpenCode and Kilo, `extensions/package.json` on pi. It is written only when GSD actually stages its adapter there, it never overwrites a `package.json` GSD did not write, and uninstall removes only its own.
|
||||
**Your plugin directory is pinned to CommonJS (accepted trade-off, #2544).** MSD's adapter is a CommonJS `.js` file, and Node decides a `.js` file's module type by walking up for the nearest `package.json`. So the installer writes a minimal `{"type":"commonjs"}` marker into the plugin directory itself — `plugins/package.json` on OpenCode and Kilo, `extensions/package.json` on pi. It is written only when MSD actually stages its adapter there, it never overwrites a `package.json` MSD did not write, and uninstall removes only its own.
|
||||
|
||||
The trade-off: that marker shadows your config root for **every** `.js` file in that directory, not just GSD's. If you author your own plugins as ESM `.js` and rely on a `"type": "module"` at the config root, they will stop resolving as ESM. This is deliberate — it is strictly narrower than the pre-#2544 behavior, which wrote the marker over `<configRoot>/package.json` itself and destroyed whatever was there — but it is a real constraint rather than a pure improvement, which is why it is stated here.
|
||||
The trade-off: that marker shadows your config root for **every** `.js` file in that directory, not just MSD's. If you author your own plugins as ESM `.js` and rely on a `"type": "module"` at the config root, they will stop resolving as ESM. This is deliberate — it is strictly narrower than the pre-#2544 behavior, which wrote the marker over `<configRoot>/package.json` itself and destroyed whatever was there — but it is a real constraint rather than a pure improvement, which is why it is stated here.
|
||||
|
||||
**Mitigation:** author your own plugins as `.ts`. OpenCode and Kilo compile plugin TypeScript with Bun, and a `package.json` `type` field does not affect `.ts` resolution — so a `.ts` plugin is unaffected by the marker. Failing that, keep ESM plugins outside the auto-discovered directory and load them as npm packages via the config `plugin` array.
|
||||
|
||||
**Override the install directory:**
|
||||
|
||||
```bash
|
||||
OPENCODE_CONFIG_DIR=~/.config/opencode-alt npx @opengsd/gsd-core@latest --opencode --global
|
||||
OPENCODE_CONFIG_DIR=~/.config/opencode-alt npx @golem15/msd-core@latest --opencode --global
|
||||
```
|
||||
|
||||
---
|
||||
@@ -146,7 +146,7 @@ OPENCODE_CONFIG_DIR=~/.config/opencode-alt npx @opengsd/gsd-core@latest --openco
|
||||
### Kilo
|
||||
|
||||
```bash
|
||||
npx @opengsd/gsd-core@latest --kilo --global
|
||||
npx @golem15/msd-core@latest --kilo --global
|
||||
```
|
||||
|
||||
The installer writes the same three surfaces under `~/.config/kilo/` (XDG) or `~/.kilo/` as for OpenCode — flat commands in `command/`, subagents in `agents/`, and skills in `skills/<name>/SKILL.md` — since Kilo derives from OpenCode and shares its config schema and skill layout.
|
||||
@@ -154,7 +154,7 @@ The installer writes the same three surfaces under `~/.config/kilo/` (XDG) or `~
|
||||
**Override the install directory:**
|
||||
|
||||
```bash
|
||||
KILO_CONFIG_DIR=~/.config/kilo-alt npx @opengsd/gsd-core@latest --kilo --global
|
||||
KILO_CONFIG_DIR=~/.config/kilo-alt npx @golem15/msd-core@latest --kilo --global
|
||||
```
|
||||
|
||||
---
|
||||
@@ -162,127 +162,127 @@ KILO_CONFIG_DIR=~/.config/kilo-alt npx @opengsd/gsd-core@latest --kilo --global
|
||||
### Codex
|
||||
|
||||
```bash
|
||||
npx @opengsd/gsd-core@latest --codex --global
|
||||
npx @golem15/msd-core@latest --codex --global
|
||||
```
|
||||
|
||||
Skills land in `~/.codex/skills/gsd-*/SKILL.md`. Agents are written as standalone `~/.codex/agents/gsd-*.toml` files, which Codex auto-discovers — that is the sole registration source for each role; `config.toml` only carries the shared `[agents]` dispatch-tuning scalar (`max_depth`), not a per-role table (#2406). Restart Codex (or run `codex --reload`) after install.
|
||||
Skills land in `~/.codex/skills/msd-*/SKILL.md`. Agents are written as standalone `~/.codex/agents/msd-*.toml` files, which Codex auto-discovers — that is the sole registration source for each role; `config.toml` only carries the shared `[agents]` dispatch-tuning scalar (`max_depth`), not a per-role table (#2406). Restart Codex (or run `codex --reload`) after install.
|
||||
|
||||
**Minimum supported version:** Codex CLI 0.130.0. Earlier versions had additional skill-root scanning that can produce duplicate listings.
|
||||
|
||||
**Hook coverage**
|
||||
|
||||
GSD registers the following Codex hook event automatically on install (requires Codex CLI 0.137.0+ for the stable hook-event schema):
|
||||
MSD registers the following Codex hook event automatically on install (requires Codex CLI 0.137.0+ for the stable hook-event schema):
|
||||
|
||||
| Event | Hook | Purpose |
|
||||
|---|---|---|
|
||||
| `SessionStart` | `gsd-check-update.js` | Update check at session open; Windows installs also emit a `commandWindows` field pointing to the `.cmd` shim so Codex picks the correct executor on Windows without requiring per-OS config regeneration |
|
||||
| `SessionStart` | `msd-check-update.js` | Update check at session open; Windows installs also emit a `commandWindows` field pointing to the `.cmd` shim so Codex picks the correct executor on Windows without requiring per-OS config regeneration |
|
||||
|
||||
**Context warnings are not supported on Codex (#2586).** Earlier revisions of GSD also registered `SubagentStart`/`Stop`/`PostToolUse` (plus, briefly, six more events) against `gsd-context-monitor.js` for context-headroom tracking. That hook only produces a warning by reading a remaining-context-percentage bridge file that `gsd-statusline.js` — Claude Code's own statusline mechanism — writes; Codex never installs a statusline writer, so every one of those registrations fired as a guaranteed silent no-op, every invocation, with no exceptions. GSD no longer copies or registers `gsd-context-monitor.js` on a fresh Codex install; a reinstall over an older GSD install removes the stale registrations and the now-unreferenced script automatically. Agent-facing context warnings and GSD phase/lifecycle display remain unsupported capabilities on Codex (see `capabilities/codex/capability.json`) until a real metrics producer exists for this runtime — native Codex `/statusline` configuration is a separate, not-yet-implemented surface.
|
||||
**Context warnings are not supported on Codex (#2586).** Earlier revisions of MSD also registered `SubagentStart`/`Stop`/`PostToolUse` (plus, briefly, six more events) against `msd-context-monitor.js` for context-headroom tracking. That hook only produces a warning by reading a remaining-context-percentage bridge file that `msd-statusline.js` — Claude Code's own statusline mechanism — writes; Codex never installs a statusline writer, so every one of those registrations fired as a guaranteed silent no-op, every invocation, with no exceptions. MSD no longer copies or registers `msd-context-monitor.js` on a fresh Codex install; a reinstall over an older MSD install removes the stale registrations and the now-unreferenced script automatically. Agent-facing context warnings and MSD phase/lifecycle display remain unsupported capabilities on Codex (see `capabilities/codex/capability.json`) until a real metrics producer exists for this runtime — native Codex `/statusline` configuration is a separate, not-yet-implemented surface.
|
||||
|
||||
All registered hooks are managed by GSD and are removed cleanly on `--uninstall`.
|
||||
All registered hooks are managed by MSD and are removed cleanly on `--uninstall`.
|
||||
|
||||
---
|
||||
|
||||
### Kimi CLI
|
||||
|
||||
> **Support boundary — legacy `kimi-cli` vs Kimi Code.** This integration targets the legacy/Python `kimi-cli` custom-agent contract. The `kimi --agent-file <configRoot>/agents/gsd.yaml` launch shown below is accepted by `kimi-cli`. The newer npm Kimi Code (`@moonshot-ai/kimi-code`, e.g. `0.11.0`) does **not** accept `--agent-file`; it discovers skills through fixed skill roots and `--skills-dir`. The generated `/skill:gsd-*` skills work in both, but the custom-agent (`--agent-file`) surface is specific to legacy `kimi-cli`. For Kimi Code, point it at the installed skills root with `--skills-dir <configRoot>/skills` instead of using `--agent-file`.
|
||||
> **Support boundary — legacy `kimi-cli` vs Kimi Code.** This integration targets the legacy/Python `kimi-cli` custom-agent contract. The `kimi --agent-file <configRoot>/agents/msd.yaml` launch shown below is accepted by `kimi-cli`. The newer npm Kimi Code (`@moonshot-ai/kimi-code`, e.g. `0.11.0`) does **not** accept `--agent-file`; it discovers skills through fixed skill roots and `--skills-dir`. The generated `/skill:msd-*` skills work in both, but the custom-agent (`--agent-file`) surface is specific to legacy `kimi-cli`. For Kimi Code, point it at the installed skills root with `--skills-dir <configRoot>/skills` instead of using `--agent-file`.
|
||||
|
||||
```bash
|
||||
npx @opengsd/gsd-core@latest --kimi --global
|
||||
npx @golem15/msd-core@latest --kimi --global
|
||||
```
|
||||
|
||||
Skills land in Kimi's first existing generic user skills root:
|
||||
|
||||
- `~/.config/agents/skills/gsd-*/SKILL.md` when `~/.config/agents/skills` already exists, or when neither generic root exists yet
|
||||
- `~/.agents/skills/gsd-*/SKILL.md` when `~/.agents/skills` already exists and `~/.config/agents/skills` does not
|
||||
- `~/.config/agents/skills/msd-*/SKILL.md` when `~/.config/agents/skills` already exists, or when neither generic root exists yet
|
||||
- `~/.agents/skills/msd-*/SKILL.md` when `~/.agents/skills` already exists and `~/.config/agents/skills` does not
|
||||
|
||||
Start a new Kimi CLI session after install, then invoke GSD skills with `/skill:gsd-*`, for example:
|
||||
Start a new Kimi CLI session after install, then invoke MSD skills with `/skill:msd-*`, for example:
|
||||
|
||||
```text
|
||||
/skill:gsd-new-project
|
||||
/skill:msd-new-project
|
||||
```
|
||||
|
||||
The installer also writes the GSD custom agent definition to the same selected config root: `<configRoot>/agents/gsd.yaml` with its prompt at `<configRoot>/agents/gsd.md`; subagents land under `<configRoot>/agents/subagents/gsd-*.yaml` and `<configRoot>/agents/subagents/gsd-*.md`.
|
||||
The installer also writes the MSD custom agent definition to the same selected config root: `<configRoot>/agents/msd.yaml` with its prompt at `<configRoot>/agents/msd.md`; subagents land under `<configRoot>/agents/subagents/msd-*.yaml` and `<configRoot>/agents/subagents/msd-*.md`.
|
||||
|
||||
Kimi custom agents do not auto-activate just because the files exist. Launch Kimi with the generated agent file when you want the GSD agent surface:
|
||||
Kimi custom agents do not auto-activate just because the files exist. Launch Kimi with the generated agent file when you want the MSD agent surface:
|
||||
|
||||
```bash
|
||||
kimi --agent-file ~/.config/agents/agents/gsd.yaml
|
||||
kimi --agent-file ~/.config/agents/agents/msd.yaml
|
||||
```
|
||||
|
||||
If your machine already uses `~/.agents/skills` and does not have `~/.config/agents/skills`, GSD installs there instead and the launch command becomes:
|
||||
If your machine already uses `~/.agents/skills` and does not have `~/.config/agents/skills`, MSD installs there instead and the launch command becomes:
|
||||
|
||||
```bash
|
||||
kimi --agent-file ~/.agents/agents/gsd.yaml
|
||||
kimi --agent-file ~/.agents/agents/msd.yaml
|
||||
```
|
||||
|
||||
> **If you are on Kimi Code, use `--kimi-code`, not `--kimi` with a redirected config dir.** Since 1.10.0 (#2755) Kimi Code is its own runtime with its own hooks root:
|
||||
>
|
||||
> ```bash
|
||||
> npx @opengsd/gsd-core@latest --kimi-code --global
|
||||
> npx @golem15/msd-core@latest --kimi-code --global
|
||||
> ```
|
||||
>
|
||||
> `--config-dir` and `KIMI_CONFIG_DIR` select the *skills* root only. They do **not** move the native `config.toml` that carries GSD's `[[hooks]]` block — that root is chosen by the runtime (`~/.kimi` for `--kimi` via `KIMI_SHARE_DIR`, `~/.kimi-code` for `--kimi-code` via `KIMI_CODE_HOME`). Running `--kimi --config-dir ~/.kimi-code` therefore puts your skills under `~/.kimi-code` while the hooks still land in `~/.kimi` — the exact split that left orphaned hooks behind before 1.10.0. See [Migrating from `--kimi` to `--kimi-code`](../migration/kimi-to-kimi-code.md), which also covers reclaiming artifacts an older install already wrote.
|
||||
> `--config-dir` and `KIMI_CONFIG_DIR` select the *skills* root only. They do **not** move the native `config.toml` that carries MSD's `[[hooks]]` block — that root is chosen by the runtime (`~/.kimi` for `--kimi` via `KIMI_SHARE_DIR`, `~/.kimi-code` for `--kimi-code` via `KIMI_CODE_HOME`). Running `--kimi --config-dir ~/.kimi-code` therefore puts your skills under `~/.kimi-code` while the hooks still land in `~/.kimi` — the exact split that left orphaned hooks behind before 1.10.0. See [Migrating from `--kimi` to `--kimi-code`](../migration/kimi-to-kimi-code.md), which also covers reclaiming artifacts an older install already wrote.
|
||||
|
||||
Kimi CLI also discovers user skills from the brand-specific `~/.kimi-code` directory. If you are genuinely on **Kimi CLI** and your setup is centered on `~/.kimi-code`, redirect its skills root explicitly:
|
||||
|
||||
```bash
|
||||
npx @opengsd/gsd-core@latest --kimi --global --config-dir ~/.kimi-code
|
||||
npx @golem15/msd-core@latest --kimi --global --config-dir ~/.kimi-code
|
||||
```
|
||||
|
||||
Then launch the generated agent from that directory:
|
||||
|
||||
```bash
|
||||
kimi --agent-file ~/.kimi-code/agents/gsd.yaml
|
||||
kimi --agent-file ~/.kimi-code/agents/msd.yaml
|
||||
```
|
||||
|
||||
For brand-specific scripted installs, use:
|
||||
|
||||
```bash
|
||||
KIMI_CONFIG_DIR=~/.kimi-code npx @opengsd/gsd-core@latest --kimi --global
|
||||
KIMI_CONFIG_DIR=~/.kimi-code npx @golem15/msd-core@latest --kimi --global
|
||||
```
|
||||
|
||||
Avoid arbitrary `KIMI_CONFIG_DIR` roots unless your Kimi configuration also adds the matching `skills/` directory to Kimi's extra skill directories. GSD can write files there, but Kimi will not auto-discover skills outside its documented generic and brand-specific roots without that Kimi-side configuration.
|
||||
Avoid arbitrary `KIMI_CONFIG_DIR` roots unless your Kimi configuration also adds the matching `skills/` directory to Kimi's extra skill directories. MSD can write files there, but Kimi will not auto-discover skills outside its documented generic and brand-specific roots without that Kimi-side configuration.
|
||||
|
||||
`--kimi --local` is intentionally deferred and guarded in v1; use the global install path above for Kimi CLI.
|
||||
|
||||
**Hook coverage**
|
||||
|
||||
GSD wires its lifecycle hooks into Kimi's native `[[hooks]]` array in `config.toml` — by default `~/.kimi/config.toml` (overridable via Kimi's own `KIMI_SHARE_DIR` environment variable, a directory deliberately separate from the `~/.config/agents` skills root above). Kimi CLI's hooks system is documented as **Beta**. GSD's entries are wrapped in `# GSD Hooks BEGIN`/`# GSD Hooks END` marker comments, so reinstalling only ever rewrites GSD's own block and never touches hand-written `[[hooks]]` entries around it.
|
||||
MSD wires its lifecycle hooks into Kimi's native `[[hooks]]` array in `config.toml` — by default `~/.kimi/config.toml` (overridable via Kimi's own `KIMI_SHARE_DIR` environment variable, a directory deliberately separate from the `~/.config/agents` skills root above). Kimi CLI's hooks system is documented as **Beta**. MSD's entries are wrapped in `# MSD Hooks BEGIN`/`# MSD Hooks END` marker comments, so reinstalling only ever rewrites MSD's own block and never touches hand-written `[[hooks]]` entries around it.
|
||||
|
||||
| Event | Hook | Purpose |
|
||||
|---|---|---|
|
||||
| `SessionStart` | `gsd-check-update.js`, `gsd-session-state.sh` | Update check and session-state bootstrap at session open |
|
||||
| `PreToolUse` | `gsd-prompt-guard.js`, `gsd-read-guard.js`, `gsd-worktree-path-guard.js`, `gsd-workflow-guard.js`, `gsd-secret-read-guard.js`, `gsd-validate-commit.sh` | Prompt-injection guard, read-before-edit guidance, worktree path safety, workflow guard, secret-file read protection, and commit validation before tool calls |
|
||||
| `PostToolUse` | `gsd-context-monitor.js`, `gsd-phase-boundary.sh`, `gsd-read-injection-scanner.js`, `gsd-graphify-update.sh` | Context window tracking, phase-boundary detection, read-time injection scanning, and graph updates after tool calls |
|
||||
| `Stop` | `gsd-context-monitor.js` | Context headroom tracking before the model stops |
|
||||
| `PreCompact` | `gsd-context-monitor.js` | Context headroom tracking before compaction |
|
||||
| `SubagentStart` | `gsd-context-monitor.js` | Inject context / GSD_AGENT_NAME awareness at subagent open |
|
||||
| `SubagentStop` | `gsd-context-monitor.js` | Context headroom tracking at subagent stop |
|
||||
| `SessionStart` | `msd-check-update.js`, `msd-session-state.sh` | Update check and session-state bootstrap at session open |
|
||||
| `PreToolUse` | `msd-prompt-guard.js`, `msd-read-guard.js`, `msd-worktree-path-guard.js`, `msd-workflow-guard.js`, `msd-secret-read-guard.js`, `msd-validate-commit.sh` | Prompt-injection guard, read-before-edit guidance, worktree path safety, workflow guard, secret-file read protection, and commit validation before tool calls |
|
||||
| `PostToolUse` | `msd-context-monitor.js`, `msd-phase-boundary.sh`, `msd-read-injection-scanner.js`, `msd-graphify-update.sh` | Context window tracking, phase-boundary detection, read-time injection scanning, and graph updates after tool calls |
|
||||
| `Stop` | `msd-context-monitor.js` | Context headroom tracking before the model stops |
|
||||
| `PreCompact` | `msd-context-monitor.js` | Context headroom tracking before compaction |
|
||||
| `SubagentStart` | `msd-context-monitor.js` | Inject context / MSD_AGENT_NAME awareness at subagent open |
|
||||
| `SubagentStop` | `msd-context-monitor.js` | Context headroom tracking at subagent stop |
|
||||
|
||||
All registered hooks are managed by GSD and are removed cleanly on `--uninstall`.
|
||||
All registered hooks are managed by MSD and are removed cleanly on `--uninstall`.
|
||||
|
||||
---
|
||||
|
||||
### GitHub Copilot
|
||||
|
||||
```bash
|
||||
npx @opengsd/gsd-core@latest --copilot --global
|
||||
npx @golem15/msd-core@latest --copilot --global
|
||||
```
|
||||
|
||||
Skills land in `~/.copilot/`. GSD installs as agent `.md` files and repository instruction files.
|
||||
Skills land in `~/.copilot/`. MSD installs as agent `.md` files and repository instruction files.
|
||||
|
||||
GSD also wires Copilot's lifecycle hooks and instruction files:
|
||||
MSD also wires Copilot's lifecycle hooks and instruction files:
|
||||
|
||||
- **`AGENTS.md`** (local installs) — written at the repository root, which GitHub Copilot CLI reads as primary instructions, alongside `copilot-instructions.md`.
|
||||
- **Lifecycle hook** — a `sessionStart` hook config is written to `.github/hooks/gsd-session.json` (local) or `~/.copilot/hooks/gsd-session.json` (global). It is a self-contained inline `command` hook (no separate hook script to install), so it can never reference a missing script. The hook is advisory-only: at session start it surfaces whether the project has a `.planning/` workflow.
|
||||
- **Lifecycle hook** — a `sessionStart` hook config is written to `.github/hooks/msd-session.json` (local) or `~/.copilot/hooks/msd-session.json` (global). It is a self-contained inline `command` hook (no separate hook script to install), so it can never reference a missing script. The hook is advisory-only: at session start it surfaces whether the project has a `.planning/` workflow.
|
||||
|
||||
Both are removed (and any user-authored content preserved) on `--uninstall`.
|
||||
|
||||
**Override the install directory:**
|
||||
|
||||
```bash
|
||||
COPILOT_CONFIG_DIR=~/.copilot-alt npx @opengsd/gsd-core@latest --copilot --global
|
||||
COPILOT_CONFIG_DIR=~/.copilot-alt npx @golem15/msd-core@latest --copilot --global
|
||||
```
|
||||
|
||||
---
|
||||
@@ -290,15 +290,15 @@ COPILOT_CONFIG_DIR=~/.copilot-alt npx @opengsd/gsd-core@latest --copilot --globa
|
||||
### Cursor
|
||||
|
||||
```bash
|
||||
npx @opengsd/gsd-core@latest --cursor --global
|
||||
npx @golem15/msd-core@latest --cursor --global
|
||||
```
|
||||
|
||||
Artifacts land in `~/.cursor/`. GSD installs skills (`~/.cursor/skills/gsd-*/SKILL.md`), agents, and rule references. Cursor exposes each skill once in the `/` menu while keeping it available for contextual model invocation. Upgrading removes manifest-managed legacy `~/.cursor/commands/gsd-*.md` copies that previously duplicated those menu entries; unknown user-authored command files are preserved.
|
||||
Artifacts land in `~/.cursor/`. MSD installs skills (`~/.cursor/skills/msd-*/SKILL.md`), agents, and rule references. Cursor exposes each skill once in the `/` menu while keeping it available for contextual model invocation. Upgrading removes manifest-managed legacy `~/.cursor/commands/msd-*.md` copies that previously duplicated those menu entries; unknown user-authored command files are preserved.
|
||||
|
||||
**Override the install directory:**
|
||||
|
||||
```bash
|
||||
CURSOR_CONFIG_DIR=~/.cursor-alt npx @opengsd/gsd-core@latest --cursor --global
|
||||
CURSOR_CONFIG_DIR=~/.cursor-alt npx @golem15/msd-core@latest --cursor --global
|
||||
```
|
||||
|
||||
---
|
||||
@@ -308,50 +308,50 @@ CURSOR_CONFIG_DIR=~/.cursor-alt npx @opengsd/gsd-core@latest --cursor --global
|
||||
Windsurf has rebranded to **Devin Desktop**. Both runtime names are accepted — use either `--windsurf` or `--devin-desktop`.
|
||||
|
||||
```bash
|
||||
npx @opengsd/gsd-core@latest --windsurf --global
|
||||
npx @golem15/msd-core@latest --windsurf --global
|
||||
# or equivalently:
|
||||
npx @opengsd/gsd-core@latest --devin-desktop --global
|
||||
npx @golem15/msd-core@latest --devin-desktop --global
|
||||
```
|
||||
|
||||
Use a workspace install for Windsurf slash commands. Workspace installs write `/gsd-*` commands as Windsurf workflow files under `.windsurf/workflows/`. Windsurf discovers those `.md` workflow files in Cascade and exposes them through the `/` menu. Global-scope Windsurf workflow installation is intentionally a no-op for now because global workflow locations are outside GSD's normal user-owned runtime config directory.
|
||||
Use a workspace install for Windsurf slash commands. Workspace installs write `/msd-*` commands as Windsurf workflow files under `.windsurf/workflows/`. Windsurf discovers those `.md` workflow files in Cascade and exposes them through the `/` menu. Global-scope Windsurf workflow installation is intentionally a no-op for now because global workflow locations are outside MSD's normal user-owned runtime config directory.
|
||||
|
||||
**Override the install directory:**
|
||||
|
||||
```bash
|
||||
WINDSURF_CONFIG_DIR=~/.codeium/windsurf-alt npx @opengsd/gsd-core@latest --windsurf --global
|
||||
WINDSURF_CONFIG_DIR=~/.codeium/windsurf-alt npx @golem15/msd-core@latest --windsurf --global
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Cline
|
||||
|
||||
GSD gives Cline both skills (≥ v3.48.0) and the `.clinerules/` directory integration — no custom slash commands are registered.
|
||||
MSD gives Cline both skills (≥ v3.48.0) and the `.clinerules/` directory integration — no custom slash commands are registered.
|
||||
|
||||
```bash
|
||||
# Global install (all projects — skills + rules directory)
|
||||
npx @opengsd/gsd-core@latest --cline --global
|
||||
npx @golem15/msd-core@latest --cline --global
|
||||
|
||||
# Local install (this project only — rules directory only)
|
||||
npx @opengsd/gsd-core@latest --cline --local
|
||||
npx @golem15/msd-core@latest --cline --local
|
||||
```
|
||||
|
||||
GSD writes the [`.clinerules/` directory form](https://docs.cline.bot/customization/cline-rules):
|
||||
MSD writes the [`.clinerules/` directory form](https://docs.cline.bot/customization/cline-rules):
|
||||
|
||||
- **`.clinerules/gsd.md`** — the GSD rule file. Cline loads every `.md`/`.txt` file in
|
||||
- **`.clinerules/msd.md`** — the MSD rule file. Cline loads every `.md`/`.txt` file in
|
||||
the `.clinerules/` directory automatically; no custom slash commands are registered.
|
||||
- **`.clinerules/hooks/PreToolUse`** — a [lifecycle hook](https://cline.bot/blog/cline-v3-36-hooks)
|
||||
(Cline v3.36+). It is an executable script that receives the tool-call context as JSON on
|
||||
stdin and returns a JSON decision (`cancel` / `errorMessage` / `contextModification`). The
|
||||
GSD hook guards `.planning/` artifacts from direct edits and otherwise allows the operation;
|
||||
MSD hook guards `.planning/` artifacts from direct edits and otherwise allows the operation;
|
||||
it fails open, so a hook error never blocks you. Cline runs hooks on macOS and Linux only.
|
||||
|
||||
**Global install additionally:**
|
||||
|
||||
- Emits each GSD command as **`~/.cline/skills/<name>/SKILL.md`**. Cline ≥ v3.48.0 loads
|
||||
- Emits each MSD command as **`~/.cline/skills/<name>/SKILL.md`**. Cline ≥ v3.48.0 loads
|
||||
skills from `~/.cline/skills/` automatically — no configuration needed.
|
||||
- Merges GSD instructions into **`~/.agents/AGENTS.md`**, the cross-tool global instruction
|
||||
- Merges MSD instructions into **`~/.agents/AGENTS.md`**, the cross-tool global instruction
|
||||
file Cline reads. The block is marker-delimited, so your own `AGENTS.md` content (and other
|
||||
tools' entries) is preserved, and `--uninstall` strips only the GSD block.
|
||||
tools' entries) is preserved, and `--uninstall` strips only the MSD block.
|
||||
|
||||
**Local install** writes the `.clinerules/` directory into the current project only. No skills
|
||||
directory is created for local scope.
|
||||
@@ -365,26 +365,26 @@ directory is created for local scope.
|
||||
### CodeBuddy
|
||||
|
||||
```bash
|
||||
npx @opengsd/gsd-core@latest --codebuddy --global
|
||||
npx @golem15/msd-core@latest --codebuddy --global
|
||||
```
|
||||
|
||||
GSD installs four surfaces. Slash command definitions land in `~/.codebuddy/commands/gsd-*.md` and appear as `/gsd-help`, `/gsd-phase`, `/gsd-ship`, etc. in the `/` menu. Subagents land in `~/.codebuddy/agents/gsd-*.md`. Skills land in `~/.codebuddy/skills/gsd-*/SKILL.md` — emitted with `user-invocable: false` so they stay out of the `/` menu (the commands surface is the sole `/` entry point) and remain available for model invocation. CodeBuddy hooks are written to `settings.json`. No `mcp.json` is written: GSD ships no MCP server.
|
||||
MSD installs four surfaces. Slash command definitions land in `~/.codebuddy/commands/msd-*.md` and appear as `/msd-help`, `/msd-phase`, `/msd-ship`, etc. in the `/` menu. Subagents land in `~/.codebuddy/agents/msd-*.md`. Skills land in `~/.codebuddy/skills/msd-*/SKILL.md` — emitted with `user-invocable: false` so they stay out of the `/` menu (the commands surface is the sole `/` entry point) and remain available for model invocation. CodeBuddy hooks are written to `settings.json`. No `mcp.json` is written: MSD ships no MCP server.
|
||||
|
||||
**Hook coverage**
|
||||
|
||||
GSD registers the following events automatically on install (Claude hook event dialect):
|
||||
MSD registers the following events automatically on install (Claude hook event dialect):
|
||||
|
||||
| Event | Hook | Purpose |
|
||||
|---|---|---|
|
||||
| `SessionStart` | `gsd-check-update.js`, `gsd-session-state.sh` | Update check, session orientation |
|
||||
| `PreToolUse` | `gsd-prompt-guard.js`, `gsd-read-guard.js`, `gsd-workflow-guard.js`, `gsd-worktree-path-guard.js`, `gsd-agent-isolation-guard.js`, `gsd-secret-read-guard.js`, `gsd-validate-commit.sh` | Prompt guard, read-before-edit, workflow + worktree safety, agent-dispatch isolation, secret-file read protection, commit validation |
|
||||
| `PostToolUse` | `gsd-context-monitor.js`, `gsd-read-injection-scanner.js`, `gsd-phase-boundary.sh`, `gsd-graphify-update.sh` | Context monitoring, read-time scan, phase boundary detection |
|
||||
| `SubagentStop` | `gsd-context-monitor.js` | Context headroom tracking after subagent completion |
|
||||
| `SubagentStart` | `gsd-context-monitor.js` | Context headroom tracking at subagent start |
|
||||
| `Stop` | `gsd-context-monitor.js` | Context headroom tracking before model stop |
|
||||
| `PreCompact` | `gsd-context-monitor.js` | Context awareness before conversation compaction |
|
||||
| `SessionStart` | `msd-check-update.js`, `msd-session-state.sh` | Update check, session orientation |
|
||||
| `PreToolUse` | `msd-prompt-guard.js`, `msd-read-guard.js`, `msd-workflow-guard.js`, `msd-worktree-path-guard.js`, `msd-agent-isolation-guard.js`, `msd-secret-read-guard.js`, `msd-validate-commit.sh` | Prompt guard, read-before-edit, workflow + worktree safety, agent-dispatch isolation, secret-file read protection, commit validation |
|
||||
| `PostToolUse` | `msd-context-monitor.js`, `msd-read-injection-scanner.js`, `msd-phase-boundary.sh`, `msd-graphify-update.sh` | Context monitoring, read-time scan, phase boundary detection |
|
||||
| `SubagentStop` | `msd-context-monitor.js` | Context headroom tracking after subagent completion |
|
||||
| `SubagentStart` | `msd-context-monitor.js` | Context headroom tracking at subagent start |
|
||||
| `Stop` | `msd-context-monitor.js` | Context headroom tracking before model stop |
|
||||
| `PreCompact` | `msd-context-monitor.js` | Context awareness before conversation compaction |
|
||||
|
||||
CodeBuddy's own [background sub-agent dispatch](https://www.codebuddy.ai/docs/cli/sub-agents) (`run_in_background: true`) is a caller-side invocation parameter, not something GSD's installed agent files control — there is no frontmatter field to set on GSD's agent artifacts to request it.
|
||||
CodeBuddy's own [background sub-agent dispatch](https://www.codebuddy.ai/docs/cli/sub-agents) (`run_in_background: true`) is a caller-side invocation parameter, not something MSD's installed agent files control — there is no frontmatter field to set on MSD's agent artifacts to request it.
|
||||
|
||||
---
|
||||
|
||||
@@ -393,59 +393,59 @@ CodeBuddy's own [background sub-agent dispatch](https://www.codebuddy.ai/docs/cl
|
||||
Qwen Code uses the same open skills standard as Claude Code 2.1.88+.
|
||||
|
||||
```bash
|
||||
npx @opengsd/gsd-core@latest --qwen --global
|
||||
npx @golem15/msd-core@latest --qwen --global
|
||||
```
|
||||
|
||||
Skills land in `~/.qwen/skills/gsd-*/SKILL.md`.
|
||||
Skills land in `~/.qwen/skills/msd-*/SKILL.md`.
|
||||
|
||||
GSD's main-loop skills are emitted with Qwen's optional numeric `priority` frontmatter field so the most-used workflows surface first in the `/skills` TUI list. Higher values sort earlier (per Qwen's skills spec), so core commands such as `/skills` for `new-project` (100), `plan-phase` (90), and `execute-phase` (85) appear above utility skills, which are left unset (default 0). This affects only the `/skills` list order — slash-command completion and `/help` remain alphabetical.
|
||||
MSD's main-loop skills are emitted with Qwen's optional numeric `priority` frontmatter field so the most-used workflows surface first in the `/skills` TUI list. Higher values sort earlier (per Qwen's skills spec), so core commands such as `/skills` for `new-project` (100), `plan-phase` (90), and `execute-phase` (85) appear above utility skills, which are left unset (default 0). This affects only the `/skills` list order — slash-command completion and `/help` remain alphabetical.
|
||||
|
||||
Subagents land in `~/.qwen/agents/gsd-*.md` as native Qwen subagents, converted to Qwen's own `name:`/`description:`/`tools:` (YAML block list) frontmatter schema rather than Claude Code's.
|
||||
Subagents land in `~/.qwen/agents/msd-*.md` as native Qwen subagents, converted to Qwen's own `name:`/`description:`/`tools:` (YAML block list) frontmatter schema rather than Claude Code's.
|
||||
|
||||
**Override the install directory:**
|
||||
|
||||
```bash
|
||||
QWEN_CONFIG_DIR=~/.qwen-alt npx @opengsd/gsd-core@latest --qwen --global
|
||||
QWEN_CONFIG_DIR=~/.qwen-alt npx @golem15/msd-core@latest --qwen --global
|
||||
```
|
||||
|
||||
**Hook coverage**
|
||||
|
||||
Qwen Code supports 15 hook events. GSD registers the following events automatically on install:
|
||||
Qwen Code supports 15 hook events. MSD registers the following events automatically on install:
|
||||
|
||||
| Event | Hook | Purpose |
|
||||
|---|---|---|
|
||||
| `SessionStart` | `gsd-check-update.js`, `gsd-session-state.sh` | Update check, session orientation |
|
||||
| `PostToolUse` | `gsd-context-monitor.js`, `gsd-read-injection-scanner.js`, `gsd-phase-boundary.sh`, `gsd-graphify-update.sh` | Context monitoring, read-time scan, phase boundary detection |
|
||||
| `PreToolUse` | `gsd-prompt-guard.js`, `gsd-read-guard.js`, `gsd-workflow-guard.js`, `gsd-worktree-path-guard.js`, `gsd-agent-isolation-guard.js`, `gsd-secret-read-guard.js`, `gsd-validate-commit.sh` | Prompt guard, read-before-edit, workflow + worktree safety, agent-dispatch isolation, secret-file read protection, commit validation |
|
||||
| `SubagentStop` | `gsd-context-monitor.js` | Context headroom tracking after subagent completion |
|
||||
| `SubagentStart` | `gsd-context-monitor.js` | Context headroom tracking at subagent start |
|
||||
| `Stop` | `gsd-context-monitor.js` | Context headroom tracking before model stop |
|
||||
| `PreCompact` | `gsd-context-monitor.js` | Context awareness before conversation compaction |
|
||||
| `SessionStart` | `msd-check-update.js`, `msd-session-state.sh` | Update check, session orientation |
|
||||
| `PostToolUse` | `msd-context-monitor.js`, `msd-read-injection-scanner.js`, `msd-phase-boundary.sh`, `msd-graphify-update.sh` | Context monitoring, read-time scan, phase boundary detection |
|
||||
| `PreToolUse` | `msd-prompt-guard.js`, `msd-read-guard.js`, `msd-workflow-guard.js`, `msd-worktree-path-guard.js`, `msd-agent-isolation-guard.js`, `msd-secret-read-guard.js`, `msd-validate-commit.sh` | Prompt guard, read-before-edit, workflow + worktree safety, agent-dispatch isolation, secret-file read protection, commit validation |
|
||||
| `SubagentStop` | `msd-context-monitor.js` | Context headroom tracking after subagent completion |
|
||||
| `SubagentStart` | `msd-context-monitor.js` | Context headroom tracking at subagent start |
|
||||
| `Stop` | `msd-context-monitor.js` | Context headroom tracking before model stop |
|
||||
| `PreCompact` | `msd-context-monitor.js` | Context awareness before conversation compaction |
|
||||
|
||||
---
|
||||
|
||||
### Augment Code
|
||||
|
||||
```bash
|
||||
npx @opengsd/gsd-core@latest --augment --global
|
||||
npx @golem15/msd-core@latest --augment --global
|
||||
```
|
||||
|
||||
Skills land in `~/.augment/skills/` and slash command definitions land in `~/.augment/commands/`. GSD installs skills, agents, and commands (`/gsd-phase`, `/gsd-ship`, etc.). GSD's managed lifecycle hooks are registered into Augment's own `settings.json` `hooks` block (Claude hook event dialect, covering session-start, tool-use, and phase-boundary events) — no statusline ownership. #2097 also registers the GSD companion MCP server under `settings.json`'s `mcpServers.gsd` (see [Connect a host to the GSD MCP server](connect-gsd-mcp-server.md)).
|
||||
Skills land in `~/.augment/skills/` and slash command definitions land in `~/.augment/commands/`. MSD installs skills, agents, and commands (`/msd-phase`, `/msd-ship`, etc.). MSD's managed lifecycle hooks are registered into Augment's own `settings.json` `hooks` block (Claude hook event dialect, covering session-start, tool-use, and phase-boundary events) — no statusline ownership. #2097 also registers the MSD companion MCP server under `settings.json`'s `mcpServers.msd` (see [Connect a host to the MSD MCP server](connect-msd-mcp-server.md)).
|
||||
|
||||
---
|
||||
|
||||
### Antigravity
|
||||
|
||||
```bash
|
||||
npx @opengsd/gsd-core@latest --antigravity --global
|
||||
npx @golem15/msd-core@latest --antigravity --global
|
||||
```
|
||||
|
||||
The installer auto-detects the Antigravity config directory (`~/.gemini/antigravity`, `~/.gemini/antigravity-ide`, or `~/.gemini/antigravity-cli`). Uses Gemini-compatible settings policy. Global skills and agents install under `~/.gemini/config/skills/` and `~/.gemini/config/agents/` — the directories Antigravity scans for machine-local discovery (#3738); the config directory above holds settings and GSD's runtime files.
|
||||
The installer auto-detects the Antigravity config directory (`~/.gemini/antigravity`, `~/.gemini/antigravity-ide`, or `~/.gemini/antigravity-cli`). Uses Gemini-compatible settings policy. Global skills and agents install under `~/.gemini/config/skills/` and `~/.gemini/config/agents/` — the directories Antigravity scans for machine-local discovery (#3738); the config directory above holds settings and MSD's runtime files.
|
||||
|
||||
**Override the install directory:**
|
||||
|
||||
```bash
|
||||
ANTIGRAVITY_CONFIG_DIR=~/.gemini/antigravity-alt npx @opengsd/gsd-core@latest --antigravity --global
|
||||
ANTIGRAVITY_CONFIG_DIR=~/.gemini/antigravity-alt npx @golem15/msd-core@latest --antigravity --global
|
||||
```
|
||||
|
||||
---
|
||||
@@ -453,61 +453,61 @@ ANTIGRAVITY_CONFIG_DIR=~/.gemini/antigravity-alt npx @opengsd/gsd-core@latest --
|
||||
### Trae
|
||||
|
||||
```bash
|
||||
npx @opengsd/gsd-core@latest --trae --global
|
||||
npx @golem15/msd-core@latest --trae --global
|
||||
```
|
||||
|
||||
Skills land in `~/.trae/`. GSD installs skills, agents, and rule references.
|
||||
Skills land in `~/.trae/`. MSD installs skills, agents, and rule references.
|
||||
|
||||
---
|
||||
|
||||
### ZCode
|
||||
|
||||
```bash
|
||||
npx @opengsd/gsd-core@latest --zcode --global
|
||||
npx @golem15/msd-core@latest --zcode --global
|
||||
```
|
||||
|
||||
[ZCode](https://zcode.z.ai/en) is Z.ai's desktop Agentic Development Environment for the GLM-5.2 model. GSD installs skills (nested `SKILL.md` bundles), slash commands, and subagents under `~/.zcode/`:
|
||||
[ZCode](https://zcode.z.ai/en) is Z.ai's desktop Agentic Development Environment for the GLM-5.2 model. MSD installs skills (nested `SKILL.md` bundles), slash commands, and subagents under `~/.zcode/`:
|
||||
|
||||
- **Skills** → `~/.zcode/skills/gsd-<name>/SKILL.md` (invoke with `$gsd-<name>` in chat)
|
||||
- **Commands** → `~/.zcode/commands/gsd-<name>.md` (invoke with `/gsd-<name>`)
|
||||
- **Subagents** → `~/.zcode/agents/gsd-<name>.md`
|
||||
- **Skills** → `~/.zcode/skills/msd-<name>/SKILL.md` (invoke with `$msd-<name>` in chat)
|
||||
- **Commands** → `~/.zcode/commands/msd-<name>.md` (invoke with `/msd-<name>`)
|
||||
- **Subagents** → `~/.zcode/agents/msd-<name>.md`
|
||||
|
||||
ZCode's skill format is identical to Claude Code's, so no runtime-specific converter is required — GSD lands as a pure declarative descriptor with no hardcoded installer branches. ZCode also natively imports skills and MCP config from `~/.claude`; if you install GSD for **both** Claude and ZCode, you may see duplicate GSD skills inside ZCode, which is expected. To connect ZCode's MCP servers to GSD's companion server, see [how to connect the GSD MCP server](connect-gsd-mcp-server.md).
|
||||
ZCode's skill format is identical to Claude Code's, so no runtime-specific converter is required — MSD lands as a pure declarative descriptor with no hardcoded installer branches. ZCode also natively imports skills and MCP config from `~/.claude`; if you install MSD for **both** Claude and ZCode, you may see duplicate MSD skills inside ZCode, which is expected. To connect ZCode's MCP servers to MSD's companion server, see [how to connect the MSD MCP server](connect-msd-mcp-server.md).
|
||||
|
||||
GSD's hook-automation and native-MCP-registration integrations are not yet wired for ZCode — both are blocked on ZCode not yet publishing the on-disk config format for its plugin `Hook` component or the settings filename/schema for its MCP store. See the [`## zcode`](../reference/host-integration-capability-matrix.md#zcode) section of the host-integration capability matrix for the cited source URLs.
|
||||
MSD's hook-automation and native-MCP-registration integrations are not yet wired for ZCode — both are blocked on ZCode not yet publishing the on-disk config format for its plugin `Hook` component or the settings filename/schema for its MCP store. See the [`## zcode`](../reference/host-integration-capability-matrix.md#zcode) section of the host-integration capability matrix for the cited source URLs.
|
||||
|
||||
---
|
||||
|
||||
### pi
|
||||
|
||||
```bash
|
||||
npx @opengsd/gsd-core@latest --pi --global
|
||||
npx @golem15/msd-core@latest --pi --global
|
||||
```
|
||||
|
||||
**Override the install directory:**
|
||||
|
||||
```bash
|
||||
PI_CODING_AGENT_DIR=~/.pi-alt/agent npx @opengsd/gsd-core@latest --pi --global
|
||||
PI_CODING_AGENT_DIR=~/.pi-alt/agent npx @golem15/msd-core@latest --pi --global
|
||||
```
|
||||
|
||||
`PI_CODING_AGENT_DIR` is pi's own upstream override (`getAgentDir()` in pi's `config.ts`) for its global agent directory (`~/.pi/agent` by default) — GSD honors it so the install always lands where pi actually reads ([#3023](https://github.com/open-gsd/gsd-core/issues/3023)). pi also supports a `piConfig.configDir` field (`config.ts`'s `CONFIG_DIR_NAME`) that renames the `.pi` segment, but that field is read from pi's own installed `package.json`, not your project's — it is a white-label/rebranding hook for redistributed pi forks (it sits beside `piConfig.name`, which renames the app itself), not something an end user sets for their own project. GSD's pi descriptor does not target rebranded forks, so `PI_CODING_AGENT_DIR` remains the correct override for a stock pi install.
|
||||
`PI_CODING_AGENT_DIR` is pi's own upstream override (`getAgentDir()` in pi's `config.ts`) for its global agent directory (`~/.pi/agent` by default) — MSD honors it so the install always lands where pi actually reads ([#3023](https://github.com/open-gsd/gsd-core/issues/3023)). pi also supports a `piConfig.configDir` field (`config.ts`'s `CONFIG_DIR_NAME`) that renames the `.pi` segment, but that field is read from pi's own installed `package.json`, not your project's — it is a white-label/rebranding hook for redistributed pi forks (it sits beside `piConfig.name`, which renames the app itself), not something an end user sets for their own project. MSD's pi descriptor does not target rebranded forks, so `PI_CODING_AGENT_DIR` remains the correct override for a stock pi install.
|
||||
|
||||
[pi](https://pi.dev) is a bun-runtime programmatic CLI whose extensions implement pi's own `ExtensionAPI` (`registerCommand`/`registerTool`/`registerProvider`/`pi.on`) rather than a settings-file or slash-markdown surface. GSD ships a single native-extension file:
|
||||
[pi](https://pi.dev) is a bun-runtime programmatic CLI whose extensions implement pi's own `ExtensionAPI` (`registerCommand`/`registerTool`/`registerProvider`/`pi.on`) rather than a settings-file or slash-markdown surface. MSD ships a single native-extension file:
|
||||
|
||||
- **Extension** → `~/.pi/agent/extensions/gsd.js` (global) or `.pi/extensions/gsd.js` (local)
|
||||
- **Extension** → `~/.pi/agent/extensions/msd.js` (global) or `.pi/extensions/msd.js` (local)
|
||||
|
||||
The `.js` suffix is load-bearing: pi auto-discovers extensions by scanning that directory and keeping only names ending in `.ts` or `.js`, and it skips anything else **silently** — no error, no log line. GSD shipped the file as `gsd.cjs` through 1.7.0, which pi therefore never loaded, so `/gsd` never appeared ([#2470](https://github.com/open-gsd/gsd-core/issues/2470)). Upgrading removes the stale `gsd.cjs`; if you had added a manual `extensions` entry in `~/.pi/agent/settings.json` as a workaround, you can drop it.
|
||||
The `.js` suffix is load-bearing: pi auto-discovers extensions by scanning that directory and keeping only names ending in `.ts` or `.js`, and it skips anything else **silently** — no error, no log line. MSD shipped the file as `msd.cjs` through 1.7.0, which pi therefore never loaded, so `/msd` never appeared ([#2470](https://github.com/open-gsd/gsd-core/issues/2470)). Upgrading removes the stale `msd.cjs`; if you had added a manual `extensions` entry in `~/.pi/agent/settings.json` as a workaround, you can drop it.
|
||||
|
||||
The extension registers a `/gsd` command and a `gsd_invoke` tool that dispatch GSD commands via a bounded subprocess call to `gsd-core/bin/gsd-tools.cjs` (no fully-populated in-process command-routing hub exists — see the matrix's Stage 2 note). This is a **plugin-only install**: pi has no shared-settings hook surface (`hooksSurface: none`) and, unlike Claude/OpenCode/Kilo, no host-read markdown surface at all — pi's `/gsd` command is registered programmatically by the extension, not discovered from files, so GSD installs the extension plus its universal `gsd-core/` engine payload and the shared `gsd-hooks/`/`gsd-hooks/lib/` bundle (spawned by the extension itself, not by any config-file hook bus), and does **not** write any `commands/`, `agents/`, or `skills/` directory for pi. The bundle lands under `gsd-hooks/` rather than the `hooks/` name every other runtime uses because pi reserves `hooks/` for its own deprecated extension directory and warns on startup whenever that directory merely exists ([#3023](https://github.com/open-gsd/gsd-core/issues/3023)). The extension bridges GSD's `session_start`/`before_agent_start`/`session_before_compact`/`tool_call` lifecycle events to those staged `gsd-hooks/` scripts as bounded, fail-open subprocesses, and steers pi's active model (`modelMode: active`) to a tier-resolved bare anthropic id via `pi.on('before_provider_request', ...)`. See the [`## pi`](../reference/host-integration-capability-matrix.md#pi) section of the host-integration capability matrix for the negotiated axes and citations.
|
||||
The extension registers a `/msd` command and a `msd_invoke` tool that dispatch MSD commands via a bounded subprocess call to `msd-core/bin/msd-tools.cjs` (no fully-populated in-process command-routing hub exists — see the matrix's Stage 2 note). This is a **plugin-only install**: pi has no shared-settings hook surface (`hooksSurface: none`) and, unlike Claude/OpenCode/Kilo, no host-read markdown surface at all — pi's `/msd` command is registered programmatically by the extension, not discovered from files, so MSD installs the extension plus its universal `msd-core/` engine payload and the shared `msd-hooks/`/`msd-hooks/lib/` bundle (spawned by the extension itself, not by any config-file hook bus), and does **not** write any `commands/`, `agents/`, or `skills/` directory for pi. The bundle lands under `msd-hooks/` rather than the `hooks/` name every other runtime uses because pi reserves `hooks/` for its own deprecated extension directory and warns on startup whenever that directory merely exists ([#3023](https://github.com/open-gsd/gsd-core/issues/3023)). The extension bridges MSD's `session_start`/`before_agent_start`/`session_before_compact`/`tool_call` lifecycle events to those staged `msd-hooks/` scripts as bounded, fail-open subprocesses, and steers pi's active model (`modelMode: active`) to a tier-resolved bare anthropic id via `pi.on('before_provider_request', ...)`. See the [`## pi`](../reference/host-integration-capability-matrix.md#pi) section of the host-integration capability matrix for the negotiated axes and citations.
|
||||
|
||||
---
|
||||
|
||||
## Local vs global install
|
||||
|
||||
All examples above use `--global`, which installs GSD once for your user account. To scope an install to a single project, replace `--global` with `--local`:
|
||||
All examples above use `--global`, which installs MSD once for your user account. To scope an install to a single project, replace `--global` with `--local`:
|
||||
|
||||
```bash
|
||||
npx @opengsd/gsd-core@latest --claude --local
|
||||
npx @golem15/msd-core@latest --claude --local
|
||||
```
|
||||
|
||||
A local install writes into the `.claude/` directory at your project root. Local install settings take precedence over global ones when both exist.
|
||||
@@ -519,10 +519,10 @@ A local install writes into the `.claude/` directory at your project root. Local
|
||||
Prerelease editions of runtimes (Windsurf Next / Devin Desktop Next, Cursor Nightly, VS Code Insiders, Codex preview channels, etc.) read from a sibling config directory. Set the matching `*_CONFIG_DIR` env var before running the installer:
|
||||
|
||||
```bash
|
||||
WINDSURF_CONFIG_DIR=~/.codeium/windsurf-next npx @opengsd/gsd-core@latest --windsurf --global
|
||||
WINDSURF_CONFIG_DIR=~/.codeium/windsurf-next npx @golem15/msd-core@latest --windsurf --global
|
||||
```
|
||||
|
||||
Select the corresponding stable runtime in the installer prompt. GSD does not enumerate prerelease editions as separate named runtimes — they are best-effort via this env-var mechanism and are not separately tested in release CI.
|
||||
Select the corresponding stable runtime in the installer prompt. MSD does not enumerate prerelease editions as separate named runtimes — they are best-effort via this env-var mechanism and are not separately tested in release CI.
|
||||
|
||||
---
|
||||
|
||||
@@ -531,16 +531,16 @@ Select the corresponding stable runtime in the installer prompt. GSD does not en
|
||||
When one config root (`~/.claude`, `~/.config/opencode`, …) is mounted or synced into
|
||||
machines with different Node.js layouts — a host plus Docker containers bind-mounting the
|
||||
same directory, or WSL and Windows sharing a drive — install with `--portable-hooks`
|
||||
(or `GSD_PORTABLE_HOOKS=1`):
|
||||
(or `MSD_PORTABLE_HOOKS=1`):
|
||||
|
||||
```bash
|
||||
npx @opengsd/gsd-core@latest --claude --global --portable-hooks
|
||||
npx @golem15/msd-core@latest --claude --global --portable-hooks
|
||||
```
|
||||
|
||||
Hook script paths are emitted `$HOME`-relative, and every managed JavaScript hook command
|
||||
resolves its node binary at hook-fire time instead of depending on whichever machine ran
|
||||
the installer (#3662): portable installs route through a staged
|
||||
`hooks/gsd-node-runner.sh` resolver (the install-time node path first, then `command -v
|
||||
`hooks/msd-node-runner.sh` resolver (the install-time node path first, then `command -v
|
||||
node`, then the well-known layouts); non-portable installs carry an equivalent inline
|
||||
fallback chain. The install-time path is always tried first, so GUI launches with a
|
||||
minimal `PATH` keep working, and a bare `node` lookup is never depended on. Re-running
|
||||
@@ -548,34 +548,34 @@ install or update from any of the environments converges stale runner paths —
|
||||
state where some hooks work in one environment and the rest in another.
|
||||
|
||||
To pin down which node a given environment picks, run the resolver directly with
|
||||
`GSD_NODE_RUNNER_NO_FALLBACKS=1` (first-argument-only resolution) — it prints a stderr
|
||||
`MSD_NODE_RUNNER_NO_FALLBACKS=1` (first-argument-only resolution) — it prints a stderr
|
||||
diagnostic and exits non-zero when nothing resolves.
|
||||
|
||||
---
|
||||
|
||||
## Local installs across several git worktrees
|
||||
|
||||
A local (`--local`) install writes the includes that point at GSD's own installed
|
||||
A local (`--local`) install writes the includes that point at MSD's own installed
|
||||
files as absolute paths — the path the installer resolved at install time. For a
|
||||
single checkout that is invisible and works fine.
|
||||
|
||||
It stops working once the same repository is checked out more than once. Each git
|
||||
worktree gets its own `.claude/` copy, but every one of those copies points back at
|
||||
the checkout that ran the installer. So a worktree runs its own `gsd-tools.cjs`
|
||||
the checkout that ran the installer. So a worktree runs its own `msd-tools.cjs`
|
||||
(correctly resolved through `git rev-parse --show-toplevel`) while reading its
|
||||
workflow prose out of a different checkout — and the moment you update that one
|
||||
checkout, every other worktree is executing new instructions against an old engine,
|
||||
with no way to stage the update.
|
||||
|
||||
Install with `--relative-includes` (or `GSD_RELATIVE_INCLUDES=1`) to write the
|
||||
Install with `--relative-includes` (or `MSD_RELATIVE_INCLUDES=1`) to write the
|
||||
includes relative to the project instead:
|
||||
|
||||
```bash
|
||||
npx @opengsd/gsd-core@latest --claude --local --relative-includes
|
||||
npx @golem15/msd-core@latest --claude --local --relative-includes
|
||||
```
|
||||
|
||||
Every emitted `@` include then reads `@.claude/gsd-core/...` rather than
|
||||
`@/absolute/path/to/checkout/.claude/gsd-core/...`, so each worktree resolves its
|
||||
Every emitted `@` include then reads `@.claude/msd-core/...` rather than
|
||||
`@/absolute/path/to/checkout/.claude/msd-core/...`, so each worktree resolves its
|
||||
own copy and the worktrees become independent.
|
||||
|
||||
Notes:
|
||||
@@ -585,7 +585,7 @@ Notes:
|
||||
- **Global installs are unaffected.** They keep their `$HOME`-relative form, which
|
||||
is already checkout-independent.
|
||||
- **The runtime launcher keeps its absolute fallbacks.** The shell snippet that
|
||||
locates `gsd-tools.cjs` probes `${CLAUDE_CONFIG_DIR:-$HOME/.claude}` and one such
|
||||
locates `msd-tools.cjs` probes `${CLAUDE_CONFIG_DIR:-$HOME/.claude}` and one such
|
||||
default per runtime; those are shell word expansions, not includes, and a relative
|
||||
value there would resolve against the current shell's directory rather than the
|
||||
project. The launcher already probes `$(git rev-parse --show-toplevel)/.claude`
|
||||
@@ -602,11 +602,11 @@ If you cannot run `npx` (for example, on a Windows machine without Node.js), you
|
||||
**Option A — Use a machine that has Node.js.** Any machine with Node.js will do: WSL, a Linux VM, a CI runner, or a Docker container. Run the installer there, then copy the output directory to your target machine. For OpenCode:
|
||||
|
||||
```bash
|
||||
npx @opengsd/gsd-core@latest --opencode --global
|
||||
npx @golem15/msd-core@latest --opencode --global
|
||||
# Then copy ~/.config/opencode/agents/ to the Windows machine
|
||||
```
|
||||
|
||||
**Option B — Manually transform the source files.** The agent source files live in `agents/` in the GSD Core repository and are in Claude Code's native frontmatter format. Each runtime expects a different shape. For the exact field transformations per runtime, see [Manual install / no-Node.js setup](../USER-GUIDE.md#manual-install--no-nodejs-setup) in the User Guide, which covers the OpenCode transformations in full detail and points to the installer's `convert*Frontmatter` functions for other runtimes.
|
||||
**Option B — Manually transform the source files.** The agent source files live in `agents/` in the MSD Core repository and are in Claude Code's native frontmatter format. Each runtime expects a different shape. For the exact field transformations per runtime, see [Manual install / no-Node.js setup](../USER-GUIDE.md#manual-install--no-nodejs-setup) in the User Guide, which covers the OpenCode transformations in full detail and points to the installer's `convert*Frontmatter` functions for other runtimes.
|
||||
|
||||
---
|
||||
|
||||
@@ -615,8 +615,8 @@ npx @opengsd/gsd-core@latest --opencode --global
|
||||
Restart your runtime to pick up new commands and agents. Then start a new project or onboard an existing repo:
|
||||
|
||||
```bash
|
||||
/gsd-new-project # greenfield project
|
||||
/gsd-onboard # existing codebase
|
||||
/msd-new-project # greenfield project
|
||||
/msd-onboard # existing codebase
|
||||
```
|
||||
|
||||
If the command is not found after restart, verify the install directory matches the runtime's expected config path. The prerelease-editions section above covers the most common mismatch.
|
||||
@@ -636,6 +636,6 @@ If the directory is already on your PATH but the installer still warns, open a n
|
||||
## Related
|
||||
|
||||
- [Your first project](../tutorials/your-first-project.md)
|
||||
- [Update GSD Core](update-gsd.md)
|
||||
- [Update MSD Core](update-msd.md)
|
||||
- [Configuration](../CONFIGURATION.md)
|
||||
- [Docs index](../README.md)
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
# How to interpret install-shadow warnings
|
||||
|
||||
**Goal:** Understand the advisory GSD Core prints when a `/gsd-*` trigger is installed at more than one scope and one scope silently wins, tell which scope actually wins, know what to do about it, and tell "nothing to report" apart from "could not look".
|
||||
**Goal:** Understand the advisory MSD Core prints when a `/msd-*` trigger is installed at more than one scope and one scope silently wins, tell which scope actually wins, know what to do about it, and tell "nothing to report" apart from "could not look".
|
||||
|
||||
**Prerequisites:** GSD Core installed on a Claude Code (or other skills-capable) runtime at more than one scope on the same machine — most commonly `--claude --global` (writes personal skills to `~/.claude/`) followed or preceded by `--claude --local` in a project (writes project commands to `<repo>/.claude/`).
|
||||
**Prerequisites:** MSD Core installed on a Claude Code (or other skills-capable) runtime at more than one scope on the same machine — most commonly `--claude --global` (writes personal skills to `~/.claude/`) followed or preceded by `--claude --local` in a project (writes project commands to `<repo>/.claude/`).
|
||||
|
||||
---
|
||||
|
||||
## What the warning means
|
||||
|
||||
Claude Code resolves a `/gsd-<name>` trigger through two rules, both documented by the host: **personal scope overrides project scope**, and **a skill overrides a command of the same name**. GSD's own Claude artifact layout installs global (personal) as **skills** and local (project) as **commands** — so when both scopes are installed, both rules point the same way, and the global skill wins every time. The project's own `.claude/gsd-core/` spec tree — the workflow and reference files the local command correctly points at — becomes unreachable through the trigger, with no error and no missing file. Nothing in the local install is broken; it is simply never invoked (issue #2218).
|
||||
Claude Code resolves a `/msd-<name>` trigger through two rules, both documented by the host: **personal scope overrides project scope**, and **a skill overrides a command of the same name**. MSD's own Claude artifact layout installs global (personal) as **skills** and local (project) as **commands** — so when both scopes are installed, both rules point the same way, and the global skill wins every time. The project's own `.claude/msd-core/` spec tree — the workflow and reference files the local command correctly points at — becomes unreachable through the trigger, with no error and no missing file. Nothing in the local install is broken; it is simply never invoked (issue #2218).
|
||||
|
||||
The warning is GSD Core's fix for the "with no error" half of that sentence — it does not change which scope wins (see [Known limits](#known-limits)). You will see it in two places, projecting the identical fact:
|
||||
The warning is MSD Core's fix for the "with no error" half of that sentence — it does not change which scope wins (see [Known limits](#known-limits)). You will see it in two places, projecting the identical fact:
|
||||
|
||||
- **At install time**, printed once after the manifest write completes, whichever scope you install second (design: shadowing can only exist once both scopes exist, and the report is always downstream of a successful `writeManifest`, never upstream of a failed one).
|
||||
- **From `/gsd-health`**, as diagnostic code **`W028`**, severity `WARNING` — see [Health diagnostic codes](../COMMANDS.md#gsd-health) for where this fits alongside the rest of the `Wnnn`/`Ennn`/`Innn` space. `--json` health output carries the same structured fact.
|
||||
- **From `/msd-health`**, as diagnostic code **`W028`**, severity `WARNING` — see [Health diagnostic codes](../COMMANDS.md#msd-health) for where this fits alongside the rest of the `Wnnn`/`Ennn`/`Innn` space. `--json` health output carries the same structured fact.
|
||||
|
||||
A realistic install-time warning:
|
||||
|
||||
```
|
||||
2 triggers shadowed: the local commands surface is unreachable through those triggers — global skills wins instead.
|
||||
- gsd-execute-phase: local/commands shadowed by global/skills
|
||||
- gsd-plan-phase: local/commands shadowed by global/skills
|
||||
- msd-execute-phase: local/commands shadowed by global/skills
|
||||
- msd-plan-phase: local/commands shadowed by global/skills
|
||||
```
|
||||
|
||||
For a runtime whose global scope also installs **skills** (12 of the 19 supported runtimes install `skills` at both scopes), the wording is deliberately different, because nothing disappears — the loser is merely overridden, not orphaned:
|
||||
@@ -37,7 +37,7 @@ A report with more than 5 shadowed triggers shows the first 5 and a `...and N mo
|
||||
|
||||
Read the first line of the report. It always names the losing side first (`the <scope> <kind> surface/entry`) and the winning side last (`<scope> <kind> wins instead` / `overridden by <scope> <kind>`). Each subsequent bullet repeats the same fact per trigger: `<trigger>: <shadowed scope>/<shadowed kind> shadowed by <winner scope>/<winner kind>`.
|
||||
|
||||
On Claude Code specifically, the winner is always `global/skills` when both scopes are installed — that is the mechanism described above, not a per-machine coin flip. If you need to confirm this for yourself independent of the warning: run `/gsd-<name>` and check which "Base directory for this skill" (or equivalent skill-injection marker) the host reports.
|
||||
On Claude Code specifically, the winner is always `global/skills` when both scopes are installed — that is the mechanism described above, not a per-machine coin flip. If you need to confirm this for yourself independent of the warning: run `/msd-<name>` and check which "Base directory for this skill" (or equivalent skill-injection marker) the host reports.
|
||||
|
||||
An optional `Note:` line after the trigger list means one scope's own manifest disagrees with the directory it was actually found in (for example, a manifest copied between machines, or an `--config-dir` install). This is surfaced, never silently absorbed — see the trailing `declared runtime "…" does not match this runtime` / `declared scope "…" does not match the probed <scope> scope` text.
|
||||
|
||||
@@ -48,36 +48,36 @@ An optional `Note:` line after the trigger list means one scope's own manifest d
|
||||
The warning never changes the install's exit code — a shadowed install is a warning, not a failure, and the install itself is not broken. Your options, in order of how much they cost:
|
||||
|
||||
1. **Do nothing, if the global spec tree is what you want everywhere.** This is a legitimate configuration.
|
||||
2. **On Claude Code, rely on the built-in resolution described in [Known limits](#known-limits)** — at global scope, the workflow spec `@`-include the winning skill carries is resolved by an explicit, imperative two-step lookup that prefers your project's own `.claude/gsd-core/workflows/<name>.md` over the global one, so the project you are standing in gets its own specs even though the global skill is what's invoked. This is automatic; there is nothing to configure. It applies only to the workflow-spec include — see the limits below for what it does *not* cover.
|
||||
3. **Uninstall one scope.** If you never intend to use per-project GSD customizations, uninstalling the local scope removes the ambiguity entirely. If you always want project-local behavior, uninstalling the global scope does the same from the other direction.
|
||||
2. **On Claude Code, rely on the built-in resolution described in [Known limits](#known-limits)** — at global scope, the workflow spec `@`-include the winning skill carries is resolved by an explicit, imperative two-step lookup that prefers your project's own `.claude/msd-core/workflows/<name>.md` over the global one, so the project you are standing in gets its own specs even though the global skill is what's invoked. This is automatic; there is nothing to configure. It applies only to the workflow-spec include — see the limits below for what it does *not* cover.
|
||||
3. **Uninstall one scope.** If you never intend to use per-project MSD customizations, uninstalling the local scope removes the ambiguity entirely. If you always want project-local behavior, uninstalling the global scope does the same from the other direction.
|
||||
4. **On a non-Claude, both-scopes-`skills` runtime**, the loser is overridden rather than orphaned, so reordering which install ran last (reinstalling the scope you want to win) resolves it directly — there is no separate spec-tree-reachability problem to reason about on those runtimes.
|
||||
|
||||
---
|
||||
|
||||
## When nothing is reported: "nothing to report" vs "could not look"
|
||||
|
||||
Absence of a shadow warning is not always proof that nothing is shadowed. GSD Core distinguishes two silent outcomes:
|
||||
Absence of a shadow warning is not always proof that nothing is shadowed. MSD Core distinguishes two silent outcomes:
|
||||
|
||||
**Nothing to report (verified clean)** — the check ran and found no genuine cross-scope collision:
|
||||
|
||||
- Only one scope is installed for that runtime.
|
||||
- Both scopes resolve to the *same* config directory (for example, `--config-dir` pointed both installs at the same place) — this is one physical install, not two.
|
||||
- The runtime's global scope installs no trigger-bearing artifact kind at all (windsurf's global install is `agents`, which is never invoked by a `/gsd-<name>` trigger) — there is nothing for the local scope to collide with.
|
||||
- The runtime's global scope installs no trigger-bearing artifact kind at all (windsurf's global install is `agents`, which is never invoked by a `/msd-<name>` trigger) — there is nothing for the local scope to collide with.
|
||||
- The other scope's manifest exists but declares zero files (an empty or partial install at that scope).
|
||||
|
||||
**Could not look (degraded, not verified)** — the check itself could not run, and its silence carries no claim either way:
|
||||
|
||||
- The runtime has no installable config directory to probe (`configHome.kind === 'none'`, currently only VS Code) — the resolver this check is built on cannot even ask the question, so it degrades to no report rather than crashing your install or your `/gsd-health` run.
|
||||
- The runtime has no installable config directory to probe (`configHome.kind === 'none'`, currently only VS Code) — the resolver this check is built on cannot even ask the question, so it degrades to no report rather than crashing your install or your `/msd-health` run.
|
||||
- The other scope's manifest exists on disk but could not be read (a permissions error) — that scope is treated as not-installed for this check, exactly as if it were absent.
|
||||
- The other scope's manifest is reached through a symlinked config directory or is itself a symlink — the check refuses to follow it and treats that scope as not-installed, the same degraded outcome as an unreadable manifest.
|
||||
|
||||
If you are not sure which case applies, re-run `/gsd-health` and read the diagnostic list directly rather than inferring from silence — `/gsd-health --json`'s absence of a `W028` entry combined with a runtime you know is VS Code, or a manifest you know you cannot read, tells you it is the second case, not the first.
|
||||
If you are not sure which case applies, re-run `/msd-health` and read the diagnostic list directly rather than inferring from silence — `/msd-health --json`'s absence of a `W028` entry combined with a runtime you know is VS Code, or a manifest you know you cannot read, tells you it is the second case, not the first.
|
||||
|
||||
---
|
||||
|
||||
## Known limits
|
||||
|
||||
- **Detection is manifest-based.** If you deleted `gsd-file-manifest.json` at a scope but kept the installed artifacts, that scope is reported as not-installed and cannot shadow (or be shadowed by) anything.
|
||||
- **Detection is manifest-based.** If you deleted `msd-file-manifest.json` at a scope but kept the installed artifacts, that scope is reported as not-installed and cannot shadow (or be shadowed by) anything.
|
||||
- **The workflow-spec resolution (item 2 above) is instruction-following, not guaranteed inclusion.** A static `@`-include is pre-expanded by the host before the agent ever runs; this resolved reference instead costs the agent one file read, following an explicit instruction. That is a weaker guarantee than a real `@`-include — it is deliberately confined to one reference, in the Claude runtime, at global scope only, which is what keeps that weaker guarantee acceptable rather than something the whole install quietly depends on.
|
||||
- **It covers only the workflow-spec include.** The winning global skill's `references/` and `templates/` includes still point at the global tree. If you customize only a *reference* file locally (not a workflow), the global copy of that reference is still what loads — you reach your local references only by way of entering the local workflow spec, whose own internal includes are already baked to local-absolute paths.
|
||||
- **Non-Claude runtimes get detection only, never the spec-root resolution above.** The 12 both-scopes-`skills` runtimes have the same shadowing mechanic but identical artifact kinds on both sides, so no spec tree becomes unreachable the way it does for Claude Code.
|
||||
@@ -89,5 +89,5 @@ If you are not sure which case applies, re-run `/gsd-health` and read the diagno
|
||||
- [Install on your runtime](install-on-your-runtime.md) — per-runtime install commands, including the Claude Code coexistence note
|
||||
- [Host Integration Capability Matrix](../reference/host-integration-capability-matrix.md) — trigger precedence and per-runtime axis reference
|
||||
- [Interpret scope-conformance warnings](interpret-scope-conformance-warnings.md) — the sibling advisory-warning guide for worktree-wave merges
|
||||
- [`/gsd-health`](../COMMANDS.md#gsd-health) — command reference, including the diagnostic-code table this warning's `W028` belongs to
|
||||
- [`/msd-health`](../COMMANDS.md#msd-health) — command reference, including the diagnostic-code table this warning's `W028` belongs to
|
||||
- [docs index](../README.md)
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
**Goal:** Understand the advisory `warnings` that the `worktree.cleanup-wave` gauntlet emits when a plan branch commits changes outside the scope it declared, and decide what — if anything — to do about one.
|
||||
|
||||
**Prerequisites:** GSD Core is installed and you have run `/gsd-execute-phase` with worktree isolation enabled (`workflow.use_worktrees: true`, the default), so that plan branches were merged back by a `cleanup-wave`.
|
||||
**Prerequisites:** MSD Core is installed and you have run `/msd-execute-phase` with worktree isolation enabled (`workflow.use_worktrees: true`, the default), so that plan branches were merged back by a `cleanup-wave`.
|
||||
|
||||
---
|
||||
|
||||
## What you will see
|
||||
|
||||
When `/gsd-execute-phase` runs plans in isolated worktrees, each plan branch is merged back into the phase branch by the `worktree.cleanup-wave` gauntlet. If the wave manifest recorded the plan's declared scope (`files_modified`, passed as `--files` to `worktree record-agent` / `worktree create`), the gauntlet compares the branch's actual committed diff (`HEAD...<branch>`) against that declared scope and reports any committed path that falls outside it.
|
||||
When `/msd-execute-phase` runs plans in isolated worktrees, each plan branch is merged back into the phase branch by the `worktree.cleanup-wave` gauntlet. If the wave manifest recorded the plan's declared scope (`files_modified`, passed as `--files` to `worktree record-agent` / `worktree create`), the gauntlet compares the branch's actual committed diff (`HEAD...<branch>`) against that declared scope and reports any committed path that falls outside it.
|
||||
|
||||
A realistic `cleanup-wave` result with one such warning:
|
||||
|
||||
@@ -44,7 +44,7 @@ A realistic `cleanup-wave` result with one such warning:
|
||||
|
||||
## Why this happens
|
||||
|
||||
`/gsd-execute-phase` gives each plan a declared scope up front (`files_modified` in the phase plan index), so that parallel plan branches can be reasoned about and merged with some confidence about what each one touched. The scope-conformance check is a post-hoc, best-effort verification of that promise: after a branch merges, the gauntlet diffs what was actually committed against what was declared, and flags any mismatch as a warning. This is issue #2596.
|
||||
`/msd-execute-phase` gives each plan a declared scope up front (`files_modified` in the phase plan index), so that parallel plan branches can be reasoned about and merged with some confidence about what each one touched. The scope-conformance check is a post-hoc, best-effort verification of that promise: after a branch merges, the gauntlet diffs what was actually committed against what was declared, and flags any mismatch as a warning. This is issue #2596.
|
||||
|
||||
---
|
||||
|
||||
@@ -84,7 +84,7 @@ Absence of `scope_out_of_declared` / `scope_check_unavailable` warnings is not p
|
||||
|
||||
- **Glob matching is literal-prefix only.** `src/**/*.ts` matches anything under `src/`, including `src/a/b.json` — the check does not parse glob syntax past the literal prefix.
|
||||
- **Renames are not detected specially, and mostly are not gated at all.** Git's rename detection runs by default, so a *pure* rename (content unchanged, similarity 100%) is reported as a single `R` entry and appears in **no** `--diff-filter=D` output. The deletions guard therefore never fires on it — before or after #3003 — and the rename lands here at the advisory, where the new path is compared against the declared scope like any other. Only a rename that also edits the file enough to fall below git's similarity threshold decomposes into a separate add and delete; that delete is a real deletion, and the guard blocks the entry unless the old path is declared in `files_deleted`. Declaring it is the fix in that case. The old path needs no `files_modified` entry either way: a declared deletion is subtracted from this check's findings, so it never shows up as out-of-scope.
|
||||
- **`/gsd-quick` worktrees have no plan-declared scope.** They are never checked, for the same reason as the "no `--files` recorded" case above.
|
||||
- **`/msd-quick` worktrees have no plan-declared scope.** They are never checked, for the same reason as the "no `--files` recorded" case above.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
**Prerequisites:** A `.planning/STATE.md` file. Run the check with:
|
||||
|
||||
```bash
|
||||
node gsd-tools.cjs state validate
|
||||
node msd-tools.cjs state validate
|
||||
```
|
||||
|
||||
For the flag/output reference, see [`state validate`](../COMMANDS.md#state-validate). This guide covers only how to *read and act on* the result.
|
||||
@@ -55,7 +55,7 @@ By default `state validate` exits `0` whatever it finds, so a shell gate needs t
|
||||
JSON. Pass `--strict` and the exit status carries the verdict instead:
|
||||
|
||||
```bash
|
||||
node gsd-tools.cjs state validate --strict
|
||||
node msd-tools.cjs state validate --strict
|
||||
```
|
||||
|
||||
Exit `0` means `valid: true`; any other exit means the report was not clean (drift
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# How to isolate work with workspaces
|
||||
|
||||
**Goal:** Create a fully isolated GSD environment — separate git worktree, independent `.planning/` root, and optionally multiple repositories — for feature branches or multi-repo work.
|
||||
**Goal:** Create a fully isolated MSD environment — separate git worktree, independent `.planning/` root, and optionally multiple repositories — for feature branches or multi-repo work.
|
||||
|
||||
**Prerequisites:** `git` is installed and the repository supports worktrees. For multi-repo workspaces, the target repos exist on your local machine or are accessible by path.
|
||||
|
||||
@@ -14,13 +14,13 @@ A workspace is a self-contained environment that pairs one or more git worktrees
|
||||
- Its own `WORKSPACE.md` manifest tracking member repos
|
||||
- Git worktrees (default) or full clones of the specified repos, checked out on a dedicated branch (default: `workspace/<name>`)
|
||||
|
||||
Workspaces live under `~/gsd-workspaces/<name>/` by default.
|
||||
Workspaces live under `~/msd-workspaces/<name>/` by default.
|
||||
|
||||
```
|
||||
~/gsd-workspaces/
|
||||
~/msd-workspaces/
|
||||
└── feature-b/
|
||||
├── WORKSPACE.md ← manifest
|
||||
├── .planning/ ← fully independent GSD state
|
||||
├── .planning/ ← fully independent MSD state
|
||||
│ ├── PROJECT.md
|
||||
│ ├── ROADMAP.md
|
||||
│ └── ...
|
||||
@@ -35,15 +35,15 @@ Because the workspace's `.planning/` is separate from the source repos, there is
|
||||
## Create a workspace for multiple repos
|
||||
|
||||
```bash
|
||||
/gsd-workspace --new --name feature-b --repos hr-ui,ZeymoAPI
|
||||
/msd-workspace --new --name feature-b --repos hr-ui,ZeymoAPI
|
||||
```
|
||||
|
||||
GSD creates worktrees of `hr-ui` and `ZeymoAPI` inside `~/gsd-workspaces/feature-b/`, checks out a `workspace/feature-b` branch in each, writes `WORKSPACE.md`, and creates an empty `.planning/` directory ready for `/gsd-new-project`.
|
||||
MSD creates worktrees of `hr-ui` and `ZeymoAPI` inside `~/msd-workspaces/feature-b/`, checks out a `workspace/feature-b` branch in each, writes `WORKSPACE.md`, and creates an empty `.planning/` directory ready for `/msd-new-project`.
|
||||
|
||||
To customise the location:
|
||||
|
||||
```bash
|
||||
/gsd-workspace --new --name feature-b --repos hr-ui,ZeymoAPI --path /projects/feature-b
|
||||
/msd-workspace --new --name feature-b --repos hr-ui,ZeymoAPI --path /projects/feature-b
|
||||
```
|
||||
|
||||
---
|
||||
@@ -53,15 +53,15 @@ To customise the location:
|
||||
When you want feature-branch isolation on a single repo — independent branch, independent `.planning/`, no state bleed from main:
|
||||
|
||||
```bash
|
||||
/gsd-workspace --new --name payments-rework --repos .
|
||||
/msd-workspace --new --name payments-rework --repos .
|
||||
```
|
||||
|
||||
The `.` tells GSD to create a worktree of the current repo. The worktree is checked out on `workspace/payments-rework`.
|
||||
The `.` tells MSD to create a worktree of the current repo. The worktree is checked out on `workspace/payments-rework`.
|
||||
|
||||
To force a full clone instead of a worktree:
|
||||
|
||||
```bash
|
||||
/gsd-workspace --new --name payments-rework --repos . --strategy clone
|
||||
/msd-workspace --new --name payments-rework --repos . --strategy clone
|
||||
```
|
||||
|
||||
---
|
||||
@@ -69,7 +69,7 @@ To force a full clone instead of a worktree:
|
||||
## Specify a branch explicitly
|
||||
|
||||
```bash
|
||||
/gsd-workspace --new --name payments-rework --repos . --branch feature/payments-v2
|
||||
/msd-workspace --new --name payments-rework --repos . --branch feature/payments-v2
|
||||
```
|
||||
|
||||
The `--branch` flag sets the branch name for all repos in the workspace. Defaults to `workspace/<name>`.
|
||||
@@ -79,43 +79,43 @@ The `--branch` flag sets the branch name for all repos in the workspace. Default
|
||||
## Skip interactive questions
|
||||
|
||||
```bash
|
||||
/gsd-workspace --new --name payments-rework --repos . --auto
|
||||
/msd-workspace --new --name payments-rework --repos . --auto
|
||||
```
|
||||
|
||||
GSD accepts all defaults without prompting.
|
||||
MSD accepts all defaults without prompting.
|
||||
|
||||
---
|
||||
|
||||
## Initialise GSD inside the workspace
|
||||
## Initialise MSD inside the workspace
|
||||
|
||||
After creating a workspace, move into it and initialise a GSD project:
|
||||
After creating a workspace, move into it and initialise a MSD project:
|
||||
|
||||
```bash
|
||||
cd ~/gsd-workspaces/feature-b
|
||||
/gsd-new-project
|
||||
cd ~/msd-workspaces/feature-b
|
||||
/msd-new-project
|
||||
```
|
||||
|
||||
The `.planning/` directory inside the workspace is the root for all subsequent GSD commands run from that directory. It is entirely separate from any `.planning/` that exists in the source repos.
|
||||
The `.planning/` directory inside the workspace is the root for all subsequent MSD commands run from that directory. It is entirely separate from any `.planning/` that exists in the source repos.
|
||||
|
||||
---
|
||||
|
||||
## List workspaces
|
||||
|
||||
```bash
|
||||
/gsd-workspace --list
|
||||
/msd-workspace --list
|
||||
```
|
||||
|
||||
Prints all active GSD workspaces and their status.
|
||||
Prints all active MSD workspaces and their status.
|
||||
|
||||
---
|
||||
|
||||
## Remove a workspace
|
||||
|
||||
```bash
|
||||
/gsd-workspace --remove feature-b
|
||||
/msd-workspace --remove feature-b
|
||||
```
|
||||
|
||||
GSD removes the git worktrees and cleans up the workspace directory. This does not delete the branches from the origin remote — only the local worktrees and workspace directory.
|
||||
MSD removes the git worktrees and cleans up the workspace directory. This does not delete the branches from the origin remote — only the local worktrees and workspace directory.
|
||||
|
||||
---
|
||||
|
||||
@@ -123,15 +123,15 @@ GSD removes the git worktrees and cleans up the workspace directory. This does n
|
||||
|
||||
Choose workspaces when:
|
||||
|
||||
- You are working across **multiple repositories** that need to be co-ordinated under one GSD project (e.g., an API repo and a UI repo that ship together)
|
||||
- You are working across **multiple repositories** that need to be co-ordinated under one MSD project (e.g., an API repo and a UI repo that ship together)
|
||||
- You need a **separate git worktree** with its own branch, lock files, and build artefacts per feature — so builds and dependency installs in one environment cannot affect another
|
||||
- You want a **wholly independent `.planning/` root** rather than a subdirectory of the main repo's `.planning/`
|
||||
- You are following an issue-driven workflow where each tracker issue maps to a workspace (see [Drive GSD from a tracker issue](drive-gsd-from-a-tracker-issue.md))
|
||||
- You are following an issue-driven workflow where each tracker issue maps to a workspace (see [Drive MSD from a tracker issue](drive-msd-from-a-tracker-issue.md))
|
||||
|
||||
Choose [workstreams](work-in-parallel-with-workstreams.md) instead when:
|
||||
|
||||
- All the work lives in **one repository** and shares the same git history
|
||||
- You want to run `/gsd-plan-phase` or `/gsd-discuss-phase` on different concern areas concurrently — API, UI, infra — without context bleed between their `STATE.md` files
|
||||
- You want to run `/msd-plan-phase` or `/msd-discuss-phase` on different concern areas concurrently — API, UI, infra — without context bleed between their `STATE.md` files
|
||||
- You do not need a separate worktree per concern; switching planning context is sufficient
|
||||
|
||||
---
|
||||
@@ -139,6 +139,6 @@ Choose [workstreams](work-in-parallel-with-workstreams.md) instead when:
|
||||
## Related
|
||||
|
||||
- [Work in parallel with workstreams](work-in-parallel-with-workstreams.md)
|
||||
- [Drive GSD from a tracker issue](drive-gsd-from-a-tracker-issue.md)
|
||||
- [Drive MSD from a tracker issue](drive-msd-from-a-tracker-issue.md)
|
||||
- [Commands](../COMMANDS.md)
|
||||
- [docs index](../README.md)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Keep planning docs out of a shared repo
|
||||
|
||||
You are working in a team repo and want GSD's `.planning/` artifacts — PLAN.md, SUMMARY.md,
|
||||
You are working in a team repo and want MSD's `.planning/` artifacts — PLAN.md, SUMMARY.md,
|
||||
ROADMAP.md, STATE.md — to stay on your machine instead of appearing in commits your teammates read.
|
||||
|
||||
This takes four steps, and the third is the one people miss.
|
||||
@@ -8,10 +8,10 @@ This takes four steps, and the third is the one people miss.
|
||||
## 1. Turn off doc commits
|
||||
|
||||
```bash
|
||||
gsd-tools config-set planning.commit_docs false
|
||||
msd-tools config-set planning.commit_docs false
|
||||
```
|
||||
|
||||
`gsd-tools query commit` now returns a `skipped` envelope instead of committing, and every workflow
|
||||
`msd-tools query commit` now returns a `skipped` envelope instead of committing, and every workflow
|
||||
that writes a planning artifact honors it.
|
||||
|
||||
## 2. Ignore the directory
|
||||
@@ -23,7 +23,7 @@ Add to `.gitignore`:
|
||||
```
|
||||
|
||||
This is also enough on its own: when `.planning/` is gitignored and `config.json` sets no explicit
|
||||
value, GSD auto-resolves `commit_docs` to `false`. Setting it explicitly in step 1 is clearer, and
|
||||
value, MSD auto-resolves `commit_docs` to `false`. Setting it explicitly in step 1 is clearer, and
|
||||
it survives someone later editing `.gitignore`.
|
||||
|
||||
## 3. Untrack what git is already tracking
|
||||
@@ -32,7 +32,7 @@ it survives someone later editing `.gitignore`.
|
||||
It has no effect on files already committed — git keeps tracking those, so `git add -A` keeps
|
||||
staging them even though steps 1 and 2 are both done.
|
||||
|
||||
Because GSD's default is `commit_docs: true`, most existing projects already have `.planning/`
|
||||
Because MSD's default is `commit_docs: true`, most existing projects already have `.planning/`
|
||||
in history, which makes this the common case rather than an edge case.
|
||||
|
||||
```bash
|
||||
@@ -52,12 +52,12 @@ Any output means git is still tracking those paths.
|
||||
|
||||
## 4. Keep search working
|
||||
|
||||
With `.planning/` ignored, tools that respect `.gitignore` stop searching it — including GSD's own
|
||||
With `.planning/` ignored, tools that respect `.gitignore` stop searching it — including MSD's own
|
||||
broad searches, which is rarely what you want, since the planning docs are exactly what you want an
|
||||
agent to read.
|
||||
|
||||
```bash
|
||||
gsd-tools config-set planning.search_gitignored true
|
||||
msd-tools config-set planning.search_gitignored true
|
||||
```
|
||||
|
||||
This adds `--no-ignore` to broad searches so `.planning/` is still found locally.
|
||||
@@ -65,7 +65,7 @@ This adds `--no-ignore` to broad searches so `.planning/` is still found locally
|
||||
## Verify
|
||||
|
||||
```bash
|
||||
gsd-tools validate health
|
||||
msd-tools validate health
|
||||
```
|
||||
|
||||
A clean result means you are done. If you skipped step 3, you will see:
|
||||
@@ -75,7 +75,7 @@ W029 .planning/ is gitignored but N file(s) are still tracked by git
|
||||
Fix: git rm -r --cached .planning/ && git commit -m "chore: stop tracking planning docs"
|
||||
```
|
||||
|
||||
`W029` is advisory. GSD will not untrack files for you, and `--repair` deliberately does not act on
|
||||
`W029` is advisory. MSD will not untrack files for you, and `--repair` deliberately does not act on
|
||||
it — removing files from the index is destructive and the timing is yours.
|
||||
|
||||
## Notes
|
||||
@@ -96,8 +96,8 @@ team — committed while every other phase stays local, set a `phase_commit_docs
|
||||
phase's number instead of (or on top of) the project-wide switch:
|
||||
|
||||
```bash
|
||||
gsd-tools config-set planning.commit_docs false
|
||||
gsd-tools config-set phase_commit_docs.03 true
|
||||
msd-tools config-set planning.commit_docs false
|
||||
msd-tools config-set phase_commit_docs.03 true
|
||||
```
|
||||
|
||||
```json
|
||||
@@ -107,7 +107,7 @@ gsd-tools config-set phase_commit_docs.03 true
|
||||
}
|
||||
```
|
||||
|
||||
Now `gsd-tools query commit` commits phase 03's artifacts normally, and skips (with the
|
||||
Now `msd-tools query commit` commits phase 03's artifacts normally, and skips (with the
|
||||
`skipped_commit_docs_phase_false`-or-`skipped_commit_docs_false` reason depending on which tier
|
||||
decided) every other phase's — the project-wide setting from step 1 still governs everything
|
||||
`phase_commit_docs` does not name.
|
||||
@@ -115,10 +115,10 @@ decided) every other phase's — the project-wide setting from step 1 still gove
|
||||
A few things worth knowing before you rely on this:
|
||||
|
||||
- **The phase-id form doesn't matter.** `phase_commit_docs.3`, `phase_commit_docs.03`, and (if your
|
||||
project uses a `project_code`) `phase_commit_docs.PROJ-03` all resolve to the same entry — GSD
|
||||
project uses a `project_code`) `phase_commit_docs.PROJ-03` all resolve to the same entry — MSD
|
||||
normalizes the phase number before lookup, the same way it does everywhere else phase numbers are
|
||||
compared.
|
||||
- **It only applies to a commit that names a phase-scoped file.** `gsd-tools query commit` resolves
|
||||
- **It only applies to a commit that names a phase-scoped file.** `msd-tools query commit` resolves
|
||||
the phase from the `--files` paths you pass it (via the `.planning/phases/<phase-dir>/…`
|
||||
segment). A commit that names no phase file — e.g. a bare `ROADMAP.md` update — has no phase to
|
||||
look up, so `phase_commit_docs` never applies to it and the project-wide setting governs, same as
|
||||
@@ -136,33 +136,33 @@ for the complete rules, including how a non-boolean value is handled.
|
||||
|
||||
## Pre-commit guard hook (optional)
|
||||
|
||||
Steps 1-4 stop **GSD's own** commit path from writing `.planning/`. They do not stop a plain
|
||||
`git add -A` + `git commit` — run by hand, by a teammate, or by a script outside GSD's own
|
||||
tooling — from staging and committing `.planning/` anyway. `gsd-tools commit-docs-guard enable`
|
||||
Steps 1-4 stop **MSD's own** commit path from writing `.planning/`. They do not stop a plain
|
||||
`git add -A` + `git commit` — run by hand, by a teammate, or by a script outside MSD's own
|
||||
tooling — from staging and committing `.planning/` anyway. `msd-tools commit-docs-guard enable`
|
||||
closes that specific gap by installing a `.git/hooks/pre-commit` hook that refuses any commit
|
||||
staging `.planning/` files while `commit_docs` resolves to `false`. Resolution honors the full
|
||||
precedence chain above — including a `phase_commit_docs.<phase-id>` override for the phase the
|
||||
staged `.planning/` files belong to — the same resolution `gsd-tools commit`/`query commit` uses,
|
||||
staged `.planning/` files belong to — the same resolution `msd-tools commit`/`query commit` uses,
|
||||
so the hook never contradicts them.
|
||||
|
||||
This is opt-in only — no GSD install path wires it in for you:
|
||||
This is opt-in only — no MSD install path wires it in for you:
|
||||
|
||||
```bash
|
||||
gsd-tools commit-docs-guard enable
|
||||
msd-tools commit-docs-guard enable
|
||||
```
|
||||
|
||||
If a commit would violate `commit_docs`, the hook blocks it and names the staged files and the
|
||||
`git reset` command to unstage them, matching `gsd-tools check-commit`'s own message. Remove it
|
||||
`git reset` command to unstage them, matching `msd-tools check-commit`'s own message. Remove it
|
||||
with:
|
||||
|
||||
```bash
|
||||
gsd-tools commit-docs-guard disable
|
||||
msd-tools commit-docs-guard disable
|
||||
```
|
||||
|
||||
**Enable refuses rather than guesses** in three situations, each reported with a reason:
|
||||
|
||||
- **An existing `pre-commit` hook you didn't get from GSD.** The file is left byte-for-byte
|
||||
unchanged; wire the guard into it by hand (`gsd-tools check-commit --raw` is the check to add).
|
||||
- **An existing `pre-commit` hook you didn't get from MSD.** The file is left byte-for-byte
|
||||
unchanged; wire the guard into it by hand (`msd-tools check-commit --raw` is the check to add).
|
||||
- **`core.hooksPath` is already configured.** A hook written to `.git/hooks/pre-commit` would
|
||||
never run in that case, so nothing is written; add the same check to whatever hook lives at the
|
||||
configured path instead.
|
||||
@@ -170,13 +170,13 @@ gsd-tools commit-docs-guard disable
|
||||
|
||||
`enable`/`disable` are idempotent and safe to script: a second `enable` is a no-op that reports
|
||||
success rather than duplicating content, and `disable` on a repo with no hook installed succeeds
|
||||
rather than erroring. The hook is identified by a stable `# gsd-core:commit-docs-guard` marker
|
||||
rather than erroring. The hook is identified by a stable `# msd-core:commit-docs-guard` marker
|
||||
line inside the file, checked by presence rather than exact content — appending your own line to
|
||||
the installed hook afterward does not make GSD stop recognizing it as its own. In a linked
|
||||
the installed hook afterward does not make MSD stop recognizing it as its own. In a linked
|
||||
worktree or submodule (where `.git` is a file, not a directory), `enable` resolves the real,
|
||||
shared hooks directory via git itself rather than assuming a literal `.git/hooks` path.
|
||||
|
||||
Windows note: the hook runs under Git Bash, same as any other git hook. GSD's own remote test
|
||||
Windows note: the hook runs under Git Bash, same as any other git hook. MSD's own remote test
|
||||
matrix is Linux-only, so this specific behavior is verified on Linux/macOS plus code review, not
|
||||
by an automated Windows run.
|
||||
|
||||
@@ -185,7 +185,7 @@ by an automated Windows run.
|
||||
Everything above keeps `.planning/` out of git, and that has one consequence worth knowing before
|
||||
you commit to it: **parallel executor worktrees stop working.** A worktree is checked out from a
|
||||
commit, so an untracked or ignored `.planning/` does not exist inside it and the executor has no
|
||||
`PLAN.md` to read. Untracked planning also has no git history, so `/gsd-undo` and revert paths have
|
||||
`PLAN.md` to read. Untracked planning also has no git history, so `/msd-undo` and revert paths have
|
||||
nothing to restore.
|
||||
|
||||
If what you actually want is "planning is versioned locally, but never reaches the remote", leave
|
||||
|
||||
@@ -2,20 +2,20 @@
|
||||
|
||||
**Goal:** Get a reviewer lane you have built into the **Reviewer Lane Registry**, so other people can find it, install it, and give you feedback.
|
||||
|
||||
**Prerequisites:** A working lane in a public repository, with a tagged release. If you have not built one yet, start with [Ship a reviewer lane in your capability](ship-a-reviewer-lane.md). GSD 1.9.1 or later.
|
||||
**Prerequisites:** A working lane in a public repository, with a tagged release. If you have not built one yet, start with [Ship a reviewer lane in your capability](ship-a-reviewer-lane.md). MSD 1.9.1 or later.
|
||||
|
||||
Listing is a documentation PR against `gsd-core`. There is no separate account, package publish, or approval queue — you append one JSON object, regenerate a catalog, and open a PR.
|
||||
Listing is a documentation PR against `msd-core`. There is no separate account, package publish, or approval queue — you append one JSON object, regenerate a catalog, and open a PR.
|
||||
|
||||
---
|
||||
|
||||
## Check you are aiming at the right catalog
|
||||
|
||||
GSD has three discoverability catalogs, and picking the wrong one costs you a review round-trip. Pick by what your capability *is*, not by what it does:
|
||||
MSD has three discoverability catalogs, and picking the wrong one costs you a review round-trip. Pick by what your capability *is*, not by what it does:
|
||||
|
||||
| Your capability | Catalog | Source file |
|
||||
|---|---|---|
|
||||
| A lane and nothing else — `role: "reviewer"`, GSD never installs into it | **Reviewer Lane Registry** | `docs/registries/reviewers.json` |
|
||||
| A runtime GSD installs into, that *also* carries a `reviewer` body | Whichever matches its **primary install shape** — usually the Capability or EoS registry | `capabilities.json` / `eos.json` |
|
||||
| A lane and nothing else — `role: "reviewer"`, MSD never installs into it | **Reviewer Lane Registry** | `docs/registries/reviewers.json` |
|
||||
| A runtime MSD installs into, that *also* carries a `reviewer` body | Whichever matches its **primary install shape** — usually the Capability or EoS registry | `capabilities.json` / `eos.json` |
|
||||
| A feature capability attaching at Loop Extension Points | Community Capability Registry | `docs/registries/capabilities.json` |
|
||||
|
||||
The Reviewer Lane Registry exists specifically for lanes that are **not install targets in their own right**. If your capability is a host integration that happens to review as well, it belongs under its primary shape — do not list it twice.
|
||||
@@ -41,13 +41,13 @@ Append **exactly one** object to `docs/registries/reviewers.json`:
|
||||
"id": "acme-review-lane",
|
||||
"name": "Acme Review Lane",
|
||||
"type": "reviewer",
|
||||
"repo": "some-org/gsd-lane-acme",
|
||||
"description": "Adds an Acme-hosted model as an external reviewer lane for /gsd-review, evaluating diffs against Acme's static-analysis findings.",
|
||||
"repo": "some-org/msd-lane-acme",
|
||||
"description": "Adds an Acme-hosted model as an external reviewer lane for /msd-review, evaluating diffs against Acme's static-analysis findings.",
|
||||
"author": "Some Org <hello@some-org.example>",
|
||||
"license": "MIT",
|
||||
"enginesGsd": ">=1.9.1",
|
||||
"install": "gsd capability install https://github.com/some-org/gsd-lane-acme.git#v1.0.0",
|
||||
"uninstall": "gsd capability remove acme-review-lane",
|
||||
"enginesMsd": ">=1.9.1",
|
||||
"install": "msd capability install https://github.com/some-org/msd-lane-acme.git#v1.0.0",
|
||||
"uninstall": "msd capability remove acme-review-lane",
|
||||
"interactions": {
|
||||
"slug": "acme",
|
||||
"flags": ["--acme"],
|
||||
@@ -102,7 +102,7 @@ A maintainer checks one thing: whether the entry is a real, linkable solution wi
|
||||
|
||||
Each entry embeds a live shields.io badge and a permalink to your repository's latest release, rendered directly by GitHub's markdown viewer. Cutting `v1.1.0` updates what visitors see with no follow-up PR.
|
||||
|
||||
The one thing worth revisiting is `enginesGsd` — if a later version of your lane starts depending on a newer GSD, update that range so the catalog does not advertise compatibility you no longer support.
|
||||
The one thing worth revisiting is `enginesMsd` — if a later version of your lane starts depending on a newer MSD, update that range so the catalog does not advertise compatibility you no longer support.
|
||||
|
||||
---
|
||||
|
||||
@@ -111,4 +111,4 @@ The one thing worth revisiting is `enginesGsd` — if a later version of your la
|
||||
- [Ship a reviewer lane in your capability](ship-a-reviewer-lane.md) — build the lane you are listing
|
||||
- [Registry specification](../registries/README.md) — the full entry schema, non-endorsement stance, and removal policy
|
||||
- [Reviewer Lane Registry](../registries/reviewer-registry.md) — the generated catalog itself
|
||||
- [Publish a capability](publish-a-capability.md) — versioning, `engines.gsd`, and distribution
|
||||
- [Publish a capability](publish-a-capability.md) — versioning, `engines.msd`, and distribution
|
||||
|
||||
@@ -20,13 +20,13 @@
|
||||
}
|
||||
```
|
||||
|
||||
`kinds` names every kind the layout wrote this call (`skills`, `agents`, `commands`, …), each with the `sourceDir`/`destDir` it copied between and which user-owned subdirs (e.g. `gsd-dev-preferences`) were preserved across a wipe-and-replace. `cleanup` makes a previously-silent, best-effort `rmSync` failure visible instead of swallowed. This value never claims bytes landed — see [What this cannot prove](#what-this-cannot-prove). For the full contract and the fs-adapter injection point, read the doc comment on `installRuntimeArtifacts` in `src/install-engine.cts` and the module doc in `src/install-fs-adapter.cts`; this guide covers only the migration mechanics.
|
||||
`kinds` names every kind the layout wrote this call (`skills`, `agents`, `commands`, …), each with the `sourceDir`/`destDir` it copied between and which user-owned subdirs (e.g. `msd-dev-preferences`) were preserved across a wipe-and-replace. `cleanup` makes a previously-silent, best-effort `rmSync` failure visible instead of swallowed. This value never claims bytes landed — see [What this cannot prove](#what-this-cannot-prove). For the full contract and the fs-adapter injection point, read the doc comment on `installRuntimeArtifacts` in `src/install-engine.cts` and the module doc in `src/install-fs-adapter.cts`; this guide covers only the migration mechanics.
|
||||
|
||||
---
|
||||
|
||||
## Migrating a probing test group
|
||||
|
||||
The worked example is the qwen group in `tests/install.test.cjs` (`describe('install/uninstall — qwen …')`, test `'installs GSD into ./.qwen and removes it cleanly'`). The pattern:
|
||||
The worked example is the qwen group in `tests/install.test.cjs` (`describe('install/uninstall — qwen …')`, test `'installs MSD into ./.qwen and removes it cleanly'`). The pattern:
|
||||
|
||||
1. Run the real install as before (`install(false, 'qwen')`), unchanged.
|
||||
2. Immediately after, call `installRuntimeArtifacts` again directly with the same `runtime`/`targetDir`/`scope`/resolved profile. Because the tree the first call wrote is already installed, this second call is an idempotent re-run (prune + rewrite converges to the same on-disk result) — it does no new writes, but it surfaces the same executed-plan value the first call's caller (`bin/install.js`) discarded.
|
||||
@@ -42,7 +42,7 @@ Before converting a probing group, list every fact its existing `fs.existsSync`/
|
||||
In the qwen migration, nine facts were enumerated. Only **two** moved to the value assertion — that `skills` and `agents` kinds wrote to the expected `destDir`. The other **seven** were deliberately retained as `fs` probes, because they sit outside the plan's per-kind contract (one `destDir` per kind, not a file list, and not everything the surrounding `install()`/`uninstall()` functions do):
|
||||
|
||||
- the specific nested `SKILL.md` file existing at its stem-level path (finer-grained than a per-kind `destDir`)
|
||||
- the `gsd-core/VERSION` file, written by `install()`'s own copy step, not by `installRuntimeArtifacts`
|
||||
- the `msd-core/VERSION` file, written by `install()`'s own copy step, not by `installRuntimeArtifacts`
|
||||
- the manifest's file-key content (`writeManifest`'s own output, not the executed plan)
|
||||
- four post-uninstall absence checks
|
||||
|
||||
@@ -72,11 +72,11 @@ Two traps, both documented at the seam in `src/install-fs-adapter.cts`'s module
|
||||
|
||||
## The destination-vs-package-source boundary
|
||||
|
||||
The seam's claim is **zero real destination IO**, never zero real IO. `findInstallSourceRoot`, `findAgentsSourceRoot` (both `src/runtime-artifact-layout.cts`) and `readGsdCommandNames` (`src/command-roster.cts`) are deliberately left unrouted — they locate *this package's own source tree* (`commands/gsd/`, `agents/`), not the install destination. A destination-fake's in-memory store starts empty and is never seeded with the repo's own real paths; routing those lookups through it would make every fake-adapter install throw "could not locate commands/gsd" instead of exercising the install.
|
||||
The seam's claim is **zero real destination IO**, never zero real IO. `findInstallSourceRoot`, `findAgentsSourceRoot` (both `src/runtime-artifact-layout.cts`) and `readMsdCommandNames` (`src/command-roster.cts`) are deliberately left unrouted — they locate *this package's own source tree* (`commands/msd/`, `agents/`), not the install destination. A destination-fake's in-memory store starts empty and is never seeded with the repo's own real paths; routing those lookups through it would make every fake-adapter install throw "could not locate commands/msd" instead of exercising the install.
|
||||
|
||||
`tests/executed-plan.test.cjs`'s F2 test group encodes this boundary by poisoning **by path**, not by method: `poisonRealFsAgainstDestination` wraps every fs method the routed call tree touches so that a call against a non-package-source path throws, while a call whose resolved path falls under `commands/gsd/` or `agents/` is allowed through to the real filesystem and counted. Each F2 test then positively asserts the package-source count is non-zero (`packageSourceHits.get('readdirSync') > 0`), proving the unrouted read actually happened rather than merely being tolerated.
|
||||
`tests/executed-plan.test.cjs`'s F2 test group encodes this boundary by poisoning **by path**, not by method: `poisonRealFsAgainstDestination` wraps every fs method the routed call tree touches so that a call against a non-package-source path throws, while a call whose resolved path falls under `commands/msd/` or `agents/` is allowed through to the real filesystem and counted. Each F2 test then positively asserts the package-source count is non-zero (`packageSourceHits.get('readdirSync') > 0`), proving the unrouted read actually happened rather than merely being tolerated.
|
||||
|
||||
Do not poison by method (blocking `readdirSync`/`statSync` outright regardless of target path). That makes a correct, unmodified `findInstallSourceRoot`/`readGsdCommandNames` fail for a reason that has nothing to do with destination-IO routing — a mistake already made once on this seam. If you add a test asserting no real fs contact, derive your poison set from the destination/package-source rule above, and re-derive it (not copy-paste it) if the routed call tree changes.
|
||||
Do not poison by method (blocking `readdirSync`/`statSync` outright regardless of target path). That makes a correct, unmodified `findInstallSourceRoot`/`readMsdCommandNames` fail for a reason that has nothing to do with destination-IO routing — a mistake already made once on this seam. If you add a test asserting no real fs contact, derive your poison set from the destination/package-source rule above, and re-derive it (not copy-paste it) if the routed call tree changes.
|
||||
|
||||
---
|
||||
|
||||
@@ -91,5 +91,5 @@ The executed plan describes what `installRuntimeArtifacts` *executed* — which
|
||||
- [ADR-58](../adr/58-runtime-install-policy-module.md) — the policy/adapter boundary this seam implements
|
||||
- [`docs/ARCHITECTURE.md`](../ARCHITECTURE.md) — why install correctness is modeled this way
|
||||
- `src/install-fs-adapter.cts` — the adapter seam's own module doc (delivery mechanism, partial-adapter trap, deliberately-unrouted list)
|
||||
- `.gsd/phase/feat-2874-executed-plan-return/40-design.md` — the design doc this phase shipped against
|
||||
- `.msd/phase/feat-2874-executed-plan-return/40-design.md` — the design doc this phase shipped against
|
||||
- [docs index](../README.md)
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
# How to migrate from GSD-2
|
||||
|
||||
**Goal:** Bring an older GSD-2 project (`.gsd/` directory layout) forward into GSD Core (`.planning/` layout), and optionally absorb any existing ADRs, PRDs, or specs that live in the repository into the new planning structure.
|
||||
**Goal:** Bring an older GSD-2 project (`.gsd/` directory layout) forward into MSD Core (`.planning/` layout), and optionally absorb any existing ADRs, PRDs, or specs that live in the repository into the new planning structure.
|
||||
|
||||
**Prerequisites:** GSD Core is installed. The GSD-2 project directory is available on disk.
|
||||
**Prerequisites:** MSD Core is installed. The GSD-2 project directory is available on disk.
|
||||
|
||||
---
|
||||
|
||||
## Understand what migrates
|
||||
|
||||
GSD-2 used a `.gsd/` directory as its planning root. GSD Core uses `.planning/`. The migration reverses this: it reads `.gsd/` artifacts and writes them into the standard `.planning/` structure that all GSD Core commands expect.
|
||||
GSD-2 used a `.gsd/` directory as its planning root. MSD Core uses `.planning/`. The migration reverses this: it reads `.gsd/` artifacts and writes them into the standard `.planning/` structure that all MSD Core commands expect.
|
||||
|
||||
| What exists in GSD-2 | What `/gsd-import --from-gsd2` produces |
|
||||
| What exists in GSD-2 | What `/msd-import --from-gsd2` produces |
|
||||
|----------------------|-----------------------------------------|
|
||||
| `.gsd/PROJECT.md` | `.planning/PROJECT.md` |
|
||||
| `.gsd/ROADMAP.md` | `.planning/ROADMAP.md` |
|
||||
| `.gsd/STATE.md` | `.planning/STATE.md` |
|
||||
| `.gsd/phases/` directories | `.planning/phases/` directories |
|
||||
| Phase `PLAN.md` files | GSD Core `{NN}-{MM}-PLAN.md` files (renaming enforced) |
|
||||
| Phase `PLAN.md` files | MSD Core `{NN}-{MM}-PLAN.md` files (renaming enforced) |
|
||||
|
||||
Conflict detection runs before any files are written. If the target directory already has a `PROJECT.md` and the imported content contradicts it, the migration stops at the BLOCKER gate and lists the conflicts for you to resolve.
|
||||
|
||||
@@ -27,15 +27,15 @@ Conflict detection runs before any files are written. If the target directory al
|
||||
### Migrate the current directory
|
||||
|
||||
```bash
|
||||
/gsd-import --from-gsd2
|
||||
/msd-import --from-gsd2
|
||||
```
|
||||
|
||||
GSD reads `.gsd/` in the current working directory and writes the migrated artifacts into `.planning/`.
|
||||
MSD reads `.gsd/` in the current working directory and writes the migrated artifacts into `.planning/`.
|
||||
|
||||
### Migrate from a different path
|
||||
|
||||
```bash
|
||||
/gsd-import --from-gsd2 --path ~/projects/old-project
|
||||
/msd-import --from-gsd2 --path ~/projects/old-project
|
||||
```
|
||||
|
||||
Use `--path` when the GSD-2 project is not your current working directory.
|
||||
@@ -46,7 +46,7 @@ Use `--path` when the GSD-2 project is not your current working directory.
|
||||
|
||||
If conflict detection finds blockers — for example, a GSD-2 tech-stack declaration that contradicts an existing `.planning/PROJECT.md` — it prints a conflict report and stops without writing any files.
|
||||
|
||||
Read the report, resolve the contradiction (edit the source document or the existing planning artifact), then re-run `/gsd-import --from-gsd2`. The migration is safe to re-run until it passes cleanly.
|
||||
Read the report, resolve the contradiction (edit the source document or the existing planning artifact), then re-run `/msd-import --from-gsd2`. The migration is safe to re-run until it passes cleanly.
|
||||
|
||||
---
|
||||
|
||||
@@ -55,30 +55,30 @@ Read the report, resolve the contradiction (edit the source document or the exis
|
||||
If you have a standalone plan document (a team planning document, a Markdown spec, an exported task list) rather than a full GSD-2 project, use `--from` instead:
|
||||
|
||||
```bash
|
||||
/gsd-import --from /tmp/team-plan.md
|
||||
/msd-import --from /tmp/team-plan.md
|
||||
```
|
||||
|
||||
GSD performs the same conflict-detection pass, converts the content to GSD Core `PLAN.md` format, and validates the result with the plan-checker. After validation you will see the target filename and next steps.
|
||||
MSD performs the same conflict-detection pass, converts the content to MSD Core `PLAN.md` format, and validates the result with the plan-checker. After validation you will see the target filename and next steps.
|
||||
|
||||
---
|
||||
|
||||
## Absorb existing documentation
|
||||
|
||||
If your repository already contains ADRs (Architecture Decision Records), PRDs, or specification documents, use `/gsd-ingest-docs` to synthesise them into the `.planning/` structure after migration:
|
||||
If your repository already contains ADRs (Architecture Decision Records), PRDs, or specification documents, use `/msd-ingest-docs` to synthesise them into the `.planning/` structure after migration:
|
||||
|
||||
### Scan the whole repository (auto-detects mode)
|
||||
|
||||
```bash
|
||||
/gsd-ingest-docs
|
||||
/msd-ingest-docs
|
||||
```
|
||||
|
||||
If `.planning/` is already present (for example, from the migration you just ran), GSD defaults to merge mode — it synthesises the ingested documents alongside what is already there rather than overwriting it.
|
||||
If `.planning/` is already present (for example, from the migration you just ran), MSD defaults to merge mode — it synthesises the ingested documents alongside what is already there rather than overwriting it.
|
||||
|
||||
### Scope to a specific directory
|
||||
|
||||
```bash
|
||||
/gsd-ingest-docs docs/
|
||||
/gsd-ingest-docs docs/adr/
|
||||
/msd-ingest-docs docs/
|
||||
/msd-ingest-docs docs/adr/
|
||||
```
|
||||
|
||||
### Use an explicit precedence manifest
|
||||
@@ -86,7 +86,7 @@ If `.planning/` is already present (for example, from the migration you just ran
|
||||
When documents have mixed types or you want to control which document wins on conflicts:
|
||||
|
||||
```bash
|
||||
/gsd-ingest-docs --manifest ingest.yaml
|
||||
/msd-ingest-docs --manifest ingest.yaml
|
||||
```
|
||||
|
||||
The manifest is a YAML file listing `{path, type, precedence?}` per document. See the `--manifest` flag description in [Commands](../COMMANDS.md) for the expected shape.
|
||||
@@ -94,11 +94,11 @@ The manifest is a YAML file listing `{path, type, precedence?}` per document. Se
|
||||
### Force a specific mode
|
||||
|
||||
```bash
|
||||
/gsd-ingest-docs --mode merge # Merge into existing .planning/
|
||||
/gsd-ingest-docs --mode new # Bootstrap from scratch (overwrites)
|
||||
/msd-ingest-docs --mode merge # Merge into existing .planning/
|
||||
/msd-ingest-docs --mode new # Bootstrap from scratch (overwrites)
|
||||
```
|
||||
|
||||
**Output:** `/gsd-ingest-docs` always produces an `INGEST-CONFLICTS.md` with three buckets — auto-resolved, competing-variants, and unresolved-blockers. Review this file after every ingest run. Hard-stops only occur on LOCKED-vs-LOCKED ADR contradictions; everything else is surfaced for your review, not silently discarded.
|
||||
**Output:** `/msd-ingest-docs` always produces an `INGEST-CONFLICTS.md` with three buckets — auto-resolved, competing-variants, and unresolved-blockers. Review this file after every ingest run. Hard-stops only occur on LOCKED-vs-LOCKED ADR contradictions; everything else is surfaced for your review, not silently discarded.
|
||||
|
||||
---
|
||||
|
||||
@@ -107,19 +107,19 @@ The manifest is a YAML file listing `{path, type, precedence?}` per document. Se
|
||||
Once migration and any doc ingestion are complete, confirm the project state is consistent:
|
||||
|
||||
```bash
|
||||
/gsd-health
|
||||
/gsd-health --repair
|
||||
/msd-health
|
||||
/msd-health --repair
|
||||
```
|
||||
|
||||
`/gsd-health` checks `.planning/` directory integrity and reports any drift. `--repair` auto-fixes recoverable issues.
|
||||
`/msd-health` checks `.planning/` directory integrity and reports any drift. `--repair` auto-fixes recoverable issues.
|
||||
|
||||
Then check that GSD Core can read your project state:
|
||||
Then check that MSD Core can read your project state:
|
||||
|
||||
```bash
|
||||
/gsd-progress
|
||||
/msd-progress
|
||||
```
|
||||
|
||||
If the project came across cleanly you will see the current phase status and the recommended next step. From here the standard GSD Core workflow applies.
|
||||
If the project came across cleanly you will see the current phase status and the recommended next step. From here the standard MSD Core workflow applies.
|
||||
|
||||
---
|
||||
|
||||
@@ -127,13 +127,13 @@ If the project came across cleanly you will see the current phase status and the
|
||||
|
||||
| Situation | What to do |
|
||||
|-----------|-----------|
|
||||
| `.gsd/` exists in the current directory | Run `/gsd-import --from-gsd2` (no `--path` needed) |
|
||||
| `.gsd/` exists in the current directory | Run `/msd-import --from-gsd2` (no `--path` needed) |
|
||||
| `.gsd/` is in a different directory | Use `--path ~/projects/old-project` |
|
||||
| You have a standalone plan document, not a full GSD-2 project | Use `/gsd-import --from /path/to/plan.md` |
|
||||
| You have ADRs in `docs/adr/` | Run `/gsd-ingest-docs docs/adr/` after migration |
|
||||
| You have a mix of ADRs, PRDs, and specs | Run `/gsd-ingest-docs` at repo root; it classifies automatically |
|
||||
| You have a standalone plan document, not a full GSD-2 project | Use `/msd-import --from /path/to/plan.md` |
|
||||
| You have ADRs in `docs/adr/` | Run `/msd-ingest-docs docs/adr/` after migration |
|
||||
| You have a mix of ADRs, PRDs, and specs | Run `/msd-ingest-docs` at repo root; it classifies automatically |
|
||||
| Conflict detection reports blockers | Resolve the listed contradictions then re-run; no files are written until all blockers clear |
|
||||
| You are not sure whether migration worked | Run `/gsd-health` and `/gsd-progress` to confirm |
|
||||
| You are not sure whether migration worked | Run `/msd-health` and `/msd-progress` to confirm |
|
||||
| INGEST-CONFLICTS.md lists unresolved blockers | These require manual resolution before affected documents are incorporated into planning |
|
||||
|
||||
---
|
||||
|
||||
@@ -2,23 +2,23 @@
|
||||
|
||||
**Goal:** Turn phase decisions and research into an atomic, verifiable task plan ready for execution.
|
||||
|
||||
**Prerequisites:** `.planning/ROADMAP.md` exists. A `{phase}-CONTEXT.md` from `/gsd-discuss-phase` is strongly recommended but not required.
|
||||
**Prerequisites:** `.planning/ROADMAP.md` exists. A `{phase}-CONTEXT.md` from `/msd-discuss-phase` is strongly recommended but not required.
|
||||
|
||||
---
|
||||
|
||||
## Run the standard planning flow
|
||||
|
||||
```bash
|
||||
/gsd-plan-phase 2
|
||||
/msd-plan-phase 2
|
||||
```
|
||||
|
||||
This runs three stages in sequence:
|
||||
|
||||
1. **Research** — A `gsd-phase-researcher` subagent investigates the domain and writes `{phase}-RESEARCH.md`.
|
||||
2. **Plan** — A `gsd-planner` subagent reads context, research, and requirements, then writes one or more `{phase}-{N}-PLAN.md` files.
|
||||
3. **Verify** — A `gsd-plan-checker` subagent validates plan quality across eight dimensions and triggers a revision loop (up to three iterations) until quality gates pass.
|
||||
1. **Research** — A `msd-phase-researcher` subagent investigates the domain and writes `{phase}-RESEARCH.md`.
|
||||
2. **Plan** — A `msd-planner` subagent reads context, research, and requirements, then writes one or more `{phase}-{N}-PLAN.md` files.
|
||||
3. **Verify** — A `msd-plan-checker` subagent validates plan quality across eight dimensions and triggers a revision loop (up to three iterations) until quality gates pass.
|
||||
|
||||
If no phase number is given, the `/gsd-plan-phase` orchestrating workflow reads `ROADMAP.md` and targets the next unplanned phase. This detection happens in the workflow/LLM layer, not in the `gsd-tools.cjs` CLI — its phase-lookup commands require an explicit phase number.
|
||||
If no phase number is given, the `/msd-plan-phase` orchestrating workflow reads `ROADMAP.md` and targets the next unplanned phase. This detection happens in the workflow/LLM layer, not in the `msd-tools.cjs` CLI — its phase-lookup commands require an explicit phase number.
|
||||
|
||||
---
|
||||
|
||||
@@ -27,34 +27,34 @@ If no phase number is given, the `/gsd-plan-phase` orchestrating workflow reads
|
||||
**If the domain is familiar and you do not need new research:**
|
||||
|
||||
```bash
|
||||
/gsd-plan-phase 3 --skip-research
|
||||
/msd-plan-phase 3 --skip-research
|
||||
```
|
||||
|
||||
**If RESEARCH.md already exists but you want to force a refresh:**
|
||||
|
||||
```bash
|
||||
/gsd-plan-phase 3 --research
|
||||
/msd-plan-phase 3 --research
|
||||
```
|
||||
|
||||
**If you want to run research only** — write RESEARCH.md and exit before planning:
|
||||
|
||||
```bash
|
||||
/gsd-plan-phase --research-phase 4
|
||||
/msd-plan-phase --research-phase 4
|
||||
```
|
||||
|
||||
If RESEARCH.md already exists, you are prompted to update, view, or skip. To force-refresh without the prompt:
|
||||
|
||||
```bash
|
||||
/gsd-plan-phase --research-phase 4 --research
|
||||
/msd-plan-phase --research-phase 4 --research
|
||||
```
|
||||
|
||||
To print existing RESEARCH.md to stdout without spawning the researcher:
|
||||
|
||||
```bash
|
||||
/gsd-plan-phase --research-phase 4 --view
|
||||
/msd-plan-phase --research-phase 4 --view
|
||||
```
|
||||
|
||||
Note: `--research-phase <N>` is a flag on `/gsd-plan-phase`. There is no standalone research-phase command — the removed standalone research command was retired in favour of this flag.
|
||||
Note: `--research-phase <N>` is a flag on `/msd-plan-phase`. There is no standalone research-phase command — the removed standalone research command was retired in favour of this flag.
|
||||
|
||||
---
|
||||
|
||||
@@ -63,13 +63,13 @@ Note: `--research-phase <N>` is a flag on `/gsd-plan-phase`. There is no standal
|
||||
**If you want fewer, larger tasks** for a simple or well-understood phase:
|
||||
|
||||
```bash
|
||||
/gsd-plan-phase 2 --granularity coarse
|
||||
/msd-plan-phase 2 --granularity coarse
|
||||
```
|
||||
|
||||
**If you want more, smaller tasks** for tighter control over a risky or complex phase:
|
||||
|
||||
```bash
|
||||
/gsd-plan-phase 2 --granularity fine
|
||||
/msd-plan-phase 2 --granularity fine
|
||||
```
|
||||
|
||||
`--granularity` accepts `coarse`, `standard`, or `fine`. It overrides all granularity config keys (`granularities.planning`, `granularity`, `planning.granularity`) for this invocation only — no config edit required. Invalid values are rejected immediately with an error.
|
||||
@@ -85,13 +85,13 @@ If you want this granularity applied permanently, set it in config — see [CONF
|
||||
To opt out and plan horizontal layers (the legacy default):
|
||||
|
||||
```bash
|
||||
/gsd-plan-phase 1 --no-tracer
|
||||
/msd-plan-phase 1 --no-tracer
|
||||
```
|
||||
|
||||
`--mvp` layers MVP enrichment on top of tracer-first — it frames the phase goal as a user story and, on Phase 1 of a new project with no prior phase summaries, also produces `SKELETON.md` (a Walking Skeleton covering project scaffold, routing, one real DB read/write, one real UI interaction, and dev deployment):
|
||||
|
||||
```bash
|
||||
/gsd-plan-phase 1 --mvp
|
||||
/msd-plan-phase 1 --mvp
|
||||
```
|
||||
|
||||
You can persist MVP enrichment for a phase without the flag by adding `**Mode:** mvp` to that phase's entry in ROADMAP.md.
|
||||
@@ -103,13 +103,13 @@ You can persist MVP enrichment for a phase without the flag by adding `**Mode:**
|
||||
**If you want TDD enforcement** — each behaviour-adding task begins with a failing test before implementation:
|
||||
|
||||
```bash
|
||||
/gsd-plan-phase 1 --tdd
|
||||
/msd-plan-phase 1 --tdd
|
||||
```
|
||||
|
||||
Composable with `--mvp`:
|
||||
|
||||
```bash
|
||||
/gsd-plan-phase 1 --mvp --tdd
|
||||
/msd-plan-phase 1 --mvp --tdd
|
||||
```
|
||||
|
||||
This produces vertical slices where every behaviour-adding task follows RED → GREEN → REFACTOR. The planner applies `type: tdd` to eligible tasks (business logic, API endpoints, data transformations) and uses standard `type: execute` for UI, configuration, and glue code.
|
||||
@@ -117,17 +117,17 @@ This produces vertical slices where every behaviour-adding task follows RED →
|
||||
TDD mode can also be persisted in config:
|
||||
|
||||
```bash
|
||||
node gsd-tools.cjs config-set workflow.tdd_mode true
|
||||
node msd-tools.cjs config-set workflow.tdd_mode true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Replan using cross-AI review feedback
|
||||
|
||||
**If you have run `/gsd-review --phase N` and a `REVIEWS.md` exists:**
|
||||
**If you have run `/msd-review --phase N` and a `REVIEWS.md` exists:**
|
||||
|
||||
```bash
|
||||
/gsd-plan-phase 3 --reviews
|
||||
/msd-plan-phase 3 --reviews
|
||||
```
|
||||
|
||||
The planner reads `REVIEWS.md` and revises plans to address the feedback. Cannot be combined with `--gaps`.
|
||||
@@ -135,7 +135,7 @@ The planner reads `REVIEWS.md` and revises plans to address the feedback. Cannot
|
||||
**If you want an automated loop** — replan and re-review until no HIGH concerns remain:
|
||||
|
||||
```bash
|
||||
/gsd-plan-review-convergence 3
|
||||
/msd-plan-review-convergence 3
|
||||
```
|
||||
|
||||
The convergence loop runs plan → review → replan → re-review cycles (up to three by default). Use `--max-cycles N` to override the cap.
|
||||
@@ -147,7 +147,7 @@ The convergence loop runs plan → review → replan → re-review cycles (up to
|
||||
**If `VERIFICATION.md` exists with unresolved gaps and you want to replan against those gaps only:**
|
||||
|
||||
```bash
|
||||
/gsd-plan-phase 3 --gaps
|
||||
/msd-plan-phase 3 --gaps
|
||||
```
|
||||
|
||||
Research is skipped; the planner reads the verification gaps directly.
|
||||
@@ -159,13 +159,13 @@ Research is skipped; the planner reads the verification gaps directly.
|
||||
**If `workflow.plan_bounce_script` is configured and you want external validation of the finished plan:**
|
||||
|
||||
```bash
|
||||
/gsd-plan-phase 1 --bounce
|
||||
/msd-plan-phase 1 --bounce
|
||||
```
|
||||
|
||||
To skip bounce even if it is enabled in config:
|
||||
|
||||
```bash
|
||||
/gsd-plan-phase 1 --skip-bounce
|
||||
/msd-plan-phase 1 --skip-bounce
|
||||
```
|
||||
|
||||
---
|
||||
@@ -173,7 +173,7 @@ To skip bounce even if it is enabled in config:
|
||||
## Suppress interactive confirmations
|
||||
|
||||
```bash
|
||||
/gsd-plan-phase --auto
|
||||
/msd-plan-phase --auto
|
||||
```
|
||||
|
||||
Skips all prompts. Useful in automated pipelines. Research is skipped if `research_enabled` is false in config.
|
||||
@@ -197,7 +197,7 @@ For the full field reference see [PLAN.md schema](../reference/plan-md.md).
|
||||
|
||||
### Plan quality dimensions
|
||||
|
||||
The `gsd-plan-checker` validates plans across eight dimensions before allowing execution:
|
||||
The `msd-plan-checker` validates plans across eight dimensions before allowing execution:
|
||||
|
||||
1. Task atomicity — each task is a single concern
|
||||
2. Dependency correctness — wave ordering is consistent
|
||||
@@ -217,7 +217,7 @@ The revision loop runs up to three times. If quality gates have not passed after
|
||||
If a phase has `VERIFICATION.md` with `status: passed`, it is considered closed. Attempting to replan it stops with an error. If the closeout was incorrect, override with `--force`:
|
||||
|
||||
```bash
|
||||
/gsd-plan-phase 2 --force
|
||||
/msd-plan-phase 2 --force
|
||||
```
|
||||
|
||||
A warning is emitted into the transcript and any committed plan docs.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
**Goal:** Get real edge-completeness coverage on a spec written in a language other than English, instead of every requirement landing in `unclassified` and the whole taxonomy quietly contributing nothing.
|
||||
|
||||
**Prerequisites:** A project with `response_language` set (see [Configuration](../CONFIGURATION.md)), and a phase whose `/gsd-spec-phase` run has passed the ambiguity gate. The edge-completeness probe (Step 5.5) then runs automatically — you do not invoke it separately.
|
||||
**Prerequisites:** A project with `response_language` set (see [Configuration](../CONFIGURATION.md)), and a phase whose `/msd-spec-phase` run has passed the ambiguity gate. The edge-completeness probe (Step 5.5) then runs automatically — you do not invoke it separately.
|
||||
|
||||
For the taxonomy and the reasoning behind front-of-pipeline edge analysis, see [Spec-Phase Edge-Completeness Probe](../FEATURES.md#144-spec-phase-edge-completeness-probe). For how to act on findings once they appear, see [Resolve edge-coverage findings](resolve-edge-coverage-findings.md). This guide covers only what is different when your spec is not in English.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# How to publish a capability so others can install it
|
||||
|
||||
This guide is for capability authors who want to distribute their work so other GSD users can install it with `gsd capability install`. It covers preparing the manifest, validating locally, and releasing through each supported distribution channel.
|
||||
This guide is for capability authors who want to distribute their work so other MSD users can install it with `msd capability install`. It covers preparing the manifest, validating locally, and releasing through each supported distribution channel.
|
||||
|
||||
Before publishing, make sure your capability works locally by following [Develop a Capability](./develop-a-capability.md).
|
||||
|
||||
@@ -16,19 +16,19 @@ Open your `capabilities/<id>/capability.json` and add these fields if they are n
|
||||
"version": "1.0.0"
|
||||
```
|
||||
|
||||
Use [Semantic Versioning](https://semver.org/). Every published capability must carry a version; GSD will reject installation of a manifest that omits it.
|
||||
Use [Semantic Versioning](https://semver.org/). Every published capability must carry a version; MSD will reject installation of a manifest that omits it.
|
||||
|
||||
### `engines.gsd` (required)
|
||||
### `engines.msd` (required)
|
||||
|
||||
```json
|
||||
"engines": {
|
||||
"gsd": ">=1.6.0"
|
||||
"msd": ">=1.6.0"
|
||||
}
|
||||
```
|
||||
|
||||
Declare the minimum GSD version your capability requires. GSD checks this constraint at both install time and load time and refuses to activate the capability on an incompatible installation. Be as permissive as correctness allows — a tighter range blocks more users.
|
||||
Declare the minimum MSD version your capability requires. MSD checks this constraint at both install time and load time and refuses to activate the capability on an incompatible installation. Be as permissive as correctness allows — a tighter range blocks more users.
|
||||
|
||||
If you need to offer a graceful downgrade path for users on older GSD versions, you can also declare `compatVersions`:
|
||||
If you need to offer a graceful downgrade path for users on older MSD versions, you can also declare `compatVersions`:
|
||||
|
||||
```json
|
||||
"compatVersions": {
|
||||
@@ -49,8 +49,8 @@ These fields are displayed in the pre-install summary that users see before they
|
||||
"email": "you@example.com",
|
||||
"url": "https://example.com"
|
||||
},
|
||||
"homepage": "https://github.com/your-org/gsd-cap-example",
|
||||
"repository": "https://github.com/your-org/gsd-cap-example",
|
||||
"homepage": "https://github.com/your-org/msd-cap-example",
|
||||
"repository": "https://github.com/your-org/msd-cap-example",
|
||||
"license": "MIT"
|
||||
```
|
||||
|
||||
@@ -62,7 +62,7 @@ For the full list of manifest fields and their validation rules, see [Capability
|
||||
|
||||
## Namespace reservation
|
||||
|
||||
The prefixes `gsd-`, `gsd-core-`, and `anthropic-` are reserved for first-party capabilities. Do not use them as the `id` or package name of a third-party capability.
|
||||
The prefixes `msd-`, `msd-core-`, and `anthropic-` are reserved for first-party capabilities. Do not use them as the `id` or package name of a third-party capability.
|
||||
|
||||
---
|
||||
|
||||
@@ -74,11 +74,11 @@ Run the registry check to confirm the manifest is well-formed:
|
||||
node scripts/gen-capability-registry.cjs --check
|
||||
```
|
||||
|
||||
If you are developing outside the core repo, use the standalone validator when it is available, or install your capability locally and check that `gsd capability list` shows it without errors:
|
||||
If you are developing outside the core repo, use the standalone validator when it is available, or install your capability locally and check that `msd capability list` shows it without errors:
|
||||
|
||||
```bash
|
||||
gsd capability install ./path/to/your-capability --scope project
|
||||
gsd capability list
|
||||
msd capability install ./path/to/your-capability --scope project
|
||||
msd capability list
|
||||
```
|
||||
|
||||
Fix any validation errors before proceeding.
|
||||
@@ -101,13 +101,13 @@ git push origin v1.0.0
|
||||
Consumers install by pointing at the tag:
|
||||
|
||||
```bash
|
||||
gsd capability install https://github.com/your-org/gsd-cap-example.git#v1.0.0
|
||||
msd capability install https://github.com/your-org/msd-cap-example.git#v1.0.0
|
||||
```
|
||||
|
||||
For a reproducible pin that cannot be moved, consumers can use a commit SHA instead:
|
||||
|
||||
```bash
|
||||
gsd capability install https://github.com/your-org/gsd-cap-example.git#sha:abc123def456...
|
||||
msd capability install https://github.com/your-org/msd-cap-example.git#sha:abc123def456...
|
||||
```
|
||||
|
||||
Publish release notes on your Git host so users know what changed between versions.
|
||||
@@ -123,13 +123,13 @@ npm publish
|
||||
Consumers install using the `npm:` prefix:
|
||||
|
||||
```bash
|
||||
gsd capability install npm:@your-org/gsd-cap-example@1.0.0
|
||||
msd capability install npm:@your-org/msd-cap-example@1.0.0
|
||||
```
|
||||
|
||||
A version range is also accepted:
|
||||
|
||||
```bash
|
||||
gsd capability install npm:@your-org/gsd-cap-example@^1.0.0
|
||||
msd capability install npm:@your-org/msd-cap-example@^1.0.0
|
||||
```
|
||||
|
||||
### Tarball release
|
||||
@@ -137,13 +137,13 @@ gsd capability install npm:@your-org/gsd-cap-example@^1.0.0
|
||||
Build a tarball of the capability directory and attach it to a GitHub release or host it on any HTTPS URL:
|
||||
|
||||
```bash
|
||||
tar -czf gsd-cap-example-1.0.0.tgz capabilities/example/
|
||||
tar -czf msd-cap-example-1.0.0.tgz capabilities/example/
|
||||
```
|
||||
|
||||
Consumers install using the tarball URL:
|
||||
|
||||
```bash
|
||||
gsd capability install https://github.com/your-org/gsd-cap-example/releases/download/v1.0.0/gsd-cap-example-1.0.0.tgz
|
||||
msd capability install https://github.com/your-org/msd-cap-example/releases/download/v1.0.0/msd-cap-example-1.0.0.tgz
|
||||
```
|
||||
|
||||
For tarball releases, publishing an integrity hash is strongly recommended (see below).
|
||||
@@ -155,17 +155,17 @@ For tarball releases, publishing an integrity hash is strongly recommended (see
|
||||
An `sha512` integrity hash lets consumers verify the download has not been tampered with. Compute it with:
|
||||
|
||||
```bash
|
||||
openssl dgst -sha512 -binary gsd-cap-example-1.0.0.tgz | openssl base64 -A | sed 's/^/sha512-/'
|
||||
openssl dgst -sha512 -binary msd-cap-example-1.0.0.tgz | openssl base64 -A | sed 's/^/sha512-/'
|
||||
```
|
||||
|
||||
Publish the resulting string in your release notes. Consumers pass it at install time:
|
||||
|
||||
```bash
|
||||
gsd capability install https://example.com/gsd-cap-example-1.0.0.tgz \
|
||||
msd capability install https://example.com/msd-cap-example-1.0.0.tgz \
|
||||
--integrity sha512-<hash>
|
||||
```
|
||||
|
||||
GSD verifies the hash before extracting the archive and aborts if it does not match.
|
||||
MSD verifies the hash before extracting the archive and aborts if it does not match.
|
||||
|
||||
---
|
||||
|
||||
@@ -175,7 +175,7 @@ If your release process produces a provenance record — for example, a GitHub A
|
||||
|
||||
```json
|
||||
"provenance": {
|
||||
"sourceRepo": "https://github.com/your-org/gsd-cap-example",
|
||||
"sourceRepo": "https://github.com/your-org/msd-cap-example",
|
||||
"commit": "abc123def456..."
|
||||
}
|
||||
```
|
||||
@@ -187,6 +187,6 @@ This is optional metadata. It does not change the install-time trust model.
|
||||
## Next steps
|
||||
|
||||
- [Import a capability from a URL](./import-a-capability-from-a-url.md) — walk through installation from the consumer's perspective.
|
||||
- [Version and update a capability](./version-a-capability.md) — manage `version`, `engines.gsd`, and `compatVersions` across releases.
|
||||
- [Version and update a capability](./version-a-capability.md) — manage `version`, `engines.msd`, and `compatVersions` across releases.
|
||||
- [Capability manifest](../reference/capability-manifest.md) — full field reference.
|
||||
- [Capability trust model](../explanation/capability-trust-model.md) — how GSD treats third-party capabilities at install time.
|
||||
- [Capability trust model](../explanation/capability-trust-model.md) — how MSD treats third-party capabilities at install time.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Publish PRs without planning artifacts
|
||||
|
||||
You want GSD's `.planning/` tree versioned in git on your own branch — so parallel executors can
|
||||
read their plans and `/gsd-undo` has something to restore — while the pull request your team
|
||||
You want MSD's `.planning/` tree versioned in git on your own branch — so parallel executors can
|
||||
read their plans and `/msd-undo` has something to restore — while the pull request your team
|
||||
reviews contains none of it.
|
||||
|
||||
This is the opposite trade to
|
||||
@@ -14,7 +14,7 @@ Five steps, and the fourth is the one that decides whether the guarantee actuall
|
||||
## 1. Keep planning artifacts committed
|
||||
|
||||
```bash
|
||||
gsd-tools config-set planning.commit_docs true
|
||||
msd-tools config-set planning.commit_docs true
|
||||
```
|
||||
|
||||
This is already the default. Set it explicitly if someone previously turned it off, or if
|
||||
@@ -27,13 +27,13 @@ If `.planning/` is currently in `.gitignore`, remove that line before continuing
|
||||
## 2. Turn on strict PR filtering
|
||||
|
||||
```bash
|
||||
gsd-tools config-set planning.pr_strict true
|
||||
msd-tools config-set planning.pr_strict true
|
||||
```
|
||||
|
||||
Confirm it took:
|
||||
|
||||
```bash
|
||||
gsd-tools query config-get planning.pr_strict --raw
|
||||
msd-tools query config-get planning.pr_strict --raw
|
||||
```
|
||||
|
||||
`true` means every `.planning/` path will be filtered out of the generated PR branch —
|
||||
@@ -41,14 +41,14 @@ gsd-tools query config-get planning.pr_strict --raw
|
||||
|
||||
## 3. Do the work normally
|
||||
|
||||
Nothing about the phase loop changes. `/gsd-plan-phase` and `/gsd-execute-phase` commit planning
|
||||
Nothing about the phase loop changes. `/msd-plan-phase` and `/msd-execute-phase` commit planning
|
||||
artifacts exactly as they always have, executor worktrees find their `PLAN.md`, and your working
|
||||
branch carries the full planning history.
|
||||
|
||||
## 4. Generate the PR branch — and push *that* branch
|
||||
|
||||
```bash
|
||||
/gsd-pr-branch
|
||||
/msd-pr-branch
|
||||
```
|
||||
|
||||
The command creates `<your-branch>-pr` from the target branch and rebuilds the history without any
|
||||
@@ -85,7 +85,7 @@ allowed population.
|
||||
| `Mode: strict` … `forbidden 0` | The guarantee held. | Push the `-pr` branch. |
|
||||
| `Mode: default` | `planning.pr_strict` did not resolve to `true`. | Re-run step 2; the key is read from the project's `.planning/config.json`, so check you are in the right project root. |
|
||||
| `forbidden` greater than `0` | The filter did not remove everything it promised. | Do **not** push. This is a bug — report it with the listed paths. |
|
||||
| `Conflict outside the .planning/ filter` | A real content conflict between your commits and the target branch. | Resolve it on your working branch, then re-run `/gsd-pr-branch`. |
|
||||
| `Conflict outside the .planning/ filter` | A real content conflict between your commits and the target branch. | Resolve it on your working branch, then re-run `/msd-pr-branch`. |
|
||||
| `Working tree has uncommitted changes` | Step 4's precondition failed. | Commit or stash, then re-run. |
|
||||
| `No commits ahead of <target>` | There is nothing to filter. | Not an error — you have not committed anything yet, or the target is wrong. |
|
||||
|
||||
@@ -110,4 +110,4 @@ a non-zero `forbidden` count you should not push past.
|
||||
planning never enters git, at the cost of parallel executor worktrees
|
||||
- [Planning settings reference](../CONFIGURATION.md#planning-settings) — `planning.pr_strict`,
|
||||
`planning.commit_docs`, and the rest of the `planning.*` keys
|
||||
- [`/gsd-pr-branch` reference](../COMMANDS.md#gsd-pr-branch)
|
||||
- [`/msd-pr-branch` reference](../COMMANDS.md#msd-pr-branch)
|
||||
|
||||
@@ -17,16 +17,16 @@ The marker is **advisory and approximate**. It never blocks anything.
|
||||
## Turn it on
|
||||
|
||||
```bash
|
||||
gsd-tools config-set statusline.show_state_freshness true
|
||||
msd-tools config-set statusline.show_state_freshness true
|
||||
```
|
||||
|
||||
It is off by default. That is the only step — the `state_head` stamp it reads is written
|
||||
automatically every time GSD syncs `STATE.md`, so an active project already has one.
|
||||
automatically every time MSD syncs `STATE.md`, so an active project already has one.
|
||||
|
||||
To turn it off again:
|
||||
|
||||
```bash
|
||||
gsd-tools config-set statusline.show_state_freshness false
|
||||
msd-tools config-set statusline.show_state_freshness false
|
||||
```
|
||||
|
||||
The marker also appears in the compact statusline format
|
||||
@@ -42,7 +42,7 @@ Only when **all** of these hold:
|
||||
4. The stamp is an ancestor of the current `HEAD`.
|
||||
5. `HEAD` is at least **20 commits** past the stamp.
|
||||
|
||||
Twenty is the same advisory threshold `/gsd-health` uses for its `W024` warning, and it is
|
||||
Twenty is the same advisory threshold `/msd-health` uses for its `W024` warning, and it is
|
||||
deliberately not `1`. With `commit_docs: true` (the default) the commit that carries a
|
||||
`STATE.md` sync advances `HEAD` by one, so a threshold of `> 0` would show
|
||||
`state ~1 commits back` permanently on a project that is, by construction, perfectly fresh.
|
||||
@@ -57,13 +57,13 @@ look" render identically — both are simply absent. Work down this table to tel
|
||||
| **Fewer than 20 commits behind** | `git rev-list --count $(grep '^state_head:' .planning/STATE.md \| cut -d' ' -f2)..HEAD` | No — this is the healthy case |
|
||||
| **No `state_head` stamp** | `grep '^state_head:' .planning/STATE.md` returns nothing | No — the stamp appears on the next state write |
|
||||
| **Project root does not own its `.git`** | `ls -d .git` at the directory holding `.planning/` | No — deliberate. See below |
|
||||
| **`planning.sub_repos` is set** | `gsd-tools config-get planning.sub_repos` | No — deliberate. See below |
|
||||
| **`planning.sub_repos` is set** | `msd-tools config-get planning.sub_repos` | No — deliberate. See below |
|
||||
| **History was rewound past the stamp** | `git merge-base --is-ancestor <stamp> HEAD; echo $?` prints `1` | No — reported as unknown on purpose |
|
||||
| **The stamp is not a commit in this repo** | `git cat-file -e <stamp>` fails | Possibly — a hand-edited `STATE.md` |
|
||||
| **`git` unavailable, or the repo is enormous** | `git --version`; the read is abandoned after 1.5s | Rarely — the marker yields rather than stall your prompt |
|
||||
| **A todo task is showing instead** | The middle segment shows a task, not GSD state | No — the whole GSD-state segment is replaced |
|
||||
| **A todo task is showing instead** | The middle segment shows a task, not MSD state | No — the whole MSD-state segment is replaced |
|
||||
|
||||
Run `/gsd-health` for the same signal in a form that always explains itself — it reports `W024`
|
||||
Run `/msd-health` for the same signal in a form that always explains itself — it reports `W024`
|
||||
with the count, and it is not subject to the statusline's silence.
|
||||
|
||||
### Why it stays quiet instead of guessing
|
||||
@@ -71,15 +71,15 @@ with the count, and it is not subject to the statusline's silence.
|
||||
Two cases deserve spelling out, because in both the marker *could* print a number and that
|
||||
number would be a confident lie:
|
||||
|
||||
- **A GSD project nested inside an unrelated checkout.** `git` resolves `HEAD` from the nearest
|
||||
- **A MSD project nested inside an unrelated checkout.** `git` resolves `HEAD` from the nearest
|
||||
enclosing `.git`, which might belong to a dotfiles or notes repo that has nothing to do with
|
||||
your project. Rather than report that repo's history as your project's freshness, GSD checks
|
||||
your project. Rather than report that repo's history as your project's freshness, MSD checks
|
||||
that the directory holding `.planning/` owns its own `.git` and otherwise says nothing.
|
||||
- **A `planning.sub_repos` workspace.** The outer directory legitimately owns both `.planning/`
|
||||
and its own repo, while every code commit lands in a nested child. The outer `HEAD` never
|
||||
advances, so the marker would read "fresh" forever while the code moved arbitrarily far.
|
||||
Per-child freshness would require choosing one `HEAD` out of several unrelated histories, so
|
||||
GSD declines to answer instead.
|
||||
MSD declines to answer instead.
|
||||
|
||||
The rule in both: a freshness claim the project cannot substantiate degrades to *unknown*,
|
||||
never to *fresh*.
|
||||
@@ -108,4 +108,4 @@ costs you a missing marker rather than a stalled prompt.
|
||||
|
||||
- [Configuration reference](../CONFIGURATION.md) — `statusline.show_state_freshness` and the
|
||||
other `statusline.*` keys
|
||||
- [`/gsd-health`](../COMMANDS.md) — the `W024` warning that thresholds on the same constant
|
||||
- [`/msd-health`](../COMMANDS.md) — the `W024` warning that thresholds on the same constant
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
**Goal:** Identify and fix common problems — from lost context and corrupted state to installation failures and permission errors — using a conditional recipe structure.
|
||||
|
||||
**Prerequisites:** GSD Core is installed. For install problems specifically, see [Install on your runtime](install-on-your-runtime.md).
|
||||
**Prerequisites:** MSD Core is installed. For install problems specifically, see [Install on your runtime](install-on-your-runtime.md).
|
||||
|
||||
---
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
### If you have lost track of where you are
|
||||
|
||||
```bash
|
||||
/gsd-progress
|
||||
/msd-progress
|
||||
```
|
||||
|
||||
Reads all state files and tells you exactly where you are and what to do next.
|
||||
@@ -19,13 +19,13 @@ Reads all state files and tells you exactly where you are and what to do next.
|
||||
To automatically advance to the correct next step:
|
||||
|
||||
```bash
|
||||
/gsd-progress --next
|
||||
/msd-progress --next
|
||||
```
|
||||
|
||||
### If you are starting a new session and need to restore context
|
||||
|
||||
```bash
|
||||
/gsd-resume-work
|
||||
/msd-resume-work
|
||||
```
|
||||
|
||||
Restores your full session context from the last handoff, including current phase, planning decisions, and where work stopped.
|
||||
@@ -41,21 +41,21 @@ Clear your context window between major commands:
|
||||
Then restore state:
|
||||
|
||||
```bash
|
||||
/gsd-resume-work
|
||||
/msd-resume-work
|
||||
```
|
||||
|
||||
GSD is designed around fresh contexts. Every subagent already gets a clean 200k window. The main session degrades over time — clearing it and resuming is the correct remedy, not pushing on.
|
||||
MSD is designed around fresh contexts. Every subagent already gets a clean 200k window. The main session degrades over time — clearing it and resuming is the correct remedy, not pushing on.
|
||||
|
||||
### If you want to save context before stopping
|
||||
|
||||
```bash
|
||||
/gsd-pause-work
|
||||
/msd-pause-work
|
||||
```
|
||||
|
||||
Creates `.planning/HANDOFF.json` with your current position. Add `--report` to also write a post-session summary to `.planning/reports/`:
|
||||
|
||||
```bash
|
||||
/gsd-pause-work --report
|
||||
/msd-pause-work --report
|
||||
```
|
||||
|
||||
---
|
||||
@@ -65,7 +65,7 @@ Creates `.planning/HANDOFF.json` with your current position. Add `--report` to a
|
||||
### If `.planning/` integrity is uncertain
|
||||
|
||||
```bash
|
||||
/gsd-health
|
||||
/msd-health
|
||||
```
|
||||
|
||||
Reports status across errors, warnings, and informational notes:
|
||||
@@ -79,7 +79,7 @@ Reports status across errors, warnings, and informational notes:
|
||||
Common auto-repairable issues (errors E004, E005; warnings W003, W008):
|
||||
|
||||
```bash
|
||||
/gsd-health --repair
|
||||
/msd-health --repair
|
||||
```
|
||||
|
||||
This recreates missing `STATE.md`, resets a corrupt `config.json` to defaults, and adds any missing configuration keys. It will not overwrite `PROJECT.md` or `ROADMAP.md`.
|
||||
@@ -89,40 +89,40 @@ This recreates missing `STATE.md`, resets a corrupt `config.json` to defaults, a
|
||||
This produces warning `W002`. Use the state CLI to diagnose and repair:
|
||||
|
||||
```bash
|
||||
node "$HOME/.claude/gsd-core/bin/gsd-tools.cjs" state validate
|
||||
node "$HOME/.claude/msd-core/bin/msd-tools.cjs" state validate
|
||||
```
|
||||
|
||||
Preview what a sync would change without writing:
|
||||
|
||||
```bash
|
||||
node "$HOME/.claude/gsd-core/bin/gsd-tools.cjs" state sync --verify
|
||||
node "$HOME/.claude/msd-core/bin/msd-tools.cjs" state sync --verify
|
||||
```
|
||||
|
||||
Apply the sync:
|
||||
|
||||
```bash
|
||||
node "$HOME/.claude/gsd-core/bin/gsd-tools.cjs" state sync
|
||||
node "$HOME/.claude/msd-core/bin/msd-tools.cjs" state sync
|
||||
```
|
||||
|
||||
These commands reconstruct `STATE.md` from actual project state on disk. They replace manual `STATE.md` editing.
|
||||
|
||||
### If you see "Project already initialised"
|
||||
|
||||
`.planning/PROJECT.md` already exists. `/gsd-new-project` is a safety check. If you genuinely want to start over, delete the `.planning/` directory first:
|
||||
`.planning/PROJECT.md` already exists. `/msd-new-project` is a safety check. If you genuinely want to start over, delete the `.planning/` directory first:
|
||||
|
||||
```bash
|
||||
rm -rf .planning/
|
||||
```
|
||||
|
||||
Then re-run `/gsd-new-project`.
|
||||
Then re-run `/msd-new-project`.
|
||||
|
||||
### If context-window utilisation is high
|
||||
|
||||
```bash
|
||||
/gsd-health --context
|
||||
/msd-health --context
|
||||
```
|
||||
|
||||
Probes the context-window utilisation guard. Warns at 60 %, critical at 70 %. If you are above the warning threshold, run `/clear` followed by `/gsd-resume-work` before starting the next major command.
|
||||
Probes the context-window utilisation guard. Warns at 60 %, critical at 70 %. If you are above the warning threshold, run `/clear` followed by `/msd-resume-work` before starting the next major command.
|
||||
|
||||
---
|
||||
|
||||
@@ -130,7 +130,7 @@ Probes the context-window utilisation guard. Warns at 60 %, critical at 70 %. If
|
||||
|
||||
### If an executor gets "Permission denied" on Bash commands
|
||||
|
||||
GSD's `gsd-executor` subagents need write-capable Bash access. Add the required patterns to `~/.claude/settings.json` under `permissions.allow`. At minimum:
|
||||
MSD's `msd-executor` subagents need write-capable Bash access. Add the required patterns to `~/.claude/settings.json` under `permissions.allow`. At minimum:
|
||||
|
||||
```json
|
||||
"Bash(git add:*)",
|
||||
@@ -148,7 +148,7 @@ Per-project alternative: add the same block to `.claude/settings.local.json` in
|
||||
Check whether the plan is too ambitious. Plans should have two or three tasks at most. If tasks are too large they exceed what a single context window can produce reliably. Re-plan the phase with smaller scope:
|
||||
|
||||
```bash
|
||||
/gsd-plan-phase 1
|
||||
/msd-plan-phase 1
|
||||
```
|
||||
|
||||
For systematic diagnosis of what went wrong, see [Debug a failed execution](debug-a-failed-execution.md).
|
||||
@@ -157,20 +157,20 @@ For systematic diagnosis of what went wrong, see [Debug a failed execution](debu
|
||||
|
||||
This happens when your current branch is ahead of the repository's default branch (for example, an unmerged milestone or feature branch). Claude Code forks executor worktrees from `origin/HEAD`, not your `HEAD`, so plan files that exist only on your branch are absent inside the worktree.
|
||||
|
||||
Since the fix landed, GSD automatically degrades to sequential execution on the main working tree and prints a one-line warning — the phase will complete without any action from you. To restore parallel execution permanently, run:
|
||||
Since the fix landed, MSD automatically degrades to sequential execution on the main working tree and prints a one-line warning — the phase will complete without any action from you. To restore parallel execution permanently, run:
|
||||
|
||||
```bash
|
||||
node "$HOME/.claude/gsd-core/bin/gsd-tools.cjs" worktree set-baseref
|
||||
node "$HOME/.claude/msd-core/bin/msd-tools.cjs" worktree set-baseref
|
||||
```
|
||||
|
||||
For a full explanation and all available options, see [Fix the worktree base-mismatch (exit 42) error](fix-worktree-base-mismatch.md).
|
||||
|
||||
### If parallel execution causes build lock errors or pre-commit hook failures
|
||||
|
||||
This is caused by multiple agents triggering build tools simultaneously. GSD handles this automatically since v1.26. If you are on an older version, or still seeing contention, disable parallel execution:
|
||||
This is caused by multiple agents triggering build tools simultaneously. MSD handles this automatically since v1.26. If you are on an older version, or still seeing contention, disable parallel execution:
|
||||
|
||||
```bash
|
||||
/gsd-settings
|
||||
/msd-settings
|
||||
```
|
||||
|
||||
Set `parallelization.enabled` to `false`.
|
||||
@@ -183,7 +183,7 @@ Check git log before concluding something broke:
|
||||
git log --oneline -10
|
||||
```
|
||||
|
||||
A known Claude Code classification bug can report failure while work succeeded. GSD's orchestrators spot-check actual output, but if you see a mismatch, the commits are the ground truth.
|
||||
A known Claude Code classification bug can report failure while work succeeded. MSD's orchestrators spot-check actual output, but if you see a mismatch, the commits are the ground truth.
|
||||
|
||||
---
|
||||
|
||||
@@ -191,31 +191,31 @@ A known Claude Code classification bug can report failure while work succeeded.
|
||||
|
||||
### If plans seem wrong or misaligned with your intent
|
||||
|
||||
Run `/gsd-discuss-phase N` before planning. Most plan quality issues come from assumptions that `CONTEXT.md` would have prevented:
|
||||
Run `/msd-discuss-phase N` before planning. Most plan quality issues come from assumptions that `CONTEXT.md` would have prevented:
|
||||
|
||||
```bash
|
||||
/gsd-discuss-phase 1
|
||||
/msd-discuss-phase 1
|
||||
```
|
||||
|
||||
To see what assumptions GSD is currently making without starting a full session:
|
||||
To see what assumptions MSD is currently making without starting a full session:
|
||||
|
||||
```bash
|
||||
/gsd-discuss-phase 3 --assumptions
|
||||
/msd-discuss-phase 3 --assumptions
|
||||
```
|
||||
|
||||
### If you need to change something after execution
|
||||
|
||||
Do not re-run `/gsd-execute-phase`. Use `/gsd-quick` for targeted fixes:
|
||||
Do not re-run `/msd-execute-phase`. Use `/msd-quick` for targeted fixes:
|
||||
|
||||
```bash
|
||||
/gsd-quick "Fix the login button not responding on mobile Safari"
|
||||
/msd-quick "Fix the login button not responding on mobile Safari"
|
||||
```
|
||||
|
||||
Or use `/gsd-verify-work N` to systematically identify and fix issues through UAT.
|
||||
Or use `/msd-verify-work N` to systematically identify and fix issues through UAT.
|
||||
|
||||
### If a command appears frozen at "Spawning…"
|
||||
|
||||
Wait. GSD subagents run in a separate context window. Their work is invisible to the parent session while in progress. The liveness note on the spawn line confirms this is expected. Research and planning agents routinely take 1–5 minutes; verification agents can take longer on large phases.
|
||||
Wait. MSD subagents run in a separate context window. Their work is invisible to the parent session while in progress. The liveness note on the spawn line confirms this is expected. Research and planning agents routinely take 1–5 minutes; verification agents can take longer on large phases.
|
||||
|
||||
Do not interrupt the session. Killing it discards in-progress subagent work.
|
||||
|
||||
@@ -228,39 +228,39 @@ If it has been more than 10 minutes, check whether the agent task still shows as
|
||||
### If the workflow seems corrupted or state is inconsistent
|
||||
|
||||
```bash
|
||||
/gsd-forensics
|
||||
/msd-forensics
|
||||
```
|
||||
|
||||
Or with a description:
|
||||
|
||||
```bash
|
||||
/gsd-forensics "Phase 3 execution stalled after wave 1"
|
||||
/msd-forensics "Phase 3 execution stalled after wave 1"
|
||||
```
|
||||
|
||||
`/gsd-forensics` runs a post-mortem investigation: git history anomalies, artefact integrity, STATE.md consistency, uncommitted work, and orphaned worktrees. It writes a report to `.planning/forensics/` and surfaces recommended remediation steps. It is read-only and never modifies your project files.
|
||||
`/msd-forensics` runs a post-mortem investigation: git history anomalies, artefact integrity, STATE.md consistency, uncommitted work, and orphaned worktrees. It writes a report to `.planning/forensics/` and surfaces recommended remediation steps. It is read-only and never modifies your project files.
|
||||
|
||||
### If you need to roll back a phase or plan
|
||||
|
||||
```bash
|
||||
/gsd-undo --phase 03 # Roll back all commits for phase 3
|
||||
/gsd-undo --plan 03-02 # Roll back commits for plan 02 of phase 3
|
||||
/gsd-undo --last 5 # Pick interactively from the 5 most recent GSD commits
|
||||
/msd-undo --phase 03 # Roll back all commits for phase 3
|
||||
/msd-undo --plan 03-02 # Roll back commits for plan 02 of phase 3
|
||||
/msd-undo --last 5 # Pick interactively from the 5 most recent MSD commits
|
||||
```
|
||||
|
||||
`/gsd-undo` checks dependent phases before reverting and always shows a confirmation gate.
|
||||
`/msd-undo` checks dependent phases before reverting and always shows a confirmation gate.
|
||||
|
||||
---
|
||||
|
||||
## Install and update problems
|
||||
|
||||
### If GSD is not recognised after install
|
||||
### If MSD is not recognised after install
|
||||
|
||||
Restart your runtime. GSD installs slash commands into your runtime's command directory (for example `~/.claude/commands/gsd/`). Most runtimes discover new commands only at startup.
|
||||
Restart your runtime. MSD installs slash commands into your runtime's command directory (for example `~/.claude/commands/msd/`). Most runtimes discover new commands only at startup.
|
||||
|
||||
If the problem persists, verify the install:
|
||||
|
||||
```bash
|
||||
npx @opengsd/gsd-core@latest --claude --local
|
||||
npx @golem15/msd-core@latest --claude --local
|
||||
```
|
||||
|
||||
For runtime-specific install paths and troubleshooting, see [Install on your runtime](install-on-your-runtime.md).
|
||||
@@ -269,10 +269,10 @@ For runtime-specific install paths and troubleshooting, see [Install on your run
|
||||
|
||||
Nothing to do — finish the interrupted command by running it again.
|
||||
|
||||
GSD deletes and rebuilds whole directories while installing, and some files in them are yours
|
||||
rather than GSD's: `USER-PROFILE.md` (written by `/gsd-profile-user`) and `dev-preferences.md`.
|
||||
Before anything is deleted, GSD copies those to a staging area under your runtime's config
|
||||
directory, at `.gsd-staging/user-artifacts/`. The copy is committed to disk before the delete
|
||||
MSD deletes and rebuilds whole directories while installing, and some files in them are yours
|
||||
rather than MSD's: `USER-PROFILE.md` (written by `/msd-profile-user`) and `dev-preferences.md`.
|
||||
Before anything is deleted, MSD copies those to a staging area under your runtime's config
|
||||
directory, at `.msd-staging/user-artifacts/`. The copy is committed to disk before the delete
|
||||
begins, so pressing <kbd>Ctrl</kbd>+<kbd>C</kbd>, a crash, or a machine losing power cannot leave
|
||||
you without them.
|
||||
|
||||
@@ -284,17 +284,17 @@ still running.
|
||||
To confirm your profile came back:
|
||||
|
||||
```bash
|
||||
ls ~/.claude/gsd-core/USER-PROFILE.md
|
||||
ls ~/.claude/msd-core/USER-PROFILE.md
|
||||
```
|
||||
|
||||
If the file is missing but `.gsd-staging/user-artifacts/` still contains an entry, run the install
|
||||
If the file is missing but `.msd-staging/user-artifacts/` still contains an entry, run the install
|
||||
again; recovery happens at the start of the next run, not in the background. If you are curious
|
||||
what is staged, each entry holds a `record.json` naming the directory it came from and the files it
|
||||
holds — those are ordinary files you can inspect or copy out by hand.
|
||||
|
||||
### If Codex agents fail to spawn with a 400 about an unsupported model
|
||||
|
||||
Symptom — a typed agent (`gsd-planner`, `gsd-executor`, …) fails to start and the whole
|
||||
Symptom — a typed agent (`msd-planner`, `msd-executor`, …) fails to start and the whole
|
||||
plan/execute flow falls back to a generic agent:
|
||||
|
||||
```
|
||||
@@ -309,16 +309,16 @@ ChatGPT-account session exposes only its own model, so the pin fails the request
|
||||
Check which agents are affected:
|
||||
|
||||
```bash
|
||||
node gsd-tools.cjs validate agents
|
||||
node msd-tools.cjs validate agents
|
||||
```
|
||||
|
||||
The `codex_posture` section reports one violation per offending agent, naming the file and the
|
||||
offending value. Two things it flags:
|
||||
|
||||
- `anthropic_flavored_model` — the `.toml` pins a GSD tier alias (`opus`, `sonnet`, `haiku`,
|
||||
- `anthropic_flavored_model` — the `.toml` pins a MSD tier alias (`opus`, `sonnet`, `haiku`,
|
||||
`fable`) or a `claude-*` id. Codex rejects all of these.
|
||||
- `orphaned_reasoning_effort` — a `model_reasoning_effort` with no `model`, which leaves the model
|
||||
following your Codex session while the effort follows GSD.
|
||||
following your Codex session while the effort follows MSD.
|
||||
|
||||
An empty violations list means every regular `.toml` in the directory is posture-clean, so the 400
|
||||
is coming from somewhere else — check that your Codex session itself is healthy.
|
||||
@@ -330,13 +330,13 @@ verify those targets by hand.
|
||||
**Fix — repair in place, without a reinstall.** Preview what would change:
|
||||
|
||||
```bash
|
||||
node gsd-tools.cjs effort sync
|
||||
node msd-tools.cjs effort sync
|
||||
```
|
||||
|
||||
That is a dry run; it writes nothing. When the reported changes look right, apply them:
|
||||
|
||||
```bash
|
||||
node gsd-tools.cjs effort sync --apply
|
||||
node msd-tools.cjs effort sync --apply
|
||||
```
|
||||
|
||||
It removes only the offending `model` / `model_reasoning_effort` lines. Everything else — your line
|
||||
@@ -348,7 +348,7 @@ and a file it cannot parse is refused and reported rather than partially rewritt
|
||||
model at all, so agents inherit the session model:
|
||||
|
||||
```bash
|
||||
npx @opengsd/gsd-core@latest --codex --global
|
||||
npx @golem15/msd-core@latest --codex --global
|
||||
```
|
||||
|
||||
Prefer the sync if you have hand-edited your `.toml` files — a reinstall regenerates them.
|
||||
@@ -360,17 +360,17 @@ per agent instead — see [How to configure model profiles](configure-model-prof
|
||||
|
||||
### If an update overwrote your local changes
|
||||
|
||||
Since v1.17, the installer backs up locally modified files to `gsd-local-patches/`. Reapply your changes:
|
||||
Since v1.17, the installer backs up locally modified files to `msd-local-patches/`. Reapply your changes:
|
||||
|
||||
```bash
|
||||
/gsd-update --reapply
|
||||
/msd-update --reapply
|
||||
```
|
||||
|
||||
### If you cannot update via npm
|
||||
|
||||
If `npx @opengsd/gsd-core` fails due to npm outages or network restrictions, see `docs/manual-update.md` for a step-by-step manual update procedure that works without npm access.
|
||||
If `npx @golem15/msd-core` fails due to npm outages or network restrictions, see `docs/manual-update.md` for a step-by-step manual update procedure that works without npm access.
|
||||
|
||||
For routine updates, see [Update GSD](update-gsd.md).
|
||||
For routine updates, see [Update MSD](update-msd.md).
|
||||
|
||||
---
|
||||
|
||||
@@ -381,13 +381,13 @@ For routine updates, see [Update GSD](update-gsd.md).
|
||||
Switch to the budget profile:
|
||||
|
||||
```bash
|
||||
/gsd-config --profile budget
|
||||
/msd-config --profile budget
|
||||
```
|
||||
|
||||
Disable research and plan-check agents via settings if the domain is familiar:
|
||||
|
||||
```bash
|
||||
/gsd-settings
|
||||
/msd-settings
|
||||
```
|
||||
|
||||
Also audit which MCP servers are enabled. Every enabled MCP server injects its tool schema into every turn. Browser and platform-specific tools can cost 20k+ tokens each. Disable any that the current phase does not need in `.claude/settings.json`:
|
||||
@@ -404,19 +404,19 @@ Also audit which MCP servers are enabled. Every enabled MCP server injects its t
|
||||
|
||||
| Problem | Solution |
|
||||
|---------|---------|
|
||||
| Lost context or new session | `/gsd-resume-work` or `/gsd-progress` |
|
||||
| Don't know what step is next | `/gsd-progress --next` |
|
||||
| Phase went wrong | `/gsd-undo --phase NN`, then re-plan |
|
||||
| Something broke | `/gsd-debug "description"` (add `--diagnose` for analysis without fixes) |
|
||||
| Lost context or new session | `/msd-resume-work` or `/msd-progress` |
|
||||
| Don't know what step is next | `/msd-progress --next` |
|
||||
| Phase went wrong | `/msd-undo --phase NN`, then re-plan |
|
||||
| Something broke | `/msd-debug "description"` (add `--diagnose` for analysis without fixes) |
|
||||
| STATE.md out of sync | `state validate` then `state sync` |
|
||||
| `.planning/` integrity uncertain | `/gsd-health`, then `/gsd-health --repair` |
|
||||
| Workflow state seems corrupted | `/gsd-forensics` |
|
||||
| Quick targeted fix | `/gsd-quick` |
|
||||
| Plan doesn't match your vision | `/gsd-discuss-phase N` then re-plan |
|
||||
| Costs running high | `/gsd-config --profile budget` and `/gsd-settings` to toggle agents off |
|
||||
| Update broke local changes | `/gsd-update --reapply` |
|
||||
| Want session summary | `/gsd-pause-work --report` |
|
||||
| Parallel execution build errors | Update GSD or set `parallelization.enabled: false` |
|
||||
| `.planning/` integrity uncertain | `/msd-health`, then `/msd-health --repair` |
|
||||
| Workflow state seems corrupted | `/msd-forensics` |
|
||||
| Quick targeted fix | `/msd-quick` |
|
||||
| Plan doesn't match your vision | `/msd-discuss-phase N` then re-plan |
|
||||
| Costs running high | `/msd-config --profile budget` and `/msd-settings` to toggle agents off |
|
||||
| Update broke local changes | `/msd-update --reapply` |
|
||||
| Want session summary | `/msd-pause-work --report` |
|
||||
| Parallel execution build errors | Update MSD or set `parallelization.enabled: false` |
|
||||
| Worktree base mismatch / exit 42 | Auto-degraded to sequential (no action needed); run `worktree set-baseref` to restore parallelism |
|
||||
|
||||
---
|
||||
|
||||
@@ -2,24 +2,24 @@
|
||||
|
||||
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).
|
||||
> **Which one applies depends on where the capability came from.** `disable`/`enable` work **only** on first-party capabilities shipped inside MSD. An **installed third-party overlay** (added with `msd capability install …`) cannot be disabled — its only off-switch is `remove` (re-install to restore it).
|
||||
|
||||
---
|
||||
|
||||
## Disable a first-party capability (reversible, files kept)
|
||||
|
||||
`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.
|
||||
`disable`/`enable`/`set` are for **first-party** capabilities only — the ones that ship inside MSD (for example `ui`, `code-review`, `research`). They validate `<id>` against MSD's **build-time** capability registry, so an **installed third-party overlay** (anything you added with `msd 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>
|
||||
msd capability disable <id>
|
||||
```
|
||||
|
||||
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>
|
||||
msd capability enable <id>
|
||||
```
|
||||
|
||||
Everything you had before is restored — hook registrations, config keys, contributed agents — without reinstalling.
|
||||
@@ -33,15 +33,15 @@ If you want to toggle a capability off within a single runtime session rather th
|
||||
Removal is permanent within the current install. Use it when you no longer need the capability and want to reclaim its disk footprint and clean its entries from your runtime configuration.
|
||||
|
||||
```bash
|
||||
gsd capability remove <id>
|
||||
msd capability remove <id>
|
||||
```
|
||||
|
||||
### What is removed
|
||||
|
||||
GSD uses the **ledger** — a per-runtime record written at install time (for example, `~/.claude/.gsd-capabilities.json`) — as the authoritative list of what the install owns. Removal acts precisely on that record:
|
||||
MSD uses the **ledger** — a per-runtime record written at install time (for example, `~/.claude/.msd-capabilities.json`) — as the authoritative list of what the install owns. Removal acts precisely on that record:
|
||||
|
||||
- **Owned files** — every file the capability wrote at install (skills, agents, referenced assets) is deleted.
|
||||
- **Shared configuration fragments** — entries the capability injected into shared files such as `settings.json` (hooks, MCP server registrations) are stripped. Each capability-added entry is stamped at install with a `_gsdCapability` marker naming the owning capability, and removal strips **only** entries carrying that marker. No other capability's entries — and nothing you added by hand — is touched: if you hand-edited `settings.json` between install and remove (added your own hook, your own MCP server, or any other field), those edits are preserved exactly.
|
||||
- **Shared configuration fragments** — entries the capability injected into shared files such as `settings.json` (hooks, MCP server registrations) are stripped. Each capability-added entry is stamped at install with a `_msdCapability` marker naming the owning capability, and removal strips **only** entries carrying that marker. No other capability's entries — and nothing you added by hand — is touched: if you hand-edited `settings.json` between install and remove (added your own hook, your own MCP server, or any other field), those edits are preserved exactly.
|
||||
- **Federated config keys** — configuration keys that belong to the capability's declared config slice are dropped from the merged config.
|
||||
|
||||
### What is NOT removed
|
||||
@@ -50,29 +50,29 @@ GSD uses the **ledger** — a per-runtime record written at install time (for ex
|
||||
- **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
|
||||
msd capability remove <id> --purge-data
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
### No prompt — `remove` is non-interactive
|
||||
|
||||
`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:
|
||||
`msd 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> [--purge-data] [--scope global|project]
|
||||
msd capability remove <id> [--purge-data] [--scope global|project]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**If a previous remove was interrupted** (for example, the process was killed mid-run), GSD's reconciliation sweep repairs the orphaned state automatically on the next command invocation. You do not need to intervene manually; running any `gsd capability` command is sufficient to trigger the sweep.
|
||||
**If a previous remove was interrupted** (for example, the process was killed mid-run), MSD's reconciliation sweep repairs the orphaned state automatically on the next command invocation. You do not need to intervene manually; running any `msd capability` command is sufficient to trigger the sweep.
|
||||
|
||||
**If the capability ships hooks**, removal strips its hook entries from `settings.json` without affecting any other hook entry. If after removal you still see the capability's hooks listed under `settings.json`, run:
|
||||
|
||||
```bash
|
||||
gsd capability list --json
|
||||
msd capability list --json
|
||||
```
|
||||
|
||||
and confirm the capability is no longer present. If it still appears, re-run the remove command — the reconciliation sweep will complete any partial work.
|
||||
@@ -80,14 +80,14 @@ and confirm the capability is no longer present. If it still appears, re-run the
|
||||
**If you see "capability not found" during remove**, the capability may have been installed under a different scope (global vs. project). Check which scope it was installed under:
|
||||
|
||||
```bash
|
||||
gsd capability list
|
||||
msd capability list
|
||||
```
|
||||
|
||||
The `--scope` column indicates whether an entry is `global` or `project`. Pass the matching scope explicitly if needed:
|
||||
|
||||
```bash
|
||||
gsd capability remove <id> --scope global
|
||||
gsd capability remove <id> --scope project
|
||||
msd capability remove <id> --scope global
|
||||
msd capability remove <id> --scope project
|
||||
```
|
||||
|
||||
---
|
||||
@@ -109,6 +109,6 @@ gsd capability remove <id> --scope project
|
||||
## Related guides
|
||||
|
||||
- [How to version and upgrade a capability](version-a-capability.md)
|
||||
- [Develop a Capability for GSD 1.5+](develop-a-capability.md)
|
||||
- [Develop a Capability for MSD 1.5+](develop-a-capability.md)
|
||||
- [Turn a capability off (and keep it off)](turn-a-capability-off.md)
|
||||
- [The capability trust model](../explanation/capability-trust-model.md) — why removal is surgical and reversible
|
||||
|
||||
@@ -89,7 +89,7 @@ Exactly two call sites in the repo are exempt, both for structural reasons, not
|
||||
`terminateNow`, *and* the file's basename is `cli-exit.cts`. The basename check matters on its
|
||||
own: without it, any function named `terminateNow` anywhere in the repo would silently inherit
|
||||
the allowlist.
|
||||
2. **`gsd-core/bin/gsd-tools.cjs`'s `ensureRuntimeBuild` bootstrap-failure path**, via an inline
|
||||
2. **`msd-core/bin/msd-tools.cjs`'s `ensureRuntimeBuild` bootstrap-failure path**, via an inline
|
||||
`// eslint-disable-next-line local/require-registered-exit` carrying a reason. This one call
|
||||
runs *before* `./lib/cli-exit.cjs` is even required — the registered-exit seam has not been
|
||||
loaded yet at that point in the process's lifetime, so there is nothing to route through.
|
||||
|
||||
@@ -26,7 +26,7 @@ the true answer is "nobody looked." Now it says which one happened.
|
||||
|---|---|---|---|
|
||||
| `scope_unavailable` | The seal-time gate found no phase scope at all | No plan body (`.planning/phases/<N>/*-PLAN.md`) *and* no ROADMAP section for the phase | Add the plan or roadmap section, or write a reasoned `No external API integration: <reason>` declaration to `COVERAGE.md` |
|
||||
| `phase_unresolved` | The `assumption-delta scan` query could not resolve a phase section to scan | No `ROADMAP.md`, an unknown phase number, or a phase section with no body | If you expected a real scan, fix the phase reference or roadmap section; otherwise no action — the checkpoint correctly stays silent |
|
||||
| `probe_unavailable` | The detector process itself produced no output | The probe crashed, was not found, or its stdout was empty for a reason unrelated to input content | Check that `gsd-core/bin/lib/api-coverage.cjs` or `gsd-core/bin/lib/assumption-delta.cjs` runs standalone; re-run the checkpoint once the probe itself is healthy |
|
||||
| `probe_unavailable` | The detector process itself produced no output | The probe crashed, was not found, or its stdout was empty for a reason unrelated to input content | Check that `msd-core/bin/lib/api-coverage.cjs` or `msd-core/bin/lib/assumption-delta.cjs` runs standalone; re-run the checkpoint once the probe itself is healthy |
|
||||
| `no_input` | The detector ran but stdin was empty or whitespace-only | The phase scope resolved to nothing (empty plan body and empty roadmap section) | Same as `scope_unavailable` — give the detector something to read |
|
||||
| `stdin_error` | The detector could not read stdin at all | A pipe/read failure upstream of the detector, not an empty-input case | Re-run; if it recurs, the caller constructing `$SCOPE` is the thing to fix, not the detector |
|
||||
|
||||
@@ -35,7 +35,7 @@ the true answer is "nobody looked." Now it says which one happened.
|
||||
1. Confirm the reason directly:
|
||||
|
||||
```bash
|
||||
gsd_run check api-coverage.verify-pre <phase> --raw
|
||||
msd_run check api-coverage.verify-pre <phase> --raw
|
||||
```
|
||||
|
||||
Look for `"scope_unavailable": true` in the output. That confirms this is
|
||||
@@ -45,7 +45,7 @@ the true answer is "nobody looked." Now it says which one happened.
|
||||
|
||||
```bash
|
||||
ls .planning/phases/<N>/*-PLAN.md 2>/dev/null
|
||||
gsd_run query roadmap.get-phase <phase>
|
||||
msd_run query roadmap.get-phase <phase>
|
||||
```
|
||||
|
||||
If both come back empty, the gate is correct — there is genuinely nothing
|
||||
@@ -64,12 +64,12 @@ the true answer is "nobody looked." Now it says which one happened.
|
||||
|
||||
This is the same reasoned overrule the gate already accepts when a
|
||||
detector *does* find (or falsely flags) a signal — see
|
||||
[`gsd-core/references/api-coverage.md`](../../gsd-core/references/api-coverage.md#declaring-no-external-api-integration-2365).
|
||||
[`msd-core/references/api-coverage.md`](../../msd-core/references/api-coverage.md#declaring-no-external-api-integration-2365).
|
||||
|
||||
4. Re-run the gate to confirm it clears:
|
||||
|
||||
```bash
|
||||
gsd_run check api-coverage.verify-pre <phase> --raw
|
||||
msd_run check api-coverage.verify-pre <phase> --raw
|
||||
```
|
||||
|
||||
**Turning the gate off does not answer the question.** Setting
|
||||
@@ -111,6 +111,6 @@ is a request for more scope, not a clean bill of health.
|
||||
|
||||
## Related
|
||||
|
||||
- [`gsd-core/references/api-coverage.md`](../../gsd-core/references/api-coverage.md) — the full API-coverage gate reference, including the seal-time outcome table
|
||||
- [`msd-core/references/api-coverage.md`](../../msd-core/references/api-coverage.md) — the full API-coverage gate reference, including the seal-time outcome table
|
||||
- [Resolve unreachable-guard findings](resolve-unreachable-guard-findings.md) — the same "nothing to report vs. could not look" distinction, one layer down
|
||||
- [Consume the planning snapshot](consume-the-planning-snapshot.md) — the `scope` field's version of this same rule
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# How to resolve a contract-drift finding
|
||||
|
||||
**Goal:** Bring `gsd-core/references/agent-contracts.md`'s Agent Registry back into agreement with what agents actually emit and what workflows, commands, and agents actually consume — so a completion marker, a read-tag gate, or a deleted-file reference can never silently drift apart again.
|
||||
**Goal:** Bring `msd-core/references/agent-contracts.md`'s Agent Registry back into agreement with what agents actually emit and what workflows, commands, and agents actually consume — so a completion marker, a read-tag gate, or a deleted-file reference can never silently drift apart again.
|
||||
|
||||
**Prerequisites:** A failing `npm run lint:ci` (or a direct `npm run check:contract-drift`) reporting one or more violations. The check runs automatically as part of `lint:ci` — you do not invoke it separately.
|
||||
|
||||
@@ -14,7 +14,7 @@ For why the registry exists (five shipped defects, all one root cause: two surfa
|
||||
ERROR check-contract-drift: 2 violation(s) across 2 kind(s)
|
||||
|
||||
no_consumer (1):
|
||||
- gsd-example marker "EXAMPLE COMPLETE": no consumer text contains "EXAMPLE COMPLETE" (exact case)
|
||||
- msd-example marker "EXAMPLE COMPLETE": no consumer text contains "EXAMPLE COMPLETE" (exact case)
|
||||
remedy: add an exact-case consumer for this marker, or reclassify the row Kind to artifact+query/structured-return
|
||||
```
|
||||
|
||||
@@ -26,7 +26,7 @@ Every finding names its **kind**, the agent (or registry), the marker where one
|
||||
| `declared_consumer_no_match` | The marker is consumed somewhere, but by none of the files the row's `Consumed by` cell names | Fix the cell to name a real consumer — the cell is what the read-tag arm and humans navigate by |
|
||||
| `case_only_match` | A marker matches a consumer only case-insensitively | Fix the casing to match exactly — never relax the matcher; lowercase prose is a coincidence, not a contract |
|
||||
| `case_collision` | Two declared markers differ only by case | Rename one deliberately; a case-insensitive runtime match cannot tell them apart |
|
||||
| `declared_marker_not_emitted` | The registry declares a marker the agent never emits in-fence | Emit it as a fenced example in the agent file (a `@`-included `gsd-core/references/**` file counts), or remove it from the row |
|
||||
| `declared_marker_not_emitted` | The registry declares a marker the agent never emits in-fence | Emit it as a fenced example in the agent file (a `@`-included `msd-core/references/**` file counts), or remove it from the row |
|
||||
| `emitted_marker_not_declared` | The agent emits an in-fence marker-shaped heading absent from its row | Add it to the row — after verifying a real consumer exists (it may be your next `no_consumer`) |
|
||||
| `vestigial_marker` | An `artifact+query`/`structured-return` row's agent still emits a marker | Delete the marker from the agent — unless it carries an `(unconsumed: …)` annotation (see below) |
|
||||
| `agent_without_contract` / `duplicate_registry_row` | An agent file with no row, or two rows | Add exactly one row; the registry is the declaration of record for every agent |
|
||||
@@ -44,7 +44,7 @@ Every finding names its **kind**, the agent (or registry), the marker where one
|
||||
Every row declares exactly one of three kinds, and the kind is a **measured fact about the consumer**, not a style preference:
|
||||
|
||||
- **`sentinel-match`** — a workflow, command, or another agent detects completion by an exact-case string match. Only kind whose markers need a consumer.
|
||||
- **`artifact+query`** — the agent writes a file and the caller reads or queries it (`*-VERIFICATION.md` + `gsd_run query verification.status`). No marker required.
|
||||
- **`artifact+query`** — the agent writes a file and the caller reads or queries it (`*-VERIFICATION.md` + `msd_run query verification.status`). No marker required.
|
||||
- **`structured-return`** — the agent cannot write (no `Write` tool) or returns parseable sections/JSON inline, and the caller reads the return text.
|
||||
|
||||
To decide, open the consumer and find the line that waits for the agent. If it greps a marker string → `sentinel-match`. If it reads a file or queries a CLI → `artifact+query`. If it parses the return message → `structured-return`.
|
||||
@@ -67,7 +67,7 @@ Nothing regenerates from `agent-contracts.md` — it is the source of truth, rea
|
||||
npm run check:contract-drift
|
||||
```
|
||||
|
||||
If the failing finding came from the `tests/` arm of `lint-removed-but-needed`, re-run `npm run lint:removed-but-needed` with `GSD_REMOVED_BUT_NEEDED_BASE` pointing at your base branch (CI sets this automatically).
|
||||
If the failing finding came from the `tests/` arm of `lint-removed-but-needed`, re-run `npm run lint:removed-but-needed` with `MSD_REMOVED_BUT_NEEDED_BASE` pointing at your base branch (CI sets this automatically).
|
||||
|
||||
## Silent cases are clean by design
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
**Goal:** Turn each domain-boundary edge the spec phase surfaces into an explicit, verifiable spec decision — so omitted boundaries (rounding ties, touching ranges, grapheme truncation) become checkable requirements *before* any code exists, instead of silent blind spots the verifier is confidently wrong about.
|
||||
|
||||
**Prerequisites:** A phase whose `/gsd-spec-phase` run has passed the ambiguity gate. The edge-completeness probe (Step 5.5) then runs automatically and presents its findings — you do not invoke it separately.
|
||||
**Prerequisites:** A phase whose `/msd-spec-phase` run has passed the ambiguity gate. The edge-completeness probe (Step 5.5) then runs automatically and presents its findings — you do not invoke it separately.
|
||||
|
||||
For the category taxonomy and the reasoning behind front-of-pipeline edge analysis, see [Spec-Phase Edge-Completeness Probe](../FEATURES.md#144-spec-phase-edge-completeness-probe). This guide covers only how to *act* on the findings.
|
||||
|
||||
@@ -76,7 +76,7 @@ The gate is *soft*: it never blocks you, but every unresolved edge remains visib
|
||||
**If the edges are low-stakes or already implied by earlier phases**, run the spec phase in auto mode:
|
||||
|
||||
```bash
|
||||
/gsd-spec-phase 3 --auto
|
||||
/msd-spec-phase 3 --auto
|
||||
```
|
||||
|
||||
In `--auto`, Claude marks an edge `covered` where it can write a defensible acceptance criterion, and `backstop` otherwise. It **never auto-dismisses** — dismissing an edge requires a human reason, because a wrong auto-dismissal is precisely the silent failure being eliminated. Claude logs the tally, for example:
|
||||
@@ -91,7 +91,7 @@ Review the logged choices afterwards; auto mode is a fast first pass, not a subs
|
||||
|
||||
## What happens to resolved findings downstream
|
||||
|
||||
When you next run `/gsd-plan-phase`, the planner reads the spec's `## Edge Coverage` section and:
|
||||
When you next run `/msd-plan-phase`, the planner reads the spec's `## Edge Coverage` section and:
|
||||
|
||||
- lifts every `covered` edge's acceptance criterion into `must_haves.truths`,
|
||||
- carries every `backstop` edge into `must_haves.truths` as a non-inferable check (needing a held-out/property test),
|
||||
@@ -104,6 +104,6 @@ This is the payoff: a resolved edge becomes a unit the goal-backward verifier ac
|
||||
## Related
|
||||
|
||||
- [Spec-Phase Edge-Completeness Probe](../FEATURES.md#144-spec-phase-edge-completeness-probe) — taxonomy, output schema, and the front-of-pipeline rationale
|
||||
- [`/gsd-spec-phase`](../COMMANDS.md#gsd-spec-phase) — command reference and flags
|
||||
- [`/msd-spec-phase`](../COMMANDS.md#msd-spec-phase) — command reference and flags
|
||||
- [Plan a phase](plan-a-phase.md) — where `covered`/`backstop` edges become `must_haves`
|
||||
- [docs index](../README.md)
|
||||
|
||||
@@ -66,7 +66,7 @@ The `reason` is **structurally required** — an entry with a missing, empty, or
|
||||
|
||||
⚠️ **"Not linted yet" is not a reason.** An allowlist entry meaning *we will get to it* is a TODO wearing an exemption's badge, and it will outlive everyone who remembers it. If the file should eventually be linted, lint it now.
|
||||
|
||||
A file that is **explicitly ignored** — the `gsd-core/bin/lib/**` tsc artifacts under ADR-457 — needs no allowlist entry. Ignored is a recorded decision; unmatched is an accident. The guard already tells them apart.
|
||||
A file that is **explicitly ignored** — the `msd-core/bin/lib/**` tsc artifacts under ADR-457 — needs no allowlist entry. Ignored is a recorded decision; unmatched is an accident. The guard already tells them apart.
|
||||
|
||||
Note that `bin/install.js` also needs no entry: it resolves to two rules under ADR-1703's deliberately minimal coverage, which is non-empty and therefore passes.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
**Goal:** Turn each must-NOT the spec phase surfaces into an explicit, checkable spec decision — so a constraint the author assumed but never wrote (the reminder that must not shame the user, the model that must not proxy on protected attributes, the log that must not store raw PII) becomes an acceptance criterion the verifier can enforce *before* any code exists, instead of an unwritten intent a literal `✅ done` can silently violate.
|
||||
|
||||
**Prerequisites:** A phase whose `/gsd-spec-phase` run has passed the ambiguity gate and the edge-completeness probe (Step 5.5). The prohibition probe (Step 5.6) then runs automatically over the same requirements and presents its findings — you do not invoke it separately.
|
||||
**Prerequisites:** A phase whose `/msd-spec-phase` run has passed the ambiguity gate and the edge-completeness probe (Step 5.5). The prohibition probe (Step 5.6) then runs automatically over the same requirements and presents its findings — you do not invoke it separately.
|
||||
|
||||
For the two-stage recall→precision protocol, the canon-referral rule, and the `status × verification` schema, see [Spec-Phase Prohibition Probe](../FEATURES.md#146-spec-phase-prohibition-probe). This guide covers only how to *act* on the findings.
|
||||
|
||||
@@ -49,7 +49,7 @@ A wrong dismissal is the exact silent failure this probe exists to prevent, so d
|
||||
|
||||
## When a finding is canon, not yours
|
||||
|
||||
Some candidates are **canon** security/compliance constraints a dedicated tool already owns (OWASP / prototype-pollution / path-traversal / injection → `/gsd-secure-phase` + eslint; GDPR retention / consent → `/gsd-secure-phase`). The probe does not surface these as findings to resolve — it emits a one-line breadcrumb and drops them, so the list you triage stays the ~2–3 **bespoke** prohibitions no other tool would catch. You do not act on a breadcrumb here; pick it up in `/gsd-secure-phase`.
|
||||
Some candidates are **canon** security/compliance constraints a dedicated tool already owns (OWASP / prototype-pollution / path-traversal / injection → `/msd-secure-phase` + eslint; GDPR retention / consent → `/msd-secure-phase`). The probe does not surface these as findings to resolve — it emits a one-line breadcrumb and drops them, so the list you triage stays the ~2–3 **bespoke** prohibitions no other tool would catch. You do not act on a breadcrumb here; pick it up in `/msd-secure-phase`.
|
||||
|
||||
---
|
||||
|
||||
@@ -72,7 +72,7 @@ The gate is *soft*: it never blocks you, but every unresolved prohibition stays
|
||||
**If the prohibitions are low-stakes or already settled by earlier phases**, run the spec phase in auto mode:
|
||||
|
||||
```bash
|
||||
/gsd-spec-phase 3 --auto
|
||||
/msd-spec-phase 3 --auto
|
||||
```
|
||||
|
||||
In `--auto`, Claude marks a prohibition `resolved` where it can write a defensible negative acceptance criterion (at the `test` or `judgment` tier), and leaves it `unresolved` otherwise. It **never auto-dismisses** — dismissing a prohibition requires a human reason, because a wrong auto-dismissal is precisely the silent failure being eliminated. Claude logs the tally, for example:
|
||||
@@ -87,7 +87,7 @@ Review the logged choices afterwards; auto mode is a fast first pass, not a subs
|
||||
|
||||
## What happens to resolved findings downstream
|
||||
|
||||
When you next run `/gsd-plan-phase`, the planner reads the spec's `## Prohibitions` section and:
|
||||
When you next run `/msd-plan-phase`, the planner reads the spec's `## Prohibitions` section and:
|
||||
|
||||
- lifts every confirmed prohibition into the plan's `must_haves.prohibitions`,
|
||||
- carries the `test`-tier and `judgment`-tier distinction with it,
|
||||
@@ -103,7 +103,7 @@ This is the payoff: a resolved prohibition becomes a checkable negative the goal
|
||||
|
||||
- [Spec-Phase Prohibition Probe](../FEATURES.md#146-spec-phase-prohibition-probe) — protocol, schema, host-mapping table, and the front-of-pipeline rationale
|
||||
- [Resolve edge-coverage findings](resolve-edge-coverage-findings.md) — the sibling probe on the data/behavior-shape axis
|
||||
- [`/gsd-spec-phase`](../COMMANDS.md#gsd-spec-phase) — command reference and flags
|
||||
- [`/msd-spec-phase`](../COMMANDS.md#msd-spec-phase) — command reference and flags
|
||||
- [Plan a phase](plan-a-phase.md) — where resolved prohibitions become `must_haves.prohibitions`
|
||||
- [docs index](../README.md)
|
||||
</content>
|
||||
|
||||
@@ -13,7 +13,7 @@ acknowledging is the right answer. For *why* the invariant exists, see
|
||||
|
||||
```
|
||||
unreachable-guard-drift: NEW unreachable shell-guard shape(s) found in the prompt layer.
|
||||
gsd-core/workflows/ship.md:312 cat cat .planning/phases/*-*/*-SUMMARY.md
|
||||
msd-core/workflows/ship.md:312 cat cat .planning/phases/*-*/*-SUMMARY.md
|
||||
```
|
||||
|
||||
Each line is `file:line`, the token that matched, and the offending source line.
|
||||
@@ -39,7 +39,7 @@ outcomes and only one of them is good news.
|
||||
| `ok_baseline_updated` | 0 | You ran `--update`; the baseline was rewritten. |
|
||||
| `fail_fresh_violation` | 1 | A new instance of Shape B (Shape A was retired upstream, #3884 — see below). **Fix it** — see below. |
|
||||
| `fail_stale_entry` | 1 | A baseline entry matched fewer occurrences than it acknowledges. Either a site was migrated (good — re-record) or only *some* copies were (finish the job). |
|
||||
| `fail_malformed_marker` | 1 | A `# gsd-scan-ignore:` whose reason names no issue or URL. Not a violation — a broken exemption. |
|
||||
| `fail_malformed_marker` | 1 | A `# msd-scan-ignore:` whose reason names no issue or URL. Not a violation — a broken exemption. |
|
||||
| `fail_baseline_load` | 1 | The baseline file is missing, empty, not JSON, or structurally wrong. The guard **could not look**; this is not a clean run. |
|
||||
|
||||
## Shape A — `--pick` with an `|| echo` fallback (resolved upstream, #3884)
|
||||
@@ -56,13 +56,13 @@ shape it shows is now the **correct, idiomatic** way to write this:
|
||||
# Previously BROKEN (pre-#3884): the fallback could never fire, because an
|
||||
# absent field printed '' at exit 0. As of #3884 this now works as written —
|
||||
# `|| echo "false"` fires exactly when `active` cannot be resolved.
|
||||
AUTO_MODE=$(gsd_run query check auto-mode --pick active 2>/dev/null || echo "false")
|
||||
AUTO_MODE=$(msd_run query check auto-mode --pick active 2>/dev/null || echo "false")
|
||||
```
|
||||
|
||||
You can confirm the new behavior directly:
|
||||
|
||||
```bash
|
||||
node gsd-core/bin/gsd-tools.cjs query phases.list --pick a_field_that_does_not_exist; echo "exit=$?"
|
||||
node msd-core/bin/msd-tools.cjs query phases.list --pick a_field_that_does_not_exist; echo "exit=$?"
|
||||
```
|
||||
|
||||
That now prints nothing on stdout, a diagnostic on stderr, and exits `1`
|
||||
@@ -72,7 +72,7 @@ That now prints nothing on stdout, a diagnostic on stderr, and exits `1`
|
||||
required, but remains harmless:**
|
||||
|
||||
```bash
|
||||
AUTO_MODE=$(gsd_run query check auto-mode --pick active 2>/dev/null)
|
||||
AUTO_MODE=$(msd_run query check auto-mode --pick active 2>/dev/null)
|
||||
AUTO_MODE="${AUTO_MODE:-false}"
|
||||
```
|
||||
|
||||
@@ -88,7 +88,7 @@ be resolved** — this half of the contract is unchanged by #3884 and remains
|
||||
the reason a `:-0` default on an absent field would be a bug:
|
||||
|
||||
```bash
|
||||
PRIOR_SUMMARIES=$(gsd_run query phases.list --type summaries --pick count 2>/dev/null)
|
||||
PRIOR_SUMMARIES=$(msd_run query phases.list --type summaries --pick count 2>/dev/null)
|
||||
if [ "$PRIOR_SUMMARIES" = "0" ]; then WALKING_SKELETON=true; fi
|
||||
```
|
||||
|
||||
@@ -137,7 +137,7 @@ element, so the count is `1` and the count guard passes wrongly. Measured:
|
||||
`nullglob` is frequently set in a *different fenced block* of the same file, so
|
||||
you cannot tell from the line you are editing. Use `-e` and stop having to know.
|
||||
|
||||
`gsd-core/workflows/review.md` keeps count guards because that block sets
|
||||
`msd-core/workflows/review.md` keeps count guards because that block sets
|
||||
`nullglob` two lines above them — correct in context, not a template to copy.
|
||||
|
||||
### What does not fire
|
||||
@@ -148,9 +148,9 @@ Deliberately, so the guard stays worth reading:
|
||||
consumed, not the exit code. Not a guard.
|
||||
- `ls foo/*.md 2>/dev/null || true` — suppressing a failure; there is no
|
||||
fallback value to defeat.
|
||||
- `gsd_run query config-get <key> … || echo "default"` — `config-get` genuinely
|
||||
- `msd_run query config-get <key> … || echo "default"` — `config-get` genuinely
|
||||
exits `1` on a missing key, so its `||` works. Verify with
|
||||
`node gsd-core/bin/gsd-tools.cjs query config-get no.such.key; echo $?`.
|
||||
`node msd-core/bin/msd-tools.cjs query config-get no.such.key; echo $?`.
|
||||
- `for f in dir/*.md; do` — the construct `nullglob` exists to make correct.
|
||||
|
||||
## Acknowledge a finding you cannot fix yet
|
||||
@@ -177,7 +177,7 @@ Documentation that *shows* the anti-pattern is byte-identical to a regression,
|
||||
so it must declare itself, on the offending line:
|
||||
|
||||
```bash
|
||||
cat .planning/phases/*/*-SUMMARY.md # gsd-scan-ignore: #3409 counter-example for the docs
|
||||
cat .planning/phases/*/*-SUMMARY.md # msd-scan-ignore: #3409 counter-example for the docs
|
||||
```
|
||||
|
||||
The reason must name an issue (`#123`) or an `http(s)://` URL. A free-text,
|
||||
|
||||
@@ -13,7 +13,7 @@ For what counts as a reference and why the check is shaped this way, see [ADR-00
|
||||
```
|
||||
ERROR lint-command-contract: 1 unreachable workflow file(s)
|
||||
|
||||
gsd-core/workflows/scan.md
|
||||
msd-core/workflows/scan.md
|
||||
ships to every runtime install tree, but no command, agent, or skill references it
|
||||
```
|
||||
|
||||
@@ -21,8 +21,8 @@ The check walks the transitive closure from every `commands/**`, `agents/**`, an
|
||||
|
||||
| Shape | Example | When it is used |
|
||||
|---|---|---|
|
||||
| Eager include | `@~/.claude/gsd-core/workflows/x.md` | Inlined on every invocation. Reserve for workflows the command always needs. |
|
||||
| Lazy path | `` `~/.claude/gsd-core/workflows/x.md` `` | Read on demand at the point of use. The default for flag-gated or conditional workflows. |
|
||||
| Eager include | `@~/.claude/msd-core/workflows/x.md` | Inlined on every invocation. Reserve for workflows the command always needs. |
|
||||
| Lazy path | `` `~/.claude/msd-core/workflows/x.md` `` | Read on demand at the point of use. The default for flag-gated or conditional workflows. |
|
||||
| Parent-relative | `execute-phase/steps/x.md` | A sub-file under an existing workflow directory. |
|
||||
|
||||
A finding means **none** of those reaches the file. There are exactly two correct resolutions.
|
||||
@@ -37,18 +37,18 @@ Add a reference in the loader that dispatches to it. Prefer a **lazy path** unle
|
||||
|
||||
```markdown
|
||||
- If it is `--fast`: strip the flag, then read and execute
|
||||
`~/.claude/gsd-core/workflows/scan.md` (passing remaining args).
|
||||
`~/.claude/msd-core/workflows/scan.md` (passing remaining args).
|
||||
```
|
||||
|
||||
An eager `@`-include is inlined into context on *every* invocation of that command, including the paths that never use the workflow. The progressive-disclosure split ([#717](https://github.com/open-gsd/gsd-core/issues/717)) exists specifically to keep that cost off the common path, so reach for the lazy form first.
|
||||
|
||||
If the loader is a `commands/gsd/*.md` file, regenerate the skill surface afterward:
|
||||
If the loader is a `commands/msd/*.md` file, regenerate the skill surface afterward:
|
||||
|
||||
```bash
|
||||
npm run gen:plugin-skills
|
||||
```
|
||||
|
||||
**This was the right answer for `scan.md`** — `/gsd-map-codebase --fast` was a shipped, documented flag whose routing line named no resolvable path. Deleting the file would have removed the only implementation of a live feature ([#3561](https://github.com/open-gsd/gsd-core/issues/3561)).
|
||||
**This was the right answer for `scan.md`** — `/msd-map-codebase --fast` was a shipped, documented flag whose routing line named no resolvable path. Deleting the file would have removed the only implementation of a live feature ([#3561](https://github.com/open-gsd/gsd-core/issues/3561)).
|
||||
|
||||
---
|
||||
|
||||
@@ -56,12 +56,12 @@ npm run gen:plugin-skills
|
||||
|
||||
**Choose this when nothing is supposed to reach it** — typically because its command was removed and the workflow was left behind.
|
||||
|
||||
Before deleting, confirm the fence is not load-bearing: check the file's own header for a claimed caller and verify that caller exists. The `discovery-phase` workflow's header claimed it was "called from plan-phase.md's mandatory_discovery step"; that step did not exist. `docs/INVENTORY.md` claimed it was an alternate `/gsd-new-project` entry; `new-project.md` never referenced it. **A claimed caller is not a caller.** (The `discovery-phase` workflow was deleted in #3560.)
|
||||
Before deleting, confirm the fence is not load-bearing: check the file's own header for a claimed caller and verify that caller exists. The `discovery-phase` workflow's header claimed it was "called from plan-phase.md's mandatory_discovery step"; that step did not exist. `docs/INVENTORY.md` claimed it was an alternate `/msd-new-project` entry; `new-project.md` never referenced it. **A claimed caller is not a caller.** (The `discovery-phase` workflow was deleted in #3560.)
|
||||
|
||||
Deletion is a five-step sweep, and skipping any step leaves the tree inconsistent:
|
||||
|
||||
```bash
|
||||
git rm gsd-core/workflows/<name>.md
|
||||
git rm msd-core/workflows/<name>.md
|
||||
```
|
||||
|
||||
1. **Remove its `docs/INVENTORY.md` row — in all five locales.** `docs/INVENTORY.md` plus `docs/ja-JP/`, `docs/ko-KR/`, `docs/zh-CN/`, `docs/pt-BR/`. Check the explanatory note near the bottom of each file too; a workflow is sometimes named there as well as in the table.
|
||||
@@ -77,7 +77,7 @@ git rm gsd-core/workflows/<name>.md
|
||||
- An **allowlist keyed on the bare basename** will not match a full-path search. `tests/planner-language-regression.test.cjs` carried a stale entry for the `discovery-phase` workflow that a path-based sweep missed.
|
||||
- A test that **asserts the file's existence or content** pins it. `tests/phase.test.cjs` required the `plan-milestone-gaps` workflow to exist and checked its `mkdir` patterns; deleting the file turned that into four red tests on the remote runner. Cut the coupling in the same change — but keep any sibling assertions that guard *other* files, since these blocks are often shared across several workflows.
|
||||
|
||||
Note that `scripts/lint-removed-but-needed.cjs` will **not** catch either: it scans `.github/workflows/`, `gsd-core/`, `docs/`, and `package.json` — not `tests/`. Search `tests/` yourself.
|
||||
Note that `scripts/lint-removed-but-needed.cjs` will **not** catch either: it scans `.github/workflows/`, `msd-core/`, `docs/`, and `package.json` — not `tests/`. Search `tests/` yourself.
|
||||
5. **Add a `Removed` changeset fragment**, and remember that a `Removed` type requires a `docs/` change — which step 1 already satisfies.
|
||||
|
||||
Then confirm the tree is consistent:
|
||||
@@ -90,7 +90,7 @@ npm run lint:ci
|
||||
|
||||
## What does *not* count as a reference
|
||||
|
||||
The check deliberately scans only `commands/`, `agents/`, `skills/`, and `gsd-core/**`. A mention anywhere else confers no reachability:
|
||||
The check deliberately scans only `commands/`, `agents/`, `skills/`, and `msd-core/**`. A mention anywhere else confers no reachability:
|
||||
|
||||
| Location | Counts? | Why |
|
||||
|---|---|---|
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Resolve verify-command path findings
|
||||
|
||||
`/gsd-plan-phase` runs a deterministic probe over every `<automated>` verify command in a
|
||||
`/msd-plan-phase` runs a deterministic probe over every `<automated>` verify command in a
|
||||
phase's plans before the plan-check pass. When a command's target directory does not resolve,
|
||||
the plan checker reports it and planning does not pass. This page is what to do with that
|
||||
report.
|
||||
@@ -10,7 +10,7 @@ the executor's cwd?* — and it answers it without ever running the command.
|
||||
|
||||
## When you will see this
|
||||
|
||||
`/gsd-plan-phase N` returns `## ISSUES FOUND` with a blocker like:
|
||||
`/msd-plan-phase N` returns `## ISSUES FOUND` with a blocker like:
|
||||
|
||||
```
|
||||
Verify Command Path Resolvability — BLOCKER
|
||||
@@ -30,7 +30,7 @@ prior phase that had any — at **every** context window. If a previous phase al
|
||||
builds the same tree, that command resolved in a real run. Reuse it verbatim.
|
||||
|
||||
```bash
|
||||
gsd-tools query init.plan-phase N --pick prior_verify_commands
|
||||
msd-tools query init.plan-phase N --pick prior_verify_commands
|
||||
```
|
||||
|
||||
If that returns commands, the fix is usually a copy-paste, not a new path.
|
||||
@@ -51,12 +51,12 @@ Two forms are recognized. Prefer the second:
|
||||
| `cd <dir> && npm run <script>` | Depends on the executor's cwd; a relative climb resolves differently inside a worktree |
|
||||
| `npm --prefix <dir> run <script>` | Independent of cwd — **prefer this** |
|
||||
|
||||
Rewrite the plan's `<automated>` block, then re-run `/gsd-plan-phase N`.
|
||||
Rewrite the plan's `<automated>` block, then re-run `/msd-plan-phase N`.
|
||||
|
||||
### 3. Re-run the probe by hand to confirm
|
||||
|
||||
```bash
|
||||
gsd-tools check verify-command-paths N --raw
|
||||
msd-tools check verify-command-paths N --raw
|
||||
```
|
||||
|
||||
Every row should be `severity: none`, or carry a warning you have consciously accepted.
|
||||
@@ -100,6 +100,6 @@ Act on `severity`, not on `status` — a row can be `status: ok` and still carry
|
||||
|
||||
## Related
|
||||
|
||||
- [Verify Command Path Resolvability](../COMMANDS.md#gsd-tools-check-verify-command-paths) — the command reference
|
||||
- [Verify Command Path Resolvability](../COMMANDS.md#msd-tools-check-verify-command-paths) — the command reference
|
||||
- [Resolve edge-coverage findings](resolve-edge-coverage-findings.md)
|
||||
- [Resolve prohibition findings](resolve-prohibition-findings.md)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# How to run phases autonomously
|
||||
|
||||
Run all remaining phases — or a bounded range of them — unattended, so GSD moves through discuss → plan → execute for each phase without you driving every step.
|
||||
Run all remaining phases — or a bounded range of them — unattended, so MSD moves through discuss → plan → execute for each phase without you driving every step.
|
||||
|
||||
For background on what the phase loop is doing during an autonomous run, see [The phase loop](../explanation/the-phase-loop.md).
|
||||
|
||||
@@ -10,17 +10,17 @@ For background on what the phase loop is doing during an autonomous run, see [Th
|
||||
|
||||
- An active project with `.planning/ROADMAP.md` and `.planning/STATE.md`
|
||||
- All phases you want to run must be in a state that autonomous mode can drive (pending or in-progress; not already complete)
|
||||
- Any design decisions you care about should already be in `PROJECT.md` or captured via a prior `/gsd-discuss-phase` — autonomous mode can surface grey areas interactively only when you use `--interactive`
|
||||
- Any design decisions you care about should already be in `PROJECT.md` or captured via a prior `/msd-discuss-phase` — autonomous mode can surface grey areas interactively only when you use `--interactive`
|
||||
|
||||
---
|
||||
|
||||
## Run all remaining phases
|
||||
|
||||
```bash
|
||||
/gsd-autonomous
|
||||
/msd-autonomous
|
||||
```
|
||||
|
||||
GSD reads `ROADMAP.md`, discovers every incomplete phase in numeric order, and runs discuss → plan → execute on each one. After all phases complete it automatically runs the milestone lifecycle: audit → complete → cleanup.
|
||||
MSD reads `ROADMAP.md`, discovers every incomplete phase in numeric order, and runs discuss → plan → execute on each one. After all phases complete it automatically runs the milestone lifecycle: audit → complete → cleanup.
|
||||
|
||||
---
|
||||
|
||||
@@ -29,15 +29,15 @@ GSD reads `ROADMAP.md`, discovers every incomplete phase in numeric order, and r
|
||||
Use `--from` and `--to` to bound the run. Both flags accept decimal phase numbers (e.g. `3.1`).
|
||||
|
||||
```bash
|
||||
/gsd-autonomous --from 3 # phases 3, 4, 5 … (skip already-done phases 1 and 2)
|
||||
/gsd-autonomous --to 5 # phases up to and including 5
|
||||
/gsd-autonomous --from 3 --to 5 # exactly phases 3, 4, and 5
|
||||
/msd-autonomous --from 3 # phases 3, 4, 5 … (skip already-done phases 1 and 2)
|
||||
/msd-autonomous --to 5 # phases up to and including 5
|
||||
/msd-autonomous --from 3 --to 5 # exactly phases 3, 4, and 5
|
||||
```
|
||||
|
||||
When `--to` is reached the lifecycle step is skipped, because not all milestone phases are done. The completion banner tells you how to resume:
|
||||
|
||||
```text
|
||||
Resume with: /gsd-autonomous --from 6
|
||||
Resume with: /msd-autonomous --from 6
|
||||
```
|
||||
|
||||
---
|
||||
@@ -47,7 +47,7 @@ Resume with: /gsd-autonomous --from 6
|
||||
To run exactly one phase without triggering the milestone lifecycle, use `--only N`:
|
||||
|
||||
```bash
|
||||
/gsd-autonomous --only 4
|
||||
/msd-autonomous --only 4
|
||||
```
|
||||
|
||||
If the phase is already complete, autonomous mode exits immediately with a message rather than re-running it.
|
||||
@@ -56,25 +56,25 @@ If the phase is already complete, autonomous mode exits immediately with a messa
|
||||
|
||||
## Run with plan convergence
|
||||
|
||||
Use `--converge` when you want each phase to run the plan-review convergence loop before execution. Both `/gsd-autonomous` and `/gsd-progress --next --auto` support this flag.
|
||||
Use `--converge` when you want each phase to run the plan-review convergence loop before execution. Both `/msd-autonomous` and `/msd-progress --next --auto` support this flag.
|
||||
|
||||
```bash
|
||||
# Needed only for /gsd-progress --next --converge and standalone /gsd-plan-review-convergence
|
||||
# (/gsd-autonomous --converge overrides the gate for its own run):
|
||||
gsd config-set workflow.plan_review_convergence true
|
||||
# Needed only for /msd-progress --next --converge and standalone /msd-plan-review-convergence
|
||||
# (/msd-autonomous --converge overrides the gate for its own run):
|
||||
msd config-set workflow.plan_review_convergence true
|
||||
|
||||
# Via autonomous (multi-phase or single-phase):
|
||||
/gsd-autonomous --only 4 --converge
|
||||
/gsd-autonomous --from 3 --to 5 --converge --all --max-cycles 5
|
||||
/msd-autonomous --only 4 --converge
|
||||
/msd-autonomous --from 3 --to 5 --converge --all --max-cycles 5
|
||||
|
||||
# Via progress --next --auto (step-chaining with convergence):
|
||||
/gsd-progress --next --auto --converge
|
||||
/gsd-progress --next --auto --converge --codex --max-cycles 4
|
||||
/msd-progress --next --auto --converge
|
||||
/msd-progress --next --auto --converge --codex --max-cycles 4
|
||||
```
|
||||
|
||||
`--cross-ai` is accepted as an alias for `--converge`. Reviewer flags supported by `/gsd-plan-review-convergence` pass through unchanged, including `--codex`, `--claude`, `--opencode`, `--ollama`, `--lm-studio`, `--llama-cpp`, `--all`, and `--max-cycles N`.
|
||||
`--cross-ai` is accepted as an alias for `--converge`. Reviewer flags supported by `/msd-plan-review-convergence` pass through unchanged, including `--codex`, `--claude`, `--opencode`, `--ollama`, `--lm-studio`, `--llama-cpp`, `--all`, and `--max-cycles N`.
|
||||
|
||||
An explicit `--converge` on `/gsd-autonomous` overrides the gate for that run: convergence runs even when `workflow.plan_review_convergence` is `false`, and without the flag autonomous plans with `gsd-plan-phase`. The gate still governs `/gsd-progress --next --converge` and standalone `/gsd-plan-review-convergence`, which stop with the enable command when it is not enabled.
|
||||
An explicit `--converge` on `/msd-autonomous` overrides the gate for that run: convergence runs even when `workflow.plan_review_convergence` is `false`, and without the flag autonomous plans with `msd-plan-phase`. The gate still governs `/msd-progress --next --converge` and standalone `/msd-plan-review-convergence`, which stop with the enable command when it is not enabled.
|
||||
|
||||
---
|
||||
|
||||
@@ -83,11 +83,11 @@ An explicit `--converge` on `/gsd-autonomous` overrides the gate for that run: c
|
||||
By default, autonomous mode answers discuss questions automatically using smart discuss (batch table proposals). If you want to answer design questions yourself while keeping plan and execute out of the main context:
|
||||
|
||||
```bash
|
||||
/gsd-autonomous --interactive
|
||||
/msd-autonomous --interactive
|
||||
```
|
||||
|
||||
In interactive mode:
|
||||
- `/gsd-discuss-phase` runs inline and waits for your answers
|
||||
- `/msd-discuss-phase` runs inline and waits for your answers
|
||||
- On runtimes that support nested background dispatch, planning and execution are dispatched as background agents so you can discuss the next phase while the current one builds; on Claude Code, planning and execution run inline (the next phase's discuss does not overlap)
|
||||
- The main context stays lean — only discuss conversations accumulate (on runtimes with background dispatch; on Claude Code, inline plan/execute also accumulate)
|
||||
|
||||
@@ -98,8 +98,8 @@ In interactive mode:
|
||||
To run autonomously on a runtime that does not support the `AskUserQuestion` tool (for example Codex CLI or Antigravity), add `--text`:
|
||||
|
||||
```bash
|
||||
/gsd-autonomous --text
|
||||
/gsd-autonomous --from 3 --text
|
||||
/msd-autonomous --text
|
||||
/msd-autonomous --from 3 --text
|
||||
```
|
||||
|
||||
All interactive prompts become plain numbered lists; type the choice number to respond. When combined with `--converge`, `--text` is also forwarded to the convergence loop via `CONVERGENCE_ARGS` so reviewer prompts inside plan-review convergence use the same plain-text mode.
|
||||
@@ -108,7 +108,7 @@ All interactive prompts become plain numbered lists; type the choice number to r
|
||||
|
||||
## What safety gates still apply
|
||||
|
||||
Autonomous mode does not bypass GSD's quality pipeline. Each phase still:
|
||||
Autonomous mode does not bypass MSD's quality pipeline. Each phase still:
|
||||
|
||||
- Runs the plan-checker before execution
|
||||
- Reads `VERIFICATION.md` after execution and routes on the result
|
||||
@@ -123,15 +123,15 @@ The package legitimacy gate also remains active. If a plan includes a `checkpoin
|
||||
|
||||
## When not to use autonomous mode
|
||||
|
||||
Do not use `/gsd-autonomous` when:
|
||||
Do not use `/msd-autonomous` when:
|
||||
|
||||
- **Phases have unsettled design decisions.** If you have not run `/gsd-discuss-phase` and your `PROJECT.md` does not capture your preferences, smart discuss will make autonomous choices you may not agree with. Run discuss interactively first, or use `--interactive`.
|
||||
- **Phases have unsettled design decisions.** If you have not run `/msd-discuss-phase` and your `PROJECT.md` does not capture your preferences, smart discuss will make autonomous choices you may not agree with. Run discuss interactively first, or use `--interactive`.
|
||||
|
||||
- **You need fine-grained control over a single phase.** For one phase, `/gsd-execute-phase N` gives you step-by-step output and lets you react before continuing. Use `--only N` if you want the autonomous quality pipeline on a single phase but do not need step-by-step interaction.
|
||||
- **You need fine-grained control over a single phase.** For one phase, `/msd-execute-phase N` gives you step-by-step output and lets you react before continuing. Use `--only N` if you want the autonomous quality pipeline on a single phase but do not need step-by-step interaction.
|
||||
|
||||
- **The phase has novel or high-risk work.** Autonomous mode skips pauses unless it hits a blocker. On a phase where you expect surprises, stay in the loop with manual execution.
|
||||
|
||||
- **You are mid-phase with partial execution.** Autonomous mode picks up incomplete phases but it does not resume a partially-executed wave. Use `/gsd-execute-phase N` to finish a phase that is already in progress.
|
||||
- **You are mid-phase with partial execution.** Autonomous mode picks up incomplete phases but it does not resume a partially-executed wave. Use `/msd-execute-phase N` to finish a phase that is already in progress.
|
||||
|
||||
If a run stops partway through, see [Debug a failed execution](debug-a-failed-execution.md) for how to diagnose what went wrong.
|
||||
|
||||
@@ -142,13 +142,13 @@ If a run stops partway through, see [Debug a failed execution](debug-a-failed-ex
|
||||
Autonomous mode prints a progress banner before each phase:
|
||||
|
||||
```text
|
||||
GSD ► AUTONOMOUS ▸ Phase 3/7: Auth Middleware [████░░░░] 28%
|
||||
MSD ► AUTONOMOUS ▸ Phase 3/7: Auth Middleware [████░░░░] 28%
|
||||
```
|
||||
|
||||
If you need to check where the run stands mid-session, open another terminal and run:
|
||||
|
||||
```bash
|
||||
/gsd-progress
|
||||
/msd-progress
|
||||
```
|
||||
|
||||
---
|
||||
@@ -158,16 +158,16 @@ If you need to check where the run stands mid-session, open another terminal and
|
||||
If autonomous mode stops — whether you chose "Stop autonomous mode" from the blocker prompt, or the session was interrupted — resume from where it left off:
|
||||
|
||||
```bash
|
||||
/gsd-autonomous --from 4 # replace 4 with the first incomplete phase number
|
||||
/msd-autonomous --from 4 # replace 4 with the first incomplete phase number
|
||||
```
|
||||
|
||||
GSD skips already-complete phases automatically, so it is safe to re-run from an earlier phase number if you are not sure where the run stopped.
|
||||
MSD skips already-complete phases automatically, so it is safe to re-run from an earlier phase number if you are not sure where the run stopped.
|
||||
|
||||
If a prior run recorded a `Deferred Verification` entry in `STATE.md`, later `/gsd-autonomous` reruns skip that phase instead of re-entering the same deferral prompt. Resume deferred work with the exact command shown in the table:
|
||||
If a prior run recorded a `Deferred Verification` entry in `STATE.md`, later `/msd-autonomous` reruns skip that phase instead of re-entering the same deferral prompt. Resume deferred work with the exact command shown in the table:
|
||||
|
||||
```bash
|
||||
/gsd-verify-work 4 # for verification_deferred_human
|
||||
/gsd-plan-phase 6 --gaps # for verification_deferred_gaps
|
||||
/msd-verify-work 4 # for verification_deferred_human
|
||||
/msd-plan-phase 6 --gaps # for verification_deferred_gaps
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# How to scope code review depth by path
|
||||
|
||||
**Goal:** Escalate `/gsd-code-review` to `deep` for sensitive directories (auth, billing, payments) while the rest of the repository keeps reviewing at the project's normal default — without having to remember `--depth=deep` on every review that happens to touch one of those paths.
|
||||
**Goal:** Escalate `/msd-code-review` to `deep` for sensitive directories (auth, billing, payments) while the rest of the repository keeps reviewing at the project's normal default — without having to remember `--depth=deep` on every review that happens to touch one of those paths.
|
||||
|
||||
**Prerequisites:** A project with `/gsd-code-review` enabled (`workflow.code_review: true`). This guide assumes you already have a working default depth via `workflow.code_review_depth`; see [Configuration Reference](../CONFIGURATION.md#workflow-toggles) if you don't.
|
||||
**Prerequisites:** A project with `/msd-code-review` enabled (`workflow.code_review: true`). This guide assumes you already have a working default depth via `workflow.code_review_depth`; see [Configuration Reference](../CONFIGURATION.md#workflow-toggles) if you don't.
|
||||
|
||||
---
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
1. **Set the global default**, if you haven't already:
|
||||
|
||||
```bash
|
||||
gsd config-set workflow.code_review_depth standard
|
||||
msd config-set workflow.code_review_depth standard
|
||||
```
|
||||
|
||||
2. **Add path-scoped rules** to `workflow.code_review_depth_overrides` in `.planning/config.json`. It's an ordered array of `{ "paths": [...], "depth": "quick" | "standard" | "deep" }` objects:
|
||||
@@ -31,7 +31,7 @@
|
||||
3. **Run the review** as usual:
|
||||
|
||||
```bash
|
||||
/gsd-code-review 12
|
||||
/msd-code-review 12
|
||||
```
|
||||
|
||||
4. **Read the provenance line** in the output to confirm which rule (if any) fired — see [Read the resolved-depth line](#read-the-resolved-depth-line) below.
|
||||
@@ -99,7 +99,7 @@ Two outcomes look similar but mean opposite things:
|
||||
|
||||
## Configuration error reasons
|
||||
|
||||
If `workflow.code_review_depth_overrides` is malformed, `/gsd-code-review` prints one error per defect (all of them, not just the first) and stops — it never silently falls back to a default depth. Errors report the reason as one of the following typed values (from `src/code-review-depth.cts`):
|
||||
If `workflow.code_review_depth_overrides` is malformed, `/msd-code-review` prints one error per defect (all of them, not just the first) and stops — it never silently falls back to a default depth. Errors report the reason as one of the following typed values (from `src/code-review-depth.cts`):
|
||||
|
||||
| Reason | Meaning | Fix |
|
||||
|---|---|---|
|
||||
@@ -120,5 +120,5 @@ Each printed error names the rule index (and, where applicable, the offending pa
|
||||
|
||||
- [Configuration Reference](../CONFIGURATION.md#workflow-toggles) — full schema for `workflow.code_review_depth_overrides` and `workflow.code_review_depth`
|
||||
- [Feature Reference — Code Review Pipeline](../FEATURES.md#93-code-review-pipeline) — why escalation is whole-review and why v1 is prefix-only, not glob
|
||||
- [`/gsd-code-review`](../COMMANDS.md#gsd-code-review) — command reference and the `--depth=` flag
|
||||
- [`/msd-code-review`](../COMMANDS.md#msd-code-review) — command reference and the `--depth=` flag
|
||||
- [docs index](../README.md)
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
|
||||
## Decide which reviewers to use
|
||||
|
||||
GSD Core can route review requests to any combination of: Claude (separate session), Codex CLI, CodeRabbit, OpenCode, Qwen Code, Cursor, Antigravity CLI, Ollama, LM Studio, llama.cpp, and Kimi Code.
|
||||
MSD Core can route review requests to any combination of: Claude (separate session), Codex CLI, CodeRabbit, OpenCode, Qwen Code, Cursor, Antigravity CLI, Ollama, LM Studio, llama.cpp, and Kimi Code.
|
||||
|
||||
That list is not fixed. Each of those is a declared reviewer lane, and a capability can ship its own — see [Ship a reviewer lane in your capability](ship-a-reviewer-lane.md). To see exactly which lanes your installation has, run `gsd-tools review-lane sections`.
|
||||
That list is not fixed. Each of those is a declared reviewer lane, and a capability can ship its own — see [Ship a reviewer lane in your capability](ship-a-reviewer-lane.md). To see exactly which lanes your installation has, run `msd-tools review-lane sections`.
|
||||
|
||||
Each reviewer runs the same structured prompt against your `PLAN.md` files independently. Because different models have different blind spots, multi-reviewer consensus catches more issues than any single reviewer.
|
||||
|
||||
@@ -28,23 +28,23 @@ npm install -g @openai/codex
|
||||
|
||||
## Set default reviewers (optional)
|
||||
|
||||
By default, `/gsd-review` runs all detected CLIs. To pin a subset as project defaults:
|
||||
By default, `/msd-review` runs all detected CLIs. To pin a subset as project defaults:
|
||||
|
||||
```bash
|
||||
/gsd-config --integrations
|
||||
/msd-config --integrations
|
||||
```
|
||||
|
||||
The integrations wizard covers API keys, code-review CLI routing, and the `review.default_reviewers` list. Set the list to the reviewers you want as the no-flag default — for example `["codex","claude"]`.
|
||||
|
||||
Alternatively, set it directly with `gsd-tools`:
|
||||
Alternatively, set it directly with `msd-tools`:
|
||||
|
||||
```bash
|
||||
gsd config-set review.default_reviewers '["codex","claude"]'
|
||||
msd config-set review.default_reviewers '["codex","claude"]'
|
||||
```
|
||||
|
||||
For the full integration settings schema (API keys, model overrides per reviewer, local server host addresses), see [Configuration](../CONFIGURATION.md).
|
||||
|
||||
If you need multiple independent reviewer voices from the same adapter, configure `review.reviewer_instances` and add those instance names to `review.default_reviewers`. Instance names run only through `review.default_reviewers`; they are not valid `/gsd-review` flags. See [Reviewer instances](../CONFIGURATION.md#reviewer-instances) for the schema.
|
||||
If you need multiple independent reviewer voices from the same adapter, configure `review.reviewer_instances` and add those instance names to `review.default_reviewers`. Instance names run only through `review.default_reviewers`; they are not valid `/msd-review` flags. See [Reviewer instances](../CONFIGURATION.md#reviewer-instances) for the schema.
|
||||
|
||||
---
|
||||
|
||||
@@ -53,17 +53,17 @@ If you need multiple independent reviewer voices from the same adapter, configur
|
||||
### Standard review (uses your configured defaults or all detected CLIs)
|
||||
|
||||
```bash
|
||||
/gsd-review --phase 3
|
||||
/msd-review --phase 3
|
||||
```
|
||||
|
||||
GSD invokes each reviewer in sequence, collects structured feedback (Summary, Strengths, Concerns at HIGH/MEDIUM/LOW, Suggestions, Risk Assessment), and writes the combined output to `.planning/phases/03-.../03-REVIEWS.md`.
|
||||
MSD invokes each reviewer in sequence, collects structured feedback (Summary, Strengths, Concerns at HIGH/MEDIUM/LOW, Suggestions, Risk Assessment), and writes the combined output to `.planning/phases/03-.../03-REVIEWS.md`.
|
||||
|
||||
### Select a single reviewer for a one-off run
|
||||
|
||||
```bash
|
||||
/gsd-review --phase 3 --agy
|
||||
/gsd-review --phase 3 --codex
|
||||
/gsd-review --phase 3 --cursor
|
||||
/msd-review --phase 3 --agy
|
||||
/msd-review --phase 3 --codex
|
||||
/msd-review --phase 3 --cursor
|
||||
```
|
||||
|
||||
Any explicit flag overrides both the `--all` default and `review.default_reviewers` for that run.
|
||||
@@ -71,7 +71,7 @@ Any explicit flag overrides both the `--all` default and `review.default_reviewe
|
||||
### Run every available reviewer in parallel
|
||||
|
||||
```bash
|
||||
/gsd-review --phase 3 --all
|
||||
/msd-review --phase 3 --all
|
||||
```
|
||||
|
||||
`--all` always overrides config and runs the full detected set, including any configured local model servers (Ollama, LM Studio, llama.cpp).
|
||||
@@ -81,11 +81,11 @@ Any explicit flag overrides both the `--all` default and `review.default_reviewe
|
||||
If you run Ollama or LM Studio locally, they are included automatically with `--all` when the server is reachable. You can also target them explicitly:
|
||||
|
||||
```bash
|
||||
/gsd-review --phase 3 --ollama
|
||||
/gsd-review --phase 3 --lm-studio
|
||||
/msd-review --phase 3 --ollama
|
||||
/msd-review --phase 3 --lm-studio
|
||||
```
|
||||
|
||||
Configure the host addresses and model selection under `review.*` keys via `/gsd-config --integrations` if the defaults (`localhost:11434` / `localhost:1234`) do not apply.
|
||||
Configure the host addresses and model selection under `review.*` keys via `/msd-config --integrations` if the defaults (`localhost:11434` / `localhost:1234`) do not apply.
|
||||
|
||||
---
|
||||
|
||||
@@ -106,7 +106,7 @@ If a reviewer's entry reads `unknown`, pin it: set `review.models.<slug>` for th
|
||||
|
||||
Some `unknown` values are expected, not a bug to chase: lanes that accept no model at all (`cursor`, `qwen`, `coderabbit`), and any lane whose CLI didn't disclose one on this run. `pinned` is a certain value; `banner` and `transcript` are recovered from third-party CLI output and can degrade to `unknown` after an upstream release changes that output.
|
||||
|
||||
A `models:` entry like `gpt-5.6-sol (reasoning=high)` is not a formatting quirk: the `(reasoning=<level>)` suffix reflects a reasoning effort GSD itself applied to that lane, driven by your `effort.*` config — not the CLI's own default.
|
||||
A `models:` entry like `gpt-5.6-sol (reasoning=high)` is not a formatting quirk: the `(reasoning=<level>)` suffix reflects a reasoning effort MSD itself applied to that lane, driven by your `effort.*` config — not the CLI's own default.
|
||||
|
||||
---
|
||||
|
||||
@@ -115,7 +115,7 @@ A `models:` entry like `gpt-5.6-sol (reasoning=high)` is not a formatting quirk:
|
||||
Once you have reviewed the output, replan incorporating the feedback:
|
||||
|
||||
```bash
|
||||
/gsd-plan-phase 3 --reviews
|
||||
/msd-plan-phase 3 --reviews
|
||||
```
|
||||
|
||||
The planner reads `REVIEWS.md` and adjusts the plans to address the concerns before saving.
|
||||
@@ -127,7 +127,7 @@ The planner reads `REVIEWS.md` and adjusts the plans to address the concerns bef
|
||||
For phases where you want to iterate until all HIGH-severity concerns are resolved, use the convergence loop:
|
||||
|
||||
```bash
|
||||
/gsd-plan-review-convergence 3
|
||||
/msd-plan-review-convergence 3
|
||||
```
|
||||
|
||||
This runs `plan-phase → review → replan → re-review` up to three cycles (default). The loop exits when the HIGH-concern count reaches zero.
|
||||
@@ -135,17 +135,17 @@ This runs `plan-phase → review → replan → re-review` up to three cycles (d
|
||||
### Convergence with a specific reviewer
|
||||
|
||||
```bash
|
||||
/gsd-plan-review-convergence 3 --codex
|
||||
/gsd-plan-review-convergence 3 --agy
|
||||
/msd-plan-review-convergence 3 --codex
|
||||
/msd-plan-review-convergence 3 --agy
|
||||
```
|
||||
|
||||
### Convergence with all reviewers and a higher cycle cap
|
||||
|
||||
```bash
|
||||
/gsd-plan-review-convergence 3 --all --max-cycles 5
|
||||
/msd-plan-review-convergence 3 --all --max-cycles 5
|
||||
```
|
||||
|
||||
**Stall detection:** if the HIGH-concern count is not decreasing across cycles, GSD warns you. When the cycle cap is reached with open HIGH concerns, an escalation gate asks whether to proceed or review manually.
|
||||
**Stall detection:** if the HIGH-concern count is not decreasing across cycles, MSD warns you. When the cycle cap is reached with open HIGH concerns, an escalation gate asks whether to proceed or review manually.
|
||||
|
||||
---
|
||||
|
||||
@@ -158,15 +158,15 @@ This runs `plan-phase → review → replan → re-review` up to three cycles (d
|
||||
| Your project is OpenAI-heavy | add `--codex` for an OpenAI-model perspective |
|
||||
| You want GitHub Copilot's model | add `--opencode` |
|
||||
| You want to avoid API costs entirely | configure Ollama with a local model and use `--ollama` |
|
||||
| You need maximum coverage before a release | `/gsd-plan-review-convergence N --all` |
|
||||
| You're iterating quickly and want fast feedback | pick one CLI: `/gsd-review --phase N --agy` |
|
||||
| You need maximum coverage before a release | `/msd-plan-review-convergence N --all` |
|
||||
| You're iterating quickly and want fast feedback | pick one CLI: `/msd-review --phase N --agy` |
|
||||
|
||||
---
|
||||
|
||||
## Related
|
||||
|
||||
- [Verify and ship](verify-and-ship.md)
|
||||
- [Ship a reviewer lane in your capability](ship-a-reviewer-lane.md) — add a reviewer GSD does not ship with, by declaring it in a capability manifest
|
||||
- [Ship a reviewer lane in your capability](ship-a-reviewer-lane.md) — add a reviewer MSD does not ship with, by declaring it in a capability manifest
|
||||
- [Configuration](../CONFIGURATION.md)
|
||||
- [Commands](../COMMANDS.md)
|
||||
- [docs index](../README.md)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# How to ship a reviewer lane in your capability
|
||||
|
||||
**Goal:** Declare a *reviewer lane* in a capability manifest so `/gsd-review` discovers your external review CLI or model endpoint, offers a flag for it, invokes it, and renders its output into `REVIEWS.md` — without patching GSD core.
|
||||
**Goal:** Declare a *reviewer lane* in a capability manifest so `/msd-review` discovers your external review CLI or model endpoint, offers a flag for it, invokes it, and renders its output into `REVIEWS.md` — without patching MSD core.
|
||||
|
||||
**Prerequisites:** You already have a capability (`capability.json`), or you are creating one. The reviewer tool is installed and works from your shell. GSD 1.9.0 or later.
|
||||
**Prerequisites:** You already have a capability (`capability.json`), or you are creating one. The reviewer tool is installed and works from your shell. MSD 1.9.0 or later.
|
||||
|
||||
Before 1.9.0 a reviewer was a core patch: a hardcoded roster entry, a hand-authored bash leg in `review.md`, a hardcoded output heading, and central config keys. From 1.9.0 a lane is manifest data, so shipping a reviewer is shipping a capability. See [ADR-2782](../adr/2782-reviewer-lane-capability-surface.md) for the decision record.
|
||||
|
||||
@@ -10,12 +10,12 @@ Before 1.9.0 a reviewer was a core patch: a hardcoded roster entry, a hand-autho
|
||||
|
||||
## Decide which shape your lane takes
|
||||
|
||||
A `reviewer` body is admissible on two roles. Pick by whether GSD installs *into* your tool.
|
||||
A `reviewer` body is admissible on two roles. Pick by whether MSD installs *into* your tool.
|
||||
|
||||
| Your situation | Use | Why |
|
||||
|---|---|---|
|
||||
| Your capability is already a runtime GSD installs into (it has a `runtime` body) and that same CLI can also review | Keep `role: "runtime"`, add a `reviewer` body | One manifest stays one manifest — this is how `codex`, `cursor`, and `antigravity` ship |
|
||||
| Your tool only reviews — GSD never installs commands, agents, or skills into it | `role: "reviewer"` | The honest description: a lane with no install surface, like `gemini`, `coderabbit`, and `ollama` |
|
||||
| Your capability is already a runtime MSD installs into (it has a `runtime` body) and that same CLI can also review | Keep `role: "runtime"`, add a `reviewer` body | One manifest stays one manifest — this is how `codex`, `cursor`, and `antigravity` ship |
|
||||
| Your tool only reviews — MSD never installs commands, agents, or skills into it | `role: "reviewer"` | The honest description: a lane with no install surface, like `gemini`, `coderabbit`, and `ollama` |
|
||||
| Your capability adds planning steps, gates, or contributions | `role: "feature"` — and a separate lane capability | A feature manifest may not carry a `reviewer` body; the validator rejects it |
|
||||
|
||||
A `role: "reviewer"` capability **must** carry a `reviewer` body, **must not** carry a `runtime` body, and **must not** carry any feature-only field — `skills`, `agents`, `steps`, `contributions`, `gates`, `hooks`, or `activationKey`. A lane owns no artifacts and wires no loop extension point.
|
||||
@@ -24,7 +24,7 @@ A `role: "reviewer"` capability **must** carry a `reviewer` body, **must not** c
|
||||
|
||||
## Declare a spawned-CLI lane
|
||||
|
||||
Most lanes are `transport: "spawn"` — GSD runs a binary and reads its output. Add a `reviewer` block to your manifest:
|
||||
Most lanes are `transport: "spawn"` — MSD runs a binary and reads its output. Add a `reviewer` block to your manifest:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -32,10 +32,10 @@ Most lanes are `transport: "spawn"` — GSD runs a binary and reads its output.
|
||||
"role": "reviewer",
|
||||
"version": "1.0.0",
|
||||
"title": "Acme Review CLI",
|
||||
"description": "Acme CLI — cross-AI /gsd-review reviewer lane only; not a GSD install target.",
|
||||
"description": "Acme CLI — cross-AI /msd-review reviewer lane only; not a MSD install target.",
|
||||
"tier": "full",
|
||||
"requires": [],
|
||||
"engines": { "gsd": ">=1.9.0" },
|
||||
"engines": { "msd": ">=1.9.0" },
|
||||
|
||||
"reviewer": {
|
||||
"slug": "acme",
|
||||
@@ -78,7 +78,7 @@ Most lanes are `transport: "spawn"` — GSD runs a binary and reads its output.
|
||||
|
||||
Four fields decide whether the lane works at all, so get these right first:
|
||||
|
||||
- **`invoke.args`** carries the `{{model}}`, `{{prompt}}`, `{{effort}}`, and `{{output}}` placeholders. GSD substitutes them; anything else is passed through literally.
|
||||
- **`invoke.args`** carries the `{{model}}`, `{{prompt}}`, `{{effort}}`, and `{{output}}` placeholders. MSD substitutes them; anything else is passed through literally.
|
||||
- **`promptChannel`** says how the plan text reaches the tool — `stdin` when it reads a pipe, `argv` or `argv-file-ref` when it takes the prompt path as an argument, `none` when the tool reads the working tree itself (as CodeRabbit does).
|
||||
- **`outputChannel`** is `stdout`, or `file-arg` when the tool writes to a path you name (then also declare `invoke.outputArg`, as `codex` does with `-o`).
|
||||
- **`timeoutFloorMs`** is the measured wall-clock floor for *your* tool. Lane divergence here is expected and correct — the descriptor exists to declare divergence in one place, not to impose one number on every lane.
|
||||
@@ -146,7 +146,7 @@ Users then set them the ordinary way, in `.planning/config.json`:
|
||||
|
||||
## Build and install
|
||||
|
||||
If your capability lives in the GSD repo, regenerate the committed registry and check for drift:
|
||||
If your capability lives in the MSD repo, regenerate the committed registry and check for drift:
|
||||
|
||||
```bash
|
||||
npm run gen:capability-registry
|
||||
@@ -156,20 +156,20 @@ npm run lint:generated-sync
|
||||
If you are shipping out-of-tree, package and install it like any other capability:
|
||||
|
||||
```bash
|
||||
gsd capability install <url>
|
||||
msd capability install <url>
|
||||
```
|
||||
|
||||
Uniqueness is checked across the merged first-party ∪ overlay set — a duplicate `slug`, a duplicate entry in `flags`, or a duplicate `reviewsSection` collides. **Expect that collision to be quiet.** `gsd capability install` does not run the cross-capability check; it runs at *load* time, and a colliding overlay is dropped from the active set with a warning rather than failing the install. First-party always wins.
|
||||
Uniqueness is checked across the merged first-party ∪ overlay set — a duplicate `slug`, a duplicate entry in `flags`, or a duplicate `reviewsSection` collides. **Expect that collision to be quiet.** `msd capability install` does not run the cross-capability check; it runs at *load* time, and a colliding overlay is dropped from the active set with a warning rather than failing the install. First-party always wins.
|
||||
|
||||
That failure mode is worth internalizing before you debug it: the install command reports success, and your lane simply never appears. If a lane you just installed is missing from `gsd-tools review-lane sections`, suspect a name collision before you suspect the probe. Malformed values inside the body — a `slug` outside `^[a-z0-9][a-z0-9_-]*$`, an enum member that does not exist, an `outputArg` without `outputChannel: "file-arg"` — are ordinary validation errors and are reported directly.
|
||||
That failure mode is worth internalizing before you debug it: the install command reports success, and your lane simply never appears. If a lane you just installed is missing from `msd-tools review-lane sections`, suspect a name collision before you suspect the probe. Malformed values inside the body — a `slug` outside `^[a-z0-9][a-z0-9_-]*$`, an enum member that does not exist, an `outputArg` without `outputChannel: "file-arg"` — are ordinary validation errors and are reported directly.
|
||||
|
||||
Two naming rules are easy to conflate, so keep them apart. Your `slug` may not be `__proto__`, `constructor`, or `prototype` — a prototype-pollution guard, not a namespace policy; any other grammatical slug is yours, including one starting `gsd-`. Your capability **`id`**, separately, may not begin with `gsd-`, `gsd-core-`, or `anthropic-`; those prefixes are reserved so nothing can impersonate a first-party capability.
|
||||
Two naming rules are easy to conflate, so keep them apart. Your `slug` may not be `__proto__`, `constructor`, or `prototype` — a prototype-pollution guard, not a namespace policy; any other grammatical slug is yours, including one starting `msd-`. Your capability **`id`**, separately, may not begin with `msd-`, `msd-core-`, or `anthropic-`; those prefixes are reserved so nothing can impersonate a first-party capability.
|
||||
|
||||
An *unknown* field inside your `reviewer` body behaves differently: it is a non-fatal warning on stderr, never a build failure. A manifest built against a newer GSD degrades visibly instead of crashing.
|
||||
An *unknown* field inside your `reviewer` body behaves differently: it is a non-fatal warning on stderr, never a build failure. A manifest built against a newer MSD degrades visibly instead of crashing.
|
||||
|
||||
### Publish it so people can find it
|
||||
|
||||
From GSD 1.9.1, a lane has its own discoverability catalog: the [Reviewer Lane Registry](../registries/reviewer-registry.md). Listing is a documentation PR — append one entry to `docs/registries/reviewers.json`, regenerate, open a PR. Register once; your GitHub Releases are the update channel from then on.
|
||||
From MSD 1.9.1, a lane has its own discoverability catalog: the [Reviewer Lane Registry](../registries/reviewer-registry.md). Listing is a documentation PR — append one entry to `docs/registries/reviewers.json`, regenerate, open a PR. Register once; your GitHub Releases are the update channel from then on.
|
||||
|
||||
Follow [List your reviewer lane in the registry](list-your-reviewer-lane.md) for the task flow.
|
||||
|
||||
@@ -179,11 +179,11 @@ The Reviewer Lane Registry is for lanes that are **not install targets in their
|
||||
|
||||
## Verify the lane resolves
|
||||
|
||||
Check that GSD sees your lane before you run a real review:
|
||||
Check that MSD sees your lane before you run a real review:
|
||||
|
||||
```bash
|
||||
gsd-tools review-lane sections
|
||||
gsd-tools review-lane flags
|
||||
msd-tools review-lane sections
|
||||
msd-tools review-lane flags
|
||||
```
|
||||
|
||||
`sections` lists every `slug` with the heading it renders under; `flags` lists every selector flag. Your lane appears in both, or it is not installed.
|
||||
@@ -191,16 +191,16 @@ gsd-tools review-lane flags
|
||||
Then dry-check the invocation plan for your lane alone:
|
||||
|
||||
```bash
|
||||
gsd-tools review-lane plan --selected acme
|
||||
msd-tools review-lane plan --selected acme
|
||||
```
|
||||
|
||||
A resolvable lane returns `"ok": true` with its `section`, `transport`, and prompt path. Once that is green, run it for real against a planned phase:
|
||||
|
||||
```bash
|
||||
/gsd-review --phase 3 --acme
|
||||
/msd-review --phase 3 --acme
|
||||
```
|
||||
|
||||
If the lane is absent from `--all`, the probe is the usual culprit: `command-exists` fails silently when the binary is not on `PATH` in the environment GSD runs in.
|
||||
If the lane is absent from `--all`, the probe is the usual culprit: `command-exists` fails silently when the binary is not on `PATH` in the environment MSD runs in.
|
||||
|
||||
---
|
||||
|
||||
@@ -219,8 +219,8 @@ Be clear-eyed about what that buys, because your users are trusting your judgmen
|
||||
Three consequences you should design for:
|
||||
|
||||
- **Your `args` are signature-bound, not just your binary.** Changing `binary`, `args`, `hostConfigKey`, `promptChannel`, or `handler` in a new version re-triggers consent on update. Changing `reviewsSection` or `timeoutFloorMs` does not — a cosmetic prompt is how users learn to click through.
|
||||
- **An `openai-http` lane binds the *resolved host*, not just the config key.** GSD re-resolves `hostConfigKey` before every invocation and blocks the lane if the destination changed, rather than silently sending plans somewhere new. Users see the lane refuse and must re-consent. Point `defaultHost` at the address you actually mean.
|
||||
- **What the user saw is only tamper-evident because the bundle is pinned.** The disclosure is trustworthy because the downloaded capability is integrity-checked and its hash recorded at install; a later change to your `args` or `hostConfigKey` shows up as a changed signature rather than sliding in quietly. Keep `engines.gsd` honest for the same reason — it is a hard gate, so a lane declaring a range it does not actually work on is blocked at install and skipped at load rather than failing confusingly at review time.
|
||||
- **An `openai-http` lane binds the *resolved host*, not just the config key.** MSD re-resolves `hostConfigKey` before every invocation and blocks the lane if the destination changed, rather than silently sending plans somewhere new. Users see the lane refuse and must re-consent. Point `defaultHost` at the address you actually mean.
|
||||
- **What the user saw is only tamper-evident because the bundle is pinned.** The disclosure is trustworthy because the downloaded capability is integrity-checked and its hash recorded at install; a later change to your `args` or `hostConfigKey` shows up as a changed signature rather than sliding in quietly. Keep `engines.msd` honest for the same reason — it is a hard gate, so a lane declaring a range it does not actually work on is blocked at install and skipped at load rather than failing confusingly at review time.
|
||||
|
||||
For the reasoning behind consent-plus-integrity rather than a sandbox, see [The capability trust model](../explanation/capability-trust-model.md).
|
||||
|
||||
@@ -234,9 +234,9 @@ Before 1.9.0, a runtime capability declared itself a reviewer with a boolean in
|
||||
"runtime": { "hostBehaviors": { "reviewerCli": true } }
|
||||
```
|
||||
|
||||
That flag carried no invocation data — it only added the capability id to the roster, leaving the probe, argv shape, timeout, and output policy hardcoded in GSD core. It was superseded by the `reviewer` body in 1.9.0, kept working for one release as a derived alias, and **was removed in the release after that**.
|
||||
That flag carried no invocation data — it only added the capability id to the roster, leaving the probe, argv shape, timeout, and output policy hardcoded in MSD core. It was superseded by the `reviewer` body in 1.9.0, kept working for one release as a derived alias, and **was removed in the release after that**.
|
||||
|
||||
**Symptom.** Your capability installs and validates exactly as before, but `/gsd-review` no longer offers your flag and your lane never runs. On a registry build or a capability install you will see:
|
||||
**Symptom.** Your capability installs and validates exactly as before, but `/msd-review` no longer offers your flag and your lane never runs. On a registry build or a capability install you will see:
|
||||
|
||||
```
|
||||
⚠ capability "your-cap" runtime.hostBehaviors.reviewerCli was removed (ADR-2782 D9)
|
||||
@@ -260,7 +260,7 @@ That flag carried no invocation data — it only added the capability id to the
|
||||
|
||||
Then rebuild and re-verify with the steps in [Build and install](#build-and-install) and [Verify the lane resolves](#verify-the-lane-resolves).
|
||||
|
||||
Two things the migration buys you beyond restoring the lane: your invocation shape becomes declared data rather than something GSD core has to know about, and your lane can own its own config keys (see [Own your lane's config keys](#own-your-lanes-config-keys)).
|
||||
Two things the migration buys you beyond restoring the lane: your invocation shape becomes declared data rather than something MSD core has to know about, and your lane can own its own config keys (see [Own your lane's config keys](#own-your-lanes-config-keys)).
|
||||
|
||||
> **Nothing else about your capability changes.** A manifest still carrying the removed key parses, validates, and installs exactly as before — it simply contributes no lane, and says so. The key is inert, not fatal.
|
||||
|
||||
@@ -287,7 +287,7 @@ Filing the issue is the supported route, not a workaround. The `openai-http` tra
|
||||
- [Capability manifest](../reference/capability-manifest.md) — the full `reviewer` body field table and validation rules
|
||||
- [Capability manifest → `hostBehaviors`](../reference/capability-manifest.md#hostbehaviors) — why the bag is unvalidated, and the one removal notice inside it
|
||||
- [Set up cross-AI review](set-up-cross-ai-review.md) — the user-facing side: choosing, configuring, and running reviewers
|
||||
- [Develop a Capability for GSD 1.5+](develop-a-capability.md) — manifests, registry generation, and federated config
|
||||
- [Publish a capability](publish-a-capability.md) — versioning, `engines.gsd`, and distribution
|
||||
- [Develop a Capability for MSD 1.5+](develop-a-capability.md) — manifests, registry generation, and federated config
|
||||
- [Publish a capability](publish-a-capability.md) — versioning, `engines.msd`, and distribution
|
||||
- [The capability trust model](../explanation/capability-trust-model.md) — disclosure, consent, and integrity
|
||||
- [ADR-2782](../adr/2782-reviewer-lane-capability-surface.md) — why the lane became a capability surface, and what it deliberately excludes
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
**Goal:** De-risk an implementation by running focused feasibility experiments (spikes) and exploring visual directions through throwaway HTML mockups (sketches) before committing a phase to any specific approach.
|
||||
|
||||
**Prerequisites:** None. `/gsd-spike` and `/gsd-sketch` create their own storage directories and do not require an initialised GSD project.
|
||||
**Prerequisites:** None. `/msd-spike` and `/msd-sketch` create their own storage directories and do not require an initialised MSD project.
|
||||
|
||||
---
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
|
||||
| You want to answer… | Use |
|
||||
|---|---|
|
||||
| "Will this technical approach actually work?" | `/gsd-spike` |
|
||||
| "Does this layout / interaction / visual treatment feel right?" | `/gsd-sketch` |
|
||||
| "Will this technical approach actually work?" | `/msd-spike` |
|
||||
| "Does this layout / interaction / visual treatment feel right?" | `/msd-sketch` |
|
||||
| "What's the right technical approach, and what should it look like?" | Both, in order: spike first, then sketch |
|
||||
|
||||
Spikes answer binary feasibility questions with executable code and a VALIDATED / INVALIDATED / PARTIAL verdict. Sketches answer visual questions with 2–3 browser-comparable HTML variants. They are complementary — a spike proves the approach is buildable, a sketch proves the design is worth building.
|
||||
@@ -23,21 +23,21 @@ Spikes answer binary feasibility questions with executable code and a VALIDATED
|
||||
### Interactive intake (default)
|
||||
|
||||
```bash
|
||||
/gsd-spike
|
||||
/msd-spike
|
||||
```
|
||||
|
||||
GSD asks about the technical question, decomposes it into 2–5 independent experiments framed as **Given / When / Then** hypotheses, and asks for confirmation before building.
|
||||
MSD asks about the technical question, decomposes it into 2–5 independent experiments framed as **Given / When / Then** hypotheses, and asks for confirmation before building.
|
||||
|
||||
### Provide the idea directly
|
||||
|
||||
```bash
|
||||
/gsd-spike "can we stream LLM tokens through SSE"
|
||||
/msd-spike "can we stream LLM tokens through SSE"
|
||||
```
|
||||
|
||||
### Skip intake and run immediately
|
||||
|
||||
```bash
|
||||
/gsd-spike --quick "websocket vs SSE latency"
|
||||
/msd-spike --quick "websocket vs SSE latency"
|
||||
```
|
||||
|
||||
`--quick` skips the decomposition conversation and treats the argument as a single spike question. Use this when the question is already specific enough to run without refinement.
|
||||
@@ -59,10 +59,10 @@ All spikes are indexed in `.planning/spikes/MANIFEST.md`.
|
||||
When you have signal, wrap the findings into a project-local skill so future sessions load them automatically:
|
||||
|
||||
```bash
|
||||
/gsd-spike --wrap-up
|
||||
/msd-spike --wrap-up
|
||||
```
|
||||
|
||||
This writes `.claude/skills/spike-findings-[project]/`. The skill is discovered automatically and loaded by subsequent `/gsd-sketch`, `/gsd-ui-phase`, and `/gsd-plan-phase` runs — you do not need to reference it explicitly.
|
||||
This writes `.claude/skills/spike-findings-[project]/`. The skill is discovered automatically and loaded by subsequent `/msd-sketch`, `/msd-ui-phase`, and `/msd-plan-phase` runs — you do not need to reference it explicitly.
|
||||
|
||||
---
|
||||
|
||||
@@ -71,21 +71,21 @@ This writes `.claude/skills/spike-findings-[project]/`. The skill is discovered
|
||||
### Mood intake (default)
|
||||
|
||||
```bash
|
||||
/gsd-sketch
|
||||
/msd-sketch
|
||||
```
|
||||
|
||||
GSD opens a short conversation to explore feel, visual references, and the core user action before any code is written. It asks one question at a time and only starts building when you say go.
|
||||
MSD opens a short conversation to explore feel, visual references, and the core user action before any code is written. It asks one question at a time and only starts building when you say go.
|
||||
|
||||
### Provide a design direction directly
|
||||
|
||||
```bash
|
||||
/gsd-sketch "dashboard layout"
|
||||
/msd-sketch "dashboard layout"
|
||||
```
|
||||
|
||||
### Skip mood intake and run immediately
|
||||
|
||||
```bash
|
||||
/gsd-sketch --quick "sidebar navigation"
|
||||
/msd-sketch --quick "sidebar navigation"
|
||||
```
|
||||
|
||||
`--quick` skips the intake conversation entirely and uses the argument as the design direction.
|
||||
@@ -93,7 +93,7 @@ GSD opens a short conversation to explore feel, visual references, and the core
|
||||
### Non-Claude runtimes (Codex, Antigravity CLI, etc.)
|
||||
|
||||
```bash
|
||||
/gsd-sketch --text "onboarding flow"
|
||||
/msd-sketch --text "onboarding flow"
|
||||
```
|
||||
|
||||
`--text` replaces interactive prompts with plain-text numbered lists. Use this when your runtime does not support `AskUserQuestion`.
|
||||
@@ -115,10 +115,10 @@ All sketches are indexed in `.planning/sketches/MANIFEST.md`.
|
||||
After picking a variant, capture the visual decisions into a project-local skill:
|
||||
|
||||
```bash
|
||||
/gsd-sketch --wrap-up
|
||||
/msd-sketch --wrap-up
|
||||
```
|
||||
|
||||
This writes `.claude/skills/sketch-findings-[project]/`. The skill is picked up automatically by `/gsd-ui-phase` — pre-validated decisions (layout, colour palette, typography, spacing) are treated as locked and are not re-asked.
|
||||
This writes `.claude/skills/sketch-findings-[project]/`. The skill is picked up automatically by `/msd-ui-phase` — pre-validated decisions (layout, colour palette, typography, spacing) are treated as locked and are not re-asked.
|
||||
|
||||
---
|
||||
|
||||
@@ -127,26 +127,26 @@ This writes `.claude/skills/sketch-findings-[project]/`. The skill is picked up
|
||||
This is the recommended sequence when you are uncertain about both technical feasibility and visual direction:
|
||||
|
||||
```bash
|
||||
/gsd-spike "SSE vs WebSocket for real-time feed"
|
||||
/gsd-spike --wrap-up
|
||||
/msd-spike "SSE vs WebSocket for real-time feed"
|
||||
/msd-spike --wrap-up
|
||||
|
||||
/gsd-sketch "real-time feed UI"
|
||||
/gsd-sketch --wrap-up
|
||||
/msd-sketch "real-time feed UI"
|
||||
/msd-sketch --wrap-up
|
||||
|
||||
/gsd-discuss-phase N
|
||||
/gsd-plan-phase N
|
||||
/msd-discuss-phase N
|
||||
/msd-plan-phase N
|
||||
```
|
||||
|
||||
The spike findings inform the sketch (real data shapes, real interaction states, realistic constraints). Both wrap-ups persist decisions that the planner and UI researcher load automatically, so you do not need to re-explain choices during `/gsd-discuss-phase` or `/gsd-ui-phase`.
|
||||
The spike findings inform the sketch (real data shapes, real interaction states, realistic constraints). Both wrap-ups persist decisions that the planner and UI researcher load automatically, so you do not need to re-explain choices during `/msd-discuss-phase` or `/msd-ui-phase`.
|
||||
|
||||
---
|
||||
|
||||
## How a spike or sketch feeds into a phase
|
||||
|
||||
Spike and sketch artifacts do not need to be manually referenced. GSD reads them automatically at two points:
|
||||
Spike and sketch artifacts do not need to be manually referenced. MSD reads them automatically at two points:
|
||||
|
||||
1. **`/gsd-sketch`** — loads `.claude/skills/spike-findings-*/` before building mockups, so variants reflect proven constraints (streaming states, real field names, etc.)
|
||||
2. **`/gsd-ui-phase N`** — loads `.claude/skills/sketch-findings-*/` before generating the UI design contract; pre-validated design decisions are treated as locked
|
||||
1. **`/msd-sketch`** — loads `.claude/skills/spike-findings-*/` before building mockups, so variants reflect proven constraints (streaming states, real field names, etc.)
|
||||
2. **`/msd-ui-phase N`** — loads `.claude/skills/sketch-findings-*/` before generating the UI design contract; pre-validated design decisions are treated as locked
|
||||
|
||||
The planner also reads spike findings when a `spike-findings-*` skill is present, so validated technical choices (which library, which protocol, which data format) flow directly into task plans without repeated explanation.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# State a failing direction
|
||||
|
||||
`/gsd-plan-phase` blocks when a plan's `<automated>` acceptance command does not say what output
|
||||
`/msd-plan-phase` blocks when a plan's `<automated>` acceptance command does not say what output
|
||||
constitutes failure. This page is what to do about it — how to write the statement, how to read
|
||||
the probe's verdicts, and how to migrate a phase planned before the rule existed.
|
||||
|
||||
@@ -40,7 +40,7 @@ prose here.
|
||||
## Run the probe yourself
|
||||
|
||||
```bash
|
||||
gsd-tools check verify-failure-directions 3 --raw
|
||||
msd-tools check verify-failure-directions 3 --raw
|
||||
```
|
||||
|
||||
Same JSON the plan-checker acts on. Each row carries `command`, `statement`, `plan`, `task`,
|
||||
@@ -82,13 +82,13 @@ blocker per runnable command. Two ways forward:
|
||||
1. **Add the statements by hand.** Run the probe with `--raw`, and for each `missing` row open
|
||||
the named `plan` and `task` and add a `<fails_when>` after that command. This preserves the
|
||||
plan as reviewed.
|
||||
2. **Re-plan the phase** with `/gsd-plan-phase <N>`, which emits statements from the start. Do
|
||||
2. **Re-plan the phase** with `/msd-plan-phase <N>`, which emits statements from the start. Do
|
||||
this when the plan needs revising anyway; it discards any hand edits.
|
||||
|
||||
Sentinel commands need no migration — they were never runnable.
|
||||
|
||||
## Related
|
||||
|
||||
- [`gsd-tools check verify-failure-directions`](../COMMANDS.md#gsd-tools-check-verify-failure-directions) — the command reference
|
||||
- [`msd-tools check verify-failure-directions`](../COMMANDS.md#msd-tools-check-verify-failure-directions) — the command reference
|
||||
- [Resolve verify-command path findings](resolve-verify-command-path-findings.md) — the sibling probe, for a command whose *target* does not resolve
|
||||
- [Stated Failing Direction](../FEATURES.md#167-stated-failing-direction) — why the check is shaped this way
|
||||
|
||||
@@ -2,16 +2,16 @@
|
||||
|
||||
A **takeover** changes who maintains something that already exists and is already listed — a third-party Feature Capability, a reviewer lane, or an Embeddable Orchestration System (EoS) host integration.
|
||||
|
||||
There is no `gsd capability transfer` command and no rename tooling. A takeover is a governance process executed entirely through registry pull requests and the entry's GitHub Discussion thread. Everything below is manual and auditable by design.
|
||||
There is no `msd capability transfer` command and no rename tooling. A takeover is a governance process executed entirely through registry pull requests and the entry's GitHub Discussion thread. Everything below is manual and auditable by design.
|
||||
|
||||
## Decide what you are taking over
|
||||
|
||||
| Surface | Manifest | Registry source | Ships in |
|
||||
|---|---|---|---|
|
||||
| First-party capability | `capabilities/<id>/capability.json` | none — generated registry only | the `gsd-core` release |
|
||||
| First-party capability | `capabilities/<id>/capability.json` | none — generated registry only | the `msd-core` release |
|
||||
| Third-party Feature Capability | `capability.json`, `role: "feature"` | `docs/registries/capabilities.json` | the author's own repo |
|
||||
| Third-party reviewer lane | `capability.json`, `role: "reviewer"` | `docs/registries/reviewers.json` | the author's own repo |
|
||||
| Third-party EoS host integration | ADR-1239 host plugin (no `capability.json` in `gsd-core`) | `docs/registries/eos.json` | the author's own repo |
|
||||
| Third-party EoS host integration | ADR-1239 host plugin (no `capability.json` in `msd-core`) | `docs/registries/eos.json` | the author's own repo |
|
||||
|
||||
A first-party capability has no registry entry and no external owner — changing who works on it is ordinary contribution, not a takeover. Use this guide only when an external `repo` and `author` are recorded somewhere under `docs/registries/`.
|
||||
|
||||
@@ -21,7 +21,7 @@ A first-party capability has no registry entry and no external owner — changin
|
||||
|---|---|---|
|
||||
| **T1 — Consensual handoff** | The current author agrees, in public, to hand the project off | Same `id`, same entry, new `repo` and `author` |
|
||||
| **T2 — Adoption fork** | The author is unreachable but the linked repo still works | **New** `id`, new entry, new Discussion; the original entry stays |
|
||||
| **T3 — First-party absorption** | GSD absorbs the surface into `capabilities/<id>/` | In-repo capability; the registry entry is annotated, not deleted |
|
||||
| **T3 — First-party absorption** | MSD absorbs the surface into `capabilities/<id>/` | In-repo capability; the registry entry is annotated, not deleted |
|
||||
| **T4 — Retirement** | Illegal content, malware, spam, or a dead link | Entry removed |
|
||||
|
||||
> **The narrow removal policy constrains every mode.** A merged entry is removed only for illegal content, malware, spam, or a repo that is dead or completely non-functional. It is **never** removed for staleness, quality, abandonment, or a maintainer's disagreement with its design. An abandoned-but-working entry therefore cannot be reclaimed — T2 is always additive, and the original `id` stays taken forever.
|
||||
@@ -32,7 +32,7 @@ Collect all of this before opening anything. Every later step reads from it.
|
||||
|
||||
- The current registry object, copied verbatim from `capabilities.json`, `reviewers.json`, or `eos.json`.
|
||||
- The upstream `capability.json` (or, for EoS, the host plugin's own manifest), copied verbatim.
|
||||
- `id`, `author`, `repo`, `license`, `enginesGsd`, and — for EoS — `protocolVersion`.
|
||||
- `id`, `author`, `repo`, `license`, `enginesMsd`, and — for EoS — `protocolVersion`.
|
||||
- The entry's `discussion` URL and its full comment history.
|
||||
- A liveness probe of `repo`: is the default branch reachable and non-empty? If the link is dead, the correct mode is **T4**, not T2.
|
||||
- The upstream release history — the shields badge and the update channel both read from `repo`, so a repo with no releases has no update channel at all.
|
||||
@@ -41,7 +41,7 @@ Collect all of this before opening anything. Every later step reads from it.
|
||||
|
||||
**License gate.** T2 and T3 both require a fork or a derivative. If `license` is `UNLICENSED` or `Proprietary`, stop — neither mode is available without written permission from the rights holder.
|
||||
|
||||
**Reserved-prefix gate.** The `gsd-`, `gsd-core-`, and `anthropic-` prefixes are reserved for first-party, and a third-party id claiming one is rejected at the conformance gate. You may only move into a reserved prefix as part of **T3**.
|
||||
**Reserved-prefix gate.** The `msd-`, `msd-core-`, and `anthropic-` prefixes are reserved for first-party, and a third-party id claiming one is rejected at the conformance gate. You may only move into a reserved prefix as part of **T3**.
|
||||
|
||||
**Consent gate (T1 only).** The handoff must be a public comment in the entry's Discussion thread, posted from the GitHub account that owns `repo`. A DM, an email, or a comment from any other account is not sufficient. The reason is structural: the registry-entry PR template's ownership statement is self-attested and no automated gate checks who is changing `repo` or `author`, so the Discussion permalink is the only auditable record that the handoff happened.
|
||||
|
||||
@@ -53,7 +53,7 @@ These fields are the user-visible contract. A takeover **preserves** them. If yo
|
||||
|
||||
**Feature Capability** — `interactions.loopExtensionPoints` (which of the 12 Loop Extension Points it registers on), `hookKinds`, `configKeys`, `requires`, `runtimeCompat`, `produces`, `consumes`; plus the manifest's `skills` and `agents` stems, which must stay unique across the merged first-party and overlay set.
|
||||
|
||||
**Reviewer lane** — `interactions.slug`, `flags`, `transport`, `evidenceClass`, `reviewsSection`, `requiresBinaries`, `configKeys`. The `slug`, `flags`, and `reviewsSection` must remain unique across the merged first-party and overlay set; a collision breaks `/gsd-review` for anyone running both lanes.
|
||||
**Reviewer lane** — `interactions.slug`, `flags`, `transport`, `evidenceClass`, `reviewsSection`, `requiresBinaries`, `configKeys`. The `slug`, `flags`, and `reviewsSection` must remain unique across the merged first-party and overlay set; a collision breaks `/msd-review` for anyone running both lanes.
|
||||
|
||||
**EoS host integration** — `protocolVersion`, `interactions.interfacePoints` (the subset of `command`, `dispatch`, `model`, `hooks`, `state`, `artifact` it binds), `interactions.profile`, and all eight required axes: `embeddingMode`, `commandSurface`, `dispatch`, `modelMode`, `hookBus`, `stateIO`, `transport`, `runtime` — plus `effortSurface` if the entry already carries it.
|
||||
|
||||
@@ -61,11 +61,11 @@ These fields are the user-visible contract. A takeover **preserves** them. If yo
|
||||
|
||||
Each item below breaks an existing install if you get it wrong.
|
||||
|
||||
- **Keep the `id`.** Consent is stored per `(realpath(projectRoot), capability id)`. Changing the `id` re-prompts consent in every project that has the capability installed, and orphans the old `gsd capability update <id>` path.
|
||||
- **Keep the `id`.** Consent is stored per `(realpath(projectRoot), capability id)`. Changing the `id` re-prompts consent in every project that has the capability installed, and orphans the old `msd capability update <id>` path.
|
||||
- **Re-state `integrity`.** The `sha512-<base64>` hash is computed over the published artifact. A rebuild under new ownership produces a new hash, and anyone who pinned with `--integrity` will fail verification until you publish and communicate the new value.
|
||||
- **Re-state `provenance`.** `sourceRepo` and `commit` must point at the new repository and the exact commit you published.
|
||||
- **Re-consent on executable-surface change.** If the set of hooks, MCP servers, or command modules changes, installers are re-prompted. Keep it identical through the takeover so the handoff itself is not a consent event.
|
||||
- **Do not narrow `engines.gsd`.** If you raise the floor, add the corresponding `compatVersions` row so older GSD versions can still resolve a working version.
|
||||
- **Do not narrow `engines.msd`.** If you raise the floor, add the corresponding `compatVersions` row so older MSD versions can still resolve a working version.
|
||||
- **Make `install` and `uninstall` copy-pasteable against the new repo.** They are exact commands, not descriptions, for capability and reviewer entries.
|
||||
- **Do not drop `protocolVersion`** on an EoS entry. It must stay an integer of 1 or greater and must still name the ADR-1239 protocol the integration actually implements.
|
||||
|
||||
@@ -99,7 +99,7 @@ Absorption is a feature-scale change, so the contribution rules apply before any
|
||||
3. Regenerate the capability registry with `scripts/gen-capability-registry.cjs --write`.
|
||||
4. Update `CONTEXT.md` domain terms, `docs/README.md`, and the surface docs the capability touches.
|
||||
5. **Do not delete the registry entry.** Absorption is not one of the four removal grounds. Note the supersession in `description` through a separate `Changed` PR.
|
||||
6. **Publish a migration note telling existing users to run `gsd capability remove <old-id>` first.** Config keys are exclusive to one capability and skill/agent stems must be unique; a first-party capability that collides with an installed overlay wins silently, leaving the user running code they did not think they were running.
|
||||
6. **Publish a migration note telling existing users to run `msd capability remove <old-id>` first.** Config keys are exclusive to one capability and skill/agent stems must be unique; a first-party capability that collides with an installed overlay wins silently, leaving the user running code they did not think they were running.
|
||||
|
||||
### T4 — Retirement
|
||||
|
||||
@@ -112,7 +112,7 @@ Staleness, low quality, an unmaintained-but-working project, or a design you wou
|
||||
## Step 6 — Post-takeover obligations
|
||||
|
||||
- **Cut a GitHub Release under the new repo.** There is no re-registration on new versions: the shields badge and the `releases/latest` permalink render live from `repo`, so releases are the update channel forever. A takeover with no release leaves consumers with a badge that never moves.
|
||||
- **Bump `version`** in the manifest, and add a `compatVersions` row if you raised the `engines.gsd` floor.
|
||||
- **Bump `version`** in the manifest, and add a `compatVersions` row if you raised the `engines.msd` floor.
|
||||
- **Publish the new `integrity` hash and `provenance` object.**
|
||||
- **Keep the Discussion thread.** It is the continuity record across maintainers, and it carries the community's upvotes and experience reports.
|
||||
|
||||
@@ -122,7 +122,7 @@ Staleness, low quality, an unmaintained-but-working project, or a design you wou
|
||||
- Repoint `repo` at a fork while the original is alive and maintained. That is an entry hijack, not a takeover.
|
||||
- Reclaim an `id` that is still listed.
|
||||
- Remove a working entry in order to make room for a replacement.
|
||||
- Rename into `gsd-`, `gsd-core-`, or `anthropic-` outside of T3.
|
||||
- Rename into `msd-`, `msd-core-`, or `anthropic-` outside of T3.
|
||||
- Bundle the change with any other registry entry, code change, or unrelated docs edit.
|
||||
|
||||
## Known gaps in the enforcement path
|
||||
@@ -134,8 +134,8 @@ Two parts of this process rest on human judgment rather than an automated gate.
|
||||
|
||||
## Related
|
||||
|
||||
- [Develop a Capability for GSD 1.5+](develop-a-capability.md)
|
||||
- [Develop a Capability for MSD 1.5+](develop-a-capability.md)
|
||||
- [How to publish a capability so others can install it](publish-a-capability.md)
|
||||
- [Version a capability](version-a-capability.md)
|
||||
- [Remove a capability](remove-a-capability.md)
|
||||
- [GSD Registries: schema and submission process](../registries/README.md)
|
||||
- [MSD Registries: schema and submission process](../registries/README.md)
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
# Turn a capability off (and keep it off)
|
||||
|
||||
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.
|
||||
This guide shows you how to switch a MSD 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.6.0+](develop-a-capability.md).
|
||||
MSD 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 MSD 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>`.
|
||||
> - A **first-party** capability — one that ships with MSD (for example `ui`, `code-review`, `research`) — is turned off with `msd capability disable <id>` or gated with `msd capability set <id> --gate …`. These verbs validate `<id>` against the built-in capability registry.
|
||||
> - An **installed third-party overlay** — one you added with `msd 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 `msd 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.
|
||||
The reliable, fully general way to change first-party capability state is the `capability` command. The `/msd-surface` and `/msd-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.
|
||||
|
||||
---
|
||||
|
||||
@@ -20,23 +20,23 @@ The reliable, fully general way to change first-party capability state is the `c
|
||||
Disable the capability by id:
|
||||
|
||||
```bash
|
||||
gsd capability disable <id>
|
||||
msd capability disable <id>
|
||||
```
|
||||
|
||||
For example, to stop the UI capability:
|
||||
|
||||
```bash
|
||||
gsd capability disable ui
|
||||
msd capability disable ui
|
||||
```
|
||||
|
||||
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`).
|
||||
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. `msd capability disable <id>` is exactly `msd capability set <id> --off`; re-enable with `msd 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
|
||||
gsd capability state --raw
|
||||
msd capability state --raw
|
||||
```
|
||||
|
||||
The capability now reports `enabled: false` and every hook `active: false`.
|
||||
@@ -48,10 +48,10 @@ The capability now reports `enabled: false` and every hook `active: false`.
|
||||
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
|
||||
gsd capability set code-review --gate workflow.code_review=false
|
||||
msd capability set code-review --gate workflow.code_review=false
|
||||
```
|
||||
|
||||
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.
|
||||
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/msd-capability-command.md#set) for the full contract.
|
||||
|
||||
---
|
||||
|
||||
@@ -60,43 +60,43 @@ The capability stays enabled; only that hook stops firing. `--gate` is repeatabl
|
||||
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
|
||||
gsd capability set research --gate workflow.research=false
|
||||
msd capability set research --gate workflow.research=false
|
||||
```
|
||||
|
||||
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.
|
||||
If you gate every hook of a capability off while it is still surfaced, `msd 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:
|
||||
A capability you added with `msd 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
|
||||
msd 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
|
||||
msd capability remove my-overlay --scope global # default scope is global
|
||||
msd 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`.)
|
||||
`--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, `msd --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.
|
||||
> The `/msd-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.
|
||||
See [Remove a capability](remove-a-capability.md) for the full removal flow and [`msd capability remove`](../reference/msd-capability-command.md#remove) for every flag and output field.
|
||||
|
||||
---
|
||||
|
||||
## The interactive paths (`/gsd-surface` and `/gsd-settings`)
|
||||
## The interactive paths (`/msd-surface` and `/msd-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.
|
||||
- **`/msd-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 `/msd-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 (`msd capability disable <id>` for first-party, `msd capability remove <id>` for an installed overlay). Reverse a cluster with `/msd-surface enable <cluster>`.
|
||||
- **`/msd-settings`** is the interactive prompt for MSD'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 `msd 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.
|
||||
|
||||
@@ -108,25 +108,25 @@ To mutate capability state directly (in scripts or CI), call the command non-int
|
||||
|
||||
```bash
|
||||
# Disable a whole first-party capability
|
||||
gsd capability disable <id> # equivalently: gsd capability set <id> --off
|
||||
msd capability disable <id> # equivalently: msd capability set <id> --off
|
||||
|
||||
# Re-enable
|
||||
gsd capability enable <id> # equivalently: gsd capability set <id> --on
|
||||
msd capability enable <id> # equivalently: msd capability set <id> --on
|
||||
|
||||
# Toggle one hook gate
|
||||
gsd capability set <id> --gate <key>=<true|false>
|
||||
msd 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>
|
||||
msd capability remove <id> --scope <global|project>
|
||||
```
|
||||
|
||||
See the [`gsd capability` command reference](../reference/gsd-capability-command.md) for every subcommand, flag, and output shape.
|
||||
See the [`msd capability` command reference](../reference/msd-capability-command.md) for every subcommand, flag, and output shape.
|
||||
|
||||
---
|
||||
|
||||
## Related
|
||||
|
||||
- [`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)
|
||||
- [`msd capability` command reference](../reference/msd-capability-command.md) — `disable`, `enable`, `set`, and the rest of the family
|
||||
- [Develop a Capability for MSD 1.6.0+](develop-a-capability.md)
|
||||
- [Install a minimal MSD and add skills later](install-minimal-and-add-skills.md)
|
||||
- [docs index](../README.md)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# How to update GSD Core
|
||||
# How to update MSD Core
|
||||
|
||||
Update an existing GSD Core install to the latest release, preview the changelog before committing, and recover any local customisations that the update would overwrite.
|
||||
Update an existing MSD Core install to the latest release, preview the changelog before committing, and recover any local customisations that the update would overwrite.
|
||||
|
||||
**What you need:** The same runtime GSD is installed for. The update command re-runs the installer under the hood, so it needs Node.js and npx available (same requirement as the original install).
|
||||
**What you need:** The same runtime MSD is installed for. The update command re-runs the installer under the hood, so it needs Node.js and npx available (same requirement as the original install).
|
||||
|
||||
---
|
||||
|
||||
@@ -11,24 +11,24 @@ Update an existing GSD Core install to the latest release, preview the changelog
|
||||
From inside your AI runtime, run:
|
||||
|
||||
```bash
|
||||
/gsd-update
|
||||
/msd-update
|
||||
```
|
||||
|
||||
GSD will:
|
||||
MSD will:
|
||||
|
||||
1. Detect the installed version and install scope (global or local).
|
||||
2. Check npm for the latest release of `@opengsd/gsd-core`.
|
||||
2. Check npm for the latest release of `@golem15/msd-core`.
|
||||
3. Fetch the changelog and show you what changed between your installed version and the latest.
|
||||
4. Ask for confirmation before touching anything.
|
||||
5. Back up any user-added files found inside GSD-managed directories to `gsd-user-files-backup/`.
|
||||
6. Run the installer (`npx @opengsd/gsd-core@latest --<runtime> --<scope>`).
|
||||
5. Back up any user-added files found inside MSD-managed directories to `msd-user-files-backup/`.
|
||||
6. Run the installer (`npx @golem15/msd-core@latest --<runtime> --<scope>`).
|
||||
7. Clear the update-check cache so the statusline indicator resets.
|
||||
8. Offer to restore the user-added files it backed up in step 5.
|
||||
9. Report whether locally modified GSD files were backed up to `gsd-local-patches/`.
|
||||
9. Report whether locally modified MSD files were backed up to `msd-local-patches/`.
|
||||
|
||||
Before reporting completion, the installer checks each GSD-managed script and interpreter path written into runtime configuration, resolving the interpreter against the current install-time `PATH`. This only proves the path resolves now — a hook fired later under a different, more restricted `PATH` (e.g. a GUI launcher) can still fail even after this check passes.
|
||||
Before reporting completion, the installer checks each MSD-managed script and interpreter path written into runtime configuration, resolving the interpreter against the current install-time `PATH`. This only proves the path resolves now — a hook fired later under a different, more restricted `PATH` (e.g. a GUI launcher) can still fail even after this check passes.
|
||||
|
||||
If a script is missing, unreadable, has the wrong file type, lacks a required execute permission, or its interpreter cannot be resolved, the update fails and reports every invalid path, each tagged with what happens to that runtime's config next. For Claude Code and other settings.json-based runtimes, this check runs before the update writes settings.json, so nothing new is persisted (an earlier settings.json/settings.local.json migration, if one applied, is the one exception and stays applied) — reported as "not persisted". For Codex, this reverts config.toml/hooks.json along with the rest of that runtime's pre-install snapshot (skills/, agents/, gsd-core/VERSION) — reported as "reverted". For Cursor, Windsurf, Kimi, and Cline, the runtime's config file is already written earlier in the update, ahead of this check, so a failure is reported but that file is left in place, broken — reported as "NOT reverted". Fix the reported path problem and rerun `/gsd-update` — do not restart into the incomplete update.
|
||||
If a script is missing, unreadable, has the wrong file type, lacks a required execute permission, or its interpreter cannot be resolved, the update fails and reports every invalid path, each tagged with what happens to that runtime's config next. For Claude Code and other settings.json-based runtimes, this check runs before the update writes settings.json, so nothing new is persisted (an earlier settings.json/settings.local.json migration, if one applied, is the one exception and stays applied) — reported as "not persisted". For Codex, this reverts config.toml/hooks.json along with the rest of that runtime's pre-install snapshot (skills/, agents/, msd-core/VERSION) — reported as "reverted". For Cursor, Windsurf, Kimi, and Cline, the runtime's config file is already written earlier in the update, ahead of this check, so a failure is reported but that file is left in place, broken — reported as "NOT reverted". Fix the reported path problem and rerun `/msd-update` — do not restart into the incomplete update.
|
||||
|
||||
Restart your runtime after a successful update to pick up new commands and agents.
|
||||
|
||||
@@ -36,7 +36,7 @@ Restart your runtime after a successful update to pick up new commands and agent
|
||||
|
||||
## If the update target cannot be resolved
|
||||
|
||||
`UPDATE_TARGET_UNRESOLVED` means GSD could not identify an installed runtime to update. No update, cache clear, or installer run occurred. Rerun `/gsd-update` from a valid installed runtime, or use the [standard installer](install-on-your-runtime.md#standard-install) for a fresh install.
|
||||
`UPDATE_TARGET_UNRESOLVED` means MSD could not identify an installed runtime to update. No update, cache clear, or installer run occurred. Rerun `/msd-update` from a valid installed runtime, or use the [standard installer](install-on-your-runtime.md#standard-install) for a fresh install.
|
||||
|
||||
---
|
||||
|
||||
@@ -44,29 +44,29 @@ Restart your runtime after a successful update to pick up new commands and agent
|
||||
|
||||
| Flag | What it does |
|
||||
|------|--------------|
|
||||
| `--sync` | After updating, sync skills from the GSD registry |
|
||||
| `--reapply` | After updating, merge locally modified GSD files back in from `gsd-local-patches/` |
|
||||
| `--sync` | After updating, sync skills from the MSD registry |
|
||||
| `--reapply` | After updating, merge locally modified MSD files back in from `msd-local-patches/` |
|
||||
| `--next` / `--rc` | Target the `@next` RC dist-tag instead of `@latest` (installs or refreshes a release candidate; see ADR #660) |
|
||||
|
||||
```bash
|
||||
/gsd-update --sync # Update and sync skills
|
||||
/gsd-update --reapply # Update and reapply local patches
|
||||
/gsd-update --next # Install from the @next RC dist-tag
|
||||
/msd-update --sync # Update and sync skills
|
||||
/msd-update --reapply # Update and reapply local patches
|
||||
/msd-update --next # Install from the @next RC dist-tag
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Install or refresh a release candidate
|
||||
|
||||
GSD publishes release candidates on the `@next` npm dist-tag (established by ADR #660). To install or refresh from that channel:
|
||||
MSD publishes release candidates on the `@next` npm dist-tag (established by ADR #660). To install or refresh from that channel:
|
||||
|
||||
```bash
|
||||
/gsd-update --next
|
||||
/msd-update --next
|
||||
# or equivalently:
|
||||
/gsd-update --rc
|
||||
/msd-update --rc
|
||||
```
|
||||
|
||||
The full update flow applies — scope/runtime detection, changelog preview, custom-file backup, and cache clearing all run normally. The only difference is that `check-latest-version.cjs` resolves the `@next` tag and npx installs from `@opengsd/gsd-core@next`.
|
||||
The full update flow applies — scope/runtime detection, changelog preview, custom-file backup, and cache clearing all run normally. The only difference is that `check-latest-version.cjs` resolves the `@next` tag and npx installs from `@golem15/msd-core@next`.
|
||||
|
||||
Only `latest` and `next` are supported channels; no arbitrary dist-tag can be passed (the script enforces an allowlist and exits with code 2 on an invalid tag).
|
||||
|
||||
@@ -76,10 +76,10 @@ Omitting `--next`/`--rc` keeps targeting `@latest` (stable channel, no change in
|
||||
|
||||
## Reviewing the changelog before updating
|
||||
|
||||
`/gsd-update` always shows the changelog diff between your installed version and the latest *before* it asks for confirmation. You do not need to visit GitHub separately. The output looks like:
|
||||
`/msd-update` always shows the changelog diff between your installed version and the latest *before* it asks for confirmation. You do not need to visit GitHub separately. The output looks like:
|
||||
|
||||
```text
|
||||
## GSD Update Available
|
||||
## MSD Update Available
|
||||
|
||||
Installed: 1.39.0
|
||||
Latest: 1.41.0
|
||||
@@ -101,9 +101,9 @@ If the changelog cannot be fetched (no network access, npm outage), the update s
|
||||
|
||||
## Recovering local customisations
|
||||
|
||||
### Files you added inside GSD-managed directories
|
||||
### Files you added inside MSD-managed directories
|
||||
|
||||
If you placed custom files inside directories that GSD owns (for example, custom agents prefixed with `gsd-` or extra files in `commands/gsd/`), the installer detects them and copies them to `gsd-user-files-backup/` before wiping those directories.
|
||||
If you placed custom files inside directories that MSD owns (for example, custom agents prefixed with `msd-` or extra files in `commands/msd/`), the installer detects them and copies them to `msd-user-files-backup/` before wiping those directories.
|
||||
|
||||
After the new version is installed, the update offers to put them back. You get a list of what was backed up, then a choice:
|
||||
|
||||
@@ -112,11 +112,11 @@ After the new version is installed, the update offers to put them back. You get
|
||||
|
||||
Either way the backup is **never deleted**, so declining is not destructive and you can restore later.
|
||||
|
||||
Before copying anything back, the restore runs a compatibility pass against the version that was just installed and attaches a warning to any file that looks like it may no longer work — one that references a workflow or `/gsd:` command the new release retired, or a skill missing its `name` / `description` frontmatter. Warnings are advisory: the file is still restored, with the warning shown next to it, so you can decide whether to fix it.
|
||||
Before copying anything back, the restore runs a compatibility pass against the version that was just installed and attaches a warning to any file that looks like it may no longer work — one that references a workflow or `/msd:` command the new release retired, or a skill missing its `name` / `description` frontmatter. Warnings are advisory: the file is still restored, with the warning shown next to it, so you can decide whether to fix it.
|
||||
|
||||
Two cases are skipped rather than restored, because restoring would destroy something:
|
||||
|
||||
- The new release now ships a file at that exact path (your custom file would overwrite GSD's).
|
||||
- The new release now ships a file at that exact path (your custom file would overwrite MSD's).
|
||||
- A different file is already sitting at that path (restoring would overwrite your current version).
|
||||
|
||||
Both stay in the backup and are reported with the reason.
|
||||
@@ -124,48 +124,48 @@ Both stay in the backup and are reported with the reason.
|
||||
To restore later — or after an update where you declined — run the same operation directly:
|
||||
|
||||
```bash
|
||||
node <config-dir>/gsd-core/bin/gsd-tools.cjs restore-custom-files --config-dir <config-dir> --apply
|
||||
node <config-dir>/msd-core/bin/msd-tools.cjs restore-custom-files --config-dir <config-dir> --apply
|
||||
```
|
||||
|
||||
Drop `--apply` to preview what would be restored without writing anything.
|
||||
|
||||
Files you placed outside GSD-managed directories — custom agents not prefixed with `gsd-`, custom commands outside `commands/gsd/`, your `CLAUDE.md` files, and custom hooks — are never touched by the installer.
|
||||
Files you placed outside MSD-managed directories — custom agents not prefixed with `msd-`, custom commands outside `commands/msd/`, your `CLAUDE.md` files, and custom hooks — are never touched by the installer.
|
||||
|
||||
### GSD files you modified directly
|
||||
### MSD files you modified directly
|
||||
|
||||
If you edited a file that GSD installed (for example, tweaking an agent's system prompt), the installer detects the modification via a hash comparison against its manifest, backs the file up to `gsd-local-patches/`, and then replaces it with the new version. After the update:
|
||||
If you edited a file that MSD installed (for example, tweaking an agent's system prompt), the installer detects the modification via a hash comparison against its manifest, backs the file up to `msd-local-patches/`, and then replaces it with the new version. After the update:
|
||||
|
||||
```bash
|
||||
/gsd-update --reapply
|
||||
/msd-update --reapply
|
||||
```
|
||||
|
||||
This merges your modifications from `gsd-local-patches/` back into the newly installed files.
|
||||
This merges your modifications from `msd-local-patches/` back into the newly installed files.
|
||||
|
||||
If you skipped `--reapply` after a previous update and want to apply patches now:
|
||||
|
||||
```bash
|
||||
/gsd-update --reapply
|
||||
/msd-update --reapply
|
||||
```
|
||||
|
||||
It is safe to run `--reapply` on its own without triggering a new download — if you are already on the latest version, GSD skips the install step and goes straight to reapplying patches.
|
||||
It is safe to run `--reapply` on its own without triggering a new download — if you are already on the latest version, MSD skips the install step and goes straight to reapplying patches.
|
||||
|
||||
---
|
||||
|
||||
## When npm is unavailable
|
||||
|
||||
If `npx @opengsd/gsd-core@latest` fails due to an npm outage, network restrictions, or because you are working from the source repository, use the manual update procedure in [docs/manual-update.md](../manual-update.md). That document covers pulling the latest commit, building the hooks dist, and running `node bin/install.js` directly.
|
||||
If `npx @golem15/msd-core@latest` fails due to an npm outage, network restrictions, or because you are working from the source repository, use the manual update procedure in [docs/manual-update.md](../manual-update.md). That document covers pulling the latest commit, building the hooks dist, and running `node bin/install.js` directly.
|
||||
|
||||
---
|
||||
|
||||
## If you are already on the latest version
|
||||
|
||||
`/gsd-update` exits early with a confirmation message — no download, no install, no restart needed.
|
||||
`/msd-update` exits early with a confirmation message — no download, no install, no restart needed.
|
||||
|
||||
---
|
||||
|
||||
## Installer migrations
|
||||
|
||||
Each GSD release may include installer migrations that rename, move, or retire managed files. The migration layer runs automatically before the new package payload is written. Migrations that would affect files you have modified prompt for confirmation rather than acting silently. For the full design and runtime-configuration contract registry, see [docs/installer-migrations.md](../installer-migrations.md).
|
||||
Each MSD release may include installer migrations that rename, move, or retire managed files. The migration layer runs automatically before the new package payload is written. Migrations that would affect files you have modified prompt for confirmation rather than acting silently. For the full design and runtime-configuration contract registry, see [docs/installer-migrations.md](../installer-migrations.md).
|
||||
|
||||
---
|
||||
|
||||
@@ -179,10 +179,10 @@ Each GSD release may include installer migrations that rename, move, or retire m
|
||||
|
||||
## CLI version-skew warning
|
||||
|
||||
GSD warns (to stderr, non-blocking) when the resolved `gsd-tools.cjs` is **outside your project root** while a project-local install exists — a sign that a global install (often a retired `@gsd-build/sdk` canary) is shadowing your project-local GSD. The warning names the resolved path and, for the `@gsd-build/sdk` case, gives the removal command:
|
||||
MSD warns (to stderr, non-blocking) when the resolved `msd-tools.cjs` is **outside your project root** while a project-local install exists — a sign that a global install (often a retired `@gsd-build/sdk` canary) is shadowing your project-local MSD. The warning names the resolved path and, for the `@gsd-build/sdk` case, gives the removal command:
|
||||
|
||||
```bash
|
||||
npm uninstall -g @gsd-build/sdk
|
||||
```
|
||||
|
||||
If you see this warning, remove the stale global package so `gsd_run` resolves the project-local install.
|
||||
If you see this warning, remove the stale global package so `msd_run` resolves the project-local install.
|
||||
@@ -1,6 +1,6 @@
|
||||
# How to vendor a dependency
|
||||
|
||||
**Goal:** Add a third-party package that `gsd-core/bin/**` needs at runtime, in the vendored form the installer's copy step actually supports, without breaking the lint gate that keeps the vendored copy from silently drifting.
|
||||
**Goal:** Add a third-party package that `msd-core/bin/**` needs at runtime, in the vendored form the installer's copy step actually supports, without breaking the lint gate that keeps the vendored copy from silently drifting.
|
||||
|
||||
**Prerequisites:** The package is a devDependency already (`npm install --save-dev <pkg>`), and its build output ships (or can be built into) a self-contained CommonJS/UMD bundle with zero external `require()` calls.
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
## Why vendoring exists at all
|
||||
|
||||
`gsd-core/bin/**` is copied by the installer into trees that have **no `node_modules`** (for example `~/.claude/gsd-core/`). Any external, non-relative, non-builtin `require()`/`import` under `gsd-core/bin/**` breaks every command that touches it for every installed user, because the module simply cannot be resolved on disk there — there is no `node_modules` to resolve it from. `eslint-rules/no-external-require-in-bin.cjs` (`local/no-external-require-in-bin`) enforces this at lint time: it fails on any bare-specifier `require`/`import` under `gsd-core/bin/**`, whether or not the target actually exists in this repo's own `node_modules`. Vendoring — copying the package's compiled build artifact in-tree under `gsd-core/bin/lib/vendor/` and importing it with a relative path — is the only way around that constraint; there is no exemption mechanism, and there should not be one.
|
||||
`msd-core/bin/**` is copied by the installer into trees that have **no `node_modules`** (for example `~/.claude/msd-core/`). Any external, non-relative, non-builtin `require()`/`import` under `msd-core/bin/**` breaks every command that touches it for every installed user, because the module simply cannot be resolved on disk there — there is no `node_modules` to resolve it from. `eslint-rules/no-external-require-in-bin.cjs` (`local/no-external-require-in-bin`) enforces this at lint time: it fails on any bare-specifier `require`/`import` under `msd-core/bin/**`, whether or not the target actually exists in this repo's own `node_modules`. Vendoring — copying the package's compiled build artifact in-tree under `msd-core/bin/lib/vendor/` and importing it with a relative path — is the only way around that constraint; there is no exemption mechanism, and there should not be one.
|
||||
|
||||
## The package MUST stay a devDependency
|
||||
|
||||
@@ -28,9 +28,9 @@ For js-yaml (ADR-3473 §8.1, #3881) the correct artifact is `dist/js-yaml.js`
|
||||
{
|
||||
name: 'your-package', // matches package.json devDependencies key
|
||||
upstreamCjs: 'node_modules/your-package/dist/bundle.js', // the self-contained artifact you picked above
|
||||
vendoredCjs: 'gsd-core/bin/lib/vendor/your-package.cjs',
|
||||
vendoredCjs: 'msd-core/bin/lib/vendor/your-package.cjs',
|
||||
upstreamDts: null, // or a path, if the package ships its own .d.ts/.d.cts
|
||||
vendoredDts: null, // or the gsd-core/bin/lib/vendor/ copy of that .d.ts
|
||||
vendoredDts: null, // or the msd-core/bin/lib/vendor/ copy of that .d.ts
|
||||
srcTwin: 'src/vendor/your-package.d.cts',
|
||||
twinKind: 'hand-authored', // or 'upstream-verbatim' — see below
|
||||
},
|
||||
@@ -39,31 +39,31 @@ For js-yaml (ADR-3473 §8.1, #3881) the correct artifact is `dist/js-yaml.js`
|
||||
Then copy the artifact in:
|
||||
|
||||
```
|
||||
cp node_modules/your-package/dist/bundle.js gsd-core/bin/lib/vendor/your-package.cjs
|
||||
cp node_modules/your-package/dist/bundle.js msd-core/bin/lib/vendor/your-package.cjs
|
||||
```
|
||||
|
||||
## The two kinds of type twin
|
||||
|
||||
Every vendored package needs a `.d.cts` under `src/vendor/` so TypeScript can resolve types for the relative `./vendor/your-package.cjs` import from `src/**` — module resolution for a `.cts` source is relative to `src/`, not the compiled output directory, so `gsd-core/bin/lib/vendor/your-package.d.cts` alone is not enough. There are two kinds, distinguished by `twinKind`:
|
||||
Every vendored package needs a `.d.cts` under `src/vendor/` so TypeScript can resolve types for the relative `./vendor/your-package.cjs` import from `src/**` — module resolution for a `.cts` source is relative to `src/`, not the compiled output directory, so `msd-core/bin/lib/vendor/your-package.d.cts` alone is not enough. There are two kinds, distinguished by `twinKind`:
|
||||
|
||||
- **`upstream-verbatim`** — the package ships its own `.d.ts`/`.d.cts` upstream. Copy it verbatim to both `gsd-core/bin/lib/vendor/your-package.d.cts` and `src/vendor/your-package.d.cts`. `lint-vendored-deps.cjs` byte-compares both copies against the upstream file and against each other, so any manual edit is caught as drift.
|
||||
- **`upstream-verbatim`** — the package ships its own `.d.ts`/`.d.cts` upstream. Copy it verbatim to both `msd-core/bin/lib/vendor/your-package.d.cts` and `src/vendor/your-package.d.cts`. `lint-vendored-deps.cjs` byte-compares both copies against the upstream file and against each other, so any manual edit is caught as drift.
|
||||
- **`hand-authored`** — the package ships no type declarations upstream (js-yaml's case: no bundled `.d.ts`, and `@types/js-yaml` is not installed). Write `src/vendor/your-package.d.cts` by hand, declaring only the symbols this repo actually imports — narrower is safer, since anything not declared is simply unreachable from typed code. This twin is **excluded** from the byte-compare (there is no upstream file to compare it against) and is instead pinned by a test asserting the declared surface matches what the module actually uses.
|
||||
|
||||
Set `upstreamDts`/`vendoredDts` to `null` for a hand-authored twin — `checkRow` in `scripts/lint-vendored-deps.cjs` skips the byte-compare checks entirely when either is `null`.
|
||||
|
||||
## Document it in `gsd-core/bin/lib/vendor/README.md`
|
||||
## Document it in `msd-core/bin/lib/vendor/README.md`
|
||||
|
||||
Add an entry alongside the existing ones: which upstream artifact you copied, why it (and not the package's main entry point) is the vendorable one, which symbols it exposes, and the refresh command. This is the first place a future contributor looks when `lint-vendored-deps.cjs` reports drift.
|
||||
|
||||
## The `docs/INVENTORY.md` row
|
||||
|
||||
`gsd-core/bin/lib/vendor/your-package.cjs` is a shipped file under `gsd-core/bin/**`, so it needs a row in `docs/INVENTORY.md` per the inventory-drift rule for anything added under a manifest-scanned directory. Describe it as a vendored third-party artifact (not a GSD module), name the ADR/issue that introduced it, and cross-reference `gsd-core/bin/lib/vendor/README.md`.
|
||||
`msd-core/bin/lib/vendor/your-package.cjs` is a shipped file under `msd-core/bin/**`, so it needs a row in `docs/INVENTORY.md` per the inventory-drift rule for anything added under a manifest-scanned directory. Describe it as a vendored third-party artifact (not a MSD module), name the ADR/issue that introduced it, and cross-reference `msd-core/bin/lib/vendor/README.md`.
|
||||
|
||||
## The ordering trap: build before you regenerate the manifest
|
||||
|
||||
`node scripts/gen-inventory-manifest.cjs --write` derives its manifest from the **compiled** `gsd-core/bin/**` tree, not from `src/**`. If you regenerate the inventory manifest before running `npm run build:lib`, the generator either misses your new vendored file (if `gsd-core/bin/lib/vendor/your-package.cjs` was not yet copied in) or captures a stale prior build's contents. The required order is:
|
||||
`node scripts/gen-inventory-manifest.cjs --write` derives its manifest from the **compiled** `msd-core/bin/**` tree, not from `src/**`. If you regenerate the inventory manifest before running `npm run build:lib`, the generator either misses your new vendored file (if `msd-core/bin/lib/vendor/your-package.cjs` was not yet copied in) or captures a stale prior build's contents. The required order is:
|
||||
|
||||
1. `cp node_modules/your-package/dist/bundle.js gsd-core/bin/lib/vendor/your-package.cjs` (and the type twins, per above)
|
||||
1. `cp node_modules/your-package/dist/bundle.js msd-core/bin/lib/vendor/your-package.cjs` (and the type twins, per above)
|
||||
2. `npm run build:lib`
|
||||
3. `node scripts/gen-inventory-manifest.cjs --write`
|
||||
|
||||
@@ -73,13 +73,13 @@ Running step 3 before step 1/2 produces a manifest that silently omits or misdes
|
||||
|
||||
- `node scripts/lint-vendored-deps.cjs` — exits 0 once the vendored copy, its type twins (if `upstream-verbatim`), and the `package.json` devDependency version pin all agree with `node_modules`.
|
||||
- `npx tsc --noEmit -p tsconfig.json` — confirms the `src/vendor/*.d.cts` twin actually resolves for every `.cts` importer.
|
||||
- `npm run lint` — confirms `local/no-external-require-in-bin` still finds zero external requires under `gsd-core/bin/**`.
|
||||
- `npm run lint` — confirms `local/no-external-require-in-bin` still finds zero external requires under `msd-core/bin/**`.
|
||||
|
||||
---
|
||||
|
||||
## Related
|
||||
|
||||
- `gsd-core/bin/lib/vendor/README.md` — the vendored-files README this how-to keeps in step with
|
||||
- `msd-core/bin/lib/vendor/README.md` — the vendored-files README this how-to keeps in step with
|
||||
- `scripts/lint-vendored-deps.cjs` — the table-driven freshness gate (`VENDORED` array)
|
||||
- `eslint-rules/no-external-require-in-bin.cjs` — the rule that makes vendoring necessary in the first place
|
||||
- ADR-3473 §8.1 (#3881) — the js-yaml vendoring this how-to was extracted from
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
**Goal:** Turn a compatibility claim that came back `[ASSUMED]` — "this library does not support that runtime version" — into either a `[VERIFIED]` claim backed by a real probe, a `[CITED]` claim backed by an affirmative sentence in the vendor's own docs, or a decision you deliberately take without locking. The point is that an *absence* of metadata never becomes a constraint by default, so the version bound you end up pinning is the one the world actually imposes rather than the one a missing field seemed to imply.
|
||||
|
||||
**Prerequisites:** A phase whose `/gsd-plan-phase` research pass has produced a RESEARCH.md. The absent-evidence provenance rule runs inside `gsd-phase-researcher` automatically — there is no flag and nothing to enable. You reach this guide because a claim you expected to be settled is tagged `[ASSUMED]` and `/gsd-discuss-phase` is asking you to confirm it before it can lock a decision.
|
||||
**Prerequisites:** A phase whose `/msd-plan-phase` research pass has produced a RESEARCH.md. The absent-evidence provenance rule runs inside `msd-phase-researcher` automatically — there is no flag and nothing to enable. You reach this guide because a claim you expected to be settled is tagged `[ASSUMED]` and `/msd-discuss-phase` is asking you to confirm it before it can lock a decision.
|
||||
|
||||
For the rule itself and the other two provenance rules beside it, see [`/gsd-plan-phase` in COMMANDS.md](../COMMANDS.md#gsd-plan-phase). This guide covers only how to *act* on the claim.
|
||||
For the rule itself and the other two provenance rules beside it, see [`/msd-plan-phase` in COMMANDS.md](../COMMANDS.md#msd-plan-phase). This guide covers only how to *act* on the claim.
|
||||
|
||||
---
|
||||
|
||||
@@ -69,7 +69,7 @@ Record the result:
|
||||
|
||||
Sometimes the probe is genuinely unavailable: no interpreter for that version, no reachable target host, no network in this environment. That is a normal outcome and the rule is built for it.
|
||||
|
||||
Leave the claim `[ASSUMED]` and tell `/gsd-discuss-phase` to proceed without locking. The claim still reaches the planner and can still shape a plan — it simply cannot become a locked `CONTEXT.md` decision that downstream phases treat as settled. **A probe you cannot run costs you a confirmation checkpoint, not a blocked plan.**
|
||||
Leave the claim `[ASSUMED]` and tell `/msd-discuss-phase` to proceed without locking. The claim still reaches the planner and can still shape a plan — it simply cannot become a locked `CONTEXT.md` decision that downstream phases treat as settled. **A probe you cannot run costs you a confirmation checkpoint, not a blocked plan.**
|
||||
|
||||
What you should *not* do is confirm the claim at the checkpoint to make the prompt go away. Confirming is you asserting the premise on your own authority; it will be treated as settled by every phase after this one, and the checkpoint is the last place anybody will look at it.
|
||||
|
||||
@@ -93,6 +93,6 @@ The failure this rule exists to prevent, from the report that prompted it ([#295
|
||||
|
||||
## Related
|
||||
|
||||
- [`/gsd-plan-phase`](../COMMANDS.md#gsd-plan-phase) — the two sibling provenance rules: package-name legitimacy, and in-repo value citation
|
||||
- [`/msd-plan-phase`](../COMMANDS.md#msd-plan-phase) — the two sibling provenance rules: package-name legitimacy, and in-repo value citation
|
||||
- [Discuss a phase](discuss-a-phase.md) — where an `[ASSUMED]` claim reaches its confirmation checkpoint
|
||||
- [gsd-phase-researcher](../AGENTS.md#gsd-phase-researcher) — the agent that applies the rule
|
||||
- [msd-phase-researcher](../AGENTS.md#msd-phase-researcher) — the agent that applies the rule
|
||||
|
||||
@@ -9,36 +9,36 @@
|
||||
## Run user acceptance testing
|
||||
|
||||
```bash
|
||||
/gsd-verify-work 1
|
||||
/msd-verify-work 1
|
||||
```
|
||||
|
||||
GSD reads the phase's `SUMMARY.md` files, extracts user-observable deliverables, and walks you through them one at a time. For each checkpoint it presents what *should* happen and asks whether reality matches.
|
||||
MSD reads the phase's `SUMMARY.md` files, extracts user-observable deliverables, and walks you through them one at a time. For each checkpoint it presents what *should* happen and asks whether reality matches.
|
||||
|
||||
- `yes` / `y` / empty → pass, move to next test
|
||||
- Anything else → recorded as an issue, severity inferred from your description
|
||||
|
||||
You never need to categorise severity — GSD infers it from your words ("crashes" → blocker, "doesn't work" → major, "looks off" → cosmetic).
|
||||
You never need to categorise severity — MSD infers it from your words ("crashes" → blocker, "doesn't work" → major, "looks off" → cosmetic).
|
||||
|
||||
Progress is written to `.planning/phases/01-<name>/01-UAT.md` and survives a `/clear`. If a session is interrupted, re-run `/gsd-verify-work 1` and GSD offers to resume from the last checkpoint.
|
||||
Progress is written to `.planning/phases/01-<name>/01-UAT.md` and survives a `/clear`. If a session is interrupted, re-run `/msd-verify-work 1` and MSD offers to resume from the last checkpoint.
|
||||
|
||||
---
|
||||
|
||||
## When failures are found: auto-diagnose and fix planning
|
||||
|
||||
If any tests report issues, GSD proceeds automatically:
|
||||
If any tests report issues, MSD proceeds automatically:
|
||||
|
||||
1. **Diagnoses root causes** — spawns parallel debug agents, one per issue, and updates `UAT.md` with root causes.
|
||||
2. **Plans gap closure** — spawns a `gsd-planner` in gap-closure mode, which reads `UAT.md` (with diagnoses) and writes new `PLAN.md` files.
|
||||
3. **Verifies the fix plans** — spawns a `gsd-plan-checker` to ensure the plans are executable. If issues are found, the planner and checker iterate up to three times.
|
||||
2. **Plans gap closure** — spawns a `msd-planner` in gap-closure mode, which reads `UAT.md` (with diagnoses) and writes new `PLAN.md` files.
|
||||
3. **Verifies the fix plans** — spawns a `msd-plan-checker` to ensure the plans are executable. If issues are found, the planner and checker iterate up to three times.
|
||||
4. **Presents next step** — when plans pass the checker:
|
||||
|
||||
```
|
||||
Plans verified and ready for execution.
|
||||
|
||||
`/clear` then `/gsd-execute-phase 1 --gaps-only`
|
||||
`/clear` then `/msd-execute-phase 1 --gaps-only`
|
||||
```
|
||||
|
||||
Run the suggested command to apply fixes, then re-run `/gsd-verify-work 1` to confirm everything passes.
|
||||
Run the suggested command to apply fixes, then re-run `/msd-verify-work 1` to confirm everything passes.
|
||||
|
||||
---
|
||||
|
||||
@@ -47,14 +47,14 @@ Run the suggested command to apply fixes, then re-run `/gsd-verify-work 1` to co
|
||||
Once all UAT tests pass (or if this is your first run and no issues are found), the phase is marked complete in `ROADMAP.md` and `STATE.md` automatically.
|
||||
|
||||
```bash
|
||||
/gsd-ship 1
|
||||
/msd-ship 1
|
||||
```
|
||||
|
||||
GSD runs preflight checks (verification status, clean working tree, branch, remote, `gh` CLI authentication), pushes the branch, and creates a PR:
|
||||
MSD runs preflight checks (verification status, clean working tree, branch, remote, `gh` CLI authentication), pushes the branch, and creates a PR:
|
||||
|
||||
```bash
|
||||
/gsd-ship 1 # Ready-for-review PR
|
||||
/gsd-ship 1 --draft # Draft PR — useful when more phases will follow
|
||||
/msd-ship 1 # Ready-for-review PR
|
||||
/msd-ship 1 --draft # Draft PR — useful when more phases will follow
|
||||
```
|
||||
|
||||
The PR body is assembled from planning artefacts automatically:
|
||||
@@ -71,19 +71,19 @@ No manual body writing required.
|
||||
|
||||
## Optional: code review before or after shipping
|
||||
|
||||
`/gsd-ship` does not run a code review automatically, but you can slot one in at any point:
|
||||
`/msd-ship` does not run a code review automatically, but you can slot one in at any point:
|
||||
|
||||
**Before verification** (catches issues before UAT):
|
||||
|
||||
```bash
|
||||
/gsd-code-review 1 # Standard review
|
||||
/gsd-code-review 1 --fix # Review then auto-fix Critical + Warning findings
|
||||
/msd-code-review 1 # Standard review
|
||||
/msd-code-review 1 --fix # Review then auto-fix Critical + Warning findings
|
||||
```
|
||||
|
||||
**After the PR is open** (to gate on quality before merge):
|
||||
|
||||
```bash
|
||||
/gsd-code-review 1 --depth=deep # Cross-file analysis including import graphs
|
||||
/msd-code-review 1 --depth=deep # Cross-file analysis including import graphs
|
||||
```
|
||||
|
||||
See [Set up cross-AI review](set-up-cross-ai-review.md) to configure Antigravity, Codex, or other reviewers for plan review earlier in the cycle.
|
||||
@@ -95,11 +95,11 @@ See [Set up cross-AI review](set-up-cross-ai-review.md) to configure Antigravity
|
||||
If your branch contains `.planning/` commits that you do not want reviewers to see:
|
||||
|
||||
```bash
|
||||
/gsd-pr-branch # Filter against main
|
||||
/gsd-pr-branch develop # Filter against develop
|
||||
/msd-pr-branch # Filter against main
|
||||
/msd-pr-branch develop # Filter against develop
|
||||
```
|
||||
|
||||
`/gsd-pr-branch` creates a new branch with only code changes — planning artefact commits are excluded. Run this before `/gsd-ship` if your team's review policy excludes planning noise.
|
||||
`/msd-pr-branch` creates a new branch with only code changes — planning artefact commits are excluded. Run this before `/msd-ship` if your team's review policy excludes planning noise.
|
||||
|
||||
---
|
||||
|
||||
@@ -110,7 +110,7 @@ A `*-VERIFICATION.md` reporting `status: passed` is re-checked, not cached, ever
|
||||
- **Content fingerprint (default for new reports).** The verifier records a digest of every input its verdict covers — the phase's `PLAN.md`/`SUMMARY.md` files, mapped requirements, and implementation files in the change set. If any of those files changes, disappears, or becomes unreadable after verification, the gate recomputes the digest, finds a mismatch, and reports `stale`. This catches drift even when nothing touches `SUMMARY.md` itself — an implementation file edited after verification is enough.
|
||||
- **Legacy SUMMARY-mtime check.** A `*-VERIFICATION.md` written before this fingerprint existed has no digest to check, so it keeps the older rule: `stale` when a `SUMMARY.md` is newer than the verification report.
|
||||
|
||||
Either way, `stale` routes the same as any other incomplete state: re-run `/gsd-verify-work 1` before shipping.
|
||||
Either way, `stale` routes the same as any other incomplete state: re-run `/msd-verify-work 1` before shipping.
|
||||
|
||||
The content fingerprint hashes covered files exactly as they sit on disk, including line endings. A checkout without a `.gitattributes` `eol=lf` rule pinning text files to LF (a Windows checkout with `core.autocrlf=true`, for example) can report `stale` on unchanged content — fix with a `.gitattributes` `eol=lf` rule, not by treating it as drift.
|
||||
|
||||
@@ -121,11 +121,11 @@ The content fingerprint hashes covered files exactly as they sit on disk, includ
|
||||
If this was the last phase in the milestone, run the milestone audit and archive it:
|
||||
|
||||
```bash
|
||||
/gsd-audit-milestone # Verify all requirements shipped
|
||||
/gsd-complete-milestone # Archive, create git tag
|
||||
/msd-audit-milestone # Verify all requirements shipped
|
||||
/msd-complete-milestone # Archive, create git tag
|
||||
```
|
||||
|
||||
`/gsd-complete-milestone` is the natural next step after the PR merges. See the [The phase loop](../explanation/the-phase-loop.md) for how verification and shipping fit into the full project lifecycle.
|
||||
`/msd-complete-milestone` is the natural next step after the PR merges. See the [The phase loop](../explanation/the-phase-loop.md) for how verification and shipping fit into the full project lifecycle.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# How to version and upgrade a capability
|
||||
|
||||
This guide covers two separate journeys: how a **capability author** keeps their manifest correctly versioned as GSD evolves, and how a **capability consumer** safely applies updates. Read only the section that matches your role; each stands alone.
|
||||
This guide covers two separate journeys: how a **capability author** keeps their manifest correctly versioned as MSD evolves, and how a **capability consumer** safely applies updates. Read only the section that matches your role; each stands alone.
|
||||
|
||||
---
|
||||
|
||||
@@ -8,7 +8,7 @@ This guide covers two separate journeys: how a **capability author** keeps their
|
||||
|
||||
### Choose a version number
|
||||
|
||||
Every `capability.json` must carry a `version` field expressed as a [semver](https://semver.org) string. GSD rejects a capability manifest that omits it.
|
||||
Every `capability.json` must carry a `version` field expressed as a [semver](https://semver.org) string. MSD rejects a capability manifest that omits it.
|
||||
|
||||
Use the standard semver conventions:
|
||||
|
||||
@@ -24,41 +24,41 @@ Set the version in your manifest before every release:
|
||||
{
|
||||
"id": "my-deploy-gate",
|
||||
"version": "1.2.0",
|
||||
"engines": { "gsd": ">=1.6.0 <3.0.0" }
|
||||
"engines": { "msd": ">=1.6.0 <3.0.0" }
|
||||
}
|
||||
```
|
||||
|
||||
> **First-party capabilities are versioned automatically.** The native capabilities shipped inside GSD (`capabilities/<id>/capability.json`) are stamped in lockstep with the GSD package version at release time by `scripts/sync-manifest-versions.cjs` — their `version` always equals the GSD version, so per-capability semver and `compatVersions` only carry independent signal for **third-party** capabilities. As an author of a third-party capability, you own your own version line; the lockstep rule does not apply to you.
|
||||
> **First-party capabilities are versioned automatically.** The native capabilities shipped inside MSD (`capabilities/<id>/capability.json`) are stamped in lockstep with the MSD package version at release time by `scripts/sync-manifest-versions.cjs` — their `version` always equals the MSD version, so per-capability semver and `compatVersions` only carry independent signal for **third-party** capabilities. As an author of a third-party capability, you own your own version line; the lockstep rule does not apply to you.
|
||||
|
||||
### Decide when to raise `engines.gsd`
|
||||
### Decide when to raise `engines.msd`
|
||||
|
||||
The `engines.gsd` range expresses which GSD host versions your capability is compatible with. GSD enforces this as a hard gate at install time and again at load time.
|
||||
The `engines.msd` range expresses which MSD host versions your capability is compatible with. MSD enforces this as a hard gate at install time and again at load time.
|
||||
|
||||
Raise the lower bound when you start using a GSD feature introduced in a specific release — for example, a loop extension point added in 1.7.0, a new manifest field, or a config federation key that does not exist in older GSD builds. Do not raise it pre-emptively; only raise it when the capability genuinely requires the newer behaviour.
|
||||
Raise the lower bound when you start using a MSD feature introduced in a specific release — for example, a loop extension point added in 1.7.0, a new manifest field, or a config federation key that does not exist in older MSD builds. Do not raise it pre-emptively; only raise it when the capability genuinely requires the newer behaviour.
|
||||
|
||||
When you do raise the lower bound:
|
||||
|
||||
1. Bump `version` (at minimum a minor bump, or a major bump if the change is otherwise breaking).
|
||||
2. Update `engines.gsd` to reflect the new minimum.
|
||||
2. Update `engines.msd` to reflect the new minimum.
|
||||
3. Add a `compatVersions` entry (see below).
|
||||
|
||||
### Maintain `compatVersions`
|
||||
|
||||
`compatVersions` is a capability-version → GSD-version-**range** table that lets GSD offer older consumers a downgrade instead of a hard block. Each value is a semver range (the same grammar as `engines.gsd`), evaluated against the running GSD version:
|
||||
`compatVersions` is a capability-version → MSD-version-**range** table that lets MSD offer older consumers a downgrade instead of a hard block. Each value is a semver range (the same grammar as `engines.msd`), evaluated against the running MSD version:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"engines": { "gsd": ">=1.7.0 <3.0.0" },
|
||||
"engines": { "msd": ">=1.7.0 <3.0.0" },
|
||||
"compatVersions": {
|
||||
"1.2.0": ">=1.6.0 <1.7.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This entry tells GSD: "version 1.2.0 of this capability is compatible with GSD versions `>=1.6.0 <1.7.0`." When a consumer's GSD is older than the current `engines.gsd` floor (1.7.0), GSD consults `compatVersions`, picks the **newest** capability version whose range the host satisfies, and offers that instead of failing outright.
|
||||
This entry tells MSD: "version 1.2.0 of this capability is compatible with MSD versions `>=1.6.0 <1.7.0`." When a consumer's MSD is older than the current `engines.msd` floor (1.7.0), MSD consults `compatVersions`, picks the **newest** capability version whose range the host satisfies, and offers that instead of failing outright.
|
||||
|
||||
Add a new entry **only when you change `engines.gsd`** — that is the only moment an older GSD version and a specific capability version become correlated. A `compatVersions` entry is not meaningful for a capability distributed as a bare tarball URL (a tarball exposes a single version and cannot be auto-selected from a table); it is only actionable for sources that enumerate versions: git tags, a registry, or npm.
|
||||
Add a new entry **only when you change `engines.msd`** — that is the only moment an older MSD version and a specific capability version become correlated. A `compatVersions` entry is not meaningful for a capability distributed as a bare tarball URL (a tarball exposes a single version and cannot be auto-selected from a table); it is only actionable for sources that enumerate versions: git tags, a registry, or npm.
|
||||
|
||||
### Publish a new version
|
||||
|
||||
@@ -71,16 +71,16 @@ git tag v1.2.0
|
||||
git push origin v1.2.0
|
||||
```
|
||||
|
||||
GSD's git adapter fetches tags to determine what is available. Without a matching tag, the new version is invisible to `gsd capability outdated`.
|
||||
MSD's git adapter fetches tags to determine what is available. Without a matching tag, the new version is invisible to `msd capability outdated`.
|
||||
|
||||
**npm.** Publish normally. GSD uses `dist-tags` to check for updates, so the standard `npm publish` flow is sufficient:
|
||||
**npm.** Publish normally. MSD uses `dist-tags` to check for updates, so the standard `npm publish` flow is sufficient:
|
||||
|
||||
```bash
|
||||
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, 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.
|
||||
**New tarball.** Upload the new archive at a URL and communicate the URL to consumers. MSD cannot auto-detect updates for tarball sources, and `msd 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** (`msd capability install <new-url> …`), which overwrites the recorded source. If you anticipate frequent updates, consider switching to a git or npm source so `msd capability update <id>` can pick up new versions automatically.
|
||||
|
||||
---
|
||||
|
||||
@@ -91,55 +91,55 @@ npm publish
|
||||
Run:
|
||||
|
||||
```bash
|
||||
gsd capability outdated
|
||||
msd capability outdated
|
||||
```
|
||||
|
||||
GSD contacts the source of each installed capability and reports which ones have a newer version available. Whether an update is detectable depends on the source:
|
||||
MSD contacts the source of each installed capability and reports which ones have a newer version available. Whether an update is detectable depends on the source:
|
||||
|
||||
| Source | Auto-detectable? |
|
||||
|---|---|
|
||||
| Git (tags / manifest) | Yes — GSD fetches available tags. |
|
||||
| npm | Yes — GSD checks `dist-tags`. |
|
||||
| Git (tags / manifest) | Yes — MSD fetches available tags. |
|
||||
| npm | Yes — MSD checks `dist-tags`. |
|
||||
| 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, `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.
|
||||
If a capability is installed from a tarball and the author publishes a new version at a different URL, `msd 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 `msd capability install <new-url> …`; that overwrites the recorded source with the new version.
|
||||
|
||||
### Apply an update
|
||||
|
||||
To update a specific capability:
|
||||
|
||||
```bash
|
||||
gsd capability update <id>
|
||||
msd capability update <id>
|
||||
```
|
||||
|
||||
To update all installed capabilities at once:
|
||||
|
||||
```bash
|
||||
gsd capability update --all
|
||||
msd capability update --all
|
||||
```
|
||||
|
||||
Updates are **atomic**: GSD fully fetches and validates the new version before swapping it in. The ledger write is the commit point. If GSD stops mid-update (for example, due to a network failure), the next command run will detect the orphaned state via a reconciliation sweep and restore a consistent install — you will never be left with a half-updated capability.
|
||||
Updates are **atomic**: MSD fully fetches and validates the new version before swapping it in. The ledger write is the commit point. If MSD stops mid-update (for example, due to a network failure), the next command run will detect the orphaned state via a reconciliation sweep and restore a consistent install — you will never be left with a half-updated capability.
|
||||
|
||||
### Consent when the executable surface changes
|
||||
|
||||
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:
|
||||
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, `msd 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:
|
||||
|
||||
```bash
|
||||
gsd capability update <id> --yes
|
||||
msd capability update <id> --yes
|
||||
```
|
||||
|
||||
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
|
||||
### When `engines.msd` no longer matches
|
||||
|
||||
If the new version of a capability requires a GSD version newer than what you have installed, GSD will tell you clearly and — where the source enumerates versions — offer the newest `compatVersions`-compatible version instead. If no compatible version is available, or the source is a bare tarball, you will need to either upgrade GSD or stay on your current capability version.
|
||||
If the new version of a capability requires a MSD version newer than what you have installed, MSD will tell you clearly and — where the source enumerates versions — offer the newest `compatVersions`-compatible version instead. If no compatible version is available, or the source is a bare tarball, you will need to either upgrade MSD or stay on your current capability version.
|
||||
|
||||
---
|
||||
|
||||
## Related guides
|
||||
|
||||
- [How to remove or disable a capability](remove-a-capability.md)
|
||||
- [Develop a Capability for GSD 1.5+](develop-a-capability.md)
|
||||
- [Develop a Capability for MSD 1.5+](develop-a-capability.md)
|
||||
- [Capability manifest reference](../reference/capability-manifest.md)
|
||||
- [Turn a capability off (and keep it off)](turn-a-capability-off.md)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
**Goal:** Run concurrent work on different milestone areas — backend API, frontend dashboard, infrastructure, or any other concern — without planning state from one area bleeding into another.
|
||||
|
||||
**Prerequisites:** An active GSD Core project (`.planning/ROADMAP.md` exists). If not, run `/gsd-new-project` first.
|
||||
**Prerequisites:** An active MSD Core project (`.planning/ROADMAP.md` exists). If not, run `/msd-new-project` first.
|
||||
|
||||
---
|
||||
|
||||
@@ -28,24 +28,24 @@ A workstream is an isolated planning context within a single codebase. Each work
|
||||
└── phases/
|
||||
```
|
||||
|
||||
When a workstream is active, every GSD command — `/gsd-progress`, `/gsd-discuss-phase`, `/gsd-plan-phase`, `/gsd-execute-phase` — reads from and writes to that workstream's directory. Switching workstreams redirects all of those commands to a different subtree without touching the source tree.
|
||||
When a workstream is active, every MSD command — `/msd-progress`, `/msd-discuss-phase`, `/msd-plan-phase`, `/msd-execute-phase` — reads from and writes to that workstream's directory. Switching workstreams redirects all of those commands to a different subtree without touching the source tree.
|
||||
|
||||
---
|
||||
|
||||
## Create a workstream
|
||||
|
||||
```bash
|
||||
/gsd-workstreams create backend-api
|
||||
/msd-workstreams create backend-api
|
||||
```
|
||||
|
||||
GSD creates the workstream directory under `.planning/workstreams/backend-api/` and seeds it with a skeleton `STATE.md` and `ROADMAP.md`. The workstream is not automatically activated — you switch to it explicitly.
|
||||
MSD creates the workstream directory under `.planning/workstreams/backend-api/` and seeds it with a skeleton `STATE.md` and `ROADMAP.md`. The workstream is not automatically activated — you switch to it explicitly.
|
||||
|
||||
---
|
||||
|
||||
## List workstreams
|
||||
|
||||
```bash
|
||||
/gsd-workstreams list
|
||||
/msd-workstreams list
|
||||
```
|
||||
|
||||
Shows all workstreams and which one is currently active in your session.
|
||||
@@ -55,28 +55,28 @@ Shows all workstreams and which one is currently active in your session.
|
||||
## Switch to a workstream
|
||||
|
||||
```bash
|
||||
/gsd-workstreams switch backend-api
|
||||
/msd-workstreams switch backend-api
|
||||
```
|
||||
|
||||
From this point forward, all GSD workflow commands operate in the `backend-api` context. The switch is session-scoped: when multiple Claude Code terminals are open on the same repo, each session can hold a different active workstream without interfering with the others.
|
||||
From this point forward, all MSD workflow commands operate in the `backend-api` context. The switch is session-scoped: when multiple Claude Code terminals are open on the same repo, each session can hold a different active workstream without interfering with the others.
|
||||
|
||||
The statusline's GSD-state segment (milestone, phase, progress) reflects whichever workstream resolves as active — the same `GSD_WORKSTREAM` env var / stored pointer precedence every workstream-aware command uses. If no workstream can be resolved in a workstream-mode project, the segment shows `no active workstream` rather than disappearing silently.
|
||||
The statusline's MSD-state segment (milestone, phase, progress) reflects whichever workstream resolves as active — the same `MSD_WORKSTREAM` env var / stored pointer precedence every workstream-aware command uses. If no workstream can be resolved in a workstream-mode project, the segment shows `no active workstream` rather than disappearing silently.
|
||||
|
||||
Once switched, drive the normal phase workflow:
|
||||
|
||||
```bash
|
||||
/gsd-discuss-phase 1
|
||||
/gsd-plan-phase 1
|
||||
/gsd-execute-phase 1
|
||||
/gsd-verify-work 1
|
||||
/msd-discuss-phase 1
|
||||
/msd-plan-phase 1
|
||||
/msd-execute-phase 1
|
||||
/msd-verify-work 1
|
||||
```
|
||||
|
||||
To work on another area, switch workstreams in a second terminal:
|
||||
|
||||
```bash
|
||||
/gsd-workstreams switch frontend-dash
|
||||
/gsd-discuss-phase 1
|
||||
/gsd-plan-phase 1
|
||||
/msd-workstreams switch frontend-dash
|
||||
/msd-discuss-phase 1
|
||||
/msd-plan-phase 1
|
||||
```
|
||||
|
||||
---
|
||||
@@ -84,7 +84,7 @@ To work on another area, switch workstreams in a second terminal:
|
||||
## Check progress across all workstreams
|
||||
|
||||
```bash
|
||||
/gsd-workstreams progress
|
||||
/msd-workstreams progress
|
||||
```
|
||||
|
||||
Prints a cross-workstream summary — phase status, current position, and outstanding work for every workstream — without requiring you to switch between them.
|
||||
@@ -92,7 +92,7 @@ Prints a cross-workstream summary — phase status, current position, and outsta
|
||||
For detailed status on a single workstream:
|
||||
|
||||
```bash
|
||||
/gsd-workstreams status backend-api
|
||||
/msd-workstreams status backend-api
|
||||
```
|
||||
|
||||
---
|
||||
@@ -102,10 +102,10 @@ For detailed status on a single workstream:
|
||||
After a context reset or a new session, restore your position:
|
||||
|
||||
```bash
|
||||
/gsd-workstreams resume backend-api
|
||||
/msd-workstreams resume backend-api
|
||||
```
|
||||
|
||||
This activates the workstream and restores your last known position within it, equivalent to switching and then running `/gsd-resume-work`.
|
||||
This activates the workstream and restores your last known position within it, equivalent to switching and then running `/msd-resume-work`.
|
||||
|
||||
---
|
||||
|
||||
@@ -114,10 +114,10 @@ This activates the workstream and restores your last known position within it, e
|
||||
When a workstream's milestone work is done:
|
||||
|
||||
```bash
|
||||
/gsd-workstreams complete backend-api
|
||||
/msd-workstreams complete backend-api
|
||||
```
|
||||
|
||||
GSD marks the workstream as archived and moves it out of the active listing. The planning artifacts are preserved under `.planning/workstreams/backend-api/` for audit purposes.
|
||||
MSD marks the workstream as archived and moves it out of the active listing. The planning artifacts are preserved under `.planning/workstreams/backend-api/` for audit purposes.
|
||||
|
||||
---
|
||||
|
||||
@@ -126,8 +126,8 @@ GSD marks the workstream as archived and moves it out of the active listing. The
|
||||
If you need to run one command against a specific workstream without changing your session's active context, use the `--ws` flag:
|
||||
|
||||
```bash
|
||||
/gsd-progress --ws frontend-dash
|
||||
/gsd-plan-phase 2 --ws backend-api
|
||||
/msd-progress --ws frontend-dash
|
||||
/msd-plan-phase 2 --ws backend-api
|
||||
```
|
||||
|
||||
`--ws` takes highest priority in the resolution order and does not alter the session-scoped pointer.
|
||||
@@ -147,7 +147,7 @@ Choose [workspaces](isolate-work-with-workspaces.md) instead when:
|
||||
|
||||
- You are working across **multiple repositories** (e.g., `hr-ui` and `ZeymoAPI`)
|
||||
- You need the isolation of a **separate git worktree** or clone per feature — fully independent branches, lock files, and build artefacts
|
||||
- You want to run `/gsd-new-project` independently in each workspace with a wholly separate `.planning/` root, not a subdirectory of the main repo's `.planning/`
|
||||
- You want to run `/msd-new-project` independently in each workspace with a wholly separate `.planning/` root, not a subdirectory of the main repo's `.planning/`
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user