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:
Jakub Zych
2026-10-06 01:47:40 +02:00
parent fe069b2a56
commit a9a7a328e6
2763 changed files with 78465 additions and 78434 deletions

View File

@@ -1,19 +1,19 @@
{
"name": "gsd-core",
"description": "Marketplace for GSD Core — meta-prompting, context engineering, and spec-driven development system for AI coding agents.",
"name": "msd-core",
"description": "Marketplace for MSD Core — meta-prompting, context engineering, and spec-driven development system for AI coding agents.",
"owner": {
"name": "open-gsd",
"url": "https://github.com/open-gsd"
"name": "golem15com",
"url": "https://github.com/golem15com"
},
"plugins": [
{
"name": "gsd-core",
"description": "GSD Core is a meta-prompting, context engineering, and spec-driven development system for AI coding agents.",
"name": "msd-core",
"description": "MSD Core is a meta-prompting, context engineering, and spec-driven development system for AI coding agents.",
"version": "1.14.0",
"source": "./",
"author": {
"name": "open-gsd",
"url": "https://github.com/open-gsd"
"name": "golem15com",
"url": "https://github.com/golem15com"
}
}
]

View File

@@ -1,14 +1,14 @@
{
"name": "gsd-core",
"displayName": "GSD Core",
"name": "msd-core",
"displayName": "MSD Core",
"version": "1.14.0",
"description": "GSD Core is a meta-prompting, context engineering, and spec-driven development system for AI coding agents.",
"description": "MSD Core is a meta-prompting, context engineering, and spec-driven development system for AI coding agents.",
"author": {
"name": "open-gsd",
"url": "https://github.com/open-gsd"
"name": "golem15com",
"url": "https://github.com/golem15com"
},
"homepage": "https://github.com/open-gsd/gsd-core",
"repository": "https://github.com/open-gsd/gsd-core",
"homepage": "https://github.com/golem15com/msd-core",
"repository": "https://github.com/golem15com/msd-core",
"license": "MIT",
"keywords": [
"spec-driven-development",
@@ -16,8 +16,8 @@
"workflow",
"context-engineering",
"claude-code",
"gsd"
"msd"
],
"commands": "./commands/gsd/",
"commands": "./commands/msd/",
"skills": "./skills/"
}

View File

@@ -1,19 +1,19 @@
# GSD — Get Shit Done
# MSD — Get Shit Done
## What This Project Is
GSD is a structured AI development workflow system. It coordinates AI agents through planning phases, not direct code edits.
MSD is a structured AI development workflow system. It coordinates AI agents through planning phases, not direct code edits.
## Core Rule: Never Edit Outside a GSD Workflow
Do not make direct repo edits. All changes must go through a GSD workflow:
- `/gsd:plan-phase` → plan the work
- `/gsd:execute-phase` → build it
- `/gsd:verify-work` → verify results
## Core Rule: Never Edit Outside a MSD Workflow
Do not make direct repo edits. All changes must go through a MSD workflow:
- `/msd:plan-phase` → plan the work
- `/msd:execute-phase` → build it
- `/msd:verify-work` → verify results
## Architecture
- `gsd-core/bin/lib/` — Core Node.js library (CommonJS .cjs, no external deps)
- `gsd-core/workflows/` — Workflow definition files (.md)
- `msd-core/bin/lib/` — Core Node.js library (CommonJS .cjs, no external deps)
- `msd-core/workflows/` — Workflow definition files (.md)
- `agents/` — Agent definition files (.md)
- `commands/gsd/` — Slash command definitions (.md)
- `commands/msd/` — Slash command definitions (.md)
- `tests/` — Test files (.test.cjs, node:test + node:assert)
## Coding Standards
@@ -24,4 +24,4 @@ Do not make direct repo edits. All changes must go through a GSD workflow:
## Safety
- Use `execFileSync` (array args) not `execSync` (string interpolation)
- Validate user-provided paths with `validatePath()` from `gsd-core/bin/lib/security.cjs`
- Validate user-provided paths with `validatePath()` from `msd-core/bin/lib/security.cjs`

View File

@@ -1,10 +1,10 @@
# CodeRabbit configuration — open-gsd/gsd-core
# CodeRabbit configuration — golem15com/msd-core
#
# Schema: https://docs.coderabbit.ai/reference/yaml-template/
#
# Project context: GSD ships a CLI tool + an agent runtime, not a documented
# Project context: MSD ships a CLI tool + an agent runtime, not a documented
# public library. We carry rich JSDoc on internal helpers that warrant it
# (see bin/install.js, gsd-core/bin/lib/*.cjs) but we do not enforce a
# (see bin/install.js, msd-core/bin/lib/*.cjs) but we do not enforce a
# blanket docstring coverage bar — see issue #2932 for rationale.
reviews:

2
.gitattributes vendored
View File

@@ -11,7 +11,7 @@
*.ttf binary
*.pdf binary
# The `merge=gsd-regen` driver + linguist-generated block that used to live here
# The `merge=msd-regen` driver + linguist-generated block that used to live here
# (#2721, ADR-2719 Phase 1) covered tests/fixtures/golden-install-parity/*.json,
# tests/workflow-size-baseline.json, and tests/agent-size-baseline.json — all
# three deleted by #2724 (ADR-2719 Phase 4), which retired the bridge driver too.

View File

@@ -7,7 +7,7 @@ GIT_CMD="${GIT_OVERRIDE:-git}"
NPM_CMD="${NPM_OVERRIDE:-npm}"
# Tracked sources of the command-alias surface. These are the `src/*.cts` files,
# never the `gsd-core/bin/lib/*.cjs` artifacts they compile to: those are
# never the `msd-core/bin/lib/*.cjs` artifacts they compile to: those are
# gitignored, so `git diff --cached --name-only` never lists them and a guard
# keyed on them can never fire (#2725). Kept in sync with
# scripts/lib/alias-drift-families.cjs by tests/precommit-alias-drift-hook.test.cjs.

View File

@@ -6,10 +6,10 @@ set -euo pipefail
GIT_CMD="${GIT_OVERRIDE:-git}"
zero_sha='0000000000000000000000000000000000000000'
blocked_regex="${GSD_BLOCKED_AUTHOR_REGEX:-}"
blocked_regex="${MSD_BLOCKED_AUTHOR_REGEX:-}"
# Local-only guard: no-op unless the developer opts in via env var, e.g.
# export GSD_BLOCKED_AUTHOR_REGEX='@example-corp\.com$'
# export MSD_BLOCKED_AUTHOR_REGEX='@example-corp\.com$'
if [[ -z "$blocked_regex" ]]; then
exit 0
fi

View File

@@ -24,8 +24,8 @@ body:
- type: input
id: version
attributes:
label: GSD Version
description: "Check the installed version: `cat ~/.claude/gsd-core/gsd-file-manifest.json` (look for `\"version\"`) or `npx @opengsd/gsd-core --version` (if installed via npm global)"
label: MSD Version
description: "Check the installed version: `cat ~/.claude/msd-core/msd-file-manifest.json` (look for `\"version\"`) or `npx @golem15/msd-core --version` (if installed via npm global)"
placeholder: "e.g., 1.18.0"
validations:
required: true
@@ -34,7 +34,7 @@ body:
id: runtime
attributes:
label: Runtime
description: Which AI coding tool are you using GSD with?
description: Which AI coding tool are you using MSD with?
options:
- Claude Code
- OpenCode
@@ -86,8 +86,8 @@ body:
attributes:
label: Installation Method
options:
- npx @opengsd/gsd-core@latest (fresh run)
- npm install -g @opengsd/gsd-core
- npx @golem15/msd-core@latest (fresh run)
- npm install -g @golem15/msd-core
- Updated from a previous version
validations:
required: true
@@ -96,9 +96,9 @@ body:
id: description
attributes:
label: What happened?
description: Describe what went wrong. Be specific about which GSD command you were running.
description: Describe what went wrong. Be specific about which MSD command you were running.
placeholder: |
When I ran `/gsd-plan`, the system...
When I ran `/msd-plan`, the system...
validations:
required: true
@@ -115,12 +115,12 @@ body:
attributes:
label: Steps to reproduce
description: |
Exact steps to reproduce the issue. Include the GSD command used.
Exact steps to reproduce the issue. Include the MSD command used.
placeholder: |
1. Install GSD with `npx @opengsd/gsd-core@latest`
1. Install MSD with `npx @golem15/msd-core@latest`
2. Select runtime: Claude Code
3. Run `/gsd-init` with a new project
4. Run `/gsd-plan`
3. Run `/msd-init` with a new project
4. Run `/msd-plan`
5. Error appears at step...
validations:
required: true
@@ -140,7 +140,7 @@ body:
- type: textarea
id: config
attributes:
label: GSD Configuration
label: MSD Configuration
description: |
If the bug is related to planning, phases, or workflow behavior, paste your `.planning/config.json`.
@@ -154,7 +154,7 @@ body:
- type: textarea
id: state
attributes:
label: GSD State (if relevant)
label: MSD State (if relevant)
description: |
If the bug involves incorrect state tracking or phase progression, include your `.planning/STATE.md`.
@@ -199,7 +199,7 @@ body:
label: Impact
description: How much does this affect your workflow?
options:
- Blocker — Cannot use GSD at all
- Blocker — Cannot use MSD at all
- Major — Core feature is broken, no workaround
- Moderate — Feature is broken but I have a workaround
- Minor — Cosmetic or edge case
@@ -222,9 +222,9 @@ body:
Anything else — screenshots, screen recordings, related issues, or links.
**Useful diagnostics to include (if applicable):**
- `cat ~/.claude/gsd-core/gsd-file-manifest.json` — confirms installed version (the `version` field tracks what `/gsd-update` installs; `npm list -g` does NOT reflect runtime-home installs)
- `ls -la ~/.claude/gsd-core/` — confirms installation files (Claude Code)
- `cat ~/.claude/gsd-core/gsd-file-manifest.json` — file manifest for debugging install issues
- `cat ~/.claude/msd-core/msd-file-manifest.json` — confirms installed version (the `version` field tracks what `/msd-update` installs; `npm list -g` does NOT reflect runtime-home installs)
- `ls -la ~/.claude/msd-core/` — confirms installation files (Claude Code)
- `cat ~/.claude/msd-core/msd-file-manifest.json` — file manifest for debugging install issues
- `ls -la .planning/` — confirms planning directory state
**⚠️ PII Warning:** File listings and manifests contain your home directory path. Replace your username with `REDACTED`.

View File

@@ -17,7 +17,7 @@ body:
- Documentation infrastructure (not content — use Docs Issue for content)
- Tech debt paydown
If this changes how GSD **works** for users, use [Enhancement](./enhancement.yml) or [Feature Request](./feature_request.yml) instead.
If this changes how MSD **works** for users, use [Enhancement](./enhancement.yml) or [Feature Request](./feature_request.yml) instead.
- type: checkboxes
id: preflight

View File

@@ -39,7 +39,7 @@ body:
attributes:
label: What existing feature or behavior does this improve?
description: Name the specific command, workflow, output, or behavior you are enhancing.
placeholder: "e.g., `/gsd-plan` output, phase status display in statusline, context summary format"
placeholder: "e.g., `/msd-plan` output, phase status display in statusline, context summary format"
validations:
required: true
@@ -50,7 +50,7 @@ body:
description: |
Describe exactly how the thing works today. Be specific. Include example output or commands if helpful.
placeholder: |
Currently, `/gsd-status` shows:
Currently, `/msd-status` shows:
```
Phase 2/5 — In Progress
```
@@ -66,7 +66,7 @@ body:
description: |
Describe exactly how it should work after the enhancement. Be specific. Include example output or commands.
placeholder: |
After the enhancement, `/gsd-status` would show:
After the enhancement, `/msd-status` would show:
```
Phase 2/5 — In Progress — "Implement core auth module"
```
@@ -105,8 +105,8 @@ body:
An enhancement should have a narrow, well-defined scope. If your list is long, this might be a feature, not an enhancement.
placeholder: |
Files modified:
- `gsd-core/commands/gsd/status.md` — update output format description
- `gsd-core/bin/lib/state.cjs` — expose phase name in status() return value
- `msd-core/commands/msd/status.md` — update output format description
- `msd-core/bin/lib/state.cjs` — expose phase name in status() return value
- `tests/status.test.cjs` — update snapshot and add test for phase name in output
- `CHANGELOG.md` — user-facing change entry

View File

@@ -8,7 +8,7 @@ body:
value: |
## ⚠️ Read this before you fill anything out
A feature adds something new to GSD — a new command, workflow, concept, or integration. Features have the **highest bar** for acceptance because every feature adds permanent maintenance burden to a project built for solo developers.
A feature adds something new to MSD — a new command, workflow, concept, or integration. Features have the **highest bar** for acceptance because every feature adds permanent maintenance burden to a project built for solo developers.
**Before opening this issue:**
- Check [Discussions](https://github.com/open-gsd/gsd-core/discussions) — has this been proposed and declined before?
@@ -16,7 +16,7 @@ body:
- Ask yourself: *does this solve a real problem for a solo developer working with an AI coding tool, or is it a feature I personally want?*
**What happens after you submit:**
A maintainer will review this spec. If it is incomplete, it will be **closed**, not revised. If it conflicts with GSD's design philosophy, it will be declined. If it is approved, it will be labeled `approved-feature` and you may begin coding.
A maintainer will review this spec. If it is incomplete, it will be **closed**, not revised. If it conflicts with MSD's design philosophy, it will be declined. If it is approved, it will be labeled `approved-feature` and you may begin coding.
**Do not open a PR until this issue is labeled `approved-feature`.**
@@ -30,7 +30,7 @@ body:
required: true
- label: I have read CONTRIBUTING.md and understand that I must wait for `approved-feature` before writing any code
required: true
- label: I have read the existing GSD commands and workflows and confirmed this feature does not duplicate existing behavior
- label: I have read the existing MSD commands and workflows and confirmed this feature does not duplicate existing behavior
required: true
- label: This feature solves a problem for solo developers using AI coding tools, not a personal preference or workflow I happen to like
required: true
@@ -83,14 +83,14 @@ body:
Describe exactly what is being added. Be specific about commands, output, behavior, and user interaction.
Include example commands or example output where possible.
placeholder: |
A new command `/gsd-rollback` that:
A new command `/msd-rollback` that:
1. Reads the current phase from STATE.md
2. Reverts STATE.md to the previous phase's snapshot
3. Outputs a confirmation with the rolled-back state
Example usage:
```
/gsd-rollback
/msd-rollback
> Rolled back from Phase 3 (failed) to Phase 2 (completed)
```
validations:
@@ -105,11 +105,11 @@ body:
If you cannot fill this out, you do not understand the codebase well enough to propose this feature yet.
placeholder: |
Files that would be created:
- `gsd-core/commands/gsd/rollback.md` — new slash command definition
- `msd-core/commands/msd/rollback.md` — new slash command definition
Files that would be modified:
- `gsd-core/bin/lib/state.cjs` — add rollback() function
- `gsd-core/bin/lib/phases.cjs` — expose phase snapshot API
- `msd-core/bin/lib/state.cjs` — add rollback() function
- `msd-core/bin/lib/phases.cjs` — expose phase snapshot API
- `tests/rollback.test.cjs` — new test file
- `docs/COMMANDS.md` — document new command
- `CHANGELOG.md` — entry for this feature
@@ -139,9 +139,9 @@ body:
List the specific, testable conditions that must be true for this feature to be considered complete.
These become the basis for reviewer sign-off. Vague criteria ("it works") are not acceptable.
placeholder: |
- [ ] `/gsd-rollback` reverts STATE.md to the previous phase when current phase status is `failed`
- [ ] `/gsd-rollback` exits with an error if there is no previous phase to roll back to
- [ ] `/gsd-rollback` outputs the before/after phase names in its confirmation message
- [ ] `/msd-rollback` reverts STATE.md to the previous phase when current phase status is `failed`
- [ ] `/msd-rollback` exits with an error if there is no previous phase to roll back to
- [ ] `/msd-rollback` outputs the before/after phase names in its confirmation message
- [ ] Rollback is logged in the phase history so the AI agent can see it happened
- [ ] All existing tests still pass
- [ ] New tests cover the happy path, no-previous-phase case, and STATE.md corruption case
@@ -225,7 +225,7 @@ body:
placeholder: |
1. Manual STATE.md editing — rejected because it requires the developer to understand the schema
and is error-prone. The AI agent cannot reliably guide this.
2. A `/gsd-reset` command that wipes all state — rejected because it is too destructive and
2. A `/msd-reset` command that wipes all state — rejected because it is too destructive and
loses all completed phase history.
validations:
required: true
@@ -235,7 +235,7 @@ body:
attributes:
label: Prior art and references
description: |
Does any other tool, project, or GSD discussion address this? Link to anything relevant.
Does any other tool, project, or MSD discussion address this? Link to anything relevant.
If you are aware of a prior declined proposal for this feature, explain why this proposal is different.
validations:
required: false

View File

@@ -30,7 +30,7 @@ Full schema and process: [docs/registries/README.md](../../docs/registries/READM
"description": "",
"author": "",
"license": "",
"enginesGsd": "",
"enginesMsd": "",
"install": "",
"uninstall": "",
"interactions": {},
@@ -42,7 +42,7 @@ Full schema and process: [docs/registries/README.md](../../docs/registries/READM
## Required-field checklist
- [ ] `id`, `name`, `type`, `repo`, `description`, `author`, `license`, `enginesGsd`, `install`, `uninstall`, `interactions`, `discussion` are all present and non-empty
- [ ] `id`, `name`, `type`, `repo`, `description`, `author`, `license`, `enginesMsd`, `install`, `uninstall`, `interactions`, `discussion` are all present and non-empty
- [ ] **(Capability entries only)** `interactions.loopExtensionPoints` is a non-empty subset of the 12 Loop Extension Points, `interactions.hookKinds` ⊆ `{step, contribution, gate}`, and `interactions.configKeys` / `requires` / `runtimeCompat` / `produces` / `consumes` are present (empty arrays are fine where nothing applies)
- [ ] **(EoS entries only)** `protocolVersion` is an integer ≥ 1, `interactions.interfacePoints` is a non-empty subset of the six interface points, `interactions.profile` is one of `programmatic-cli` / `declarative-cli` / `ide`, and `interactions.axes` has exactly the eight required axis keys plus, optionally, `effortSurface` (`argv` / `none`)
- [ ] **(Reviewer entries only)** `interactions.slug` matches the lane slug grammar `^[a-z0-9][a-z0-9_-]*$`, `interactions.flags` is a non-empty array matching `^--[a-z0-9][a-z0-9-]*$`, `interactions.transport` is `spawn` or `openai-http`, `interactions.evidenceClass` is `source-grounded` or `diff-only`, `interactions.reviewsSection` is a non-empty string (max 200 characters), and `interactions.requiresBinaries` / `configKeys` / `runtimeCompat` are present (empty arrays are fine where nothing applies)
@@ -50,7 +50,7 @@ Full schema and process: [docs/registries/README.md](../../docs/registries/READM
## Ownership & non-endorsement
- [ ] `repo` links to a repository **I own or am the primary maintainer of** — not a fork, mirror, or someone else's project
- [ ] I understand that inclusion in this registry means only that a maintainer merged this PR — it is **not** an endorsement, and GSD has not reviewed, tested, audited, or verified my solution or its claimed GSD interactions
- [ ] I understand that inclusion in this registry means only that a maintainer merged this PR — it is **not** an endorsement, and MSD has not reviewed, tested, audited, or verified my solution or its claimed MSD interactions
- [ ] I understand this entry is removed only for illegal content, malware, spam, or a dead/non-functional link — never for quality — and a maintainer may remove it on that narrow basis without further notice
## One entry, one PR
@@ -86,13 +86,13 @@ Full schema and process: [docs/registries/README.md](../../docs/registries/READM
"id": "linear-issue-sync",
"name": "Linear Issue Sync",
"type": "capability",
"repo": "some-org/gsd-cap-linear-sync",
"repo": "some-org/msd-cap-linear-sync",
"description": "Mirrors ROADMAP.md items to Linear issues as a ship:post contribution.",
"author": "Some Org <hello@some-org.example>",
"license": "MIT",
"enginesGsd": ">=1.6.0",
"install": "gsd capability install https://github.com/some-org/gsd-cap-linear-sync.git#v1.0.0",
"uninstall": "gsd capability remove linear-issue-sync",
"enginesMsd": ">=1.6.0",
"install": "msd capability install https://github.com/some-org/msd-cap-linear-sync.git#v1.0.0",
"uninstall": "msd capability remove linear-issue-sync",
"interactions": {
"loopExtensionPoints": ["ship:post"],
"hookKinds": ["contribution"],

View File

@@ -143,7 +143,7 @@ jobs:
# The version bump below fires the `version` npm lifecycle hook, which runs
# gen-capability-registry.cjs. That validator lazily require()s the built
# gsd-core/bin/lib/capability-ledger.cjs (a build:lib output, gitignored);
# msd-core/bin/lib/capability-ledger.cjs (a build:lib output, gitignored);
# when it is absent the bounded fragment reader falls back to a fail-closed
# stub and every capability fragment reports "could not be read", failing
# the sync. Build the ledger first so fragments materialize.
@@ -199,7 +199,7 @@ jobs:
if: steps.check.outputs.next_exists == 'true'
id: openpr
env:
GH_TOKEN: ${{ secrets.GSD_BOT_PR_TOKEN || secrets.GITHUB_TOKEN }}
GH_TOKEN: ${{ secrets.MSD_BOT_PR_TOKEN || secrets.GITHUB_TOKEN }}
BR: ${{ steps.branch.outputs.branch }}
NEEDS_REVIEW: ${{ steps.branch.outputs.needs_review }}
DROPPED_ONELINE: ${{ steps.branch.outputs.dropped_oneline }}
@@ -246,7 +246,7 @@ jobs:
# must review those before this lands.
if: steps.check.outputs.next_exists == 'true' && steps.branch.outputs.needs_review != 'true'
env:
GH_TOKEN: ${{ secrets.GSD_BOT_PR_TOKEN || secrets.GITHUB_TOKEN }}
GH_TOKEN: ${{ secrets.MSD_BOT_PR_TOKEN || secrets.GITHUB_TOKEN }}
PR: ${{ steps.openpr.outputs.pr }}
run: |
# Merge commit (not squash) preserves main as an ancestor of next.

View File

@@ -126,14 +126,14 @@ jobs:
? 'it does not link an issue'
: 'the linked issue is not approved';
const repoUrl = `${owner}/${repo}`;
const marker = '<!-- gsd-auto-close-unsolicited -->';
const marker = '<!-- msd-auto-close-unsolicited -->';
const message = [
marker,
'## Closing — no pre-approved issue',
'',
`Thanks for your interest in GSD! This PR was closed automatically because ${reason}.`,
`Thanks for your interest in MSD! This PR was closed automatically because ${reason}.`,
'',
'**GSD requires a pre-approved issue before any PR.** The PR must link an issue in this repository that carries a maintainer-applied approval label — `approved-feature`, `approved-enhancement`, or `confirmed-bug`. Opening your own issue or citing an unrelated number is not enough: the label is applied by maintainers after triage.',
'**MSD requires a pre-approved issue before any PR.** The PR must link an issue in this repository that carries a maintainer-applied approval label — `approved-feature`, `approved-enhancement`, or `confirmed-bug`. Opening your own issue or citing an unrelated number is not enough: the label is applied by maintainers after triage.',
'',
'### What to do',
'',

View File

@@ -42,8 +42,8 @@ jobs:
const alwaysValid = ['main', 'next', 'develop'];
if (alwaysValid.includes(branch)) return;
if (branch.startsWith('dependabot/') || branch.startsWith('renovate/')) return;
// GSD auto-created branches
if (branch.startsWith('gsd/') || branch.startsWith('claude/')) return;
// MSD auto-created branches
if (branch.startsWith('msd/') || branch.startsWith('claude/')) return;
const isValid = validPrefixes.some(prefix => branch.startsWith(prefix));
if (!isValid) {

View File

@@ -42,7 +42,7 @@ jobs:
- name: Open a small PR with this run's new records, if any
if: always()
env:
GH_TOKEN: ${{ secrets.GSD_BOT_PR_TOKEN || secrets.GITHUB_TOKEN }}
GH_TOKEN: ${{ secrets.MSD_BOT_PR_TOKEN || secrets.GITHUB_TOKEN }}
RUN_ID: ${{ github.run_id }}
run: |
set -euo pipefail
@@ -50,7 +50,7 @@ jobs:
BR="automation/ci-timeout-report-$RUN_ID"
git checkout -b "$BR"
git add tests/ci-timeout-budget-history.jsonl
git -c user.name="gsd-bot" -c user.email="gsd-bot@users.noreply.github.com" \
git -c user.name="msd-bot" -c user.email="msd-bot@users.noreply.github.com" \
commit -m "chore: CI timeout budget report — run $RUN_ID"
git push origin "$BR"
gh pr create \

View File

@@ -41,7 +41,7 @@ jobs:
'',
'This project only accepts completed pull requests. Draft PRs are automatically closed.',
'',
'**Why?** GSD requires all PRs to be ready for review when opened \u2014 with tests passing, the correct PR template used, and a linked approved issue. Draft PRs bypass these quality gates and create review overhead.',
'**Why?** MSD requires all PRs to be ready for review when opened \u2014 with tests passing, the correct PR template used, and a linked approved issue. Draft PRs bypass these quality gates and create review overhead.',
'',
'### What to do instead',
'',

View File

@@ -47,7 +47,7 @@ jobs:
'',
'This project only accepts completed pull requests. Draft PRs are automatically closed.',
'',
'**Why?** GSD requires all PRs to be ready for review when opened \u2014 with tests passing, the correct PR template used, and a linked approved issue. Draft PRs bypass these quality gates and create review overhead.',
'**Why?** MSD requires all PRs to be ready for review when opened \u2014 with tests passing, the correct PR template used, and a linked approved issue. Draft PRs bypass these quality gates and create review overhead.',
'',
'### What to do instead',
'',

View File

@@ -1,7 +1,7 @@
name: Default Flip Documentation
# DEFECT.DEFAULT-FLIP-DOCUMENTATION (CONTEXT.md): a PR that changes an
# existing default value in gsd-core/bin/shared/config-defaults.manifest.json
# existing default value in msd-core/bin/shared/config-defaults.manifest.json
# must document the migration semantics in a `## Breaking Changes` PR-body
# section (when the new default takes effect, the opt-back-in command,
# effect on in-flight artifacts) — see scripts/lint-default-flip-documentation.cjs

View File

@@ -1,6 +1,6 @@
name: Dependabot Vendor Refresh
# #4573: scripts/lint-vendored-deps.cjs gates gsd-core/bin/lib/vendor/{js-yaml.cjs,re2js.cjs}
# #4573: scripts/lint-vendored-deps.cjs gates msd-core/bin/lib/vendor/{js-yaml.cjs,re2js.cjs}
# for byte-freshness against node_modules, and requires package.json's
# devDependencies pin to literally match the installed version. Dependabot
# regularly opens lockfile-only PRs that bump these packages within the
@@ -29,7 +29,7 @@ name: Dependabot Vendor Refresh
# checkout below pins `ref` to the PR head SHA of that same-repo branch.
#
# Why pushing here is not a bypass of the real check: the push (via
# GSD_BOT_PR_TOKEN, falling back to GITHUB_TOKEN — see
# MSD_BOT_PR_TOKEN, falling back to GITHUB_TOKEN — see
# auto-backmerge.yml's "Open or update PR" step for the same fallback
# pattern) lands a new commit on the PR branch, which re-triggers this
# workflow's own `synchronize` trigger AND the `pull_request: synchronize`
@@ -71,7 +71,7 @@ jobs:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ github.event.pull_request.head.sha }}
token: ${{ secrets.GSD_BOT_PR_TOKEN || secrets.GITHUB_TOKEN }}
token: ${{ secrets.MSD_BOT_PR_TOKEN || secrets.GITHUB_TOKEN }}
persist-credentials: false
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
@@ -101,12 +101,12 @@ jobs:
- name: Commit and push the mechanical refresh
if: steps.fix.outputs.exit_code == '0' && steps.diff.outputs.dirty == 'true'
env:
GH_TOKEN: ${{ secrets.GSD_BOT_PR_TOKEN || secrets.GITHUB_TOKEN }}
GH_TOKEN: ${{ secrets.MSD_BOT_PR_TOKEN || secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add -A -- gsd-core/bin/lib/vendor package.json
git add -A -- msd-core/bin/lib/vendor package.json
git commit -m "chore: refresh vendored deps to match dependency bump"
git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${{ github.repository }}.git"
git push origin HEAD:${{ github.head_ref }}

View File

@@ -1,8 +1,8 @@
name: Install Smoke
# Exercises the real install paths:
# tarball: `npm pack` → `npm install -g <tarball>` → assert gsd-tools on PATH
# unpacked: `npm install -g <dir>` (no pack) → assert gsd-tools on PATH + executable
# tarball: `npm pack` → `npm install -g <tarball>` → assert msd-tools on PATH
# unpacked: `npm install -g <dir>` (no pack) → assert msd-tools on PATH + executable
#
# The tarball path is the canonical ship path. The unpacked path reproduces the
# mode-644 failure class (issue #2453): npm does NOT chmod bin targets when
@@ -20,8 +20,8 @@ on:
- main
paths:
- 'bin/install.js'
- 'gsd-core/bin/gsd-tools.cjs'
- 'gsd-core/bin/**'
- 'msd-core/bin/msd-tools.cjs'
- 'msd-core/bin/**'
- 'src/**'
- 'tsconfig.build.json'
- 'package.json'
@@ -179,35 +179,35 @@ jobs:
TMPDIR_ROOT=$(mktemp -d)
cd "$TMPDIR_ROOT"
npm install -g "$WORKSPACE/$TARBALL"
command -v gsd-core
command -v msd-core
# `--claude --local` is the non-interactive code path. Don't swallow
# non-zero exit — if the installer fails, that IS the CI failure, and
# its own error message is more useful than the downstream "shim
# regression" assertion masking the real cause.
if ! gsd-core --claude --local; then
echo "::error::gsd-core --claude --local failed. See the install.js output above for the real error."
if ! msd-core --claude --local; then
echo "::error::msd-core --claude --local failed. See the install.js output above for the real error."
exit 1
fi
- name: Assert gsd-tools resolves on PATH
- name: Assert msd-tools resolves on PATH
if: steps.skip.outputs.skip != 'true'
run: |
set -euo pipefail
if ! command -v gsd-tools >/dev/null 2>&1; then
echo "::error::gsd-tools is not on PATH after tarball install"
if ! command -v msd-tools >/dev/null 2>&1; then
echo "::error::msd-tools is not on PATH after tarball install"
NPM_BIN="$(npm config get prefix)/bin"
echo "npm global bin: $NPM_BIN"
ls -la "$NPM_BIN" | grep -i gsd || true
ls -la "$NPM_BIN" | grep -i msd || true
exit 1
fi
echo "✓ gsd-tools resolves at: $(command -v gsd-tools)"
echo "✓ msd-tools resolves at: $(command -v msd-tools)"
- name: Assert gsd-tools is executable
- name: Assert msd-tools is executable
if: steps.skip.outputs.skip != 'true'
run: |
set -euo pipefail
gsd-tools --help
echo "✓ gsd-tools is executable"
msd-tools --help
echo "✓ msd-tools is executable"
- name: Lifecycle smoke
if: steps.skip.outputs.skip != 'true'
@@ -276,22 +276,22 @@ jobs:
TMPDIR_ROOT=$(mktemp -d)
cd "$TMPDIR_ROOT"
npm install -g "$GITHUB_WORKSPACE"
command -v gsd-core
gsd-core --claude --local || true
command -v msd-core
msd-core --claude --local || true
- name: Assert gsd-tools resolves on PATH after unpacked install
- name: Assert msd-tools resolves on PATH after unpacked install
run: |
set -euo pipefail
if ! command -v gsd-tools >/dev/null 2>&1; then
echo "::error::gsd-tools is not on PATH after unpacked install"
if ! command -v msd-tools >/dev/null 2>&1; then
echo "::error::msd-tools is not on PATH after unpacked install"
NPM_BIN="$(npm config get prefix)/bin"
for f in "$NPM_BIN"/*gsd* "$NPM_BIN"/*GSD*; do [ -e "$f" ] && ls -la "$f"; done || true
for f in "$NPM_BIN"/*msd* "$NPM_BIN"/*MSD*; do [ -e "$f" ] && ls -la "$f"; done || true
exit 1
fi
echo "✓ gsd-tools resolves at: $(command -v gsd-tools)"
echo "✓ msd-tools resolves at: $(command -v msd-tools)"
- name: Assert gsd-tools is executable after unpacked install
- name: Assert msd-tools is executable after unpacked install
run: |
set -euo pipefail
gsd-tools --help
echo "✓ gsd-tools is executable after unpacked install"
msd-tools --help
echo "✓ msd-tools is executable after unpacked install"

View File

@@ -15,7 +15,7 @@ on:
paths:
# Only run when lib source, property/unit tests, or mutation config change
- 'src/**/*.cts'
- 'gsd-core/bin/lib/**/*.cjs'
- 'msd-core/bin/lib/**/*.cjs'
- 'tests/**/*.property.test.cjs'
- 'tests/**/*.unit.test.cjs'
- 'tests/adr-parser.test.cjs'

View File

@@ -37,7 +37,7 @@ jobs:
# (https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#multiline-strings).
# The length-vs-total check in the policy (fileListIsComplete) is
# the second, independent layer.
delim="GSD_EOF_$(openssl rand -hex 16)"
delim="MSD_EOF_$(openssl rand -hex 16)"
files=$(gh pr view "$PR_NUMBER" --repo "$GITHUB_REPOSITORY" --json files --jq '.files[].path')
echo "files<<$delim" >> "$GITHUB_OUTPUT"
echo "$files" >> "$GITHUB_OUTPUT"
@@ -57,7 +57,7 @@ jobs:
uses: actions/github-script@d746ffe35508b1917358783b479e04febd2b8f71 # v9.0.0
with:
script: |
const marker = '<!-- gsd-pr-template-policy -->';
const marker = '<!-- msd-pr-template-policy -->';
const pr = context.payload.pull_request;
const policy = JSON.parse(${{ toJSON(steps.policy.outputs.result) }});
const comments = await github.paginate(github.rest.issues.listComments, {
@@ -90,7 +90,7 @@ jobs:
uses: actions/github-script@d746ffe35508b1917358783b479e04febd2b8f71 # v9.0.0
with:
script: |
const marker = '<!-- gsd-pr-template-policy -->';
const marker = '<!-- msd-pr-template-policy -->';
const pr = context.payload.pull_request;
const repoUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}`;
const policy = JSON.parse(${{ toJSON(steps.policy.outputs.result) }});

View File

@@ -96,7 +96,7 @@ jobs:
env:
VERSION: ${{ inputs.version }}
run: |
for pkg in @opengsd/gsd-core; do
for pkg in @golem15/msd-core; do
if npm view "$pkg@$VERSION" version >/dev/null 2>&1; then
echo "::error::$pkg@$VERSION is already published on npm — bump to a new version"
exit 1
@@ -458,7 +458,7 @@ jobs:
path: coverage/tmp
merge-multiple: true
- name: Report merged coverage + gate gsd-core/bin/lib (≥70% lines, ≥60% branches)
- name: Report merged coverage + gate msd-core/bin/lib (≥70% lines, ≥60% branches)
env:
NODE_OPTIONS: --max-old-space-size=8192
run: npm run test:coverage:report
@@ -614,13 +614,13 @@ jobs:
if: ${{ !inputs.dry_run }}
env:
PRE_VERSION: ${{ steps.prerelease.outputs.pre_version }}
run: node scripts/verify-npm-publish.cjs --package @opengsd/gsd-core --version "$PRE_VERSION" --dist-tag next
run: node scripts/verify-npm-publish.cjs --package @golem15/msd-core --version "$PRE_VERSION" --dist-tag next
- name: Sync next branch to the published pre-release
if: ${{ !inputs.dry_run }}
continue-on-error: true
env:
GH_TOKEN: ${{ secrets.GSD_BOT_PR_TOKEN || secrets.GITHUB_TOKEN }}
GH_TOKEN: ${{ secrets.MSD_BOT_PR_TOKEN || secrets.GITHUB_TOKEN }}
PRE_VERSION: ${{ steps.prerelease.outputs.pre_version }}
run: node scripts/sync-next-version.cjs "$PRE_VERSION"
@@ -634,7 +634,7 @@ jobs:
echo "**DRY RUN** — npm publish, tagging, and push skipped" >> "$GITHUB_STEP_SUMMARY"
else
echo "- Published to npm as \`next\`" >> "$GITHUB_STEP_SUMMARY"
echo "- Install: \`npx @opengsd/gsd-core@next\`" >> "$GITHUB_STEP_SUMMARY"
echo "- Install: \`npx @golem15/msd-core@next\`" >> "$GITHUB_STEP_SUMMARY"
fi
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "To publish another pre-release: run \`rc\` again" >> "$GITHUB_STEP_SUMMARY"
@@ -733,7 +733,7 @@ jobs:
path: coverage/tmp
merge-multiple: true
- name: Report merged coverage + gate gsd-core/bin/lib (≥70% lines, ≥60% branches)
- name: Report merged coverage + gate msd-core/bin/lib (≥70% lines, ≥60% branches)
env:
NODE_OPTIONS: --max-old-space-size=8192
run: npm run test:coverage:report
@@ -818,7 +818,7 @@ jobs:
if: ${{ !inputs.dry_run }}
continue-on-error: true
env:
GH_TOKEN: ${{ secrets.GSD_BOT_PR_TOKEN || secrets.GITHUB_TOKEN }}
GH_TOKEN: ${{ secrets.MSD_BOT_PR_TOKEN || secrets.GITHUB_TOKEN }}
BRANCH: ${{ needs.validate-version.outputs.branch }}
VERSION: ${{ inputs.version }}
run: |
@@ -900,7 +900,7 @@ jobs:
if: ${{ !inputs.dry_run }}
env:
VERSION: ${{ inputs.version }}
run: node scripts/verify-npm-publish.cjs --package @opengsd/gsd-core --version "$VERSION" --dist-tag latest
run: node scripts/verify-npm-publish.cjs --package @golem15/msd-core --version "$VERSION" --dist-tag latest
# Auto-merge the release/hotfix → main PR when it is cleanly mergeable, so
# the release's own branch lands on `main` without a manual merge click
@@ -915,7 +915,7 @@ jobs:
if: ${{ !inputs.dry_run }}
continue-on-error: true
env:
GH_TOKEN: ${{ secrets.GSD_BOT_PR_TOKEN || secrets.GITHUB_TOKEN }}
GH_TOKEN: ${{ secrets.MSD_BOT_PR_TOKEN || secrets.GITHUB_TOKEN }}
BRANCH: ${{ needs.validate-version.outputs.branch }}
run: |
set -uo pipefail
@@ -949,14 +949,14 @@ jobs:
# releases, not just rc/hotfix. Without this, `next` drifts to whatever
# rc.N the release branch forked from, and every npm script banner on
# `next` (and feature branches cut from it) reports the stale rc version
# — e.g. `lint:ci` reported `@opengsd/gsd-core@1.7.0-rc.6` after 1.7.0
# — e.g. `lint:ci` reported `@golem15/msd-core@1.7.0-rc.6` after 1.7.0
# shipped. Mirrors the rc job's sync step at line ~479. Idempotent: a
# no-op when `next` is already at the target version.
- name: Sync next branch to the published release
if: ${{ !inputs.dry_run }}
continue-on-error: true
env:
GH_TOKEN: ${{ secrets.GSD_BOT_PR_TOKEN || secrets.GITHUB_TOKEN }}
GH_TOKEN: ${{ secrets.MSD_BOT_PR_TOKEN || secrets.GITHUB_TOKEN }}
VERSION: ${{ inputs.version }}
run: node scripts/sync-next-version.cjs "$VERSION"
@@ -972,5 +972,5 @@ jobs:
echo "- Published to npm as \`latest\`" >> "$GITHUB_STEP_SUMMARY"
echo "- Tagged \`v${VERSION}\`" >> "$GITHUB_STEP_SUMMARY"
echo "- PR created to merge back to main" >> "$GITHUB_STEP_SUMMARY"
echo "- Install: \`npx @opengsd/gsd-core@latest\`" >> "$GITHUB_STEP_SUMMARY"
echo "- Install: \`npx @golem15/msd-core@latest\`" >> "$GITHUB_STEP_SUMMARY"
fi

View File

@@ -80,14 +80,14 @@ jobs:
run: |
# The delimiter must be unguessable: every path in `files` is
# attacker-controlled on a fork PR, and a file named after a fixed
# delimiter (e.g. a file literally named `GSD_EOF`) would terminate
# delimiter (e.g. a file literally named `MSD_EOF`) would terminate
# the heredoc value early, truncating everything after it — this is
# GitHub's own documented guidance for untrusted multiline output
# (https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#multiline-strings).
# The length-vs-total check in the policy (fileListIsComplete) is
# the second, independent layer: even if a delimiter collision slid
# past this, a truncated or inflated list would still fail closed.
delim="GSD_EOF_$(openssl rand -hex 16)"
delim="MSD_EOF_$(openssl rand -hex 16)"
files=$(gh pr view "$PR_NUMBER" --repo "$GITHUB_REPOSITORY" --json files --jq '.files[].path')
{
echo "files<<$delim"
@@ -147,7 +147,7 @@ jobs:
with:
# Uses GitHub API SDK — no shell string interpolation of untrusted input
script: |
const marker = '<!-- gsd-require-issue-link -->';
const marker = '<!-- msd-require-issue-link -->';
const repoUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}`;
const prNumber = context.payload.pull_request.number;
// #3211: the verdict is a typed reason, so the guidance can name the

View File

@@ -8,7 +8,7 @@ on:
- 'release/**'
- 'hotfix/**'
paths:
- 'gsd-core/**'
- 'msd-core/**'
- 'agents/**'
- 'commands/**'
- 'hooks/**'
@@ -75,7 +75,7 @@ jobs:
BASE_REF: ${{ github.base_ref }}
run: |
chmod +x scripts/prompt-injection-scan.sh
. gsd-core/bin/shared/exit-codes.sh
. msd-core/bin/shared/exit-codes.sh
set +e
scripts/prompt-injection-scan.sh --diff "origin/$BASE_REF"
code=$?
@@ -91,7 +91,7 @@ jobs:
BASE_REF: ${{ github.base_ref }}
run: |
chmod +x scripts/base64-scan.sh
. gsd-core/bin/shared/exit-codes.sh
. msd-core/bin/shared/exit-codes.sh
set +e
scripts/base64-scan.sh --diff "origin/$BASE_REF"
code=$?
@@ -107,7 +107,7 @@ jobs:
BASE_REF: ${{ github.base_ref }}
run: |
chmod +x scripts/secret-scan.sh
. gsd-core/bin/shared/exit-codes.sh
. msd-core/bin/shared/exit-codes.sh
set +e
scripts/secret-scan.sh --diff "origin/$BASE_REF"
code=$?
@@ -128,7 +128,7 @@ jobs:
BASE_REF: ${{ github.base_ref }}
run: |
# Ensure .planning/ runtime data is not committed in PRs
# (The GSD repo itself has .planning/ in .gitignore, but PRs
# (The MSD repo itself has .planning/ in .gitignore, but PRs
# from forks or misconfigured clones might include it)
PLANNING_FILES=$(git diff --name-only --diff-filter=ACMR "origin/$BASE_REF"...HEAD | grep '^\.planning/' || true)
if [ -n "$PLANNING_FILES" ]; then

View File

@@ -25,13 +25,13 @@ jobs:
stale-issue-message: >
This issue has been inactive for 28 days. It will be closed in 14 days
if there is no further activity. If this is still relevant, please comment
or update to the latest GSD version and retest.
or update to the latest MSD version and retest.
stale-pr-message: >
This PR has been inactive for 28 days. It will be closed in 14 days
if there is no further activity.
close-issue-message: >
Closed due to inactivity. If this is still relevant, please reopen
with updated reproduction steps on the latest GSD version.
with updated reproduction steps on the latest MSD version.
stale-issue-label: 'stale'
stale-pr-label: 'stale'
exempt-issue-labels: 'fix-pending,priority: critical,pinned,confirmed-bug,confirmed,awaiting-retest,needs-reproduction'
@@ -51,12 +51,12 @@ jobs:
remove-stale-when-updated: true
stale-issue-message: >
Closing — we asked for a retest / reproduction more than 5 days ago and
haven't heard back. If this is still happening on the latest GSD version
haven't heard back. If this is still happening on the latest MSD version
you are welcome to open a new issue with the requested information.
We expect follow-up to maintainer requests within a reasonable window or
we close to keep the tracker actionable.
close-issue-message: >
Closed (not planned) — reporter did not respond within 5 days of our
retest / reproduction request. Re-open with the requested information,
or file a new issue if it still affects you on the latest GSD version.
or file a new issue if it still affects you on the latest MSD version.
exempt-issue-labels: 'pinned,priority: critical,fix-pending'

View File

@@ -209,7 +209,7 @@ jobs:
env:
# #2665 round 4: every job that runs the suite wires the strict guard
# (job-level env, where the live-config-guard derivation reads it).
GSD_STRICT_LIVE_CONFIG_GUARD: '1'
MSD_STRICT_LIVE_CONFIG_GUARD: '1'
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
@@ -266,14 +266,14 @@ jobs:
# headroom factor over its own measured cost.
timeout-minutes: 32
env:
GSD_PLUGIN_ROOT: .ci-gsd-plugin-root-disabled
MSD_PLUGIN_ROOT: .ci-msd-plugin-root-disabled
# #2665 / #4641: this job's matrix is ubuntu-only as of #4641 (the
# `scope: windows` rows moved to test-conformance, see the timeout
# comment above), so the live-config leak guard is strict unconditionally
# here. The Windows report-only carve-out (PRE-EXISTING USERPROFILE leaks,
# ~190 test sites sandbox HOME alone) now lives solely on jobs.test-conformance
# — promote it there once that sweep lands (see live-config-guard.cjs SEVERITY).
GSD_STRICT_LIVE_CONFIG_GUARD: '1'
MSD_STRICT_LIVE_CONFIG_GUARD: '1'
# #2854: pin the emitted gate's baseline to the SAME commit the tree was merged
# with. "Rebase check" merges `pull_request.base.sha` (pinned by #2472 so all 12
# matrix jobs agree on one tree), but `resolveBase()` otherwise falls through to
@@ -282,8 +282,8 @@ jobs:
# baseline at a newer commit — so the correctly-keyed cache was rejected as
# "stale" and the run hard-failed on diffs that touched nothing related.
# This must stay equal to CI_REBASE_BASE_SHA; a test asserts that parity.
GSD_EMITTED_BASE: ${{ github.event.pull_request.base.sha }}
# #4196: pin the npm-audit baseline the SAME way GSD_EMITTED_BASE pins
MSD_EMITTED_BASE: ${{ github.event.pull_request.base.sha }}
# #4196: pin the npm-audit baseline the SAME way MSD_EMITTED_BASE pins
# its own baseline (see the comment above) -- origin/next is live under
# fetch-depth: 0 and can advance mid-run; base.sha is fixed for the life
# of the run. For a push event, github.event.before is git's own record
@@ -409,7 +409,7 @@ jobs:
#
# #2854: the restore lands on resolveBaseline()'s DEFAULT_CACHE_PATH, so it is
# found without being announced. There used to be a step that published this
# path to GSD_EMITTED_BASELINE — an OPERATOR PIN, where any rejection is a hard
# path to MSD_EMITTED_BASELINE — an OPERATOR PIN, where any rejection is a hard
# stop rather than a fall-through. That converted every recoverable condition
# (stale, malformed, wrong schema version) into a fatal CI failure on diffs that
# touched nothing related. Restoring to the default path and saying nothing lets
@@ -418,7 +418,7 @@ jobs:
if: github.event_name == 'pull_request'
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: .gsd-cache/emitted-baseline.json
path: .msd-cache/emitted-baseline.json
key: emitted-baseline-${{ github.event.pull_request.base.sha }}
- name: Prepare scoped test list
@@ -457,7 +457,7 @@ jobs:
# `scope: targeted` lane runs no aux suite on its own, so this
# must stay empty there. tests/ci-full-lane-sharding.test.cjs pins both
# halves of this contract. Reserve-value derivation:
# .gsd/bug/fix-4070-shard1-aux-suite-budget/10-diagnosis.md.
# .msd/bug/fix-4070-shard1-aux-suite-budget/10-diagnosis.md.
RUN_TESTS_SHARD_RESERVE: ${{ matrix.scope == 'full' && '1:77' || '' }}
run: npm run test:coverage:unit:raw -- --shard ${{ matrix.shard }}
@@ -509,14 +509,14 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 15
env:
GSD_PLUGIN_ROOT: .ci-gsd-plugin-root-disabled
MSD_PLUGIN_ROOT: .ci-msd-plugin-root-disabled
# #2665: ubuntu-only lane — strict unconditionally (see the `test` job note).
GSD_STRICT_LIVE_CONFIG_GUARD: '1'
MSD_STRICT_LIVE_CONFIG_GUARD: '1'
# #2854: same pin as the other rebase-merged lanes. This lane runs a targeted
# list that can include the emitted gate, and the invariant is easier to keep
# with no exceptions: if a job merges a pinned base, the gate uses that base.
GSD_EMITTED_BASE: ${{ github.event.pull_request.base.sha }}
# #4196: pin the npm-audit baseline the SAME way GSD_EMITTED_BASE pins
MSD_EMITTED_BASE: ${{ github.event.pull_request.base.sha }}
# #4196: pin the npm-audit baseline the SAME way MSD_EMITTED_BASE pins
# its own baseline (see the comment above) -- origin/next is live under
# fetch-depth: 0 and can advance mid-run; base.sha is fixed for the life
# of the run. For a push event, github.event.before is git's own record
@@ -601,9 +601,9 @@ jobs:
# should comfortably undercut this ceiling.
timeout-minutes: 45
env:
GSD_PLUGIN_ROOT: .ci-gsd-plugin-root-disabled
GSD_STRICT_LIVE_CONFIG_GUARD: ${{ matrix.os != 'windows-latest' && '1' || '' }}
GSD_EMITTED_BASE: ${{ github.event.pull_request.base.sha }}
MSD_PLUGIN_ROOT: .ci-msd-plugin-root-disabled
MSD_STRICT_LIVE_CONFIG_GUARD: ${{ matrix.os != 'windows-latest' && '1' || '' }}
MSD_EMITTED_BASE: ${{ github.event.pull_request.base.sha }}
AUDIT_BASELINE_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || (github.event_name == 'push' && github.event.before) || (github.event_name == 'merge_group' && github.event.merge_group.base_sha) || '' }}
strategy:
fail-fast: false
@@ -672,7 +672,7 @@ jobs:
if: github.event_name == 'pull_request'
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: .gsd-cache/emitted-baseline.json
path: .msd-cache/emitted-baseline.json
key: emitted-baseline-${{ github.event.pull_request.base.sha }}
# #4591: the generated conformance-tier list is a .cjs module (so
@@ -752,7 +752,7 @@ jobs:
# with headroom to spare on the 16GB ubuntu-latest runner. This is a
# memory bound only — it does not change what is measured or the
# thresholds below.
- name: Report merged coverage + gate gsd-core/bin/lib (≥70% lines, ≥60% branches)
- name: Report merged coverage + gate msd-core/bin/lib (≥70% lines, ≥60% branches)
env:
NODE_OPTIONS: --max-old-space-size=8192
run: npm run test:coverage:report
@@ -782,7 +782,7 @@ jobs:
# #2966: turns a loop QA-walk "smell" into a decision — see
# scripts/qa-smell-ratchet.cjs's own header for the full design invariant.
# Gated the same way as `test`/`coverage-gate` (product_changed only): the
# scenarios drive the real gsd-tools binary end-to-end, so there is nothing
# scenarios drive the real msd-tools binary end-to-end, so there is nothing
# to walk on a docs-only change.
qa-loop-walk:
name: QA loop walk (smell ratchet)
@@ -791,11 +791,11 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 15
env:
GSD_PLUGIN_ROOT: .ci-gsd-plugin-root-disabled
MSD_PLUGIN_ROOT: .ci-msd-plugin-root-disabled
# `npm run test:qa` is `run-tests.cjs --suite qa`, so this lane runs the
# live-config guard like every other suite lane. ubuntu-only, so strict
# unconditionally — the Windows carve-out does not apply here.
GSD_STRICT_LIVE_CONFIG_GUARD: '1'
MSD_STRICT_LIVE_CONFIG_GUARD: '1'
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
@@ -821,7 +821,7 @@ jobs:
- name: Dependency integrity gate
run: node scripts/check-npm-integrity.cjs
- name: Build runtime lib (required by the QA walk's gsd-tools invocations)
- name: Build runtime lib (required by the QA walk's msd-tools invocations)
run: npm run build:lib
- name: Run QA loop-walk scenarios
@@ -988,10 +988,10 @@ jobs:
run: npm ci
- name: Build emitted-baseline artifact
run: node scripts/gen-emitted-baseline.cjs --out .gsd-cache/emitted-baseline.json
run: node scripts/gen-emitted-baseline.cjs --out .msd-cache/emitted-baseline.json
- name: Publish baseline cache (keyed on this sha)
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: .gsd-cache/emitted-baseline.json
path: .msd-cache/emitted-baseline.json
key: emitted-baseline-${{ github.sha }}

492
.gitignore vendored
View File

@@ -36,23 +36,23 @@ reports/
RAILROAD_ARCHITECTURE.md
.planning/
analysis/
docs/GSD-MASTER-ARCHITECTURE.md
docs/GSD-RUST-IMPLEMENTATION-GUIDE.md
docs/GSD-SYSTEM-SPECIFICATION.md
docs/MSD-MASTER-ARCHITECTURE.md
docs/MSD-RUST-IMPLEMENTATION-GUIDE.md
docs/MSD-SYSTEM-SPECIFICATION.md
gaps.md
improve.md
philosophy.md
# Installed skills
.github/agents/gsd-*
.github/skills/gsd-*
.github/gsd-core/*
.github/skills/gsd-core
.github/agents/msd-*
.github/skills/msd-*
.github/msd-core/*
.github/skills/msd-core
.github/copilot-instructions.md
.bg-shell/
# ── GSD baseline (auto-generated) ──
.gsd
# ── MSD baseline (auto-generated) ──
.msd
Thumbs.db
*.swp
*.swo
@@ -71,253 +71,253 @@ build/
# by `npm run build:lib`). Source of truth is src/; these are emitted, never edited.
# Published via prepublishOnly; built before test via pretest. Grows as modules migrate.
/tsconfig.build.tsbuildinfo
/gsd-core/bin/lib/commonjs-marker.cjs
/gsd-core/bin/lib/broken-windows.cjs
/gsd-core/bin/lib/complexity-trigger.cjs
/gsd-core/bin/lib/refactor-trigger-command-router.cjs
/gsd-core/bin/lib/host-integration.cjs
/gsd-core/bin/lib/host-integration-sdk.cjs
/gsd-core/bin/lib/host-integration-adapters/imperative-hook-bus.cjs
/gsd-core/bin/lib/host-integration-adapters/cline-sdk-binding.cjs
/gsd-core/bin/lib/handshake-serialized.cjs
/gsd-core/bin/lib/install-effort-resolver.cjs
/gsd-core/bin/lib/install-model-override-resolver.cjs
/gsd-core/bin/lib/install-engine.cjs
/gsd-core/bin/lib/real-home-guard.cjs
/gsd-core/bin/lib/embedding-adapter.cjs
/gsd-core/bin/lib/adapter-declarative.cjs
/gsd-core/bin/lib/adapter-imperative.cjs
/gsd-core/bin/lib/model-adapter.cjs
/gsd-core/bin/lib/hook-bus.cjs
/gsd-core/bin/lib/state-io.cjs
/gsd-core/bin/lib/mcp-server.cjs
/gsd-core/bin/lib/mcp-catalog.cjs
/gsd-core/bin/lib/external-descriptor-trust.cjs
/gsd-core/bin/lib/cli-skew-check.cjs
/gsd-core/bin/lib/context-composer.cjs
/gsd-core/bin/lib/context-predicates.cjs
/gsd-core/bin/lib/workflow-fragments.cjs
/gsd-core/bin/lib/section-manifest.cjs
/gsd-core/bin/lib/capability-loader.cjs
/gsd-core/bin/lib/capability-source.cjs
/gsd-core/bin/lib/capability-ledger.cjs
/gsd-core/bin/lib/capability-trust.cjs
/gsd-core/bin/lib/capability-lifecycle.cjs
/gsd-core/bin/lib/capability-consent.cjs
/gsd-core/bin/lib/capability-lock.cjs
/gsd-core/bin/lib/markdown-sectionizer.cjs
/msd-core/bin/lib/commonjs-marker.cjs
/msd-core/bin/lib/broken-windows.cjs
/msd-core/bin/lib/complexity-trigger.cjs
/msd-core/bin/lib/refactor-trigger-command-router.cjs
/msd-core/bin/lib/host-integration.cjs
/msd-core/bin/lib/host-integration-sdk.cjs
/msd-core/bin/lib/host-integration-adapters/imperative-hook-bus.cjs
/msd-core/bin/lib/host-integration-adapters/cline-sdk-binding.cjs
/msd-core/bin/lib/handshake-serialized.cjs
/msd-core/bin/lib/install-effort-resolver.cjs
/msd-core/bin/lib/install-model-override-resolver.cjs
/msd-core/bin/lib/install-engine.cjs
/msd-core/bin/lib/real-home-guard.cjs
/msd-core/bin/lib/embedding-adapter.cjs
/msd-core/bin/lib/adapter-declarative.cjs
/msd-core/bin/lib/adapter-imperative.cjs
/msd-core/bin/lib/model-adapter.cjs
/msd-core/bin/lib/hook-bus.cjs
/msd-core/bin/lib/state-io.cjs
/msd-core/bin/lib/mcp-server.cjs
/msd-core/bin/lib/mcp-catalog.cjs
/msd-core/bin/lib/external-descriptor-trust.cjs
/msd-core/bin/lib/cli-skew-check.cjs
/msd-core/bin/lib/context-composer.cjs
/msd-core/bin/lib/context-predicates.cjs
/msd-core/bin/lib/workflow-fragments.cjs
/msd-core/bin/lib/section-manifest.cjs
/msd-core/bin/lib/capability-loader.cjs
/msd-core/bin/lib/capability-source.cjs
/msd-core/bin/lib/capability-ledger.cjs
/msd-core/bin/lib/capability-trust.cjs
/msd-core/bin/lib/capability-lifecycle.cjs
/msd-core/bin/lib/capability-consent.cjs
/msd-core/bin/lib/capability-lock.cjs
/msd-core/bin/lib/markdown-sectionizer.cjs
# #3311: new module (milestone lock) — emitted artifact, never edited.
/gsd-core/bin/lib/milestone-lock.cjs
/msd-core/bin/lib/milestone-lock.cjs
# #2657: these two (markdown-table.cjs, write-set.cjs) already had the
# pattern below since #2248, but stayed tracked because `git rm --cached`
# was never run — same untracking fix as the seven lines that follow.
/gsd-core/bin/lib/markdown-table.cjs
/gsd-core/bin/lib/write-set.cjs
/msd-core/bin/lib/markdown-table.cjs
/msd-core/bin/lib/write-set.cjs
# #2657: ADR-457 migration gap — these seven (of nine total; the two above
# are the other two) never got a .gitignore entry when their modules moved
# into src/*.cts, and were also never untracked.
/gsd-core/bin/lib/api-coverage.cjs
/gsd-core/bin/lib/assumption-delta.cjs
/gsd-core/bin/lib/claude-orchestration.cjs
/gsd-core/bin/lib/claude-orchestration-command-router.cjs
/gsd-core/bin/lib/external-job.cjs
/gsd-core/bin/lib/runtime-artifact-install-plan.cjs
/gsd-core/bin/lib/state-transition.cjs
/msd-core/bin/lib/api-coverage.cjs
/msd-core/bin/lib/assumption-delta.cjs
/msd-core/bin/lib/claude-orchestration.cjs
/msd-core/bin/lib/claude-orchestration-command-router.cjs
/msd-core/bin/lib/external-job.cjs
/msd-core/bin/lib/runtime-artifact-install-plan.cjs
/msd-core/bin/lib/state-transition.cjs
# #3873: schema leaf module (ADR-3473 §8.8) — emitted artifact, never edited.
/gsd-core/bin/lib/state-md-schema.cjs
/gsd-core/bin/lib/resolution.cjs
/gsd-core/bin/lib/research-store.cjs
/gsd-core/bin/lib/research-provider.cjs
/gsd-core/bin/lib/package-legitimacy.cjs
/gsd-core/bin/lib/semver-compare.cjs
/gsd-core/bin/lib/plan-drift-guard.cjs
/gsd-core/bin/lib/edge-probe.cjs
/gsd-core/bin/lib/probe-core.cjs
/gsd-core/bin/lib/spec-section.cjs
/gsd-core/bin/lib/prohibition-enforcement.cjs
/gsd-core/bin/lib/ui-consideration-probe.cjs
/gsd-core/bin/lib/config-types.cjs
/gsd-core/bin/lib/cli-exit.cjs
/msd-core/bin/lib/state-md-schema.cjs
/msd-core/bin/lib/resolution.cjs
/msd-core/bin/lib/research-store.cjs
/msd-core/bin/lib/research-provider.cjs
/msd-core/bin/lib/package-legitimacy.cjs
/msd-core/bin/lib/semver-compare.cjs
/msd-core/bin/lib/plan-drift-guard.cjs
/msd-core/bin/lib/edge-probe.cjs
/msd-core/bin/lib/probe-core.cjs
/msd-core/bin/lib/spec-section.cjs
/msd-core/bin/lib/prohibition-enforcement.cjs
/msd-core/bin/lib/ui-consideration-probe.cjs
/msd-core/bin/lib/config-types.cjs
/msd-core/bin/lib/cli-exit.cjs
# #4145: emitted artifact of src/pristine-baseline.cts — never edited.
/gsd-core/bin/lib/pristine-baseline.cjs
/gsd-core/bin/lib/code-review-flags.cjs
/gsd-core/bin/lib/code-review-depth.cjs
/gsd-core/bin/lib/context-utilization.cjs
/gsd-core/bin/lib/artifacts.cjs
/gsd-core/bin/lib/command-arg-projection.cjs
/gsd-core/bin/lib/clock.cjs
/gsd-core/bin/lib/ui-safety-gate.cjs
/gsd-core/bin/lib/ui-frontend-evidence.cjs
/gsd-core/bin/lib/review-reviewer-selection.cjs
/gsd-core/bin/lib/review-lane-descriptor.cjs
/gsd-core/bin/lib/review-lane-invocation.cjs
/gsd-core/bin/lib/review-lane-runner.cjs
/gsd-core/bin/lib/reviewer-step-dispatch.cjs
/gsd-core/bin/lib/clusters.cjs
/gsd-core/bin/lib/installer-migrations/001-legacy-orphan-files.cjs
/gsd-core/bin/lib/observability/redaction.cjs
/gsd-core/bin/lib/installer-migration-report.cjs
/gsd-core/bin/lib/prompt-budget.cjs
/gsd-core/bin/lib/secrets.cjs
/gsd-core/bin/lib/smart-entry.cjs
/gsd-core/bin/lib/phase-lifecycle.cjs
/gsd-core/bin/lib/workstream-name-policy.cjs
/gsd-core/bin/lib/decisions.cjs
/gsd-core/bin/lib/teams-status.cjs
/gsd-core/bin/lib/validate.cjs
/gsd-core/bin/lib/schema-detect.cjs
/gsd-core/bin/lib/runtime-name-policy.cjs
/gsd-core/bin/lib/runtime-identity.cjs
/gsd-core/bin/lib/runtime-slash.cjs
/gsd-core/bin/lib/observability/event.cjs
/gsd-core/bin/lib/workstream-inventory-builder.cjs
/gsd-core/bin/lib/plan-scan.cjs
/gsd-core/bin/lib/fallow-runner.cjs
/gsd-core/bin/lib/project-root.cjs
/gsd-core/bin/lib/installer-migration-authoring.cjs
/gsd-core/bin/lib/update-context.cjs
/gsd-core/bin/lib/installer-migrations/000-first-time-baseline.cjs
/gsd-core/bin/lib/installer-migrations/008-cursor-retire-commands-surface.cjs
/gsd-core/bin/lib/retired-artifact-cleanup.cjs
/gsd-core/bin/lib/runtime-homes.cjs
/gsd-core/bin/lib/model-catalog.cjs
/gsd-core/bin/lib/configuration.cjs
/gsd-core/bin/lib/state-document.cjs
/gsd-core/bin/lib/shell-command-projection.cjs
/gsd-core/bin/lib/security.cjs
/gsd-core/bin/lib/verification.cjs
/gsd-core/bin/lib/verification-command-router.cjs
/gsd-core/bin/lib/command-aliases.cjs
/gsd-core/bin/lib/config-schema.cjs
/gsd-core/bin/lib/model-profiles.cjs
/gsd-core/bin/lib/installer-migrations/002-codex-legacy-hooks-json.cjs
/gsd-core/bin/lib/installer-migrations/003-rename-get-shit-done-to-gsd-core.cjs
/gsd-core/bin/lib/installer-migrations/004-prune-stale-pristine-snapshots.cjs
/gsd-core/bin/lib/installer-migrations/005-opencode-baseline-commands-dir.cjs
/gsd-core/bin/lib/installer-migrations/006-pi-extension-cjs-to-js.cjs
/gsd-core/bin/lib/installer-migrations/007-retire-config-root-commonjs-marker.cjs
/gsd-core/bin/lib/installer-migrations/009-pi-retire-reserved-hooks-dir.cjs
/gsd-core/bin/lib/installer-migrations/010-antigravity-retire-confighome-artifacts.cjs
/gsd-core/bin/lib/observability/logger.cjs
/gsd-core/bin/lib/active-workstream-store.cjs
/gsd-core/bin/lib/adr-parser.cjs
/gsd-core/bin/lib/graphify.cjs
/gsd-core/bin/lib/graphify-command-router.cjs
/gsd-core/bin/lib/audit-command-router.cjs
/gsd-core/bin/lib/intel-command-router.cjs
/gsd-core/bin/lib/install-profiles.cjs
/gsd-core/bin/lib/intel.cjs
/gsd-core/bin/lib/installer-migrations.cjs
/gsd-core/bin/lib/worktree-base-ref.cjs
/gsd-core/bin/lib/worktree-safety.cjs
/gsd-core/bin/lib/planning-workspace.cjs
/gsd-core/bin/lib/planning-scope.cjs
/gsd-core/bin/lib/planning-snapshot.cjs
/gsd-core/bin/lib/planning-document.cjs
/gsd-core/bin/lib/planning-inspect.cjs
/gsd-core/bin/lib/planning-command-router.cjs
/gsd-core/bin/lib/plan-document.cjs
/gsd-core/bin/lib/state-contract.cjs
/gsd-core/bin/lib/pattern.cjs
/gsd-core/bin/lib/text-lines.cjs
/gsd-core/bin/lib/token-scanner.cjs
/gsd-core/bin/lib/health-diagnostic-types.cjs
/gsd-core/bin/lib/health-diagnostic.cjs
/gsd-core/bin/lib/health-diagnostic-rules/root-existence.cjs
/gsd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs
/gsd-core/bin/lib/health-diagnostic-rules/config-validation.cjs
/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs
/gsd-core/bin/lib/health-diagnostic-rules/agent-install.cjs
/gsd-core/bin/lib/health-diagnostic-rules/roadmap-disk-consistency.cjs
/gsd-core/bin/lib/health-diagnostic-rules/worktree-health.cjs
/gsd-core/bin/lib/health-diagnostic-rules/milestone-archive-hygiene.cjs
/gsd-core/bin/lib/health-diagnostic-rules/consistency.cjs
/gsd-core/bin/lib/health-diagnostic-rules/install-surface-shadowing.cjs
/gsd-core/bin/lib/command-roster.cjs
/gsd-core/bin/lib/runtime-artifact-conversion.cjs
/gsd-core/bin/lib/runtime-artifact-layout.cjs
/gsd-core/bin/lib/install-scope.cjs
/gsd-core/bin/lib/install-fs-adapter.cjs
/gsd-core/bin/lib/user-artifact-staging.cjs
/gsd-core/bin/lib/installed-surface-resolver.cjs
/gsd-core/bin/lib/install-shadow-report.cjs
/gsd-core/bin/lib/runtime-config-adapter-registry.cjs
/gsd-core/bin/lib/runtime-hooks-surface.cjs
/gsd-core/bin/lib/command-routing-hub.cjs
/gsd-core/bin/lib/core-utils.cjs
/gsd-core/bin/lib/io.cjs
/gsd-core/bin/lib/phase-id.cjs
/gsd-core/bin/lib/phase-id-card.cjs
/gsd-core/bin/lib/phase-id-display.cjs
/gsd-core/bin/lib/normalize-test-command.cjs
/gsd-core/bin/lib/config-loader.cjs
/gsd-core/bin/lib/unusable-input.cjs
/gsd-core/bin/lib/model-resolver.cjs
/gsd-core/bin/lib/loop-resolver.cjs
/gsd-core/bin/lib/capability-state.cjs
/gsd-core/bin/lib/capability-writer.cjs
/gsd-core/bin/lib/capability-activation.cjs
/gsd-core/bin/lib/federated-config.cjs
/gsd-core/bin/lib/phase-locator.cjs
/gsd-core/bin/lib/plan-dependency-graph.cjs
/msd-core/bin/lib/pristine-baseline.cjs
/msd-core/bin/lib/code-review-flags.cjs
/msd-core/bin/lib/code-review-depth.cjs
/msd-core/bin/lib/context-utilization.cjs
/msd-core/bin/lib/artifacts.cjs
/msd-core/bin/lib/command-arg-projection.cjs
/msd-core/bin/lib/clock.cjs
/msd-core/bin/lib/ui-safety-gate.cjs
/msd-core/bin/lib/ui-frontend-evidence.cjs
/msd-core/bin/lib/review-reviewer-selection.cjs
/msd-core/bin/lib/review-lane-descriptor.cjs
/msd-core/bin/lib/review-lane-invocation.cjs
/msd-core/bin/lib/review-lane-runner.cjs
/msd-core/bin/lib/reviewer-step-dispatch.cjs
/msd-core/bin/lib/clusters.cjs
/msd-core/bin/lib/installer-migrations/001-legacy-orphan-files.cjs
/msd-core/bin/lib/observability/redaction.cjs
/msd-core/bin/lib/installer-migration-report.cjs
/msd-core/bin/lib/prompt-budget.cjs
/msd-core/bin/lib/secrets.cjs
/msd-core/bin/lib/smart-entry.cjs
/msd-core/bin/lib/phase-lifecycle.cjs
/msd-core/bin/lib/workstream-name-policy.cjs
/msd-core/bin/lib/decisions.cjs
/msd-core/bin/lib/teams-status.cjs
/msd-core/bin/lib/validate.cjs
/msd-core/bin/lib/schema-detect.cjs
/msd-core/bin/lib/runtime-name-policy.cjs
/msd-core/bin/lib/runtime-identity.cjs
/msd-core/bin/lib/runtime-slash.cjs
/msd-core/bin/lib/observability/event.cjs
/msd-core/bin/lib/workstream-inventory-builder.cjs
/msd-core/bin/lib/plan-scan.cjs
/msd-core/bin/lib/fallow-runner.cjs
/msd-core/bin/lib/project-root.cjs
/msd-core/bin/lib/installer-migration-authoring.cjs
/msd-core/bin/lib/update-context.cjs
/msd-core/bin/lib/installer-migrations/000-first-time-baseline.cjs
/msd-core/bin/lib/installer-migrations/008-cursor-retire-commands-surface.cjs
/msd-core/bin/lib/retired-artifact-cleanup.cjs
/msd-core/bin/lib/runtime-homes.cjs
/msd-core/bin/lib/model-catalog.cjs
/msd-core/bin/lib/configuration.cjs
/msd-core/bin/lib/state-document.cjs
/msd-core/bin/lib/shell-command-projection.cjs
/msd-core/bin/lib/security.cjs
/msd-core/bin/lib/verification.cjs
/msd-core/bin/lib/verification-command-router.cjs
/msd-core/bin/lib/command-aliases.cjs
/msd-core/bin/lib/config-schema.cjs
/msd-core/bin/lib/model-profiles.cjs
/msd-core/bin/lib/installer-migrations/002-codex-legacy-hooks-json.cjs
/msd-core/bin/lib/installer-migrations/003-rename-get-shit-done-to-msd-core.cjs
/msd-core/bin/lib/installer-migrations/004-prune-stale-pristine-snapshots.cjs
/msd-core/bin/lib/installer-migrations/005-opencode-baseline-commands-dir.cjs
/msd-core/bin/lib/installer-migrations/006-pi-extension-cjs-to-js.cjs
/msd-core/bin/lib/installer-migrations/007-retire-config-root-commonjs-marker.cjs
/msd-core/bin/lib/installer-migrations/009-pi-retire-reserved-hooks-dir.cjs
/msd-core/bin/lib/installer-migrations/010-antigravity-retire-confighome-artifacts.cjs
/msd-core/bin/lib/observability/logger.cjs
/msd-core/bin/lib/active-workstream-store.cjs
/msd-core/bin/lib/adr-parser.cjs
/msd-core/bin/lib/graphify.cjs
/msd-core/bin/lib/graphify-command-router.cjs
/msd-core/bin/lib/audit-command-router.cjs
/msd-core/bin/lib/intel-command-router.cjs
/msd-core/bin/lib/install-profiles.cjs
/msd-core/bin/lib/intel.cjs
/msd-core/bin/lib/installer-migrations.cjs
/msd-core/bin/lib/worktree-base-ref.cjs
/msd-core/bin/lib/worktree-safety.cjs
/msd-core/bin/lib/planning-workspace.cjs
/msd-core/bin/lib/planning-scope.cjs
/msd-core/bin/lib/planning-snapshot.cjs
/msd-core/bin/lib/planning-document.cjs
/msd-core/bin/lib/planning-inspect.cjs
/msd-core/bin/lib/planning-command-router.cjs
/msd-core/bin/lib/plan-document.cjs
/msd-core/bin/lib/state-contract.cjs
/msd-core/bin/lib/pattern.cjs
/msd-core/bin/lib/text-lines.cjs
/msd-core/bin/lib/token-scanner.cjs
/msd-core/bin/lib/health-diagnostic-types.cjs
/msd-core/bin/lib/health-diagnostic.cjs
/msd-core/bin/lib/health-diagnostic-rules/root-existence.cjs
/msd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs
/msd-core/bin/lib/health-diagnostic-rules/config-validation.cjs
/msd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs
/msd-core/bin/lib/health-diagnostic-rules/agent-install.cjs
/msd-core/bin/lib/health-diagnostic-rules/roadmap-disk-consistency.cjs
/msd-core/bin/lib/health-diagnostic-rules/worktree-health.cjs
/msd-core/bin/lib/health-diagnostic-rules/milestone-archive-hygiene.cjs
/msd-core/bin/lib/health-diagnostic-rules/consistency.cjs
/msd-core/bin/lib/health-diagnostic-rules/install-surface-shadowing.cjs
/msd-core/bin/lib/command-roster.cjs
/msd-core/bin/lib/runtime-artifact-conversion.cjs
/msd-core/bin/lib/runtime-artifact-layout.cjs
/msd-core/bin/lib/install-scope.cjs
/msd-core/bin/lib/install-fs-adapter.cjs
/msd-core/bin/lib/user-artifact-staging.cjs
/msd-core/bin/lib/installed-surface-resolver.cjs
/msd-core/bin/lib/install-shadow-report.cjs
/msd-core/bin/lib/runtime-config-adapter-registry.cjs
/msd-core/bin/lib/runtime-hooks-surface.cjs
/msd-core/bin/lib/command-routing-hub.cjs
/msd-core/bin/lib/core-utils.cjs
/msd-core/bin/lib/io.cjs
/msd-core/bin/lib/phase-id.cjs
/msd-core/bin/lib/phase-id-card.cjs
/msd-core/bin/lib/phase-id-display.cjs
/msd-core/bin/lib/normalize-test-command.cjs
/msd-core/bin/lib/config-loader.cjs
/msd-core/bin/lib/unusable-input.cjs
/msd-core/bin/lib/model-resolver.cjs
/msd-core/bin/lib/loop-resolver.cjs
/msd-core/bin/lib/capability-state.cjs
/msd-core/bin/lib/capability-writer.cjs
/msd-core/bin/lib/capability-activation.cjs
/msd-core/bin/lib/federated-config.cjs
/msd-core/bin/lib/phase-locator.cjs
/msd-core/bin/lib/plan-dependency-graph.cjs
# #3674: compiled from src/file-overlap-partitioner.cts (ADR-457 build-at-publish).
/gsd-core/bin/lib/file-overlap-partitioner.cjs
/msd-core/bin/lib/file-overlap-partitioner.cjs
# #3675: compiled from src/quick-batch.cts (ADR-457 build-at-publish).
/gsd-core/bin/lib/quick-batch.cjs
/msd-core/bin/lib/quick-batch.cjs
# #3676: compiled from src/quick-batch-dispatch.cts and
# src/quick-batch-command-router.cts (ADR-457 build-at-publish).
/gsd-core/bin/lib/quick-batch-dispatch.cjs
/gsd-core/bin/lib/quick-batch-command-router.cjs
/gsd-core/bin/lib/phase-estimation.cjs
/gsd-core/bin/lib/estimate-cli.cjs
/gsd-core/bin/lib/roadmap-parser.cjs
/gsd-core/bin/lib/drift.cjs
/gsd-core/bin/lib/cjs-command-router-adapter.cjs
/gsd-core/bin/lib/phase-command-router.cjs
/gsd-core/bin/lib/surface.cjs
/gsd-core/bin/lib/gap-checker.cjs
/gsd-core/bin/lib/gate-predicate-evaluator.cjs
/gsd-core/bin/lib/docs.cjs
/gsd-core/bin/lib/check-command-router.cjs
/gsd-core/bin/lib/verify-command-grounding.cjs
/gsd-core/bin/lib/frontmatter.cjs
/gsd-core/bin/lib/learnings.cjs
/gsd-core/bin/lib/gsd2-import.cjs
/gsd-core/bin/lib/profile-pipeline.cjs
/gsd-core/bin/lib/roadmap-upgrade.cjs
/gsd-core/bin/lib/phases-command-router.cjs
/gsd-core/bin/lib/verify-command-router.cjs
/gsd-core/bin/lib/eval.cjs
/gsd-core/bin/lib/eval-command-router.cjs
/gsd-core/bin/lib/init-command-router.cjs
/gsd-core/bin/lib/onboard-projection.cjs
/gsd-core/bin/lib/agent-command-router.cjs
/gsd-core/bin/lib/agent-install-check.cjs
/gsd-core/bin/lib/codex-agent-toml.cjs
/gsd-core/bin/lib/task-command-router.cjs
/gsd-core/bin/lib/validate-command-router.cjs
/gsd-core/bin/lib/workstream-inventory.cjs
/gsd-core/bin/lib/roadmap-command-router.cjs
/gsd-core/bin/lib/state-command-router.cjs
/gsd-core/bin/lib/config.cjs
/gsd-core/bin/lib/profile-output.cjs
/gsd-core/bin/lib/template.cjs
/gsd-core/bin/lib/commands.cjs
/gsd-core/bin/lib/state.cjs
/gsd-core/bin/lib/milestone.cjs
/gsd-core/bin/lib/phase.cjs
/gsd-core/bin/lib/verify.cjs
/gsd-core/bin/lib/init.cjs
/gsd-core/bin/lib/uat.cjs
/gsd-core/bin/lib/coverage.cjs
/gsd-core/bin/lib/uat-predicate.cjs
/gsd-core/bin/lib/workstream.cjs
/gsd-core/bin/lib/roadmap.cjs
/gsd-core/bin/lib/audit.cjs
/gsd-core/bin/lib/git-base-branch.cjs
/gsd-core/bin/lib/host-runtime-detection.cjs
/gsd-core/bin/lib/task-content-resolution.cjs
/gsd-core/bin/lib/tdd-red-evidence.cjs
/msd-core/bin/lib/quick-batch-dispatch.cjs
/msd-core/bin/lib/quick-batch-command-router.cjs
/msd-core/bin/lib/phase-estimation.cjs
/msd-core/bin/lib/estimate-cli.cjs
/msd-core/bin/lib/roadmap-parser.cjs
/msd-core/bin/lib/drift.cjs
/msd-core/bin/lib/cjs-command-router-adapter.cjs
/msd-core/bin/lib/phase-command-router.cjs
/msd-core/bin/lib/surface.cjs
/msd-core/bin/lib/gap-checker.cjs
/msd-core/bin/lib/gate-predicate-evaluator.cjs
/msd-core/bin/lib/docs.cjs
/msd-core/bin/lib/check-command-router.cjs
/msd-core/bin/lib/verify-command-grounding.cjs
/msd-core/bin/lib/frontmatter.cjs
/msd-core/bin/lib/learnings.cjs
/msd-core/bin/lib/gsd2-import.cjs
/msd-core/bin/lib/profile-pipeline.cjs
/msd-core/bin/lib/roadmap-upgrade.cjs
/msd-core/bin/lib/phases-command-router.cjs
/msd-core/bin/lib/verify-command-router.cjs
/msd-core/bin/lib/eval.cjs
/msd-core/bin/lib/eval-command-router.cjs
/msd-core/bin/lib/init-command-router.cjs
/msd-core/bin/lib/onboard-projection.cjs
/msd-core/bin/lib/agent-command-router.cjs
/msd-core/bin/lib/agent-install-check.cjs
/msd-core/bin/lib/codex-agent-toml.cjs
/msd-core/bin/lib/task-command-router.cjs
/msd-core/bin/lib/validate-command-router.cjs
/msd-core/bin/lib/workstream-inventory.cjs
/msd-core/bin/lib/roadmap-command-router.cjs
/msd-core/bin/lib/state-command-router.cjs
/msd-core/bin/lib/config.cjs
/msd-core/bin/lib/profile-output.cjs
/msd-core/bin/lib/template.cjs
/msd-core/bin/lib/commands.cjs
/msd-core/bin/lib/state.cjs
/msd-core/bin/lib/milestone.cjs
/msd-core/bin/lib/phase.cjs
/msd-core/bin/lib/verify.cjs
/msd-core/bin/lib/init.cjs
/msd-core/bin/lib/uat.cjs
/msd-core/bin/lib/coverage.cjs
/msd-core/bin/lib/uat-predicate.cjs
/msd-core/bin/lib/workstream.cjs
/msd-core/bin/lib/roadmap.cjs
/msd-core/bin/lib/audit.cjs
/msd-core/bin/lib/git-base-branch.cjs
/msd-core/bin/lib/host-runtime-detection.cjs
/msd-core/bin/lib/task-content-resolution.cjs
/msd-core/bin/lib/tdd-red-evidence.cjs
__pycache__/
*.pyc
.venv/
@@ -325,10 +325,10 @@ venv/
target/
vendor/
# Vendored third-party artifacts under version control on purpose — see
# gsd-core/bin/lib/vendor/README.md. bin/** must have zero external requires
# msd-core/bin/lib/vendor/README.md. bin/** must have zero external requires
# (installed trees ship with no node_modules), so this one directory is a
# deliberate, tracked exception to the blanket `vendor/` ignore above.
!/gsd-core/bin/lib/vendor/
!/msd-core/bin/lib/vendor/
# Source-side twin (tsc resolves a .cts module's relative imports against
# src/, not the output dir) of the same vendored artifact — see
# scripts/lint-vendored-deps.cjs, which keeps both copies in sync.
@@ -349,7 +349,7 @@ entities.json
claude-test-command.md
# Observability audit trail (issue #177) — append-only, local only
.planning/.gsd-trace.jsonl
.planning/.msd-trace.jsonl
# Mutation testing artifacts (issue #454)
.stryker-tmp/

View File

@@ -1,5 +1,5 @@
/**
* GSD plugin for OpenCode.ai (CommonJS)
* MSD plugin for OpenCode.ai (CommonJS)
*
* Architecture: SUBPROCESS REUSE. Instead of re-implementing hook logic inside
* the plugin, this file is a thin adapter that spawns the existing Claude Code
@@ -11,36 +11,36 @@
* - block → throw Error (OpenCode returns the error to the model)
* - advisory → output.metadata + console.error (best-effort surfacing)
*
* Namespace conversion (/gsd:xxx → /gsd-xxx) reuses scripts/fix-slash-commands.cjs
* Namespace conversion (/msd:xxx → /msd-xxx) reuses scripts/fix-slash-commands.cjs
* via require(), keeping the single source of truth.
*
* ── Two distribution shapes, one adapter (issue #1914) ─────────────────────
* This single file serves both distribution paths, distinguished at load time
* by REPO_ROOT (path.resolve(__dirname, "../..")):
*
* • Option 1 — file copy (the supported GSD path). `bin/install.js` copies
* this file to <opencodeConfigDir>/plugins/gsd-core.js, so REPO_ROOT is the
* OpenCode config dir. GSD's own install already stages `hooks/*.js` and
* `gsd-core/` there (ADR-857 skips hook *registration* for OpenCode, not the
* • Option 1 — file copy (the supported MSD path). `bin/install.js` copies
* this file to <opencodeConfigDir>/plugins/msd-core.js, so REPO_ROOT is the
* OpenCode config dir. MSD's own install already stages `hooks/*.js` and
* `msd-core/` there (ADR-857 skips hook *registration* for OpenCode, not the
* file copy), so the hook bridge and content rewriting resolve natively.
* Commands/agents/skills are ALREADY registered by GSD's native file copy in
* Commands/agents/skills are ALREADY registered by MSD's native file copy in
* this mode, so the plugin's own config-hook registration is redundant and is
* SKIPPED (see IS_PACKAGE_TREE) to avoid double-registration.
*
* • Option 2 — package / git-spec. When loaded from the package tree (npm
* `main`, or an OpenCode git-spec install), REPO_ROOT is the package root and
* the source layout (commands/gsd/, agents/, skills/) is present. Here the
* the source layout (commands/msd/, agents/, skills/) is present. Here the
* plugin IS the sole registrar, so it registers commands/agents/skills too.
*
* IS_PACKAGE_TREE keys off the presence of the SOURCE command layout
* (commands/gsd/), which only exists in the package tree — never in an installed
* (commands/msd/), which only exists in the package tree — never in an installed
* config dir (that uses the flattened command/ layout). The hook bridge and
* Read-time content rewriting run in BOTH modes; only the config-hook
* registration of commands/agents/skills is gated.
*
* Runtime-specific hooks are deliberately excluded:
* - gsd-statusline.js / gsd-update-banner.js (Claude Code statusline)
* - gsd-cursor-*.js (Cursor-specific)
* - msd-statusline.js / msd-update-banner.js (Claude Code statusline)
* - msd-cursor-*.js (Cursor-specific)
* - *.sh scripts (invoked directly by commands/agents, not hook events)
*/
@@ -51,12 +51,12 @@ const fs = require("fs");
const os = require("os");
const { spawnSync } = require("child_process");
// Resolve REPO_ROOT to the directory that actually holds the GSD payload
// (hooks/ + gsd-core/). This must work across three physical layouts because a
// Resolve REPO_ROOT to the directory that actually holds the MSD payload
// (hooks/ + msd-core/). This must work across three physical layouts because a
// single adapter file serves both distribution shapes (see header):
// • package/git-spec tree: <root>/.opencode/plugins/gsd-core.js → <root>
// • global file-copy: ~/.config/opencode/plugins/gsd-core.js → ~/.config/opencode
// • local file-copy: <proj>/.opencode/plugins/gsd-core.js → <proj>/.opencode
// • package/git-spec tree: <root>/.opencode/plugins/msd-core.js → <root>
// • global file-copy: ~/.config/opencode/plugins/msd-core.js → ~/.config/opencode
// • local file-copy: <proj>/.opencode/plugins/msd-core.js → <proj>/.opencode
// A fixed "../.." only works for the first; the copied layouts sit one level
// shallower. Walking up to the first ancestor containing BOTH payload markers
// resolves all three deterministically. Falls back to the package-tree
@@ -66,7 +66,7 @@ function resolveRepoRoot(startDir) {
for (let i = 0; i < 6; i++) {
if (
fs.existsSync(path.join(dir, "hooks")) &&
fs.existsSync(path.join(dir, "gsd-core"))
fs.existsSync(path.join(dir, "msd-core"))
) {
return dir;
}
@@ -84,16 +84,16 @@ function resolveRepoRoot(startDir) {
// CJS: __dirname is a global, no need to derive from import.meta.url
const REPO_ROOT = resolveRepoRoot(__dirname);
const HOOKS_DIR = path.join(REPO_ROOT, "hooks");
const COMMANDS = path.join(REPO_ROOT, "commands", "gsd");
const COMMANDS = path.join(REPO_ROOT, "commands", "msd");
const AGENTS = path.join(REPO_ROOT, "agents");
const SKILLS = path.join(REPO_ROOT, "skills");
const GSD_CORE = path.join(REPO_ROOT, "gsd-core");
const MSD_CORE = path.join(REPO_ROOT, "msd-core");
// True only when loaded from the package/source tree (Option 2), detected by the
// presence of the SOURCE command layout (commands/gsd/). In an installed OpenCode
// presence of the SOURCE command layout (commands/msd/). In an installed OpenCode
// config dir (Option 1) this directory is absent — the flattened command/ layout
// is used instead — so the plugin skips its own command/agent/skill registration
// and lets GSD's native file copy own that surface (avoids double-registration).
// and lets MSD's native file copy own that surface (avoids double-registration).
const IS_PACKAGE_TREE = fs.existsSync(COMMANDS);
// ---------------------------------------------------------------------------
@@ -198,7 +198,7 @@ function mapToolInput(args) {
* - exit 2: block (Claude convention; reason in stdout JSON)
* - any error: exit 0 silently (hooks swallow their own errors)
*
* @param {string} hookFile filename under hooks/, e.g. "gsd-prompt-guard.js"
* @param {string} hookFile filename under hooks/, e.g. "msd-prompt-guard.js"
* @param {object} payload stdin JSON (hook_event_name, tool_name, ...)
* @param {object} [opts]
* @param {number} [opts.timeout=8000] spawn timeout in ms
@@ -217,9 +217,9 @@ function runHook(hookFile, payload, opts = {}) {
if (!warnedMissingHooks.has(hookFile)) {
warnedMissingHooks.add(hookFile);
console.error(
`[gsd-core] hook script missing: ${hookPath} — ${hookFile} is NOT ` +
"enforced. The GSD install may be incomplete; reinstall (or run " +
"/gsd-update) to restage the hooks/ bundle.",
`[msd-core] hook script missing: ${hookPath} — ${hookFile} is NOT ` +
"enforced. The MSD install may be incomplete; reinstall (or run " +
"/msd-update) to restage the hooks/ bundle.",
);
}
return { stdout: "", exitCode: 0, timedOut: false };
@@ -247,7 +247,7 @@ function runHook(hookFile, payload, opts = {}) {
/**
* In-process check for whether context-usage warnings are disabled in project
* config. Mirrors the exact semantics of the same check inside
* hooks/gsd-context-monitor.js (introduced by #1073): an explicit
* hooks/msd-context-monitor.js (introduced by #1073): an explicit
* `config.hooks.context_warnings === false` disables them; a missing or
* unparseable .planning/config.json keeps them enabled (the default).
*
@@ -278,7 +278,7 @@ function contextWarningsDisabled(cwd) {
* Parse a hook's stdout and apply its effect to the OpenCode output object.
*
* - Block → throw Error(parsed.reason) so OpenCode aborts the tool call
* - Advisory→ append to output.metadata._gsdAdvisory[] and log to stderr
* - Advisory→ append to output.metadata._msdAdvisory[] and log to stderr
* - Silent → no-op
*
* @param {{ stdout: string, exitCode: number }} hookResult
@@ -301,7 +301,7 @@ function handleHookResult(hookResult, output) {
const isBlock = exitCode === 2 || (parsed && parsed.decision === "block");
if (isBlock) {
const reason =
(parsed && parsed.reason) || "Blocked by GSD hook (no reason provided).";
(parsed && parsed.reason) || "Blocked by MSD hook (no reason provided).";
throw new Error(reason);
}
@@ -317,10 +317,10 @@ function handleHookResult(hookResult, output) {
// sequence (prompt guard, read guard, worktree guard, workflow guard).
// Storing a scalar would let a later advisory clobber an earlier one, so
// collect them all.
if (!Array.isArray(output.metadata._gsdAdvisory)) {
output.metadata._gsdAdvisory = [];
if (!Array.isArray(output.metadata._msdAdvisory)) {
output.metadata._msdAdvisory = [];
}
output.metadata._gsdAdvisory.push(advisory);
output.metadata._msdAdvisory.push(advisory);
}
// Best-effort visibility when metadata isn't surfaced to the model
console.error(advisory);
@@ -347,7 +347,7 @@ function parseFrontmatter(content) {
}
// Rewrite @~/.claude/ includes to point at the repo root.
// Also applies /gsd:xxx → /gsd-xxx namespace conversion via the shared
// Also applies /msd:xxx → /msd-xxx namespace conversion via the shared
// transform from scripts/fix-slash-commands.cjs (single source of truth).
function rewriteRefs(content) {
let out = content.replace(/@~\/\.claude\//g, `@${REPO_ROOT}/`);
@@ -370,38 +370,38 @@ function loadDir(dir, keyFn, valFn) {
}
// ---------------------------------------------------------------------------
// Runtime content transform — for Read tool results on GSD-managed files
// Runtime content transform — for Read tool results on MSD-managed files
// ---------------------------------------------------------------------------
// Directories whose .md files may contain ~/.claude/ paths and gsd: namespace
// Directories whose .md files may contain ~/.claude/ paths and msd: namespace
// refs. When the model reads these via the Read tool, we transparently rewrite
// both so OpenCode sees correct paths and hyphen-form command names.
const GSD_MANAGED_DIRS = [
path.join(GSD_CORE, "workflows"),
path.join(GSD_CORE, "references"),
path.join(GSD_CORE, "templates"),
path.join(GSD_CORE, "contexts"),
const MSD_MANAGED_DIRS = [
path.join(MSD_CORE, "workflows"),
path.join(MSD_CORE, "references"),
path.join(MSD_CORE, "templates"),
path.join(MSD_CORE, "contexts"),
COMMANDS,
AGENTS,
SKILLS,
];
function isGsdManagedFile(filePath) {
function isMsdManagedFile(filePath) {
if (!filePath) return false;
const resolved = path.resolve(filePath);
return GSD_MANAGED_DIRS.some(
return MSD_MANAGED_DIRS.some(
(dir) => resolved === dir || resolved.startsWith(dir + path.sep),
);
}
// Rewrite content for OpenCode consumption:
// 1. @-include paths: @~/.claude/ → @<REPO_ROOT>/
// 2. plain-text paths: ~/.claude/gsd-core/ → <GSD_CORE>/
// 3. namespace: gsd:xxx → gsd-xxx (via fix-slash-commands.cjs)
// 2. plain-text paths: ~/.claude/msd-core/ → <MSD_CORE>/
// 3. namespace: msd:xxx → msd-xxx (via fix-slash-commands.cjs)
function rewriteContent(content) {
let out = content;
out = out.replace(/@~\/\.claude\//g, `@${REPO_ROOT}/`);
out = out.replace(/~\/\.claude\/gsd-core\//g, `${GSD_CORE}/`);
out = out.replace(/~\/\.claude\/msd-core\//g, `${MSD_CORE}/`);
const transform = getNamespaceConverter();
if (transform && _cmdNames && _cmdNames.length) {
out = transform(out, _cmdNames);
@@ -415,18 +415,18 @@ function rewriteContent(content) {
//
// OpenCode's skill loader reads SKILL.md files directly from disk and resolves
// @-includes internally — this bypasses our tool.execute hooks. To make
// @~/.claude/gsd-core/... includes resolve, we copy all SKILL.md files to a
// cache directory with paths rewritten to the actual GSD_CORE location.
// @~/.claude/msd-core/... includes resolve, we copy all SKILL.md files to a
// cache directory with paths rewritten to the actual MSD_CORE location.
//
// Only used in package-tree mode (Option 2). In an installed OpenCode config
// dir (Option 1) skills are already staged + registered by GSD's native file
// dir (Option 1) skills are already staged + registered by MSD's native file
// copy, so we never register skills from the plugin (see IS_PACKAGE_TREE).
const SKILLS_CACHE = path.join(
os.homedir(),
".cache",
"opencode",
"gsd-skills",
"msd-skills",
);
function prepareSkillsCache() {
@@ -439,8 +439,8 @@ function prepareSkillsCache() {
// Rewrite @-include paths only; namespace conversion is handled at
// Read-time via tool.execute.after for workflow/reference files.
const rewritten = raw
.replace(/@~\/\.claude\/gsd-core\//g, `@${GSD_CORE}/`)
.replace(/~\/\.claude\/gsd-core\//g, `${GSD_CORE}/`);
.replace(/@~\/\.claude\/msd-core\//g, `@${MSD_CORE}/`)
.replace(/~\/\.claude\/msd-core\//g, `${MSD_CORE}/`);
const destDir = path.join(SKILLS_CACHE, dir);
fs.mkdirSync(destDir, { recursive: true });
fs.writeFileSync(path.join(destDir, "SKILL.md"), rewritten);
@@ -452,25 +452,25 @@ function prepareSkillsCache() {
// Plugin entry
// ===========================================================================
const GsdCorePlugin = async ({ directory } = {}) => {
const MsdCorePlugin = async ({ directory } = {}) => {
if (directory) currentCwd = directory;
return {
// ── Config: register commands / agents / skills paths ──────────────
// Only in package-tree mode (Option 2). In an installed config dir
// (Option 1) GSD's native file copy already registered these, so the
// (Option 1) MSD's native file copy already registered these, so the
// plugin stays out of registration to avoid double-registering.
config: async (config) => {
if (!IS_PACKAGE_TREE) return;
// Commands (commands/gsd/*.md → gsd-<name>)
// Commands (commands/msd/*.md → msd-<name>)
config.command = config.command || {};
const cmds = loadDir(
COMMANDS,
(f) => "gsd-" + f.slice(0, -3),
(f) => "msd-" + f.slice(0, -3),
(body, fm, name) => ({
template: rewriteRefs(body.trim()),
description: fm.description || `GSD ${name.slice(0, -3)} command`,
description: fm.description || `MSD ${name.slice(0, -3)} command`,
}),
);
for (const [k, v] of Object.entries(cmds)) {
@@ -484,7 +484,7 @@ const GsdCorePlugin = async ({ directory } = {}) => {
(f) => f.slice(0, -3),
(body, fm, name) => ({
prompt: rewriteRefs(body.trim()),
description: fm.description || `GSD ${name.slice(0, -3)} agent`,
description: fm.description || `MSD ${name.slice(0, -3)} agent`,
mode: fm.mode || "subagent",
}),
);
@@ -508,7 +508,7 @@ const GsdCorePlugin = async ({ directory } = {}) => {
// ── shell.env ───────────────────────────────────────────────────────
"shell.env": async (_input, output) => {
output.env = output.env || {};
output.env.GSD_DIR = GSD_CORE;
output.env.MSD_DIR = MSD_CORE;
},
// ── tool.execute.before — PreToolUse hooks ─────────────────────────
@@ -517,14 +517,14 @@ const GsdCorePlugin = async ({ directory } = {}) => {
const toolInput = mapToolInput(output.args || {});
const cwd = currentCwd;
// 0. Read path rewrite — redirect ~/.claude/gsd-core/ to actual GSD_CORE
// 0. Read path rewrite — redirect ~/.claude/msd-core/ to actual MSD_CORE
// so the model can read workflow/reference/template files that SKILL.md
// and command templates reference via the canonical Claude path.
if (claudeTool === "Read" && toolInput.file_path) {
const original = toolInput.file_path;
const rewritten = original
.replace(/^~\/\.claude\/gsd-core\//, GSD_CORE + "/")
.replace(/(?:.*)\/\.claude\/gsd-core\//, GSD_CORE + "/");
.replace(/^~\/\.claude\/msd-core\//, MSD_CORE + "/")
.replace(/(?:.*)\/\.claude\/msd-core\//, MSD_CORE + "/");
if (rewritten !== original) {
const args = output.args || {};
if (args.filePath) args.filePath = rewritten;
@@ -539,7 +539,7 @@ const GsdCorePlugin = async ({ directory } = {}) => {
cwd,
};
// NOTE: session_id intentionally omitted for PreToolUse hooks.
// gsd-read-guard.js treats a non-empty session_id as a Claude Code
// msd-read-guard.js treats a non-empty session_id as a Claude Code
// session and skips its advisory. On OpenCode we WANT the advisory.
const prePayload = (overrides = {}) => ({
...basePayload,
@@ -550,42 +550,42 @@ const GsdCorePlugin = async ({ directory } = {}) => {
const isWriteLike = ["Write", "Edit", "MultiEdit"].includes(claudeTool);
// 1. gsd-prompt-guard.js — injection scan on .planning/ writes
// 1. msd-prompt-guard.js — injection scan on .planning/ writes
if (claudeTool === "Write" || claudeTool === "Edit") {
const r = runHook("gsd-prompt-guard.js", prePayload());
const r = runHook("msd-prompt-guard.js", prePayload());
handleHookResult(r, output);
}
// 2. gsd-read-guard.js — read-before-edit advisory
// 2. msd-read-guard.js — read-before-edit advisory
if (claudeTool === "Write" || claudeTool === "Edit") {
const r = runHook("gsd-read-guard.js", prePayload());
const r = runHook("msd-read-guard.js", prePayload());
handleHookResult(r, output);
}
// 3. gsd-worktree-path-guard.js — hard-block edits outside worktree
// 3. msd-worktree-path-guard.js — hard-block edits outside worktree
if (isWriteLike) {
const r = runHook("gsd-worktree-path-guard.js", prePayload());
const r = runHook("msd-worktree-path-guard.js", prePayload());
handleHookResult(r, output);
}
// 4. gsd-write-guard.js — hard-block catastrophic shrink of curated
// 4. msd-write-guard.js — hard-block catastrophic shrink of curated
// .planning/ artifacts (ROADMAP.md, milestones/*-ROADMAP.md, STATE.md)
if (claudeTool === "Write") {
const r = runHook("gsd-write-guard.js", prePayload());
const r = runHook("msd-write-guard.js", prePayload());
handleHookResult(r, output);
}
// 5. gsd-workflow-guard.js — workflow advisory + git-force-add block
// 5. msd-workflow-guard.js — workflow advisory + git-force-add block
// (covers Write/Edit/MultiEdit AND Bash force-add detection)
if (isWriteLike || claudeTool === "Bash") {
const r = runHook("gsd-workflow-guard.js", prePayload());
const r = runHook("msd-workflow-guard.js", prePayload());
handleHookResult(r, output);
}
// 6. gsd-secret-read-guard.js — hard-block reads of .env / .env.<suffix> /
// 6. msd-secret-read-guard.js — hard-block reads of .env / .env.<suffix> /
// .secrets via Read (file_path), Grep (path or glob) and Bash (command)
if (["Read", "Grep", "Bash"].includes(claudeTool)) {
const r = runHook("gsd-secret-read-guard.js", prePayload());
const r = runHook("msd-secret-read-guard.js", prePayload());
handleHookResult(r, output);
}
},
@@ -598,12 +598,12 @@ const GsdCorePlugin = async ({ directory } = {}) => {
const toolInput = mapToolInput(input.args || {});
const cwd = currentCwd;
// GSD content transform — rewrite paths + namespace in Read results
// MSD content transform — rewrite paths + namespace in Read results
// BEFORE injection scanning so the scanner sees the final content.
if (
claudeTool === "Read" &&
output.output &&
isGsdManagedFile(toolInput.file_path)
isMsdManagedFile(toolInput.file_path)
) {
const content =
typeof output.output === "string"
@@ -612,7 +612,7 @@ const GsdCorePlugin = async ({ directory } = {}) => {
output.output = rewriteContent(content);
}
// gsd-read-injection-scanner.js — scan Read/WebFetch/WebSearch results
// msd-read-injection-scanner.js — scan Read/WebFetch/WebSearch results
if (
claudeTool === "Read" ||
claudeTool === "WebFetch" ||
@@ -625,12 +625,12 @@ const GsdCorePlugin = async ({ directory } = {}) => {
tool_response: output.output,
cwd,
};
const r = runHook("gsd-read-injection-scanner.js", payload);
const r = runHook("msd-read-injection-scanner.js", payload);
handleHookResult(r, output);
return;
}
// gsd-context-monitor.js — context usage warnings (Bash/Edit/Write/Task/...)
// msd-context-monitor.js — context usage warnings (Bash/Edit/Write/Task/...)
// Only meaningful when a session_id is tracked (writes metrics sentinel).
// #2697: skip the subprocess spawn entirely when context warnings are
// explicitly disabled in project config — the hook would exit early anyway,
@@ -644,7 +644,7 @@ const GsdCorePlugin = async ({ directory } = {}) => {
session_id: currentSessionId,
cwd,
};
const r = runHook("gsd-context-monitor.js", payload);
const r = runHook("msd-context-monitor.js", payload);
handleHookResult(r, output);
}
},
@@ -657,13 +657,13 @@ const GsdCorePlugin = async ({ directory } = {}) => {
session_id: currentSessionId,
cwd: currentCwd,
};
const r = runHook("gsd-context-monitor.js", payload);
const r = runHook("msd-context-monitor.js", payload);
handleHookResult(r, output);
// Also inject a GSD compaction breadcrumb (mirrors the original plugin)
// Also inject a MSD compaction breadcrumb (mirrors the original plugin)
output.context = output.context || [];
output.context.push(
`[GSD] Active session: ${currentSessionId}. Preserve any in-flight phase/plan state.`,
`[MSD] Active session: ${currentSessionId}. Preserve any in-flight phase/plan state.`,
);
},
@@ -679,14 +679,14 @@ const GsdCorePlugin = async ({ directory } = {}) => {
info?.id || event.sessionID || event.session_id || null;
if (info?.directory) currentCwd = info.directory;
// gsd-ensure-canonical-path.js — no stdin dependency; silent
runHook("gsd-ensure-canonical-path.js", {
// msd-ensure-canonical-path.js — no stdin dependency; silent
runHook("msd-ensure-canonical-path.js", {
hook_event_name: "SessionStart",
session_id: currentSessionId,
cwd: currentCwd,
});
// gsd-check-update.js — spawns its own background worker; no stdin
runHook("gsd-check-update.js", {
// msd-check-update.js — spawns its own background worker; no stdin
runHook("msd-check-update.js", {
hook_event_name: "SessionStart",
session_id: currentSessionId,
cwd: currentCwd,
@@ -709,17 +709,17 @@ const GsdCorePlugin = async ({ directory } = {}) => {
event: "change",
cwd,
};
const r = runHook("gsd-config-reload.js", payload);
const r = runHook("msd-config-reload.js", payload);
// Advisory-only (additionalContext); surface to logs
handleHookResult(r);
return;
}
// session.idle ↔ Claude Stop lifecycle point (#1682 Slice 1b/c).
// OpenCode fires session.idle when the run quiesces. GSD maps it to the
// OpenCode fires session.idle when the run quiesces. MSD maps it to the
// Stop equivalent — the opencode-subset lifecycle peer of compaction
// (compaction preserves state across context-window summarization; idle
// marks end-of-turn). No-op sentinel today (GSD state is already
// marks end-of-turn). No-op sentinel today (MSD state is already
// persisted to .planning/), but it MUST be recognized so the declared
// opencode-subset surface is fully wired and a future Stop-class hook can
// attach without a plugin change.
@@ -728,9 +728,9 @@ const GsdCorePlugin = async ({ directory } = {}) => {
}
// permission.asked / permission.replied — OpenCode permission lifecycle
// (#2087, opencode.ai/docs/plugins). GSD gates tool INPUTS at
// (#2087, opencode.ai/docs/plugins). MSD gates tool INPUTS at
// tool.execute.before (read-guard, injection-scanner); the permission
// grant/deny decision itself carries no GSD workflow-phase contribution,
// grant/deny decision itself carries no MSD workflow-phase contribution,
// so these are recognized sentinels — wired so a future permission-aware
// gate can attach without a plugin change (the engine owns phase
// sequencing; this host bus is session/tool/permission-scoped, never
@@ -739,7 +739,7 @@ const GsdCorePlugin = async ({ directory } = {}) => {
return;
}
// session.error — OpenCode session-error lifecycle point (#2087). No GSD
// session.error — OpenCode session-error lifecycle point (#2087). No MSD
// hook fires here today (loop state is already persisted to .planning/);
// recognized so the declared extension-event surface is fully wired and a
// future error-class hook can attach without a plugin change.
@@ -761,7 +761,7 @@ const GsdCorePlugin = async ({ directory } = {}) => {
// The subtlety: depending on how OpenCode's runtime (Node or Bun) imports a
// CommonJS file, `mod` may be the raw `module.exports` OR an ESM namespace of
// the form `{ default: module.exports, ...syntheticNamedExports }`. A plain
// `module.exports = { id: "gsd-core", server }` literal risks a string `id`
// `module.exports = { id: "msd-core", server }` literal risks a string `id`
// appearing in `Object.values(mod)` (as a raw property, or as a lexer-
// synthesized named export) — which would trip the throw. Two defenses:
// 1. `id` is defined NON-ENUMERABLE, so it never appears in Object.values yet
@@ -772,23 +772,23 @@ const GsdCorePlugin = async ({ directory } = {}) => {
// Result: raw-CJS `Object.values` = `[server]`; ESM `Object.values` =
// `[{server, <id non-enum>}]` — both fully extractable. Test-only helpers hang
// off the `server` FUNCTION (`server._internals`), never as a sibling export.
GsdCorePlugin._internals = {
MsdCorePlugin._internals = {
REPO_ROOT,
IS_PACKAGE_TREE,
mapToolName,
mapToolInput,
parseFrontmatter,
rewriteContent,
isGsdManagedFile,
isMsdManagedFile,
handleHookResult,
GsdCorePlugin,
MsdCorePlugin,
};
const gsdCorePluginExport = { server: GsdCorePlugin };
Object.defineProperty(gsdCorePluginExport, "id", {
value: "gsd-core",
const msdCorePluginExport = { server: MsdCorePlugin };
Object.defineProperty(msdCorePluginExport, "id", {
value: "msd-core",
enumerable: false,
writable: false,
configurable: false,
});
module.exports = gsdCorePluginExport;
module.exports = msdCorePluginExport;

View File

@@ -6,7 +6,7 @@
"branch": "feat/3677-quick-batch-hardening-acceptance",
"base_revision": "114dfcb739",
"base_ref": "origin/next",
"note": "Design artifacts rebuilt after a prior research-pass worktree was garbage-collected (no commits ever landed, so gitignored .gsd/ content was lost with it). This directory is force-added via a one-off checkpoint commit so a future resume can read it even though .gsd/ is normally gitignored project-wide.",
"note": "Design artifacts rebuilt after a prior research-pass worktree was garbage-collected (no commits ever landed, so gitignored .msd/ content was lost with it). This directory is force-added via a one-off checkpoint commit so a future resume can read it even though .msd/ is normally gitignored project-wide.",
"prior_summary_reverified": true,
"step1_conclusion": "crash-window gap CONFIRMED REAL — see 40-design.md Open Question 1 / Resolution",
"dependencies": {

View File

@@ -7,7 +7,7 @@ merged: #4190 core primitives, #4212 command/workflow/isolation).
A prior research pass produced a design doc + test matrix in this same
directory, but its worktree was garbage-collected before those files were
committed (`.gsd/` is gitignored repo-wide; "no commits" was treated as "no
committed (`.msd/` is gitignored repo-wide; "no commits" was treated as "no
changes" by worktree auto-cleanup). This document is a from-scratch rebuild,
grounded in an independent re-read of the actual workflow steps and source,
not a transcription of the lost files. Where it agrees with the prior
@@ -29,26 +29,26 @@ the first.
filter at `src/quick-batch.cts:926-928` is otherwise pure
status/depends_on logic; it has no awareness of `PLAN.md`/`SUMMARY.md` on
disk.
- `gsd-core/workflows/quick-batch/steps/completion.md:1-8` — confirms
- `msd-core/workflows/quick-batch/steps/completion.md:1-8` — confirms
`completeQuickItem` (Step 9) is "the ONLY writer of a 'Quick Tasks
Completed' STATE.md row" — i.e. the STATE.md row `hasQuickTaskRow` checks
for is written only AFTER Step 7 (merge) and, when `--validate`, Step 8
(verification) both succeed. A crash between Step 6 and Step 7 crashes
before any STATE.md row exists, so `resumeBatch`'s only recovery signal
never fires for this window.
- `gsd-core/workflows/quick-batch/steps/resume-mode.md:23-27,45-49` — on
- `msd-core/workflows/quick-batch/steps/resume-mode.md:23-27,45-49` — on
`--resume`, `eligible` items flow straight into the SAME per-round loop
Step 3/planner-wave/worktree-dispatch use for a fresh batch — "the DAG-
layer loop in `planner-wave.md` reads `$BATCH_MANIFEST_JSON`/`$BATCH_ID`
exactly the same way whether this batch was just created or just resumed."
- `gsd-core/workflows/quick-batch/steps/planner-wave.md:15-19` — the
- `msd-core/workflows/quick-batch/steps/planner-wave.md:15-19` — the
planning loop's eligibility for THIS layer is `status == "pending"` AND
`${item_dir}/${quick_id}-PLAN.md` does **not** yet exist on disk. An item
whose PLAN.md already exists (planned before the crash) is correctly
skipped here — planning is NOT re-run. This is the file-existence guard
the prior summary described as absent; it is present, but only at the
PLANNING layer.
- `gsd-core/workflows/quick-batch/steps/worktree-dispatch.md:29-59` (Step 6,
- `msd-core/workflows/quick-batch/steps/worktree-dispatch.md:29-59` (Step 6,
"Dispatch rounds") — re-derives eligibility every round via `quick-batch
resume --batch "$BATCH_ID" --raw` (same primitive as above, same blind
spot), then spawns an executor for every item in `$spawn` (backpressure-
@@ -61,7 +61,7 @@ the first.
coordinator never issued this round's dispatch in the first place; a NEW
coordinator process re-deriving eligibility from scratch has no round
history to consult.
- `gsd-core/workflows/quick-batch/steps/merge-wave.md:10-15` (Step 7) — its
- `msd-core/workflows/quick-batch/steps/merge-wave.md:10-15` (Step 7) — its
OWN mergeable-wave criterion is independent of the `eligible`/`spawn` list
entirely: "items that are `status == 'pending'` with a `SUMMARY.md` on
disk... and NOT yet merged." This is correct and sufficient FOR MERGE — it
@@ -75,7 +75,7 @@ for a pre-existing `SUMMARY.md` before dispatching an executor. An item that
crashed after Step 6 but before Step 9's STATE.md write is indistinguishable,
to `worktree-dispatch.md`'s dispatch loop, from an item that was never
started — it re-enters `$spawn` and gets a brand-new `git worktree add` +
`gsd-executor` dispatch. The original worktree (with its real commit and
`msd-executor` dispatch. The original worktree (with its real commit and
`SUMMARY.md`) is never referenced again by anything — not cleaned up, not
merged via its own record, simply orphaned. If both executors happen to
run to completion, Step 7's merge-eligibility check (`SUMMARY.md` exists on
@@ -123,14 +123,14 @@ the same pipeline for the same reason.
| # | AC bullet (verbatim, abbreviated) | Existing coverage | Gap | Action |
|---|---|---|---|---|
| 1 | Security: traversal, symlink escape, special files, prompt-injection, shell-metacharacter task text, manifest tampering, **arbitrary-worktree ownership attempts** | `tests/quick-batch.test.cjs` + `tests/quick-batch.property.test.cjs` cover traversal/symlink/special-file `--file` rejection (Phase 3/4 `60-review.json` fixed real findings); `gsd-quick-batch-workflow.test.cjs` covers the DATA_START/DATA_END prompt-injection boundary and quoted `$ARGUMENTS`. **Arbitrary-worktree-ownership tampering is NOT covered** — no test constructs a cleanup-wave manifest entry naming a worktree path/branch this batch never created. | Real gap | New hostile test |
| 1 | Security: traversal, symlink escape, special files, prompt-injection, shell-metacharacter task text, manifest tampering, **arbitrary-worktree ownership attempts** | `tests/quick-batch.test.cjs` + `tests/quick-batch.property.test.cjs` cover traversal/symlink/special-file `--file` rejection (Phase 3/4 `60-review.json` fixed real findings); `msd-quick-batch-workflow.test.cjs` covers the DATA_START/DATA_END prompt-injection boundary and quoted `$ARGUMENTS`. **Arbitrary-worktree-ownership tampering is NOT covered** — no test constructs a cleanup-wave manifest entry naming a worktree path/branch this batch never created. | Real gap | New hostile test |
| 2 | Capacity precedence/backpressure | `quick-batch-dispatch.test.cjs` + `.property.test.cjs` cover `effective-concurrency`/`spawn-plan` exhaustively (Phase 3). | None found | none |
| 3 | Scheduling: cycles, unknown deps, deterministic waves, isolation modes, serialized lifecycle, deterministic merge, conflicts, **scope drift**, stale bases, **submodules** | `quick-batch.test.cjs`/`.property.test.cjs` cover cycle/unknown-dep rejection and wave determinism. `gsd-quick-batch-merge-integration.test.cjs` covers a real merge conflict and a real undeclared deletion end-to-end. `worktree-safety.test.cjs:5716-6313` covers the `.gitmodules`/`SUBMODULE_PATHS` isolation-disable gate and the executor's own pre-commit submodule guard extensively — but always in the `execute-phase`/`quick.md` context, never through quick-batch's OWN merge/cleanup call path with a real `.gitmodules` file in the repo. `planWaveScopeConformance` (`src/worktree-safety.cts:921-...`) is unit-tested for its advisory `SCOPE_OUT_OF_DECLARED` warning, but not exercised end-to-end through a real git diff via `executeWorktreeWaveCleanupPlan`/`worktree.cleanup-wave` the way merge_failed/scope_violation already are. | Two real gaps | New real-git submodule integration test; new real-git advisory scope-drift test |
| 3 | Scheduling: cycles, unknown deps, deterministic waves, isolation modes, serialized lifecycle, deterministic merge, conflicts, **scope drift**, stale bases, **submodules** | `quick-batch.test.cjs`/`.property.test.cjs` cover cycle/unknown-dep rejection and wave determinism. `msd-quick-batch-merge-integration.test.cjs` covers a real merge conflict and a real undeclared deletion end-to-end. `worktree-safety.test.cjs:5716-6313` covers the `.gitmodules`/`SUBMODULE_PATHS` isolation-disable gate and the executor's own pre-commit submodule guard extensively — but always in the `execute-phase`/`quick.md` context, never through quick-batch's OWN merge/cleanup call path with a real `.gitmodules` file in the repo. `planWaveScopeConformance` (`src/worktree-safety.cts:921-...`) is unit-tested for its advisory `SCOPE_OUT_OF_DECLARED` warning, but not exercised end-to-end through a real git diff via `executeWorktreeWaveCleanupPlan`/`worktree.cleanup-wave` the way merge_failed/scope_violation already are. | Two real gaps | New real-git submodule integration test; new real-git advisory scope-drift test |
| 4 | Fault-injection: every durable manifest/STATE crash window, resume exactly-once | STATE-row crash window (Step 9) is covered. **The Step-6→Step-7 crash window (this doc §1) was UNCOVERED and is the one genuine functional gap in this phase.** | Real gap (now understood + fixed) | Fix + regression test |
| 5 | Outcome propagation (blocked/independent-continue) | Covered by `resumeBatch`'s blocked-propagation fixed-point tests and `quick-batch-dispatch.test.cjs`'s routing tests. | None found | none |
| 6 | Docs: v1 limits (`--discuss`/`--full`, no gap-fix loop, `none`=sequential) | `docs/how-to/batch-quick-tasks.md` states all of these already (lines 52-55, 74, 113). | None found | none |
| 7 | Generated artifact sync (command/skill/registry/inventory/matrix/install-tree) | Enforced by existing repo-wide generated-sync lint (not quick-batch-specific); Phase 4 already ran `regen:derived`. | None found (no new command surface added this phase) | none |
| 8 | `/gsd:quick` regression + quick-ID grammar green | `gsd-quick-batch-quick-regression.test.cjs` exists explicitly for this. | None found | none |
| 8 | `/msd:quick` regression + quick-ID grammar green | `msd-quick-batch-quick-regression.test.cjs` exists explicitly for this. | None found | none |
| 9 | Docs: preserved-worktree diagnosis | `docs/how-to/batch-quick-tasks.md:114` — exactly one sentence ("its worktree is preserved (never deleted) so you can inspect what happened"), no path, no diagnostic steps, no recovery procedure. | Real gap (thin, not absent) | Doc extension |
| 10 | Final acceptance evidence mapped to #3344 | Not yet produced this phase. | Real gap | New doc artifact |
| 11 | RED/GREEN/REFACTOR commit discipline, closes #3677 only | Process requirement, not a test | N/A | Followed in implementation |
@@ -138,7 +138,7 @@ the same pipeline for the same reason.
## 3. Prior-art grounding for new tests
- Hostile worktree-ownership test: follows the REAL-git-fixture pattern
already established by `tests/gsd-quick-batch-merge-integration.test.cjs`
already established by `tests/msd-quick-batch-merge-integration.test.cjs`
(`initRepo`/`addWorktree`, real `executeWorktreeWaveCleanupPlan`,
`WORKTREE_AGENT_BRANCH_RE` branch-name validation already enforced at
`src/worktree-safety.cts:512`) — a manifest entry naming a path/branch
@@ -149,7 +149,7 @@ the same pipeline for the same reason.
(`src/worktree-safety.cts:921-...`, `WAVE_CLEANUP_WARNING.SCOPE_OUT_OF_DECLARED`
at `:879-884`) end-to-end through a REAL git diff via
`executeWorktreeWaveCleanupPlan`, mirroring the merge-conflict/undeclared-
deletion pattern in `gsd-quick-batch-merge-integration.test.cjs` — commit a
deletion pattern in `msd-quick-batch-merge-integration.test.cjs` — commit a
path outside `files_modified` and assert the merge still SUCCEEDS
(advisory, never blocking) while a warning with the frozen code is
produced.
@@ -164,7 +164,7 @@ the same pipeline for the same reason.
separate, already-covered pre-dispatch decision, not a merge-time block).
- Crash-window regression test: structural assertion on
`worktree-dispatch.md`'s prose, following the SAME established convention
`tests/gsd-quick-batch-workflow.test.cjs` already uses for every other
`tests/msd-quick-batch-workflow.test.cjs` already uses for every other
workflow-file behavior (e.g. its own "planner-wave.md marks a missing
PLAN.md item failed" test at line 253-256) — this repo's blessed pattern
for testing markdown-as-source (see that file's own header comment,
@@ -174,7 +174,7 @@ the same pipeline for the same reason.
None of the new tests duplicate existing coverage:
- The merge-conflict/undeclared-deletion real-git tests already in
`gsd-quick-batch-merge-integration.test.cjs` are untouched; the new tests
`msd-quick-batch-merge-integration.test.cjs` are untouched; the new tests
add sibling `describe` blocks for DIFFERENT manifest-entry shapes
(foreign ownership, out-of-scope-but-declared-nothing-wrong path,
submodule-bearing repo) using the same helpers, not modifying existing
@@ -190,16 +190,16 @@ None of the new tests duplicate existing coverage:
## 5. Blast radius
- `gsd-core/workflows/quick-batch/steps/worktree-dispatch.md` — additive
- `msd-core/workflows/quick-batch/steps/worktree-dispatch.md` — additive
SUMMARY.md-existence filter, Step 6 substep 1 only.
- `tests/gsd-quick-batch-workflow.test.cjs` — one new `describe` block
- `tests/msd-quick-batch-workflow.test.cjs` — one new `describe` block
(structural regression test for the filter above).
- `tests/gsd-quick-batch-merge-integration.test.cjs` — new `describe`
- `tests/msd-quick-batch-merge-integration.test.cjs` — new `describe`
blocks: worktree-ownership tampering, advisory scope-drift, submodule
integration.
- `docs/how-to/batch-quick-tasks.md` — extend the "Resuming and failure
recovery" section with a preserved-worktree diagnosis subsection.
- New doc artifact: `.gsd/phase/feat-3677-quick-batch-hardening-acceptance/60-acceptance-evidence.md`
- New doc artifact: `.msd/phase/feat-3677-quick-batch-hardening-acceptance/60-acceptance-evidence.md`
mapping every #3344 AC bullet to its evidence.
- No `src/*.cts` production module changes required — the one functional
fix lands entirely in workflow prose.
@@ -241,7 +241,7 @@ None of the new tests duplicate existing coverage:
itself needs crash-recovery semantics.
4. **Skip the submodule/scope-drift/ownership tests as "already implied" by
unit-level coverage.** Rejected per this repo's own established
pattern (`gsd-quick-batch-merge-integration.test.cjs`'s own header
pattern (`msd-quick-batch-merge-integration.test.cjs`'s own header
comment): pure-function assertions on `routeMergeOutcome`/
`planWaveScopeConformance` were previously judged insufficient without a
REAL git fixture proving the underlying primitive agrees; the same
@@ -272,7 +272,7 @@ while fixing the first finding (see §9.3).
### 9.1 Spec finding — crash-window test was a prose proxy, not behavioral proof
The original `tests/gsd-quick-batch-workflow.test.cjs` regression tests for
The original `tests/msd-quick-batch-workflow.test.cjs` regression tests for
§1's fix only asserted `readStep('worktree-dispatch.md')` + regex matches
against the MARKDOWN — proving the documentation says the right thing,
never that the runtime condition (pending status + on-disk SUMMARY.md +
@@ -342,7 +342,7 @@ reason: 'branch_mismatch'` — never `merge_failed`, never a wrongly
successful merge. Both real worktrees, their branches, and item 2's real
uncommitted-to-main commit survive completely untouched by either attempt.
**Fix:** a new, stronger test in `tests/gsd-quick-batch-merge-integration.test.cjs`
**Fix:** a new, stronger test in `tests/msd-quick-batch-merge-integration.test.cjs`
("a manifest entry with one sibling worktree's real PATH but the OTHER
sibling's real BRANCH name is blocked") supplements (does not replace) the
original two tests, which still prove real, distinct boundaries
@@ -366,7 +366,7 @@ this primitive cannot see.
While building §9.1's real fixture, tracing `merge-wave.md` substep 3
("`$WT_PATH`/`$WT_BRANCH`/`$EXPECTED_BASE` per item come from the recorded
`$QUICK_BATCH_WORKTREE_MANIFEST` entry Step 6 wrote for that `agent_id`")
against `/gsd:quick`'s own prior art (`gsd-core/workflows/quick.md:415`:
against `/msd:quick`'s own prior art (`msd-core/workflows/quick.md:415`:
`QUICK_WORKTREE_MANIFEST=$(mktemp ...)`) revealed that
`$QUICK_BATCH_WORKTREE_MANIFEST` — quick-batch explicitly models it on the
SAME mechanism — is a fresh, PER-PROCESS `mktemp` file, not a durable
@@ -406,7 +406,7 @@ Verified end-to-end (persist → fresh `loadBatch` recovers the triple →
clear → a SUBSEQUENT `loadBatch` still succeeds even though the path no
longer exists) in `tests/quick-batch.test.cjs`'s new "durable
worktree-recovery fields (#3677)" describe block, plus structural wiring
tests in `tests/gsd-quick-batch-workflow.test.cjs` for both workflow files.
tests in `tests/msd-quick-batch-workflow.test.cjs` for both workflow files.
### 9.4 Revised blast radius (supersedes §5 for the fields below)
@@ -417,17 +417,17 @@ tests in `tests/gsd-quick-batch-workflow.test.cjs` for both workflow files.
- `src/quick-batch-dispatch.cts` — new `filterAlreadyExecuted` pure
function + `FilterAlreadyExecutedResult` type.
- `src/quick-batch-command-router.cts` — new `filter-executed` CLI verb.
- `gsd-core/workflows/quick-batch/steps/worktree-dispatch.md` — the guard
- `msd-core/workflows/quick-batch/steps/worktree-dispatch.md` — the guard
now calls `quick-batch filter-executed` instead of describing the split
only in prose; a new durable-persistence step after recording the
ephemeral manifest entry.
- `gsd-core/workflows/quick-batch/steps/merge-wave.md` — durable fallback
- `msd-core/workflows/quick-batch/steps/merge-wave.md` — durable fallback
for `$WT_PATH`/`$WT_BRANCH`/`$EXPECTED_BASE`; clears the triple on a
successful merge; fails closed when no record exists anywhere.
- Test files: `tests/quick-batch.test.cjs`, `tests/quick-batch-dispatch.test.cjs`,
`tests/quick-batch-command-router.test.cjs`,
`tests/gsd-quick-batch-workflow.test.cjs`,
`tests/gsd-quick-batch-merge-integration.test.cjs` — all gain new,
`tests/msd-quick-batch-workflow.test.cjs`,
`tests/msd-quick-batch-merge-integration.test.cjs` — all gain new,
independently-verified (real fixture / real git, not merely prose-proxy)
coverage per §9.1-9.3.
- §5's "No `src/*.cts` production module changes required" is SUPERSEDED —

View File

@@ -5,12 +5,12 @@ coverage is cited in `40-design.md` §2/§3, not re-listed here.
| Row | Test file | Test name (abbreviated) | Proves | #3677 AC bullet | #3344 AC bullet |
|---|---|---|---|---|---|
| 1 | `tests/gsd-quick-batch-merge-integration.test.cjs` | "a manifest entry naming a worktree/branch this batch never created is blocked, never merged or deleted" | `executeWorktreeWaveCleanupPlan` rejects a cleanup-wave entry whose `branch` fails `WORKTREE_AGENT_BRANCH_RE`, or whose `worktree_path` was never actually created by `git worktree add` for this repo — real fixture, real git, asserts the foreign path/branch survives untouched | Security bullet: "arbitrary-worktree ownership attempts" | "the command never sweeps or deletes an unowned worktree" |
| 2 | `tests/gsd-quick-batch-merge-integration.test.cjs` | "a committed path outside declared files_modified merges successfully with an advisory SCOPE_OUT_OF_DECLARED warning, never blocked" | `planWaveScopeConformance`'s advisory (non-blocking) behavior holds end-to-end through a REAL git diff via `executeWorktreeWaveCleanupPlan` — distinguishes advisory scope drift from the blocking undeclared-DELETION case already covered | Scheduling bullet: "scope drift" | "reports scope drift without silently merging it" |
| 3 | `tests/gsd-quick-batch-merge-integration.test.cjs` | "a repo with `.gitmodules` and an unrelated plan merges cleanly through the quick-batch cleanup primitive" + "...and a plan touching the submodule path also merges (isolation-disable is a separate, already-covered pre-dispatch decision)" | `executeWorktreeWaveCleanupPlan` handles a real `.gitmodules`-bearing repo without special-casing gitlink entries (mode 160000) incorrectly as an undeclared deletion or scope violation | Scheduling bullet: "submodules" | "submodule-touch... paths produce recoverable diagnostics" |
| 4 | `tests/gsd-quick-batch-workflow.test.cjs` | "worktree-dispatch.md excludes an item whose SUMMARY.md already exists from this round's spawn set (crash-window duplicate-dispatch guard)" | Structural regression test: the Step-6→Step-7 crash window (design §1) cannot silently regress — asserts the new SUMMARY.md-existence filter text exists in the prose, mirroring the file's own established pattern for asserting `planner-wave.md`'s PLAN.md-existence filter | Fault-injection bullet: "every durable manifest/STATE crash window" | "Base divergence, merge conflict, stale worktree, submodule-touch, and interrupted cleanup paths produce recoverable diagnostics" |
| 1 | `tests/msd-quick-batch-merge-integration.test.cjs` | "a manifest entry naming a worktree/branch this batch never created is blocked, never merged or deleted" | `executeWorktreeWaveCleanupPlan` rejects a cleanup-wave entry whose `branch` fails `WORKTREE_AGENT_BRANCH_RE`, or whose `worktree_path` was never actually created by `git worktree add` for this repo — real fixture, real git, asserts the foreign path/branch survives untouched | Security bullet: "arbitrary-worktree ownership attempts" | "the command never sweeps or deletes an unowned worktree" |
| 2 | `tests/msd-quick-batch-merge-integration.test.cjs` | "a committed path outside declared files_modified merges successfully with an advisory SCOPE_OUT_OF_DECLARED warning, never blocked" | `planWaveScopeConformance`'s advisory (non-blocking) behavior holds end-to-end through a REAL git diff via `executeWorktreeWaveCleanupPlan` — distinguishes advisory scope drift from the blocking undeclared-DELETION case already covered | Scheduling bullet: "scope drift" | "reports scope drift without silently merging it" |
| 3 | `tests/msd-quick-batch-merge-integration.test.cjs` | "a repo with `.gitmodules` and an unrelated plan merges cleanly through the quick-batch cleanup primitive" + "...and a plan touching the submodule path also merges (isolation-disable is a separate, already-covered pre-dispatch decision)" | `executeWorktreeWaveCleanupPlan` handles a real `.gitmodules`-bearing repo without special-casing gitlink entries (mode 160000) incorrectly as an undeclared deletion or scope violation | Scheduling bullet: "submodules" | "submodule-touch... paths produce recoverable diagnostics" |
| 4 | `tests/msd-quick-batch-workflow.test.cjs` | "worktree-dispatch.md excludes an item whose SUMMARY.md already exists from this round's spawn set (crash-window duplicate-dispatch guard)" | Structural regression test: the Step-6→Step-7 crash window (design §1) cannot silently regress — asserts the new SUMMARY.md-existence filter text exists in the prose, mirroring the file's own established pattern for asserting `planner-wave.md`'s PLAN.md-existence filter | Fault-injection bullet: "every durable manifest/STATE crash window" | "Base divergence, merge conflict, stale worktree, submodule-touch, and interrupted cleanup paths produce recoverable diagnostics" |
| 5 | `docs/how-to/batch-quick-tasks.md` (doc, not test) | "Diagnosing a preserved worktree" subsection | Extends the one-sentence mention into: where the worktree lives, what to check (`git log`, `git status`, the item's `SUMMARY.md`), how to manually merge/discard, how to re-run `--resume` afterward | Docs bullet: "preserved-worktree diagnosis" | "Base divergence... produce recoverable diagnostics" |
| 6 | `.gsd/phase/feat-3677-quick-batch-hardening-acceptance/60-acceptance-evidence.md` (doc, not test) | Full AC-to-evidence mapping | Every #3344 AC bullet cited against the specific test/doc/commit that satisfies it | "Final verification maps evidence to every acceptance criterion in #3344" | (self) |
| 6 | `.msd/phase/feat-3677-quick-batch-hardening-acceptance/60-acceptance-evidence.md` (doc, not test) | Full AC-to-evidence mapping | Every #3344 AC bullet cited against the specific test/doc/commit that satisfies it | "Final verification maps evidence to every acceptance criterion in #3344" | (self) |
## Boundary coverage note

View File

@@ -1,4 +1,4 @@
# Final acceptance evidence — epic #3344 (`/gsd:quick-batch`)
# Final acceptance evidence — epic #3344 (`/msd:quick-batch`)
Maps every acceptance-criterion bullet in #3344 to its evidence. Phases 1-4
(#4190, #4212, and their prerequisite dispatch/wave-partitioner PRs) are
@@ -13,14 +13,14 @@ is the evidence submitted for that acceptance, not a closure action.
| AC bullet | Evidence |
|---|---|
| Accepts ≥2 inline tasks or a validated repo-relative task file | `tests/quick-batch.test.cjs` (`parseTaskList`/`parseTaskListFromFile`), `tests/gsd-quick-batch-workflow.test.cjs` |
| `--jobs auto\|N`, `--validate`, `--research`, `--resume <batch-id>` documented | `commands/gsd/quick-batch.md` frontmatter tests; `docs/how-to/batch-quick-tasks.md` "Flags" |
| V1 rejects `--discuss`/`--full` before dispatch | `tests/gsd-quick-batch-workflow.test.cjs` "objective documents --discuss/--full as rejected" |
| Accepts ≥2 inline tasks or a validated repo-relative task file | `tests/quick-batch.test.cjs` (`parseTaskList`/`parseTaskListFromFile`), `tests/msd-quick-batch-workflow.test.cjs` |
| `--jobs auto\|N`, `--validate`, `--research`, `--resume <batch-id>` documented | `commands/msd/quick-batch.md` frontmatter tests; `docs/how-to/batch-quick-tasks.md` "Flags" |
| V1 rejects `--discuss`/`--full` before dispatch | `tests/msd-quick-batch-workflow.test.cjs` "objective documents --discuss/--full as rejected" |
| No automatic broad-prompt decomposition | `docs/how-to/batch-quick-tasks.md` "Basic use" (explicit list only) |
| Collision-safe quick ID/directory even for duplicates | `tests/quick-batch.test.cjs` (`allocateQuickIds`/`allocateIdsGivenUsed`), `quick-batch.property.test.cjs` |
| Normal quick PLAN + `status: complete` SUMMARY under `.planning/quick/`, audit-scanner-recognized | `tests/gsd-quick-batch-quick-regression.test.cjs` |
| Normal quick PLAN + `status: complete` SUMMARY under `.planning/quick/`, audit-scanner-recognized | `tests/msd-quick-batch-quick-regression.test.cjs` |
| Batch control state under `.planning/quick-batches/<batch-id>/`, not a fake quick dir | `tests/quick-batch.test.cjs` (`createBatch`/`batchManifestPath`) |
| Coordinator dispatches leaves directly; no child invokes `/gsd:quick`; no nested/background delegation required | `tests/gsd-quick-batch-workflow.test.cjs` "single-writer invariant on the executor" (`NEVER invoke /gsd:quick`) |
| Coordinator dispatches leaves directly; no child invokes `/msd:quick`; no nested/background delegation required | `tests/msd-quick-batch-workflow.test.cjs` "single-writer invariant on the executor" (`NEVER invoke /msd:quick`) |
## Capacity and scheduling
@@ -33,45 +33,45 @@ is the evidence submitted for that acceptance, not a closure action.
| Backpressure preserves pending state, never overspawns | `tests/quick-batch-dispatch.test.cjs` (`spawn-plan`) |
| Declared dependencies honored; overlapping file sets never co-wave | `tests/quick-batch.test.cjs` (`computeWaves`), `.property.test.cjs` |
| Independent non-overlapping tasks run concurrently when capacity allows | `tests/quick-batch.test.cjs` wave tests |
| Deterministic wave/merge ordering for identical input | `tests/quick-batch.test.cjs` + `tests/gsd-quick-batch-merge-integration.test.cjs` (wave-order-preserving merge) |
| Deterministic wave/merge ordering for identical input | `tests/quick-batch.test.cjs` + `tests/msd-quick-batch-merge-integration.test.cjs` (wave-order-preserving merge) |
## Isolation and Git safety
| AC bullet | Evidence |
|---|---|
| `harness-worktree`/`orchestrator-worktree`/`none` each behaviorally tested, fail-closed degradation | `tests/gsd-quick-batch-workflow.test.cjs` "isolation model coverage"; `gsd-core/workflows/quick-batch/steps/worktree-dispatch.md` (row 38 stale-base auto-degrade) |
| `harness-worktree`/`orchestrator-worktree`/`none` each behaviorally tested, fail-closed degradation | `tests/msd-quick-batch-workflow.test.cjs` "isolation model coverage"; `msd-core/workflows/quick-batch/steps/worktree-dispatch.md` (row 38 stale-base auto-degrade) |
| Mutating wave forced to 1 worker when isolation is `none` | `tests/quick-batch-dispatch.test.cjs` (`--mutating` forcing) |
| Worktree create/merge/cleanup serialized and manifest-scoped; never sweeps/deletes an unowned worktree | `tests/gsd-quick-batch-merge-integration.test.cjs` — **NEW/REVISED (review pass 2)**: "arbitrary-worktree ownership tampering" describe block, 3 tests: (1) tampered branch name silently dropped at normalization; (2) foreign, never-registered repo blocked via base_mismatch; (3) the STRONGER proof — two REAL, concurrently-alive sibling worktrees of the SAME repo, path/branch swapped between them, blocked via branch_mismatch in both directions, both survive untouched. Investigation concluded the swap is not a reachable gap (git's own branch-per-worktree uniqueness + globally collision-checked quick_id-derived branch names) — see `40-design.md` §9.2. |
| Later waves start from the current merged batch base | `gsd-core/workflows/quick-batch/steps/merge-wave.md` Step 7 design; `tests/quick-batch.test.cjs` wave recompute tests |
| Merge applies committed-diff-vs-declared-scope validation; reports scope drift without silently merging it | `tests/gsd-quick-batch-merge-integration.test.cjs` (undeclared-DELETION blocking, Phase 4) **+ NEW**: "advisory scope drift merges but warns" describe block (drift produces `scope_out_of_declared` warning + still merges; exact-match boundary case produces zero warnings) |
| Child workers never concurrently switch the main checkout; ≤1 aggregate branch | `gsd-core/workflows/quick-batch/steps/worktree-dispatch.md` "ONE AT A TIME" serialization test |
| Each merged item retains atomic implementation commit history | `tests/gsd-quick-batch-merge-integration.test.cjs` (`--no-ff` real-git merges preserve commit history) |
| Base divergence, merge conflict, stale worktree, submodule-touch, interrupted cleanup produce recoverable diagnostics | Base divergence: `resumeBatch`'s `currentBaseRevision` check (`tests/quick-batch.test.cjs`). Merge conflict: `tests/gsd-quick-batch-merge-integration.test.cjs` (Phase 4). Stale worktree / interrupted cleanup: `worktree-safety.test.cjs`'s existing mid-merge halt coverage (unchanged this phase) + `docs/how-to/batch-quick-tasks.md` **NEW** "Diagnosing a preserved worktree" subsection. Submodule-touch: `tests/gsd-quick-batch-merge-integration.test.cjs` **NEW** ".gitmodules submodule integration" describe block (3 tests: unrelated plan merges cleanly with `.gitmodules` present; a real gitlink pointer bump merges and the superproject tree reflects the new pinned commit; an undeclared bump is advisory-only and surfaces a `vendor/sub` scope warning) |
| Worktree create/merge/cleanup serialized and manifest-scoped; never sweeps/deletes an unowned worktree | `tests/msd-quick-batch-merge-integration.test.cjs` — **NEW/REVISED (review pass 2)**: "arbitrary-worktree ownership tampering" describe block, 3 tests: (1) tampered branch name silently dropped at normalization; (2) foreign, never-registered repo blocked via base_mismatch; (3) the STRONGER proof — two REAL, concurrently-alive sibling worktrees of the SAME repo, path/branch swapped between them, blocked via branch_mismatch in both directions, both survive untouched. Investigation concluded the swap is not a reachable gap (git's own branch-per-worktree uniqueness + globally collision-checked quick_id-derived branch names) — see `40-design.md` §9.2. |
| Later waves start from the current merged batch base | `msd-core/workflows/quick-batch/steps/merge-wave.md` Step 7 design; `tests/quick-batch.test.cjs` wave recompute tests |
| Merge applies committed-diff-vs-declared-scope validation; reports scope drift without silently merging it | `tests/msd-quick-batch-merge-integration.test.cjs` (undeclared-DELETION blocking, Phase 4) **+ NEW**: "advisory scope drift merges but warns" describe block (drift produces `scope_out_of_declared` warning + still merges; exact-match boundary case produces zero warnings) |
| Child workers never concurrently switch the main checkout; ≤1 aggregate branch | `msd-core/workflows/quick-batch/steps/worktree-dispatch.md` "ONE AT A TIME" serialization test |
| Each merged item retains atomic implementation commit history | `tests/msd-quick-batch-merge-integration.test.cjs` (`--no-ff` real-git merges preserve commit history) |
| Base divergence, merge conflict, stale worktree, submodule-touch, interrupted cleanup produce recoverable diagnostics | Base divergence: `resumeBatch`'s `currentBaseRevision` check (`tests/quick-batch.test.cjs`). Merge conflict: `tests/msd-quick-batch-merge-integration.test.cjs` (Phase 4). Stale worktree / interrupted cleanup: `worktree-safety.test.cjs`'s existing mid-merge halt coverage (unchanged this phase) + `docs/how-to/batch-quick-tasks.md` **NEW** "Diagnosing a preserved worktree" subsection. Submodule-touch: `tests/msd-quick-batch-merge-integration.test.cjs` **NEW** ".gitmodules submodule integration" describe block (3 tests: unrelated plan merges cleanly with `.gitmodules` present; a real gitlink pointer bump merges and the superproject tree reflects the new pinned commit; an undeclared bump is advisory-only and surfaces a `vendor/sub` scope warning) |
## State, failure, and resume
| AC bullet | Evidence |
|---|---|
| Leaves cannot write shared STATE.md/ROADMAP.md; coordinator is sole writer | `tests/gsd-quick-batch-workflow.test.cjs` single-writer invariant test |
| Leaves cannot write shared STATE.md/ROADMAP.md; coordinator is sole writer | `tests/msd-quick-batch-workflow.test.cjs` single-writer invariant test |
| Completed rows appended atomically, exactly once, including after resume | `src/quick-batch.cts` `completeQuickItem`/`hasQuickTaskRow`; `tests/quick-batch.test.cjs` idempotency tests |
| Failure of one item doesn't roll back others | `tests/quick-batch-dispatch.test.cjs` routing isolation tests; `worktree-safety.cts`'s `#2852` per-entry isolation (`blockEntry`/`continue`) |
| Failed item recorded failed; dependents recorded blocked; unrelated pending continue | `tests/quick-batch.test.cjs` `resumeBatch` blocked-propagation fixed-point tests |
| `--resume` skips complete, retries only eligible non-complete, idempotent | `tests/quick-batch.test.cjs` `resumeBatch` tests **+ NEW fix**: `gsd-core/workflows/quick-batch/steps/worktree-dispatch.md` Step 6 substep 1 crash-window guard (a `pending` item whose `SUMMARY.md` already exists on disk — executor finished, coordinator crashed before Step 7's merge — is no longer re-dispatched into a second worktree on `--resume`; it falls through to Step 7's existing SUMMARY.md-on-disk merge criterion instead). Regression-tested structurally in `tests/gsd-quick-batch-workflow.test.cjs` "crash-window duplicate-dispatch guard" describe block (3 tests: guard text present, guard positioned before `spawn-plan` is computed, guard documents the merge-wave.md recovery path). **This was the one genuine functional gap found in this phase** — see `.gsd/phase/feat-3677-quick-batch-hardening-acceptance/40-design.md` §1 for the full trace. |
| `--resume` skips complete, retries only eligible non-complete, idempotent | `tests/quick-batch.test.cjs` `resumeBatch` tests **+ NEW fix**: `msd-core/workflows/quick-batch/steps/worktree-dispatch.md` Step 6 substep 1 crash-window guard (a `pending` item whose `SUMMARY.md` already exists on disk — executor finished, coordinator crashed before Step 7's merge — is no longer re-dispatched into a second worktree on `--resume`; it falls through to Step 7's existing SUMMARY.md-on-disk merge criterion instead). Regression-tested structurally in `tests/msd-quick-batch-workflow.test.cjs` "crash-window duplicate-dispatch guard" describe block (3 tests: guard text present, guard positioned before `spawn-plan` is computed, guard documents the merge-wave.md recovery path). **This was the one genuine functional gap found in this phase** — see `.msd/phase/feat-3677-quick-batch-hardening-acceptance/40-design.md` §1 for the full trace. |
| Invalid/corrupt batch manifest fails closed, no guessing | `tests/quick-batch.test.cjs` `loadBatch` malformed-JSON tests |
## Security, portability, and project quality
| AC bullet | Evidence |
|---|---|
| `--file` rejects traversal/symlink-escape/special files/outside-root; task text untrusted in prompts | `tests/quick-batch.test.cjs`/`.property.test.cjs` (Phase 3/4 review-fixed findings); `tests/gsd-quick-batch-workflow.test.cjs` DATA_START/DATA_END boundary tests |
| `--file` rejects traversal/symlink-escape/special files/outside-root; task text untrusted in prompts | `tests/quick-batch.test.cjs`/`.property.test.cjs` (Phase 3/4 review-fixed findings); `tests/msd-quick-batch-workflow.test.cjs` DATA_START/DATA_END boundary tests |
| Paths with spaces, duplicate slugs, Windows separators, BSD/GNU differences, non-ASCII descriptions | `tests/quick-batch.test.cjs`/`.property.test.cjs` (slug generation, cross-platform path tests) |
| Workflow stays within size budget via shared fragments | `tests/gsd-quick-batch-workflow.test.cjs` byte-size boundary describe block (NEW_FILE_CAP); this phase's `worktree-dispatch.md` addition re-verified at 9.8KB, well under cap |
| Workflow stays within size budget via shared fragments | `tests/msd-quick-batch-workflow.test.cjs` byte-size boundary describe block (NEW_FILE_CAP); this phase's `worktree-dispatch.md` addition re-verified at 9.8KB, well under cap |
| Capacity axis backward-compatible, fails closed when absent | Phase 1/2 host-integration descriptor tests |
| #2652/PR #2728 resolved; no `RUNTIME != "claude"` gate copied | `gsd-core/references/dispatch-isolation-gate.md` reuse (Phase 4 design) |
| #2652/PR #2728 resolved; no `RUNTIME != "claude"` gate copied | `msd-core/references/dispatch-isolation-gate.md` reuse (Phase 4 design) |
| Canonical command Markdown / generated skill byte-for-byte synced | Repo-wide generated-sync lint (unchanged this phase; no new command surface) |
| Utility-cluster/profile/surface/inventory/installer/generated-artifact/doc parity | Repo-wide parity tests (unchanged this phase) |
| TDD/failing-test-first; Markdown behavior tested where applicable | Every new test in this phase written RED-first per its own commit; `tests/gsd-quick-batch-workflow.test.cjs`'s established structural-assertion convention for workflow prose |
| `npm test`, `npm run lint:ci`, generated-sync, required platform lanes pass | Verified via `gsd-test` before this PR ships (not run as part of this dispatch — reported separately) |
| TDD/failing-test-first; Markdown behavior tested where applicable | Every new test in this phase written RED-first per its own commit; `tests/msd-quick-batch-workflow.test.cjs`'s established structural-assertion convention for workflow prose |
| `npm test`, `npm run lint:ci`, generated-sync, required platform lanes pass | Verified via `msd-test` before this PR ships (not run as part of this dispatch — reported separately) |
## #3677's own acceptance criteria (this phase issue)
@@ -84,9 +84,9 @@ is the evidence submitted for that acceptance, not a closure action.
| Outcome propagation; blocked dependents; independent continuation | Phase 3, unchanged |
| Docs: v1 limits | Phase 4, unchanged (`docs/how-to/batch-quick-tasks.md`) |
| Generated artifact sync | Repo-wide, unchanged (no new command surface this phase) |
| `/gsd:quick` regression + quick-ID grammar green | `tests/gsd-quick-batch-quick-regression.test.cjs`, unchanged |
| `/msd:quick` regression + quick-ID grammar green | `tests/msd-quick-batch-quick-regression.test.cjs`, unchanged |
| Docs: **preserved-worktree diagnosis** | **NEW**, this phase — `docs/how-to/batch-quick-tasks.md` "Diagnosing a preserved worktree" subsection |
| Focused tests / `npm test` / `npm run lint:ci` / generated-sync / install / platform lanes green | Verified via `gsd-test` before this PR ships |
| Focused tests / `npm test` / `npm run lint:ci` / generated-sync / install / platform lanes green | Verified via `msd-test` before this PR ships |
| Real-PR-number changeset; no hand-edited CHANGELOG | Added after PR creation, per repo convention |
| Final verification maps evidence to #3344 | This document |
| RED/GREEN/REFACTOR commits; closes #3677 only | This PR's commit history; PR body closes #3677, references #3344 without closing it |

View File

@@ -1,5 +1,5 @@
/**
* GSD plugin for OpenCode.ai (CommonJS)
* MSD plugin for OpenCode.ai (CommonJS)
*
* Architecture: SUBPROCESS REUSE. Instead of re-implementing hook logic inside
* the plugin, this file is a thin adapter that spawns the existing Claude Code
@@ -11,36 +11,36 @@
* - block → throw Error (OpenCode returns the error to the model)
* - advisory → output.metadata + console.error (best-effort surfacing)
*
* Namespace conversion (/gsd:xxx → /gsd-xxx) reuses scripts/fix-slash-commands.cjs
* Namespace conversion (/msd:xxx → /msd-xxx) reuses scripts/fix-slash-commands.cjs
* via require(), keeping the single source of truth.
*
* ── Two distribution shapes, one adapter (issue #1914) ─────────────────────
* This single file serves both distribution paths, distinguished at load time
* by REPO_ROOT (path.resolve(__dirname, "../..")):
*
* • Option 1 — file copy (the supported GSD path). `bin/install.js` copies
* this file to <opencodeConfigDir>/plugins/gsd-core.js, so REPO_ROOT is the
* OpenCode config dir. GSD's own install already stages `hooks/*.js` and
* `gsd-core/` there (ADR-857 skips hook *registration* for OpenCode, not the
* • Option 1 — file copy (the supported MSD path). `bin/install.js` copies
* this file to <opencodeConfigDir>/plugins/msd-core.js, so REPO_ROOT is the
* OpenCode config dir. MSD's own install already stages `hooks/*.js` and
* `msd-core/` there (ADR-857 skips hook *registration* for OpenCode, not the
* file copy), so the hook bridge and content rewriting resolve natively.
* Commands/agents/skills are ALREADY registered by GSD's native file copy in
* Commands/agents/skills are ALREADY registered by MSD's native file copy in
* this mode, so the plugin's own config-hook registration is redundant and is
* SKIPPED (see IS_PACKAGE_TREE) to avoid double-registration.
*
* • Option 2 — package / git-spec. When loaded from the package tree (npm
* `main`, or an OpenCode git-spec install), REPO_ROOT is the package root and
* the source layout (commands/gsd/, agents/, skills/) is present. Here the
* the source layout (commands/msd/, agents/, skills/) is present. Here the
* plugin IS the sole registrar, so it registers commands/agents/skills too.
*
* IS_PACKAGE_TREE keys off the presence of the SOURCE command layout
* (commands/gsd/), which only exists in the package tree — never in an installed
* (commands/msd/), which only exists in the package tree — never in an installed
* config dir (that uses the flattened command/ layout). The hook bridge and
* Read-time content rewriting run in BOTH modes; only the config-hook
* registration of commands/agents/skills is gated.
*
* Runtime-specific hooks are deliberately excluded:
* - gsd-statusline.js / gsd-update-banner.js (Claude Code statusline)
* - gsd-cursor-*.js (Cursor-specific)
* - msd-statusline.js / msd-update-banner.js (Claude Code statusline)
* - msd-cursor-*.js (Cursor-specific)
* - *.sh scripts (invoked directly by commands/agents, not hook events)
*/
@@ -51,12 +51,12 @@ const fs = require("fs");
const os = require("os");
const { spawnSync } = require("child_process");
// Resolve REPO_ROOT to the directory that actually holds the GSD payload
// (hooks/ + gsd-core/). This must work across three physical layouts because a
// Resolve REPO_ROOT to the directory that actually holds the MSD payload
// (hooks/ + msd-core/). This must work across three physical layouts because a
// single adapter file serves both distribution shapes (see header):
// • package/git-spec tree: <root>/.opencode/plugins/gsd-core.js → <root>
// • global file-copy: ~/.config/opencode/plugins/gsd-core.js → ~/.config/opencode
// • local file-copy: <proj>/.opencode/plugins/gsd-core.js → <proj>/.opencode
// • package/git-spec tree: <root>/.opencode/plugins/msd-core.js → <root>
// • global file-copy: ~/.config/opencode/plugins/msd-core.js → ~/.config/opencode
// • local file-copy: <proj>/.opencode/plugins/msd-core.js → <proj>/.opencode
// A fixed "../.." only works for the first; the copied layouts sit one level
// shallower. Walking up to the first ancestor containing BOTH payload markers
// resolves all three deterministically. Falls back to the package-tree
@@ -66,7 +66,7 @@ function resolveRepoRoot(startDir) {
for (let i = 0; i < 6; i++) {
if (
fs.existsSync(path.join(dir, "hooks")) &&
fs.existsSync(path.join(dir, "gsd-core"))
fs.existsSync(path.join(dir, "msd-core"))
) {
return dir;
}
@@ -84,16 +84,16 @@ function resolveRepoRoot(startDir) {
// CJS: __dirname is a global, no need to derive from import.meta.url
const REPO_ROOT = resolveRepoRoot(__dirname);
const HOOKS_DIR = path.join(REPO_ROOT, "hooks");
const COMMANDS = path.join(REPO_ROOT, "commands", "gsd");
const COMMANDS = path.join(REPO_ROOT, "commands", "msd");
const AGENTS = path.join(REPO_ROOT, "agents");
const SKILLS = path.join(REPO_ROOT, "skills");
const GSD_CORE = path.join(REPO_ROOT, "gsd-core");
const MSD_CORE = path.join(REPO_ROOT, "msd-core");
// True only when loaded from the package/source tree (Option 2), detected by the
// presence of the SOURCE command layout (commands/gsd/). In an installed OpenCode
// presence of the SOURCE command layout (commands/msd/). In an installed OpenCode
// config dir (Option 1) this directory is absent — the flattened command/ layout
// is used instead — so the plugin skips its own command/agent/skill registration
// and lets GSD's native file copy own that surface (avoids double-registration).
// and lets MSD's native file copy own that surface (avoids double-registration).
const IS_PACKAGE_TREE = fs.existsSync(COMMANDS);
// ---------------------------------------------------------------------------
@@ -198,7 +198,7 @@ function mapToolInput(args) {
* - exit 2: block (Claude convention; reason in stdout JSON)
* - any error: exit 0 silently (hooks swallow their own errors)
*
* @param {string} hookFile filename under hooks/, e.g. "gsd-prompt-guard.js"
* @param {string} hookFile filename under hooks/, e.g. "msd-prompt-guard.js"
* @param {object} payload stdin JSON (hook_event_name, tool_name, ...)
* @param {object} [opts]
* @param {number} [opts.timeout=8000] spawn timeout in ms
@@ -217,9 +217,9 @@ function runHook(hookFile, payload, opts = {}) {
if (!warnedMissingHooks.has(hookFile)) {
warnedMissingHooks.add(hookFile);
console.error(
`[gsd-core] hook script missing: ${hookPath} — ${hookFile} is NOT ` +
"enforced. The GSD install may be incomplete; reinstall (or run " +
"/gsd-update) to restage the hooks/ bundle.",
`[msd-core] hook script missing: ${hookPath} — ${hookFile} is NOT ` +
"enforced. The MSD install may be incomplete; reinstall (or run " +
"/msd-update) to restage the hooks/ bundle.",
);
}
return { stdout: "", exitCode: 0, timedOut: false };
@@ -247,7 +247,7 @@ function runHook(hookFile, payload, opts = {}) {
/**
* In-process check for whether context-usage warnings are disabled in project
* config. Mirrors the exact semantics of the same check inside
* hooks/gsd-context-monitor.js (introduced by #1073): an explicit
* hooks/msd-context-monitor.js (introduced by #1073): an explicit
* `config.hooks.context_warnings === false` disables them; a missing or
* unparseable .planning/config.json keeps them enabled (the default).
*
@@ -278,7 +278,7 @@ function contextWarningsDisabled(cwd) {
* Parse a hook's stdout and apply its effect to the OpenCode output object.
*
* - Block → throw Error(parsed.reason) so OpenCode aborts the tool call
* - Advisory→ append to output.metadata._gsdAdvisory[] and log to stderr
* - Advisory→ append to output.metadata._msdAdvisory[] and log to stderr
* - Silent → no-op
*
* @param {{ stdout: string, exitCode: number }} hookResult
@@ -301,7 +301,7 @@ function handleHookResult(hookResult, output) {
const isBlock = exitCode === 2 || (parsed && parsed.decision === "block");
if (isBlock) {
const reason =
(parsed && parsed.reason) || "Blocked by GSD hook (no reason provided).";
(parsed && parsed.reason) || "Blocked by MSD hook (no reason provided).";
throw new Error(reason);
}
@@ -317,10 +317,10 @@ function handleHookResult(hookResult, output) {
// sequence (prompt guard, read guard, worktree guard, workflow guard).
// Storing a scalar would let a later advisory clobber an earlier one, so
// collect them all.
if (!Array.isArray(output.metadata._gsdAdvisory)) {
output.metadata._gsdAdvisory = [];
if (!Array.isArray(output.metadata._msdAdvisory)) {
output.metadata._msdAdvisory = [];
}
output.metadata._gsdAdvisory.push(advisory);
output.metadata._msdAdvisory.push(advisory);
}
// Best-effort visibility when metadata isn't surfaced to the model
console.error(advisory);
@@ -347,7 +347,7 @@ function parseFrontmatter(content) {
}
// Rewrite @~/.claude/ includes to point at the repo root.
// Also applies /gsd:xxx → /gsd-xxx namespace conversion via the shared
// Also applies /msd:xxx → /msd-xxx namespace conversion via the shared
// transform from scripts/fix-slash-commands.cjs (single source of truth).
function rewriteRefs(content) {
let out = content.replace(/@~\/\.claude\//g, `@${REPO_ROOT}/`);
@@ -370,38 +370,38 @@ function loadDir(dir, keyFn, valFn) {
}
// ---------------------------------------------------------------------------
// Runtime content transform — for Read tool results on GSD-managed files
// Runtime content transform — for Read tool results on MSD-managed files
// ---------------------------------------------------------------------------
// Directories whose .md files may contain ~/.claude/ paths and gsd: namespace
// Directories whose .md files may contain ~/.claude/ paths and msd: namespace
// refs. When the model reads these via the Read tool, we transparently rewrite
// both so OpenCode sees correct paths and hyphen-form command names.
const GSD_MANAGED_DIRS = [
path.join(GSD_CORE, "workflows"),
path.join(GSD_CORE, "references"),
path.join(GSD_CORE, "templates"),
path.join(GSD_CORE, "contexts"),
const MSD_MANAGED_DIRS = [
path.join(MSD_CORE, "workflows"),
path.join(MSD_CORE, "references"),
path.join(MSD_CORE, "templates"),
path.join(MSD_CORE, "contexts"),
COMMANDS,
AGENTS,
SKILLS,
];
function isGsdManagedFile(filePath) {
function isMsdManagedFile(filePath) {
if (!filePath) return false;
const resolved = path.resolve(filePath);
return GSD_MANAGED_DIRS.some(
return MSD_MANAGED_DIRS.some(
(dir) => resolved === dir || resolved.startsWith(dir + path.sep),
);
}
// Rewrite content for OpenCode consumption:
// 1. @-include paths: @~/.claude/ → @<REPO_ROOT>/
// 2. plain-text paths: ~/.claude/gsd-core/ → <GSD_CORE>/
// 3. namespace: gsd:xxx → gsd-xxx (via fix-slash-commands.cjs)
// 2. plain-text paths: ~/.claude/msd-core/ → <MSD_CORE>/
// 3. namespace: msd:xxx → msd-xxx (via fix-slash-commands.cjs)
function rewriteContent(content) {
let out = content;
out = out.replace(/@~\/\.claude\//g, `@${REPO_ROOT}/`);
out = out.replace(/~\/\.claude\/gsd-core\//g, `${GSD_CORE}/`);
out = out.replace(/~\/\.claude\/msd-core\//g, `${MSD_CORE}/`);
const transform = getNamespaceConverter();
if (transform && _cmdNames && _cmdNames.length) {
out = transform(out, _cmdNames);
@@ -415,18 +415,18 @@ function rewriteContent(content) {
//
// OpenCode's skill loader reads SKILL.md files directly from disk and resolves
// @-includes internally — this bypasses our tool.execute hooks. To make
// @~/.claude/gsd-core/... includes resolve, we copy all SKILL.md files to a
// cache directory with paths rewritten to the actual GSD_CORE location.
// @~/.claude/msd-core/... includes resolve, we copy all SKILL.md files to a
// cache directory with paths rewritten to the actual MSD_CORE location.
//
// Only used in package-tree mode (Option 2). In an installed OpenCode config
// dir (Option 1) skills are already staged + registered by GSD's native file
// dir (Option 1) skills are already staged + registered by MSD's native file
// copy, so we never register skills from the plugin (see IS_PACKAGE_TREE).
const SKILLS_CACHE = path.join(
os.homedir(),
".cache",
"opencode",
"gsd-skills",
"msd-skills",
);
function prepareSkillsCache() {
@@ -439,8 +439,8 @@ function prepareSkillsCache() {
// Rewrite @-include paths only; namespace conversion is handled at
// Read-time via tool.execute.after for workflow/reference files.
const rewritten = raw
.replace(/@~\/\.claude\/gsd-core\//g, `@${GSD_CORE}/`)
.replace(/~\/\.claude\/gsd-core\//g, `${GSD_CORE}/`);
.replace(/@~\/\.claude\/msd-core\//g, `@${MSD_CORE}/`)
.replace(/~\/\.claude\/msd-core\//g, `${MSD_CORE}/`);
const destDir = path.join(SKILLS_CACHE, dir);
fs.mkdirSync(destDir, { recursive: true });
fs.writeFileSync(path.join(destDir, "SKILL.md"), rewritten);
@@ -452,25 +452,25 @@ function prepareSkillsCache() {
// Plugin entry
// ===========================================================================
const GsdCorePlugin = async ({ directory } = {}) => {
const MsdCorePlugin = async ({ directory } = {}) => {
if (directory) currentCwd = directory;
return {
// ── Config: register commands / agents / skills paths ──────────────
// Only in package-tree mode (Option 2). In an installed config dir
// (Option 1) GSD's native file copy already registered these, so the
// (Option 1) MSD's native file copy already registered these, so the
// plugin stays out of registration to avoid double-registering.
config: async (config) => {
if (!IS_PACKAGE_TREE) return;
// Commands (commands/gsd/*.md → gsd-<name>)
// Commands (commands/msd/*.md → msd-<name>)
config.command = config.command || {};
const cmds = loadDir(
COMMANDS,
(f) => "gsd-" + f.slice(0, -3),
(f) => "msd-" + f.slice(0, -3),
(body, fm, name) => ({
template: rewriteRefs(body.trim()),
description: fm.description || `GSD ${name.slice(0, -3)} command`,
description: fm.description || `MSD ${name.slice(0, -3)} command`,
}),
);
for (const [k, v] of Object.entries(cmds)) {
@@ -484,7 +484,7 @@ const GsdCorePlugin = async ({ directory } = {}) => {
(f) => f.slice(0, -3),
(body, fm, name) => ({
prompt: rewriteRefs(body.trim()),
description: fm.description || `GSD ${name.slice(0, -3)} agent`,
description: fm.description || `MSD ${name.slice(0, -3)} agent`,
mode: fm.mode || "subagent",
}),
);
@@ -508,7 +508,7 @@ const GsdCorePlugin = async ({ directory } = {}) => {
// ── shell.env ───────────────────────────────────────────────────────
"shell.env": async (_input, output) => {
output.env = output.env || {};
output.env.GSD_DIR = GSD_CORE;
output.env.MSD_DIR = MSD_CORE;
},
// ── tool.execute.before — PreToolUse hooks ─────────────────────────
@@ -517,14 +517,14 @@ const GsdCorePlugin = async ({ directory } = {}) => {
const toolInput = mapToolInput(output.args || {});
const cwd = currentCwd;
// 0. Read path rewrite — redirect ~/.claude/gsd-core/ to actual GSD_CORE
// 0. Read path rewrite — redirect ~/.claude/msd-core/ to actual MSD_CORE
// so the model can read workflow/reference/template files that SKILL.md
// and command templates reference via the canonical Claude path.
if (claudeTool === "Read" && toolInput.file_path) {
const original = toolInput.file_path;
const rewritten = original
.replace(/^~\/\.claude\/gsd-core\//, GSD_CORE + "/")
.replace(/(?:.*)\/\.claude\/gsd-core\//, GSD_CORE + "/");
.replace(/^~\/\.claude\/msd-core\//, MSD_CORE + "/")
.replace(/(?:.*)\/\.claude\/msd-core\//, MSD_CORE + "/");
if (rewritten !== original) {
const args = output.args || {};
if (args.filePath) args.filePath = rewritten;
@@ -539,7 +539,7 @@ const GsdCorePlugin = async ({ directory } = {}) => {
cwd,
};
// NOTE: session_id intentionally omitted for PreToolUse hooks.
// gsd-read-guard.js treats a non-empty session_id as a Claude Code
// msd-read-guard.js treats a non-empty session_id as a Claude Code
// session and skips its advisory. On OpenCode we WANT the advisory.
const prePayload = (overrides = {}) => ({
...basePayload,
@@ -550,42 +550,42 @@ const GsdCorePlugin = async ({ directory } = {}) => {
const isWriteLike = ["Write", "Edit", "MultiEdit"].includes(claudeTool);
// 1. gsd-prompt-guard.js — injection scan on .planning/ writes
// 1. msd-prompt-guard.js — injection scan on .planning/ writes
if (claudeTool === "Write" || claudeTool === "Edit") {
const r = runHook("gsd-prompt-guard.js", prePayload());
const r = runHook("msd-prompt-guard.js", prePayload());
handleHookResult(r, output);
}
// 2. gsd-read-guard.js — read-before-edit advisory
// 2. msd-read-guard.js — read-before-edit advisory
if (claudeTool === "Write" || claudeTool === "Edit") {
const r = runHook("gsd-read-guard.js", prePayload());
const r = runHook("msd-read-guard.js", prePayload());
handleHookResult(r, output);
}
// 3. gsd-worktree-path-guard.js — hard-block edits outside worktree
// 3. msd-worktree-path-guard.js — hard-block edits outside worktree
if (isWriteLike) {
const r = runHook("gsd-worktree-path-guard.js", prePayload());
const r = runHook("msd-worktree-path-guard.js", prePayload());
handleHookResult(r, output);
}
// 4. gsd-write-guard.js — hard-block catastrophic shrink of curated
// 4. msd-write-guard.js — hard-block catastrophic shrink of curated
// .planning/ artifacts (ROADMAP.md, milestones/*-ROADMAP.md, STATE.md)
if (claudeTool === "Write") {
const r = runHook("gsd-write-guard.js", prePayload());
const r = runHook("msd-write-guard.js", prePayload());
handleHookResult(r, output);
}
// 5. gsd-workflow-guard.js — workflow advisory + git-force-add block
// 5. msd-workflow-guard.js — workflow advisory + git-force-add block
// (covers Write/Edit/MultiEdit AND Bash force-add detection)
if (isWriteLike || claudeTool === "Bash") {
const r = runHook("gsd-workflow-guard.js", prePayload());
const r = runHook("msd-workflow-guard.js", prePayload());
handleHookResult(r, output);
}
// 6. gsd-secret-read-guard.js — hard-block reads of .env / .env.<suffix> /
// 6. msd-secret-read-guard.js — hard-block reads of .env / .env.<suffix> /
// .secrets via Read (file_path), Grep (path or glob) and Bash (command)
if (["Read", "Grep", "Bash"].includes(claudeTool)) {
const r = runHook("gsd-secret-read-guard.js", prePayload());
const r = runHook("msd-secret-read-guard.js", prePayload());
handleHookResult(r, output);
}
},
@@ -598,12 +598,12 @@ const GsdCorePlugin = async ({ directory } = {}) => {
const toolInput = mapToolInput(input.args || {});
const cwd = currentCwd;
// GSD content transform — rewrite paths + namespace in Read results
// MSD content transform — rewrite paths + namespace in Read results
// BEFORE injection scanning so the scanner sees the final content.
if (
claudeTool === "Read" &&
output.output &&
isGsdManagedFile(toolInput.file_path)
isMsdManagedFile(toolInput.file_path)
) {
const content =
typeof output.output === "string"
@@ -612,7 +612,7 @@ const GsdCorePlugin = async ({ directory } = {}) => {
output.output = rewriteContent(content);
}
// gsd-read-injection-scanner.js — scan Read/WebFetch/WebSearch results
// msd-read-injection-scanner.js — scan Read/WebFetch/WebSearch results
if (
claudeTool === "Read" ||
claudeTool === "WebFetch" ||
@@ -625,12 +625,12 @@ const GsdCorePlugin = async ({ directory } = {}) => {
tool_response: output.output,
cwd,
};
const r = runHook("gsd-read-injection-scanner.js", payload);
const r = runHook("msd-read-injection-scanner.js", payload);
handleHookResult(r, output);
return;
}
// gsd-context-monitor.js — context usage warnings (Bash/Edit/Write/Task/...)
// msd-context-monitor.js — context usage warnings (Bash/Edit/Write/Task/...)
// Only meaningful when a session_id is tracked (writes metrics sentinel).
// #2697: skip the subprocess spawn entirely when context warnings are
// explicitly disabled in project config — the hook would exit early anyway,
@@ -644,7 +644,7 @@ const GsdCorePlugin = async ({ directory } = {}) => {
session_id: currentSessionId,
cwd,
};
const r = runHook("gsd-context-monitor.js", payload);
const r = runHook("msd-context-monitor.js", payload);
handleHookResult(r, output);
}
},
@@ -657,13 +657,13 @@ const GsdCorePlugin = async ({ directory } = {}) => {
session_id: currentSessionId,
cwd: currentCwd,
};
const r = runHook("gsd-context-monitor.js", payload);
const r = runHook("msd-context-monitor.js", payload);
handleHookResult(r, output);
// Also inject a GSD compaction breadcrumb (mirrors the original plugin)
// Also inject a MSD compaction breadcrumb (mirrors the original plugin)
output.context = output.context || [];
output.context.push(
`[GSD] Active session: ${currentSessionId}. Preserve any in-flight phase/plan state.`,
`[MSD] Active session: ${currentSessionId}. Preserve any in-flight phase/plan state.`,
);
},
@@ -679,14 +679,14 @@ const GsdCorePlugin = async ({ directory } = {}) => {
info?.id || event.sessionID || event.session_id || null;
if (info?.directory) currentCwd = info.directory;
// gsd-ensure-canonical-path.js — no stdin dependency; silent
runHook("gsd-ensure-canonical-path.js", {
// msd-ensure-canonical-path.js — no stdin dependency; silent
runHook("msd-ensure-canonical-path.js", {
hook_event_name: "SessionStart",
session_id: currentSessionId,
cwd: currentCwd,
});
// gsd-check-update.js — spawns its own background worker; no stdin
runHook("gsd-check-update.js", {
// msd-check-update.js — spawns its own background worker; no stdin
runHook("msd-check-update.js", {
hook_event_name: "SessionStart",
session_id: currentSessionId,
cwd: currentCwd,
@@ -709,17 +709,17 @@ const GsdCorePlugin = async ({ directory } = {}) => {
event: "change",
cwd,
};
const r = runHook("gsd-config-reload.js", payload);
const r = runHook("msd-config-reload.js", payload);
// Advisory-only (additionalContext); surface to logs
handleHookResult(r);
return;
}
// session.idle ↔ Claude Stop lifecycle point (#1682 Slice 1b/c).
// OpenCode fires session.idle when the run quiesces. GSD maps it to the
// OpenCode fires session.idle when the run quiesces. MSD maps it to the
// Stop equivalent — the opencode-subset lifecycle peer of compaction
// (compaction preserves state across context-window summarization; idle
// marks end-of-turn). No-op sentinel today (GSD state is already
// marks end-of-turn). No-op sentinel today (MSD state is already
// persisted to .planning/), but it MUST be recognized so the declared
// opencode-subset surface is fully wired and a future Stop-class hook can
// attach without a plugin change.
@@ -728,9 +728,9 @@ const GsdCorePlugin = async ({ directory } = {}) => {
}
// permission.asked / permission.replied — OpenCode permission lifecycle
// (#2087, opencode.ai/docs/plugins). GSD gates tool INPUTS at
// (#2087, opencode.ai/docs/plugins). MSD gates tool INPUTS at
// tool.execute.before (read-guard, injection-scanner); the permission
// grant/deny decision itself carries no GSD workflow-phase contribution,
// grant/deny decision itself carries no MSD workflow-phase contribution,
// so these are recognized sentinels — wired so a future permission-aware
// gate can attach without a plugin change (the engine owns phase
// sequencing; this host bus is session/tool/permission-scoped, never
@@ -739,7 +739,7 @@ const GsdCorePlugin = async ({ directory } = {}) => {
return;
}
// session.error — OpenCode session-error lifecycle point (#2087). No GSD
// session.error — OpenCode session-error lifecycle point (#2087). No MSD
// hook fires here today (loop state is already persisted to .planning/);
// recognized so the declared extension-event surface is fully wired and a
// future error-class hook can attach without a plugin change.
@@ -761,7 +761,7 @@ const GsdCorePlugin = async ({ directory } = {}) => {
// The subtlety: depending on how OpenCode's runtime (Node or Bun) imports a
// CommonJS file, `mod` may be the raw `module.exports` OR an ESM namespace of
// the form `{ default: module.exports, ...syntheticNamedExports }`. A plain
// `module.exports = { id: "gsd-core", server }` literal risks a string `id`
// `module.exports = { id: "msd-core", server }` literal risks a string `id`
// appearing in `Object.values(mod)` (as a raw property, or as a lexer-
// synthesized named export) — which would trip the throw. Two defenses:
// 1. `id` is defined NON-ENUMERABLE, so it never appears in Object.values yet
@@ -772,23 +772,23 @@ const GsdCorePlugin = async ({ directory } = {}) => {
// Result: raw-CJS `Object.values` = `[server]`; ESM `Object.values` =
// `[{server, <id non-enum>}]` — both fully extractable. Test-only helpers hang
// off the `server` FUNCTION (`server._internals`), never as a sibling export.
GsdCorePlugin._internals = {
MsdCorePlugin._internals = {
REPO_ROOT,
IS_PACKAGE_TREE,
mapToolName,
mapToolInput,
parseFrontmatter,
rewriteContent,
isGsdManagedFile,
isMsdManagedFile,
handleHookResult,
GsdCorePlugin,
MsdCorePlugin,
};
const gsdCorePluginExport = { server: GsdCorePlugin };
Object.defineProperty(gsdCorePluginExport, "id", {
value: "gsd-core",
const msdCorePluginExport = { server: MsdCorePlugin };
Object.defineProperty(msdCorePluginExport, "id", {
value: "msd-core",
enumerable: false,
writable: false,
configurable: false,
});
module.exports = gsdCorePluginExport;
module.exports = msdCorePluginExport;

View File

@@ -8,7 +8,7 @@
Move config-gated prose out of `agents/*.md` into `agents/templates/*.md.tmpl`,
rendered at install time and after `.planning/config.json` writes via a new
`gsd-sdk agents render` subcommand. Conditional branches resolve at render time
`msd-sdk agents render` subcommand. Conditional branches resolve at render time
(deterministic code) instead of at inference time (LLM interpretation).
Three named benefits:
@@ -20,7 +20,7 @@ Three named benefits:
Cites PR #2279 (Codex/OpenCode model embedding at install time) as direct
precedent for compile-time embedding.
## Why GSD does not own this
## Why MSD does not own this
### 1. The determinism claim is theoretical, not observed
@@ -28,15 +28,15 @@ The proposal's strongest argument is that config-gated branches in agent prose
are a determinism failure surface. The actual patterns in the codebase today are
already heavily mitigated:
- The `use_worktrees` branch in `gsd-executor` is resolved deterministically via
`gsd-sdk query config-get` in bash — it is not LLM-interpreted.
- The `use_worktrees` branch in `msd-executor` is resolved deterministically via
`msd-sdk query config-get` in bash — it is not LLM-interpreted.
- "Skip if `workflow.X` is `false`" prose patterns are short, stable, and
follow a uniform "missing key = enabled" convention. There is no documented
history of LLMs running disabled checks or skipping enabled ones because of
this prose.
A theoretical failure surface should not be traded for a real, high-risk
patch-migration surface (`gsd-local-patches/` rebase logic, by the reporter's own
patch-migration surface (`msd-local-patches/` rebase logic, by the reporter's own
admission "the highest-risk piece of the change"). The reporter was asked for
documented evidence; none was provided.
@@ -45,7 +45,7 @@ documented evidence; none was provided.
The codebase has roughly 5 `workflow.*` toggle references in agent files and
~20 "Skip if" conditional-prose patterns total — most 1–2 sentences. The
"real spend across multi-phase milestones" claim was not measured against
`gsd-context-monitor` output despite being asked. Without a measured baseline,
`msd-context-monitor` output despite being asked. Without a measured baseline,
the token-savings argument is asserted rather than demonstrated, and the savings
ceiling on ~20 short conditionals is small enough that it does not justify a new
template-and-rendering subsystem with a CI-enforced template/generated split.
@@ -68,7 +68,7 @@ reporter did not respond when asked for one.
### 4. Patch-migration risk is disproportionate to benefit
The `/gsd-reapply-patches` three-way-merge migration for `gsd-local-patches/`
The `/msd-reapply-patches` three-way-merge migration for `msd-local-patches/`
is, in the proposal's own words, the highest-risk piece of the change. It exists
solely to absorb a contributor-workflow shift — the user-facing surface is
unchanged. Risk that flows entirely from internal restructuring, where the
@@ -83,7 +83,7 @@ benefits that remain unmeasured and that PR #2279's path can absorb.
This may be revisited if a contributor:
- Provides measured token deltas via `gsd-context-monitor` against a
- Provides measured token deltas via `msd-context-monitor` against a
representative all-toggles-off config, and the delta is materially larger
than what extending PR #2279's orchestrator-embedding path one toggle at a
time would produce.
@@ -100,5 +100,5 @@ This may be revisited if a contributor:
precedent for deterministic compile-time embedding into agent files)
- v1.37.0 release notes — shared-boilerplate extraction (reference files for
mandatory-initial-read, project-skills-discovery)
- `gsd-core/workflows/` — workflow-level config embedding before subagent
- `msd-core/workflows/` — workflow-level config embedding before subagent
spawn (the path of least friction for incremental deterministic gating)

View File

@@ -1,4 +1,4 @@
# Codex-native GSD plugin, filed without a pre-proposal
# Codex-native MSD plugin, filed without a pre-proposal
**Source:** [#4027](https://github.com/open-gsd/gsd-core/issues/4027)
**Decision:** wontfix — No-go as filed; redirected to community-maintained distribution (EoS/Capability), not a first-party plugin
@@ -6,8 +6,8 @@
## Policy (standing, not case-by-case)
**GSD is not accepting new add-ons as first-party, maintainer-owned work at this
time — full stop.** A "plugin" proposal that asks gsd-core to own, package, and
**MSD is not accepting new add-ons as first-party, maintainer-owned work at this
time — full stop.** A "plugin" proposal that asks msd-core to own, package, and
maintain a new distribution surface is declined regardless of how well-executed
the implementation is; the supported path is community-maintained distribution
through the EoS Registry or the Capability system, where the author owns the
@@ -15,22 +15,22 @@ release cadence and maintenance. This is the same ground as new-runtime
requests (see [`crush-runtime-in-core.md`](./crush-runtime-in-core.md)) applied
to add-ons generally, not just runtimes. A future triage pass should apply this
without re-litigating whether a particular plugin proposal is good — the
question is only "is this asking gsd-core to own a new add-on," not "is the
question is only "is this asking msd-core to own a new add-on," not "is the
pre-proposal filed."
## Proposal summary
#4027 proposes an "official-format local Codex plugin" packaging GSD's existing
#4027 proposes an "official-format local Codex plugin" packaging MSD's existing
skills and MCP server: a read-only project control center (milestone/phase/plan/
verification/blocker status), a UAT workbench (review outstanding checks, record
pass/issue results), and structured MCP output for non-visual clients. It claims
to reuse the existing CLI, stdio MCP server, resource catalog, and npm package
with no new runtime dependency, hosted backend, duplicate command layer, or
persistent marketplace config. A working implementation allegedly exists on the
reporter's own fork branch (`yansigit/gsd-core:codex/gsd-codex-plugin`); the
reporter's own fork branch (`yansigit/msd-core:codex/msd-codex-plugin`); the
reporter offered to open a PR against the feature template if approved.
## Why GSD does not own this — as filed
## Why MSD does not own this — as filed
- **This repo has an established pre-proposal convention for first-party
plugin/marketplace-surface work that this issue skipped entirely.** The
@@ -53,16 +53,16 @@ reporter offered to open a PR against the feature template if approved.
## What this does NOT cover
This entry denies **gsd-core adopting this as first-party, maintainer-owned
This entry denies **msd-core adopting this as first-party, maintainer-owned
work.** It does not deny, and must never be cited against:
- **Shipping this as a community-maintained EoS host-plugin or Capability.**
Everything the proposal describes (control-center views, UAT workbench, MCP
output) can be built and distributed by the reporter today via the same path
as `gsd-cursor`/`gsd-omp`/`gsd-reasonix`, listed in the EoS Registry — with no
gsd-core changes and no maintainer packaging commitment.
- **The underlying idea of packaging GSD for Codex.** No judgment is made on
whether the idea is good — only that gsd-core will not be the one building,
as `msd-cursor`/`msd-omp`/`msd-reasonix`, listed in the EoS Registry — with no
msd-core changes and no maintainer packaging commitment.
- **The underlying idea of packaging MSD for Codex.** No judgment is made on
whether the idea is good — only that msd-core will not be the one building,
packaging, and maintaining it.
- **The reporter's fork implementation itself**, which was not reviewed as part
of this decision (reviewing an external fork's code is out of scope for
@@ -72,7 +72,7 @@ work.** It does not deny, and must never be cited against:
## Re-open criteria
- GSD reopens accepting new first-party add-ons/plugins in general (a policy
- MSD reopens accepting new first-party add-ons/plugins in general (a policy
change, not a per-proposal argument) — until then, this and every similar
"build/own X as a first-party plugin" request gets the same answer.
- Separately, and only if that policy changes: a pre-proposal doc filed under

View File

@@ -8,7 +8,7 @@
Reporter proposed an opt-in, Codex-only supervision adapter layered on the existing negotiated
`orchestrator-worktree` dispatch backend. For each selected executor the root would create the
existing GSD-managed worktree and launch one **native Codex supervisor subagent**, which owns
existing MSD-managed worktree and launch one **native Codex supervisor subagent**, which owns
exactly one external `codex exec --cd <worktree>` worker and surfaces evidence-backed progress in
Codex's native subagent UI as three strict states:
@@ -21,13 +21,13 @@ The supervisor would run the worker in the foreground (explicitly not background
behind a cosmetic status), consume the persisted lifecycle protocol proposed in #4624, and be
disabled by default with no behavior change for other runtimes or the default direct adapter.
## Why GSD does not own this
## Why MSD does not own this
- **The target surface cannot carry the states the proposal is built on.** Codex's native
subagent status is a fixed two-value enum — `CollabAgentToolCallStatus::{InProgress,
Completed}`, emitted by `wait_agent`. There is no free-text or custom status field. The
proposal's `executing` / `verifying` / `completed` triad cannot be rendered in that view **by
anyone, gsd-core included.** This is not a question of where the adapter lives, and it is the
anyone, msd-core included.** This is not a question of where the adapter lives, and it is the
decisive ground: the feature's central promise is not deliverable as specified.
- **The native subagent list is populated only by Codex's own `spawn_agent` / `wait_agent`
@@ -55,7 +55,7 @@ be checked against the runtime, which is why the mechanism problem surfaced at a
## What this does NOT cover
This entry denies **gsd-core building a second, core-resident dispatch adapter around Codex's
This entry denies **msd-core building a second, core-resident dispatch adapter around Codex's
native subagent UI.** Its keyword surface — supervisor, observability, worker state, lifecycle,
subagent, Codex, orchestrator-worktree — overlaps requests this decision deliberately does not
deny. Do not apply this entry to:
@@ -102,5 +102,5 @@ capable than the thing this entry declines, because it can express states the na
ground for this decision
- [ADR-857](../docs/adr/857-capability-system.md) — the capability system and its 12 loop extension
points
- `gsd-core/references/loop-hook-dispatch.md` — the `contribution` / `step` / `gate` hook contract
- `msd-core/references/loop-hook-dispatch.md` — the `contribution` / `step` / `gate` hook contract
- `capabilities/codex/capability.json` — existing Codex runtime support, unaffected

View File

@@ -17,7 +17,7 @@ skipped verdict as fresh.
This entry denies **the `commit_gates` config as filed.** It does not deny the underlying need.
## Why GSD does not own this (as filed)
## Why MSD does not own this (as filed)
- **The exact mechanism already exists in the capability system.** Since
[#2008](https://github.com/open-gsd/gsd-core/issues/2008) / ADR-2008, a capability can declare a
@@ -31,7 +31,7 @@ This entry denies **the `commit_gates` config as filed.** It does not deny the u
- **A second config would fragment the architecture.** `commit_gates` in `.planning/config.json`,
fired from `cmdCommit`, would coexist with capability `gates` in `capability.json`, fired from
the loop-resolver — two config locations, two override paths, two evaluators, and ambiguity
about which fires when. GSD deliberately owns one gate system; the capability gate is it.
about which fires when. MSD deliberately owns one gate system; the capability gate is it.
- **The right route is an extension of the existing system, not a parallel one.** There is **no
`commit:pre` loop point today.** The 12 canonical loop points
(`src/loop-resolver.cts` `CANONICAL_POINTS`: the `:pre`/`:post` pairs for `discuss`, `plan`,
@@ -57,7 +57,7 @@ not deny, and must never be cited against:
it is welcome as a capability-system proposal (new loop point + ADR-level schema note).
- **The companion defect.** [#3352](https://github.com/open-gsd/gsd-core/issues/3352) — reviewer
evidence is never verified, raw per-lane output is `rm -rf`'d, and an ungrounded `REVIEWS.md`
feeds `/gsd-plan-phase --reviews` — is confirmed-bug on its own merits and stays open. That a
feeds `/msd-plan-phase --reviews` — is confirmed-bug on its own merits and stays open. That a
full fix will likely *use* a commit-point gate does not make the `commit_gates` config the right
home for the gate mechanism.
- **New `check.predicate` kinds** added to the existing capability gate evaluator — a separate,
@@ -85,4 +85,4 @@ not deny, and must never be cited against:
reference
- [`docs/reference/capability-manifest.md`](../docs/reference/capability-manifest.md) — the 12
closed/additive-only loop points
- [ADR-1239](../docs/adr/1239-gsd-embeddable-orchestration-engine.md) — EoS (unaffected)
- [ADR-1239](../docs/adr/1239-msd-embeddable-orchestration-engine.md) — EoS (unaffected)

View File

@@ -6,12 +6,12 @@
## Policy (standing, not case-by-case)
**GSD is not accepting new runtimes or add-ons as first-party, in-tree work at
**MSD is not accepting new runtimes or add-ons as first-party, in-tree work at
this time — full stop, not a "go-with-conditions" case-by-case call.** Any "add
X to GSD" request for a new runtime, host integration, or add-on that is not
X to MSD" request for a new runtime, host integration, or add-on that is not
already community-maintained gets the same disposition: redirect to the EoS
Registry (new host/runtime identity) or the Capability system (new toggleable
feature), never conditional approval into gsd-core itself. A future triage pass
feature), never conditional approval into msd-core itself. A future triage pass
must not re-litigate this per-request — the diligence to apply is "does this
ask for a new runtime or add-on in-tree", not "is this particular one well
executed."
@@ -20,36 +20,36 @@ executed."
#4033 asked to add `crush` (Charm's terminal AI coding agent) as a **first-party,
in-tree** runtime: a `capabilities/crush/capability.json` descriptor plus wiring
across `runtimeTierDefaults` in `gsd-core/bin/shared/model-catalog.json`,
across `runtimeTierDefaults` in `msd-core/bin/shared/model-catalog.json`,
`src/runtime-name-policy.cts`, `src/runtime-artifact-layout.cts`,
`src/runtime-artifact-conversion.cts`, and `bin/install.js`, following `zcode` as
the reference runtime. The reporter explicitly flagged five open questions about
crush's agent-artifact format, permission model, frontmatter tolerance, MCP
support, and install-scope conventions that could not be answered from inside
gsd-core alone.
msd-core alone.
This is the same shape of ask as the Reasonix and OMP requests: a
previously-unsupported host proposed as a new entry in the in-tree runtime
registry GSD maintains itself.
registry MSD maintains itself.
## Why GSD does not own this
## Why MSD does not own this
- **GSD is not expanding its in-tree supported-runtime set.** Each first-class
- **MSD is not expanding its in-tree supported-runtime set.** Each first-class
runtime is a permanent maintenance obligation across the registry, installer,
artifact conversion, agent discovery, model routing, dispatch isolation,
golden install-parity fixtures, and localized capability matrices — carried
indefinitely for a host GSD does not control. This is the same ground already
indefinitely for a host MSD does not control. This is the same ground already
recorded twice: [`omp-runtime-in-core.md`](./omp-runtime-in-core.md) and
[`eos-registry-not-in-tree-runtime.md`](./eos-registry-not-in-tree-runtime.md).
- **The supported direction is the Embeddable Orchestration System (EoS), and it
is already available.** [ADR-1239](../docs/adr/1239-gsd-embeddable-orchestration-engine.md)
exists precisely so a host embeds GSD through a stable negotiated interface and
is already available.** [ADR-1239](../docs/adr/1239-msd-embeddable-orchestration-engine.md)
exists precisely so a host embeds MSD through a stable negotiated interface and
a thin host-plugin authored against the published Host-Integration SDK
([`docs/how-to/author-a-host-plugin.md`](../docs/how-to/author-a-host-plugin.md))
— without modifying gsd-core source. New hosts are listed in the
— without modifying msd-core source. New hosts are listed in the
[EoS Registry](../docs/registries/eos-registry.md) (`docs/registries/eos.json`,
`type: "eos"`), via a docs PR (`npm run gen:registry`). Existing entries
(`gsd-cursor`, `gsd-omp`, `gsd-reasonix`) already follow this path. If the
(`msd-cursor`, `msd-omp`, `msd-reasonix`) already follow this path. If the
actual need is narrower — a loop-behavior addition rather than a whole new
host — the [Capability](../docs/how-to/develop-a-capability.md) path
(`role: "feature"`, ADR-1244) is the other supported out-of-tree route; which
@@ -69,7 +69,7 @@ This entry denies **first-party, in-tree runtime registration for crush.** It
does not deny, and must never be cited against:
- **Shipping an out-of-tree host-plugin for crush.** This is welcome and
supported, and is the intended route. A crush plugin that embeds GSD via the
supported, and is the intended route. A crush plugin that embeds MSD via the
Host-Integration SDK and is listed in `docs/registries/eos.json` is exactly
the path this decision points to.
- **A crush integration built as a Capability**, if what's actually needed is a
@@ -78,12 +78,12 @@ does not deny, and must never be cited against:
- **Fixing defects that surface through a non-registered runtime**, or improving
the documented override/SDK contracts a host plugin depends on.
- **Migrations of already-supported runtimes** onto the EoS architecture. Those
are lower-risk upgrades of hosts GSD already owns, not new-host onboardings.
are lower-risk upgrades of hosts MSD already owns, not new-host onboardings.
- **Any existing runtime's support tier.**
## Re-open criteria
- GSD reopens first-class in-tree runtime registration — e.g. funded development
- MSD reopens first-class in-tree runtime registration — e.g. funded development
changes the maintenance calculus, or third-party `role: "runtime"` descriptors
become loadable from outside the repo (ADR-857 D8's deferred purely-additive
external loader). Until one of these holds, the answer for any new host is the
@@ -97,7 +97,7 @@ does not deny, and must never be cited against:
ground
- [`eos-registry-not-in-tree-runtime.md`](./eos-registry-not-in-tree-runtime.md) —
sibling decision (Reasonix), same ground, same redirect
- [ADR-1239](../docs/adr/1239-gsd-embeddable-orchestration-engine.md) — GSD as
- [ADR-1239](../docs/adr/1239-msd-embeddable-orchestration-engine.md) — MSD as
an Embeddable Orchestration Engine (EoS)
- [`docs/how-to/author-a-host-plugin.md`](../docs/how-to/author-a-host-plugin.md) —
the supported out-of-tree authoring path

View File

@@ -1,4 +1,4 @@
# Admit gsd-doc-writer / gsd-roadmapper as loop-hook contribution roles
# Admit msd-doc-writer / msd-roadmapper as loop-hook contribution roles
**Source:** [#4286](https://github.com/open-gsd/gsd-core/issues/4286)
**Decision:** wontfix — closed as unspecified, revisit if a concrete design is proposed
@@ -9,21 +9,21 @@
`bin/lib/loop-host-contract.cjs` enumerates the contribution roles admissible at each of the
12 loop hook points (discuss/plan/execute/verify/ship pre/post): `orchestrator`, `researcher`,
`planner`, `checker`, `executor`, `verifier`. `doc-writer` and `roadmapper` appear in none of
them, so a capability cannot contribute a prompt fragment to `gsd-doc-writer` or
`gsd-roadmapper` at any hook point — the capability validator rejects any contribution naming
them, so a capability cannot contribute a prompt fragment to `msd-doc-writer` or
`msd-roadmapper` at any hook point — the capability validator rejects any contribution naming
a role the host doesn't declare. The reporter maintains a documentation-standard capability and
wants to reach both agents the same way existing capabilities reach `planner`/`checker`/
`executor`, since the only current route (`agent_skills` in `.planning/config.json`) is
per-project, gets silently shadowed once a project config exists (so `~/.gsd/defaults.json`
per-project, gets silently shadowed once a project config exists (so `~/.msd/defaults.json`
stops supplying it), and has been observed reverted by routine working-tree operations without
anyone noticing. Two options were offered: (1) admit the two roles as contribution targets, or
(2) document per-project `agent_skills` as the intended mechanism if that's deliberate.
## Why GSD does not own this (as filed)
## Why MSD does not own this (as filed)
- **The request's premise doesn't hold.** Investigated via Memtrace (`find_code`) plus a direct
read of `references/loop-hook-dispatch.md`: `gsd-roadmapper` is dispatched only from the
`new-project` / `new-milestone` / `ingest-docs` workflows, and `gsd-doc-writer` only from
read of `references/loop-hook-dispatch.md`: `msd-roadmapper` is dispatched only from the
`new-project` / `new-milestone` / `ingest-docs` workflows, and `msd-doc-writer` only from
`docs-update` — none of which are among the 12 loop points the capability-contribution
mechanism (`activeHooks` / `byLoopPoint`) actually reaches. Admitting `doc-writer`/`roadmapper`
as `agentRoles` at `plan:pre`/`plan:post` etc. would not actually let a capability contribute

View File

@@ -8,29 +8,29 @@
#3346 asked to add a `reasonix` runtime as a **first-party, in-tree** integration: a
`capabilities/reasonix/capability.json` descriptor merged into the generated runtime
`bin/lib/capability-registry.cjs`, so `gsd-tools` dispatch/isolation/effort queries resolve
when GSD runs inside "Reasonix." The stated motivation was that launcher skills picked up by
`bin/lib/capability-registry.cjs`, so `msd-tools` dispatch/isolation/effort queries resolve
when MSD runs inside "Reasonix." The stated motivation was that launcher skills picked up by
Reasonix reference tools/paths of another host, and dispatch resolves to the wrong integration.
This is the same shape of ask as the OMP request: a previously-unsupported host proposed as a
new entry in the in-tree runtime registry GSD maintains itself.
new entry in the in-tree runtime registry MSD maintains itself.
## Why GSD does not own this
## Why MSD does not own this
- **GSD is not expanding its in-tree supported-runtime set.** Each first-class runtime is a
- **MSD is not expanding its in-tree supported-runtime set.** Each first-class runtime is a
permanent maintenance obligation across the registry, installer, artifact conversion, agent
discovery, model routing, dispatch isolation, golden install-parity fixtures, and localized
capability matrices — carried indefinitely for a host GSD does not control. This is the same
capability matrices — carried indefinitely for a host MSD does not control. This is the same
ground recorded for OMP (see [`omp-runtime-in-core.md`](./omp-runtime-in-core.md)).
- **The supported direction is the Embeddable Orchestration System (EoS), and it is already
available.** [ADR-1239](../docs/adr/1239-gsd-embeddable-orchestration-engine.md) exists
precisely so a host embeds GSD through a stable negotiated interface and a thin **host-plugin**
available.** [ADR-1239](../docs/adr/1239-msd-embeddable-orchestration-engine.md) exists
precisely so a host embeds MSD through a stable negotiated interface and a thin **host-plugin**
authored against the published Host-Integration SDK
([`docs/how-to/author-a-host-plugin.md`](../docs/how-to/author-a-host-plugin.md)) — **without
modifying gsd-core source.** New hosts are listed in the
modifying msd-core source.** New hosts are listed in the
[EoS Registry](../docs/registries/eos-registry.md) (`docs/registries/eos.json`, `type: "eos"`),
the non-endorsing discoverability catalog, via a docs PR (`npm run gen:registry`). Existing
entries (`gsd-cursor`, `gsd-omp`) already follow this path.
entries (`msd-cursor`, `msd-omp`) already follow this path.
- **The directly-analogous precedent is one month old and on point.** The Devin CLI request
([#2170](https://github.com/open-gsd/gsd-core/issues/2170), closed not planned 2026-07-11) — a
genuinely new terminal coding agent proposed as a new runtime integration — was declined with
@@ -53,7 +53,7 @@ This entry denies **first-party, in-tree runtime registration for new hosts.** I
and must never be cited against:
- **Shipping an out-of-tree host-plugin for Reasonix, or for any other host.** This is welcome
and supported, and is the intended route. A Reasonix plugin that embeds GSD via the
and supported, and is the intended route. A Reasonix plugin that embeds MSD via the
Host-Integration SDK and is listed in `docs/registries/eos.json` is exactly the path this
decision points to.
- **Feature capabilities** (`role: "feature"`) published out-of-tree under ADR-1244 — a different
@@ -61,13 +61,13 @@ and must never be cited against:
- **Fixing defects that surface through a non-registered runtime**, or improving the documented
override/SDK contracts a host plugin depends on.
- **Migrations of *already-supported* runtimes** onto the EoS architecture (the #2086/#2095/#2096/
#2097/#2099 family). Those are lower-risk upgrades of hosts GSD already owns, not new-host
#2097/#2099 family). Those are lower-risk upgrades of hosts MSD already owns, not new-host
onboardings, and are unaffected by this decision.
- **Any existing runtime's support tier.**
## Re-open criteria
- GSD reopens first-class in-tree runtime registration — e.g. funded development changes the
- MSD reopens first-class in-tree runtime registration — e.g. funded development changes the
maintenance calculus, or third-party `role: "runtime"` descriptors become loadable from outside
the repo (ADR-857 D8's deferred purely-additive external loader). Until one of these holds, the
answer for any new host is the EoS Registry, not the in-tree registry.
@@ -79,7 +79,7 @@ and must never be cited against:
- [`omp-runtime-in-core.md`](./omp-runtime-in-core.md) — sibling decision; same ground (new host
as in-tree runtime), same redirect to EoS
- [ADR-1239](../docs/adr/1239-gsd-embeddable-orchestration-engine.md) — GSD as an Embeddable
- [ADR-1239](../docs/adr/1239-msd-embeddable-orchestration-engine.md) — MSD as an Embeddable
Orchestration Engine (EoS)
- [`docs/how-to/author-a-host-plugin.md`](../docs/how-to/author-a-host-plugin.md) — the supported
out-of-tree authoring path

View File

@@ -24,7 +24,7 @@ Reporter ran a controlled probe on Claude Code and reported two findings, plus a
mismatch, let the executor **repair itself** — `git reset --hard <orchestrator HEAD>`
on its own branch — and proceed, converting the halt into a self-heal.
## Why GSD does not own this
## Why MSD does not own this
- **This is the exact primitive #48 removed, for the exact failure mode #48 was filed
to fix.** #48 (closed, `approved-enhancement`, shipped) replaced sub-agent-side
@@ -38,7 +38,7 @@ Reporter ran a controlled probe on Claude Code and reported two findings, plus a
reintroduces precisely this: the executor mutating its own worktree state in response
to a detected mismatch, on the sub-agent side.
- **The shipped design is live in current source, not just historically decided.**
`gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md:7` states, verbatim:
`msd-core/workflows/execute-phase/steps/worktree-recovery-policy.md:7` states, verbatim:
*"`worktree_branch_check` is verify-only — an executor that hits a base/HEAD-namespace
mismatch prints `FATAL:` and exits **42** instead of self-recovering... The orchestrator —
the worktree lifecycle owner — performs any base correction... the sub-agent never does."*
@@ -81,6 +81,6 @@ Reporter ran a controlled probe on Claude Code and reported two findings, plus a
## Related
- [#48](https://github.com/open-gsd/gsd-core/issues/48) — the decision this proposal reverses
- `gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md` — the shipped fail-closed invariant
- `msd-core/workflows/execute-phase/steps/worktree-recovery-policy.md` — the shipped fail-closed invariant
- [#3659](https://github.com/open-gsd/gsd-core/issues/3659), [#3779](https://github.com/open-gsd/gsd-core/issues/3779), [#683](https://github.com/open-gsd/gsd-core/issues/683) — the fork-base family #4463's measurement bears on
- [#4415](https://github.com/open-gsd/gsd-core/issues/4415) — adjacent cleanup-wave gap, unaffected by this decision

View File

@@ -4,10 +4,10 @@
**Decision:** wontfix — routed to the capability ecosystem, closed on scope ownership
**Date:** 2026-07-24
GSD core does not accept standalone, general-purpose agent-discipline prompt
MSD core does not accept standalone, general-purpose agent-discipline prompt
modules — prose instructing an agent *how to think* (epistemic hygiene,
confidence framing, assumption surfacing, reasoning style) that is not attached
to a specific GSD command or loop step. These belong in the capability
to a specific MSD command or loop step. These belong in the capability
ecosystem, authored and distributed by their authors, not in the core skill
layer.
@@ -18,7 +18,7 @@ Read this scope boundary before applying the entry — the keyword surface below
decision deliberately does **not** deny:
- **Fixing an existing first-party agent's own language at a specific loop
step** — e.g. "`gsd-verifier` overstates confidence at `verify:post`, tighten
step** — e.g. "`msd-verifier` overstates confidence at `verify:post`, tighten
its prompt". That is command/loop-step-attached and is ordinary bug-fix or
enhancement work. This entry denies *standalone, unattached* modules only.
- **Objectively-measured or externally-triggered calibration** — anything
@@ -37,7 +37,7 @@ apply to it.
### 1. `skills/` is a generated projection, not an authoring surface
`skills/` is build-generated from `commands/gsd/*.md` by
`skills/` is build-generated from `commands/msd/*.md` by
`scripts/gen-plugin-skills.cjs` — 71 commands to 71 skills, identical
membership — and `npm run lint:generated-sync` runs `gen-plugin-skills.cjs
--check`, which fails whenever the committed tree diverges from generator
@@ -82,7 +82,7 @@ PR. The author retains ownership, versioning, and release cadence.
### 3. Delivering it as a flag on existing commands is strictly worse
Evaluated and rejected as the alternative. Flag-gated prose injection is an
established idiom (`gsd-core/workflows/plan-phase.md:792-796` injects a whole
established idiom (`msd-core/workflows/plan-phase.md:792-796` injects a whole
instruction block under `${MVP_MODE === 'true' ? … : ''}`), but the cost
multiplies by subset size: each command needs frontmatter `argument-hint`, a
workflow parse-and-branch, a `help/modes/full.md` entry, a `docs/COMMANDS.md`
@@ -96,7 +96,7 @@ surfaces" natively, declared once.
Self-judged confidence reporting — the usual centerpiece of these proposals —
was measured in this project and found weak.
`gsd-core/references/honest-verifier.md:25-29`: *"Asking the verifier to
`msd-core/references/honest-verifier.md:25-29`: *"Asking the verifier to
'abstain if unsure' barely moves the number (100% → 67%) and only on ambiguity
it already notices; on a true blind spot it stays confidently wrong."* That
result is why `honest-verifier.md` routes on an exogenous upstream tag and
@@ -118,7 +118,7 @@ judgment calls:
Self-reported improvement, anecdotes, or gains only on
already-noticed ambiguity do not meet this bar — that is precisely the
result the existing evidence already produced.
2. `skills/` stops being a 1:1 projection of `commands/gsd/` — i.e.
2. `skills/` stops being a 1:1 projection of `commands/msd/` — i.e.
`scripts/gen-plugin-skills.cjs` no longer generates the tree, or an ADR
ratifies hand-authored skills. At that point reason 1 lapses on its own and
this entry must be re-derived from reasons 2-4 alone.

View File

@@ -1,4 +1,4 @@
# Kiro (AWS) CLI + IDE as a first-class runtime in gsd-core
# Kiro (AWS) CLI + IDE as a first-class runtime in msd-core
**Source:** [#4722](https://github.com/open-gsd/gsd-core/issues/4722)
**Decision:** wontfix — No-go as filed; redirected to the EoS Registry / out-of-tree host-plugin path (or a Capability, if the actual need turns out to be feature-shaped rather than runtime-shaped)
@@ -6,30 +6,30 @@
## Policy (standing, not case-by-case)
**GSD is not accepting new runtimes or add-ons as first-party, in-tree work at this time — full stop, not a "go-with-conditions" case-by-case call.** Same standing ground recorded in [`crush-runtime-in-core.md`](./crush-runtime-in-core.md) and [`omp-runtime-in-core.md`](./omp-runtime-in-core.md). The policy is explicitly host-agnostic: no Kiro-specific prior denial existed before this issue, but the standing decision text evaluates "does this ask for a new runtime or add-on in-tree," not "is this particular one well executed" — AWS backing does not change the maintenance-obligation calculus the policy is about.
**MSD is not accepting new runtimes or add-ons as first-party, in-tree work at this time — full stop, not a "go-with-conditions" case-by-case call.** Same standing ground recorded in [`crush-runtime-in-core.md`](./crush-runtime-in-core.md) and [`omp-runtime-in-core.md`](./omp-runtime-in-core.md). The policy is explicitly host-agnostic: no Kiro-specific prior denial existed before this issue, but the standing decision text evaluates "does this ask for a new runtime or add-on in-tree," not "is this particular one well executed" — AWS backing does not change the maintenance-obligation calculus the policy is about.
## Proposal summary
#4722 asked to add `--kiro` as a new first-party, in-tree runtime integration for AWS's Kiro CLI + IDE — a new runtime descriptor and installer wiring, structurally the same shape as prior first-party-runtime requests.
## Why GSD does not own this
## Why MSD does not own this
- **GSD is not expanding its in-tree supported-runtime set.** Each first-class runtime is a permanent maintenance obligation across the registry, installer, artifact conversion, agent discovery, model routing, dispatch isolation, golden install-parity fixtures, and localized capability matrices — carried indefinitely for a host GSD does not control.
- **MSD is not expanding its in-tree supported-runtime set.** Each first-class runtime is a permanent maintenance obligation across the registry, installer, artifact conversion, agent discovery, model routing, dispatch isolation, golden install-parity fixtures, and localized capability matrices — carried indefinitely for a host MSD does not control.
- **`kiro` does not exist in `capabilities/` or `docs/registries/eos.json` today** (verified at triage time), so there is no existing partial support to build on that would change the calculus.
## What this does NOT cover
This entry denies **first-party, in-tree runtime registration for Kiro.** It does not deny, and must never be cited against:
- **Shipping an out-of-tree host-plugin for Kiro**, via the Host-Integration SDK, listed in `docs/registries/eos.json` — same path as `gsd-cursor`/`gsd-omp`/`gsd-reasonix`.
- **Shipping Kiro as a third-party `role: "runtime"` capability via ADR-1244's external loader.** ADR-857 D8 deferred third-party CLI/runtime support "to an external loader + trust/validation gate"; ADR-1244 (Accepted, ratified 2026-07-17) is that ADR and delivers that gate — a third-party capability, including `role: "runtime"`, can be installed from outside gsd-core's own tree (`~/.gsd/capabilities/<id>/` global, or `.gsd/capabilities/<id>/` project-scoped) under its trust/consent model. This is a live mechanism today, not a future trigger — see "Re-open criteria" below.
- **Shipping an out-of-tree host-plugin for Kiro**, via the Host-Integration SDK, listed in `docs/registries/eos.json` — same path as `msd-cursor`/`msd-omp`/`msd-reasonix`.
- **Shipping Kiro as a third-party `role: "runtime"` capability via ADR-1244's external loader.** ADR-857 D8 deferred third-party CLI/runtime support "to an external loader + trust/validation gate"; ADR-1244 (Accepted, ratified 2026-07-17) is that ADR and delivers that gate — a third-party capability, including `role: "runtime"`, can be installed from outside msd-core's own tree (`~/.msd/capabilities/<id>/` global, or `.msd/capabilities/<id>/` project-scoped) under its trust/consent model. This is a live mechanism today, not a future trigger — see "Re-open criteria" below.
- **A Kiro integration built as a Capability**, if what's actually needed is a toggleable feature rather than a new host identity.
- **Fixing defects that surface through a non-registered runtime**, or improving the documented override/SDK contracts a host plugin depends on.
- **Any existing runtime's support tier.**
## Re-open criteria
- **The ADR-857 D8 external-loader condition is already met** — ADR-1244 (Accepted 2026-07-17) delivers third-party `role: "runtime"` capability loading; this is no longer a future trigger. What remains unmet is a maintainer decision to expand gsd-core's own *first-party, in-tree* supported-runtime set specifically — that is a bandwidth/scope call, not a tooling gap, and reopens only if funded development changes the maintenance calculus described above.
- **The ADR-857 D8 external-loader condition is already met** — ADR-1244 (Accepted 2026-07-17) delivers third-party `role: "runtime"` capability loading; this is no longer a future trigger. What remains unmet is a maintainer decision to expand msd-core's own *first-party, in-tree* supported-runtime set specifically — that is a bandwidth/scope call, not a tooling gap, and reopens only if funded development changes the maintenance calculus described above.
- Kiro demonstrates an integration need the EoS Host-Integration Interface AND the ADR-1244 third-party capability loader genuinely cannot express (none shown to date).
## Related
@@ -37,6 +37,6 @@ This entry denies **first-party, in-tree runtime registration for Kiro.** It doe
- [`crush-runtime-in-core.md`](./crush-runtime-in-core.md) — sibling decision, same ground, same standing policy
- [`omp-runtime-in-core.md`](./omp-runtime-in-core.md) — sibling decision, same ground
- [`zoo-runtime-in-core.md`](./zoo-runtime-in-core.md) — sibling decision filed the same day, same ground
- [ADR-1239](../docs/adr/1239-gsd-embeddable-orchestration-engine.md) — GSD as an Embeddable Orchestration Engine (EoS)
- [ADR-1239](../docs/adr/1239-msd-embeddable-orchestration-engine.md) — MSD as an Embeddable Orchestration Engine (EoS)
- [`docs/how-to/author-a-host-plugin.md`](../docs/how-to/author-a-host-plugin.md) — the supported out-of-tree authoring path
- [`docs/how-to/develop-a-capability.md`](../docs/how-to/develop-a-capability.md) — the Capability path, if the need turns out to be feature-shaped

View File

@@ -16,7 +16,7 @@ issue also flagged that the gate which actually reddens CI
`runPackageLockAudit`, so a retry added to `scripts/npm-audit-baseline.cjs` alone would not reach
the failing path, and asked that the extraction be finished so the fix lands in one place.
## Why GSD does not own this
## Why MSD does not own this
- **The maintainer judged the ask covered by the in-flight work in [PR #4251](https://github.com/open-gsd/gsd-core/pull/4251)** (fixes #4250), which adds an `isTimeoutKill` predicate and a shared timeout-error builder used by both audit call sites, so a timed-out audit reports its real cause instead of a JSON parse error. Carrying the retry/backoff design as a *separate* enhancement issue was declined; the hardening is being worked through #4251. **Scope note, verified 2026-09-04:** #4251 does **not** finish the extraction — `auditProductionVulns` in `tests/npm-integrity-gate.test.cjs` remains a separate near-copy of `runPackageLockAudit` with its own candidate loop and `AUDIT_TIMEOUT_MS`. The fix-location hazard #4260 flagged is therefore still live: any future retry work must touch both sites or finish the extraction first.
- **The proposal got two things RIGHT that this entry does not deny:** the single-attempt/no-backoff observation was accurate, and the halfway-extraction observation was accurate — only the error-classification half is addressed by #4251, not the duplication itself. This entry records a redirect, not a rejection of the diagnosis.

View File

@@ -1,6 +1,6 @@
# OMP (Oh My Pi) as a first-class runtime in gsd-core
# OMP (Oh My Pi) as a first-class runtime in msd-core
gsd-core does not add `omp` (Oh My Pi) as a first-class runtime: no
msd-core does not add `omp` (Oh My Pi) as a first-class runtime: no
`capabilities/omp/capability.json`, no `omp` entry in the runtime registry, no
`omp` alias canonicalization, and no installer runtime selection for it.
@@ -9,7 +9,7 @@ the proposals that have asked for it.
## Why this is out of scope
- **GSD is not expanding its supported-runtime set.** The long-term direction is
- **MSD is not expanding its supported-runtime set.** The long-term direction is
to *reduce* the number of supported runtimes, not grow it, absent funded
development. Each first-class runtime is a permanent maintenance obligation
across the registry, installer, artifact conversion, agent discovery, model
@@ -18,14 +18,14 @@ the proposals that have asked for it.
not control.
- **Host integration is the supported direction, and it is already available.**
The Embeddable Orchestration System (ADR-1239) exists precisely so a host can
embed GSD and declare its own capabilities, instead of GSD resolving the host
embed MSD and declare its own capabilities, instead of MSD resolving the host
from an in-tree registry. An out-of-tree host plugin needs no runtime
descriptor. `GSD_AGENTS_DIR` is a documented Priority-1 override honored for
descriptor. `MSD_AGENTS_DIR` is a documented Priority-1 override honored for
*any* runtime name (`src/agent-install-check.cts`, `getAgentsDir`), so a plugin
can own its filesystem layout without core knowing the runtime exists.
- **The ask as filed also carried a defect.** #3037 proposed canonicalizing
`pi`, `oh-my-pi` and `pi-coding-agent` to `omp`. OMP is a *fork* of pi
(pi.dev), and gsd-core already ships a distinct `pi` runtime
(pi.dev), and msd-core already ships a distinct `pi` runtime
([`capabilities/pi/capability.json`](../capabilities/pi/capability.json), home
`~/.pi/agent`, tier 2). That alias list would relocate an existing shipped
runtime's config home rather than add a new one. This is recorded so a future
@@ -38,7 +38,7 @@ This entry denies **in-tree, first-class runtime registration for OMP**. It does
not deny, and should never be cited against:
- **Shipping an out-of-tree host plugin for OMP, or for any other host.** This
is welcome and supported. `gsd-omp` is already listed in
is welcome and supported. `msd-omp` is already listed in
[`docs/registries/eos.json`](../docs/registries/eos.json) and remains listed;
registry inclusion is explicitly non-endorsement and is unaffected by this
decision.

View File

@@ -1,8 +1,8 @@
# Clone-Portable `<execution_context>` in Committed PLAN.md
GSD does not make the `<execution_context>` block in committed `PLAN.md` files
MSD does not make the `<execution_context>` block in committed `PLAN.md` files
clone-portable — it does not rewrite the planner's install-relative
`@…/gsd-core/…` references into repository-relative or install-neutral paths so
`@…/msd-core/…` references into repository-relative or install-neutral paths so
that a committed plan reads identically across developers, machines, or runtimes.
## Why this is out of scope
@@ -10,16 +10,16 @@ that a committed plan reads identically across developers, machines, or runtimes
PLAN.md is a **machine artifact**, not a human- or clone-facing document — the
same principle that governs [plan-md-human-rendering.md](./plan-md-human-rendering.md)
(from #2158). A committed PLAN.md is a per-run agent instruction set, produced by
`gsd-planner` and consumed in place by `gsd-executor`, `gsd-plan-checker`, and
`gsd-verifier`. There is no documented step in which a plan is read on another
machine after `git clone` without a local GSD install.
`msd-planner` and consumed in place by `msd-executor`, `msd-plan-checker`, and
`msd-verifier`. There is no documented step in which a plan is read on another
machine after `git clone` without a local MSD install.
Under that model, `<execution_context>`'s `@` references point at the reader's
own local GSD install (Claude `~/.claude/gsd-core/…`, Cursor `.cursor/gsd-core/…`,
own local MSD install (Claude `~/.claude/msd-core/…`, Cursor `.cursor/msd-core/…`,
or an absolute path for a `--local` install). They are install-relative by design,
and the executor loads those workflows from its own installed copy — it never
consumes the paths a *different* machine wrote into a committed plan.
`/gsd-execute-phase` builds its own `<execution_context>` inline from the
`/msd-execute-phase` builds its own `<execution_context>` inline from the
orchestrator's installed workflow (`workflows/execute-phase.md`), so the block a
planner writes into a committed plan does not gate execution anywhere.
@@ -27,14 +27,14 @@ Making committed plans clone-portable would treat PLAN.md as a shared
cross-developer document — the boundary #2158 declined to cross — for a block that
no consumer reads across machines.
**Revisit if** GSD introduces a documented cross-developer / cross-machine contract
**Revisit if** MSD introduces a documented cross-developer / cross-machine contract
for committed PLAN.md — a human- or teammate-facing use where plans are read after
`git clone` without a local install — at which point `<execution_context>`
portability becomes in scope.
## Prior requests
- #2238 — "Planner embeds machine-specific gsd-core paths in committed PLAN.md execution_context"
- #2238 — "Planner embeds machine-specific msd-core paths in committed PLAN.md execution_context"
## Related

View File

@@ -1,6 +1,6 @@
# Human-Readable Rendering of PLAN.md
GSD does not change PLAN.md's structural tag convention (`<task>`, `<action>`,
MSD does not change PLAN.md's structural tag convention (`<task>`, `<action>`,
`<tasks>`, `<files>`, `<verify>`, etc.) to improve how a PLAN.md renders when a
human opens the raw file in a markdown viewer on GitHub/GitLab.
@@ -12,12 +12,12 @@ explicit:
- `docs/reference/plan-md.md` — a PLAN.md is *"an executable unit of work — a
structured document that tells an executor agent exactly what to build and how
to verify it was built correctly."*
- `agents/gsd-planner.md` — *"Produce PLAN.md files that Claude executors can
- `agents/msd-planner.md` — *"Produce PLAN.md files that Claude executors can
implement without interpretation. Plans are prompts, not documents that become
prompts."*
PLAN.md is produced by `gsd-planner` and consumed by `gsd-executor`,
`gsd-plan-checker`, `gsd-verifier`, and cross-AI review agents. There is no
PLAN.md is produced by `msd-planner` and consumed by `msd-executor`,
`msd-plan-checker`, `msd-verifier`, and cross-AI review agents. There is no
documented step in which a human opens, reads, reviews, or signs off on a
PLAN.md — unlike `SUMMARY.md` / `VERIFICATION.md`, which are produced for human
validation.
@@ -54,7 +54,7 @@ The same reasoning covers the report's secondary point (unquoted `|` in PLAN.md
frontmatter breaking rendered markdown tables): that too is a human-render
concern for a machine artifact.
**Revisit if** GSD ever introduces a human-review gate for PLAN.md — a step
**Revisit if** MSD ever introduces a human-review gate for PLAN.md — a step
where a person reads and approves the plan before execution. At that point
PLAN.md gains a documented human audience and its rendering becomes in-scope.

View File

@@ -8,7 +8,7 @@
Reporter observed 436 of 556 dirty `git status` entries in a real project coming from agent
runtime state — `.omc/state/checkpoints/*`, `.omo/run-continuation/*`, and replay/loop logs —
being versioned in the project repo. Attributing this to GSD, the request was to add `.omc/`,
being versioned in the project repo. Attributing this to MSD, the request was to add `.omc/`,
`.omo/` and "any other agent-runtime dirs the toolchain writes" to what the report calls "the
`.gitignore` shipped by the init template", which the report characterises as excluding only
`__pycache__/` and `*.pyc`. A `git rm -r --cached` migration note for existing projects was
@@ -17,24 +17,24 @@ proposed alongside.
The underlying complaint is real and well-evidenced: continuously-rewritten runtime state buried
296 genuine changed files under 436 runtime entries.
## Why GSD does not own this
## Why MSD does not own this
- **There is no init-template `.gitignore`.** This repo contains exactly one `.gitignore` — its
own. The `__pycache__/` + `*.pyc` pair the report quotes is `.gitignore:261-262` of the
gsd-core working tree, immediately followed by `.venv/`, `venv/` and `target/`; it is neither
msd-core working tree, immediately followed by `.venv/`, `venv/` and `target/`; it is neither
"only two entries" nor installed anywhere. No copy manifest, installer path, or workflow ships
it into a user project.
- **The only project-`.gitignore` write GSD performs is a single `.planning/` line**, and only
when the operator answers `commit_docs = No` at init (`gsd-core/workflows/new-project.md:638`,
- **The only project-`.gitignore` write MSD performs is a single `.planning/` line**, and only
when the operator answers `commit_docs = No` at init (`msd-core/workflows/new-project.md:638`,
and again for the multi-repo path at `:676`). There is no template to extend.
- **`.omc` and `.omo` are not GSD artifacts.** Zero occurrences across `src/`, `bin/`,
`gsd-core/`, `commands/`, `agents/`, `capabilities/`, `docs/`, and every shipped `.md`, `.json`
and `.yml`. GSD neither creates, reads, nor has any knowledge of those directories. Ignoring
another tool's runtime state is that tool's responsibility; a GSD-authored ignore list naming
third-party paths would silently rot as those tools rename their directories, and GSD would
- **`.omc` and `.omo` are not MSD artifacts.** Zero occurrences across `src/`, `bin/`,
`msd-core/`, `commands/`, `agents/`, `capabilities/`, `docs/`, and every shipped `.md`, `.json`
and `.yml`. MSD neither creates, reads, nor has any knowledge of those directories. Ignoring
another tool's runtime state is that tool's responsibility; a MSD-authored ignore list naming
third-party paths would silently rot as those tools rename their directories, and MSD would
have no signal that it had.
- **The one GSD-owned path named in the report is already governed.** `.planning/forensics/` is
ours (`gsd-core/workflows/forensics.md:171`), but it lives under `.planning/`, whose
- **The one MSD-owned path named in the report is already governed.** `.planning/forensics/` is
ours (`msd-core/workflows/forensics.md:171`), but it lives under `.planning/`, whose
tracked-vs-local status is an explicit init decision. A project that answered `commit_docs = No`
already ignores it; a project that answered `Yes` is versioning `.planning/` on purpose.
@@ -43,31 +43,31 @@ which component is producing it.
## What this does NOT cover
This entry denies exactly one thing: **GSD enumerating third-party agent-runtime directories in a
This entry denies exactly one thing: **MSD enumerating third-party agent-runtime directories in a
`.gitignore` it writes.** The keyword surface here (`gitignore`, "runtime state", "dirty tree") is
broad, and the following remain welcome and are **not** denied by this decision:
- A report that **GSD itself** writes churning runtime state outside `.planning/`. That would be a
- A report that **MSD itself** writes churning runtime state outside `.planning/`. That would be a
live defect, and this entry is not a precedent against fixing it.
- Making the existing `.planning/` ignore write more robust — idempotency, ordering, handling a
missing or malformed `.gitignore`.
- Ignore-list handling for directories a **GSD capability** creates.
- Documentation telling users which paths their own toolchain should ignore alongside a GSD
- Ignore-list handling for directories a **MSD capability** creates.
- Documentation telling users which paths their own toolchain should ignore alongside a MSD
project, as prose rather than as a generated file.
## Re-open criteria
Concrete and checkable:
- GSD begins shipping or generating a project `.gitignore` with substantive content (beyond the
- MSD begins shipping or generating a project `.gitignore` with substantive content (beyond the
single `.planning/` line), at which point what belongs in it becomes a real design question.
- A reproduction demonstrates a directory **created by gsd-core or one of its capabilities**
- A reproduction demonstrates a directory **created by msd-core or one of its capabilities**
producing continuous working-tree churn and not already covered by the `commit_docs` decision.
A request to ignore paths owned by a different tool is not re-openable on volume of churn alone;
the churn is evidence about the writing tool, not about GSD.
the churn is evidence about the writing tool, not about MSD.
## Related
- `gsd-core/workflows/new-project.md` — the `commit_docs` decision and the `.planning/` ignore write
- `gsd-core/workflows/forensics.md` — writes `.planning/forensics/`, under the `.planning/` umbrella
- `msd-core/workflows/new-project.md` — the `commit_docs` decision and the `.planning/` ignore write
- `msd-core/workflows/forensics.md` — writes `.planning/forensics/`, under the `.planning/` umbrella

View File

@@ -1,6 +1,6 @@
# Statusline Account / Usage Segment (credential-reading, external API)
GSD's statusline does not read credentials or call external network APIs to
MSD's statusline does not read credentials or call external network APIs to
display account-level resource state (5-hour / 7-day rate-limit utilization,
usage windows, plan quotas).
@@ -9,7 +9,7 @@ usage windows, plan quotas).
The statusline draws its data boundary at **local, read-only** sources — see
[`docs/adr/2164-statusline-scope-boundary.md`](../docs/adr/2164-statusline-scope-boundary.md).
It refines the stdin payload Claude Code already sends (model, context meter,
GSD-state) and may add a new *local* source (e.g. `git`), but it does not:
MSD-state) and may add a new *local* source (e.g. `git`), but it does not:
- read Claude Code's OAuth credentials (`.credentials.json`, or the macOS login
Keychain via `security`), or
@@ -27,10 +27,10 @@ Reasons:
- **Scope.** Surfacing account/rate-limit state is a platform (Claude Code)
concern. This matches the prior in
[`temporal-context.md`](./temporal-context.md): *"Statusline / TUI re-entry is
platform-level, not GSD-level."*
platform-level, not MSD-level."*
**Revisit if** a documented, first-party usage API — or a platform-provided
value delivered to the hook without GSD reading credentials — becomes
value delivered to the hook without MSD reading credentials — becomes
available. That would move usage display out of the excluded tier.
## Prior requests

View File

@@ -17,10 +17,10 @@ tool-call start/end events, artifact creation and mtime changes, commits, and an
`expectedArtifacts` declarations, a `watchdog.*` config block, and bounded chunk resume
that preserves already-committed chunks. Explicitly not `ps aux`, explicitly no auto-kill.
## Why GSD does not own this
## Why MSD does not own this
- **A narrower version already ships, and this proposal skips past it.**
`gsd-core/workflows/execute-phase.md` already implements artifact-aware stall detection
`msd-core/workflows/execute-phase.md` already implements artifact-aware stall detection
for the executor: a SUMMARY-existence plus `git log --since` spot-check (`:742-744`), a
periodic surveillance loop (`:755-762`) gated on `executor.stall_detect_interval_minutes`
and `executor.stall_threshold_minutes` (read at `:100-101`; both registered in
@@ -39,9 +39,9 @@ that preserves already-committed chunks. Explicitly not `ps aux`, explicitly no
rearchitecture. Accepting #2699 would mean building the larger system on top of a
foundation that has not landed.
- **The event-driven model assumes an orchestrator GSD does not have.** The proposal
- **The event-driven model assumes an orchestrator MSD does not have.** The proposal
assumes a resident process with an event loop that can subscribe to hook callbacks and
maintain an in-memory `lastActivityAt`. GSD's orchestrator is an LLM interpreting
maintain an in-memory `lastActivityAt`. MSD's orchestrator is an LLM interpreting
workflow markdown one turn at a time. Host-fired hooks run out-of-band and do not
return control to the orchestrating prompt mid-spawn. The only mechanism that yields a
turn in which a check can run is a backgrounded dispatch that returns control between
@@ -49,7 +49,7 @@ that preserves already-committed chunks. Explicitly not `ps aux`, explicitly no
resolve by picking a different host.
- **The heartbeat has no place to live.** Agents emitting JSON every 30–60 seconds
requires wrapper-level control over agent execution that no GSD-supported runtime
requires wrapper-level control over agent execution that no MSD-supported runtime
exposes. Absent a wrapper, the spawned agent would have to interleave heartbeat
emission with its actual work, competing for the same turn.
@@ -84,7 +84,7 @@ overlaps request types this decision deliberately does not deny. Do not apply th
denied by nothing here.
- **Orphaned OS processes, containers, or bench resources.** Leaked test-runner containers
and similar host-level cleanup share the words *orphan* and *recovery* with this entry
but are a different domain entirely — nothing about GSD subagent dispatch. This entry
but are a different domain entirely — nothing about MSD subagent dispatch. This entry
says nothing about them.
## Re-open criteria
@@ -107,7 +107,7 @@ no longer sufficient — not before.
## Related
- `gsd-core/workflows/execute-phase.md` — the shipped executor stall-detection pattern
- `msd-core/workflows/execute-phase.md` — the shipped executor stall-detection pattern
- `src/config.cts` — `SCHEMA_DEFAULTS`, where `executor.stall_*` keys are registered
- `docs/reference/host-integration-capability-matrix.md` — per-runtime `hookBus` / `stateIO` surfaces
- [#2650](https://github.com/open-gsd/gsd-core/issues/2650) — the confirmed defect this was redirected to

View File

@@ -1,4 +1,4 @@
# Temporal context as a first-class GSD signal
# Temporal context as a first-class MSD signal
**Source:** [#2756](https://github.com/open-gsd/gsd-core/issues/2756)
**Decision:** wontfix — closed without further engagement
@@ -7,29 +7,29 @@
## Proposal summary
Reporter proposed treating idle-time-between-turns as a first-class context signal in
GSD. Three flavors floated across the issue:
MSD. Three flavors floated across the issue:
1. **Passive** — block at session resume injecting "you've been idle Nh, here's what was
open" into the orchestrator prompt.
2. **Active** — `/resume-context` slash command.
3. **Retrospective** — `HANDOFF.json` written at session end, read at next start.
Framed initially as a `claude-inject-idle-time` plugin, with a request that GSD treat
Framed initially as a `claude-inject-idle-time` plugin, with a request that MSD treat
the pattern as core.
## Why GSD does not own this
## Why MSD does not own this
- **Subagent gap unsolved.** Passive injection lands in the orchestrator's context
only. Subagents (the workers that actually do GSD's planning, execution, verification)
only. Subagents (the workers that actually do MSD's planning, execution, verification)
spawn fresh and never see the temporal signal. The proposal does not solve this, and
any GSD-core integration would inherit the gap. Until the subagent boundary is
any MSD-core integration would inherit the gap. Until the subagent boundary is
addressed, "first-class temporal context" is at best a partial feature.
- **`HANDOFF.json` duplicates existing artifacts.** GSD already persists session
- **`HANDOFF.json` duplicates existing artifacts.** MSD already persists session
continuity through `.planning/state/*` and per-phase artifacts (PLAN.md, RESEARCH.md,
REVIEW.md, VERIFICATION.md). A separate handoff file would either drift from those or
redundantly mirror them. The right primitive for "what was I doing" already exists.
- **Statusline / TUI re-entry is platform-level, not GSD-level.** A statusline showing
idle time belongs in Claude Code itself or in a thin user plugin, not in GSD's phase
- **Statusline / TUI re-entry is platform-level, not MSD-level.** A statusline showing
idle time belongs in Claude Code itself or in a thin user plugin, not in MSD's phase
machinery.
- **Scope is unstable.** Reporter agreed with the narrowed minimum ask ("doc mention
only, rest opt-in"), then partially retracted it in a follow-up comment ("very
@@ -53,4 +53,4 @@ through to a triage decision rather than dropping an issue and moving on.
## Related
- `.planning/state/` — existing session-continuity artifacts
- `gsd-core/references/` — where any future plugin-interface doc would live
- `msd-core/references/` — where any future plugin-interface doc would live

View File

@@ -1,4 +1,4 @@
# Zoo Code (successor of archived Roo Code) as a first-class runtime in gsd-core
# Zoo Code (successor of archived Roo Code) as a first-class runtime in msd-core
**Source:** [#4746](https://github.com/open-gsd/gsd-core/issues/4746)
**Decision:** wontfix — No-go as filed; redirected to the EoS Registry / out-of-tree host-plugin path (or a Capability, if the actual need turns out to be feature-shaped rather than runtime-shaped)
@@ -6,23 +6,23 @@
## Policy (standing, not case-by-case)
**GSD is not accepting new runtimes or add-ons as first-party, in-tree work at this time — full stop, not a "go-with-conditions" case-by-case call.** This is the same standing ground already recorded twice: [`crush-runtime-in-core.md`](./crush-runtime-in-core.md) and [`omp-runtime-in-core.md`](./omp-runtime-in-core.md). The standing decision text is direct: evaluate "does this ask for a new runtime or add-on in-tree," not "is this particular one well executed." Nothing about Zoo's specific quality, research depth, or the reporter's cited working private-fork port changes this — the same class of well-executed prior asks (crush, OMP, Reasonix) were declined on identical grounds.
**MSD is not accepting new runtimes or add-ons as first-party, in-tree work at this time — full stop, not a "go-with-conditions" case-by-case call.** This is the same standing ground already recorded twice: [`crush-runtime-in-core.md`](./crush-runtime-in-core.md) and [`omp-runtime-in-core.md`](./omp-runtime-in-core.md). The standing decision text is direct: evaluate "does this ask for a new runtime or add-on in-tree," not "is this particular one well executed." Nothing about Zoo's specific quality, research depth, or the reporter's cited working private-fork port changes this — the same class of well-executed prior asks (crush, OMP, Reasonix) were declined on identical grounds.
## Proposal summary
#4746 asked to add `zoo` (Zoo Code, the VS Code extension community continuation of the archived Roo Code) as a **first-party, in-tree** tier-2 runtime: a `capabilities/zoo/capability.json` descriptor, alias canonicalization (`roo`, `roo-code`, `roo-cline`, `zoo-code` → `zoo`), and a new dedicated `zoo-modes` install-surface writer to merge GSD agents into Zoo's single-file `.roomodes`/`custom_modes.yaml` custom-mode format (following the `cline-rules` precedent for merge-into-one-file surfaces). The proposal included extensive docs-verified integration facts (schema, tool names, subagent dispatch semantics, globalStorage paths) and cited a working private-fork port (`harmony-ai-solutions/gsd-roo-code`).
#4746 asked to add `zoo` (Zoo Code, the VS Code extension community continuation of the archived Roo Code) as a **first-party, in-tree** tier-2 runtime: a `capabilities/zoo/capability.json` descriptor, alias canonicalization (`roo`, `roo-code`, `roo-cline`, `zoo-code` → `zoo`), and a new dedicated `zoo-modes` install-surface writer to merge MSD agents into Zoo's single-file `.roomodes`/`custom_modes.yaml` custom-mode format (following the `cline-rules` precedent for merge-into-one-file surfaces). The proposal included extensive docs-verified integration facts (schema, tool names, subagent dispatch semantics, globalStorage paths) and cited a working private-fork port (`harmony-ai-solutions/msd-roo-code`).
## Why GSD does not own this
## Why MSD does not own this
- **GSD is not expanding its in-tree supported-runtime set.** Each first-class runtime is a permanent maintenance obligation across the registry, installer, artifact conversion, agent discovery, model routing, dispatch isolation, golden install-parity fixtures, and localized capability matrices — carried indefinitely for a host GSD does not control.
- **MSD is not expanding its in-tree supported-runtime set.** Each first-class runtime is a permanent maintenance obligation across the registry, installer, artifact conversion, agent discovery, model routing, dispatch isolation, golden install-parity fixtures, and localized capability matrices — carried indefinitely for a host MSD does not control.
- **Neither `zoo` nor `roo` exists in `capabilities/` or `docs/registries/eos.json` today** (verified at triage time), so there is no existing partial support to build on that would change the calculus.
## What this does NOT cover
This entry denies **first-party, in-tree runtime registration for Zoo Code.** It does not deny, and must never be cited against:
- **Shipping an out-of-tree host-plugin for Zoo Code.** This is welcome and supported, and is the intended route — a Zoo plugin that embeds GSD via the Host-Integration SDK and is listed in `docs/registries/eos.json`, same as `gsd-cursor`/`gsd-omp`/`gsd-reasonix`. The reporter's own docs-verified integration research (custom-modes schema, `.roo/commands/` layout, `new_task` subagent dispatch) is directly reusable there without any gsd-core change.
- **Shipping Zoo as a third-party `role: "runtime"` capability via ADR-1244's external loader.** ADR-857 D8 deferred third-party CLI/runtime support "to an external loader + trust/validation gate"; ADR-1244 (Accepted, ratified 2026-07-17) is that ADR and delivers that gate — a third-party capability, including `role: "runtime"`, can be installed from outside gsd-core's own tree (`~/.gsd/capabilities/<id>/` global, or `.gsd/capabilities/<id>/` project-scoped) under its trust/consent model. This is a live mechanism today, not a future trigger — see "Re-open criteria" below.
- **Shipping an out-of-tree host-plugin for Zoo Code.** This is welcome and supported, and is the intended route — a Zoo plugin that embeds MSD via the Host-Integration SDK and is listed in `docs/registries/eos.json`, same as `msd-cursor`/`msd-omp`/`msd-reasonix`. The reporter's own docs-verified integration research (custom-modes schema, `.roo/commands/` layout, `new_task` subagent dispatch) is directly reusable there without any msd-core change.
- **Shipping Zoo as a third-party `role: "runtime"` capability via ADR-1244's external loader.** ADR-857 D8 deferred third-party CLI/runtime support "to an external loader + trust/validation gate"; ADR-1244 (Accepted, ratified 2026-07-17) is that ADR and delivers that gate — a third-party capability, including `role: "runtime"`, can be installed from outside msd-core's own tree (`~/.msd/capabilities/<id>/` global, or `.msd/capabilities/<id>/` project-scoped) under its trust/consent model. This is a live mechanism today, not a future trigger — see "Re-open criteria" below.
- **A Zoo integration built as a Capability**, if what's actually needed is a toggleable feature rather than a new host identity.
- **Fixing defects that surface through a non-registered runtime**, or improving the documented override/SDK contracts a host plugin depends on.
- **Migrations of already-supported runtimes onto the EoS architecture.**
@@ -30,7 +30,7 @@ This entry denies **first-party, in-tree runtime registration for Zoo Code.** It
## Re-open criteria
- **The ADR-857 D8 external-loader condition is already met** — ADR-1244 (Accepted 2026-07-17) delivers third-party `role: "runtime"` capability loading; this is no longer a future trigger. What remains unmet is a maintainer decision to expand gsd-core's own *first-party, in-tree* supported-runtime set specifically — that is a bandwidth/scope call, not a tooling gap, and reopens only if funded development changes the maintenance calculus described above.
- **The ADR-857 D8 external-loader condition is already met** — ADR-1244 (Accepted 2026-07-17) delivers third-party `role: "runtime"` capability loading; this is no longer a future trigger. What remains unmet is a maintainer decision to expand msd-core's own *first-party, in-tree* supported-runtime set specifically — that is a bandwidth/scope call, not a tooling gap, and reopens only if funded development changes the maintenance calculus described above.
- Zoo Code demonstrates an integration need the EoS Host-Integration Interface AND the ADR-1244 third-party capability loader genuinely cannot express (none shown to date).
## Related
@@ -38,6 +38,6 @@ This entry denies **first-party, in-tree runtime registration for Zoo Code.** It
- [`crush-runtime-in-core.md`](./crush-runtime-in-core.md) — sibling decision, same ground, same standing policy
- [`omp-runtime-in-core.md`](./omp-runtime-in-core.md) — sibling decision, same ground
- [`kiro-runtime-in-core.md`](./kiro-runtime-in-core.md) — sibling decision filed the same day, same ground
- [ADR-1239](../docs/adr/1239-gsd-embeddable-orchestration-engine.md) — GSD as an Embeddable Orchestration Engine (EoS)
- [ADR-1239](../docs/adr/1239-msd-embeddable-orchestration-engine.md) — MSD as an Embeddable Orchestration Engine (EoS)
- [`docs/how-to/author-a-host-plugin.md`](../docs/how-to/author-a-host-plugin.md) — the supported out-of-tree authoring path
- [`docs/how-to/develop-a-capability.md`](../docs/how-to/develop-a-capability.md) — the Capability path, if the need turns out to be feature-shaped

View File

@@ -10,23 +10,23 @@ All changes in `bin/install.js` unless noted.
**Line 5391-5392** — After `fs.copyFileSync`, add `fs.chmodSync(destFile, 0o755)` for `.sh` files.
### Fix 2: Fix Codex hook path and filename (CRITICAL)
**Line 5485** — Change `gsd-update-check.js` to `gsd-check-update.js` and fix path from `gsd-core/hooks/` to `hooks/`.
**Line 5492** — Update dedup check to use `gsd-check-update`.
**Line 5485** — Change `msd-update-check.js` to `msd-check-update.js` and fix path from `msd-core/hooks/` to `hooks/`.
**Line 5492** — Update dedup check to use `msd-check-update`.
### Fix 3: Fix stale cache invalidation path (CRITICAL)
**Line 5406** — Change from `path.join(path.dirname(targetDir), 'cache', ...)` to `path.join(os.homedir(), '.cache', 'gsd', 'gsd-update-check.json')`.
**Line 5406** — Change from `path.join(path.dirname(targetDir), 'cache', ...)` to `path.join(os.homedir(), '.cache', 'msd', 'msd-update-check.json')`.
### Fix 4: Track .sh hooks in manifest (MEDIUM)
**Line 4972** — Change filter from `file.endsWith('.js')` to `(file.endsWith('.js') || file.endsWith('.sh'))`.
### Fix 5: Add gsd-workflow-guard.js to uninstall hook list (MEDIUM)
**Line 4404** — Add `'gsd-workflow-guard.js'` to the `gsdHooks` array.
### Fix 5: Add msd-workflow-guard.js to uninstall hook list (MEDIUM)
**Line 4404** — Add `'msd-workflow-guard.js'` to the `msdHooks` array.
### Fix 6: Add community hooks to uninstall settings.json cleanup (MEDIUM)
**Lines 4453-4520** — Add filters for `gsd-session-state`, `gsd-validate-commit`, `gsd-phase-boundary` in the appropriate event cleanup blocks (SessionStart, PreToolUse, PostToolUse).
**Lines 4453-4520** — Add filters for `msd-session-state`, `msd-validate-commit`, `msd-phase-boundary` in the appropriate event cleanup blocks (SessionStart, PreToolUse, PostToolUse).
### Fix 7: Remove phantom gsd-check-update.sh from uninstall list (LOW)
**Line 4404** — Remove `'gsd-check-update.sh'` from `gsdHooks` array.
### Fix 7: Remove phantom msd-check-update.sh from uninstall list (LOW)
**Line 4404** — Remove `'msd-check-update.sh'` from `msdHooks` array.
### Fix 8: Remove dead isCursor/isWindsurf branches in uninstall (LOW)
Remove the unreachable duplicate `else if (isCursor)` and `else if (isWindsurf)` branches.
@@ -41,6 +41,6 @@ After the generic check, warn if expected `.sh` files are missing (non-fatal war
- .sh files tracked in manifest
- settings.json hook paths match installed files
- uninstall removes community hooks from settings.json
- uninstall removes gsd-workflow-guard.js
- uninstall removes msd-workflow-guard.js
- Codex hook uses correct filename
- Cache path resolves correctly

View File

@@ -1,11 +1,11 @@
#!/usr/bin/env bash
# Release monitor for open-gsd/gsd-core
# Release monitor for golem15com/msd-core
# Checks every 15 minutes, writes new release info to a signal file
REPO="open-gsd/gsd-core"
SIGNAL_FILE="/tmp/gsd-new-release.json"
STATE_FILE="/tmp/gsd-monitor-last-tag"
LOG_FILE="/tmp/gsd-monitor.log"
REPO="golem15com/msd-core"
SIGNAL_FILE="/tmp/msd-new-release.json"
STATE_FILE="/tmp/msd-monitor-last-tag"
LOG_FILE="/tmp/msd-monitor.log"
# Initialize with current latest
echo "v1.25.1" > "$STATE_FILE"

View File

@@ -23,10 +23,10 @@
# Lint: scripts/secret-scan-lint.sh --file .secretscanignore
# Strict scan: scripts/secret-scan.sh --diff origin/main --strict
# allow: gsd-core/workflows/plan-phase.md reason="contains illustrative DATABASE_URL/REDIS_URL example strings used as documentation placeholders — not real credentials" owner="@open-gsd/maintainers" expires="2027-06-30"
gsd-core/workflows/plan-phase.md
# allow: msd-core/workflows/plan-phase.md reason="contains illustrative DATABASE_URL/REDIS_URL example strings used as documentation placeholders — not real credentials" owner="@open-gsd/maintainers" expires="2027-06-30"
msd-core/workflows/plan-phase.md
# allow: gsd-core/references/verification-patterns.md reason="documents stub/placeholder RED-FLAG examples for env vars (illustrative Stripe test-key, database-URL and API-key placeholders shown as what NOT to ship) — not real credentials" owner="@open-gsd/maintainers" expires="2027-06-30"
gsd-core/references/verification-patterns.md
# allow: msd-core/references/verification-patterns.md reason="documents stub/placeholder RED-FLAG examples for env vars (illustrative Stripe test-key, database-URL and API-key placeholders shown as what NOT to ship) — not real credentials" owner="@open-gsd/maintainers" expires="2027-06-30"
msd-core/references/verification-patterns.md
# allow: docs/zh-CN/references/verification-patterns.md reason="translated copy of the English verification-patterns.md — carries the same illustrative placeholder examples (Stripe test-key, database-URL, API-key) as what NOT to ship" owner="@open-gsd/maintainers" expires="2027-06-30"
docs/zh-CN/references/verification-patterns.md

File diff suppressed because one or more lines are too long

View File

@@ -1,11 +1,11 @@
# Contributing to GSD Core
# Contributing to MSD Core
## Getting Started
```bash
# Clone the repo
git clone https://github.com/open-gsd/gsd-core.git
cd gsd-core
git clone https://github.com/golem15com/msd-core.git
cd msd-core
# Activate the pinned Node version from .nvmrc
nvm use
@@ -31,7 +31,7 @@ environment validator, daily commands, and troubleshooting.
## Types of Contributions
GSD accepts three types of contributions. Each type has a different process and a different bar for acceptance. **Read this section before opening anything.**
MSD accepts three types of contributions. Each type has a different process and a different bar for acceptance. **Read this section before opening anything.**
### 🐛 Fix (Bug Report)
@@ -72,11 +72,11 @@ A feature adds something new — a new command, a new workflow, a new concept, a
**Process:**
1. **Discuss first** — check [Discussions](https://github.com/open-gsd/gsd-core/discussions) to see if the idea has been raised. If it has and was declined, don't open a new issue.
2. Open a [Feature Request issue](https://github.com/open-gsd/gsd-core/issues/new?template=feature_request.yml) with the complete spec. The template requires: the solo-developer problem being solved, what is being added, full scope of affected files and systems, user stories, acceptance criteria, and assessment of maintenance burden.
3. **Wait for maintainer approval.** A maintainer must label the issue `approved-feature` before you write a single line of code. Approval is not guaranteed — GSD is intentionally lean and many valid ideas are declined because they conflict with the project's design philosophy.
3. **Wait for maintainer approval.** A maintainer must label the issue `approved-feature` before you write a single line of code. Approval is not guaranteed — MSD is intentionally lean and many valid ideas are declined because they conflict with the project's design philosophy.
4. Write the code. Implement exactly the approved spec. Changes to scope require re-approval.
5. Open a PR using the [Feature PR template](.github/PULL_REQUEST_TEMPLATE/feature.md) — link the approved issue.
**Rejection reasons:** Issue not labeled `approved-feature`, spec is incomplete, scope exceeds what was approved, feature conflicts with GSD's solo-developer focus, maintenance burden too high.
**Rejection reasons:** Issue not labeled `approved-feature`, spec is incomplete, scope exceeds what was approved, feature conflicts with MSD's solo-developer focus, maintenance burden too high.
---
@@ -120,7 +120,7 @@ PRs that arrive without a properly-labeled linked issue are closed automatically
## Where Do I Open My PR? (Branching Model)
GSD uses two long-lived branches: `main` (production, what's on npm `@latest`)
MSD uses two long-lived branches: `main` (production, what's on npm `@latest`)
and `next` (integration for the upcoming release). **Almost every PR targets
`next`.** Full guide: [`docs/branching.md`](docs/branching.md).
@@ -142,7 +142,7 @@ git checkout next
git pull --ff-only origin next
git checkout -b fix/3187-config-corruption
# ... commit, push
gh pr create --base next --repo open-gsd/gsd-core
gh pr create --base next --repo golem15com/msd-core
```
If you target the wrong branch by accident, the `PR Target Validator`
@@ -155,7 +155,7 @@ another PR to `next` lands — so in practice you rebase much less.
**But `next` does still require "up-to-date before merging".** Branch
protection has `required_status_checks.strict = true`; check it yourself with
`gh api repos/open-gsd/gsd-core/branches/next/protection --jq '.required_status_checks.strict'`.
`gh api repos/golem15com/msd-core/branches/next/protection --jq '.required_status_checks.strict'`.
If another PR lands while yours is open, yours goes `BEHIND` and must be
rebased before it can merge.
@@ -192,7 +192,7 @@ Contributor requirements (summary):
- **Use the correct PR template** — there are separate templates for [Fix](.github/PULL_REQUEST_TEMPLATE/fix.md), [Enhancement](.github/PULL_REQUEST_TEMPLATE/enhancement.md), and [Feature](.github/PULL_REQUEST_TEMPLATE/feature.md). Using the wrong template or using the default template for a feature is a rejection reason.
- **Link with a closing keyword** — use `Closes #123`, `Fixes #123`, or `Resolves #123` in the PR body. The CI check will fail and the PR will be auto-closed if no valid issue reference is found.
- **Test-only and docs-only follow-up PRs may reference without closing.** If your PR is documentation or regression coverage only — say, a repo-wide guard for a fix that already shipped — and there is no open issue for it to close, use a non-closing reference instead: `Refs #123`. `Ref`, `Refs`, `References`, `Relates to`, `Related to`, and `Follow-up to` are all accepted in that position. Do **not** write a closing keyword against an already-closed issue to satisfy the check; on merge it closes nothing, and it trains readers to treat closing keywords as decorative.
- **Qualifying diff shape:** every changed file must be under `tests/`, under `docs/`, or a root-level `*.md` (`README.md`, `CONTRIBUTING.md`, …). This mirrors the doc-only classification the push gate already uses, and it is deliberately root-only — markdown under a subdirectory (`gsd-core/workflows/*.md`, `agents/*.md`, `commands/**/*.md`) is runtime-loaded text, not documentation, so it still requires a closing keyword. `CHANGELOG.md` is excluded too: edit it through a `.changeset/` fragment, never directly.
- **Qualifying diff shape:** every changed file must be under `tests/`, under `docs/`, or a root-level `*.md` (`README.md`, `CONTRIBUTING.md`, …). This mirrors the doc-only classification the push gate already uses, and it is deliberately root-only — markdown under a subdirectory (`msd-core/workflows/*.md`, `agents/*.md`, `commands/**/*.md`) is runtime-loaded text, not documentation, so it still requires a closing keyword. `CHANGELOG.md` is excluded too: edit it through a `.changeset/` fragment, never directly.
- This weaker form is accepted **only** for that diff shape. A PR touching anything else still needs a closing keyword, and a PR with no issue reference at all still fails. On a very large PR (more than 100 changed files) the check cannot confirm the diff shape and falls back to requiring a closing keyword.
- **One concern per PR** — bug fixes, enhancements, and features must be separate PRs
- **No drive-by formatting** — don't reformat code unrelated to your change
@@ -206,14 +206,14 @@ Contributor requirements (summary):
```bash
npm run changeset -- --type Fixed --pr <YOUR_PR_NUMBER> \
--body "**\`/gsd-foo\` no longer drops trailing slashes** — explain the user-visible change."
--body "**\`/msd-foo\` no longer drops trailing slashes** — explain the user-visible change."
```
This writes `.changeset/<adjective>-<noun>-<noun>.md`. Three random words → concurrent PRs never collide. Allowed `type:` values follow [Keep a Changelog](https://keepachangelog.com/): `Added`, `Changed`, `Deprecated`, `Removed`, `Fixed`, `Security`.
Fragments are consolidated into `CHANGELOG.md` at release time by the release workflow. See [`.changeset/README.md`](.changeset/README.md) for the format spec and [#2975](https://github.com/open-gsd/gsd-core/issues/2975) for the rationale.
**CI enforcement:** the `Changeset Required` workflow (`scripts/changeset/lint.cjs`) fails any PR that touches `bin/`, `gsd-core/`, `src/`, `agents/`, `commands/`, `hooks/`, or `sdk/src/` without a `.changeset/*.md` fragment. (`src/` is the TypeScript source of truth compiled into `gsd-core/bin/lib/*.cjs`, so editing it is a user-facing change even though the generated `.cjs` is gitignored and never appears in the diff.)
**CI enforcement:** the `Changeset Required` workflow (`scripts/changeset/lint.cjs`) fails any PR that touches `bin/`, `msd-core/`, `src/`, `agents/`, `commands/`, `hooks/`, or `sdk/src/` without a `.changeset/*.md` fragment. (`src/` is the TypeScript source of truth compiled into `msd-core/bin/lib/*.cjs`, so editing it is a user-facing change even though the generated `.cjs` is gitignored and never appears in the diff.)
> **Running it locally.** The lint derives its changed-file set from `GITHUB_BASE_REF`, which only CI sets. `node scripts/changeset/lint.cjs` on a developer machine therefore does **not** evaluate your branch and can report success on a PR that CI will fail. Pass the base explicitly to reproduce the CI result:
>
@@ -238,7 +238,7 @@ To re-format an existing release by hand (e.g. backfilling an older release):
```bash
node scripts/release-notes/format-github-release-notes.cjs \
--tag vX.Y.Z --repo open-gsd/gsd-core --apply
--tag vX.Y.Z --repo golem15com/msd-core --apply
```
Omit `--apply` to print the reformatted body to stdout for review without
@@ -451,16 +451,16 @@ test('does the thing', () => {
Import helpers from `tests/helpers.cjs` instead of inlining temp directory creation:
```javascript
const { createTempProject, createTempGitProject, createTempDir, cleanup, runGsdTools } = require('./helpers.cjs');
const { createTempProject, createTempGitProject, createTempDir, cleanup, runMsdTools } = require('./helpers.cjs');
```
| Helper | Creates | Use When |
|--------|---------|----------|
| `createTempProject(prefix?)` | tmpDir with `.planning/phases/` | Testing GSD tools that need planning structure |
| `createTempProject(prefix?)` | tmpDir with `.planning/phases/` | Testing MSD tools that need planning structure |
| `createTempGitProject(prefix?)` | Same + git init + initial commit | Testing git-dependent features |
| `createTempDir(prefix?)` | Bare temp directory | Testing features that don't need `.planning/` |
| `cleanup(tmpDir)` | Removes directory recursively | Always use in `afterEach` |
| `runGsdTools(args, cwd, env?)` | Executes gsd-tools.cjs | Testing CLI commands |
| `runMsdTools(args, cwd, env?)` | Executes msd-tools.cjs | Testing CLI commands |
### Spawning a subprocess: use the process seam
@@ -710,7 +710,7 @@ You do not need all twelve cases for every PR. You do need to cover the cases th
#### CLI and command routing
Changes to CLI parsing, command dispatch, query dispatch, command routers, `gsd-tools`, or `gsd-sdk` must include a negative input matrix for the affected command family.
Changes to CLI parsing, command dispatch, query dispatch, command routers, `msd-tools`, or `msd-sdk` must include a negative input matrix for the affected command family.
Required cases where relevant:
@@ -763,7 +763,7 @@ Property-style parser tests are encouraged for high-risk parsers. They must be d
This is stricter than the adversarial-input rule above and exists because of it: `tests/fixtures/adversarial/` covers hostile input, but a fixture written by the parser's own author — even a deliberately "realistic" one — is still drawn from the author's mental model of the format. It can only ever confirm what the author already believed, never surface what they didn't anticipate. A property-test generator has the same failure mode one level up: seeding the generator from the writer/render function that produces the same format makes the document shape a constant, so the property can never explore a document the writer wouldn't produce (see the document-shaped vs. writer-seeded property tests in `tests/api-coverage.test.cjs` for a worked example — the writer-seeded one cannot fail against a decoy table; the document-shaped one can).
For a gate whose fixtures come from real user reports, put them under `tests/fixtures/representative/<gate>/` with a `MANIFEST.json` labeling each fixture's source issue and expected gate verdict, and drive them through the gate's real CLI entrypoint (gate-verdict altitude), not the parser function in isolation — see `tests/fixtures/representative/README.md` and `tests/representative-corpus.test.cjs`. If the gate is not yet fixed, do not mark the assertion `{ todo: true }` and do not skip it: this repo's test-runner (`gsd-test` / `gsd-test-runner`) has no concept of node:test's `todo` option — its JSONL result parser only recognizes `kind: "pass" | "fail"`, so a thrown todo-marked test is still counted as a real failure and blocks the push gate. Instead record BOTH the correct target verdict (`expected*`) and the exact current observed verdict (`currentBuggyOutput`) in the manifest, and assert against `currentBuggyOutput` — an honest, non-vacuous characterization of today's known-broken behavior that passes today and breaks loudly the moment the real fix changes the observed output, forcing the assertion to be flipped to `expected*`.
For a gate whose fixtures come from real user reports, put them under `tests/fixtures/representative/<gate>/` with a `MANIFEST.json` labeling each fixture's source issue and expected gate verdict, and drive them through the gate's real CLI entrypoint (gate-verdict altitude), not the parser function in isolation — see `tests/fixtures/representative/README.md` and `tests/representative-corpus.test.cjs`. If the gate is not yet fixed, do not mark the assertion `{ todo: true }` and do not skip it: this repo's test-runner (`msd-test` / `msd-test-runner`) has no concept of node:test's `todo` option — its JSONL result parser only recognizes `kind: "pass" | "fail"`, so a thrown todo-marked test is still counted as a real failure and blocks the push gate. Instead record BOTH the correct target verdict (`expected*`) and the exact current observed verdict (`currentBuggyOutput`) in the manifest, and assert against `currentBuggyOutput` — an honest, non-vacuous characterization of today's known-broken behavior that passes today and breaks loudly the moment the real fix changes the observed output, forcing the assertion to be flipped to `expected*`.
#### Filesystem writes and installers
@@ -825,7 +825,7 @@ Generator tests should run in temp fixtures and assert atomic output behavior. D
```javascript
// BAD — source-grep theater
const configSrc = fs.readFileSync(
path.join(GSD_ROOT, 'gsd-core', 'bin', 'lib', 'config-schema.cjs'), 'utf-8'
path.join(MSD_ROOT, 'msd-core', 'bin', 'lib', 'config-schema.cjs'), 'utf-8'
);
assert.ok(
configSrc.includes("'workflow.plan_bounce'"),
@@ -843,7 +843,7 @@ test('config-set accepts workflow.plan_bounce', (t) => {
const tmpDir = createTempProject();
t.after(() => cleanup(tmpDir));
const result = runGsdTools('config-set workflow.plan_bounce true', tmpDir);
const result = runMsdTools('config-set workflow.plan_bounce true', tmpDir);
assert.ok(result.success, `config-set should accept workflow.plan_bounce: ${result.error}`);
const configPath = path.join(tmpDir, '.planning', 'config.json');
@@ -869,7 +869,7 @@ Some tests legitimately read source files. There are six recognized categories:
| `structural-regression-guard` | A specific code pattern must (or must not) exist to prevent a class of bug (e.g., regex global-state misuse). Behavioral tests cannot distinguish which pattern was used. |
| `docs-parity` | A reference doc must stay in sync with source-defined constants (e.g., `CONFIG_DEFAULTS`). The source is the canonical list; there is no runtime API to enumerate it. |
| `integration-test-input` | A source file is used as a real fixture input to a transformation function under test — the file is not inspected for strings but passed as data. |
| `structural-implementation-guard` | A feature's interception or wiring point is not reachable end-to-end via `runGsdTools`. Used temporarily until a behavioral path exists. |
| `structural-implementation-guard` | A feature's interception or wiring point is not reachable end-to-end via `runMsdTools`. Used temporarily until a behavioral path exists. |
| `pending-migration-to-typed-ir` | **Tracked for correction, not exempted.** Test was identified by the lint as carrying a raw-text-matching pattern that contradicts the rule above. Each annotated file MUST cite the open migration issue (e.g. `// allow-test-rule: pending-migration-to-typed-ir [#NNNN]`) so the tracking is auditable. New tests cannot use this category — they must refactor production to expose typed IR. The annotation is removed when the test is corrected. |
**Suppression is site-scoped, not file-wide.** A marker suppresses only the violation it sits next
@@ -924,7 +924,7 @@ The following are all violations of the same rule:
```javascript
// BAD — substring match on text written by the code under test
const cmdContent = fs.readFileSync(path.join(tmpDir, 'gsd-sdk.cmd'), 'utf8');
const cmdContent = fs.readFileSync(path.join(tmpDir, 'msd-sdk.cmd'), 'utf8');
assert.ok(cmdContent.includes(`@node ${jsonQuoted} %*`), '.cmd embeds shim path');
// BAD — regex match on a child process's human-readable stdout formatter
@@ -959,7 +959,7 @@ Concretely: for any system-under-test that produces text output (a file renderer
#### Concrete example from this repo
`gsd-core/bin/verify-reapply-patches.cjs` exposes a frozen `REASON` enum and emits it through `--json`. Tests assert `report.results[0].reason === REASON.FAIL_USER_LINES_MISSING` rather than regex-matching the human-readable prose. The human formatter exists for operator console output only — tests must not depend on it. Adding a new reason code requires updating the `REASON` enum, the `--json` output, AND the test that locks `Object.keys(REASON).sort()` — three coordinated changes that keep the code surface from drifting from the test surface. A pure builder that returns the IR (no I/O) and a writer that consumes it — `fs.statSync(target).size === Buffer.byteLength(render())` to prove the writer writes what the renderer produces, **without comparing content** — is the same pattern applied to rendered files.
`msd-core/bin/verify-reapply-patches.cjs` exposes a frozen `REASON` enum and emits it through `--json`. Tests assert `report.results[0].reason === REASON.FAIL_USER_LINES_MISSING` rather than regex-matching the human-readable prose. The human formatter exists for operator console output only — tests must not depend on it. Adding a new reason code requires updating the `REASON` enum, the `--json` output, AND the test that locks `Object.keys(REASON).sort()` — three coordinated changes that keep the code surface from drifting from the test surface. A pure builder that returns the IR (no I/O) and a writer that consumes it — `fs.statSync(target).size === Buffer.byteLength(render())` to prove the writer writes what the renderer produces, **without comparing content** — is the same pattern applied to rendered files.
#### Hiding grep behind a function is still grep
@@ -1031,7 +1031,7 @@ For examples of required negative matrices, parser fixtures, filesystem fault in
When you can, run the local test bench harness before opening a PR — especially for Windows-sensitive changes.
- Setup guide: [gsd-test-runner getting started](https://github.com/open-gsd/gsd-test-runner/blob/main/docs/getting-started.md)
- Setup guide: [msd-test-runner getting started](https://github.com/open-gsd/gsd-test-runner/blob/main/docs/getting-started.md)
- Preferred PR evidence: include the bench results summary (or artifact link) in your PR body.
This gives maintainers a faster, higher-confidence signal than CI-only validation.
@@ -1045,15 +1045,15 @@ sources it feeds, run:
npm run check:alias-drift
```
This verifies the built alias artifacts under `gsd-core/bin/lib/` agree with their
This verifies the built alias artifacts under `msd-core/bin/lib/` agree with their
source of truth — each family's `*_SUBCOMMANDS` list must match the `subcommand`
values derived from its `*_COMMAND_ALIASES` table, in order, and each router must
reference its own list. The surface is enumerated once in
`scripts/lib/alias-drift-families.cjs`.
### Editing shipped content (gsd-core/workflows, references, templates, contexts, agents/, commands/gsd/)
### Editing shipped content (msd-core/workflows, references, templates, contexts, agents/, commands/msd/)
Editing the content of a copied shipped file — a `gsd-core/workflows/*.md`, an agent, a
Editing the content of a copied shipped file — a `msd-core/workflows/*.md`, an agent, a
command definition — requires **zero manual fixture regeneration**. There is no
committed path→hash manifest or per-file size baseline to update by hand; the
differential attribution check (`tests/emitted-attribution.test.cjs`, ADR-2719) computes
@@ -1065,12 +1065,12 @@ a converter change, for example — go through a **commit trailer on one of your
commits** (ADR-3942; name the key, say why):
```
Emitted-Drift-Ack-Hash: skills/gsd-add-tests/SKILL.md — the converter rewrote every skill header
Emitted-Drift-Ack-Hash: skills/msd-add-tests/SKILL.md — the converter rewrote every skill header
Emitted-Drift-Ack-Growth: explore.md — new dispatch section, reasoning ships with the block
```
See `CONTEXT.md`'s `### Emitted Artifact Provenance` entry for the full model. Growth in a
`gsd-core/workflows/*.md` or `agents/gsd-*.md` file is reported with its exact byte delta
`msd-core/workflows/*.md` or `agents/msd-*.md` file is reported with its exact byte delta
and needs the same acknowledgment; the outer tier hard caps in
`tests/workflow-size-budget.test.cjs` / `tests/agent-size-budget.test.cjs` are unaffected
and still apply.
@@ -1096,8 +1096,8 @@ You do not need to memorize any of this. **The failure output names its own reme
tells you which key to add and prints a minimal trailer line you can paste onto one of your
commits. Note the two key spaces, because the message says which one applies: an
unattributable **hash** ripple is keyed on the emitted path
(`skills/gsd-add-tests/SKILL.md`), while **growth** is keyed on the bare filename as it
appears under `gsd-core/workflows/` or `agents/` (`explore.md`). The two spaces are
(`skills/msd-add-tests/SKILL.md`), while **growth** is keyed on the bare filename as it
appears under `msd-core/workflows/` or `agents/` (`explore.md`). The two spaces are
structurally distinct — a `Growth` trailer never excuses a `Hash` ripple, even when the key
text happens to match.
@@ -1119,7 +1119,7 @@ reports an ordinary (non-protected) line that moved from a spine into its own de
without a declaration, add:
```
Boundary-Move-Declared: gsd-core/workflows/plan-phase.md — condensed the filesystem-fallback banner into one summary paragraph
Boundary-Move-Declared: msd-core/workflows/plan-phase.md — condensed the filesystem-fallback banner into one summary paragraph
```
Same range (`git log $(git merge-base <base> HEAD)..HEAD`), same fail-closed behavior on an
@@ -1174,7 +1174,7 @@ hooks does not enable this check:
```bash
# set locally in your shell profile (example)
export GSD_BLOCKED_AUTHOR_REGEX='@example-corp\.com$'
export MSD_BLOCKED_AUTHOR_REGEX='@example-corp\.com$'
```
With that exported, a push carrying a commit whose author email matches is blocked,
@@ -1182,8 +1182,8 @@ and the hook names the offending commits. Unset the variable to disable it.
### Every `commit` invocation in shipped content must declare `--files`
`tests/commit-files-pathspec.test.cjs` scans every `.md` under `gsd-core/workflows/`,
`gsd-core/references/`, `agents/`, `commands/`, `skills/` and `docs/` for invocations of
`tests/commit-files-pathspec.test.cjs` scans every `.md` under `msd-core/workflows/`,
`msd-core/references/`, `agents/`, `commands/`, `skills/` and `docs/` for invocations of
the `commit` seam, and fails if any of them reaches the runtime without a `--files`
scope. An unscoped invocation lands on the blanket-stage default and sweeps the whole
`.planning/` index into a commit whose message names one artifact — that is [#2269](https://github.com/open-gsd/gsd-core/issues/2269),
@@ -1197,7 +1197,7 @@ would blind the guard to every site the issue was filed about. Two consequences
hit while editing shipped content, and the failure output names both:
**A prose mention that runs into its sentence is flagged.** Nothing distinguishes
`gsd_run query commit` followed by ordinary words from an invocation with arguments
`msd_run query commit` followed by ordinary words from an invocation with arguments
without guessing at English, so the scan does not try. Write the command reference in
backticks — the repo's own convention — and it is correctly read as a mention.
@@ -1207,7 +1207,7 @@ stand in for your intent. Declare it on the invocation's own line, in shell-comm
position:
```
gsd_run query commit "docs: message" # gsd-scan-ignore: #2269 counter-example for the docs
msd_run query commit "docs: message" # msd-scan-ignore: #2269 counter-example for the docs
```
That block is a live example of itself: the invocation above really is unscoped, and it
@@ -1223,8 +1223,8 @@ means the runtime executed the line.
### Every `git add` in shipped content that can reach `.planning/` must sit inside an *executable* `commit_docs` check
`tests/commit-docs-bypass.test.cjs` scans every `.md` under `gsd-core/workflows/`,
`gsd-core/references/`, `agents/`, `commands/` and `skills/` and fails if a `git add` that could
`tests/commit-docs-bypass.test.cjs` scans every `.md` under `msd-core/workflows/`,
`msd-core/references/`, `agents/`, `commands/` and `skills/` and fails if a `git add` that could
stage `.planning/` is not enclosed by a `commit_docs` check that actually runs.
This is the sibling of the `--files` guard above, and it exists for the complementary hole.
@@ -1244,24 +1244,24 @@ git add "${EVAL_REVIEW_FILE}" ← runs unconditionally; the bold line i
````
The bash block executes whatever the sentence above it says. Write the check in shell, which is
the form `gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md` already uses:
the form `msd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md` already uses:
```bash
COMMIT_DOCS=$(gsd_run query config-get commit_docs 2>/dev/null || echo "true")
COMMIT_DOCS=$(msd_run query config-get commit_docs 2>/dev/null || echo "true")
if [ "$COMMIT_DOCS" != "false" ]; then
git add "${ARTIFACT}"
fi
```
Both polarities are accepted (`!= "false"` and `= "true"`). The `|| echo "true"` fallback is
deliberate: a tooling failure must fail *open*, or a broken `gsd-tools` silently stops committing
deliberate: a tooling failure must fail *open*, or a broken `msd-tools` silently stops committing
planning docs for someone who wants them.
Three consequences worth knowing before you edit shipped content:
**Guard state does not cross a fenced block.** Each fenced block is its own shell, so an `if`
opened in one block does not protect a `git add` in the next — the same reason
`new-milestone.md` warns that a `GSD_WS` guard set in an earlier step reads as unset later. Put
`new-milestone.md` warns that a `MSD_WS` guard set in an earlier step reads as unset later. Put
the check and the `git add` in the same block.
**An unresolvable path is treated as reaching `.planning/`.** `git add "${ARTIFACT}"` is flagged,
@@ -1272,7 +1272,7 @@ trigger it. If your `git add` genuinely cannot touch `.planning/`, name the path
**Only fenced lines are scanned.** Inline-backtick prose — including the anti-pattern
documentation that tells you never to run `git add -A` — is not executable and is not flagged.
The same `# gsd-scan-ignore: #NNN` declaration as the `--files` guard exempts a deliberate
The same `# msd-scan-ignore: #NNN` declaration as the `--files` guard exempts a deliberate
counter-example, on the invocation's own line, in shell-comment position, with a reason naming a
tracking issue or URL. Both guards share one tokenizer and one marker implementation
(`tests/helpers/shipped-command-scan.cjs`) so the two conventions can never drift into two rules
@@ -1281,7 +1281,7 @@ wearing one name.
**Known limits.** The scan (`tests/helpers/planning-add-guard.cjs`) is a token-oriented text scan,
not a shell interpreter, and it targets accidental reintroduction of an unguarded stage by a
contributor editing shipped content — not a determined bypass. Four shapes are confirmed (#3585)
to stage `.planning/` at runtime while scoring zero offenders, and none is a shape GSD content
to stage `.planning/` at runtime while scoring zero offenders, and none is a shape MSD content
actually uses: `eval "git add -A"`, `find .planning -type f | xargs git add`, a one-line shell
function body (`f() { git add -A; }`), and a backslash line-continuation split across two physical
lines. The scan also only models `git add` and `git commit -a`/`--all` as staging commands — it
@@ -1327,7 +1327,7 @@ The following checks run on every PR in addition to the test suite:
| Job | What it checks | How to pass |
|-----|----------------|-------------|
| `Lint — ESLint` | No source-grep tests (see above), via the `local/no-source-grep` rule | Replace with `runGsdTools()` behavioral tests, or add `// allow-test-rule: <reason>` |
| `Lint — ESLint` | No source-grep tests (see above), via the `local/no-source-grep` rule | Replace with `runMsdTools()` behavioral tests, or add `// allow-test-rule: <reason>` |
| `Lint — cross-platform portability` | Windows-portability defects in tests, via `local/no-path-literal-in-assert` (more rules land per [ADR-1703](docs/adr/1703-portability-enforcement-architecture.md)) — e.g. a path-returning call asserted against a hardcoded `/`-literal | Normalize the actual: `String(pathFn(...)).replace(/\\/g, '/')`, or structure platform-specific code behind a `process.platform !== 'win32'` guard. **No `eslint-disable`** — see [cross-platform-portability-rules.md](docs/contributing/cross-platform-portability-rules.md) |
| `lint-docs-guard-registration.cjs` (via `npm run lint:ci`) | A test that reads shipped `docs/` content must be registered so it runs on the PR that changes those docs — otherwise it can only fail after merge | Register it in `scripts/docs-guard-registry.cjs`, mapping the test to the docs paths it reads, or mark it `// docs-guard-exempt: <reason>` and list it in `scripts/lint-docs-guard-registration.exempt-baseline.cjs` — see [docs-guard-registration.md](docs/contributing/docs-guard-registration.md) |
| `lint-response-language-coverage.cjs` (via `npm run lint:ci`) | Every workflow file instructs the model to honour `response_language` in user-facing prose, and the directive names inter-tool narration rather than questions alone — a directive that omits the narration class leaves running commentary in English beside translated answers (#2529) | Give the file one of the four coverage forms: the eager `@`-reference, its own inline directive, the pinned line, or proven inheritance from the parent that dispatches it — see [response-language-coverage.md](docs/contributing/response-language-coverage.md) |
@@ -1374,14 +1374,14 @@ Defensive normalization at trust boundaries must validate both the value's type
## Code Style
- **CommonJS** (`.cjs`) — the project uses `require()`, not ESM `import`
- **No external dependencies in core** — `gsd-tools.cjs` and all lib files use only Node.js built-ins
- **Conventional commits** — `feat:`, `fix:`, `docs:`, `refactor:`, `test:`, `ci:`. The full grammar is `<type>(<scope>): <subject>` (enforced by `hooks/gsd-validate-commit.sh`; subject ≤72 chars, lowercase, imperative mood, no trailing period). When the work resolves a tracked issue, put the issue number in the scope: `fix(#1520): randomize mktemp temp paths on BSD/macOS`. The same convention applies to PR titles — release notes are grouped by the title's type prefix (`feat` → Feature, `fix` → Fix, non-user-facing types omitted, everything else → Enhancement).
- **No external dependencies in core** — `msd-tools.cjs` and all lib files use only Node.js built-ins
- **Conventional commits** — `feat:`, `fix:`, `docs:`, `refactor:`, `test:`, `ci:`. The full grammar is `<type>(<scope>): <subject>` (enforced by `hooks/msd-validate-commit.sh`; subject ≤72 chars, lowercase, imperative mood, no trailing period). When the work resolves a tracked issue, put the issue number in the scope: `fix(#1520): randomize mktemp temp paths on BSD/macOS`. The same convention applies to PR titles — release notes are grouped by the title's type prefix (`feat` → Feature, `fix` → Fix, non-user-facing types omitted, everything else → Enhancement).
## File Structure
```
bin/install.js — Installer (multi-runtime)
gsd-core/
msd-core/
bin/lib/ — Core library modules (.cjs)
workflows/ — Workflow definitions (.md)
Large workflows split per progressive-disclosure
@@ -1397,14 +1397,14 @@ gsd-core/
requires an Emitted-Drift-Ack-Growth commit trailer
(ADR-3942), no committed snapshot to regenerate. Loose tier
hard caps remain in tests/workflow-size-budget.test.cjs.
The same applies to agent files (agents/gsd-*.md,
The same applies to agent files (agents/msd-*.md,
tests/agent-size-budget.test.cjs). Full how-to +
reference in docs/TESTING-SUITES.md (Workflow &
agent size budget); see issue #1074.
references/ — Reference documentation (.md)
templates/ — File templates
agents/ — Agent definitions (.md) — CANONICAL SOURCE
commands/gsd/ — Slash command definitions (.md)
commands/msd/ — Slash command definitions (.md)
tests/ — Test files (.test.cjs)
helpers.cjs — Shared test utilities
docs/ — User-facing documentation
@@ -1412,13 +1412,13 @@ docs/ — User-facing documentation
### Source of truth for agents
Only `agents/` at the repo root is tracked by git. The following directories may exist on a developer machine with GSD installed and **must not be edited** — they are install-sync outputs and will be overwritten:
Only `agents/` at the repo root is tracked by git. The following directories may exist on a developer machine with MSD installed and **must not be edited** — they are install-sync outputs and will be overwritten:
| Path | Gitignored | What it is |
|------|-----------|------------|
| `.claude/agents/` | Yes (`.gitignore:9`) | Local Claude Code runtime sync |
| `.cursor/agents/` | Yes (`.gitignore:12`) | Local Cursor IDE bundle |
| `.github/agents/gsd-*` | Yes (`.gitignore:37`) | Local CI-surface bundle |
| `.github/agents/msd-*` | Yes (`.gitignore:37`) | Local CI-surface bundle |
If you find that `.claude/agents/` has drifted from `agents/` (e.g., after a branch change), re-run `bin/install.js` to re-sync from the canonical source. Always edit `agents/` — never the derivative directories.

View File

@@ -1,4 +1,4 @@
# GSD Core — Antigravity CLI context
# MSD Core — Antigravity CLI context
> **Gemini CLI was sunset by Google on 2026-06-18** and is no longer served for
> free/Pro/Ultra tiers. Antigravity CLI is its official successor, and this file
@@ -6,12 +6,12 @@
> `GEMINI.md`, inherited from the shared Gemini 3 backend).
This context gives Antigravity the operating context for
[GSD Core](https://github.com/open-gsd/gsd-core), a meta-prompting,
[MSD Core](https://github.com/golem15com/msd-core), a meta-prompting,
context-engineering, and spec-driven development system for AI coding agents.
## What GSD is
## What MSD is
GSD turns a vague goal into shipped software through an explicit,
MSD turns a vague goal into shipped software through an explicit,
resumable workflow: **explore → plan → execute → verify → ship**. Work is
organised into milestones and phases under a `.planning/` directory, with each
phase carrying a SPEC, a PLAN, and verification criteria. The system favours
@@ -21,35 +21,35 @@ files rather than in the conversation.
## The slash commands (installed separately)
> **This file ships only the context above — not the slash commands.** To
> install the `/gsd-*` command set, agents, and hooks into `~/.gemini/antigravity/`,
> install the `/msd-*` command set, agents, and hooks into `~/.gemini/antigravity/`,
> run the dedicated installer:
>
> ```bash
> npx gsd-core --antigravity --global
> npx msd-core --antigravity --global
> ```
>
> The commands below are available only once that installer has run.
If you have installed the gsd commands, the workflow is driven by these `/gsd-*`
slash commands (Antigravity registers gsd's commands under a hyphenated
If you have installed the msd commands, the workflow is driven by these `/msd-*`
slash commands (Antigravity registers msd's commands under a hyphenated
namespace):
- `/gsd-new-project` — initialise a project and gather deep context.
- `/gsd-progress` — the unified situational command: check progress, advance the
- `/msd-new-project` — initialise a project and gather deep context.
- `/msd-progress` — the unified situational command: check progress, advance the
workflow, or dispatch a freeform intent.
- `/gsd-plan-phase <N>` — produce a detailed phase plan with a verification loop.
- `/gsd-execute-phase <N>` — execute a phase's plans with wave-based parallelism.
- `/gsd-verify-work` — validate built features through conversational UAT.
- `/gsd-ship` — open a PR, run review, and prepare for merge.
- `/gsd-help` — list every available command.
- `/msd-plan-phase <N>` — produce a detailed phase plan with a verification loop.
- `/msd-execute-phase <N>` — execute a phase's plans with wave-based parallelism.
- `/msd-verify-work` — validate built features through conversational UAT.
- `/msd-ship` — open a PR, run review, and prepare for merge.
- `/msd-help` — list every available command.
## Working with GSD
## Working with MSD
- Treat `.planning/` as the source of truth for project state — read it before
acting, and keep it current as work progresses.
- Prefer the smallest change that satisfies the phase's verification criteria.
- Run the project's tests and linters before declaring a phase done.
- When unsure what to do next, and the gsd commands are installed, `/gsd-progress`
- When unsure what to do next, and the msd commands are installed, `/msd-progress`
is the situational entry point.
Learn more: <https://github.com/open-gsd/gsd-core>
Learn more: <https://github.com/golem15com/msd-core>

View File

@@ -1,6 +1,7 @@
MIT License
Copyright (c) 2026 Open GSD
Copyright (c) 2026 golem15 (MSD Core, a fork of GSD Core)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -1,27 +1,27 @@
<div align="center">
# GSD Core
# MSD Core
**Git. Ship. Done.**
**Make Software Done.**
[English](README.md) · [Português](README.pt-BR.md) · [简体中文](README.zh-CN.md) · **日本語** · [한국어](README.ko-KR.md)
**Claude Code、OpenCode、Antigravity CLI、Kimi CLI、Kilo、Codex、Copilot、Cursor、Windsurf などに対応した、軽量なメタプロンプティング・コンテキストエンジニアリング・仕様駆動開発システムです。**
[![npm version](https://img.shields.io/npm/v/%40opengsd%2Fgsd-core?style=for-the-badge&logo=npm&logoColor=white&color=CB3837)](https://www.npmjs.com/package/@opengsd/gsd-core)
[![npm downloads](https://img.shields.io/npm/dm/%40opengsd%2Fgsd-core?style=for-the-badge&logo=npm&logoColor=white&color=CB3837)](https://www.npmjs.com/package/@opengsd/gsd-core)
[![Tests](https://img.shields.io/github/actions/workflow/status/open-gsd/gsd-core/test.yml?branch=main&style=for-the-badge&logo=github&label=Tests)](https://github.com/open-gsd/gsd-core/actions/workflows/test.yml)
[![npm version](https://img.shields.io/npm/v/%40golem15%2Fmsd-core?style=for-the-badge&logo=npm&logoColor=white&color=CB3837)](https://www.npmjs.com/package/@golem15/msd-core)
[![npm downloads](https://img.shields.io/npm/dm/%40golem15%2Fmsd-core?style=for-the-badge&logo=npm&logoColor=white&color=CB3837)](https://www.npmjs.com/package/@golem15/msd-core)
[![Tests](https://img.shields.io/github/actions/workflow/status/golem15com/msd-core/test.yml?branch=main&style=for-the-badge&logo=github&label=Tests)](https://github.com/open-gsd/gsd-core/actions/workflows/test.yml)
[![Discord](https://img.shields.io/badge/Discord-Join-5865F2?style=for-the-badge&logo=discord&logoColor=white)](https://discord.gg/mYgfVNfA2r)
[![GitHub stars](https://img.shields.io/github/stars/open-gsd/gsd-core?style=for-the-badge&logo=github&color=181717)](https://github.com/open-gsd/gsd-core)
[![GitHub stars](https://img.shields.io/github/stars/golem15com/msd-core?style=for-the-badge&logo=github&color=181717)](https://github.com/golem15com/msd-core)
[![License](https://img.shields.io/badge/license-MIT-blue?style=for-the-badge)](LICENSE)
</div>
---
## GSD Core とは
## MSD Core とは
GSD Core は、コンテキストエンジニアリングと仕様駆動開発のフレームワークです。AI コーディングエージェント(Claude Code、Codex、Antigravity CLI、Kimi CLI、Copilot、Cursor など)を規律あるフェーズループで動かします。[コンテキストの腐敗](docs/ja-JP/explanation/context-engineering.md)—AI がコンテキストウィンドウを埋めるにつれて出力品質が低下する問題—を解決するために、重いリサーチ・計画・実行作業をすべて新鮮なコンテキストのサブエージェントで実行し、メインセッションをスリムに保ちます。
MSD Core は、コンテキストエンジニアリングと仕様駆動開発のフレームワークです。AI コーディングエージェント(Claude Code、Codex、Antigravity CLI、Kimi CLI、Copilot、Cursor など)を規律あるフェーズループで動かします。[コンテキストの腐敗](docs/ja-JP/explanation/context-engineering.md)—AI がコンテキストウィンドウを埋めるにつれて出力品質が低下する問題—を解決するために、重いリサーチ・計画・実行作業をすべて新鮮なコンテキストのサブエージェントで実行し、メインセッションをスリムに保ちます。
---
@@ -40,7 +40,7 @@ GSD Core は、コンテキストエンジニアリングと仕様駆動開発
## クイックスタート
```bash
npx @opengsd/gsd-core@latest
npx @golem15/msd-core@latest
```
インストーラーはランタイム(Claude Code、OpenCode、Antigravity CLI、Kimi CLI、Kilo、Codex、Copilot、Cursor、Windsurf など)とグローバルインストールかローカルインストールかを尋ねます。クロスランタイム互換性のためにインストーラーが必要です。`agents/` や `commands/` からファイルを直接コピーしないでください。
@@ -50,8 +50,8 @@ npx @opengsd/gsd-core@latest
インストール後、新規プロジェクトを開始するか、既存リポジトリをオンボーディングします。
```bash
/gsd-new-project # グリーンフィールドプロジェクト
/gsd-onboard # 既存コードベース
/msd-new-project # グリーンフィールドプロジェクト
/msd-onboard # 既存コードベース
```
初めての方は [はじめてのプロジェクト](docs/ja-JP/tutorials/your-first-project.md) で、インストールから最初のフェーズ出荷までのガイド付きチュートリアルをご覧ください。既存リポジトリの場合は [既存コードベースのオンボーディング](docs/ja-JP/tutorials/onboarding-an-existing-codebase.md) を参照してください。
@@ -86,7 +86,7 @@ npx @opengsd/gsd-core@latest
## なぜ機能するのか
多くの AI コーディング環境は、コンテキストの膨張が出力品質を静かに低下させ、セッション間に共有メモリがなく、コードが実際に動作するかを検証するものがないため、大規模では失敗します。GSD Core はこの 3 つすべてを解決します。重い作業は新鮮なサブエージェントで実行され、`STATE.md` や `CONTEXT.md` などの構造化アーティファクトがセッション境界を越えて保存され、検証ステップが構築されたものを確認してフェーズを完了と宣言する前に修正計画を生成します。詳細な理由については [docs/ja-JP/explanation/context-engineering.md](docs/ja-JP/explanation/context-engineering.md) を参照してください。
多くの AI コーディング環境は、コンテキストの膨張が出力品質を静かに低下させ、セッション間に共有メモリがなく、コードが実際に動作するかを検証するものがないため、大規模では失敗します。MSD Core はこの 3 つすべてを解決します。重い作業は新鮮なサブエージェントで実行され、`STATE.md` や `CONTEXT.md` などの構造化アーティファクトがセッション境界を越えて保存され、検証ステップが構築されたものを確認してフェーズを完了と宣言する前に修正計画を生成します。詳細な理由については [docs/ja-JP/explanation/context-engineering.md](docs/ja-JP/explanation/context-engineering.md) を参照してください。
トラブルシューティングは [docs/ja-JP/how-to/recover-and-troubleshoot.md](docs/ja-JP/how-to/recover-and-troubleshoot.md) を参照してください。
@@ -103,11 +103,11 @@ npx @opengsd/gsd-core@latest
## スター履歴
<a href="https://star-history.com/#open-gsd/gsd-core&Date">
<a href="https://star-history.com/#golem15com/msd-core&Date">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=open-gsd/gsd-core&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=open-gsd/gsd-core&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=open-gsd/gsd-core&type=Date" />
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=golem15com/msd-core&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=golem15com/msd-core&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=golem15com/msd-core&type=Date" />
</picture>
</a>
@@ -121,6 +121,6 @@ MIT ライセンス。詳細は [LICENSE](LICENSE) を参照してください
<div align="center">
**Claude Code は強力です。GSD Core はそれを信頼できるものにします。**
**Claude Code は強力です。MSD Core はそれを信頼できるものにします。**
</div>

View File

@@ -1,27 +1,27 @@
<div align="center">
# GSD Core
# MSD Core
**Git. Ship. Done.**
**Make Software Done.**
[English](README.md) · [Português](README.pt-BR.md) · [简体中文](README.zh-CN.md) · [日本語](README.ja-JP.md) · **한국어**
**Claude Code, OpenCode, Antigravity CLI, Kimi CLI, Kilo, Codex, Copilot, Cursor, Windsurf 등을 위한 경량 메타 프롬프팅, 컨텍스트 엔지니어링, 스펙 기반 개발 시스템.**
[![npm version](https://img.shields.io/npm/v/%40opengsd%2Fgsd-core?style=for-the-badge&logo=npm&logoColor=white&color=CB3837)](https://www.npmjs.com/package/@opengsd/gsd-core)
[![npm downloads](https://img.shields.io/npm/dm/%40opengsd%2Fgsd-core?style=for-the-badge&logo=npm&logoColor=white&color=CB3837)](https://www.npmjs.com/package/@opengsd/gsd-core)
[![Tests](https://img.shields.io/github/actions/workflow/status/open-gsd/gsd-core/test.yml?branch=main&style=for-the-badge&logo=github&label=Tests)](https://github.com/open-gsd/gsd-core/actions/workflows/test.yml)
[![npm version](https://img.shields.io/npm/v/%40golem15%2Fmsd-core?style=for-the-badge&logo=npm&logoColor=white&color=CB3837)](https://www.npmjs.com/package/@golem15/msd-core)
[![npm downloads](https://img.shields.io/npm/dm/%40golem15%2Fmsd-core?style=for-the-badge&logo=npm&logoColor=white&color=CB3837)](https://www.npmjs.com/package/@golem15/msd-core)
[![Tests](https://img.shields.io/github/actions/workflow/status/golem15com/msd-core/test.yml?branch=main&style=for-the-badge&logo=github&label=Tests)](https://github.com/open-gsd/gsd-core/actions/workflows/test.yml)
[![Discord](https://img.shields.io/badge/Discord-Join-5865F2?style=for-the-badge&logo=discord&logoColor=white)](https://discord.gg/mYgfVNfA2r)
[![GitHub stars](https://img.shields.io/github/stars/open-gsd/gsd-core?style=for-the-badge&logo=github&color=181717)](https://github.com/open-gsd/gsd-core)
[![GitHub stars](https://img.shields.io/github/stars/golem15com/msd-core?style=for-the-badge&logo=github&color=181717)](https://github.com/golem15com/msd-core)
[![License](https://img.shields.io/badge/license-MIT-blue?style=for-the-badge)](LICENSE)
</div>
---
## GSD Core란
## MSD Core란
GSD Core는 컨텍스트 엔지니어링 및 스펙 기반 개발 프레임워크로, AI 코딩 에이전트(Claude Code, Codex, Antigravity CLI, Kimi CLI, Copilot, Cursor 등)를 엄격한 단계 루프로 운용합니다. AI가 컨텍스트 창을 채워 나가면서 발생하는 품질 저하인 [컨텍스트 rot](docs/ko-KR/explanation/context-engineering.md) 문제를 해결합니다. 무거운 리서치, 기획, 실행 작업은 새로운 컨텍스트의 서브에이전트에서 처리하고, 메인 세션은 가볍게 유지됩니다.
MSD Core는 컨텍스트 엔지니어링 및 스펙 기반 개발 프레임워크로, AI 코딩 에이전트(Claude Code, Codex, Antigravity CLI, Kimi CLI, Copilot, Cursor 등)를 엄격한 단계 루프로 운용합니다. AI가 컨텍스트 창을 채워 나가면서 발생하는 품질 저하인 [컨텍스트 rot](docs/ko-KR/explanation/context-engineering.md) 문제를 해결합니다. 무거운 리서치, 기획, 실행 작업은 새로운 컨텍스트의 서브에이전트에서 처리하고, 메인 세션은 가볍게 유지됩니다.
---
@@ -40,7 +40,7 @@ GSD Core는 컨텍스트 엔지니어링 및 스펙 기반 개발 프레임워
## 빠른 시작
```bash
npx @opengsd/gsd-core@latest
npx @golem15/msd-core@latest
```
설치 프로그램이 런타임(Claude Code, OpenCode, Antigravity CLI, Kimi CLI, Kilo, Codex, Copilot, Cursor, Windsurf 등)과 전역/로컬 설치 여부를 묻습니다. 크로스 런타임 호환성을 위해 설치 프로그램을 사용해야 합니다 — `agents/` 또는 `commands/`에서 파일을 직접 복사하지 마세요.
@@ -50,8 +50,8 @@ npx @opengsd/gsd-core@latest
설치 후 새 프로젝트를 시작하거나 기존 저장소를 온보딩합니다:
```bash
/gsd-new-project # 그린필드 프로젝트
/gsd-onboard # 기존 코드베이스
/msd-new-project # 그린필드 프로젝트
/msd-onboard # 기존 코드베이스
```
처음 사용하시나요? [첫 번째 프로젝트](docs/ko-KR/tutorials/your-first-project.md)를 따라 설치부터 첫 단계 출시까지 안내받으세요. 기존 저장소라면 [기존 코드베이스 온보딩](docs/ko-KR/tutorials/onboarding-an-existing-codebase.md)을 참고하세요.
@@ -86,7 +86,7 @@ npx @opengsd/gsd-core@latest
## 왜 효과적인가
대부분의 AI 코딩 환경은 규모가 커지면 실패합니다. 컨텍스트 비대화로 출력 품질이 조용히 저하되고, 세션 간 공유 메모리가 없으며, 코드가 실제로 동작하는지 검증하는 것이 없기 때문입니다. GSD Core는 이 세 가지를 모두 해결합니다. 무거운 작업은 새 서브에이전트에서 실행되고, `STATE.md`와 `CONTEXT.md` 같은 구조화된 아티팩트가 세션 경계를 넘어 유지되며, 검증 단계가 구현 결과를 검토하고 단계 완료 선언 전 수정 계획을 생성합니다. 자세한 내용은 [docs/ko-KR/explanation/context-engineering.md](docs/ko-KR/explanation/context-engineering.md)를 참조하세요.
대부분의 AI 코딩 환경은 규모가 커지면 실패합니다. 컨텍스트 비대화로 출력 품질이 조용히 저하되고, 세션 간 공유 메모리가 없으며, 코드가 실제로 동작하는지 검증하는 것이 없기 때문입니다. MSD Core는 이 세 가지를 모두 해결합니다. 무거운 작업은 새 서브에이전트에서 실행되고, `STATE.md`와 `CONTEXT.md` 같은 구조화된 아티팩트가 세션 경계를 넘어 유지되며, 검증 단계가 구현 결과를 검토하고 단계 완료 선언 전 수정 계획을 생성합니다. 자세한 내용은 [docs/ko-KR/explanation/context-engineering.md](docs/ko-KR/explanation/context-engineering.md)를 참조하세요.
문제가 발생했나요? [docs/ko-KR/how-to/recover-and-troubleshoot.md](docs/ko-KR/how-to/recover-and-troubleshoot.md)를 확인하세요.
@@ -103,11 +103,11 @@ npx @opengsd/gsd-core@latest
## 스타 히스토리
<a href="https://star-history.com/#open-gsd/gsd-core&Date">
<a href="https://star-history.com/#golem15com/msd-core&Date">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=open-gsd/gsd-core&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=open-gsd/gsd-core&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=open-gsd/gsd-core&type=Date" />
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=golem15com/msd-core&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=golem15com/msd-core&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=golem15com/msd-core&type=Date" />
</picture>
</a>
@@ -121,6 +121,6 @@ MIT 라이선스. 자세한 내용은 [LICENSE](LICENSE)를 참조하세요.
<div align="center">
**Claude Code는 강력합니다. GSD Core가 그걸 신뢰할 수 있게 만듭니다.**
**Claude Code는 강력합니다. MSD Core가 그걸 신뢰할 수 있게 만듭니다.**
</div>

View File

@@ -1,27 +1,27 @@
<div align="center">
# GSD Core
# MSD Core
**Git. Ship. Done.**
**Make Software Done.**
**English** · [Português](README.pt-BR.md) · [简体中文](README.zh-CN.md) · [日本語](README.ja-JP.md) · [한국어](README.ko-KR.md)
**A light-weight meta-prompting, context engineering, and spec-driven development system for Claude Code, OpenCode, Antigravity CLI, Kimi CLI, Kilo, Codex, Copilot, Cursor, Windsurf, and more.**
[![npm version](https://img.shields.io/npm/v/%40opengsd%2Fgsd-core?style=for-the-badge&logo=npm&logoColor=white&color=CB3837)](https://www.npmjs.com/package/@opengsd/gsd-core)
[![npm downloads](https://img.shields.io/npm/dm/%40opengsd%2Fgsd-core?style=for-the-badge&logo=npm&logoColor=white&color=CB3837)](https://www.npmjs.com/package/@opengsd/gsd-core)
[![Tests](https://img.shields.io/github/actions/workflow/status/open-gsd/gsd-core/test.yml?branch=main&style=for-the-badge&logo=github&label=Tests)](https://github.com/open-gsd/gsd-core/actions/workflows/test.yml)
[![npm version](https://img.shields.io/npm/v/%40golem15%2Fmsd-core?style=for-the-badge&logo=npm&logoColor=white&color=CB3837)](https://www.npmjs.com/package/@golem15/msd-core)
[![npm downloads](https://img.shields.io/npm/dm/%40golem15%2Fmsd-core?style=for-the-badge&logo=npm&logoColor=white&color=CB3837)](https://www.npmjs.com/package/@golem15/msd-core)
[![Tests](https://img.shields.io/github/actions/workflow/status/golem15com/msd-core/test.yml?branch=main&style=for-the-badge&logo=github&label=Tests)](https://github.com/open-gsd/gsd-core/actions/workflows/test.yml)
[![Discord](https://img.shields.io/badge/Discord-Join-5865F2?style=for-the-badge&logo=discord&logoColor=white)](https://discord.gg/mYgfVNfA2r)
[![GitHub stars](https://img.shields.io/github/stars/open-gsd/gsd-core?style=for-the-badge&logo=github&color=181717)](https://github.com/open-gsd/gsd-core)
[![GitHub stars](https://img.shields.io/github/stars/golem15com/msd-core?style=for-the-badge&logo=github&color=181717)](https://github.com/golem15com/msd-core)
[![License](https://img.shields.io/badge/license-MIT-blue?style=for-the-badge)](LICENSE)
</div>
---
## What is GSD Core
## What is MSD Core
GSD Core is a context-engineering and spec-driven development framework that drives AI coding agents (Claude Code, Codex, Antigravity CLI, Kimi CLI, Copilot, Cursor, and more) through a disciplined phase loop. It solves [context rot](docs/explanation/context-engineering.md) — the quality degradation that accumulates as an AI fills its context window — by running all heavy research, planning, and execution work in fresh-context subagents while keeping your main session lean.
MSD Core is a context-engineering and spec-driven development framework that drives AI coding agents (Claude Code, Codex, Antigravity CLI, Kimi CLI, Copilot, Cursor, and more) through a disciplined phase loop. It solves [context rot](docs/explanation/context-engineering.md) — the quality degradation that accumulates as an AI fills its context window — by running all heavy research, planning, and execution work in fresh-context subagents while keeping your main session lean.
---
@@ -40,7 +40,7 @@ Each milestone repeats the same five-step loop, one phase at a time:
## Quickstart
```bash
npx @opengsd/gsd-core@latest
npx @golem15/msd-core@latest
```
The installer prompts for your runtime (Claude Code, OpenCode, Antigravity CLI, Kimi CLI, Kilo, Codex, Copilot, Cursor, Windsurf, and more) and whether to install globally or locally. The installer is required for cross-runtime compatibility — do not copy files from `agents/` or `commands/` directly.
@@ -50,8 +50,8 @@ On another runtime or without Node.js? See [Install on your runtime](docs/how-to
Once installed, 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
```
New here? Follow [Your first project](docs/tutorials/your-first-project.md) for a guided walkthrough from install to first shipped phase, or [Onboarding an existing codebase](docs/tutorials/onboarding-an-existing-codebase.md) for brownfield setup.
@@ -88,7 +88,7 @@ Full index: [docs/README.md](docs/README.md). Other languages: [日本語](READM
## Why it works
Most AI-coding setups fail at scale because context bloat silently degrades output quality, there is no shared memory between sessions, and nothing verifies that code actually works. GSD Core solves all three: heavy work runs in fresh subagents, structured artifacts like `STATE.md` and `CONTEXT.md` survive session boundaries, and the verify step walks through what was built and generates fix plans before a phase is declared done. See [docs/explanation/context-engineering.md](docs/explanation/context-engineering.md) for the full reasoning.
Most AI-coding setups fail at scale because context bloat silently degrades output quality, there is no shared memory between sessions, and nothing verifies that code actually works. MSD Core solves all three: heavy work runs in fresh subagents, structured artifacts like `STATE.md` and `CONTEXT.md` survive session boundaries, and the verify step walks through what was built and generates fix plans before a phase is declared done. See [docs/explanation/context-engineering.md](docs/explanation/context-engineering.md) for the full reasoning.
Troubleshooting? See [docs/how-to/recover-and-troubleshoot.md](docs/how-to/recover-and-troubleshoot.md).
@@ -105,11 +105,11 @@ Troubleshooting? See [docs/how-to/recover-and-troubleshoot.md](docs/how-to/recov
## Star History
<a href="https://star-history.com/#open-gsd/gsd-core&Date">
<a href="https://star-history.com/#golem15com/msd-core&Date">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=open-gsd/gsd-core&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=open-gsd/gsd-core&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=open-gsd/gsd-core&type=Date" />
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=golem15com/msd-core&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=golem15com/msd-core&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=golem15com/msd-core&type=Date" />
</picture>
</a>
@@ -133,6 +133,6 @@ MIT License. See [LICENSE](LICENSE) for details.
<div align="center">
**Claude Code is powerful. GSD Core makes it reliable.**
**Claude Code is powerful. MSD Core makes it reliable.**
</div>

View File

@@ -1,27 +1,27 @@
<div align="center">
# GSD Core
# MSD Core
**Git. Ship. Done.**
**Make Software Done.**
[English](README.md) · **Português** · [简体中文](README.zh-CN.md) · [日本語](README.ja-JP.md) · [한국어](README.ko-KR.md)
**Um sistema leve de meta-prompting, engenharia de contexto e desenvolvimento orientado a especificações para Claude Code, OpenCode, Antigravity CLI, Kimi CLI, Kilo, Codex, Copilot, Cursor, Windsurf e muito mais.**
[![npm version](https://img.shields.io/npm/v/%40opengsd%2Fgsd-core?style=for-the-badge&logo=npm&logoColor=white&color=CB3837)](https://www.npmjs.com/package/@opengsd/gsd-core)
[![npm downloads](https://img.shields.io/npm/dm/%40opengsd%2Fgsd-core?style=for-the-badge&logo=npm&logoColor=white&color=CB3837)](https://www.npmjs.com/package/@opengsd/gsd-core)
[![Tests](https://img.shields.io/github/actions/workflow/status/open-gsd/gsd-core/test.yml?branch=main&style=for-the-badge&logo=github&label=Tests)](https://github.com/open-gsd/gsd-core/actions/workflows/test.yml)
[![npm version](https://img.shields.io/npm/v/%40golem15%2Fmsd-core?style=for-the-badge&logo=npm&logoColor=white&color=CB3837)](https://www.npmjs.com/package/@golem15/msd-core)
[![npm downloads](https://img.shields.io/npm/dm/%40golem15%2Fmsd-core?style=for-the-badge&logo=npm&logoColor=white&color=CB3837)](https://www.npmjs.com/package/@golem15/msd-core)
[![Tests](https://img.shields.io/github/actions/workflow/status/golem15com/msd-core/test.yml?branch=main&style=for-the-badge&logo=github&label=Tests)](https://github.com/open-gsd/gsd-core/actions/workflows/test.yml)
[![Discord](https://img.shields.io/badge/Discord-Join-5865F2?style=for-the-badge&logo=discord&logoColor=white)](https://discord.gg/mYgfVNfA2r)
[![GitHub stars](https://img.shields.io/github/stars/open-gsd/gsd-core?style=for-the-badge&logo=github&color=181717)](https://github.com/open-gsd/gsd-core)
[![GitHub stars](https://img.shields.io/github/stars/golem15com/msd-core?style=for-the-badge&logo=github&color=181717)](https://github.com/golem15com/msd-core)
[![License](https://img.shields.io/badge/license-MIT-blue?style=for-the-badge)](LICENSE)
</div>
---
## O que é o GSD Core
## O que é o MSD Core
GSD Core é um framework de engenharia de contexto e desenvolvimento orientado a especificações que conduz agentes de codificação com IA (Claude Code, Codex, Antigravity CLI, Kimi CLI, Copilot, Cursor e mais) por meio de um ciclo de fases disciplinado. Ele resolve o [context rot](docs/pt-BR/explanation/context-engineering.md) — a degradação de qualidade que se acumula à medida que uma IA preenche sua janela de contexto — executando todo o trabalho pesado de pesquisa, planejamento e execução em subagentes com contexto limpo, mantendo sua sessão principal enxuta.
MSD Core é um framework de engenharia de contexto e desenvolvimento orientado a especificações que conduz agentes de codificação com IA (Claude Code, Codex, Antigravity CLI, Kimi CLI, Copilot, Cursor e mais) por meio de um ciclo de fases disciplinado. Ele resolve o [context rot](docs/pt-BR/explanation/context-engineering.md) — a degradação de qualidade que se acumula à medida que uma IA preenche sua janela de contexto — executando todo o trabalho pesado de pesquisa, planejamento e execução em subagentes com contexto limpo, mantendo sua sessão principal enxuta.
---
@@ -40,7 +40,7 @@ Cada marco repete o mesmo ciclo de cinco etapas, uma fase por vez:
## Início rápido
```bash
npx @opengsd/gsd-core@latest
npx @golem15/msd-core@latest
```
O instalador solicita seu ambiente de execução (Claude Code, OpenCode, Antigravity CLI, Kimi CLI, Kilo, Codex, Copilot, Cursor, Windsurf e mais) e se deseja instalar globalmente ou localmente. O instalador é necessário para compatibilidade entre runtimes — não copie arquivos diretamente de `agents/` ou `commands/`.
@@ -50,8 +50,8 @@ Em outro runtime ou sem Node.js? Consulte [Instalar no seu runtime](docs/pt-BR/h
Após a instalação, inicie um projeto novo ou integre um repositório existente:
```bash
/gsd-new-project # projeto greenfield
/gsd-onboard # base de código existente
/msd-new-project # projeto greenfield
/msd-onboard # base de código existente
```
É a primeira vez? Siga [Seu primeiro projeto](docs/pt-BR/tutorials/your-first-project.md) para um passo a passo guiado, desde a instalação até a primeira fase entregue. Para um repositório existente, consulte [Integrar uma base de código existente](docs/pt-BR/tutorials/onboarding-an-existing-codebase.md).
@@ -86,7 +86,7 @@ Após a instalação, inicie um projeto novo ou integre um repositório existent
## Por que funciona
A maioria das configurações de codificação com IA falha em escala porque o inchaço de contexto degrada silenciosamente a qualidade da saída, não há memória compartilhada entre sessões e nada verifica se o código realmente funciona. O GSD Core resolve os três problemas: o trabalho pesado é executado em subagentes com contexto limpo, artefatos estruturados como `STATE.md` e `CONTEXT.md` sobrevivem às fronteiras de sessão, e a etapa de verificação percorre o que foi construído e gera planos de correção antes de uma fase ser declarada concluída. Consulte [docs/pt-BR/explanation/context-engineering.md](docs/pt-BR/explanation/context-engineering.md) para o raciocínio completo.
A maioria das configurações de codificação com IA falha em escala porque o inchaço de contexto degrada silenciosamente a qualidade da saída, não há memória compartilhada entre sessões e nada verifica se o código realmente funciona. O MSD Core resolve os três problemas: o trabalho pesado é executado em subagentes com contexto limpo, artefatos estruturados como `STATE.md` e `CONTEXT.md` sobrevivem às fronteiras de sessão, e a etapa de verificação percorre o que foi construído e gera planos de correção antes de uma fase ser declarada concluída. Consulte [docs/pt-BR/explanation/context-engineering.md](docs/pt-BR/explanation/context-engineering.md) para o raciocínio completo.
Problemas? Consulte [docs/pt-BR/how-to/recover-and-troubleshoot.md](docs/pt-BR/how-to/recover-and-troubleshoot.md).
@@ -103,11 +103,11 @@ Problemas? Consulte [docs/pt-BR/how-to/recover-and-troubleshoot.md](docs/pt-BR/h
## Histórico de estrelas
<a href="https://star-history.com/#open-gsd/gsd-core&Date">
<a href="https://star-history.com/#golem15com/msd-core&Date">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=open-gsd/gsd-core&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=open-gsd/gsd-core&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=open-gsd/gsd-core&type=Date" />
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=golem15com/msd-core&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=golem15com/msd-core&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=golem15com/msd-core&type=Date" />
</picture>
</a>
@@ -121,6 +121,6 @@ Licença MIT. Consulte [LICENSE](LICENSE) para detalhes.
<div align="center">
**Claude Code é poderoso. GSD Core o torna confiável.**
**Claude Code é poderoso. MSD Core o torna confiável.**
</div>

View File

@@ -1,27 +1,27 @@
<div align="center">
# GSD Core
# MSD Core
**Git. Ship. Done.**
**Make Software Done.**
[English](README.md) · [Português](README.pt-BR.md) · **简体中文** · [日本語](README.ja-JP.md) · [한국어](README.ko-KR.md)
**一套轻量级的元提示、上下文工程与规范驱动开发系统,适用于 Claude Code、OpenCode、Antigravity CLI、Kimi CLI、Kilo、Codex、Copilot、Cursor、Windsurf 等 AI 编程工具。**
[![npm version](https://img.shields.io/npm/v/%40opengsd%2Fgsd-core?style=for-the-badge&logo=npm&logoColor=white&color=CB3837)](https://www.npmjs.com/package/@opengsd/gsd-core)
[![npm downloads](https://img.shields.io/npm/dm/%40opengsd%2Fgsd-core?style=for-the-badge&logo=npm&logoColor=white&color=CB3837)](https://www.npmjs.com/package/@opengsd/gsd-core)
[![Tests](https://img.shields.io/github/actions/workflow/status/open-gsd/gsd-core/test.yml?branch=main&style=for-the-badge&logo=github&label=Tests)](https://github.com/open-gsd/gsd-core/actions/workflows/test.yml)
[![npm version](https://img.shields.io/npm/v/%40golem15%2Fmsd-core?style=for-the-badge&logo=npm&logoColor=white&color=CB3837)](https://www.npmjs.com/package/@golem15/msd-core)
[![npm downloads](https://img.shields.io/npm/dm/%40golem15%2Fmsd-core?style=for-the-badge&logo=npm&logoColor=white&color=CB3837)](https://www.npmjs.com/package/@golem15/msd-core)
[![Tests](https://img.shields.io/github/actions/workflow/status/golem15com/msd-core/test.yml?branch=main&style=for-the-badge&logo=github&label=Tests)](https://github.com/open-gsd/gsd-core/actions/workflows/test.yml)
[![Discord](https://img.shields.io/badge/Discord-Join-5865F2?style=for-the-badge&logo=discord&logoColor=white)](https://discord.gg/mYgfVNfA2r)
[![GitHub stars](https://img.shields.io/github/stars/open-gsd/gsd-core?style=for-the-badge&logo=github&color=181717)](https://github.com/open-gsd/gsd-core)
[![GitHub stars](https://img.shields.io/github/stars/golem15com/msd-core?style=for-the-badge&logo=github&color=181717)](https://github.com/golem15com/msd-core)
[![License](https://img.shields.io/badge/license-MIT-blue?style=for-the-badge)](LICENSE)
</div>
---
## 什么是 GSD Core
## 什么是 MSD Core
GSD Core 是一套上下文工程与规范驱动开发框架,能够引导 AI 编程智能体(Claude Code、Codex、Antigravity CLI、Kimi CLI、Copilot、Cursor 等)按照严格的阶段循环推进工作。它解决了[上下文腐化](docs/zh-CN/explanation/context-engineering.md)问题——即随着 AI 填满上下文窗口而逐渐累积的质量下降——通过在全新上下文的子智能体中运行所有繁重的研究、规划和执行工作,同时保持主会话的精简。
MSD Core 是一套上下文工程与规范驱动开发框架,能够引导 AI 编程智能体(Claude Code、Codex、Antigravity CLI、Kimi CLI、Copilot、Cursor 等)按照严格的阶段循环推进工作。它解决了[上下文腐化](docs/zh-CN/explanation/context-engineering.md)问题——即随着 AI 填满上下文窗口而逐渐累积的质量下降——通过在全新上下文的子智能体中运行所有繁重的研究、规划和执行工作,同时保持主会话的精简。
---
@@ -40,7 +40,7 @@ GSD Core 是一套上下文工程与规范驱动开发框架,能够引导 AI
## 快速开始
```bash
npx @opengsd/gsd-core@latest
npx @golem15/msd-core@latest
```
安装程序会提示选择运行时(Claude Code、OpenCode、Antigravity CLI、Kimi CLI、Kilo、Codex、Copilot、Cursor、Windsurf 等)以及是全局安装还是本地安装。跨运行时兼容性需要使用安装程序——请勿直接从 `agents/` 或 `commands/` 目录复制文件。
@@ -50,8 +50,8 @@ npx @opengsd/gsd-core@latest
安装完成后,启动一个新项目或接入现有仓库:
```bash
/gsd-new-project # 新建项目
/gsd-onboard # 现有代码库
/msd-new-project # 新建项目
/msd-onboard # 现有代码库
```
初次使用?请按照[你的第一个项目](docs/zh-CN/tutorials/your-first-project.md)进行引导式操作,从安装到完成第一个交付阶段。对于现有仓库,请参阅[接入现有代码库](docs/zh-CN/tutorials/onboarding-an-existing-codebase.md)。
@@ -86,7 +86,7 @@ npx @opengsd/gsd-core@latest
## 为什么有效
大多数 AI 编程方案在规模化时都会失败,原因在于上下文膨胀会悄无声息地降低输出质量,各会话之间没有共享记忆,也没有任何机制来验证代码是否真正可用。GSD Core 解决了这三个问题:繁重的工作在全新的子智能体中运行,`STATE.md` 和 `CONTEXT.md` 等结构化工件能够跨越会话边界保持存续,验证步骤会检查已构建的内容并在宣告阶段完成前生成修复计划。完整的设计思路请参阅 [docs/zh-CN/explanation/context-engineering.md](docs/zh-CN/explanation/context-engineering.md)。
大多数 AI 编程方案在规模化时都会失败,原因在于上下文膨胀会悄无声息地降低输出质量,各会话之间没有共享记忆,也没有任何机制来验证代码是否真正可用。MSD Core 解决了这三个问题:繁重的工作在全新的子智能体中运行,`STATE.md` 和 `CONTEXT.md` 等结构化工件能够跨越会话边界保持存续,验证步骤会检查已构建的内容并在宣告阶段完成前生成修复计划。完整的设计思路请参阅 [docs/zh-CN/explanation/context-engineering.md](docs/zh-CN/explanation/context-engineering.md)。
遇到问题?请参阅 [docs/zh-CN/how-to/recover-and-troubleshoot.md](docs/zh-CN/how-to/recover-and-troubleshoot.md)。
@@ -103,11 +103,11 @@ npx @opengsd/gsd-core@latest
## Star History
<a href="https://star-history.com/#open-gsd/gsd-core&Date">
<a href="https://star-history.com/#golem15com/msd-core&Date">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=open-gsd/gsd-core&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=open-gsd/gsd-core&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=open-gsd/gsd-core&type=Date" />
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=golem15com/msd-core&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=golem15com/msd-core&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=golem15com/msd-core&type=Date" />
</picture>
</a>
@@ -121,6 +121,6 @@ MIT 许可证。详情请参阅 [LICENSE](LICENSE)。
<div align="center">
**Claude Code 功能强大。GSD Core 让它更可靠。**
**Claude Code 功能强大。MSD Core 让它更可靠。**
</div>

View File

@@ -25,7 +25,7 @@ Include:
## Scope
Security issues in the GSD codebase that could:
Security issues in the MSD codebase that could:
- Execute arbitrary code on user machines
- Expose sensitive data (API keys, credentials)
- Compromise the integrity of generated plans/code
@@ -74,7 +74,7 @@ If `--strict` finds findings that default mode does not, those findings represen
### Exit codes
`secret-scan.sh`, `base64-scan.sh`, and `prompt-injection-scan.sh` share one contract, registered in `gsd-core/bin/shared/exit-codes.json` (ADR-3889):
`secret-scan.sh`, `base64-scan.sh`, and `prompt-injection-scan.sh` share one contract, registered in `msd-core/bin/shared/exit-codes.json` (ADR-3889):
| Code | Meaning |
|--:|---|

View File

@@ -1,6 +1,6 @@
# Test Examples
This document shows the kinds of tests GSD expects for high-risk changes. Use it with the testing standards in [`CONTRIBUTING.md`](CONTRIBUTING.md).
This document shows the kinds of tests MSD expects for high-risk changes. Use it with the testing standards in [`CONTRIBUTING.md`](CONTRIBUTING.md).
The examples are intentionally small. Copy the pattern, not the exact assertion text.
@@ -51,13 +51,13 @@ const cases = [
];
for (const scenario of cases) {
test(`gsd-tools rejects ${scenario.name}`, (t) => {
test(`msd-tools rejects ${scenario.name}`, (t) => {
const projectDir = createTempProject('cli-negative-');
t.after(() => cleanup(projectDir));
const result = spawnSync(
process.execPath,
[path.join(__dirname, '..', 'gsd-core', 'bin', 'gsd-tools.cjs'), ...scenario.args, '--json'],
[path.join(__dirname, '..', 'msd-core', 'bin', 'msd-tools.cjs'), ...scenario.args, '--json'],
{ cwd: projectDir, encoding: 'utf8' },
);
@@ -97,7 +97,7 @@ test('worker run leaves a valid cache', (t) => {
```javascript
const { PROBE_TIMEOUT_MS } = require('./helpers/timeouts.cjs');
test('gsd-tools reports the resolved config', (t) => {
test('msd-tools reports the resolved config', (t) => {
const r = runNode([TOOLS_PATH, 'config', '--json'], { timeoutMs: PROBE_TIMEOUT_MS });
assert.equal(r.exitCode, 0);
});
@@ -106,7 +106,7 @@ test('gsd-tools reports the resolved config', (t) => {
**Compliant — a genuinely distinct class: name it, and size it relative to what it wraps:**
```javascript
const { NPM_VIEW_TIMEOUT_MS } = require('../gsd-core/bin/check-latest-version.cjs');
const { NPM_VIEW_TIMEOUT_MS } = require('../msd-core/bin/check-latest-version.cjs');
// Real headroom beyond the inner timeout the worker itself is bounded by — not a
// second independent guess. See TESTING-STANDARDS.md's "No ad hoc timeout literals".
@@ -231,7 +231,7 @@ test('installer refuses symlink escape outside target root', (t) => {
assert.equal(result.ok, false);
assert.equal(result.reason, 'symlink_escape');
assert.equal(fs.existsSync(path.join(outside, 'gsd-prompt-guard.js')), false);
assert.equal(fs.existsSync(path.join(outside, 'msd-prompt-guard.js')), false);
});
```

View File

@@ -22,7 +22,7 @@ Tests call exported functions or run the CLI and parse structured output. They d
**Compliant:**
```javascript
const { stdout } = await runGsdTools(['plan', '--json']);
const { stdout } = await runMsdTools(['plan', '--json']);
const result = JSON.parse(stdout);
assert.strictEqual(result.phases[0].id, 'plan-1.1');
```
@@ -141,7 +141,7 @@ assert(Date.now() - start < 200, 'must complete in 200ms');
### Clock-seam pattern for concurrency
Concurrency logic must be tested deterministically, via one of three reachability-selected mechanisms (see ADR-456 §(a)): an injectable clock seam for modules that accept `{clock = Date}`, `node:test` `mock.timers` for in-process direct-`Date`-reading code, or the `GSD_TEST_MODE`+`GSD_NOW_MS` subprocess pin (routed through `realClock`) for CLI-spawned code. Real OS scheduler races are non-deterministic on loaded CI runners and are not a permitted test pattern regardless of which mechanism applies.
Concurrency logic must be tested deterministically, via one of three reachability-selected mechanisms (see ADR-456 §(a)): an injectable clock seam for modules that accept `{clock = Date}`, `node:test` `mock.timers` for in-process direct-`Date`-reading code, or the `MSD_TEST_MODE`+`MSD_NOW_MS` subprocess pin (routed through `realClock`) for CLI-spawned code. Real OS scheduler races are non-deterministic on loaded CI runners and are not a permitted test pattern regardless of which mechanism applies.
**Compliant pattern:**
@@ -195,7 +195,7 @@ const r = runHookSeam(WORKER_PATH, [], { timeoutMs: GIT_TIMEOUT_MS });
**Compliant — a genuinely distinct class, declared locally with a margin over the thing it wraps** (the actual fix in PR #4428 — the worker's inner `npm view` call is bounded by its own named `NPM_VIEW_TIMEOUT_MS`, so the outer test imports it and adds explicit headroom instead of re-guessing a number):
```javascript
const { NPM_VIEW_TIMEOUT_MS } = require('../gsd-core/bin/check-latest-version.cjs');
const { NPM_VIEW_TIMEOUT_MS } = require('../msd-core/bin/check-latest-version.cjs');
const WORKER_TEARDOWN_MARGIN_MS = 10_000; // real headroom beyond the inner timeout it wraps

View File

@@ -1,14 +1,14 @@
# Versioning & Release Strategy
GSD follows [Semantic Versioning 2.0.0](https://semver.org/) with three release tiers mapped to npm dist-tags.
MSD follows [Semantic Versioning 2.0.0](https://semver.org/) with three release tiers mapped to npm dist-tags.
## Release Tiers
| Tier | What ships | Version format | npm tag | Branch | Install |
|------|-----------|---------------|---------|--------|---------|
| **Patch** | Bug fixes only | `1.27.1` | `latest` | `hotfix/1.27.1` | `npx @opengsd/gsd-core@latest` |
| **Minor** | Fixes + enhancements | `1.28.0` | `latest` (after RC) | `release/1.28.0` | `npx @opengsd/gsd-core@next` (RC) |
| **Major** | Fixes + enhancements + features | `2.0.0` | `latest` (after beta) | `release/2.0.0` | `npx @opengsd/gsd-core@next` (beta) |
| **Patch** | Bug fixes only | `1.27.1` | `latest` | `hotfix/1.27.1` | `npx @golem15/msd-core@latest` |
| **Minor** | Fixes + enhancements | `1.28.0` | `latest` (after RC) | `release/1.28.0` | `npx @golem15/msd-core@next` (RC) |
| **Major** | Fixes + enhancements + features | `2.0.0` | `latest` (after beta) | `release/2.0.0` | `npx @golem15/msd-core@next` (beta) |
## npm Dist-Tags
@@ -16,8 +16,8 @@ Only two tags, following Angular/Next.js convention:
| Tag | Meaning | Installed by |
|-----|---------|-------------|
| `latest` | Stable production release | `npm install @opengsd/gsd-core` (default) |
| `next` | Pre-release (RC or beta) | `npm install @opengsd/gsd-core@next` (opt-in) |
| `latest` | Stable production release | `npm install @golem15/msd-core` (default) |
| `next` | Pre-release (RC or beta) | `npm install @golem15/msd-core@next` (opt-in) |
The version string (`-rc.1` vs `-beta.1`) communicates stability level. Users never get pre-releases unless they explicitly opt in.
@@ -96,7 +96,7 @@ For accumulated fixes and enhancements.
1. Trigger `release.yml` with action `create` and version (e.g., `1.28.0`)
2. Workflow creates `release/1.28.0` branch from main, bumps package.json
3. Trigger `release.yml` with action `rc` to publish `1.28.0-rc.1` to `next`
4. Test the RC: `npx @opengsd/gsd-core@next`
4. Test the RC: `npx @golem15/msd-core@next`
5. If issues found: fix on release branch, publish `rc.2`, `rc.3`, etc.
6. Trigger `release.yml` with action `finalize` — publishes `1.28.0` to `latest`
7. Merge release branch to main
@@ -156,5 +156,5 @@ npm publish
npm publish --tag next
# Verify what latest and next point to
npm dist-tag ls @opengsd/gsd-core
npm dist-tag ls @golem15/msd-core
```

View File

@@ -1,24 +1,24 @@
---
name: gsd-advisor-researcher
name: msd-advisor-researcher
description: Researches a single gray area decision and returns a structured comparison table with rationale. Spawned by discuss-phase advisor mode.
tools: Read, Bash, Grep, Glob, Skill, WebSearch, WebFetch, mcp__context7__*, mcp__plugin_context7_context7__*
color: cyan
---
<role>
GSD advisor researcher. Research ONE gray area, produce ONE comparison table with rationale.
MSD advisor researcher. Research ONE gray area, produce ONE comparison table with rationale.
Spawned by `discuss-phase` via `Task()`. Do NOT present output directly to the user — return
structured output for the main agent to synthesize: a 5-column comparison table of genuinely
viable options (via Claude's knowledge + Context7 + web search) plus a rationale paragraph
grounded in project context.
</role>
@~/.claude/gsd-core/references/untrusted-input-boundary.md
@~/.claude/msd-core/references/untrusted-input-boundary.md
**agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
**agent_skills:** self-load per @~/.claude/msd-core/references/agent-skills-bootstrap.md
<documentation_lookup>
@~/.claude/gsd-core/references/research-documentation-lookup.md
@~/.claude/msd-core/references/research-documentation-lookup.md
</documentation_lookup>
<input>

View File

@@ -1,12 +1,12 @@
---
name: gsd-advisor-researcher
name: msd-advisor-researcher
description: Researches a single gray area decision and returns a structured comparison table with rationale. Spawned by discuss-phase advisor mode.
tools: Read, Bash, Grep, Glob, Skill, WebSearch, WebFetch, mcp__context7__*, mcp__plugin_context7_context7__*
color: cyan
---
<role>
You are a GSD advisor researcher. You research ONE gray area and produce ONE comparison table with rationale.
You are a MSD advisor researcher. You research ONE gray area and produce ONE comparison table with rationale.
Spawned by `discuss-phase` via `Task()`. You do NOT present output directly to the user -- you return structured output for the main agent to synthesize.
@@ -17,12 +17,12 @@ Spawned by `discuss-phase` via `Task()`. You do NOT present output directly to t
- Return structured markdown output for the main agent to synthesize
</role>
@~/.claude/gsd-core/references/untrusted-input-boundary.md
@~/.claude/msd-core/references/untrusted-input-boundary.md
**agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
**agent_skills:** self-load per @~/.claude/msd-core/references/agent-skills-bootstrap.md
<documentation_lookup>
@~/.claude/gsd-core/references/research-documentation-lookup.md
@~/.claude/msd-core/references/research-documentation-lookup.md
</documentation_lookup>
<input>

View File

@@ -1,6 +1,6 @@
---
name: gsd-ai-researcher
description: Researches a chosen AI framework's official docs to produce implementation-ready guidance — best practices, syntax, core patterns, and pitfalls distilled for the specific use case. Writes the Framework Quick Reference and Implementation Guidance sections of AI-SPEC.md. Spawned by /gsd:ai-integration-phase orchestrator.
name: msd-ai-researcher
description: Researches a chosen AI framework's official docs to produce implementation-ready guidance — best practices, syntax, core patterns, and pitfalls distilled for the specific use case. Writes the Framework Quick Reference and Implementation Guidance sections of AI-SPEC.md. Spawned by /msd:ai-integration-phase orchestrator.
tools: Read, Write, Edit, Bash, Grep, Glob, WebFetch, WebSearch, mcp__context7__*, mcp__plugin_context7_context7__*
color: green
# hooks:
@@ -12,18 +12,18 @@ color: green
---
<role>
GSD AI researcher. Answer: "How do I correctly implement this AI system with the chosen framework?"
MSD AI researcher. Answer: "How do I correctly implement this AI system with the chosen framework?"
Write Sections 3–4b of AI-SPEC.md: framework quick reference, implementation guidance, AI systems best practices.
</role>
@~/.claude/gsd-core/references/untrusted-input-boundary.md
@~/.claude/msd-core/references/untrusted-input-boundary.md
<documentation_lookup>
@~/.claude/gsd-core/references/research-documentation-lookup.md
@~/.claude/msd-core/references/research-documentation-lookup.md
</documentation_lookup>
<required_reading>
Read `~/.claude/gsd-core/references/ai-frameworks.md` for framework profiles and known pitfalls before fetching docs.
Read `~/.claude/msd-core/references/ai-frameworks.md` for framework profiles and known pitfalls before fetching docs.
</required_reading>
<input>

View File

@@ -1,6 +1,6 @@
---
name: gsd-ai-researcher
description: Researches a chosen AI framework's official docs to produce implementation-ready guidance — best practices, syntax, core patterns, and pitfalls distilled for the specific use case. Writes the Framework Quick Reference and Implementation Guidance sections of AI-SPEC.md. Spawned by /gsd:ai-integration-phase orchestrator.
name: msd-ai-researcher
description: Researches a chosen AI framework's official docs to produce implementation-ready guidance — best practices, syntax, core patterns, and pitfalls distilled for the specific use case. Writes the Framework Quick Reference and Implementation Guidance sections of AI-SPEC.md. Spawned by /msd:ai-integration-phase orchestrator.
tools: Read, Write, Edit, Bash, Grep, Glob, WebFetch, WebSearch, mcp__context7__*, mcp__plugin_context7_context7__*
color: green
# hooks:
@@ -12,18 +12,18 @@ color: green
---
<role>
You are a GSD AI researcher. Answer: "How do I correctly implement this AI system with the chosen framework?"
You are a MSD AI researcher. Answer: "How do I correctly implement this AI system with the chosen framework?"
Write Sections 3–4b of AI-SPEC.md: framework quick reference, implementation guidance, and AI systems best practices.
</role>
@~/.claude/gsd-core/references/untrusted-input-boundary.md
@~/.claude/msd-core/references/untrusted-input-boundary.md
<documentation_lookup>
@~/.claude/gsd-core/references/research-documentation-lookup.md
@~/.claude/msd-core/references/research-documentation-lookup.md
</documentation_lookup>
<required_reading>
Read `~/.claude/gsd-core/references/ai-frameworks.md` for framework profiles and known pitfalls before fetching docs.
Read `~/.claude/msd-core/references/ai-frameworks.md` for framework profiles and known pitfalls before fetching docs.
</required_reading>
<input>

View File

@@ -1,17 +1,17 @@
---
name: gsd-assumptions-analyzer
name: msd-assumptions-analyzer
description: Deeply analyzes codebase for a phase and returns structured assumptions with evidence. Spawned by discuss-phase assumptions mode.
tools: Read, Bash, Grep, Glob, Skill
color: cyan
---
<role>
GSD assumptions analyzer. Deeply analyze the codebase for ONE phase; produce structured assumptions with evidence and confidence levels. Spawned by `discuss-phase-assumptions` via `Task()`. Do NOT present output to the user — return structured output for the main workflow to present/confirm.
MSD assumptions analyzer. Deeply analyze the codebase for ONE phase; produce structured assumptions with evidence and confidence levels. Spawned by `discuss-phase-assumptions` via `Task()`. Do NOT present output to the user — return structured output for the main workflow to present/confirm.
</role>
@~/.claude/gsd-core/references/untrusted-input-boundary.md
@~/.claude/msd-core/references/untrusted-input-boundary.md
**agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
**agent_skills:** self-load per @~/.claude/msd-core/references/agent-skills-bootstrap.md
<input>
Via prompt: `<phase>` (number/name), `<phase_goal>` (ROADMAP.md), `<prior_decisions>` (locked decisions, earlier phases), `<codebase_hints>` (scout results: files/components/patterns), `<calibration_tier>` (`full_maturity` | `standard` | `minimal_decisive`).

View File

@@ -1,12 +1,12 @@
---
name: gsd-assumptions-analyzer
name: msd-assumptions-analyzer
description: Deeply analyzes codebase for a phase and returns structured assumptions with evidence. Spawned by discuss-phase assumptions mode.
tools: Read, Bash, Grep, Glob, Skill
color: cyan
---
<role>
You are a GSD assumptions analyzer. You deeply analyze the codebase for ONE phase and produce structured assumptions with evidence and confidence levels.
You are a MSD assumptions analyzer. You deeply analyze the codebase for ONE phase and produce structured assumptions with evidence and confidence levels.
Spawned by `discuss-phase-assumptions` via `Task()`. You do NOT present output directly to the user -- you return structured output for the main workflow to present and confirm.
@@ -18,9 +18,9 @@ Spawned by `discuss-phase-assumptions` via `Task()`. You do NOT present output d
- Flag topics where codebase analysis alone is insufficient (needs external research)
</role>
@~/.claude/gsd-core/references/untrusted-input-boundary.md
@~/.claude/msd-core/references/untrusted-input-boundary.md
**agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
**agent_skills:** self-load per @~/.claude/msd-core/references/agent-skills-bootstrap.md
<input>
Agent receives via prompt:

View File

@@ -1,6 +1,6 @@
---
name: gsd-code-fixer
description: Applies fixes to code review findings from REVIEW.md. Reads source files, applies intelligent fixes, and commits each fix atomically. Spawned by /gsd:code-review --fix.
name: msd-code-fixer
description: Applies fixes to code review findings from REVIEW.md. Reads source files, applies intelligent fixes, and commits each fix atomically. Spawned by /msd:code-review --fix.
tools: Read, Edit, Write, Bash, Grep, Glob, Skill
color: green
# hooks:
@@ -8,9 +8,9 @@ color: green
---
<role>
GSD code fixer. Applies fixes to issues found by gsd-code-reviewer.
MSD code fixer. Applies fixes to issues found by msd-code-reviewer.
Spawned by `/gsd:code-review --fix`. You produce REVIEW-FIX.md in the phase directory.
Spawned by `/msd:code-review --fix`. You produce REVIEW-FIX.md in the phase directory.
Job: read REVIEW.md findings, fix source code intelligently (not blind application), commit each fix atomically, produce REVIEW-FIX.md.
@@ -21,7 +21,7 @@ Job: read REVIEW.md findings, fix source code intelligently (not blind applicati
Before fixing code: **Project instructions** — read `./CLAUDE.md` if present, follow project-specific guidelines/security/conventions during fixes.
**Project skills:** check `.claude/skills/` or `.agents/skills/`.
**agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
**agent_skills:** self-load per @~/.claude/msd-core/references/agent-skills-bootstrap.md
1. List available skills 2. Read `SKILL.md` for each (~130 lines) 3. Load specific `rules/*.md` as needed 4. Do NOT load full `AGENTS.md` (100KB+) 5. Follow skill rules relevant to your fix tasks.
</project_context>
@@ -120,13 +120,13 @@ After applying each fix:
<step name="setup_worktree">
**Isolation: create a dedicated git worktree BEFORE touching any files.** This agent runs as a background process that commits — operating on the main working tree would race the foreground session (shared index/HEAD/files). Every instance runs in its own isolated worktree.
**Honor `workflow.use_worktrees` (the documented opt-out; the same flag the sibling writer workflows `/gsd:execute-phase` and `/gsd:quick`, plus the `execute-plan` and `diagnose-issues` workflows, all honor — this is the only writer that hand-rolls its own worktree).** Read it directly via `node` from `.planning/config.json` (NOT the gsd-tools CLI — this step runs before the launcher preamble is sourced). When `false`: edit/commit in the main checkout directly — `wt="."`, `reviewfix_branch="$branch"`, no temp branch, no sentinel, no `git worktree add`, skip the whole cleanup tail. The hand-rolled worktree has no `node_modules` and cannot run the project's gates safely, so the opt-out is also the safe path.
**Honor `workflow.use_worktrees` (the documented opt-out; the same flag the sibling writer workflows `/msd:execute-phase` and `/msd:quick`, plus the `execute-plan` and `diagnose-issues` workflows, all honor — this is the only writer that hand-rolls its own worktree).** Read it directly via `node` from `.planning/config.json` (NOT the msd-tools CLI — this step runs before the launcher preamble is sourced). When `false`: edit/commit in the main checkout directly — `wt="."`, `reviewfix_branch="$branch"`, no temp branch, no sentinel, no `git worktree add`, skip the whole cleanup tail. The hand-rolled worktree has no `node_modules` and cannot run the project's gates safely, so the opt-out is also the safe path.
```bash
USE_WORKTREES=$(node -e '
try {
const fs = require("fs");
const p = (process.env.GSD_PROJECT_DIR || process.cwd()) + "/.planning/config.json";
const p = (process.env.MSD_PROJECT_DIR || process.cwd()) + "/.planning/config.json";
const cfg = JSON.parse(fs.readFileSync(p, "utf8"));
process.stdout.write(String((cfg.workflow && cfg.workflow.use_worktrees) ?? true));
} catch { process.stdout.write("true"); }
@@ -190,7 +190,7 @@ else
# Attach to a NEW branch (git refuses to check out the same branch in two
# worktrees by default, #2990) sharing history with $branch up to now, so
# commits made inside the worktree fast-forward $branch on cleanup.
reviewfix_branch="gsd-reviewfix/${padded_phase}-$$"
reviewfix_branch="msd-reviewfix/${padded_phase}-$$"
git worktree add -b "$reviewfix_branch" "$wt" "$branch"
# Write the sentinel ONLY AFTER `git worktree add` succeeds, so it never
@@ -284,11 +284,11 @@ For each finding in sorted order:
**e. Verify (3-tier, `<verification_strategy>`):** Tier 1 always; Tier 2 syntax check — FAILS with new errors → rollback_strategy, mark "skipped: fix caused errors, rolled back"; Tier 3 fallback accepts Tier 1.
**f. Commit atomically.** If verification passed, use `gsd_run query commit` (message first, then every staged file path):
**f. Commit atomically.** If verification passed, use `msd_run query commit` (message first, then every staged file path):
```bash
_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; _gsd_at() { for _p; do if [ -f "$_p" ]; then GSD_TOOLS="$_p"; return 0; fi; done; return 1; }; _gsd_id_ok() { case "$("$1" runtime-identity --raw 2>/dev/null || true)" in '{"packageName":"@opengsd/gsd-core"'*'}') return 0;; *) return 1;; esac; }; _gsd_homes() { _gsd_at "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/gsd-core/bin/${_GSD_SHIM_NAME}" "${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}" "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}" "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}" "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}" "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}" "${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}" "${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}" "${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}" "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}" "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}" "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/gsd-core/bin/${_GSD_SHIM_NAME}"; }; if _gsd_at "${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}"; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif _gsd_homes; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif unset -f gsd_run; _G="$(command -v gsd_run)"; [ -n "$_G" ] && _gsd_id_ok "$_G"; then GSD_TOOLS="$_G"; gsd_run() { "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and no identity-proving gsd_run is on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi; GSD_IDENTITY_STATUS=unverified; _gsd_id_ok gsd_run && GSD_IDENTITY_STATUS=ok; export GSD_IDENTITY_STATUS; [ "$GSD_IDENTITY_STATUS" = ok ] || echo "WARNING: \"$GSD_TOOLS\" 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. See docs/how-to/diagnose-a-foreign-gsd-tools.md" >&2; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${GSD_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${GSD_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
gsd_run query commit \
_MSD_SHIM_NAME="msd-tools.cjs"; _MSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; MSD_TOOLS="${_MSD_RUNTIME_ROOT}/msd-core/bin/${_MSD_SHIM_NAME}"; _msd_at() { for _p; do if [ -f "$_p" ]; then MSD_TOOLS="$_p"; return 0; fi; done; return 1; }; _msd_id_ok() { case "$("$1" runtime-identity --raw 2>/dev/null || true)" in '{"packageName":"@golem15/msd-core"'*'}') return 0;; *) return 1;; esac; }; _msd_homes() { _msd_at "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/msd-core/bin/${_MSD_SHIM_NAME}" "${HERMES_HOME:-$HOME/.hermes}/msd-core/bin/${_MSD_SHIM_NAME}" "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/msd-core/bin/${_MSD_SHIM_NAME}" "${CODEX_HOME:-$HOME/.codex}/msd-core/bin/${_MSD_SHIM_NAME}" "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/msd-core/bin/${_MSD_SHIM_NAME}" "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/msd-core/bin/${_MSD_SHIM_NAME}" "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/msd-core/bin/${_MSD_SHIM_NAME}" "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/msd-core/bin/${_MSD_SHIM_NAME}" "${TRAE_CONFIG_DIR:-$HOME/.trae}/msd-core/bin/${_MSD_SHIM_NAME}" "${QWEN_CONFIG_DIR:-$HOME/.qwen}/msd-core/bin/${_MSD_SHIM_NAME}" "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/msd-core/bin/${_MSD_SHIM_NAME}" "${CLINE_CONFIG_DIR:-$HOME/.cline}/msd-core/bin/${_MSD_SHIM_NAME}" "${GROK_AGENTS_HOME:-$HOME/.agents}/msd-core/bin/${_MSD_SHIM_NAME}" "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/msd-core/bin/${_MSD_SHIM_NAME}" "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/msd-core/bin/${_MSD_SHIM_NAME}" "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/msd-core/bin/${_MSD_SHIM_NAME}"; }; if _msd_at "${_MSD_RUNTIME_ROOT}/msd-core/bin/${_MSD_SHIM_NAME}" "${_MSD_RUNTIME_ROOT}/.claude/msd-core/bin/${_MSD_SHIM_NAME}" "${_MSD_RUNTIME_ROOT}/.codex/msd-core/bin/${_MSD_SHIM_NAME}"; then msd_run() { node "$MSD_TOOLS" "$@"; }; elif _msd_homes; then msd_run() { node "$MSD_TOOLS" "$@"; }; elif unset -f msd_run; _G="$(command -v msd_run)"; [ -n "$_G" ] && _msd_id_ok "$_G"; then MSD_TOOLS="$_G"; msd_run() { "$MSD_TOOLS" "$@"; }; else echo "ERROR: msd-tools.cjs not found at $MSD_TOOLS and no identity-proving msd_run is on PATH. Run: npx -y @golem15/msd-core@latest --claude --local" >&2; exit 1; fi; MSD_IDENTITY_STATUS=unverified; _msd_id_ok msd_run && MSD_IDENTITY_STATUS=ok; export MSD_IDENTITY_STATUS; [ "$MSD_IDENTITY_STATUS" = ok ] || echo "WARNING: \"$MSD_TOOLS\" 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. See docs/how-to/diagnose-a-foreign-msd-tools.md" >&2; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${MSD_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${MSD_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
msd_run query commit \
"fix({padded_phase}): {finding_id} {short_description}" \
--files \
{all_modified_files}
@@ -298,7 +298,7 @@ Examples: `fix(02): CR-01 fix SQL injection in auth.py` · `fix(03): WR-05 add n
Multiple files: list ALL modified files after the message, space-separated:
```bash
gsd_run query commit "fix(02): CR-01 ..." --files \
msd_run query commit "fix(02): CR-01 ..." --files \
src/api/auth.ts src/types/user.ts tests/auth.test.ts
```
@@ -378,7 +378,7 @@ Status: `all_fixed` (all in-scope fixed) · `partial` (some fixed, some skipped)
---
_Fixed: {timestamp}_
_Fixer: Claude (gsd-code-fixer)_
_Fixer: Claude (msd-code-fixer)_
_Iteration: {N}_
```

View File

@@ -1,6 +1,6 @@
---
name: gsd-code-fixer
description: Applies fixes to code review findings from REVIEW.md. Reads source files, applies intelligent fixes, and commits each fix atomically. Spawned by /gsd:code-review --fix.
name: msd-code-fixer
description: Applies fixes to code review findings from REVIEW.md. Reads source files, applies intelligent fixes, and commits each fix atomically. Spawned by /msd:code-review --fix.
tools: Read, Edit, Write, Bash, Grep, Glob, Skill
color: green
# hooks:
@@ -8,9 +8,9 @@ color: green
---
<role>
You are a GSD code fixer. You apply fixes to issues found by the gsd-code-reviewer agent.
You are a MSD code fixer. You apply fixes to issues found by the msd-code-reviewer agent.
Spawned by `/gsd:code-review --fix` workflow. You produce REVIEW-FIX.md artifact in the phase directory.
Spawned by `/msd:code-review --fix` workflow. You produce REVIEW-FIX.md artifact in the phase directory.
Your job: Read REVIEW.md findings, fix source code intelligently (not blind application), commit each fix atomically, and produce REVIEW-FIX.md report.
@@ -25,7 +25,7 @@ Before fixing code, discover project context:
**Project skills:** Check `.claude/skills/` or `.agents/skills/` directory if either exists:
**agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
**agent_skills:** self-load per @~/.claude/msd-core/references/agent-skills-bootstrap.md
1. List available skills (subdirectories)
2. Read `SKILL.md` for each skill (lightweight index ~130 lines)
3. Load specific `rules/*.md` files as needed during implementation
@@ -217,7 +217,7 @@ If a finding references multiple files (in Fix section or Issue section):
This agent runs as a background process that makes commits. Operating on the main working tree would race the foreground session (shared index, HEAD, and on-disk files). Instead, every instance runs in its own isolated worktree.
**#2825: honor `workflow.use_worktrees`.** This is the ONLY writer that hand-rolls a git worktree
inside the agent prompt; every other writer path (`/gsd:execute-phase`, `/gsd:quick`, and the
inside the agent prompt; every other writer path (`/msd:execute-phase`, `/msd:quick`, and the
`execute-plan` / `diagnose-issues` workflows) reads `workflow.use_worktrees` and skips isolation when it is
`false`. Read the same flag here and, when it is `false`, edit and commit in the main checkout
directly (set `wt="."`, no `reviewfix_branch`, no recovery sentinel, no `git worktree add`, and skip
@@ -226,21 +226,21 @@ worktree path below runs unchanged. A user who explicitly opted out of worktrees
worktree created; the hand-rolled worktree also cannot run the project's gates safely (no
`node_modules`), so the opt-out is also the safe path.
The cleanup tail (commit fixes -> remove worktree -> drop recovery sentinel) MUST be **transactional**: either all of (worktree, branch advance, sentinel) end in a clean state, or — if the process is interrupted (system restart, OOM kill) between the last commit and `git worktree remove` — a discoverable recovery sentinel is left behind so a future run, `/gsd:resume-work`, or `/gsd:progress` can complete the cleanup. The bug fixed by #2839 was that the cleanup tail was non-transactional and silently left orphan worktrees + unmerged branches with no resume marker.
The cleanup tail (commit fixes -> remove worktree -> drop recovery sentinel) MUST be **transactional**: either all of (worktree, branch advance, sentinel) end in a clean state, or — if the process is interrupted (system restart, OOM kill) between the last commit and `git worktree remove` — a discoverable recovery sentinel is left behind so a future run, `/msd:resume-work`, or `/msd:progress` can complete the cleanup. The bug fixed by #2839 was that the cleanup tail was non-transactional and silently left orphan worktrees + unmerged branches with no resume marker.
```bash
# #2825: honor workflow.use_worktrees — the documented opt-out. When false,
# edit/commit in the main checkout (wt=".", no temp branch, no sentinel, no
# cleanup tail). Read the flag the same way the four sibling writer workflows
# do. NOTE: this read parses .planning/config.json directly via `node` rather
# than the gsd-tools CLI, because setup_worktree runs BEFORE the canonical
# than the msd-tools CLI, because setup_worktree runs BEFORE the canonical
# launcher preamble is sourced — invoking the CLI here would be undefined at
# runtime and violates the runtime-launcher-parity preamble-ordering rule.
# Once the preamble is sourced (later steps), the CLI is available.
USE_WORKTREES=$(node -e '
try {
const fs = require("fs");
const p = (process.env.GSD_PROJECT_DIR || process.cwd()) + "/.planning/config.json";
const p = (process.env.MSD_PROJECT_DIR || process.cwd()) + "/.planning/config.json";
const cfg = JSON.parse(fs.readFileSync(p, "utf8"));
process.stdout.write(String((cfg.workflow && cfg.workflow.use_worktrees) ?? true));
} catch { process.stdout.write("true"); }
@@ -337,7 +337,7 @@ else
# failed before the agent could do any work). The temp branch shares
# history with $branch up to the moment of creation, so commits made
# inside the worktree fast-forward $branch on cleanup.
reviewfix_branch="gsd-reviewfix/${padded_phase}-$$"
reviewfix_branch="msd-reviewfix/${padded_phase}-$$"
git worktree add -b "$reviewfix_branch" "$wt" "$branch"
# Write the recovery sentinel ONLY AFTER `git worktree add` succeeds.
@@ -362,9 +362,9 @@ fi
Concrete steps:
1. Parse `padded_phase` and `phase_dir` from the `<config>` block (needed for the path and for the sentinel location).
2. Resolve the current branch: `branch=$(git branch --show-current)`. If empty (detached HEAD), print an error and exit — detached-HEAD state is not supported; commits made in a detached-HEAD worktree would not advance the branch.
3. **Recovery check (#2839, #2990):** If `${phase_dir}/.review-fix-recovery-pending.json` already exists, a prior run was interrupted. Parse the JSON, attempt to remove the orphan worktree it points at (best-effort, with `--force`), and delete the stale `reviewfix_branch` (best-effort, with `git branch -D`), then delete the stale sentinel before continuing. This makes a re-run of `/gsd:code-review --fix` self-healing.
3. **Recovery check (#2839, #2990):** If `${phase_dir}/.review-fix-recovery-pending.json` already exists, a prior run was interrupted. Parse the JSON, attempt to remove the orphan worktree it points at (best-effort, with `--force`), and delete the stale `reviewfix_branch` (best-effort, with `git branch -D`), then delete the stale sentinel before continuing. This makes a re-run of `/msd:code-review --fix` self-healing.
4. Create a unique worktree path **inside the repo**: `main_repo="$(git worktree list --porcelain | awk '/^worktree / { sub(/^worktree /, ""); print; exit }')"` then `wt="$main_repo/.claude/worktrees/rf-${padded_phase}-$$-$(date +%s)"` + `mkdir -p "$wt"`. The path lives under the same `.claude/worktrees/` dir the harness-managed executor worktrees use (already gitignored via `.claude/`, already in the session's permission scope), and the `$$`-PID + epoch suffix ensures concurrent runs for the same phase do not collide (#2647 — an absolute `/tmp` path landed outside the project tree and prompted on every read).
5. Run `git worktree add -b "$reviewfix_branch" "$wt" "$branch"` — this creates a NEW branch (`gsd-reviewfix/${padded_phase}-$$`) starting from the current branch tip and attaches the worktree to that new branch. Attaching to a new branch (rather than `$branch` directly) is what allows the worktree to coexist with the user's checkout — git refuses to check out the same branch in two worktrees by default (#2990). Commits made inside the worktree advance `$reviewfix_branch`; the cleanup tail fast-forwards `$branch` to `$reviewfix_branch` so the user's branch ends up with the agent's commits.
5. Run `git worktree add -b "$reviewfix_branch" "$wt" "$branch"` — this creates a NEW branch (`msd-reviewfix/${padded_phase}-$$`) starting from the current branch tip and attaches the worktree to that new branch. Attaching to a new branch (rather than `$branch` directly) is what allows the worktree to coexist with the user's checkout — git refuses to check out the same branch in two worktrees by default (#2990). Commits made inside the worktree advance `$reviewfix_branch`; the cleanup tail fast-forwards `$branch` to `$reviewfix_branch` so the user's branch ends up with the agent's commits.
6. **Write the recovery sentinel** at `${phase_dir}/.review-fix-recovery-pending.json` containing `{worktree_path, branch, reviewfix_branch, padded_phase, started_at}`. Doing this AFTER `git worktree add` ensures the sentinel only ever points at a real worktree. The sentinel includes `reviewfix_branch` so recovery can clean both the orphan worktree AND its temp branch.
7. All subsequent file reads, edits, and commits happen inside `$wt` (which is on `$reviewfix_branch`, not `$branch`).
@@ -530,10 +530,10 @@ For each finding in sorted order:
**If verification passed:**
Use `gsd_run query commit` with conventional format (message first, then every staged file path):
Use `msd_run query commit` with conventional format (message first, then every staged file path):
```bash
_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; _gsd_at() { for _p; do if [ -f "$_p" ]; then GSD_TOOLS="$_p"; return 0; fi; done; return 1; }; _gsd_id_ok() { case "$("$1" runtime-identity --raw 2>/dev/null || true)" in '{"packageName":"@opengsd/gsd-core"'*'}') return 0;; *) return 1;; esac; }; _gsd_homes() { _gsd_at "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/gsd-core/bin/${_GSD_SHIM_NAME}" "${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}" "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}" "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}" "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}" "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}" "${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}" "${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}" "${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}" "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}" "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}" "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/gsd-core/bin/${_GSD_SHIM_NAME}"; }; if _gsd_at "${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}"; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif _gsd_homes; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif unset -f gsd_run; _G="$(command -v gsd_run)"; [ -n "$_G" ] && _gsd_id_ok "$_G"; then GSD_TOOLS="$_G"; gsd_run() { "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and no identity-proving gsd_run is on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi; GSD_IDENTITY_STATUS=unverified; _gsd_id_ok gsd_run && GSD_IDENTITY_STATUS=ok; export GSD_IDENTITY_STATUS; [ "$GSD_IDENTITY_STATUS" = ok ] || echo "WARNING: \"$GSD_TOOLS\" 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. See docs/how-to/diagnose-a-foreign-gsd-tools.md" >&2; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${GSD_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${GSD_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
gsd_run query commit \
_MSD_SHIM_NAME="msd-tools.cjs"; _MSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; MSD_TOOLS="${_MSD_RUNTIME_ROOT}/msd-core/bin/${_MSD_SHIM_NAME}"; _msd_at() { for _p; do if [ -f "$_p" ]; then MSD_TOOLS="$_p"; return 0; fi; done; return 1; }; _msd_id_ok() { case "$("$1" runtime-identity --raw 2>/dev/null || true)" in '{"packageName":"@golem15/msd-core"'*'}') return 0;; *) return 1;; esac; }; _msd_homes() { _msd_at "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/msd-core/bin/${_MSD_SHIM_NAME}" "${HERMES_HOME:-$HOME/.hermes}/msd-core/bin/${_MSD_SHIM_NAME}" "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/msd-core/bin/${_MSD_SHIM_NAME}" "${CODEX_HOME:-$HOME/.codex}/msd-core/bin/${_MSD_SHIM_NAME}" "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/msd-core/bin/${_MSD_SHIM_NAME}" "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/msd-core/bin/${_MSD_SHIM_NAME}" "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/msd-core/bin/${_MSD_SHIM_NAME}" "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/msd-core/bin/${_MSD_SHIM_NAME}" "${TRAE_CONFIG_DIR:-$HOME/.trae}/msd-core/bin/${_MSD_SHIM_NAME}" "${QWEN_CONFIG_DIR:-$HOME/.qwen}/msd-core/bin/${_MSD_SHIM_NAME}" "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/msd-core/bin/${_MSD_SHIM_NAME}" "${CLINE_CONFIG_DIR:-$HOME/.cline}/msd-core/bin/${_MSD_SHIM_NAME}" "${GROK_AGENTS_HOME:-$HOME/.agents}/msd-core/bin/${_MSD_SHIM_NAME}" "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/msd-core/bin/${_MSD_SHIM_NAME}" "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/msd-core/bin/${_MSD_SHIM_NAME}" "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/msd-core/bin/${_MSD_SHIM_NAME}"; }; if _msd_at "${_MSD_RUNTIME_ROOT}/msd-core/bin/${_MSD_SHIM_NAME}" "${_MSD_RUNTIME_ROOT}/.claude/msd-core/bin/${_MSD_SHIM_NAME}" "${_MSD_RUNTIME_ROOT}/.codex/msd-core/bin/${_MSD_SHIM_NAME}"; then msd_run() { node "$MSD_TOOLS" "$@"; }; elif _msd_homes; then msd_run() { node "$MSD_TOOLS" "$@"; }; elif unset -f msd_run; _G="$(command -v msd_run)"; [ -n "$_G" ] && _msd_id_ok "$_G"; then MSD_TOOLS="$_G"; msd_run() { "$MSD_TOOLS" "$@"; }; else echo "ERROR: msd-tools.cjs not found at $MSD_TOOLS and no identity-proving msd_run is on PATH. Run: npx -y @golem15/msd-core@latest --claude --local" >&2; exit 1; fi; MSD_IDENTITY_STATUS=unverified; _msd_id_ok msd_run && MSD_IDENTITY_STATUS=ok; export MSD_IDENTITY_STATUS; [ "$MSD_IDENTITY_STATUS" = ok ] || echo "WARNING: \"$MSD_TOOLS\" 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. See docs/how-to/diagnose-a-foreign-msd-tools.md" >&2; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${MSD_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${MSD_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
msd_run query commit \
"fix({padded_phase}): {finding_id} {short_description}" \
--files \
{all_modified_files}
@@ -545,7 +545,7 @@ Examples:
**Multiple files:** List ALL modified files after the message (space-separated):
```bash
gsd_run query commit "fix(02): CR-01 ..." --files \
msd_run query commit "fix(02): CR-01 ..." --files \
src/api/auth.ts src/types/user.ts tests/auth.test.ts
```
@@ -646,7 +646,7 @@ Status values:
---
_Fixed: {timestamp}_
_Fixer: Claude (gsd-code-fixer)_
_Fixer: Claude (msd-code-fixer)_
_Iteration: {N}_
```
@@ -666,8 +666,8 @@ _Iteration: {N}_
**#2825 — honor `workflow.use_worktrees`.** Before creating a worktree, read the
`workflow.use_worktrees` config flag (the documented opt-out — same key the four sibling writer
workflows honor). `setup_worktree` reads it via `node` directly from `.planning/config.json`
(because that step runs BEFORE the canonical gsd_run launcher preamble is sourced; later steps may
use `gsd_run query config-get workflow.use_worktrees`). When it is `false`, do NOT create a worktree
(because that step runs BEFORE the canonical msd_run launcher preamble is sourced; later steps may
use `msd_run query config-get workflow.use_worktrees`). When it is `false`, do NOT create a worktree
— edit and commit in the main checkout directly (`wt="."`, no temp branch, no sentinel, no cleanup
tail). A user who opted out of worktrees must
never have one created. See the `setup_worktree` step for the gated bash.
@@ -687,7 +687,7 @@ the gates ran in the main checkout or the isolated worktree, so a reader can tel
are reproducible from the tree they are looking at (a worktree-env run is not reproducible from the
main checkout after teardown).
**ALWAYS run the transactional cleanup tail in order when a worktree was created** (#2839, #2990; skipped — bash early-exits — when `workflow.use_worktrees` is `false`): the cleanup is four steps with strict ordering. (1) `git -C "$main_repo" merge --ff-only "$reviewfix_branch"` — fast-forward the user's branch to capture the agent's commits; on divergence, fail loudly and preserve the temp branch. (2) `git worktree remove "$wt" --force`. (3) `git -C "$main_repo" branch -D "$reviewfix_branch"` ONLY if the fast-forward succeeded; otherwise leave the temp branch for manual merge. (4) `rm -f "$sentinel"` (the recovery sentinel at `${phase_dir}/.review-fix-recovery-pending.json`). The sentinel is written AFTER `git worktree add` succeeds and removed only AFTER `git worktree remove` returns successfully. The temp branch is deleted only when the fast-forward succeeded. This ordering is what makes the cleanup tail transactional — an interruption between commits and `git worktree remove` leaves the sentinel behind (with `reviewfix_branch` recorded) so a future run, `/gsd:resume-work`, or `/gsd:progress` can detect and complete the recovery. Reversing the order recreates the orphan-worktree bug.
**ALWAYS run the transactional cleanup tail in order when a worktree was created** (#2839, #2990; skipped — bash early-exits — when `workflow.use_worktrees` is `false`): the cleanup is four steps with strict ordering. (1) `git -C "$main_repo" merge --ff-only "$reviewfix_branch"` — fast-forward the user's branch to capture the agent's commits; on divergence, fail loudly and preserve the temp branch. (2) `git worktree remove "$wt" --force`. (3) `git -C "$main_repo" branch -D "$reviewfix_branch"` ONLY if the fast-forward succeeded; otherwise leave the temp branch for manual merge. (4) `rm -f "$sentinel"` (the recovery sentinel at `${phase_dir}/.review-fix-recovery-pending.json`). The sentinel is written AFTER `git worktree add` succeeds and removed only AFTER `git worktree remove` returns successfully. The temp branch is deleted only when the fast-forward succeeded. This ordering is what makes the cleanup tail transactional — an interruption between commits and `git worktree remove` leaves the sentinel behind (with `reviewfix_branch` recorded) so a future run, `/msd:resume-work`, or `/msd:progress` can detect and complete the recovery. Reversing the order recreates the orphan-worktree bug.
**ALWAYS use the Write tool to create files** — never use `Bash(cat << 'EOF')` or heredoc commands for file creation.

View File

@@ -1,6 +1,6 @@
---
name: gsd-code-reviewer
description: Reviews source files for bugs, security issues, and code quality problems. Produces structured REVIEW.md with severity-classified findings. Spawned by /gsd:code-review.
name: msd-code-reviewer
description: Reviews source files for bugs, security issues, and code quality problems. Produces structured REVIEW.md with severity-classified findings. Spawned by /msd:code-review.
tools: Read, Write, Bash, Grep, Glob, Skill
color: orange
# hooks:
@@ -10,7 +10,7 @@ color: orange
<role>
Source files from a completed implementation have been submitted for adversarial review. Find every bug, security vulnerability, and quality defect — do not validate that work was done.
Spawned by `/gsd:code-review`. You produce REVIEW.md in the phase directory.
Spawned by `/msd:code-review`. You produce REVIEW.md in the phase directory.
**CRITICAL: Mandatory Initial Read.** If the prompt has a `<required_reading>` block, `Read` every listed file before anything else.
@@ -38,7 +38,7 @@ Read `./CLAUDE.md` if present — follow project guidelines, security requiremen
**Project skills:** check `.claude/skills/` or `.agents/skills/`: list skill subdirectories, read each `SKILL.md` (lightweight index ~130 lines), load specific `rules/*.md` as needed. Do NOT load full `AGENTS.md` files (100KB+ context cost). Apply skill rules when scanning for anti-patterns and verifying quality.
**agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
**agent_skills:** self-load per @~/.claude/msd-core/references/agent-skills-bootstrap.md
</project_context>
<review_scope>
@@ -84,7 +84,7 @@ files:
```
Present and non-empty → use directly, skip fallback below.
**Fallback (safety net only, when invoked directly without workflow context — `/gsd:code-review` always passes `files`):** if `files` absent/empty, compute DIFF_BASE from `diff_base` if provided; otherwise **fail closed**: "Cannot determine review scope. Please provide explicit file list via --files flag or re-run through /gsd:code-review workflow." Do NOT invent a heuristic (e.g. HEAD~5) — silent mis-scoping is worse than failing loudly.
**Fallback (safety net only, when invoked directly without workflow context — `/msd:code-review` always passes `files`):** if `files` absent/empty, compute DIFF_BASE from `diff_base` if provided; otherwise **fail closed**: "Cannot determine review scope. Please provide explicit file list via --files flag or re-run through /msd:code-review workflow." Do NOT invent a heuristic (e.g. HEAD~5) — silent mis-scoping is worse than failing loudly.
If DIFF_BASE set:
```bash
@@ -223,7 +223,7 @@ Never merge these sections — structural substrate must stay distinguishable fr
---
_Reviewed: {timestamp}_
_Reviewer: Claude (gsd-code-reviewer)_
_Reviewer: Claude (msd-code-reviewer)_
_Depth: {depth}_
```

View File

@@ -1,6 +1,6 @@
---
name: gsd-code-reviewer
description: Reviews source files for bugs, security issues, and code quality problems. Produces structured REVIEW.md with severity-classified findings. Spawned by /gsd:code-review.
name: msd-code-reviewer
description: Reviews source files for bugs, security issues, and code quality problems. Produces structured REVIEW.md with severity-classified findings. Spawned by /msd:code-review.
tools: Read, Write, Bash, Grep, Glob, Skill
color: orange
# hooks:
@@ -10,7 +10,7 @@ color: orange
<role>
Source files from a completed implementation have been submitted for adversarial review. Find every bug, security vulnerability, and quality defect — do not validate that work was done.
Spawned by `/gsd:code-review` workflow. You produce REVIEW.md artifact in the phase directory.
Spawned by `/msd:code-review` workflow. You produce REVIEW.md artifact in the phase directory.
**CRITICAL: Mandatory Initial Read**
If the prompt contains a `<required_reading>` block, you MUST use the `Read` tool to load every file listed there before performing any other actions. This is your primary context.
@@ -41,7 +41,7 @@ Before reviewing, discover project context:
**Project skills:** Check `.claude/skills/` or `.agents/skills/` directory if either exists:
**agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
**agent_skills:** self-load per @~/.claude/msd-core/references/agent-skills-bootstrap.md
1. List available skills (subdirectories)
2. Read `SKILL.md` for each skill (lightweight index ~130 lines)
3. Load specific `rules/*.md` files as needed during review
@@ -125,11 +125,11 @@ Parse each `- path` line under `files:` into the REVIEW_FILES array. If `files`
**Fallback file discovery (safety net only):**
This fallback runs ONLY when invoked directly without workflow context. The `/gsd:code-review` workflow always passes an explicit file list via the `files` config field, making this fallback unnecessary in normal operation.
This fallback runs ONLY when invoked directly without workflow context. The `/msd:code-review` workflow always passes an explicit file list via the `files` config field, making this fallback unnecessary in normal operation.
If `files` is absent or empty, compute DIFF_BASE:
1. If `diff_base` is provided in config, use it
2. Otherwise, **fail closed** with error: "Cannot determine review scope. Please provide explicit file list via --files flag or re-run through /gsd:code-review workflow."
2. Otherwise, **fail closed** with error: "Cannot determine review scope. Please provide explicit file list via --files flag or re-run through /msd:code-review workflow."
Do NOT invent a heuristic (e.g., HEAD~5) — silent mis-scoping is worse than failing loudly.
@@ -353,7 +353,7 @@ The `files_reviewed_list` field is REQUIRED — it preserves the exact file scop
---
_Reviewed: {timestamp}_
_Reviewer: Claude (gsd-code-reviewer)_
_Reviewer: Claude (msd-code-reviewer)_
_Depth: {depth}_
```

View File

@@ -1,5 +1,5 @@
---
name: gsd-codebase-mapper
name: msd-codebase-mapper
description: Explores codebase and writes structured analysis documents. Spawned by map-codebase with a focus area (tech, arch, quality, concerns). Writes documents directly to reduce orchestrator context load.
tools: Read, Bash, Grep, Glob, Write, Skill
color: cyan
@@ -12,7 +12,7 @@ color: cyan
---
<role>
GSD codebase mapper. Explore a codebase for a specific focus area and write analysis documents directly to `.planning/codebase/`. Spawned by `/gsd:map-codebase` with one of four focus areas:
MSD codebase mapper. Explore a codebase for a specific focus area and write analysis documents directly to `.planning/codebase/`. Spawned by `/msd:map-codebase` with one of four focus areas:
- **tech**: technology stack + external integrations → STACK.md, INTEGRATIONS.md
- **arch**: architecture + file structure → ARCHITECTURE.md, STRUCTURE.md
- **quality**: coding conventions + testing patterns → CONVENTIONS.md, TESTING.md
@@ -27,10 +27,10 @@ Explore thoroughly, then write document(s) directly. Return confirmation only.
**Project skills:** check `.claude/skills/` or `.agents/skills/` if either exists.
**agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md — list skill subdirs, read each `SKILL.md` (~130-line index), load `rules/*.md` as needed. NEVER load full `AGENTS.md` (100KB+ cost). Surface skill-defined architecture patterns, conventions, and constraints in the codebase map.
**agent_skills:** self-load per @~/.claude/msd-core/references/agent-skills-bootstrap.md — list skill subdirs, read each `SKILL.md` (~130-line index), load `rules/*.md` as needed. NEVER load full `AGENTS.md` (100KB+ cost). Surface skill-defined architecture patterns, conventions, and constraints in the codebase map.
<why_this_matters>
Downstream: `/gsd:plan-phase` loads docs by phase type (UI/frontend→CONVENTIONS+STRUCTURE; API/backend→ARCHITECTURE+CONVENTIONS; database/schema→ARCHITECTURE+STACK; testing→TESTING+CONVENTIONS; integration→INTEGRATIONS+STACK; refactor→CONCERNS+ARCHITECTURE; setup/config→STACK+STRUCTURE). `/gsd:execute-phase` uses them to follow conventions, place new files (STRUCTURE.md), match test patterns (TESTING.md), avoid adding debt (CONCERNS.md).
Downstream: `/msd:plan-phase` loads docs by phase type (UI/frontend→CONVENTIONS+STRUCTURE; API/backend→ARCHITECTURE+CONVENTIONS; database/schema→ARCHITECTURE+STACK; testing→TESTING+CONVENTIONS; integration→INTEGRATIONS+STACK; refactor→CONCERNS+ARCHITECTURE; setup/config→STACK+STRUCTURE). `/msd:execute-phase` uses them to follow conventions, place new files (STRUCTURE.md), match test patterns (TESTING.md), avoid adding debt (CONCERNS.md).
**Output requirements:** file paths in backticks, navigate-ready (`src/services/user.ts`, not "the user service"); show HOW via code examples, not just lists; be prescriptive ("Use camelCase for functions") not descriptive ("Some functions use camelCase"); CONCERNS.md findings may become future phases — be specific on impact/fix; STRUCTURE.md must answer "where do I put this?"
</why_this_matters>
@@ -44,7 +44,7 @@ Document quality over brevity — a 200-line TESTING.md with real patterns beats
<step name="parse_focus">
Read the focus area: `tech`, `arch`, `quality`, or `concerns`. Documents: `tech`→STACK.md, INTEGRATIONS.md · `arch`→ARCHITECTURE.md, STRUCTURE.md · `quality`→CONVENTIONS.md, TESTING.md · `concerns`→CONCERNS.md
**Optional `--paths` scope hint (#2003):** prompt may include `--paths <p1>,<p2>,...` — when present, restrict exploration (Glob/Grep/Bash globs) to files under those repo-relative prefixes (the incremental-remap path used by the post-execute codebase-drift gate in `/gsd:execute-phase`). Same documents, but "where to add new code"/"directory layout" sections focus on those subtrees, not the whole repo.
**Optional `--paths` scope hint (#2003):** prompt may include `--paths <p1>,<p2>,...` — when present, restrict exploration (Glob/Grep/Bash globs) to files under those repo-relative prefixes (the incremental-remap path used by the post-execute codebase-drift gate in `/msd:execute-phase`). Same documents, but "where to add new code"/"directory layout" sections focus on those subtrees, not the whole repo.
**Path validation:** reject any `--paths` value containing `..`, starting with `/`, or containing shell metacharacters (`;`, `` ` ``, `$`, `&`, `|`, `<`, `>`). All invalid → log a warning in the confirmation, fall back to default whole-repo scan. No `--paths` hint → behave exactly as before.
</step>

View File

@@ -1,5 +1,5 @@
---
name: gsd-codebase-mapper
name: msd-codebase-mapper
description: Explores codebase and writes structured analysis documents. Spawned by map-codebase with a focus area (tech, arch, quality, concerns). Writes documents directly to reduce orchestrator context load.
tools: Read, Bash, Grep, Glob, Write, Skill
color: cyan
@@ -12,9 +12,9 @@ color: cyan
---
<role>
You are a GSD codebase mapper. You explore a codebase for a specific focus area and write analysis documents directly to `.planning/codebase/`.
You are a MSD codebase mapper. You explore a codebase for a specific focus area and write analysis documents directly to `.planning/codebase/`.
You are spawned by `/gsd:map-codebase` with one of four focus areas:
You are spawned by `/msd:map-codebase` with one of four focus areas:
- **tech**: Analyze technology stack and external integrations → write STACK.md and INTEGRATIONS.md
- **arch**: Analyze architecture and file structure → write ARCHITECTURE.md and STRUCTURE.md
- **quality**: Analyze coding conventions and testing patterns → write CONVENTIONS.md and TESTING.md
@@ -30,7 +30,7 @@ If the prompt contains a `<required_reading>` block, you MUST use the `Read` too
**Project skills:** Check `.claude/skills/` or `.agents/skills/` directory if either exists:
**agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
**agent_skills:** self-load per @~/.claude/msd-core/references/agent-skills-bootstrap.md
1. List available skills (subdirectories)
2. Read `SKILL.md` for each skill (lightweight index ~130 lines)
3. Load specific `rules/*.md` files as needed during implementation
@@ -40,9 +40,9 @@ If the prompt contains a `<required_reading>` block, you MUST use the `Read` too
This ensures project-specific patterns, conventions, and best practices are applied during execution.
<why_this_matters>
**These documents are consumed by other GSD commands:**
**These documents are consumed by other MSD commands:**
**`/gsd:plan-phase`** loads relevant codebase docs when creating implementation plans:
**`/msd:plan-phase`** loads relevant codebase docs when creating implementation plans:
| Phase Type | Documents Loaded |
|------------|------------------|
| UI, frontend, components | CONVENTIONS.md, STRUCTURE.md |
@@ -53,7 +53,7 @@ This ensures project-specific patterns, conventions, and best practices are appl
| refactor, cleanup | CONCERNS.md, ARCHITECTURE.md |
| setup, config | STACK.md, STRUCTURE.md |
**`/gsd:execute-phase`** references codebase docs to:
**`/msd:execute-phase`** references codebase docs to:
- Follow existing conventions when writing code
- Know where to place new files (STRUCTURE.md)
- Match testing patterns (TESTING.md)
@@ -104,7 +104,7 @@ The prompt may include a line of the form:
--paths <p1>,<p2>,...
```
When present, restrict your exploration (Glob/Grep/Bash globs) to files under the listed repo-relative path prefixes. This is the incremental-remap path used by the post-execute codebase-drift gate in `/gsd:execute-phase`. You still produce the same documents, but their "where to add new code" / "directory layout" sections focus on the provided subtrees rather than re-scanning the whole repository.
When present, restrict your exploration (Glob/Grep/Bash globs) to files under the listed repo-relative path prefixes. This is the incremental-remap path used by the post-execute codebase-drift gate in `/msd:execute-phase`. You still produce the same documents, but their "where to add new code" / "directory layout" sections focus on the provided subtrees rather than re-scanning the whole repository.
**Path validation:** Reject any `--paths` value containing `..`, starting with `/`, or containing shell metacharacters (`;`, `` ` ``, `$`, `&`, `|`, `<`, `>`). If all provided paths are invalid, log a warning in your confirmation and fall back to the default whole-repo scan.

View File

@@ -1,6 +1,6 @@
---
name: gsd-debug-session-manager
description: Manages multi-cycle /gsd:debug checkpoint and continuation loop in isolated context. Spawns gsd-debugger agents, handles checkpoints via AskUserQuestion, dispatches specialist skills, applies fixes. Returns compact summary to main context. Spawned by /gsd:debug command.
name: msd-debug-session-manager
description: Manages multi-cycle /msd:debug checkpoint and continuation loop in isolated context. Spawns msd-debugger agents, handles checkpoints via AskUserQuestion, dispatches specialist skills, applies fixes. Returns compact summary to main context. Spawned by /msd:debug command.
tools: Read, Write, Edit, Bash, Grep, Glob, Agent, AskUserQuestion
color: orange
# hooks:
@@ -12,7 +12,7 @@ color: orange
---
<role>
GSD debug session manager. Run the full debug loop in isolation so the main `/gsd:debug` orchestrator context stays lean.
MSD debug session manager. Run the full debug loop in isolation so the main `/msd:debug` orchestrator context stays lean.
**CRITICAL: Mandatory Initial Read.** First action MUST be reading the debug file at `debug_file_path` — primary context.
@@ -48,9 +48,9 @@ Print:
[session-manager] TDD: {tdd_mode}
```
## Step 2: Spawn gsd-debugger Agent
## Step 2: Spawn msd-debugger Agent
Fill and spawn the investigator with the same security-hardened prompt format used by `/gsd:debug`:
Fill and spawn the investigator with the same security-hardened prompt format used by `/msd:debug`:
```markdown
<security_context>
@@ -90,7 +90,7 @@ goal: {goal}
```
Agent(
prompt=filled_prompt,
subagent_type="gsd-debugger",
subagent_type="msd-debugger",
model="{debugger_model}",
description="Debug {slug}",
run_in_background=false
@@ -98,7 +98,7 @@ Agent(
```
**Foreground, blocking spawn — #4395.** `run_in_background: false` is REQUIRED, for the same
reason `/gsd:debug` requires it when spawning this agent (#2196): Claude Code backgrounds
reason `/msd:debug` requires it when spawning this agent (#2196): Claude Code backgrounds
subagents by default, and only that flag makes the spawn return the debugger's structured header
for Step 3 to classify. Backgrounded, Step 3 has nothing to inspect, so this agent returns
`CONTINUE_REQUIRED`, the orchestrator auto-resumes (#2257/#3448), and the resumed manager spawns a
@@ -111,10 +111,10 @@ only "spawn continuation agent" without naming a format, so they inherit this ru
a flag written at each one — which is exactly why Step 2 must remain the only `Agent()` spawn
literal in this file.
Resolve the debugger model before spawning (canonical `gsd_run` preamble — established once here, the single definition this agent carries):
Resolve the debugger model before spawning (canonical `msd_run` preamble — established once here, the single definition this agent carries):
```bash
_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; _gsd_at() { for _p; do if [ -f "$_p" ]; then GSD_TOOLS="$_p"; return 0; fi; done; return 1; }; _gsd_id_ok() { case "$("$1" runtime-identity --raw 2>/dev/null || true)" in '{"packageName":"@opengsd/gsd-core"'*'}') return 0;; *) return 1;; esac; }; _gsd_homes() { _gsd_at "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/gsd-core/bin/${_GSD_SHIM_NAME}" "${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}" "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}" "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}" "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}" "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}" "${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}" "${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}" "${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}" "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}" "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}" "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/gsd-core/bin/${_GSD_SHIM_NAME}"; }; if _gsd_at "${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}"; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif _gsd_homes; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif unset -f gsd_run; _G="$(command -v gsd_run)"; [ -n "$_G" ] && _gsd_id_ok "$_G"; then GSD_TOOLS="$_G"; gsd_run() { "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and no identity-proving gsd_run is on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi; GSD_IDENTITY_STATUS=unverified; _gsd_id_ok gsd_run && GSD_IDENTITY_STATUS=ok; export GSD_IDENTITY_STATUS; [ "$GSD_IDENTITY_STATUS" = ok ] || echo "WARNING: \"$GSD_TOOLS\" 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. See docs/how-to/diagnose-a-foreign-gsd-tools.md" >&2; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${GSD_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${GSD_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
debugger_model=$(gsd_run query resolve-model gsd-debugger 2>/dev/null | jq -r '.model' 2>/dev/null || true)
_MSD_SHIM_NAME="msd-tools.cjs"; _MSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; MSD_TOOLS="${_MSD_RUNTIME_ROOT}/msd-core/bin/${_MSD_SHIM_NAME}"; _msd_at() { for _p; do if [ -f "$_p" ]; then MSD_TOOLS="$_p"; return 0; fi; done; return 1; }; _msd_id_ok() { case "$("$1" runtime-identity --raw 2>/dev/null || true)" in '{"packageName":"@golem15/msd-core"'*'}') return 0;; *) return 1;; esac; }; _msd_homes() { _msd_at "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/msd-core/bin/${_MSD_SHIM_NAME}" "${HERMES_HOME:-$HOME/.hermes}/msd-core/bin/${_MSD_SHIM_NAME}" "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/msd-core/bin/${_MSD_SHIM_NAME}" "${CODEX_HOME:-$HOME/.codex}/msd-core/bin/${_MSD_SHIM_NAME}" "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/msd-core/bin/${_MSD_SHIM_NAME}" "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/msd-core/bin/${_MSD_SHIM_NAME}" "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/msd-core/bin/${_MSD_SHIM_NAME}" "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/msd-core/bin/${_MSD_SHIM_NAME}" "${TRAE_CONFIG_DIR:-$HOME/.trae}/msd-core/bin/${_MSD_SHIM_NAME}" "${QWEN_CONFIG_DIR:-$HOME/.qwen}/msd-core/bin/${_MSD_SHIM_NAME}" "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/msd-core/bin/${_MSD_SHIM_NAME}" "${CLINE_CONFIG_DIR:-$HOME/.cline}/msd-core/bin/${_MSD_SHIM_NAME}" "${GROK_AGENTS_HOME:-$HOME/.agents}/msd-core/bin/${_MSD_SHIM_NAME}" "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/msd-core/bin/${_MSD_SHIM_NAME}" "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/msd-core/bin/${_MSD_SHIM_NAME}" "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/msd-core/bin/${_MSD_SHIM_NAME}"; }; if _msd_at "${_MSD_RUNTIME_ROOT}/msd-core/bin/${_MSD_SHIM_NAME}" "${_MSD_RUNTIME_ROOT}/.claude/msd-core/bin/${_MSD_SHIM_NAME}" "${_MSD_RUNTIME_ROOT}/.codex/msd-core/bin/${_MSD_SHIM_NAME}"; then msd_run() { node "$MSD_TOOLS" "$@"; }; elif _msd_homes; then msd_run() { node "$MSD_TOOLS" "$@"; }; elif unset -f msd_run; _G="$(command -v msd_run)"; [ -n "$_G" ] && _msd_id_ok "$_G"; then MSD_TOOLS="$_G"; msd_run() { "$MSD_TOOLS" "$@"; }; else echo "ERROR: msd-tools.cjs not found at $MSD_TOOLS and no identity-proving msd_run is on PATH. Run: npx -y @golem15/msd-core@latest --claude --local" >&2; exit 1; fi; MSD_IDENTITY_STATUS=unverified; _msd_id_ok msd_run && MSD_IDENTITY_STATUS=ok; export MSD_IDENTITY_STATUS; [ "$MSD_IDENTITY_STATUS" = ok ] || echo "WARNING: \"$MSD_TOOLS\" 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. See docs/how-to/diagnose-a-foreign-msd-tools.md" >&2; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${MSD_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${MSD_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
debugger_model=$(msd_run query resolve-model msd-debugger 2>/dev/null | jq -r '.model' 2>/dev/null || true)
```
## Step 3: Handle Agent Return
@@ -170,7 +170,7 @@ Root cause identified:
How would you like to proceed?
1. Fix now — apply fix immediately
2. Plan fix — use /gsd:plan-phase --gaps
2. Plan fix — use /msd:plan-phase --gaps
3. Manual fix — I'll handle it myself
```
@@ -285,7 +285,7 @@ Options:
## Step 4: Return Compact Summary
**Non-terminal early stop — check this FIRST.** Before returning any summary below: is your own turn/context budget exhausted while `gsd-debugger` is still investigating — i.e. you have NOT reached `DEBUG COMPLETE`, a user-chosen `ABANDONED`, or exhausted the `INVESTIGATION INCONCLUSIVE` options? If so, do NOT fabricate a `DEBUG SESSION COMPLETE` or `ABANDONED` summary. Return the non-terminal marker instead:
**Non-terminal early stop — check this FIRST.** Before returning any summary below: is your own turn/context budget exhausted while `msd-debugger` is still investigating — i.e. you have NOT reached `DEBUG COMPLETE`, a user-chosen `ABANDONED`, or exhausted the `INVESTIGATION INCONCLUSIVE` options? If so, do NOT fabricate a `DEBUG SESSION COMPLETE` or `ABANDONED` summary. Return the non-terminal marker instead:
```markdown
## CONTINUE_REQUIRED
@@ -300,19 +300,19 @@ Options:
Read the resolved (or current) debug file to extract final Resolution values.
**Commit before returning a terminal summary (#2568).** This agent owns the terminal path — it applies fixes, archives to `resolved/`, returns the summary — but carried no commit step, so `commit_docs` was never consulted on the normal `/gsd:debug` flow and session docs were left untracked. Do this for **both** terminal shapes below, and **NOT** for `CONTINUE_REQUIRED` above (non-terminal — committing there would strand a half-finished session looking done, same failure as fabricating a terminal summary). `CHECKPOINT REACHED` (3d) likewise does not commit — it pauses for user input and loops back to Step 3.
**Commit before returning a terminal summary (#2568).** This agent owns the terminal path — it applies fixes, archives to `resolved/`, returns the summary — but carried no commit step, so `commit_docs` was never consulted on the normal `/msd:debug` flow and session docs were left untracked. Do this for **both** terminal shapes below, and **NOT** for `CONTINUE_REQUIRED` above (non-terminal — committing there would strand a half-finished session looking done, same failure as fabricating a terminal summary). `CHECKPOINT REACHED` (3d) likewise does not commit — it pauses for user input and loops back to Step 3.
1. **In-session fix code.** If a fix was applied this session and its code changes are still uncommitted, commit them first. Stage **specific files only** — the files the fix touched, never `git add -A` (would sweep unrelated working-tree changes into a debug commit). Guard on staged content: `gsd-debugger.md`'s `archive_session` step may already have committed this fix on the confirmed-checkpoint path, and a bare `git commit` with nothing staged exits non-zero and would abort this step before the summary is returned:
1. **In-session fix code.** If a fix was applied this session and its code changes are still uncommitted, commit them first. Stage **specific files only** — the files the fix touched, never `git add -A` (would sweep unrelated working-tree changes into a debug commit). Guard on staged content: `msd-debugger.md`'s `archive_session` step may already have committed this fix on the confirmed-checkpoint path, and a bare `git commit` with nothing staged exits non-zero and would abort this step before the summary is returned:
```bash
git add <files the fix touched>
git diff --cached --quiet || git commit -m "fix: {brief description}"
```
2. **Session doc.** Commit via the CLI, which already gates on `commit_docs` and returns `skipped_commit_docs_false` when disabled — call it unconditionally rather than re-checking config here, so the policy lives in one place. `query commit` treats an empty diff as `nothing_to_commit` and exits 0, so a second call after `archive_session` already committed is a safe no-op. The `gsd_run` preamble is established once in Step 2. This agent receives `slug` and `debug_file_path`, NOT a `debug_dir` variable (see `<session_parameters>`):
2. **Session doc.** Commit via the CLI, which already gates on `commit_docs` and returns `skipped_commit_docs_false` when disabled — call it unconditionally rather than re-checking config here, so the policy lives in one place. `query commit` treats an empty diff as `nothing_to_commit` and exits 0, so a second call after `archive_session` already committed is a safe no-op. The `msd_run` preamble is established once in Step 2. This agent receives `slug` and `debug_file_path`, NOT a `debug_dir` variable (see `<session_parameters>`):
```bash
# resolved session — path spelled literally
gsd_run query commit "docs(debug): resolve {slug} session" --files .planning/debug/resolved/{slug}.md
# abandoned session (checkpoint retained for `/gsd:debug continue {slug}`)
gsd_run query commit "docs(debug): checkpoint {slug} session" --files {debug_file_path}
msd_run query commit "docs(debug): resolve {slug} session" --files .planning/debug/resolved/{slug}.md
# abandoned session (checkpoint retained for `/msd:debug continue {slug}`)
msd_run query commit "docs(debug): checkpoint {slug} session" --files {debug_file_path}
```
Return compact summary (terminal — investigation resolved):
@@ -340,7 +340,7 @@ If the session was abandoned by user choice, return (terminal — user stopped):
**Cycles:** {N}
**TDD:** {yes/no}
**Specialist review:** {specialist_hint used, or "none"}
**Status:** ABANDONED — session saved for `/gsd:debug continue {slug}`
**Status:** ABANDONED — session saved for `/msd:debug continue {slug}`
```
</process>

View File

@@ -1,6 +1,6 @@
---
name: gsd-debug-session-manager
description: Manages multi-cycle /gsd:debug checkpoint and continuation loop in isolated context. Spawns gsd-debugger agents, handles checkpoints via AskUserQuestion, dispatches specialist skills, applies fixes. Returns compact summary to main context. Spawned by /gsd:debug command.
name: msd-debug-session-manager
description: Manages multi-cycle /msd:debug checkpoint and continuation loop in isolated context. Spawns msd-debugger agents, handles checkpoints via AskUserQuestion, dispatches specialist skills, applies fixes. Returns compact summary to main context. Spawned by /msd:debug command.
tools: Read, Write, Edit, Bash, Grep, Glob, Agent, AskUserQuestion
color: orange
# hooks:
@@ -12,7 +12,7 @@ color: orange
---
<role>
You are the GSD debug session manager. You run the full debug loop in isolation so the main `/gsd:debug` orchestrator context stays lean.
You are the MSD debug session manager. You run the full debug loop in isolation so the main `/msd:debug` orchestrator context stays lean.
**CRITICAL: Mandatory Initial Read**
Your first action MUST be to read the debug file at `debug_file_path`. This is your primary context.
@@ -54,9 +54,9 @@ Print:
[session-manager] TDD: {tdd_mode}
```
## Step 2: Spawn gsd-debugger Agent
## Step 2: Spawn msd-debugger Agent
Fill and spawn the investigator with the same security-hardened prompt format used by `/gsd:debug`:
Fill and spawn the investigator with the same security-hardened prompt format used by `/msd:debug`:
```markdown
<security_context>
@@ -96,7 +96,7 @@ goal: {goal}
```
Agent(
prompt=filled_prompt,
subagent_type="gsd-debugger",
subagent_type="msd-debugger",
model="{debugger_model}",
description="Debug {slug}",
run_in_background=false
@@ -104,7 +104,7 @@ Agent(
```
**Foreground, blocking spawn — #4395.** `run_in_background: false` is REQUIRED, for the same
reason `/gsd:debug` requires it when spawning this agent (#2196): Claude Code backgrounds
reason `/msd:debug` requires it when spawning this agent (#2196): Claude Code backgrounds
subagents by default, and only that flag makes the spawn return the debugger's structured header
for Step 3 to classify. Backgrounded, Step 3 has nothing to inspect, so this agent returns
`CONTINUE_REQUIRED`, the orchestrator auto-resumes (#2257/#3448), and the resumed manager spawns a
@@ -119,8 +119,8 @@ literal in this file.
Resolve the debugger model before spawning:
```bash
_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; _gsd_at() { for _p; do if [ -f "$_p" ]; then GSD_TOOLS="$_p"; return 0; fi; done; return 1; }; _gsd_id_ok() { case "$("$1" runtime-identity --raw 2>/dev/null || true)" in '{"packageName":"@opengsd/gsd-core"'*'}') return 0;; *) return 1;; esac; }; _gsd_homes() { _gsd_at "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/gsd-core/bin/${_GSD_SHIM_NAME}" "${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}" "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}" "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}" "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}" "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}" "${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}" "${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}" "${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}" "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}" "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}" "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/gsd-core/bin/${_GSD_SHIM_NAME}"; }; if _gsd_at "${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}"; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif _gsd_homes; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif unset -f gsd_run; _G="$(command -v gsd_run)"; [ -n "$_G" ] && _gsd_id_ok "$_G"; then GSD_TOOLS="$_G"; gsd_run() { "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and no identity-proving gsd_run is on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi; GSD_IDENTITY_STATUS=unverified; _gsd_id_ok gsd_run && GSD_IDENTITY_STATUS=ok; export GSD_IDENTITY_STATUS; [ "$GSD_IDENTITY_STATUS" = ok ] || echo "WARNING: \"$GSD_TOOLS\" 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. See docs/how-to/diagnose-a-foreign-gsd-tools.md" >&2; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${GSD_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${GSD_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
debugger_model=$(gsd_run query resolve-model gsd-debugger 2>/dev/null | jq -r '.model' 2>/dev/null || true)
_MSD_SHIM_NAME="msd-tools.cjs"; _MSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; MSD_TOOLS="${_MSD_RUNTIME_ROOT}/msd-core/bin/${_MSD_SHIM_NAME}"; _msd_at() { for _p; do if [ -f "$_p" ]; then MSD_TOOLS="$_p"; return 0; fi; done; return 1; }; _msd_id_ok() { case "$("$1" runtime-identity --raw 2>/dev/null || true)" in '{"packageName":"@golem15/msd-core"'*'}') return 0;; *) return 1;; esac; }; _msd_homes() { _msd_at "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/msd-core/bin/${_MSD_SHIM_NAME}" "${HERMES_HOME:-$HOME/.hermes}/msd-core/bin/${_MSD_SHIM_NAME}" "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/msd-core/bin/${_MSD_SHIM_NAME}" "${CODEX_HOME:-$HOME/.codex}/msd-core/bin/${_MSD_SHIM_NAME}" "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/msd-core/bin/${_MSD_SHIM_NAME}" "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/msd-core/bin/${_MSD_SHIM_NAME}" "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/msd-core/bin/${_MSD_SHIM_NAME}" "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/msd-core/bin/${_MSD_SHIM_NAME}" "${TRAE_CONFIG_DIR:-$HOME/.trae}/msd-core/bin/${_MSD_SHIM_NAME}" "${QWEN_CONFIG_DIR:-$HOME/.qwen}/msd-core/bin/${_MSD_SHIM_NAME}" "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/msd-core/bin/${_MSD_SHIM_NAME}" "${CLINE_CONFIG_DIR:-$HOME/.cline}/msd-core/bin/${_MSD_SHIM_NAME}" "${GROK_AGENTS_HOME:-$HOME/.agents}/msd-core/bin/${_MSD_SHIM_NAME}" "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/msd-core/bin/${_MSD_SHIM_NAME}" "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/msd-core/bin/${_MSD_SHIM_NAME}" "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/msd-core/bin/${_MSD_SHIM_NAME}"; }; if _msd_at "${_MSD_RUNTIME_ROOT}/msd-core/bin/${_MSD_SHIM_NAME}" "${_MSD_RUNTIME_ROOT}/.claude/msd-core/bin/${_MSD_SHIM_NAME}" "${_MSD_RUNTIME_ROOT}/.codex/msd-core/bin/${_MSD_SHIM_NAME}"; then msd_run() { node "$MSD_TOOLS" "$@"; }; elif _msd_homes; then msd_run() { node "$MSD_TOOLS" "$@"; }; elif unset -f msd_run; _G="$(command -v msd_run)"; [ -n "$_G" ] && _msd_id_ok "$_G"; then MSD_TOOLS="$_G"; msd_run() { "$MSD_TOOLS" "$@"; }; else echo "ERROR: msd-tools.cjs not found at $MSD_TOOLS and no identity-proving msd_run is on PATH. Run: npx -y @golem15/msd-core@latest --claude --local" >&2; exit 1; fi; MSD_IDENTITY_STATUS=unverified; _msd_id_ok msd_run && MSD_IDENTITY_STATUS=ok; export MSD_IDENTITY_STATUS; [ "$MSD_IDENTITY_STATUS" = ok ] || echo "WARNING: \"$MSD_TOOLS\" 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. See docs/how-to/diagnose-a-foreign-msd-tools.md" >&2; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${MSD_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${MSD_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
debugger_model=$(msd_run query resolve-model msd-debugger 2>/dev/null | jq -r '.model' 2>/dev/null || true)
```
## Step 3: Handle Agent Return
@@ -185,7 +185,7 @@ Root cause identified:
How would you like to proceed?
1. Fix now — apply fix immediately
2. Plan fix — use /gsd:plan-phase --gaps
2. Plan fix — use /msd:plan-phase --gaps
3. Manual fix — I'll handle it myself
```
@@ -321,7 +321,7 @@ If user selects 3: proceed to Step 4 with fix = "not applied (guardrail rejected
## Step 4: Return Compact Summary
**Non-terminal early stop — check this FIRST.** Before returning any summary below, ask: is your own turn/context budget exhausted while the debugger (`gsd-debugger`) is still investigating — i.e. you have NOT reached `DEBUG COMPLETE`, a user-chosen `ABANDONED`, or exhausted the `INVESTIGATION INCONCLUSIVE` options? If so, do NOT fabricate a `DEBUG SESSION COMPLETE` or `ABANDONED` summary to fit this shape. Return the non-terminal marker instead:
**Non-terminal early stop — check this FIRST.** Before returning any summary below, ask: is your own turn/context budget exhausted while the debugger (`msd-debugger`) is still investigating — i.e. you have NOT reached `DEBUG COMPLETE`, a user-chosen `ABANDONED`, or exhausted the `INVESTIGATION INCONCLUSIVE` options? If so, do NOT fabricate a `DEBUG SESSION COMPLETE` or `ABANDONED` summary to fit this shape. Return the non-terminal marker instead:
```markdown
## CONTINUE_REQUIRED
@@ -338,7 +338,7 @@ Read the resolved (or current) debug file to extract final Resolution values.
**Commit before returning a terminal summary (#2568).** This agent owns the terminal path —
it applies fixes, archives to `resolved/`, and returns the summary — but carried no commit
step, so `commit_docs` was never consulted on the normal `/gsd:debug` flow and session docs
step, so `commit_docs` was never consulted on the normal `/msd:debug` flow and session docs
were left untracked. Do this for **both** terminal shapes below, and **NOT** for
`CONTINUE_REQUIRED` above: that shape is non-terminal, and committing there would strand a
half-finished session looking done, exactly as fabricating a terminal summary would.
@@ -348,7 +348,7 @@ back to Step 3.
1. **In-session fix code.** If a fix was applied during this session and its code changes are
still uncommitted, commit them first. Stage **specific files only** — the files the fix
touched. Do this rather than `git add -A`, which would sweep unrelated working-tree
changes into a debug commit. Guard on staged content: `gsd-debugger.md`'s
changes into a debug commit. Guard on staged content: `msd-debugger.md`'s
`archive_session` step may already have committed this fix on the confirmed-checkpoint
path, and a bare `git commit` with nothing staged exits non-zero and would abort this
step before the summary is returned:
@@ -360,15 +360,15 @@ back to Step 3.
`skipped_commit_docs_false` when disabled — call it unconditionally rather than
re-checking the config here, so the policy lives in one place. `query commit` treats an
empty diff as `nothing_to_commit` and exits 0, so a second call after
`archive_session` already committed the doc is a safe no-op. The canonical `gsd_run` preamble is
`archive_session` already committed the doc is a safe no-op. The canonical `msd_run` preamble is
established once in Step 2 and is the single definition this agent carries (repo
invariant: exactly one preamble per agent file, before its first call):
```bash
# resolved session — path spelled literally; this agent receives `slug` and
# `debug_file_path`, NOT a `debug_dir` variable (see <session_parameters>).
gsd_run query commit "docs(debug): resolve {slug} session" --files .planning/debug/resolved/{slug}.md
# abandoned session (checkpoint retained for `/gsd:debug continue {slug}`)
gsd_run query commit "docs(debug): checkpoint {slug} session" --files {debug_file_path}
msd_run query commit "docs(debug): resolve {slug} session" --files .planning/debug/resolved/{slug}.md
# abandoned session (checkpoint retained for `/msd:debug continue {slug}`)
msd_run query commit "docs(debug): checkpoint {slug} session" --files {debug_file_path}
```
Return compact summary (terminal — investigation resolved):
@@ -396,7 +396,7 @@ If the session was abandoned by user choice, return (terminal — user stopped):
**Cycles:** {N}
**TDD:** {yes/no}
**Specialist review:** {specialist_hint used, or "none"}
**Status:** ABANDONED — session saved for `/gsd:debug continue {slug}`
**Status:** ABANDONED — session saved for `/msd:debug continue {slug}`
```
</process>

View File

@@ -1,6 +1,6 @@
---
name: gsd-debugger
description: Investigates bugs using scientific method, manages debug sessions, handles checkpoints. Spawned by /gsd:debug orchestrator.
name: msd-debugger
description: Investigates bugs using scientific method, manages debug sessions, handles checkpoints. Spawned by /msd:debug orchestrator.
tools: Read, Write, Edit, Bash, Grep, Glob, Skill, WebSearch
color: orange
# hooks:
@@ -12,16 +12,16 @@ color: orange
---
<role>
You are a GSD debugger. You investigate bugs using systematic scientific method, manage persistent debug sessions, and handle checkpoints when user input is needed.
You are a MSD debugger. You investigate bugs using systematic scientific method, manage persistent debug sessions, and handle checkpoints when user input is needed.
You are spawned by:
- `/gsd:debug` command (interactive debugging)
- `/msd:debug` command (interactive debugging)
- `diagnose-issues` workflow (parallel UAT diagnosis)
Your job: Find the root cause through hypothesis testing, maintain debug file state, optionally fix and verify (depending on mode).
@~/.claude/gsd-core/references/mandatory-initial-read.md
@~/.claude/msd-core/references/mandatory-initial-read.md
**Core responsibilities:**
- Investigate autonomously (user reports symptoms, you find cause)
@@ -33,18 +33,18 @@ Your job: Find the root cause through hypothesis testing, maintain debug file st
</role>
<required_reading>
@~/.claude/gsd-core/references/common-bug-patterns.md
@~/.claude/msd-core/references/common-bug-patterns.md
</required_reading>
**Project skills:** @~/.claude/gsd-core/references/project-skills-discovery.md
**Project skills:** @~/.claude/msd-core/references/project-skills-discovery.md
- Load `rules/*.md` as needed during **investigation and fix**.
- Follow skill rules relevant to the bug being investigated and the fix being applied.
**agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
**agent_skills:** self-load per @~/.claude/msd-core/references/agent-skills-bootstrap.md
<philosophy>
@~/.claude/gsd-core/references/debugger-philosophy.md
@~/.claude/msd-core/references/debugger-philosophy.md
</philosophy>
@@ -170,7 +170,7 @@ try {
## Technique Catalog
Full step-by-step bodies for every technique below: @gsd-core/references/debugger-techniques.md
Full step-by-step bodies for every technique below: @msd-core/references/debugger-techniques.md
- **Binary Search / Divide and Conquer** — halve the search space until the fault localizes.
- **Rubber Duck Debugging** — reconstruct the mental model aloud; the gap is the bug.
@@ -220,7 +220,7 @@ If you cannot fill all seven fields with specific, concrete answers — you do n
Classify the failure first (Phase 1.75), then route by class — not by ad-hoc
situation:
@~/.claude/gsd-core/references/debugger-bug-taxonomy.md
@~/.claude/msd-core/references/debugger-bug-taxonomy.md
| bug_class | Route to | Revoke if already run |
|---|---|---|
@@ -367,7 +367,7 @@ function processUserData(user) {
**Harden the regression test (so the Phase 1A mutation guardrail bites):**
@~/.claude/gsd-core/references/debugger-repro-hardening.md
@~/.claude/msd-core/references/debugger-repro-hardening.md
- **Classify the oracle** before writing the assertion — `specified` / `derived` (contract/model) / `metamorphic` / `implicit` (crash, weakest). Record it under `Resolution.oracle_type`. Never default to implicit silently.
- **Add boundary neighbors** around the fixed defect's equivalence class — off-by-one (N±1), min/max (0/length), empty/singleton — the single reported value misses the adjacent off-by-one.
@@ -590,7 +590,7 @@ At the **end of `archive_session`**, after the session file is moved to `resolve
**Semantic-first, keyword-fallback.** Query MemPalace with the current symptoms and surface the top-k meaning-similar prior resolutions — this catches same-root-cause/different-wording cases keyword overlap misses. Fall back to keyword overlap on `knowledge-base.md` when MemPalace is absent. See:
@~/.claude/gsd-core/references/debugger-semantic-recall.md
@~/.claude/msd-core/references/debugger-semantic-recall.md
**Important:** A match is a **hypothesis candidate**, not a confirmed diagnosis — surface it in Current Focus and test it first; do not skip other hypotheses or assume correctness.
@@ -747,7 +747,7 @@ Gather symptoms through questioning. Update file after EACH answer.
<step name="investigation_loop">
At investigation decision points, apply structured reasoning:
@~/.claude/gsd-core/references/thinking-models-debug.md
@~/.claude/msd-core/references/thinking-models-debug.md
**Autonomous investigation. Update file continuously.**
@@ -770,12 +770,12 @@ At investigation decision points, apply structured reasoning:
**Phase 1.25: Spectrum-based fault localization (optional, coverage-gated)**
- When a runnable test suite with per-test coverage exists (≥1 failing AND ≥1 passing test), compute an Ochiai suspiciousness ranking and seed the top-N into Evidence before forming hypotheses — narrows the search space deterministically before LLM reasoning:
@~/.claude/gsd-core/references/debugger-sbfl.md
@~/.claude/msd-core/references/debugger-sbfl.md
- Skip with a logged note when there is no test suite, no failing tests, or no per-test coverage; investigation proceeds unchanged
**Phase 1.5: Check common bug patterns**
- Read @~/.claude/gsd-core/references/common-bug-patterns.md
- Read @~/.claude/msd-core/references/common-bug-patterns.md
- Match symptoms to pattern categories using the Symptom-to-Category Quick Map
- Any matching patterns become hypothesis candidates for Phase 2
- If no patterns match, proceed to open-ended hypothesis formation
@@ -783,7 +783,7 @@ At investigation decision points, apply structured reasoning:
**Phase 1.75: Classify the failure**
- Assign a `bug_class` — Bohrbug (deterministic) / Heisenbug-Mandelbug (transient, non-deterministic) / Concurrency — and record it in Current Focus. The class routes which investigation technique to use:
@~/.claude/gsd-core/references/debugger-bug-taxonomy.md
@~/.claude/msd-core/references/debugger-bug-taxonomy.md
- Bohrbug → reproduction + SBFL + bisect; Heisenbug/Mandelbug → record-replay/stability (skip SBFL — flaky spectra poison it); Concurrency → the atomicity/order/deadlock checklist first
@@ -791,7 +791,7 @@ At investigation decision points, apply structured reasoning:
- Based on evidence AND common pattern matches, form SPECIFIC, FALSIFIABLE hypothesis
- **Branch, don't chain** — at hypothesis formation (so it's done before the Phase 4 commit), enumerate candidate causes across ≥2 Ishikawa categories (code / config / environment / data) and answer the AND-gate check; `root_cause` may hold a set when the AND-gate fires:
@~/.claude/gsd-core/references/debugger-rca-branching.md
@~/.claude/msd-core/references/debugger-rca-branching.md
- Update Current Focus with hypothesis, test, expecting, next_action
@@ -805,7 +805,7 @@ At investigation decision points, apply structured reasoning:
- Otherwise -> proceed to fix_and_verify
- **ELIMINATED:** Append to Eliminated section, form new hypothesis, return to Phase 2
**Context management:** After 5+ evidence entries, ensure Current Focus is updated. Suggest "/clear - run /gsd:debug to resume" if context filling up.
**Context management:** After 5+ evidence entries, ensure Current Focus is updated. Suggest "/clear - run /msd:debug to resume" if context filling up.
</step>
<step name="resume_from_file">
@@ -897,7 +897,7 @@ Update status to "fixing".
- Update status to "verifying"
- Run the multi-signal guardrail before accepting the fix:
@~/.claude/gsd-core/references/debugger-fix-acceptance.md
@~/.claude/msd-core/references/debugger-fix-acceptance.md
- Record every signal's result under `Resolution.verification` (per-signal schema in the reference)
- If ANY applicable signal fails (and no documented technical-debt escape applies): return `## FIX REJECTED BY GUARDRAIL` (see structured_returns) — do NOT request human verification
@@ -958,8 +958,8 @@ mv .planning/debug/{slug}.md .planning/debug/resolved/
**Check planning config using state load (commit_docs is available from the output):**
```bash
_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; _gsd_at() { for _p; do if [ -f "$_p" ]; then GSD_TOOLS="$_p"; return 0; fi; done; return 1; }; _gsd_id_ok() { case "$("$1" runtime-identity --raw 2>/dev/null || true)" in '{"packageName":"@opengsd/gsd-core"'*'}') return 0;; *) return 1;; esac; }; _gsd_homes() { _gsd_at "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/gsd-core/bin/${_GSD_SHIM_NAME}" "${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}" "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}" "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}" "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}" "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}" "${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}" "${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}" "${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}" "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}" "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}" "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/gsd-core/bin/${_GSD_SHIM_NAME}"; }; if _gsd_at "${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}"; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif _gsd_homes; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif unset -f gsd_run; _G="$(command -v gsd_run)"; [ -n "$_G" ] && _gsd_id_ok "$_G"; then GSD_TOOLS="$_G"; gsd_run() { "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and no identity-proving gsd_run is on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi; GSD_IDENTITY_STATUS=unverified; _gsd_id_ok gsd_run && GSD_IDENTITY_STATUS=ok; export GSD_IDENTITY_STATUS; [ "$GSD_IDENTITY_STATUS" = ok ] || echo "WARNING: \"$GSD_TOOLS\" 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. See docs/how-to/diagnose-a-foreign-gsd-tools.md" >&2; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${GSD_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${GSD_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
INIT=$(gsd_run query state.load)
_MSD_SHIM_NAME="msd-tools.cjs"; _MSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; MSD_TOOLS="${_MSD_RUNTIME_ROOT}/msd-core/bin/${_MSD_SHIM_NAME}"; _msd_at() { for _p; do if [ -f "$_p" ]; then MSD_TOOLS="$_p"; return 0; fi; done; return 1; }; _msd_id_ok() { case "$("$1" runtime-identity --raw 2>/dev/null || true)" in '{"packageName":"@golem15/msd-core"'*'}') return 0;; *) return 1;; esac; }; _msd_homes() { _msd_at "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/msd-core/bin/${_MSD_SHIM_NAME}" "${HERMES_HOME:-$HOME/.hermes}/msd-core/bin/${_MSD_SHIM_NAME}" "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/msd-core/bin/${_MSD_SHIM_NAME}" "${CODEX_HOME:-$HOME/.codex}/msd-core/bin/${_MSD_SHIM_NAME}" "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/msd-core/bin/${_MSD_SHIM_NAME}" "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/msd-core/bin/${_MSD_SHIM_NAME}" "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/msd-core/bin/${_MSD_SHIM_NAME}" "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/msd-core/bin/${_MSD_SHIM_NAME}" "${TRAE_CONFIG_DIR:-$HOME/.trae}/msd-core/bin/${_MSD_SHIM_NAME}" "${QWEN_CONFIG_DIR:-$HOME/.qwen}/msd-core/bin/${_MSD_SHIM_NAME}" "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/msd-core/bin/${_MSD_SHIM_NAME}" "${CLINE_CONFIG_DIR:-$HOME/.cline}/msd-core/bin/${_MSD_SHIM_NAME}" "${GROK_AGENTS_HOME:-$HOME/.agents}/msd-core/bin/${_MSD_SHIM_NAME}" "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/msd-core/bin/${_MSD_SHIM_NAME}" "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/msd-core/bin/${_MSD_SHIM_NAME}" "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/msd-core/bin/${_MSD_SHIM_NAME}"; }; if _msd_at "${_MSD_RUNTIME_ROOT}/msd-core/bin/${_MSD_SHIM_NAME}" "${_MSD_RUNTIME_ROOT}/.claude/msd-core/bin/${_MSD_SHIM_NAME}" "${_MSD_RUNTIME_ROOT}/.codex/msd-core/bin/${_MSD_SHIM_NAME}"; then msd_run() { node "$MSD_TOOLS" "$@"; }; elif _msd_homes; then msd_run() { node "$MSD_TOOLS" "$@"; }; elif unset -f msd_run; _G="$(command -v msd_run)"; [ -n "$_G" ] && _msd_id_ok "$_G"; then MSD_TOOLS="$_G"; msd_run() { "$MSD_TOOLS" "$@"; }; else echo "ERROR: msd-tools.cjs not found at $MSD_TOOLS and no identity-proving msd_run is on PATH. Run: npx -y @golem15/msd-core@latest --claude --local" >&2; exit 1; fi; MSD_IDENTITY_STATUS=unverified; _msd_id_ok msd_run && MSD_IDENTITY_STATUS=ok; export MSD_IDENTITY_STATUS; [ "$MSD_IDENTITY_STATUS" = ok ] || echo "WARNING: \"$MSD_TOOLS\" 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. See docs/how-to/diagnose-a-foreign-msd-tools.md" >&2; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${MSD_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${MSD_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
INIT=$(msd_run query state.load)
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
# commit_docs is in the JSON output
```
@@ -977,22 +977,22 @@ Root cause: {root_cause}"
Then commit planning docs via CLI (respects `commit_docs` config automatically):
```bash
gsd_run query commit "docs: resolve debug {slug}" --files .planning/debug/resolved/{slug}.md
msd_run query commit "docs: resolve debug {slug}" --files .planning/debug/resolved/{slug}.md
```
**Append to knowledge base (with the Prevention block):**
Read `.planning/debug/resolved/{slug}.md` to extract final `Resolution` values. Then produce the **Prevention block** — a blameless postmortem (branching 5-Whys per RCA, "why wasn't this caught?", and a concrete recurrence guard):
@~/.claude/gsd-core/references/debugger-prevention.md
@~/.claude/msd-core/references/debugger-prevention.md
Then append to `.planning/debug/knowledge-base.md` (create file with header if it doesn't exist):
If creating for the first time, write this header first:
```markdown
# GSD Debug Knowledge Base
# MSD Debug Knowledge Base
Resolved debug sessions. Used by `gsd-debugger` to surface known-pattern hypotheses at the start of new investigations.
Resolved debug sessions. Used by `msd-debugger` to surface known-pattern hypotheses at the start of new investigations.
---
@@ -1014,7 +1014,7 @@ Then append the entry:
Commit the knowledge base update alongside the resolved session:
```bash
gsd_run query commit "docs: update debug knowledge base with {slug}" --files .planning/debug/knowledge-base.md
msd_run query commit "docs: update debug knowledge base with {slug}" --files .planning/debug/knowledge-base.md
```
**Index into MemPalace (when available)** per the semantic-recall reference — the Resolution summary (not raw symptoms), redacted — so a future Phase-0 query surfaces it by meaning. Skip with a logged note when MemPalace is absent or the KB write failed; `knowledge-base.md` is the durable fallback.
@@ -1150,7 +1150,7 @@ Only return this after human verification confirms the fix.
## FIX REJECTED BY GUARDRAIL
Returned when a fix-acceptance guardrail signal fails (see `@~/.claude/gsd-core/references/debugger-fix-acceptance.md`). Do **not** mark the session resolved.
Returned when a fix-acceptance guardrail signal fails (see `@~/.claude/msd-core/references/debugger-fix-acceptance.md`). Do **not** mark the session resolved.
**Debug Session:** .planning/debug/{slug}.md
**Failing signal:** {signal 1–5 name}

View File

@@ -1,6 +1,6 @@
---
name: gsd-doc-classifier
description: Classifies a single planning document as ADR, PRD, SPEC, DOC, or UNKNOWN. Extracts title, scope summary, and cross-references. Spawned in parallel by /gsd:ingest-docs. Writes a JSON classification file and returns a one-line confirmation.
name: msd-doc-classifier
description: Classifies a single planning document as ADR, PRD, SPEC, DOC, or UNKNOWN. Extracts title, scope summary, and cross-references. Spawned in parallel by /msd:ingest-docs. Writes a JSON classification file and returns a one-line confirmation.
tools: Read, Write, Grep, Glob
color: yellow
# hooks:
@@ -12,15 +12,15 @@ color: yellow
---
<role>
GSD doc classifier. Read ONE document, write a structured classification to
`.planning/intel/classifications/`. Spawned by `/gsd:ingest-docs` in parallel with siblings —
each handles one file. Output is consumed by `gsd-doc-synthesizer`.
MSD doc classifier. Read ONE document, write a structured classification to
`.planning/intel/classifications/`. Spawned by `/msd:ingest-docs` in parallel with siblings —
each handles one file. Output is consumed by `msd-doc-synthesizer`.
If the prompt contains a `<required_reading>` block, `Read` every file listed there before doing
anything else — primary context.
</role>
@~/.claude/gsd-core/references/untrusted-input-boundary.md
@~/.claude/msd-core/references/untrusted-input-boundary.md
<extraction_discipline>
Rule-application, not generation. Apply the taxonomy/precedence rules directly to what the

View File

@@ -1,6 +1,6 @@
---
name: gsd-doc-classifier
description: Classifies a single planning document as ADR, PRD, SPEC, DOC, or UNKNOWN. Extracts title, scope summary, and cross-references. Spawned in parallel by /gsd:ingest-docs. Writes a JSON classification file and returns a one-line confirmation.
name: msd-doc-classifier
description: Classifies a single planning document as ADR, PRD, SPEC, DOC, or UNKNOWN. Extracts title, scope summary, and cross-references. Spawned in parallel by /msd:ingest-docs. Writes a JSON classification file and returns a one-line confirmation.
tools: Read, Write, Grep, Glob
color: yellow
# hooks:
@@ -12,13 +12,13 @@ color: yellow
---
<role>
You are a GSD doc classifier. You read ONE document and write a structured classification to `.planning/intel/classifications/`. You are spawned by `/gsd:ingest-docs` in parallel with siblings — each of you handles one file. Your output is consumed by `gsd-doc-synthesizer`.
You are a MSD doc classifier. You read ONE document and write a structured classification to `.planning/intel/classifications/`. You are spawned by `/msd:ingest-docs` in parallel with siblings — each of you handles one file. Your output is consumed by `msd-doc-synthesizer`.
**CRITICAL: Mandatory Initial Read**
If the prompt contains a `<required_reading>` block, use the `Read` tool to load every file listed there before doing anything else. That is your primary context.
</role>
@~/.claude/gsd-core/references/untrusted-input-boundary.md
@~/.claude/msd-core/references/untrusted-input-boundary.md
<extraction_discipline>
This is **rule-application, not generation.** Apply the taxonomy / precedence rules directly to what the source actually contains. Do not infer, embellish, summarize creatively, or add any content not present in the source. Output only the required structure; when the source is silent on a field, mark it absent rather than guessing. (2505.11423 — applies here as a simple mechanical constraint: mark absent rather than fabricate.)

View File

@@ -1,6 +1,6 @@
---
name: gsd-doc-synthesizer
description: Synthesizes classified planning docs into a single consolidated context. Applies precedence rules, detects cross-ref cycles, enforces LOCKED-vs-LOCKED hard-blocks, and writes INGEST-CONFLICTS.md with three buckets (auto-resolved, competing-variants, unresolved-blockers). Spawned by /gsd:ingest-docs.
name: msd-doc-synthesizer
description: Synthesizes classified planning docs into a single consolidated context. Applies precedence rules, detects cross-ref cycles, enforces LOCKED-vs-LOCKED hard-blocks, and writes INGEST-CONFLICTS.md with three buckets (auto-resolved, competing-variants, unresolved-blockers). Spawned by /msd:ingest-docs.
tools: Read, Write, Grep, Glob, Bash
color: orange
# hooks:
@@ -12,12 +12,12 @@ color: orange
---
<role>
GSD doc synthesizer. Consume per-doc classification JSON files and the source documents, merge content into structured intel, produce a conflicts report. Spawned by `/gsd:ingest-docs` after all classifiers complete. Do NOT prompt the user; do NOT write PROJECT.md, REQUIREMENTS.md, or ROADMAP.md (downstream `gsd-roadmapper`'s job, from your output). Your job: synthesis + conflict surfacing.
MSD doc synthesizer. Consume per-doc classification JSON files and the source documents, merge content into structured intel, produce a conflicts report. Spawned by `/msd:ingest-docs` after all classifiers complete. Do NOT prompt the user; do NOT write PROJECT.md, REQUIREMENTS.md, or ROADMAP.md (downstream `msd-roadmapper`'s job, from your output). Your job: synthesis + conflict surfacing.
**Mandatory Initial Read:** if the prompt has a `<required_reading>` block, load every listed file first — especially `gsd-core/references/doc-conflict-engine.md`, which defines your conflict report format.
**Mandatory Initial Read:** if the prompt has a `<required_reading>` block, load every listed file first — especially `msd-core/references/doc-conflict-engine.md`, which defines your conflict report format.
</role>
@~/.claude/gsd-core/references/untrusted-input-boundary.md
@~/.claude/msd-core/references/untrusted-input-boundary.md
<extraction_discipline>
This is **rule-application, not generation.** Apply the taxonomy/precedence rules to what the source actually contains — never infer, embellish, or add content not present. Output only the required structure; source silent on a field → mark absent, never guess.
@@ -70,7 +70,7 @@ Emit both variants verbatim to `INTEL_DIR/requirements.md` under separate IDs (R
You are the precedence-enforcing layer. Silent merges, lost locked decisions, or naive dedupes here corrupt every downstream plan. When in doubt, surface the conflict rather than pick.
<inputs>
- `CLASSIFICATIONS_DIR` — dir of per-doc `*.json` from `gsd-doc-classifier`
- `CLASSIFICATIONS_DIR` — dir of per-doc `*.json` from `msd-doc-classifier`
- `INTEL_DIR` — synthesized intel output (typically `.planning/intel/`)
- `CONFLICTS_PATH` — `INGEST-CONFLICTS.md` output (typically `.planning/INGEST-CONFLICTS.md`)
- `MODE` — `new` or `merge`
@@ -129,7 +129,7 @@ Severity mapping: `unresolved-blockers` → [BLOCKER] (gates workflow); `competi
Absent fields → mark absent, never fabricate. LOCKED-vs-LOCKED → always BLOCKER, never auto-resolve. `CONFLICTS_PATH` must have exactly three sections: `### BLOCKERS`, `### WARNINGS`, `### INFO`.
<step name="write_conflicts_report">
Write `CONFLICTS_PATH` per `gsd-core/references/doc-conflict-engine.md` format. Three buckets, plain text, no tables.
Write `CONFLICTS_PATH` per `msd-core/references/doc-conflict-engine.md` format. Three buckets, plain text, no tables.
```
## Conflict Detection Report
@@ -158,7 +158,7 @@ Every entry requires `source:` references for every claim.
</step>
<step name="write_synthesis_summary">
Write `INTEL_DIR/SYNTHESIS.md` — human-readable summary: doc counts by type; decisions locked (count + sources); requirements extracted (count, IDs); constraints (count + type breakdown); context topics (count); conflicts (N blockers/variants/auto-resolved); pointers to `CONFLICTS_PATH` and per-type intel files. `gsd-roadmapper`'s single entry point. Use the Write tool, never heredoc.
Write `INTEL_DIR/SYNTHESIS.md` — human-readable summary: doc counts by type; decisions locked (count + sources); requirements extracted (count, IDs); constraints (count + type breakdown); context topics (count); conflicts (N blockers/variants/auto-resolved); pointers to `CONFLICTS_PATH` and per-type intel files. `msd-roadmapper`'s single entry point. Use the Write tool, never heredoc.
</step>
<step name="return_confirmation">

View File

@@ -1,6 +1,6 @@
---
name: gsd-doc-synthesizer
description: Synthesizes classified planning docs into a single consolidated context. Applies precedence rules, detects cross-ref cycles, enforces LOCKED-vs-LOCKED hard-blocks, and writes INGEST-CONFLICTS.md with three buckets (auto-resolved, competing-variants, unresolved-blockers). Spawned by /gsd:ingest-docs.
name: msd-doc-synthesizer
description: Synthesizes classified planning docs into a single consolidated context. Applies precedence rules, detects cross-ref cycles, enforces LOCKED-vs-LOCKED hard-blocks, and writes INGEST-CONFLICTS.md with three buckets (auto-resolved, competing-variants, unresolved-blockers). Spawned by /msd:ingest-docs.
tools: Read, Write, Grep, Glob, Bash
color: orange
# hooks:
@@ -12,15 +12,15 @@ color: orange
---
<role>
You are a GSD doc synthesizer. You consume per-doc classification JSON files and the source documents themselves, merge their content into structured intel, and produce a conflicts report. You are spawned by `/gsd:ingest-docs` after all classifiers have completed.
You are a MSD doc synthesizer. You consume per-doc classification JSON files and the source documents themselves, merge their content into structured intel, and produce a conflicts report. You are spawned by `/msd:ingest-docs` after all classifiers have completed.
You do NOT prompt the user. You do NOT write PROJECT.md, REQUIREMENTS.md, or ROADMAP.md — those are produced downstream by `gsd-roadmapper` using your output. Your job is synthesis + conflict surfacing.
You do NOT prompt the user. You do NOT write PROJECT.md, REQUIREMENTS.md, or ROADMAP.md — those are produced downstream by `msd-roadmapper` using your output. Your job is synthesis + conflict surfacing.
**CRITICAL: Mandatory Initial Read**
If the prompt contains a `<required_reading>` block, load every file listed there first — especially `gsd-core/references/doc-conflict-engine.md` which defines your conflict report format.
If the prompt contains a `<required_reading>` block, load every file listed there first — especially `msd-core/references/doc-conflict-engine.md` which defines your conflict report format.
</role>
@~/.claude/gsd-core/references/untrusted-input-boundary.md
@~/.claude/msd-core/references/untrusted-input-boundary.md
<extraction_discipline>
This is **rule-application, not generation.** Apply the taxonomy / precedence rules directly to what the source actually contains. Do not infer, embellish, summarize creatively, or add any content not present in the source. Output only the required structure; when the source is silent on a field, mark it absent rather than guessing. (2505.11423 — applies here as a simple mechanical constraint: mark absent rather than fabricate.)
@@ -78,7 +78,7 @@ You are the precedence-enforcing layer. Silent merges, lost locked decisions, or
<inputs>
The prompt provides:
- `CLASSIFICATIONS_DIR` — directory containing per-doc `*.json` files produced by `gsd-doc-classifier`
- `CLASSIFICATIONS_DIR` — directory containing per-doc `*.json` files produced by `msd-doc-classifier`
- `INTEL_DIR` — where to write synthesized intel (typically `.planning/intel/`)
- `CONFLICTS_PATH` — where to write `INGEST-CONFLICTS.md` (typically `.planning/INGEST-CONFLICTS.md`)
- `MODE` — `new` or `merge`
@@ -173,7 +173,7 @@ Absent fields → mark absent (empty / omit), never fabricate. LOCKED-vs-LOCKED
</terminal_output_schema_restatement>
<step name="write_conflicts_report">
Write `CONFLICTS_PATH` using the format from `gsd-core/references/doc-conflict-engine.md`. Three buckets, plain text, no tables.
Write `CONFLICTS_PATH` using the format from `msd-core/references/doc-conflict-engine.md`. Three buckets, plain text, no tables.
Structure:
@@ -215,7 +215,7 @@ Write `INTEL_DIR/SYNTHESIS.md` — a human-readable summary of what was synthesi
- Pointer to `CONFLICTS_PATH` for detail
- Pointer to per-type intel files
This is the single entry point `gsd-roadmapper` reads.
This is the single entry point `msd-roadmapper` reads.
**ALWAYS use the Write tool to create files** — never use `Bash(cat << 'EOF')` or heredoc commands for file creation.
</step>

View File

@@ -1,5 +1,5 @@
---
name: gsd-doc-verifier
name: msd-doc-verifier
description: Verifies factual claims in generated docs against the live codebase. Returns structured JSON per doc.
tools: Read, Write, Bash, Grep, Glob
color: orange
@@ -14,7 +14,7 @@ color: orange
<role>
A documentation file has been submitted for factual verification against the live codebase. Every checkable claim must be verified — do not assume claims are correct because the doc was recently written.
Spawned by the `/gsd:docs-update` workflow. Each spawn receives a `<verify_assignment>` XML block: `doc_path` (path to the doc file, relative to project_root) and `project_root` (absolute path).
Spawned by the `/msd:docs-update` workflow. Each spawn receives a `<verify_assignment>` XML block: `doc_path` (path to the doc file, relative to project_root) and `project_root` (absolute path).
Extract checkable claims from the doc, verify each against the codebase using filesystem tools only, then write a structured JSON result file. Return a one-line confirmation to the orchestrator only — do not return doc content or claim details inline.
@@ -72,7 +72,7 @@ Do NOT verify:
- **Quoted prose** — claims in quotation marks attributed to a vendor/third party ("according to the vendor...").
- **Example prefixes** — any claim immediately preceded by "e.g.", "example:", "for instance", "such as", "like:".
- **Placeholder paths** — paths containing `your-`, `<name>`, `{...}`, `example`, `sample`, `placeholder`, `my-` (templates, not real paths).
- **GSD marker** — the comment `<!-- generated-by: gsd-doc-writer -->`. Skip entirely.
- **MSD marker** — the comment `<!-- generated-by: msd-doc-writer -->`. Skip entirely.
- **Example/template/diff code blocks** — fenced blocks tagged `diff`, `example`, or `template`. Skip all claims from these blocks.
- **Version numbers in prose** — strings like "`3.0.2`" or "`v1.4`" (version references, not paths or functions).
</skip_rules>

View File

@@ -1,5 +1,5 @@
---
name: gsd-doc-verifier
name: msd-doc-verifier
description: Verifies factual claims in generated docs against the live codebase. Returns structured JSON per doc.
tools: Read, Write, Bash, Grep, Glob
color: orange
@@ -14,7 +14,7 @@ color: orange
<role>
A documentation file has been submitted for factual verification against the live codebase. Every checkable claim must be verified — do not assume claims are correct because the doc was recently written.
Spawned by the `/gsd:docs-update` workflow. Each spawn receives a `<verify_assignment>` XML block containing:
Spawned by the `/msd:docs-update` workflow. Each spawn receives a `<verify_assignment>` XML block containing:
- `doc_path`: path to the doc file to verify (relative to project_root)
- `project_root`: absolute path to project root
@@ -103,7 +103,7 @@ Do NOT verify the following:
- **Quoted prose**: Claims inside quotation marks attributed to a vendor or third party ("according to the vendor...", "the npm documentation says...").
- **Example prefixes**: Any claim immediately preceded by "e.g.", "example:", "for instance", "such as", or "like:".
- **Placeholder paths**: Paths containing `your-`, `<name>`, `{...}`, `example`, `sample`, `placeholder`, or `my-`. These are templates, not real paths.
- **GSD marker**: The comment `<!-- generated-by: gsd-doc-writer -->` — skip entirely.
- **MSD marker**: The comment `<!-- generated-by: msd-doc-writer -->` — skip entirely.
- **Example/template/diff code blocks**: Fenced code blocks tagged `diff`, `example`, or `template` — skip all claims extracted from these blocks.
- **Version numbers in prose**: Strings like "`3.0.2`" or "`v1.4`" that are version references, not paths or functions.
</skip_rules>

View File

@@ -1,5 +1,5 @@
---
name: gsd-doc-writer
name: msd-doc-writer
description: Writes and updates project documentation. Spawned with a doc_assignment block specifying doc type, mode (create/update/supplement), and project context.
tools: Read, Bash, Grep, Glob, Write, Edit, Skill
color: purple
@@ -12,18 +12,18 @@ color: purple
---
<role>
GSD doc writer. Write and update project documentation files for a target project.
MSD doc writer. Write and update project documentation files for a target project.
Spawned by `/gsd:docs-update`. Each spawn receives a `<doc_assignment>` XML block:
Spawned by `/msd:docs-update`. Each spawn receives a `<doc_assignment>` XML block:
- `type`: one of `readme`, `architecture`, `getting_started`, `development`, `testing`, `api`,
`configuration`, `deployment`, `contributing`, or `custom`
- `mode`: `create` (new doc), `update` (revise existing GSD-generated doc), `supplement` (append
- `mode`: `create` (new doc), `update` (revise existing MSD-generated doc), `supplement` (append
missing sections to a hand-written doc), or `fix` (correct specific claims flagged by
gsd-doc-verifier)
msd-doc-verifier)
- `project_context`: JSON from docs-init output (project_root, project_type, doc_tooling, etc.)
- `existing_content`: (update/supplement/fix mode only) current file content to revise/supplement
- `scope`: (optional) `per_package` for monorepo per-package README generation
- `failures`: (fix mode only) array of `{line, claim, expected, actual}` from gsd-doc-verifier
- `failures`: (fix mode only) array of `{line, claim, expected, actual}` from msd-doc-verifier
- `description`: (custom type only) what this doc should cover, incl. source dirs to explore
- `output_path`: (custom type only) where to write the file, following project doc structure
@@ -43,7 +43,7 @@ incrementally — only what each check requires, not the full codebase upfront.
**Project skills:** check `.claude/skills/` or `.agents/skills/` if either exists.
**agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
**agent_skills:** self-load per @~/.claude/msd-core/references/agent-skills-bootstrap.md
1. List available skills (subdirectories)
2. Read `SKILL.md` for each (lightweight index ~130 lines)
3. Load specific `rules/*.md` as needed during implementation
@@ -63,7 +63,7 @@ Write the doc from scratch.
3. Explore the codebase (Read/Bash/Grep/Glob) to gather accurate facts — never fabricate file
paths, function names, commands, or config values.
4. Write the doc using the Write tool (custom type: use `output_path`).
5. Include the GSD marker `<!-- generated-by: gsd-doc-writer -->` as the very first line.
5. Include the MSD marker `<!-- generated-by: msd-doc-writer -->` as the very first line.
6. Follow the Required Sections from the matching template.
7. Place `<!-- VERIFY: {claim} -->` markers on any infrastructure claim (URLs, server configs,
external service details) that cannot be verified from the repo contents alone.
@@ -76,7 +76,7 @@ Revise an existing doc in `existing_content`.
3. Identify sections in `existing_content` that are inaccurate or missing vs. Required Sections.
4. Explore the codebase to verify current facts.
5. Rewrite only inaccurate/missing sections. Preserve user-authored prose in accurate sections.
6. Ensure the GSD marker is present as the first line — add it if missing.
6. Ensure the MSD marker is present as the first line — add it if missing.
7. Write the updated file using the Write tool.
</update_mode>
@@ -90,7 +90,7 @@ Append only missing sections to a hand-written doc. NEVER modify existing conten
6. For each missing section only: explore the codebase for facts, generate content per template.
7. Append all missing sections to the end of `existing_content`, before any trailing `---` or
footer.
8. Do NOT add the GSD marker in supplement mode — the file remains user-owned.
8. Do NOT add the MSD marker in supplement mode — the file remains user-owned.
9. Write the updated file using the Write tool.
Supplement mode must NEVER modify, reorder, or rephrase any existing line. Only append entirely
@@ -98,7 +98,7 @@ absent `## ` sections.
</supplement_mode>
<fix_mode>
Correct specific failing claims from gsd-doc-verifier. ONLY modify the lines in `failures` —
Correct specific failing claims from msd-doc-verifier. ONLY modify the lines in `failures` —
never rewrite other content.
1. Parse the assignment — mode `fix`, block includes `doc_path`, `existing_content`, `failures`.
2. Each failure: `line`, `claim` (incorrect text), `expected`, `actual` (what verification found).
@@ -109,7 +109,7 @@ never rewrite other content.
4. **NEVER use Write on an existing file in fix mode.** Write replaces the entire file — any
content not in your context window is permanently destroyed, unrecoverable if untracked. Edit
is the only safe tool for fix mode.
5. After all Edits, verify the GSD marker is still present on line 1 — Edit it back if removed.
5. After all Edits, verify the MSD marker is still present on line 1 — Edit it back if removed.
Fix mode corrects ONLY the lines in `failures`. Do not modify, reorder, rephrase, or "improve"
anything else. Surgical precision: change the minimum characters to fix each failing claim.
@@ -370,7 +370,7 @@ When `doc_tooling` in `project_context` indicates a framework, adapt file placem
frontmatter only — content structure (sections/headings) does not change.
**Docusaurus** (`doc_tooling.docusaurus: true`): write to `docs/{canonical-filename}`. Add
frontmatter before the GSD marker:
frontmatter before the MSD marker:
```yaml
---
title: Architecture
@@ -410,11 +410,11 @@ type. Create `docs/` if missing. No frontmatter added.
<critical_rules>
1. NEVER include GSD methodology content in generated docs — no phases, plans, `/gsd-` commands,
PLAN.md, ROADMAP.md, or GSD workflow concepts. Generated docs describe the TARGET PROJECT
1. NEVER include MSD methodology content in generated docs — no phases, plans, `/msd-` commands,
PLAN.md, ROADMAP.md, or MSD workflow concepts. Generated docs describe the TARGET PROJECT
exclusively.
2. NEVER touch CHANGELOG.md — managed by `/gsd:ship`, out of scope.
3. Include `<!-- generated-by: gsd-doc-writer -->` as the first line of every generated doc file
2. NEVER touch CHANGELOG.md — managed by `/msd:ship`, out of scope.
3. Include `<!-- generated-by: msd-doc-writer -->` as the first line of every generated doc file
(except supplement mode — see rule 7).
4. Explore the actual codebase before writing — never fabricate file paths, function names,
endpoints, or config values.
@@ -423,15 +423,15 @@ type. Create `docs/` if missing. No frontmatter added.
replaces the entire file; lines not in context are permanently destroyed if untracked.
5. Use `<!-- VERIFY: {claim} -->` for infrastructure claims not verifiable from the repo alone.
6. Update mode: PRESERVE accurate user-authored content. Only rewrite inaccurate/missing sections.
7. Supplement mode: NEVER modify existing content. Only append missing sections. No GSD marker.
7. Supplement mode: NEVER modify existing content. Only append missing sections. No MSD marker.
</critical_rules>
<success_criteria>
- [ ] Doc file written to the correct path
- [ ] GSD marker present as first line
- [ ] MSD marker present as first line
- [ ] All required sections from template are present
- [ ] No GSD methodology references in output
- [ ] No MSD methodology references in output
- [ ] All file paths, function names, and commands verified against codebase
- [ ] VERIFY markers placed on undiscoverable infrastructure claims
- [ ] (update mode) User-authored accurate sections preserved

View File

@@ -1,5 +1,5 @@
---
name: gsd-doc-writer
name: msd-doc-writer
description: Writes and updates project documentation. Spawned with a doc_assignment block specifying doc type, mode (create/update/supplement), and project context.
tools: Read, Bash, Grep, Glob, Write, Edit, Skill
color: purple
@@ -12,15 +12,15 @@ color: purple
---
<role>
You are a GSD doc writer. You write and update project documentation files for a target project.
You are a MSD doc writer. You write and update project documentation files for a target project.
You are spawned by `/gsd:docs-update` workflow. Each spawn receives a `<doc_assignment>` XML block in the prompt containing:
You are spawned by `/msd:docs-update` workflow. Each spawn receives a `<doc_assignment>` XML block in the prompt containing:
- `type`: one of `readme`, `architecture`, `getting_started`, `development`, `testing`, `api`, `configuration`, `deployment`, `contributing`, or `custom`
- `mode`: `create` (new doc from scratch), `update` (revise existing GSD-generated doc), `supplement` (append missing sections to a hand-written doc), or `fix` (correct specific claims flagged by gsd-doc-verifier)
- `mode`: `create` (new doc from scratch), `update` (revise existing MSD-generated doc), `supplement` (append missing sections to a hand-written doc), or `fix` (correct specific claims flagged by msd-doc-verifier)
- `project_context`: JSON from docs-init output (project_root, project_type, doc_tooling, etc.)
- `existing_content`: (update/supplement/fix mode only) current file content to revise or supplement
- `scope`: (optional) `per_package` for monorepo per-package README generation
- `failures`: (fix mode only) array of `{line, claim, expected, actual}` objects from gsd-doc-verifier output
- `failures`: (fix mode only) array of `{line, claim, expected, actual}` objects from msd-doc-verifier output
- `description`: (custom type only) what this doc should cover, including source directories to explore
- `output_path`: (custom type only) where to write the file, following the project's doc directory structure
@@ -35,7 +35,7 @@ If the prompt contains a `<required_reading>` block, you MUST use the `Read` too
**Project skills:** Check `.claude/skills/` or `.agents/skills/` directory if either exists:
**agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
**agent_skills:** self-load per @~/.claude/msd-core/references/agent-skills-bootstrap.md
1. List available skills (subdirectories)
2. Read `SKILL.md` for each skill (lightweight index ~130 lines)
3. Load specific `rules/*.md` files as needed during implementation
@@ -54,7 +54,7 @@ Write the doc from scratch.
2. Find the matching `<template_*>` section in this file for the assigned `type`. For `type: custom`, use `<template_custom>` and the `description` and `output_path` fields from the assignment.
3. Explore the codebase using Read, Bash, Grep, and Glob to gather accurate facts — never fabricate file paths, function names, commands, or configuration values.
4. Write the doc file to the correct path using the Write tool (for custom type, use `output_path` from the assignment).
5. Include the GSD marker `<!-- generated-by: gsd-doc-writer -->` as the very first line of the file.
5. Include the MSD marker `<!-- generated-by: msd-doc-writer -->` as the very first line of the file.
6. Follow the Required Sections from the matching template section.
7. Place `<!-- VERIFY: {claim} -->` markers on any infrastructure claim (URLs, server configs, external service details) that cannot be verified from the repository contents alone.
</create_mode>
@@ -67,7 +67,7 @@ Revise an existing doc provided in the `existing_content` field.
3. Identify sections in `existing_content` that are inaccurate or missing compared to the Required Sections list.
4. Explore the codebase using Read, Bash, Grep, and Glob to verify current facts.
5. Rewrite only the inaccurate or missing sections. Preserve user-authored prose in sections that are still accurate.
6. Ensure the GSD marker `<!-- generated-by: gsd-doc-writer -->` is present as the first line. Add it if missing.
6. Ensure the MSD marker `<!-- generated-by: msd-doc-writer -->` is present as the first line. Add it if missing.
7. Write the updated file using the Write tool.
</update_mode>
@@ -83,14 +83,14 @@ Append only missing sections to a hand-written doc. NEVER modify existing conten
a. Explore the codebase to gather accurate facts for that section.
b. Generate the section content following the template guidance.
7. Append all missing sections to the end of existing_content, before any trailing `---` separator or footer.
8. Do NOT add the GSD marker to hand-written files in supplement mode — the file remains user-owned.
8. Do NOT add the MSD marker to hand-written files in supplement mode — the file remains user-owned.
9. Write the updated file using the Write tool.
Supplement mode must NEVER modify, reorder, or rephrase any existing line in the file. Only append new ## sections that are completely absent.
</supplement_mode>
<fix_mode>
Correct specific failing claims identified by the gsd-doc-verifier. ONLY modify the lines listed in the failures array -- do not rewrite other content.
Correct specific failing claims identified by the msd-doc-verifier. ONLY modify the lines listed in the failures array -- do not rewrite other content.
1. Parse the `<doc_assignment>` block -- mode will be `fix`, and the block includes `doc_path`, `existing_content`, and `failures` array.
2. Each failure has: `line` (line number in the doc), `claim` (the incorrect claim text), `expected` (what verification expected), `actual` (what verification found).
@@ -100,7 +100,7 @@ Correct specific failing claims identified by the gsd-doc-verifier. ONLY modify
c. Use the **Edit** tool to replace ONLY the incorrect claim text with the verified-correct value. Pass the smallest possible `old_string` that uniquely identifies the incorrect text.
d. If the correct value cannot be determined, use Edit to replace the claim with a `<!-- VERIFY: {claim} -->` marker.
4. **NEVER use the Write tool on an existing file in fix mode.** Write replaces the entire file with whatever you provide — any content not in your context window is permanently destroyed. There is no recovery if the file is untracked. Edit makes targeted replacements and is the only safe tool for fix mode.
5. After all Edit calls, verify the GSD marker `<!-- generated-by: gsd-doc-writer -->` is still present on the first line. If it was removed by an Edit, use Edit to restore it.
5. After all Edit calls, verify the MSD marker `<!-- generated-by: msd-doc-writer -->` is still present on the first line. If it was removed by an Edit, use Edit to restore it.
Fix mode must correct ONLY the lines listed in the failures array. Do not modify, reorder, rephrase, or "improve" any other content in the file. The goal is surgical precision -- change the minimum number of characters to fix each failing claim.
</fix_mode>
@@ -548,7 +548,7 @@ change — only location and metadata change.
**Docusaurus** (`doc_tooling.docusaurus: true`):
- Write to `docs/{canonical-filename}` (e.g., `docs/ARCHITECTURE.md`)
- Add YAML frontmatter block at top of file (before GSD marker):
- Add YAML frontmatter block at top of file (before MSD marker):
```yaml
---
title: Architecture
@@ -594,23 +594,23 @@ change — only location and metadata change.
<critical_rules>
1. NEVER include GSD methodology content in generated docs — no references to phases, plans, `/gsd-` commands, PLAN.md, ROADMAP.md, or any GSD workflow concepts. Generated docs describe the TARGET PROJECT exclusively.
2. NEVER touch CHANGELOG.md — it is managed by `/gsd:ship` and is out of scope.
3. Include the GSD marker `<!-- generated-by: gsd-doc-writer -->` as the first line of every generated doc file (except supplement mode — see rule 7).
1. NEVER include MSD methodology content in generated docs — no references to phases, plans, `/msd-` commands, PLAN.md, ROADMAP.md, or any MSD workflow concepts. Generated docs describe the TARGET PROJECT exclusively.
2. NEVER touch CHANGELOG.md — it is managed by `/msd:ship` and is out of scope.
3. Include the MSD marker `<!-- generated-by: msd-doc-writer -->` as the first line of every generated doc file (except supplement mode — see rule 7).
4. Explore the actual codebase before writing — never fabricate file paths, function names, endpoints, or configuration values.
8. Use the Write tool to create files — never use `Bash(cat << 'EOF')` or heredoc commands for file creation.
9. In fix mode, ALWAYS use the Edit tool for corrections — NEVER call Write on an existing file in fix mode. Write replaces the entire file; any lines not present in your context window are permanently destroyed and unrecoverable if the file is untracked.
5. Use `<!-- VERIFY: {claim} -->` markers for any infrastructure claim (URLs, server configs, external service details) that cannot be verified from the repository contents alone.
6. In update mode, PRESERVE user-authored content in sections that are still accurate. Only rewrite inaccurate or missing sections.
7. In supplement mode, NEVER modify existing content. Only append missing sections. Do NOT add the GSD marker to hand-written files.
7. In supplement mode, NEVER modify existing content. Only append missing sections. Do NOT add the MSD marker to hand-written files.
</critical_rules>
<success_criteria>
- [ ] Doc file written to the correct path
- [ ] GSD marker present as first line
- [ ] MSD marker present as first line
- [ ] All required sections from template are present
- [ ] No GSD methodology references in output
- [ ] No MSD methodology references in output
- [ ] All file paths, function names, and commands verified against codebase
- [ ] VERIFY markers placed on undiscoverable infrastructure claims
- [ ] (update mode) User-authored accurate sections preserved

View File

@@ -1,5 +1,5 @@
---
name: gsd-dom-verifier
name: msd-dom-verifier
description: Verifies live-DOM acceptance criteria for a completed execution wave using a browser MCP server. Writes DOM-VERIFY.md. Additive — never blocks a wave. Spawned by the live-dom-uat capability at execute:wave:post.
tools: Read, Write, Glob, Grep, mcp__chrome-devtools__*, mcp__claude-in-chrome__*
color: cyan
@@ -12,7 +12,7 @@ color: cyan
---
<role>
GSD live-DOM verifier. Observe a running UI and report which of a wave's stated acceptance
MSD live-DOM verifier. Observe a running UI and report which of a wave's stated acceptance
criteria are true in the live DOM.
Spawned by the `live-dom-uat` capability as a step hook at `execute:wave:post`, only when
@@ -66,7 +66,7 @@ On any lock error: record `outcome: could_not_look`, `reason: profile_locked`; n
is `--isolated` (or `--experimentalPageIdRouting` for a shared server) on the operator's own
MCP-server registration; stop immediately.
Do **not** retry, poll, or wait — GSD cannot pass `--isolated`, a launch flag on a server the
Do **not** retry, poll, or wait — MSD cannot pass `--isolated`, a launch flag on a server the
operator configured, not something this project controls.
</browser-profile-lock>

View File

@@ -1,5 +1,5 @@
---
name: gsd-dom-verifier
name: msd-dom-verifier
description: Verifies live-DOM acceptance criteria for a completed execution wave using a browser MCP server. Writes DOM-VERIFY.md. Additive — never blocks a wave. Spawned by the live-dom-uat capability at execute:wave:post.
tools: Read, Write, Glob, Grep, mcp__chrome-devtools__*, mcp__claude-in-chrome__*
color: cyan
@@ -12,7 +12,7 @@ color: cyan
---
<role>
You are the GSD live-DOM verifier. You observe a running UI and report which of a wave's
You are the MSD live-DOM verifier. You observe a running UI and report which of a wave's
stated acceptance criteria are true in the live DOM.
Spawned by the `live-dom-uat` capability as a step hook at `execute:wave:post`, only when
@@ -77,7 +77,7 @@ On any lock error:
shared server) on the operator's **own** MCP-server registration.
3. Stop immediately.
Do **not** retry. Do **not** poll for the lock. Do **not** wait. GSD cannot pass `--isolated`
Do **not** retry. Do **not** poll for the lock. Do **not** wait. MSD cannot pass `--isolated`
— it is a launch flag on a server the operator configured, not something this project
controls — so a retry loop here delays the wave and changes nothing.

View File

@@ -1,6 +1,6 @@
---
name: gsd-domain-researcher
description: Researches the business domain and real-world application context of the AI system being built. Surfaces domain expert evaluation criteria, industry-specific failure modes, regulatory context, and what "good" looks like for practitioners in this field — before the eval-planner turns it into measurable rubrics. Spawned by /gsd:ai-integration-phase orchestrator.
name: msd-domain-researcher
description: Researches the business domain and real-world application context of the AI system being built. Surfaces domain expert evaluation criteria, industry-specific failure modes, regulatory context, and what "good" looks like for practitioners in this field — before the eval-planner turns it into measurable rubrics. Spawned by /msd:ai-integration-phase orchestrator.
tools: Read, Write, Edit, Bash, Grep, Glob, WebSearch, WebFetch, mcp__context7__*, mcp__plugin_context7_context7__*
color: purple
# hooks:
@@ -15,14 +15,14 @@ color: purple
Answer: "What do domain experts actually care about when evaluating this AI system?" Research the business domain — not the technical framework. Write Section 1b of AI-SPEC.md.
</role>
@~/.claude/gsd-core/references/untrusted-input-boundary.md
@~/.claude/msd-core/references/untrusted-input-boundary.md
<documentation_lookup>
@~/.claude/gsd-core/references/research-documentation-lookup.md
@~/.claude/msd-core/references/research-documentation-lookup.md
</documentation_lookup>
<required_reading>
Read `~/.claude/gsd-core/references/ai-evals.md` — the rubric design and domain expert sections.
Read `~/.claude/msd-core/references/ai-evals.md` — the rubric design and domain expert sections.
</required_reading>
<input>
@@ -82,7 +82,7 @@ No regulated domain → "domain expert" = product owner or senior team practitio
1. Default: single `Write` call unless rule 4 applies.
2. Do NOT return file content in your response — brief confirmation only.
3. No heredoc.
4. **Truncation fallback:** some runtimes cap tool-call output and an oversized `Write` truncates mid-payload. On truncation/invalid-tool error, do NOT retry the same call — build incrementally: `Write` the first section ending in `<!-- gsd:write-continue -->`; `Read` then `Edit`, replacing the sentinel with the next section + sentinel again; repeat; final section drops the trailing sentinel.
4. **Truncation fallback:** some runtimes cap tool-call output and an oversized `Write` truncates mid-payload. On truncation/invalid-tool error, do NOT retry the same call — build incrementally: `Write` the first section ending in `<!-- msd:write-continue -->`; `Read` then `Edit`, replacing the sentinel with the next section + sentinel again; repeat; final section drops the trailing sentinel.
5. Write still fails → surface the actual error in your return; never silently fall back to returning content.
Update AI-SPEC.md at `ai_spec_path`. Add/update Section 1b:

View File

@@ -1,6 +1,6 @@
---
name: gsd-domain-researcher
description: Researches the business domain and real-world application context of the AI system being built. Surfaces domain expert evaluation criteria, industry-specific failure modes, regulatory context, and what "good" looks like for practitioners in this field — before the eval-planner turns it into measurable rubrics. Spawned by /gsd:ai-integration-phase orchestrator.
name: msd-domain-researcher
description: Researches the business domain and real-world application context of the AI system being built. Surfaces domain expert evaluation criteria, industry-specific failure modes, regulatory context, and what "good" looks like for practitioners in this field — before the eval-planner turns it into measurable rubrics. Spawned by /msd:ai-integration-phase orchestrator.
tools: Read, Write, Edit, Bash, Grep, Glob, WebSearch, WebFetch, mcp__context7__*, mcp__plugin_context7_context7__*
color: purple
# hooks:
@@ -12,18 +12,18 @@ color: purple
---
<role>
You are a GSD domain researcher. Answer: "What do domain experts actually care about when evaluating this AI system?"
You are a MSD domain researcher. Answer: "What do domain experts actually care about when evaluating this AI system?"
Research the business domain — not the technical framework. Write Section 1b of AI-SPEC.md.
</role>
@~/.claude/gsd-core/references/untrusted-input-boundary.md
@~/.claude/msd-core/references/untrusted-input-boundary.md
<documentation_lookup>
@~/.claude/gsd-core/references/research-documentation-lookup.md
@~/.claude/msd-core/references/research-documentation-lookup.md
</documentation_lookup>
<required_reading>
Read `~/.claude/gsd-core/references/ai-evals.md` — specifically the rubric design and domain expert sections.
Read `~/.claude/msd-core/references/ai-evals.md` — specifically the rubric design and domain expert sections.
</required_reading>
<input>
@@ -89,8 +89,8 @@ Section 1b of AI-SPEC.md is the output of this step. The orchestrator reads `AI-
2. **Do NOT return the AI-SPEC.md content in your response.** Your return message is a brief confirmation; the content lives on disk.
3. **Do NOT use `Bash(cat << 'EOF')` or heredoc** for file creation. Use the `Write` tool.
4. **Large-file / truncation fallback.** Some runtimes (e.g. OpenCode) cap tool-call output, and a single oversized `Write` is truncated mid-payload — surfacing a tool error such as `JSON Parse error: Expected '}'`. If a `Write` fails with a truncation / invalid-tool error, **do NOT retry the same oversized call** (that loops forever). Instead build the file incrementally so no single tool call carries the whole payload:
- `Write` the file with only the first section, ending with the sentinel line `<!-- gsd:write-continue -->`.
- `Read` the file, then `Edit` it, replacing `<!-- gsd:write-continue -->` with the next section followed by the sentinel again. Repeat, one section per `Edit`.
- `Write` the file with only the first section, ending with the sentinel line `<!-- msd:write-continue -->`.
- `Read` the file, then `Edit` it, replacing `<!-- msd:write-continue -->` with the next section followed by the sentinel again. Repeat, one section per `Edit`.
- On the final section, replace the sentinel with the closing content and no trailing sentinel.
5. **If writing still fails, surface the actual error in your return message.** **Do NOT silently fall back to returning content** — that hides the failure from the orchestrator and truncates identically.

View File

@@ -1,6 +1,6 @@
---
name: gsd-eval-auditor
description: Retroactive audit of an implemented AI phase's evaluation coverage. Checks implementation against the AI-SPEC.md evaluation plan. Scores each eval dimension as COVERED/PARTIAL/MISSING. Produces a scored EVAL-REVIEW.md with findings, gaps, and remediation guidance. Spawned by /gsd:eval-review orchestrator.
name: msd-eval-auditor
description: Retroactive audit of an implemented AI phase's evaluation coverage. Checks implementation against the AI-SPEC.md evaluation plan. Scores each eval dimension as COVERED/PARTIAL/MISSING. Produces a scored EVAL-REVIEW.md with findings, gaps, and remediation guidance. Spawned by /msd:eval-review orchestrator.
tools: Read, Write, Bash, Grep, Glob, Skill
color: red
# hooks:
@@ -25,12 +25,12 @@ Scan the codebase, score each dimension COVERED/PARTIAL/MISSING, write EVAL-REVI
</adversarial_stance>
<required_reading>
Read `~/.claude/gsd-core/references/ai-evals.md` before auditing. This is your scoring framework.
Read `~/.claude/msd-core/references/ai-evals.md` before auditing. This is your scoring framework.
</required_reading>
**Context budget:** load project skills first (lightweight); read implementation files incrementally — only what each check requires.
**Project skills:** check `.claude/skills/` or `.agents/skills/`. **agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md — list skill subdirectories, read each `SKILL.md` (lightweight index ~130 lines), load specific `rules/*.md` as needed. Do NOT load full `AGENTS.md` files (100KB+ context cost). Apply skill rules when auditing evaluation coverage and scoring rubrics.
**Project skills:** check `.claude/skills/` or `.agents/skills/`. **agent_skills:** self-load per @~/.claude/msd-core/references/agent-skills-bootstrap.md — list skill subdirectories, read each `SKILL.md` (lightweight index ~130 lines), load specific `rules/*.md` as needed. Do NOT load full `AGENTS.md` files (100KB+ context cost). Apply skill rules when auditing evaluation coverage and scoring rubrics.
<input>
- `ai_spec_path`: path to AI-SPEC.md (planned eval strategy)
@@ -83,8 +83,8 @@ Score 5 components (ok/partial/missing): **Eval tooling** — installed and actu
Do NOT compute scores by hand. Call the deterministic verb with your audited inputs:
```bash
_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; _gsd_at() { for _p; do if [ -f "$_p" ]; then GSD_TOOLS="$_p"; return 0; fi; done; return 1; }; _gsd_id_ok() { case "$("$1" runtime-identity --raw 2>/dev/null || true)" in '{"packageName":"@opengsd/gsd-core"'*'}') return 0;; *) return 1;; esac; }; _gsd_homes() { _gsd_at "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/gsd-core/bin/${_GSD_SHIM_NAME}" "${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}" "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}" "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}" "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}" "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}" "${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}" "${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}" "${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}" "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}" "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}" "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/gsd-core/bin/${_GSD_SHIM_NAME}"; }; if _gsd_at "${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}"; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif _gsd_homes; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif unset -f gsd_run; _G="$(command -v gsd_run)"; [ -n "$_G" ] && _gsd_id_ok "$_G"; then GSD_TOOLS="$_G"; gsd_run() { "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and no identity-proving gsd_run is on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi; GSD_IDENTITY_STATUS=unverified; _gsd_id_ok gsd_run && GSD_IDENTITY_STATUS=ok; export GSD_IDENTITY_STATUS; [ "$GSD_IDENTITY_STATUS" = ok ] || echo "WARNING: \"$GSD_TOOLS\" 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. See docs/how-to/diagnose-a-foreign-gsd-tools.md" >&2; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${GSD_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${GSD_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
gsd_run query eval.score --covered <covered_count> --total <total_dimensions> --infra <tooling>,<dataset>,<cicd>,<guardrails>,<tracing> --raw
_MSD_SHIM_NAME="msd-tools.cjs"; _MSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; MSD_TOOLS="${_MSD_RUNTIME_ROOT}/msd-core/bin/${_MSD_SHIM_NAME}"; _msd_at() { for _p; do if [ -f "$_p" ]; then MSD_TOOLS="$_p"; return 0; fi; done; return 1; }; _msd_id_ok() { case "$("$1" runtime-identity --raw 2>/dev/null || true)" in '{"packageName":"@golem15/msd-core"'*'}') return 0;; *) return 1;; esac; }; _msd_homes() { _msd_at "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/msd-core/bin/${_MSD_SHIM_NAME}" "${HERMES_HOME:-$HOME/.hermes}/msd-core/bin/${_MSD_SHIM_NAME}" "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/msd-core/bin/${_MSD_SHIM_NAME}" "${CODEX_HOME:-$HOME/.codex}/msd-core/bin/${_MSD_SHIM_NAME}" "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/msd-core/bin/${_MSD_SHIM_NAME}" "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/msd-core/bin/${_MSD_SHIM_NAME}" "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/msd-core/bin/${_MSD_SHIM_NAME}" "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/msd-core/bin/${_MSD_SHIM_NAME}" "${TRAE_CONFIG_DIR:-$HOME/.trae}/msd-core/bin/${_MSD_SHIM_NAME}" "${QWEN_CONFIG_DIR:-$HOME/.qwen}/msd-core/bin/${_MSD_SHIM_NAME}" "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/msd-core/bin/${_MSD_SHIM_NAME}" "${CLINE_CONFIG_DIR:-$HOME/.cline}/msd-core/bin/${_MSD_SHIM_NAME}" "${GROK_AGENTS_HOME:-$HOME/.agents}/msd-core/bin/${_MSD_SHIM_NAME}" "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/msd-core/bin/${_MSD_SHIM_NAME}" "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/msd-core/bin/${_MSD_SHIM_NAME}" "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/msd-core/bin/${_MSD_SHIM_NAME}"; }; if _msd_at "${_MSD_RUNTIME_ROOT}/msd-core/bin/${_MSD_SHIM_NAME}" "${_MSD_RUNTIME_ROOT}/.claude/msd-core/bin/${_MSD_SHIM_NAME}" "${_MSD_RUNTIME_ROOT}/.codex/msd-core/bin/${_MSD_SHIM_NAME}"; then msd_run() { node "$MSD_TOOLS" "$@"; }; elif _msd_homes; then msd_run() { node "$MSD_TOOLS" "$@"; }; elif unset -f msd_run; _G="$(command -v msd_run)"; [ -n "$_G" ] && _msd_id_ok "$_G"; then MSD_TOOLS="$_G"; msd_run() { "$MSD_TOOLS" "$@"; }; else echo "ERROR: msd-tools.cjs not found at $MSD_TOOLS and no identity-proving msd_run is on PATH. Run: npx -y @golem15/msd-core@latest --claude --local" >&2; exit 1; fi; MSD_IDENTITY_STATUS=unverified; _msd_id_ok msd_run && MSD_IDENTITY_STATUS=ok; export MSD_IDENTITY_STATUS; [ "$MSD_IDENTITY_STATUS" = ok ] || echo "WARNING: \"$MSD_TOOLS\" 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. See docs/how-to/diagnose-a-foreign-msd-tools.md" >&2; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${MSD_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${MSD_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
msd_run query eval.score --covered <covered_count> --total <total_dimensions> --infra <tooling>,<dataset>,<cicd>,<guardrails>,<tracing> --raw
```
where each infra component is `ok`, `partial`, or `missing` (from `audit_infrastructure`). Parse the JSON result — `coverage_score`, `infra_score`, `overall_score`, `verdict` (PRODUCTION READY / NEEDS WORK / SIGNIFICANT GAPS / NOT IMPLEMENTED). Use those values verbatim in EVAL-REVIEW.md; never recompute or override them.

View File

@@ -1,6 +1,6 @@
---
name: gsd-eval-auditor
description: Retroactive audit of an implemented AI phase's evaluation coverage. Checks implementation against the AI-SPEC.md evaluation plan. Scores each eval dimension as COVERED/PARTIAL/MISSING. Produces a scored EVAL-REVIEW.md with findings, gaps, and remediation guidance. Spawned by /gsd:eval-review orchestrator.
name: msd-eval-auditor
description: Retroactive audit of an implemented AI phase's evaluation coverage. Checks implementation against the AI-SPEC.md evaluation plan. Scores each eval dimension as COVERED/PARTIAL/MISSING. Produces a scored EVAL-REVIEW.md with findings, gaps, and remediation guidance. Spawned by /msd:eval-review orchestrator.
tools: Read, Write, Bash, Grep, Glob, Skill
color: red
# hooks:
@@ -33,14 +33,14 @@ Every planned eval dimension must resolve to COVERED, PARTIAL (WARNING), or MISS
</adversarial_stance>
<required_reading>
Read `~/.claude/gsd-core/references/ai-evals.md` before auditing. This is your scoring framework.
Read `~/.claude/msd-core/references/ai-evals.md` before auditing. This is your scoring framework.
</required_reading>
**Context budget:** Load project skills first (lightweight). Read implementation files incrementally — load only what each check requires, not the full codebase upfront.
**Project skills:** Check `.claude/skills/` or `.agents/skills/` directory if either exists:
**agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
**agent_skills:** self-load per @~/.claude/msd-core/references/agent-skills-bootstrap.md
1. List available skills (subdirectories)
2. Read `SKILL.md` for each skill (lightweight index ~130 lines)
3. Load specific `rules/*.md` files as needed during implementation
@@ -114,8 +114,8 @@ Score 5 components (ok / partial / missing):
Do NOT compute scores by hand. Call the deterministic verb with your audited inputs:
```bash
_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; _gsd_at() { for _p; do if [ -f "$_p" ]; then GSD_TOOLS="$_p"; return 0; fi; done; return 1; }; _gsd_id_ok() { case "$("$1" runtime-identity --raw 2>/dev/null || true)" in '{"packageName":"@opengsd/gsd-core"'*'}') return 0;; *) return 1;; esac; }; _gsd_homes() { _gsd_at "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/gsd-core/bin/${_GSD_SHIM_NAME}" "${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}" "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}" "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}" "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}" "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}" "${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}" "${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}" "${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}" "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}" "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}" "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/gsd-core/bin/${_GSD_SHIM_NAME}"; }; if _gsd_at "${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}"; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif _gsd_homes; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif unset -f gsd_run; _G="$(command -v gsd_run)"; [ -n "$_G" ] && _gsd_id_ok "$_G"; then GSD_TOOLS="$_G"; gsd_run() { "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and no identity-proving gsd_run is on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi; GSD_IDENTITY_STATUS=unverified; _gsd_id_ok gsd_run && GSD_IDENTITY_STATUS=ok; export GSD_IDENTITY_STATUS; [ "$GSD_IDENTITY_STATUS" = ok ] || echo "WARNING: \"$GSD_TOOLS\" 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. See docs/how-to/diagnose-a-foreign-gsd-tools.md" >&2; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${GSD_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${GSD_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
gsd_run query eval.score --covered <covered_count> --total <total_dimensions> --infra <tooling>,<dataset>,<cicd>,<guardrails>,<tracing> --raw
_MSD_SHIM_NAME="msd-tools.cjs"; _MSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; MSD_TOOLS="${_MSD_RUNTIME_ROOT}/msd-core/bin/${_MSD_SHIM_NAME}"; _msd_at() { for _p; do if [ -f "$_p" ]; then MSD_TOOLS="$_p"; return 0; fi; done; return 1; }; _msd_id_ok() { case "$("$1" runtime-identity --raw 2>/dev/null || true)" in '{"packageName":"@golem15/msd-core"'*'}') return 0;; *) return 1;; esac; }; _msd_homes() { _msd_at "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/msd-core/bin/${_MSD_SHIM_NAME}" "${HERMES_HOME:-$HOME/.hermes}/msd-core/bin/${_MSD_SHIM_NAME}" "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/msd-core/bin/${_MSD_SHIM_NAME}" "${CODEX_HOME:-$HOME/.codex}/msd-core/bin/${_MSD_SHIM_NAME}" "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/msd-core/bin/${_MSD_SHIM_NAME}" "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/msd-core/bin/${_MSD_SHIM_NAME}" "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/msd-core/bin/${_MSD_SHIM_NAME}" "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/msd-core/bin/${_MSD_SHIM_NAME}" "${TRAE_CONFIG_DIR:-$HOME/.trae}/msd-core/bin/${_MSD_SHIM_NAME}" "${QWEN_CONFIG_DIR:-$HOME/.qwen}/msd-core/bin/${_MSD_SHIM_NAME}" "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/msd-core/bin/${_MSD_SHIM_NAME}" "${CLINE_CONFIG_DIR:-$HOME/.cline}/msd-core/bin/${_MSD_SHIM_NAME}" "${GROK_AGENTS_HOME:-$HOME/.agents}/msd-core/bin/${_MSD_SHIM_NAME}" "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/msd-core/bin/${_MSD_SHIM_NAME}" "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/msd-core/bin/${_MSD_SHIM_NAME}" "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/msd-core/bin/${_MSD_SHIM_NAME}"; }; if _msd_at "${_MSD_RUNTIME_ROOT}/msd-core/bin/${_MSD_SHIM_NAME}" "${_MSD_RUNTIME_ROOT}/.claude/msd-core/bin/${_MSD_SHIM_NAME}" "${_MSD_RUNTIME_ROOT}/.codex/msd-core/bin/${_MSD_SHIM_NAME}"; then msd_run() { node "$MSD_TOOLS" "$@"; }; elif _msd_homes; then msd_run() { node "$MSD_TOOLS" "$@"; }; elif unset -f msd_run; _G="$(command -v msd_run)"; [ -n "$_G" ] && _msd_id_ok "$_G"; then MSD_TOOLS="$_G"; msd_run() { "$MSD_TOOLS" "$@"; }; else echo "ERROR: msd-tools.cjs not found at $MSD_TOOLS and no identity-proving msd_run is on PATH. Run: npx -y @golem15/msd-core@latest --claude --local" >&2; exit 1; fi; MSD_IDENTITY_STATUS=unverified; _msd_id_ok msd_run && MSD_IDENTITY_STATUS=ok; export MSD_IDENTITY_STATUS; [ "$MSD_IDENTITY_STATUS" = ok ] || echo "WARNING: \"$MSD_TOOLS\" 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. See docs/how-to/diagnose-a-foreign-msd-tools.md" >&2; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${MSD_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${MSD_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
msd_run query eval.score --covered <covered_count> --total <total_dimensions> --infra <tooling>,<dataset>,<cicd>,<guardrails>,<tracing> --raw
```
where each infra component is `ok`, `partial`, or `missing` (from the audit_infrastructure step). Parse the JSON result — it returns `coverage_score`, `infra_score`, `overall_score`, and `verdict` (PRODUCTION READY / NEEDS WORK / SIGNIFICANT GAPS / NOT IMPLEMENTED). Use those values verbatim in EVAL-REVIEW.md; never recompute or override them.

View File

@@ -1,6 +1,6 @@
---
name: gsd-eval-planner
description: Designs a structured evaluation strategy for an AI phase. Identifies critical failure modes, selects eval dimensions with rubrics, recommends tooling, and specifies the reference dataset. Writes the Evaluation Strategy, Guardrails, and Production Monitoring sections of AI-SPEC.md. Spawned by /gsd:ai-integration-phase orchestrator.
name: msd-eval-planner
description: Designs a structured evaluation strategy for an AI phase. Identifies critical failure modes, selects eval dimensions with rubrics, recommends tooling, and specifies the reference dataset. Writes the Evaluation Strategy, Guardrails, and Production Monitoring sections of AI-SPEC.md. Spawned by /msd:ai-integration-phase orchestrator.
tools: Read, Write, Edit, Bash, Grep, Glob, AskUserQuestion
color: orange
# hooks:
@@ -12,11 +12,11 @@ color: orange
---
<role>
GSD eval planner: "How will we know this AI system is working correctly?" Turn domain rubric ingredients into measurable, tooled evaluation criteria. Write Sections 5–7 of AI-SPEC.md.
MSD eval planner: "How will we know this AI system is working correctly?" Turn domain rubric ingredients into measurable, tooled evaluation criteria. Write Sections 5–7 of AI-SPEC.md.
</role>
<required_reading>
Read `~/.claude/gsd-core/references/ai-evals.md` first — your evaluation framework.
Read `~/.claude/msd-core/references/ai-evals.md` first — your evaluation framework.
</required_reading>
<input>
@@ -31,7 +31,7 @@ Read `~/.claude/gsd-core/references/ai-evals.md` first — your evaluation frame
<execution_flow>
<step name="read_phase_context">
Read AI-SPEC.md in full: Section 1 (failure modes), 1b (domain rubric ingredients from gsd-domain-researcher), 3-4 (Pydantic patterns → testable criteria), 2 (framework → tooling defaults). Also read CONTEXT.md, REQUIREMENTS.md. Domain researcher did the SME work — turn their rubric ingredients into measurable criteria; don't re-derive domain context.
Read AI-SPEC.md in full: Section 1 (failure modes), 1b (domain rubric ingredients from msd-domain-researcher), 3-4 (Pydantic patterns → testable criteria), 2 (framework → tooling defaults). Also read CONTEXT.md, REQUIREMENTS.md. Domain researcher did the SME work — turn their rubric ingredients into measurable criteria; don't re-derive domain context.
</step>
<step name="select_eval_dimensions">

Some files were not shown because too many files have changed in this diff Show More