refactor: hard-fork GSD -> MSD (Make Software Done)
Mechanical rename produced by scripts/msd-rename.cjs: gsd/Gsd/GSD -> msd/Msd/MSD across contents and paths, upstream package/repo coordinates -> @golem15/msd-core and golem15com/msd-core. Deep links into upstream history, sibling upstream packages, the GSD-2 import feature, CHANGELOG.md and .changeset/ are kept as-is. Hand edits on top: MSD block-letter banner and logos, LICENSE copyright line, package/plugin identity, regenerated lockfile, install-tree fixtures, derived registries and benchmark baseline; migration checksum baseline re-locked (MSD keeps its own install state, so no install had applied the old sums); sort-order and regex-escaped expectations in tests adjusted.
This commit is contained in:
@@ -1,19 +1,19 @@
|
|||||||
{
|
{
|
||||||
"name": "gsd-core",
|
"name": "msd-core",
|
||||||
"description": "Marketplace for GSD Core — meta-prompting, context engineering, and spec-driven development system for AI coding agents.",
|
"description": "Marketplace for MSD Core — meta-prompting, context engineering, and spec-driven development system for AI coding agents.",
|
||||||
"owner": {
|
"owner": {
|
||||||
"name": "open-gsd",
|
"name": "golem15com",
|
||||||
"url": "https://github.com/open-gsd"
|
"url": "https://github.com/golem15com"
|
||||||
},
|
},
|
||||||
"plugins": [
|
"plugins": [
|
||||||
{
|
{
|
||||||
"name": "gsd-core",
|
"name": "msd-core",
|
||||||
"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.",
|
||||||
"version": "1.14.0",
|
"version": "1.14.0",
|
||||||
"source": "./",
|
"source": "./",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "open-gsd",
|
"name": "golem15com",
|
||||||
"url": "https://github.com/open-gsd"
|
"url": "https://github.com/golem15com"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
{
|
{
|
||||||
"name": "gsd-core",
|
"name": "msd-core",
|
||||||
"displayName": "GSD Core",
|
"displayName": "MSD Core",
|
||||||
"version": "1.14.0",
|
"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": {
|
"author": {
|
||||||
"name": "open-gsd",
|
"name": "golem15com",
|
||||||
"url": "https://github.com/open-gsd"
|
"url": "https://github.com/golem15com"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/open-gsd/gsd-core",
|
"homepage": "https://github.com/golem15com/msd-core",
|
||||||
"repository": "https://github.com/open-gsd/gsd-core",
|
"repository": "https://github.com/golem15com/msd-core",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"spec-driven-development",
|
"spec-driven-development",
|
||||||
@@ -16,8 +16,8 @@
|
|||||||
"workflow",
|
"workflow",
|
||||||
"context-engineering",
|
"context-engineering",
|
||||||
"claude-code",
|
"claude-code",
|
||||||
"gsd"
|
"msd"
|
||||||
],
|
],
|
||||||
"commands": "./commands/gsd/",
|
"commands": "./commands/msd/",
|
||||||
"skills": "./skills/"
|
"skills": "./skills/"
|
||||||
}
|
}
|
||||||
|
|||||||
22
.clinerules
22
.clinerules
@@ -1,19 +1,19 @@
|
|||||||
# GSD — Get Shit Done
|
# MSD — Get Shit Done
|
||||||
|
|
||||||
## What This Project Is
|
## 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
|
## Core Rule: Never Edit Outside a MSD Workflow
|
||||||
Do not make direct repo edits. All changes must go through a GSD workflow:
|
Do not make direct repo edits. All changes must go through a MSD workflow:
|
||||||
- `/gsd:plan-phase` → plan the work
|
- `/msd:plan-phase` → plan the work
|
||||||
- `/gsd:execute-phase` → build it
|
- `/msd:execute-phase` → build it
|
||||||
- `/gsd:verify-work` → verify results
|
- `/msd:verify-work` → verify results
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
- `gsd-core/bin/lib/` — Core Node.js library (CommonJS .cjs, no external deps)
|
- `msd-core/bin/lib/` — Core Node.js library (CommonJS .cjs, no external deps)
|
||||||
- `gsd-core/workflows/` — Workflow definition files (.md)
|
- `msd-core/workflows/` — Workflow definition files (.md)
|
||||||
- `agents/` — Agent 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)
|
- `tests/` — Test files (.test.cjs, node:test + node:assert)
|
||||||
|
|
||||||
## Coding Standards
|
## Coding Standards
|
||||||
@@ -24,4 +24,4 @@ Do not make direct repo edits. All changes must go through a GSD workflow:
|
|||||||
|
|
||||||
## Safety
|
## Safety
|
||||||
- Use `execFileSync` (array args) not `execSync` (string interpolation)
|
- 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`
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
# CodeRabbit configuration — open-gsd/gsd-core
|
# CodeRabbit configuration — golem15com/msd-core
|
||||||
#
|
#
|
||||||
# Schema: https://docs.coderabbit.ai/reference/yaml-template/
|
# 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
|
# 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.
|
# blanket docstring coverage bar — see issue #2932 for rationale.
|
||||||
|
|
||||||
reviews:
|
reviews:
|
||||||
|
|||||||
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -11,7 +11,7 @@
|
|||||||
*.ttf binary
|
*.ttf binary
|
||||||
*.pdf 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,
|
# (#2721, ADR-2719 Phase 1) covered tests/fixtures/golden-install-parity/*.json,
|
||||||
# tests/workflow-size-baseline.json, and tests/agent-size-baseline.json — all
|
# 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.
|
# three deleted by #2724 (ADR-2719 Phase 4), which retired the bridge driver too.
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ GIT_CMD="${GIT_OVERRIDE:-git}"
|
|||||||
NPM_CMD="${NPM_OVERRIDE:-npm}"
|
NPM_CMD="${NPM_OVERRIDE:-npm}"
|
||||||
|
|
||||||
# Tracked sources of the command-alias surface. These are the `src/*.cts` files,
|
# 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
|
# gitignored, so `git diff --cached --name-only` never lists them and a guard
|
||||||
# keyed on them can never fire (#2725). Kept in sync with
|
# 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.
|
# scripts/lib/alias-drift-families.cjs by tests/precommit-alias-drift-hook.test.cjs.
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ set -euo pipefail
|
|||||||
GIT_CMD="${GIT_OVERRIDE:-git}"
|
GIT_CMD="${GIT_OVERRIDE:-git}"
|
||||||
|
|
||||||
zero_sha='0000000000000000000000000000000000000000'
|
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.
|
# 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
|
if [[ -z "$blocked_regex" ]]; then
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|||||||
34
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
34
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -24,8 +24,8 @@ body:
|
|||||||
- type: input
|
- type: input
|
||||||
id: version
|
id: version
|
||||||
attributes:
|
attributes:
|
||||||
label: GSD Version
|
label: MSD 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)"
|
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"
|
placeholder: "e.g., 1.18.0"
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
@@ -34,7 +34,7 @@ body:
|
|||||||
id: runtime
|
id: runtime
|
||||||
attributes:
|
attributes:
|
||||||
label: Runtime
|
label: Runtime
|
||||||
description: Which AI coding tool are you using GSD with?
|
description: Which AI coding tool are you using MSD with?
|
||||||
options:
|
options:
|
||||||
- Claude Code
|
- Claude Code
|
||||||
- OpenCode
|
- OpenCode
|
||||||
@@ -86,8 +86,8 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: Installation Method
|
label: Installation Method
|
||||||
options:
|
options:
|
||||||
- npx @opengsd/gsd-core@latest (fresh run)
|
- npx @golem15/msd-core@latest (fresh run)
|
||||||
- npm install -g @opengsd/gsd-core
|
- npm install -g @golem15/msd-core
|
||||||
- Updated from a previous version
|
- Updated from a previous version
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
@@ -96,9 +96,9 @@ body:
|
|||||||
id: description
|
id: description
|
||||||
attributes:
|
attributes:
|
||||||
label: What happened?
|
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: |
|
placeholder: |
|
||||||
When I ran `/gsd-plan`, the system...
|
When I ran `/msd-plan`, the system...
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
@@ -115,12 +115,12 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: Steps to reproduce
|
label: Steps to reproduce
|
||||||
description: |
|
description: |
|
||||||
Exact steps to reproduce the issue. Include the GSD command used.
|
Exact steps to reproduce the issue. Include the MSD command used.
|
||||||
placeholder: |
|
placeholder: |
|
||||||
1. Install GSD with `npx @opengsd/gsd-core@latest`
|
1. Install MSD with `npx @golem15/msd-core@latest`
|
||||||
2. Select runtime: Claude Code
|
2. Select runtime: Claude Code
|
||||||
3. Run `/gsd-init` with a new project
|
3. Run `/msd-init` with a new project
|
||||||
4. Run `/gsd-plan`
|
4. Run `/msd-plan`
|
||||||
5. Error appears at step...
|
5. Error appears at step...
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
@@ -140,7 +140,7 @@ body:
|
|||||||
- type: textarea
|
- type: textarea
|
||||||
id: config
|
id: config
|
||||||
attributes:
|
attributes:
|
||||||
label: GSD Configuration
|
label: MSD Configuration
|
||||||
description: |
|
description: |
|
||||||
If the bug is related to planning, phases, or workflow behavior, paste your `.planning/config.json`.
|
If the bug is related to planning, phases, or workflow behavior, paste your `.planning/config.json`.
|
||||||
|
|
||||||
@@ -154,7 +154,7 @@ body:
|
|||||||
- type: textarea
|
- type: textarea
|
||||||
id: state
|
id: state
|
||||||
attributes:
|
attributes:
|
||||||
label: GSD State (if relevant)
|
label: MSD State (if relevant)
|
||||||
description: |
|
description: |
|
||||||
If the bug involves incorrect state tracking or phase progression, include your `.planning/STATE.md`.
|
If the bug involves incorrect state tracking or phase progression, include your `.planning/STATE.md`.
|
||||||
|
|
||||||
@@ -199,7 +199,7 @@ body:
|
|||||||
label: Impact
|
label: Impact
|
||||||
description: How much does this affect your workflow?
|
description: How much does this affect your workflow?
|
||||||
options:
|
options:
|
||||||
- Blocker — Cannot use GSD at all
|
- Blocker — Cannot use MSD at all
|
||||||
- Major — Core feature is broken, no workaround
|
- Major — Core feature is broken, no workaround
|
||||||
- Moderate — Feature is broken but I have a workaround
|
- Moderate — Feature is broken but I have a workaround
|
||||||
- Minor — Cosmetic or edge case
|
- Minor — Cosmetic or edge case
|
||||||
@@ -222,9 +222,9 @@ body:
|
|||||||
Anything else — screenshots, screen recordings, related issues, or links.
|
Anything else — screenshots, screen recordings, related issues, or links.
|
||||||
|
|
||||||
**Useful diagnostics to include (if applicable):**
|
**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)
|
- `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/gsd-core/` — confirms installation files (Claude Code)
|
- `ls -la ~/.claude/msd-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` — file manifest for debugging install issues
|
||||||
- `ls -la .planning/` — confirms planning directory state
|
- `ls -la .planning/` — confirms planning directory state
|
||||||
|
|
||||||
**⚠️ PII Warning:** File listings and manifests contain your home directory path. Replace your username with `REDACTED`.
|
**⚠️ PII Warning:** File listings and manifests contain your home directory path. Replace your username with `REDACTED`.
|
||||||
|
|||||||
2
.github/ISSUE_TEMPLATE/chore.yml
vendored
2
.github/ISSUE_TEMPLATE/chore.yml
vendored
@@ -17,7 +17,7 @@ body:
|
|||||||
- Documentation infrastructure (not content — use Docs Issue for content)
|
- Documentation infrastructure (not content — use Docs Issue for content)
|
||||||
- Tech debt paydown
|
- 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
|
- type: checkboxes
|
||||||
id: preflight
|
id: preflight
|
||||||
|
|||||||
10
.github/ISSUE_TEMPLATE/enhancement.yml
vendored
10
.github/ISSUE_TEMPLATE/enhancement.yml
vendored
@@ -39,7 +39,7 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: What existing feature or behavior does this improve?
|
label: What existing feature or behavior does this improve?
|
||||||
description: Name the specific command, workflow, output, or behavior you are enhancing.
|
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:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ body:
|
|||||||
description: |
|
description: |
|
||||||
Describe exactly how the thing works today. Be specific. Include example output or commands if helpful.
|
Describe exactly how the thing works today. Be specific. Include example output or commands if helpful.
|
||||||
placeholder: |
|
placeholder: |
|
||||||
Currently, `/gsd-status` shows:
|
Currently, `/msd-status` shows:
|
||||||
```
|
```
|
||||||
Phase 2/5 — In Progress
|
Phase 2/5 — In Progress
|
||||||
```
|
```
|
||||||
@@ -66,7 +66,7 @@ body:
|
|||||||
description: |
|
description: |
|
||||||
Describe exactly how it should work after the enhancement. Be specific. Include example output or commands.
|
Describe exactly how it should work after the enhancement. Be specific. Include example output or commands.
|
||||||
placeholder: |
|
placeholder: |
|
||||||
After the enhancement, `/gsd-status` would show:
|
After the enhancement, `/msd-status` would show:
|
||||||
```
|
```
|
||||||
Phase 2/5 — In Progress — "Implement core auth module"
|
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.
|
An enhancement should have a narrow, well-defined scope. If your list is long, this might be a feature, not an enhancement.
|
||||||
placeholder: |
|
placeholder: |
|
||||||
Files modified:
|
Files modified:
|
||||||
- `gsd-core/commands/gsd/status.md` — update output format description
|
- `msd-core/commands/msd/status.md` — update output format description
|
||||||
- `gsd-core/bin/lib/state.cjs` — expose phase name in status() return value
|
- `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
|
- `tests/status.test.cjs` — update snapshot and add test for phase name in output
|
||||||
- `CHANGELOG.md` — user-facing change entry
|
- `CHANGELOG.md` — user-facing change entry
|
||||||
|
|
||||||
|
|||||||
26
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
26
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
@@ -8,7 +8,7 @@ body:
|
|||||||
value: |
|
value: |
|
||||||
## ⚠️ Read this before you fill anything out
|
## ⚠️ 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:**
|
**Before opening this issue:**
|
||||||
- Check [Discussions](https://github.com/open-gsd/gsd-core/discussions) — has this been proposed and declined before?
|
- 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?*
|
- 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:**
|
**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`.**
|
**Do not open a PR until this issue is labeled `approved-feature`.**
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ body:
|
|||||||
required: true
|
required: true
|
||||||
- label: I have read CONTRIBUTING.md and understand that I must wait for `approved-feature` before writing any code
|
- label: I have read CONTRIBUTING.md and understand that I must wait for `approved-feature` before writing any code
|
||||||
required: true
|
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
|
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
|
- 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
|
required: true
|
||||||
@@ -83,14 +83,14 @@ body:
|
|||||||
Describe exactly what is being added. Be specific about commands, output, behavior, and user interaction.
|
Describe exactly what is being added. Be specific about commands, output, behavior, and user interaction.
|
||||||
Include example commands or example output where possible.
|
Include example commands or example output where possible.
|
||||||
placeholder: |
|
placeholder: |
|
||||||
A new command `/gsd-rollback` that:
|
A new command `/msd-rollback` that:
|
||||||
1. Reads the current phase from STATE.md
|
1. Reads the current phase from STATE.md
|
||||||
2. Reverts STATE.md to the previous phase's snapshot
|
2. Reverts STATE.md to the previous phase's snapshot
|
||||||
3. Outputs a confirmation with the rolled-back state
|
3. Outputs a confirmation with the rolled-back state
|
||||||
|
|
||||||
Example usage:
|
Example usage:
|
||||||
```
|
```
|
||||||
/gsd-rollback
|
/msd-rollback
|
||||||
> Rolled back from Phase 3 (failed) to Phase 2 (completed)
|
> Rolled back from Phase 3 (failed) to Phase 2 (completed)
|
||||||
```
|
```
|
||||||
validations:
|
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.
|
If you cannot fill this out, you do not understand the codebase well enough to propose this feature yet.
|
||||||
placeholder: |
|
placeholder: |
|
||||||
Files that would be created:
|
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:
|
Files that would be modified:
|
||||||
- `gsd-core/bin/lib/state.cjs` — add rollback() function
|
- `msd-core/bin/lib/state.cjs` — add rollback() function
|
||||||
- `gsd-core/bin/lib/phases.cjs` — expose phase snapshot API
|
- `msd-core/bin/lib/phases.cjs` — expose phase snapshot API
|
||||||
- `tests/rollback.test.cjs` — new test file
|
- `tests/rollback.test.cjs` — new test file
|
||||||
- `docs/COMMANDS.md` — document new command
|
- `docs/COMMANDS.md` — document new command
|
||||||
- `CHANGELOG.md` — entry for this feature
|
- `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.
|
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.
|
These become the basis for reviewer sign-off. Vague criteria ("it works") are not acceptable.
|
||||||
placeholder: |
|
placeholder: |
|
||||||
- [ ] `/gsd-rollback` reverts STATE.md to the previous phase when current phase status is `failed`
|
- [ ] `/msd-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
|
- [ ] `/msd-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` 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
|
- [ ] Rollback is logged in the phase history so the AI agent can see it happened
|
||||||
- [ ] All existing tests still pass
|
- [ ] All existing tests still pass
|
||||||
- [ ] New tests cover the happy path, no-previous-phase case, and STATE.md corruption case
|
- [ ] New tests cover the happy path, no-previous-phase case, and STATE.md corruption case
|
||||||
@@ -225,7 +225,7 @@ body:
|
|||||||
placeholder: |
|
placeholder: |
|
||||||
1. Manual STATE.md editing — rejected because it requires the developer to understand the schema
|
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.
|
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.
|
loses all completed phase history.
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
@@ -235,7 +235,7 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: Prior art and references
|
label: Prior art and references
|
||||||
description: |
|
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.
|
If you are aware of a prior declined proposal for this feature, explain why this proposal is different.
|
||||||
validations:
|
validations:
|
||||||
required: false
|
required: false
|
||||||
|
|||||||
14
.github/PULL_REQUEST_TEMPLATE/registry-entry.md
vendored
14
.github/PULL_REQUEST_TEMPLATE/registry-entry.md
vendored
@@ -30,7 +30,7 @@ Full schema and process: [docs/registries/README.md](../../docs/registries/READM
|
|||||||
"description": "",
|
"description": "",
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "",
|
"license": "",
|
||||||
"enginesGsd": "",
|
"enginesMsd": "",
|
||||||
"install": "",
|
"install": "",
|
||||||
"uninstall": "",
|
"uninstall": "",
|
||||||
"interactions": {},
|
"interactions": {},
|
||||||
@@ -42,7 +42,7 @@ Full schema and process: [docs/registries/README.md](../../docs/registries/READM
|
|||||||
|
|
||||||
## Required-field checklist
|
## 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)
|
- [ ] **(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`)
|
- [ ] **(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)
|
- [ ] **(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
|
## 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
|
- [ ] `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
|
- [ ] 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
|
## One entry, one PR
|
||||||
@@ -86,13 +86,13 @@ Full schema and process: [docs/registries/README.md](../../docs/registries/READM
|
|||||||
"id": "linear-issue-sync",
|
"id": "linear-issue-sync",
|
||||||
"name": "Linear Issue Sync",
|
"name": "Linear Issue Sync",
|
||||||
"type": "capability",
|
"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.",
|
"description": "Mirrors ROADMAP.md items to Linear issues as a ship:post contribution.",
|
||||||
"author": "Some Org <hello@some-org.example>",
|
"author": "Some Org <hello@some-org.example>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"enginesGsd": ">=1.6.0",
|
"enginesMsd": ">=1.6.0",
|
||||||
"install": "gsd capability install https://github.com/some-org/gsd-cap-linear-sync.git#v1.0.0",
|
"install": "msd capability install https://github.com/some-org/msd-cap-linear-sync.git#v1.0.0",
|
||||||
"uninstall": "gsd capability remove linear-issue-sync",
|
"uninstall": "msd capability remove linear-issue-sync",
|
||||||
"interactions": {
|
"interactions": {
|
||||||
"loopExtensionPoints": ["ship:post"],
|
"loopExtensionPoints": ["ship:post"],
|
||||||
"hookKinds": ["contribution"],
|
"hookKinds": ["contribution"],
|
||||||
|
|||||||
6
.github/workflows/auto-backmerge.yml
vendored
6
.github/workflows/auto-backmerge.yml
vendored
@@ -143,7 +143,7 @@ jobs:
|
|||||||
|
|
||||||
# The version bump below fires the `version` npm lifecycle hook, which runs
|
# The version bump below fires the `version` npm lifecycle hook, which runs
|
||||||
# gen-capability-registry.cjs. That validator lazily require()s the built
|
# 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
|
# 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
|
# stub and every capability fragment reports "could not be read", failing
|
||||||
# the sync. Build the ledger first so fragments materialize.
|
# the sync. Build the ledger first so fragments materialize.
|
||||||
@@ -199,7 +199,7 @@ jobs:
|
|||||||
if: steps.check.outputs.next_exists == 'true'
|
if: steps.check.outputs.next_exists == 'true'
|
||||||
id: openpr
|
id: openpr
|
||||||
env:
|
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 }}
|
BR: ${{ steps.branch.outputs.branch }}
|
||||||
NEEDS_REVIEW: ${{ steps.branch.outputs.needs_review }}
|
NEEDS_REVIEW: ${{ steps.branch.outputs.needs_review }}
|
||||||
DROPPED_ONELINE: ${{ steps.branch.outputs.dropped_oneline }}
|
DROPPED_ONELINE: ${{ steps.branch.outputs.dropped_oneline }}
|
||||||
@@ -246,7 +246,7 @@ jobs:
|
|||||||
# must review those before this lands.
|
# must review those before this lands.
|
||||||
if: steps.check.outputs.next_exists == 'true' && steps.branch.outputs.needs_review != 'true'
|
if: steps.check.outputs.next_exists == 'true' && steps.branch.outputs.needs_review != 'true'
|
||||||
env:
|
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 }}
|
PR: ${{ steps.openpr.outputs.pr }}
|
||||||
run: |
|
run: |
|
||||||
# Merge commit (not squash) preserves main as an ancestor of next.
|
# Merge commit (not squash) preserves main as an ancestor of next.
|
||||||
|
|||||||
@@ -126,14 +126,14 @@ jobs:
|
|||||||
? 'it does not link an issue'
|
? 'it does not link an issue'
|
||||||
: 'the linked issue is not approved';
|
: 'the linked issue is not approved';
|
||||||
const repoUrl = `${owner}/${repo}`;
|
const repoUrl = `${owner}/${repo}`;
|
||||||
const marker = '<!-- gsd-auto-close-unsolicited -->';
|
const marker = '<!-- msd-auto-close-unsolicited -->';
|
||||||
const message = [
|
const message = [
|
||||||
marker,
|
marker,
|
||||||
'## Closing — no pre-approved issue',
|
'## 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',
|
'### What to do',
|
||||||
'',
|
'',
|
||||||
|
|||||||
4
.github/workflows/branch-naming.yml
vendored
4
.github/workflows/branch-naming.yml
vendored
@@ -42,8 +42,8 @@ jobs:
|
|||||||
const alwaysValid = ['main', 'next', 'develop'];
|
const alwaysValid = ['main', 'next', 'develop'];
|
||||||
if (alwaysValid.includes(branch)) return;
|
if (alwaysValid.includes(branch)) return;
|
||||||
if (branch.startsWith('dependabot/') || branch.startsWith('renovate/')) return;
|
if (branch.startsWith('dependabot/') || branch.startsWith('renovate/')) return;
|
||||||
// GSD auto-created branches
|
// MSD auto-created branches
|
||||||
if (branch.startsWith('gsd/') || branch.startsWith('claude/')) return;
|
if (branch.startsWith('msd/') || branch.startsWith('claude/')) return;
|
||||||
|
|
||||||
const isValid = validPrefixes.some(prefix => branch.startsWith(prefix));
|
const isValid = validPrefixes.some(prefix => branch.startsWith(prefix));
|
||||||
if (!isValid) {
|
if (!isValid) {
|
||||||
|
|||||||
4
.github/workflows/ci-timeout-report.yml
vendored
4
.github/workflows/ci-timeout-report.yml
vendored
@@ -42,7 +42,7 @@ jobs:
|
|||||||
- name: Open a small PR with this run's new records, if any
|
- name: Open a small PR with this run's new records, if any
|
||||||
if: always()
|
if: always()
|
||||||
env:
|
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_ID: ${{ github.run_id }}
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
@@ -50,7 +50,7 @@ jobs:
|
|||||||
BR="automation/ci-timeout-report-$RUN_ID"
|
BR="automation/ci-timeout-report-$RUN_ID"
|
||||||
git checkout -b "$BR"
|
git checkout -b "$BR"
|
||||||
git add tests/ci-timeout-budget-history.jsonl
|
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"
|
commit -m "chore: CI timeout budget report — run $RUN_ID"
|
||||||
git push origin "$BR"
|
git push origin "$BR"
|
||||||
gh pr create \
|
gh pr create \
|
||||||
|
|||||||
2
.github/workflows/close-draft-prs-sweep.yml
vendored
2
.github/workflows/close-draft-prs-sweep.yml
vendored
@@ -41,7 +41,7 @@ jobs:
|
|||||||
'',
|
'',
|
||||||
'This project only accepts completed pull requests. Draft PRs are automatically closed.',
|
'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',
|
'### What to do instead',
|
||||||
'',
|
'',
|
||||||
|
|||||||
2
.github/workflows/close-draft-prs.yml
vendored
2
.github/workflows/close-draft-prs.yml
vendored
@@ -47,7 +47,7 @@ jobs:
|
|||||||
'',
|
'',
|
||||||
'This project only accepts completed pull requests. Draft PRs are automatically closed.',
|
'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',
|
'### What to do instead',
|
||||||
'',
|
'',
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
name: Default Flip Documentation
|
name: Default Flip Documentation
|
||||||
|
|
||||||
# DEFECT.DEFAULT-FLIP-DOCUMENTATION (CONTEXT.md): a PR that changes an
|
# 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
|
# must document the migration semantics in a `## Breaking Changes` PR-body
|
||||||
# section (when the new default takes effect, the opt-back-in command,
|
# section (when the new default takes effect, the opt-back-in command,
|
||||||
# effect on in-flight artifacts) — see scripts/lint-default-flip-documentation.cjs
|
# effect on in-flight artifacts) — see scripts/lint-default-flip-documentation.cjs
|
||||||
|
|||||||
10
.github/workflows/dependabot-vendor-refresh.yml
vendored
10
.github/workflows/dependabot-vendor-refresh.yml
vendored
@@ -1,6 +1,6 @@
|
|||||||
name: Dependabot Vendor Refresh
|
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
|
# for byte-freshness against node_modules, and requires package.json's
|
||||||
# devDependencies pin to literally match the installed version. Dependabot
|
# devDependencies pin to literally match the installed version. Dependabot
|
||||||
# regularly opens lockfile-only PRs that bump these packages within the
|
# 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.
|
# 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
|
# 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
|
# 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
|
# pattern) lands a new commit on the PR branch, which re-triggers this
|
||||||
# workflow's own `synchronize` trigger AND the `pull_request: synchronize`
|
# workflow's own `synchronize` trigger AND the `pull_request: synchronize`
|
||||||
@@ -71,7 +71,7 @@ jobs:
|
|||||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
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
|
persist-credentials: false
|
||||||
|
|
||||||
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||||
@@ -101,12 +101,12 @@ jobs:
|
|||||||
- name: Commit and push the mechanical refresh
|
- name: Commit and push the mechanical refresh
|
||||||
if: steps.fix.outputs.exit_code == '0' && steps.diff.outputs.dirty == 'true'
|
if: steps.fix.outputs.exit_code == '0' && steps.diff.outputs.dirty == 'true'
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ secrets.GSD_BOT_PR_TOKEN || secrets.GITHUB_TOKEN }}
|
GH_TOKEN: ${{ secrets.MSD_BOT_PR_TOKEN || secrets.GITHUB_TOKEN }}
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
git config user.name "github-actions[bot]"
|
git config user.name "github-actions[bot]"
|
||||||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
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 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 remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${{ github.repository }}.git"
|
||||||
git push origin HEAD:${{ github.head_ref }}
|
git push origin HEAD:${{ github.head_ref }}
|
||||||
|
|||||||
50
.github/workflows/install-smoke.yml
vendored
50
.github/workflows/install-smoke.yml
vendored
@@ -1,8 +1,8 @@
|
|||||||
name: Install Smoke
|
name: Install Smoke
|
||||||
|
|
||||||
# Exercises the real install paths:
|
# Exercises the real install paths:
|
||||||
# tarball: `npm pack` → `npm install -g <tarball>` → assert gsd-tools on PATH
|
# tarball: `npm pack` → `npm install -g <tarball>` → assert msd-tools on PATH
|
||||||
# unpacked: `npm install -g <dir>` (no pack) → assert gsd-tools on PATH + executable
|
# 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
|
# 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
|
# mode-644 failure class (issue #2453): npm does NOT chmod bin targets when
|
||||||
@@ -20,8 +20,8 @@ on:
|
|||||||
- main
|
- main
|
||||||
paths:
|
paths:
|
||||||
- 'bin/install.js'
|
- 'bin/install.js'
|
||||||
- 'gsd-core/bin/gsd-tools.cjs'
|
- 'msd-core/bin/msd-tools.cjs'
|
||||||
- 'gsd-core/bin/**'
|
- 'msd-core/bin/**'
|
||||||
- 'src/**'
|
- 'src/**'
|
||||||
- 'tsconfig.build.json'
|
- 'tsconfig.build.json'
|
||||||
- 'package.json'
|
- 'package.json'
|
||||||
@@ -179,35 +179,35 @@ jobs:
|
|||||||
TMPDIR_ROOT=$(mktemp -d)
|
TMPDIR_ROOT=$(mktemp -d)
|
||||||
cd "$TMPDIR_ROOT"
|
cd "$TMPDIR_ROOT"
|
||||||
npm install -g "$WORKSPACE/$TARBALL"
|
npm install -g "$WORKSPACE/$TARBALL"
|
||||||
command -v gsd-core
|
command -v msd-core
|
||||||
# `--claude --local` is the non-interactive code path. Don't swallow
|
# `--claude --local` is the non-interactive code path. Don't swallow
|
||||||
# non-zero exit — if the installer fails, that IS the CI failure, and
|
# non-zero exit — if the installer fails, that IS the CI failure, and
|
||||||
# its own error message is more useful than the downstream "shim
|
# its own error message is more useful than the downstream "shim
|
||||||
# regression" assertion masking the real cause.
|
# regression" assertion masking the real cause.
|
||||||
if ! gsd-core --claude --local; then
|
if ! msd-core --claude --local; then
|
||||||
echo "::error::gsd-core --claude --local failed. See the install.js output above for the real error."
|
echo "::error::msd-core --claude --local failed. See the install.js output above for the real error."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Assert gsd-tools resolves on PATH
|
- name: Assert msd-tools resolves on PATH
|
||||||
if: steps.skip.outputs.skip != 'true'
|
if: steps.skip.outputs.skip != 'true'
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
if ! command -v gsd-tools >/dev/null 2>&1; then
|
if ! command -v msd-tools >/dev/null 2>&1; then
|
||||||
echo "::error::gsd-tools is not on PATH after tarball install"
|
echo "::error::msd-tools is not on PATH after tarball install"
|
||||||
NPM_BIN="$(npm config get prefix)/bin"
|
NPM_BIN="$(npm config get prefix)/bin"
|
||||||
echo "npm global bin: $NPM_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
|
exit 1
|
||||||
fi
|
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'
|
if: steps.skip.outputs.skip != 'true'
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
gsd-tools --help
|
msd-tools --help
|
||||||
echo "✓ gsd-tools is executable"
|
echo "✓ msd-tools is executable"
|
||||||
|
|
||||||
- name: Lifecycle smoke
|
- name: Lifecycle smoke
|
||||||
if: steps.skip.outputs.skip != 'true'
|
if: steps.skip.outputs.skip != 'true'
|
||||||
@@ -276,22 +276,22 @@ jobs:
|
|||||||
TMPDIR_ROOT=$(mktemp -d)
|
TMPDIR_ROOT=$(mktemp -d)
|
||||||
cd "$TMPDIR_ROOT"
|
cd "$TMPDIR_ROOT"
|
||||||
npm install -g "$GITHUB_WORKSPACE"
|
npm install -g "$GITHUB_WORKSPACE"
|
||||||
command -v gsd-core
|
command -v msd-core
|
||||||
gsd-core --claude --local || true
|
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: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
if ! command -v gsd-tools >/dev/null 2>&1; then
|
if ! command -v msd-tools >/dev/null 2>&1; then
|
||||||
echo "::error::gsd-tools is not on PATH after unpacked install"
|
echo "::error::msd-tools is not on PATH after unpacked install"
|
||||||
NPM_BIN="$(npm config get prefix)/bin"
|
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
|
exit 1
|
||||||
fi
|
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: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
gsd-tools --help
|
msd-tools --help
|
||||||
echo "✓ gsd-tools is executable after unpacked install"
|
echo "✓ msd-tools is executable after unpacked install"
|
||||||
|
|||||||
2
.github/workflows/mutation.yml
vendored
2
.github/workflows/mutation.yml
vendored
@@ -15,7 +15,7 @@ on:
|
|||||||
paths:
|
paths:
|
||||||
# Only run when lib source, property/unit tests, or mutation config change
|
# Only run when lib source, property/unit tests, or mutation config change
|
||||||
- 'src/**/*.cts'
|
- 'src/**/*.cts'
|
||||||
- 'gsd-core/bin/lib/**/*.cjs'
|
- 'msd-core/bin/lib/**/*.cjs'
|
||||||
- 'tests/**/*.property.test.cjs'
|
- 'tests/**/*.property.test.cjs'
|
||||||
- 'tests/**/*.unit.test.cjs'
|
- 'tests/**/*.unit.test.cjs'
|
||||||
- 'tests/adr-parser.test.cjs'
|
- 'tests/adr-parser.test.cjs'
|
||||||
|
|||||||
6
.github/workflows/pr-template-format.yml
vendored
6
.github/workflows/pr-template-format.yml
vendored
@@ -37,7 +37,7 @@ jobs:
|
|||||||
# (https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#multiline-strings).
|
# (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 length-vs-total check in the policy (fileListIsComplete) is
|
||||||
# the second, independent layer.
|
# 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')
|
files=$(gh pr view "$PR_NUMBER" --repo "$GITHUB_REPOSITORY" --json files --jq '.files[].path')
|
||||||
echo "files<<$delim" >> "$GITHUB_OUTPUT"
|
echo "files<<$delim" >> "$GITHUB_OUTPUT"
|
||||||
echo "$files" >> "$GITHUB_OUTPUT"
|
echo "$files" >> "$GITHUB_OUTPUT"
|
||||||
@@ -57,7 +57,7 @@ jobs:
|
|||||||
uses: actions/github-script@d746ffe35508b1917358783b479e04febd2b8f71 # v9.0.0
|
uses: actions/github-script@d746ffe35508b1917358783b479e04febd2b8f71 # v9.0.0
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
const marker = '<!-- gsd-pr-template-policy -->';
|
const marker = '<!-- msd-pr-template-policy -->';
|
||||||
const pr = context.payload.pull_request;
|
const pr = context.payload.pull_request;
|
||||||
const policy = JSON.parse(${{ toJSON(steps.policy.outputs.result) }});
|
const policy = JSON.parse(${{ toJSON(steps.policy.outputs.result) }});
|
||||||
const comments = await github.paginate(github.rest.issues.listComments, {
|
const comments = await github.paginate(github.rest.issues.listComments, {
|
||||||
@@ -90,7 +90,7 @@ jobs:
|
|||||||
uses: actions/github-script@d746ffe35508b1917358783b479e04febd2b8f71 # v9.0.0
|
uses: actions/github-script@d746ffe35508b1917358783b479e04febd2b8f71 # v9.0.0
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
const marker = '<!-- gsd-pr-template-policy -->';
|
const marker = '<!-- msd-pr-template-policy -->';
|
||||||
const pr = context.payload.pull_request;
|
const pr = context.payload.pull_request;
|
||||||
const repoUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}`;
|
const repoUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}`;
|
||||||
const policy = JSON.parse(${{ toJSON(steps.policy.outputs.result) }});
|
const policy = JSON.parse(${{ toJSON(steps.policy.outputs.result) }});
|
||||||
|
|||||||
24
.github/workflows/release.yml
vendored
24
.github/workflows/release.yml
vendored
@@ -96,7 +96,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
VERSION: ${{ inputs.version }}
|
VERSION: ${{ inputs.version }}
|
||||||
run: |
|
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
|
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"
|
echo "::error::$pkg@$VERSION is already published on npm — bump to a new version"
|
||||||
exit 1
|
exit 1
|
||||||
@@ -458,7 +458,7 @@ jobs:
|
|||||||
path: coverage/tmp
|
path: coverage/tmp
|
||||||
merge-multiple: true
|
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:
|
env:
|
||||||
NODE_OPTIONS: --max-old-space-size=8192
|
NODE_OPTIONS: --max-old-space-size=8192
|
||||||
run: npm run test:coverage:report
|
run: npm run test:coverage:report
|
||||||
@@ -614,13 +614,13 @@ jobs:
|
|||||||
if: ${{ !inputs.dry_run }}
|
if: ${{ !inputs.dry_run }}
|
||||||
env:
|
env:
|
||||||
PRE_VERSION: ${{ steps.prerelease.outputs.pre_version }}
|
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
|
- name: Sync next branch to the published pre-release
|
||||||
if: ${{ !inputs.dry_run }}
|
if: ${{ !inputs.dry_run }}
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
env:
|
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 }}
|
PRE_VERSION: ${{ steps.prerelease.outputs.pre_version }}
|
||||||
run: node scripts/sync-next-version.cjs "$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"
|
echo "**DRY RUN** — npm publish, tagging, and push skipped" >> "$GITHUB_STEP_SUMMARY"
|
||||||
else
|
else
|
||||||
echo "- Published to npm as \`next\`" >> "$GITHUB_STEP_SUMMARY"
|
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
|
fi
|
||||||
echo "" >> "$GITHUB_STEP_SUMMARY"
|
echo "" >> "$GITHUB_STEP_SUMMARY"
|
||||||
echo "To publish another pre-release: run \`rc\` again" >> "$GITHUB_STEP_SUMMARY"
|
echo "To publish another pre-release: run \`rc\` again" >> "$GITHUB_STEP_SUMMARY"
|
||||||
@@ -733,7 +733,7 @@ jobs:
|
|||||||
path: coverage/tmp
|
path: coverage/tmp
|
||||||
merge-multiple: true
|
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:
|
env:
|
||||||
NODE_OPTIONS: --max-old-space-size=8192
|
NODE_OPTIONS: --max-old-space-size=8192
|
||||||
run: npm run test:coverage:report
|
run: npm run test:coverage:report
|
||||||
@@ -818,7 +818,7 @@ jobs:
|
|||||||
if: ${{ !inputs.dry_run }}
|
if: ${{ !inputs.dry_run }}
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
env:
|
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 }}
|
BRANCH: ${{ needs.validate-version.outputs.branch }}
|
||||||
VERSION: ${{ inputs.version }}
|
VERSION: ${{ inputs.version }}
|
||||||
run: |
|
run: |
|
||||||
@@ -900,7 +900,7 @@ jobs:
|
|||||||
if: ${{ !inputs.dry_run }}
|
if: ${{ !inputs.dry_run }}
|
||||||
env:
|
env:
|
||||||
VERSION: ${{ inputs.version }}
|
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
|
# 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
|
# the release's own branch lands on `main` without a manual merge click
|
||||||
@@ -915,7 +915,7 @@ jobs:
|
|||||||
if: ${{ !inputs.dry_run }}
|
if: ${{ !inputs.dry_run }}
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
env:
|
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 }}
|
BRANCH: ${{ needs.validate-version.outputs.branch }}
|
||||||
run: |
|
run: |
|
||||||
set -uo pipefail
|
set -uo pipefail
|
||||||
@@ -949,14 +949,14 @@ jobs:
|
|||||||
# releases, not just rc/hotfix. Without this, `next` drifts to whatever
|
# releases, not just rc/hotfix. Without this, `next` drifts to whatever
|
||||||
# rc.N the release branch forked from, and every npm script banner on
|
# 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
|
# `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
|
# shipped. Mirrors the rc job's sync step at line ~479. Idempotent: a
|
||||||
# no-op when `next` is already at the target version.
|
# no-op when `next` is already at the target version.
|
||||||
- name: Sync next branch to the published release
|
- name: Sync next branch to the published release
|
||||||
if: ${{ !inputs.dry_run }}
|
if: ${{ !inputs.dry_run }}
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ secrets.GSD_BOT_PR_TOKEN || secrets.GITHUB_TOKEN }}
|
GH_TOKEN: ${{ secrets.MSD_BOT_PR_TOKEN || secrets.GITHUB_TOKEN }}
|
||||||
VERSION: ${{ inputs.version }}
|
VERSION: ${{ inputs.version }}
|
||||||
run: node scripts/sync-next-version.cjs "$VERSION"
|
run: node scripts/sync-next-version.cjs "$VERSION"
|
||||||
|
|
||||||
@@ -972,5 +972,5 @@ jobs:
|
|||||||
echo "- Published to npm as \`latest\`" >> "$GITHUB_STEP_SUMMARY"
|
echo "- Published to npm as \`latest\`" >> "$GITHUB_STEP_SUMMARY"
|
||||||
echo "- Tagged \`v${VERSION}\`" >> "$GITHUB_STEP_SUMMARY"
|
echo "- Tagged \`v${VERSION}\`" >> "$GITHUB_STEP_SUMMARY"
|
||||||
echo "- PR created to merge back to main" >> "$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
|
fi
|
||||||
|
|||||||
6
.github/workflows/require-issue-link.yml
vendored
6
.github/workflows/require-issue-link.yml
vendored
@@ -80,14 +80,14 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
# The delimiter must be unguessable: every path in `files` is
|
# The delimiter must be unguessable: every path in `files` is
|
||||||
# attacker-controlled on a fork PR, and a file named after a fixed
|
# 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
|
# the heredoc value early, truncating everything after it — this is
|
||||||
# GitHub's own documented guidance for untrusted multiline output
|
# GitHub's own documented guidance for untrusted multiline output
|
||||||
# (https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#multiline-strings).
|
# (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 length-vs-total check in the policy (fileListIsComplete) is
|
||||||
# the second, independent layer: even if a delimiter collision slid
|
# the second, independent layer: even if a delimiter collision slid
|
||||||
# past this, a truncated or inflated list would still fail closed.
|
# 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')
|
files=$(gh pr view "$PR_NUMBER" --repo "$GITHUB_REPOSITORY" --json files --jq '.files[].path')
|
||||||
{
|
{
|
||||||
echo "files<<$delim"
|
echo "files<<$delim"
|
||||||
@@ -147,7 +147,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
# Uses GitHub API SDK — no shell string interpolation of untrusted input
|
# Uses GitHub API SDK — no shell string interpolation of untrusted input
|
||||||
script: |
|
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 repoUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}`;
|
||||||
const prNumber = context.payload.pull_request.number;
|
const prNumber = context.payload.pull_request.number;
|
||||||
// #3211: the verdict is a typed reason, so the guidance can name the
|
// #3211: the verdict is a typed reason, so the guidance can name the
|
||||||
|
|||||||
10
.github/workflows/security-scan.yml
vendored
10
.github/workflows/security-scan.yml
vendored
@@ -8,7 +8,7 @@ on:
|
|||||||
- 'release/**'
|
- 'release/**'
|
||||||
- 'hotfix/**'
|
- 'hotfix/**'
|
||||||
paths:
|
paths:
|
||||||
- 'gsd-core/**'
|
- 'msd-core/**'
|
||||||
- 'agents/**'
|
- 'agents/**'
|
||||||
- 'commands/**'
|
- 'commands/**'
|
||||||
- 'hooks/**'
|
- 'hooks/**'
|
||||||
@@ -75,7 +75,7 @@ jobs:
|
|||||||
BASE_REF: ${{ github.base_ref }}
|
BASE_REF: ${{ github.base_ref }}
|
||||||
run: |
|
run: |
|
||||||
chmod +x scripts/prompt-injection-scan.sh
|
chmod +x scripts/prompt-injection-scan.sh
|
||||||
. gsd-core/bin/shared/exit-codes.sh
|
. msd-core/bin/shared/exit-codes.sh
|
||||||
set +e
|
set +e
|
||||||
scripts/prompt-injection-scan.sh --diff "origin/$BASE_REF"
|
scripts/prompt-injection-scan.sh --diff "origin/$BASE_REF"
|
||||||
code=$?
|
code=$?
|
||||||
@@ -91,7 +91,7 @@ jobs:
|
|||||||
BASE_REF: ${{ github.base_ref }}
|
BASE_REF: ${{ github.base_ref }}
|
||||||
run: |
|
run: |
|
||||||
chmod +x scripts/base64-scan.sh
|
chmod +x scripts/base64-scan.sh
|
||||||
. gsd-core/bin/shared/exit-codes.sh
|
. msd-core/bin/shared/exit-codes.sh
|
||||||
set +e
|
set +e
|
||||||
scripts/base64-scan.sh --diff "origin/$BASE_REF"
|
scripts/base64-scan.sh --diff "origin/$BASE_REF"
|
||||||
code=$?
|
code=$?
|
||||||
@@ -107,7 +107,7 @@ jobs:
|
|||||||
BASE_REF: ${{ github.base_ref }}
|
BASE_REF: ${{ github.base_ref }}
|
||||||
run: |
|
run: |
|
||||||
chmod +x scripts/secret-scan.sh
|
chmod +x scripts/secret-scan.sh
|
||||||
. gsd-core/bin/shared/exit-codes.sh
|
. msd-core/bin/shared/exit-codes.sh
|
||||||
set +e
|
set +e
|
||||||
scripts/secret-scan.sh --diff "origin/$BASE_REF"
|
scripts/secret-scan.sh --diff "origin/$BASE_REF"
|
||||||
code=$?
|
code=$?
|
||||||
@@ -128,7 +128,7 @@ jobs:
|
|||||||
BASE_REF: ${{ github.base_ref }}
|
BASE_REF: ${{ github.base_ref }}
|
||||||
run: |
|
run: |
|
||||||
# Ensure .planning/ runtime data is not committed in PRs
|
# 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)
|
# from forks or misconfigured clones might include it)
|
||||||
PLANNING_FILES=$(git diff --name-only --diff-filter=ACMR "origin/$BASE_REF"...HEAD | grep '^\.planning/' || true)
|
PLANNING_FILES=$(git diff --name-only --diff-filter=ACMR "origin/$BASE_REF"...HEAD | grep '^\.planning/' || true)
|
||||||
if [ -n "$PLANNING_FILES" ]; then
|
if [ -n "$PLANNING_FILES" ]; then
|
||||||
|
|||||||
8
.github/workflows/stale.yml
vendored
8
.github/workflows/stale.yml
vendored
@@ -25,13 +25,13 @@ jobs:
|
|||||||
stale-issue-message: >
|
stale-issue-message: >
|
||||||
This issue has been inactive for 28 days. It will be closed in 14 days
|
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
|
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: >
|
stale-pr-message: >
|
||||||
This PR has been inactive for 28 days. It will be closed in 14 days
|
This PR has been inactive for 28 days. It will be closed in 14 days
|
||||||
if there is no further activity.
|
if there is no further activity.
|
||||||
close-issue-message: >
|
close-issue-message: >
|
||||||
Closed due to inactivity. If this is still relevant, please reopen
|
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-issue-label: 'stale'
|
||||||
stale-pr-label: 'stale'
|
stale-pr-label: 'stale'
|
||||||
exempt-issue-labels: 'fix-pending,priority: critical,pinned,confirmed-bug,confirmed,awaiting-retest,needs-reproduction'
|
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
|
remove-stale-when-updated: true
|
||||||
stale-issue-message: >
|
stale-issue-message: >
|
||||||
Closing — we asked for a retest / reproduction more than 5 days ago and
|
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.
|
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 expect follow-up to maintainer requests within a reasonable window or
|
||||||
we close to keep the tracker actionable.
|
we close to keep the tracker actionable.
|
||||||
close-issue-message: >
|
close-issue-message: >
|
||||||
Closed (not planned) — reporter did not respond within 5 days of our
|
Closed (not planned) — reporter did not respond within 5 days of our
|
||||||
retest / reproduction request. Re-open with the requested information,
|
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'
|
exempt-issue-labels: 'pinned,priority: critical,fix-pending'
|
||||||
|
|||||||
46
.github/workflows/test.yml
vendored
46
.github/workflows/test.yml
vendored
@@ -209,7 +209,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
# #2665 round 4: every job that runs the suite wires the strict guard
|
# #2665 round 4: every job that runs the suite wires the strict guard
|
||||||
# (job-level env, where the live-config-guard derivation reads it).
|
# (job-level env, where the live-config-guard derivation reads it).
|
||||||
GSD_STRICT_LIVE_CONFIG_GUARD: '1'
|
MSD_STRICT_LIVE_CONFIG_GUARD: '1'
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
with:
|
with:
|
||||||
@@ -266,14 +266,14 @@ jobs:
|
|||||||
# headroom factor over its own measured cost.
|
# headroom factor over its own measured cost.
|
||||||
timeout-minutes: 32
|
timeout-minutes: 32
|
||||||
env:
|
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
|
# #2665 / #4641: this job's matrix is ubuntu-only as of #4641 (the
|
||||||
# `scope: windows` rows moved to test-conformance, see the timeout
|
# `scope: windows` rows moved to test-conformance, see the timeout
|
||||||
# comment above), so the live-config leak guard is strict unconditionally
|
# comment above), so the live-config leak guard is strict unconditionally
|
||||||
# here. The Windows report-only carve-out (PRE-EXISTING USERPROFILE leaks,
|
# here. The Windows report-only carve-out (PRE-EXISTING USERPROFILE leaks,
|
||||||
# ~190 test sites sandbox HOME alone) now lives solely on jobs.test-conformance
|
# ~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).
|
# — 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
|
# #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
|
# 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
|
# 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
|
# 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.
|
# "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.
|
# This must stay equal to CI_REBASE_BASE_SHA; a test asserts that parity.
|
||||||
GSD_EMITTED_BASE: ${{ github.event.pull_request.base.sha }}
|
MSD_EMITTED_BASE: ${{ github.event.pull_request.base.sha }}
|
||||||
# #4196: pin the npm-audit baseline the SAME way GSD_EMITTED_BASE pins
|
# #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
|
# 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
|
# 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
|
# 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
|
# #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
|
# 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
|
# stop rather than a fall-through. That converted every recoverable condition
|
||||||
# (stale, malformed, wrong schema version) into a fatal CI failure on diffs that
|
# (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
|
# touched nothing related. Restoring to the default path and saying nothing lets
|
||||||
@@ -418,7 +418,7 @@ jobs:
|
|||||||
if: github.event_name == 'pull_request'
|
if: github.event_name == 'pull_request'
|
||||||
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
||||||
with:
|
with:
|
||||||
path: .gsd-cache/emitted-baseline.json
|
path: .msd-cache/emitted-baseline.json
|
||||||
key: emitted-baseline-${{ github.event.pull_request.base.sha }}
|
key: emitted-baseline-${{ github.event.pull_request.base.sha }}
|
||||||
|
|
||||||
- name: Prepare scoped test list
|
- name: Prepare scoped test list
|
||||||
@@ -457,7 +457,7 @@ jobs:
|
|||||||
# `scope: targeted` lane runs no aux suite on its own, so this
|
# `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
|
# must stay empty there. tests/ci-full-lane-sharding.test.cjs pins both
|
||||||
# halves of this contract. Reserve-value derivation:
|
# 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_TESTS_SHARD_RESERVE: ${{ matrix.scope == 'full' && '1:77' || '' }}
|
||||||
run: npm run test:coverage:unit:raw -- --shard ${{ matrix.shard }}
|
run: npm run test:coverage:unit:raw -- --shard ${{ matrix.shard }}
|
||||||
|
|
||||||
@@ -509,14 +509,14 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 15
|
timeout-minutes: 15
|
||||||
env:
|
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).
|
# #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
|
# #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
|
# 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.
|
# with no exceptions: if a job merges a pinned base, the gate uses that base.
|
||||||
GSD_EMITTED_BASE: ${{ github.event.pull_request.base.sha }}
|
MSD_EMITTED_BASE: ${{ github.event.pull_request.base.sha }}
|
||||||
# #4196: pin the npm-audit baseline the SAME way GSD_EMITTED_BASE pins
|
# #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
|
# 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
|
# 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
|
# 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.
|
# should comfortably undercut this ceiling.
|
||||||
timeout-minutes: 45
|
timeout-minutes: 45
|
||||||
env:
|
env:
|
||||||
GSD_PLUGIN_ROOT: .ci-gsd-plugin-root-disabled
|
MSD_PLUGIN_ROOT: .ci-msd-plugin-root-disabled
|
||||||
GSD_STRICT_LIVE_CONFIG_GUARD: ${{ matrix.os != 'windows-latest' && '1' || '' }}
|
MSD_STRICT_LIVE_CONFIG_GUARD: ${{ matrix.os != 'windows-latest' && '1' || '' }}
|
||||||
GSD_EMITTED_BASE: ${{ github.event.pull_request.base.sha }}
|
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) || '' }}
|
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:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
@@ -672,7 +672,7 @@ jobs:
|
|||||||
if: github.event_name == 'pull_request'
|
if: github.event_name == 'pull_request'
|
||||||
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
||||||
with:
|
with:
|
||||||
path: .gsd-cache/emitted-baseline.json
|
path: .msd-cache/emitted-baseline.json
|
||||||
key: emitted-baseline-${{ github.event.pull_request.base.sha }}
|
key: emitted-baseline-${{ github.event.pull_request.base.sha }}
|
||||||
|
|
||||||
# #4591: the generated conformance-tier list is a .cjs module (so
|
# #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
|
# 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
|
# memory bound only — it does not change what is measured or the
|
||||||
# thresholds below.
|
# 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:
|
env:
|
||||||
NODE_OPTIONS: --max-old-space-size=8192
|
NODE_OPTIONS: --max-old-space-size=8192
|
||||||
run: npm run test:coverage:report
|
run: npm run test:coverage:report
|
||||||
@@ -782,7 +782,7 @@ jobs:
|
|||||||
# #2966: turns a loop QA-walk "smell" into a decision — see
|
# #2966: turns a loop QA-walk "smell" into a decision — see
|
||||||
# scripts/qa-smell-ratchet.cjs's own header for the full design invariant.
|
# 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
|
# 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.
|
# to walk on a docs-only change.
|
||||||
qa-loop-walk:
|
qa-loop-walk:
|
||||||
name: QA loop walk (smell ratchet)
|
name: QA loop walk (smell ratchet)
|
||||||
@@ -791,11 +791,11 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 15
|
timeout-minutes: 15
|
||||||
env:
|
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
|
# `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
|
# live-config guard like every other suite lane. ubuntu-only, so strict
|
||||||
# unconditionally — the Windows carve-out does not apply here.
|
# unconditionally — the Windows carve-out does not apply here.
|
||||||
GSD_STRICT_LIVE_CONFIG_GUARD: '1'
|
MSD_STRICT_LIVE_CONFIG_GUARD: '1'
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
with:
|
with:
|
||||||
@@ -821,7 +821,7 @@ jobs:
|
|||||||
- name: Dependency integrity gate
|
- name: Dependency integrity gate
|
||||||
run: node scripts/check-npm-integrity.cjs
|
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
|
run: npm run build:lib
|
||||||
|
|
||||||
- name: Run QA loop-walk scenarios
|
- name: Run QA loop-walk scenarios
|
||||||
@@ -988,10 +988,10 @@ jobs:
|
|||||||
run: npm ci
|
run: npm ci
|
||||||
|
|
||||||
- name: Build emitted-baseline artifact
|
- 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)
|
- name: Publish baseline cache (keyed on this sha)
|
||||||
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
||||||
with:
|
with:
|
||||||
path: .gsd-cache/emitted-baseline.json
|
path: .msd-cache/emitted-baseline.json
|
||||||
key: emitted-baseline-${{ github.sha }}
|
key: emitted-baseline-${{ github.sha }}
|
||||||
|
|||||||
492
.gitignore
vendored
492
.gitignore
vendored
@@ -36,23 +36,23 @@ reports/
|
|||||||
RAILROAD_ARCHITECTURE.md
|
RAILROAD_ARCHITECTURE.md
|
||||||
.planning/
|
.planning/
|
||||||
analysis/
|
analysis/
|
||||||
docs/GSD-MASTER-ARCHITECTURE.md
|
docs/MSD-MASTER-ARCHITECTURE.md
|
||||||
docs/GSD-RUST-IMPLEMENTATION-GUIDE.md
|
docs/MSD-RUST-IMPLEMENTATION-GUIDE.md
|
||||||
docs/GSD-SYSTEM-SPECIFICATION.md
|
docs/MSD-SYSTEM-SPECIFICATION.md
|
||||||
gaps.md
|
gaps.md
|
||||||
improve.md
|
improve.md
|
||||||
philosophy.md
|
philosophy.md
|
||||||
|
|
||||||
# Installed skills
|
# Installed skills
|
||||||
.github/agents/gsd-*
|
.github/agents/msd-*
|
||||||
.github/skills/gsd-*
|
.github/skills/msd-*
|
||||||
.github/gsd-core/*
|
.github/msd-core/*
|
||||||
.github/skills/gsd-core
|
.github/skills/msd-core
|
||||||
.github/copilot-instructions.md
|
.github/copilot-instructions.md
|
||||||
.bg-shell/
|
.bg-shell/
|
||||||
|
|
||||||
# ── GSD baseline (auto-generated) ──
|
# ── MSD baseline (auto-generated) ──
|
||||||
.gsd
|
.msd
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
*.swp
|
*.swp
|
||||||
*.swo
|
*.swo
|
||||||
@@ -71,253 +71,253 @@ build/
|
|||||||
# by `npm run build:lib`). Source of truth is src/; these are emitted, never edited.
|
# 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.
|
# Published via prepublishOnly; built before test via pretest. Grows as modules migrate.
|
||||||
/tsconfig.build.tsbuildinfo
|
/tsconfig.build.tsbuildinfo
|
||||||
/gsd-core/bin/lib/commonjs-marker.cjs
|
/msd-core/bin/lib/commonjs-marker.cjs
|
||||||
/gsd-core/bin/lib/broken-windows.cjs
|
/msd-core/bin/lib/broken-windows.cjs
|
||||||
/gsd-core/bin/lib/complexity-trigger.cjs
|
/msd-core/bin/lib/complexity-trigger.cjs
|
||||||
/gsd-core/bin/lib/refactor-trigger-command-router.cjs
|
/msd-core/bin/lib/refactor-trigger-command-router.cjs
|
||||||
/gsd-core/bin/lib/host-integration.cjs
|
/msd-core/bin/lib/host-integration.cjs
|
||||||
/gsd-core/bin/lib/host-integration-sdk.cjs
|
/msd-core/bin/lib/host-integration-sdk.cjs
|
||||||
/gsd-core/bin/lib/host-integration-adapters/imperative-hook-bus.cjs
|
/msd-core/bin/lib/host-integration-adapters/imperative-hook-bus.cjs
|
||||||
/gsd-core/bin/lib/host-integration-adapters/cline-sdk-binding.cjs
|
/msd-core/bin/lib/host-integration-adapters/cline-sdk-binding.cjs
|
||||||
/gsd-core/bin/lib/handshake-serialized.cjs
|
/msd-core/bin/lib/handshake-serialized.cjs
|
||||||
/gsd-core/bin/lib/install-effort-resolver.cjs
|
/msd-core/bin/lib/install-effort-resolver.cjs
|
||||||
/gsd-core/bin/lib/install-model-override-resolver.cjs
|
/msd-core/bin/lib/install-model-override-resolver.cjs
|
||||||
/gsd-core/bin/lib/install-engine.cjs
|
/msd-core/bin/lib/install-engine.cjs
|
||||||
/gsd-core/bin/lib/real-home-guard.cjs
|
/msd-core/bin/lib/real-home-guard.cjs
|
||||||
/gsd-core/bin/lib/embedding-adapter.cjs
|
/msd-core/bin/lib/embedding-adapter.cjs
|
||||||
/gsd-core/bin/lib/adapter-declarative.cjs
|
/msd-core/bin/lib/adapter-declarative.cjs
|
||||||
/gsd-core/bin/lib/adapter-imperative.cjs
|
/msd-core/bin/lib/adapter-imperative.cjs
|
||||||
/gsd-core/bin/lib/model-adapter.cjs
|
/msd-core/bin/lib/model-adapter.cjs
|
||||||
/gsd-core/bin/lib/hook-bus.cjs
|
/msd-core/bin/lib/hook-bus.cjs
|
||||||
/gsd-core/bin/lib/state-io.cjs
|
/msd-core/bin/lib/state-io.cjs
|
||||||
/gsd-core/bin/lib/mcp-server.cjs
|
/msd-core/bin/lib/mcp-server.cjs
|
||||||
/gsd-core/bin/lib/mcp-catalog.cjs
|
/msd-core/bin/lib/mcp-catalog.cjs
|
||||||
/gsd-core/bin/lib/external-descriptor-trust.cjs
|
/msd-core/bin/lib/external-descriptor-trust.cjs
|
||||||
/gsd-core/bin/lib/cli-skew-check.cjs
|
/msd-core/bin/lib/cli-skew-check.cjs
|
||||||
/gsd-core/bin/lib/context-composer.cjs
|
/msd-core/bin/lib/context-composer.cjs
|
||||||
/gsd-core/bin/lib/context-predicates.cjs
|
/msd-core/bin/lib/context-predicates.cjs
|
||||||
/gsd-core/bin/lib/workflow-fragments.cjs
|
/msd-core/bin/lib/workflow-fragments.cjs
|
||||||
/gsd-core/bin/lib/section-manifest.cjs
|
/msd-core/bin/lib/section-manifest.cjs
|
||||||
/gsd-core/bin/lib/capability-loader.cjs
|
/msd-core/bin/lib/capability-loader.cjs
|
||||||
/gsd-core/bin/lib/capability-source.cjs
|
/msd-core/bin/lib/capability-source.cjs
|
||||||
/gsd-core/bin/lib/capability-ledger.cjs
|
/msd-core/bin/lib/capability-ledger.cjs
|
||||||
/gsd-core/bin/lib/capability-trust.cjs
|
/msd-core/bin/lib/capability-trust.cjs
|
||||||
/gsd-core/bin/lib/capability-lifecycle.cjs
|
/msd-core/bin/lib/capability-lifecycle.cjs
|
||||||
/gsd-core/bin/lib/capability-consent.cjs
|
/msd-core/bin/lib/capability-consent.cjs
|
||||||
/gsd-core/bin/lib/capability-lock.cjs
|
/msd-core/bin/lib/capability-lock.cjs
|
||||||
/gsd-core/bin/lib/markdown-sectionizer.cjs
|
/msd-core/bin/lib/markdown-sectionizer.cjs
|
||||||
# #3311: new module (milestone lock) — emitted artifact, never edited.
|
# #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
|
# #2657: these two (markdown-table.cjs, write-set.cjs) already had the
|
||||||
# pattern below since #2248, but stayed tracked because `git rm --cached`
|
# pattern below since #2248, but stayed tracked because `git rm --cached`
|
||||||
# was never run — same untracking fix as the seven lines that follow.
|
# was never run — same untracking fix as the seven lines that follow.
|
||||||
/gsd-core/bin/lib/markdown-table.cjs
|
/msd-core/bin/lib/markdown-table.cjs
|
||||||
/gsd-core/bin/lib/write-set.cjs
|
/msd-core/bin/lib/write-set.cjs
|
||||||
# #2657: ADR-457 migration gap — these seven (of nine total; the two above
|
# #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
|
# are the other two) never got a .gitignore entry when their modules moved
|
||||||
# into src/*.cts, and were also never untracked.
|
# into src/*.cts, and were also never untracked.
|
||||||
/gsd-core/bin/lib/api-coverage.cjs
|
/msd-core/bin/lib/api-coverage.cjs
|
||||||
/gsd-core/bin/lib/assumption-delta.cjs
|
/msd-core/bin/lib/assumption-delta.cjs
|
||||||
/gsd-core/bin/lib/claude-orchestration.cjs
|
/msd-core/bin/lib/claude-orchestration.cjs
|
||||||
/gsd-core/bin/lib/claude-orchestration-command-router.cjs
|
/msd-core/bin/lib/claude-orchestration-command-router.cjs
|
||||||
/gsd-core/bin/lib/external-job.cjs
|
/msd-core/bin/lib/external-job.cjs
|
||||||
/gsd-core/bin/lib/runtime-artifact-install-plan.cjs
|
/msd-core/bin/lib/runtime-artifact-install-plan.cjs
|
||||||
/gsd-core/bin/lib/state-transition.cjs
|
/msd-core/bin/lib/state-transition.cjs
|
||||||
# #3873: schema leaf module (ADR-3473 §8.8) — emitted artifact, never edited.
|
# #3873: schema leaf module (ADR-3473 §8.8) — emitted artifact, never edited.
|
||||||
/gsd-core/bin/lib/state-md-schema.cjs
|
/msd-core/bin/lib/state-md-schema.cjs
|
||||||
/gsd-core/bin/lib/resolution.cjs
|
/msd-core/bin/lib/resolution.cjs
|
||||||
/gsd-core/bin/lib/research-store.cjs
|
/msd-core/bin/lib/research-store.cjs
|
||||||
/gsd-core/bin/lib/research-provider.cjs
|
/msd-core/bin/lib/research-provider.cjs
|
||||||
/gsd-core/bin/lib/package-legitimacy.cjs
|
/msd-core/bin/lib/package-legitimacy.cjs
|
||||||
/gsd-core/bin/lib/semver-compare.cjs
|
/msd-core/bin/lib/semver-compare.cjs
|
||||||
/gsd-core/bin/lib/plan-drift-guard.cjs
|
/msd-core/bin/lib/plan-drift-guard.cjs
|
||||||
/gsd-core/bin/lib/edge-probe.cjs
|
/msd-core/bin/lib/edge-probe.cjs
|
||||||
/gsd-core/bin/lib/probe-core.cjs
|
/msd-core/bin/lib/probe-core.cjs
|
||||||
/gsd-core/bin/lib/spec-section.cjs
|
/msd-core/bin/lib/spec-section.cjs
|
||||||
/gsd-core/bin/lib/prohibition-enforcement.cjs
|
/msd-core/bin/lib/prohibition-enforcement.cjs
|
||||||
/gsd-core/bin/lib/ui-consideration-probe.cjs
|
/msd-core/bin/lib/ui-consideration-probe.cjs
|
||||||
/gsd-core/bin/lib/config-types.cjs
|
/msd-core/bin/lib/config-types.cjs
|
||||||
/gsd-core/bin/lib/cli-exit.cjs
|
/msd-core/bin/lib/cli-exit.cjs
|
||||||
# #4145: emitted artifact of src/pristine-baseline.cts — never edited.
|
# #4145: emitted artifact of src/pristine-baseline.cts — never edited.
|
||||||
/gsd-core/bin/lib/pristine-baseline.cjs
|
/msd-core/bin/lib/pristine-baseline.cjs
|
||||||
/gsd-core/bin/lib/code-review-flags.cjs
|
/msd-core/bin/lib/code-review-flags.cjs
|
||||||
/gsd-core/bin/lib/code-review-depth.cjs
|
/msd-core/bin/lib/code-review-depth.cjs
|
||||||
/gsd-core/bin/lib/context-utilization.cjs
|
/msd-core/bin/lib/context-utilization.cjs
|
||||||
/gsd-core/bin/lib/artifacts.cjs
|
/msd-core/bin/lib/artifacts.cjs
|
||||||
/gsd-core/bin/lib/command-arg-projection.cjs
|
/msd-core/bin/lib/command-arg-projection.cjs
|
||||||
/gsd-core/bin/lib/clock.cjs
|
/msd-core/bin/lib/clock.cjs
|
||||||
/gsd-core/bin/lib/ui-safety-gate.cjs
|
/msd-core/bin/lib/ui-safety-gate.cjs
|
||||||
/gsd-core/bin/lib/ui-frontend-evidence.cjs
|
/msd-core/bin/lib/ui-frontend-evidence.cjs
|
||||||
/gsd-core/bin/lib/review-reviewer-selection.cjs
|
/msd-core/bin/lib/review-reviewer-selection.cjs
|
||||||
/gsd-core/bin/lib/review-lane-descriptor.cjs
|
/msd-core/bin/lib/review-lane-descriptor.cjs
|
||||||
/gsd-core/bin/lib/review-lane-invocation.cjs
|
/msd-core/bin/lib/review-lane-invocation.cjs
|
||||||
/gsd-core/bin/lib/review-lane-runner.cjs
|
/msd-core/bin/lib/review-lane-runner.cjs
|
||||||
/gsd-core/bin/lib/reviewer-step-dispatch.cjs
|
/msd-core/bin/lib/reviewer-step-dispatch.cjs
|
||||||
/gsd-core/bin/lib/clusters.cjs
|
/msd-core/bin/lib/clusters.cjs
|
||||||
/gsd-core/bin/lib/installer-migrations/001-legacy-orphan-files.cjs
|
/msd-core/bin/lib/installer-migrations/001-legacy-orphan-files.cjs
|
||||||
/gsd-core/bin/lib/observability/redaction.cjs
|
/msd-core/bin/lib/observability/redaction.cjs
|
||||||
/gsd-core/bin/lib/installer-migration-report.cjs
|
/msd-core/bin/lib/installer-migration-report.cjs
|
||||||
/gsd-core/bin/lib/prompt-budget.cjs
|
/msd-core/bin/lib/prompt-budget.cjs
|
||||||
/gsd-core/bin/lib/secrets.cjs
|
/msd-core/bin/lib/secrets.cjs
|
||||||
/gsd-core/bin/lib/smart-entry.cjs
|
/msd-core/bin/lib/smart-entry.cjs
|
||||||
/gsd-core/bin/lib/phase-lifecycle.cjs
|
/msd-core/bin/lib/phase-lifecycle.cjs
|
||||||
/gsd-core/bin/lib/workstream-name-policy.cjs
|
/msd-core/bin/lib/workstream-name-policy.cjs
|
||||||
/gsd-core/bin/lib/decisions.cjs
|
/msd-core/bin/lib/decisions.cjs
|
||||||
/gsd-core/bin/lib/teams-status.cjs
|
/msd-core/bin/lib/teams-status.cjs
|
||||||
/gsd-core/bin/lib/validate.cjs
|
/msd-core/bin/lib/validate.cjs
|
||||||
/gsd-core/bin/lib/schema-detect.cjs
|
/msd-core/bin/lib/schema-detect.cjs
|
||||||
/gsd-core/bin/lib/runtime-name-policy.cjs
|
/msd-core/bin/lib/runtime-name-policy.cjs
|
||||||
/gsd-core/bin/lib/runtime-identity.cjs
|
/msd-core/bin/lib/runtime-identity.cjs
|
||||||
/gsd-core/bin/lib/runtime-slash.cjs
|
/msd-core/bin/lib/runtime-slash.cjs
|
||||||
/gsd-core/bin/lib/observability/event.cjs
|
/msd-core/bin/lib/observability/event.cjs
|
||||||
/gsd-core/bin/lib/workstream-inventory-builder.cjs
|
/msd-core/bin/lib/workstream-inventory-builder.cjs
|
||||||
/gsd-core/bin/lib/plan-scan.cjs
|
/msd-core/bin/lib/plan-scan.cjs
|
||||||
/gsd-core/bin/lib/fallow-runner.cjs
|
/msd-core/bin/lib/fallow-runner.cjs
|
||||||
/gsd-core/bin/lib/project-root.cjs
|
/msd-core/bin/lib/project-root.cjs
|
||||||
/gsd-core/bin/lib/installer-migration-authoring.cjs
|
/msd-core/bin/lib/installer-migration-authoring.cjs
|
||||||
/gsd-core/bin/lib/update-context.cjs
|
/msd-core/bin/lib/update-context.cjs
|
||||||
/gsd-core/bin/lib/installer-migrations/000-first-time-baseline.cjs
|
/msd-core/bin/lib/installer-migrations/000-first-time-baseline.cjs
|
||||||
/gsd-core/bin/lib/installer-migrations/008-cursor-retire-commands-surface.cjs
|
/msd-core/bin/lib/installer-migrations/008-cursor-retire-commands-surface.cjs
|
||||||
/gsd-core/bin/lib/retired-artifact-cleanup.cjs
|
/msd-core/bin/lib/retired-artifact-cleanup.cjs
|
||||||
/gsd-core/bin/lib/runtime-homes.cjs
|
/msd-core/bin/lib/runtime-homes.cjs
|
||||||
/gsd-core/bin/lib/model-catalog.cjs
|
/msd-core/bin/lib/model-catalog.cjs
|
||||||
/gsd-core/bin/lib/configuration.cjs
|
/msd-core/bin/lib/configuration.cjs
|
||||||
/gsd-core/bin/lib/state-document.cjs
|
/msd-core/bin/lib/state-document.cjs
|
||||||
/gsd-core/bin/lib/shell-command-projection.cjs
|
/msd-core/bin/lib/shell-command-projection.cjs
|
||||||
/gsd-core/bin/lib/security.cjs
|
/msd-core/bin/lib/security.cjs
|
||||||
/gsd-core/bin/lib/verification.cjs
|
/msd-core/bin/lib/verification.cjs
|
||||||
/gsd-core/bin/lib/verification-command-router.cjs
|
/msd-core/bin/lib/verification-command-router.cjs
|
||||||
/gsd-core/bin/lib/command-aliases.cjs
|
/msd-core/bin/lib/command-aliases.cjs
|
||||||
/gsd-core/bin/lib/config-schema.cjs
|
/msd-core/bin/lib/config-schema.cjs
|
||||||
/gsd-core/bin/lib/model-profiles.cjs
|
/msd-core/bin/lib/model-profiles.cjs
|
||||||
/gsd-core/bin/lib/installer-migrations/002-codex-legacy-hooks-json.cjs
|
/msd-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
|
/msd-core/bin/lib/installer-migrations/003-rename-get-shit-done-to-msd-core.cjs
|
||||||
/gsd-core/bin/lib/installer-migrations/004-prune-stale-pristine-snapshots.cjs
|
/msd-core/bin/lib/installer-migrations/004-prune-stale-pristine-snapshots.cjs
|
||||||
/gsd-core/bin/lib/installer-migrations/005-opencode-baseline-commands-dir.cjs
|
/msd-core/bin/lib/installer-migrations/005-opencode-baseline-commands-dir.cjs
|
||||||
/gsd-core/bin/lib/installer-migrations/006-pi-extension-cjs-to-js.cjs
|
/msd-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
|
/msd-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
|
/msd-core/bin/lib/installer-migrations/009-pi-retire-reserved-hooks-dir.cjs
|
||||||
/gsd-core/bin/lib/installer-migrations/010-antigravity-retire-confighome-artifacts.cjs
|
/msd-core/bin/lib/installer-migrations/010-antigravity-retire-confighome-artifacts.cjs
|
||||||
/gsd-core/bin/lib/observability/logger.cjs
|
/msd-core/bin/lib/observability/logger.cjs
|
||||||
/gsd-core/bin/lib/active-workstream-store.cjs
|
/msd-core/bin/lib/active-workstream-store.cjs
|
||||||
/gsd-core/bin/lib/adr-parser.cjs
|
/msd-core/bin/lib/adr-parser.cjs
|
||||||
/gsd-core/bin/lib/graphify.cjs
|
/msd-core/bin/lib/graphify.cjs
|
||||||
/gsd-core/bin/lib/graphify-command-router.cjs
|
/msd-core/bin/lib/graphify-command-router.cjs
|
||||||
/gsd-core/bin/lib/audit-command-router.cjs
|
/msd-core/bin/lib/audit-command-router.cjs
|
||||||
/gsd-core/bin/lib/intel-command-router.cjs
|
/msd-core/bin/lib/intel-command-router.cjs
|
||||||
/gsd-core/bin/lib/install-profiles.cjs
|
/msd-core/bin/lib/install-profiles.cjs
|
||||||
/gsd-core/bin/lib/intel.cjs
|
/msd-core/bin/lib/intel.cjs
|
||||||
/gsd-core/bin/lib/installer-migrations.cjs
|
/msd-core/bin/lib/installer-migrations.cjs
|
||||||
/gsd-core/bin/lib/worktree-base-ref.cjs
|
/msd-core/bin/lib/worktree-base-ref.cjs
|
||||||
/gsd-core/bin/lib/worktree-safety.cjs
|
/msd-core/bin/lib/worktree-safety.cjs
|
||||||
/gsd-core/bin/lib/planning-workspace.cjs
|
/msd-core/bin/lib/planning-workspace.cjs
|
||||||
/gsd-core/bin/lib/planning-scope.cjs
|
/msd-core/bin/lib/planning-scope.cjs
|
||||||
/gsd-core/bin/lib/planning-snapshot.cjs
|
/msd-core/bin/lib/planning-snapshot.cjs
|
||||||
/gsd-core/bin/lib/planning-document.cjs
|
/msd-core/bin/lib/planning-document.cjs
|
||||||
/gsd-core/bin/lib/planning-inspect.cjs
|
/msd-core/bin/lib/planning-inspect.cjs
|
||||||
/gsd-core/bin/lib/planning-command-router.cjs
|
/msd-core/bin/lib/planning-command-router.cjs
|
||||||
/gsd-core/bin/lib/plan-document.cjs
|
/msd-core/bin/lib/plan-document.cjs
|
||||||
/gsd-core/bin/lib/state-contract.cjs
|
/msd-core/bin/lib/state-contract.cjs
|
||||||
/gsd-core/bin/lib/pattern.cjs
|
/msd-core/bin/lib/pattern.cjs
|
||||||
/gsd-core/bin/lib/text-lines.cjs
|
/msd-core/bin/lib/text-lines.cjs
|
||||||
/gsd-core/bin/lib/token-scanner.cjs
|
/msd-core/bin/lib/token-scanner.cjs
|
||||||
/gsd-core/bin/lib/health-diagnostic-types.cjs
|
/msd-core/bin/lib/health-diagnostic-types.cjs
|
||||||
/gsd-core/bin/lib/health-diagnostic.cjs
|
/msd-core/bin/lib/health-diagnostic.cjs
|
||||||
/gsd-core/bin/lib/health-diagnostic-rules/root-existence.cjs
|
/msd-core/bin/lib/health-diagnostic-rules/root-existence.cjs
|
||||||
/gsd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs
|
/msd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs
|
||||||
/gsd-core/bin/lib/health-diagnostic-rules/config-validation.cjs
|
/msd-core/bin/lib/health-diagnostic-rules/config-validation.cjs
|
||||||
/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs
|
/msd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs
|
||||||
/gsd-core/bin/lib/health-diagnostic-rules/agent-install.cjs
|
/msd-core/bin/lib/health-diagnostic-rules/agent-install.cjs
|
||||||
/gsd-core/bin/lib/health-diagnostic-rules/roadmap-disk-consistency.cjs
|
/msd-core/bin/lib/health-diagnostic-rules/roadmap-disk-consistency.cjs
|
||||||
/gsd-core/bin/lib/health-diagnostic-rules/worktree-health.cjs
|
/msd-core/bin/lib/health-diagnostic-rules/worktree-health.cjs
|
||||||
/gsd-core/bin/lib/health-diagnostic-rules/milestone-archive-hygiene.cjs
|
/msd-core/bin/lib/health-diagnostic-rules/milestone-archive-hygiene.cjs
|
||||||
/gsd-core/bin/lib/health-diagnostic-rules/consistency.cjs
|
/msd-core/bin/lib/health-diagnostic-rules/consistency.cjs
|
||||||
/gsd-core/bin/lib/health-diagnostic-rules/install-surface-shadowing.cjs
|
/msd-core/bin/lib/health-diagnostic-rules/install-surface-shadowing.cjs
|
||||||
/gsd-core/bin/lib/command-roster.cjs
|
/msd-core/bin/lib/command-roster.cjs
|
||||||
/gsd-core/bin/lib/runtime-artifact-conversion.cjs
|
/msd-core/bin/lib/runtime-artifact-conversion.cjs
|
||||||
/gsd-core/bin/lib/runtime-artifact-layout.cjs
|
/msd-core/bin/lib/runtime-artifact-layout.cjs
|
||||||
/gsd-core/bin/lib/install-scope.cjs
|
/msd-core/bin/lib/install-scope.cjs
|
||||||
/gsd-core/bin/lib/install-fs-adapter.cjs
|
/msd-core/bin/lib/install-fs-adapter.cjs
|
||||||
/gsd-core/bin/lib/user-artifact-staging.cjs
|
/msd-core/bin/lib/user-artifact-staging.cjs
|
||||||
/gsd-core/bin/lib/installed-surface-resolver.cjs
|
/msd-core/bin/lib/installed-surface-resolver.cjs
|
||||||
/gsd-core/bin/lib/install-shadow-report.cjs
|
/msd-core/bin/lib/install-shadow-report.cjs
|
||||||
/gsd-core/bin/lib/runtime-config-adapter-registry.cjs
|
/msd-core/bin/lib/runtime-config-adapter-registry.cjs
|
||||||
/gsd-core/bin/lib/runtime-hooks-surface.cjs
|
/msd-core/bin/lib/runtime-hooks-surface.cjs
|
||||||
/gsd-core/bin/lib/command-routing-hub.cjs
|
/msd-core/bin/lib/command-routing-hub.cjs
|
||||||
/gsd-core/bin/lib/core-utils.cjs
|
/msd-core/bin/lib/core-utils.cjs
|
||||||
/gsd-core/bin/lib/io.cjs
|
/msd-core/bin/lib/io.cjs
|
||||||
/gsd-core/bin/lib/phase-id.cjs
|
/msd-core/bin/lib/phase-id.cjs
|
||||||
/gsd-core/bin/lib/phase-id-card.cjs
|
/msd-core/bin/lib/phase-id-card.cjs
|
||||||
/gsd-core/bin/lib/phase-id-display.cjs
|
/msd-core/bin/lib/phase-id-display.cjs
|
||||||
/gsd-core/bin/lib/normalize-test-command.cjs
|
/msd-core/bin/lib/normalize-test-command.cjs
|
||||||
/gsd-core/bin/lib/config-loader.cjs
|
/msd-core/bin/lib/config-loader.cjs
|
||||||
/gsd-core/bin/lib/unusable-input.cjs
|
/msd-core/bin/lib/unusable-input.cjs
|
||||||
/gsd-core/bin/lib/model-resolver.cjs
|
/msd-core/bin/lib/model-resolver.cjs
|
||||||
/gsd-core/bin/lib/loop-resolver.cjs
|
/msd-core/bin/lib/loop-resolver.cjs
|
||||||
/gsd-core/bin/lib/capability-state.cjs
|
/msd-core/bin/lib/capability-state.cjs
|
||||||
/gsd-core/bin/lib/capability-writer.cjs
|
/msd-core/bin/lib/capability-writer.cjs
|
||||||
/gsd-core/bin/lib/capability-activation.cjs
|
/msd-core/bin/lib/capability-activation.cjs
|
||||||
/gsd-core/bin/lib/federated-config.cjs
|
/msd-core/bin/lib/federated-config.cjs
|
||||||
/gsd-core/bin/lib/phase-locator.cjs
|
/msd-core/bin/lib/phase-locator.cjs
|
||||||
/gsd-core/bin/lib/plan-dependency-graph.cjs
|
/msd-core/bin/lib/plan-dependency-graph.cjs
|
||||||
# #3674: compiled from src/file-overlap-partitioner.cts (ADR-457 build-at-publish).
|
# #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).
|
# #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
|
# #3676: compiled from src/quick-batch-dispatch.cts and
|
||||||
# src/quick-batch-command-router.cts (ADR-457 build-at-publish).
|
# src/quick-batch-command-router.cts (ADR-457 build-at-publish).
|
||||||
/gsd-core/bin/lib/quick-batch-dispatch.cjs
|
/msd-core/bin/lib/quick-batch-dispatch.cjs
|
||||||
/gsd-core/bin/lib/quick-batch-command-router.cjs
|
/msd-core/bin/lib/quick-batch-command-router.cjs
|
||||||
/gsd-core/bin/lib/phase-estimation.cjs
|
/msd-core/bin/lib/phase-estimation.cjs
|
||||||
/gsd-core/bin/lib/estimate-cli.cjs
|
/msd-core/bin/lib/estimate-cli.cjs
|
||||||
/gsd-core/bin/lib/roadmap-parser.cjs
|
/msd-core/bin/lib/roadmap-parser.cjs
|
||||||
/gsd-core/bin/lib/drift.cjs
|
/msd-core/bin/lib/drift.cjs
|
||||||
/gsd-core/bin/lib/cjs-command-router-adapter.cjs
|
/msd-core/bin/lib/cjs-command-router-adapter.cjs
|
||||||
/gsd-core/bin/lib/phase-command-router.cjs
|
/msd-core/bin/lib/phase-command-router.cjs
|
||||||
/gsd-core/bin/lib/surface.cjs
|
/msd-core/bin/lib/surface.cjs
|
||||||
/gsd-core/bin/lib/gap-checker.cjs
|
/msd-core/bin/lib/gap-checker.cjs
|
||||||
/gsd-core/bin/lib/gate-predicate-evaluator.cjs
|
/msd-core/bin/lib/gate-predicate-evaluator.cjs
|
||||||
/gsd-core/bin/lib/docs.cjs
|
/msd-core/bin/lib/docs.cjs
|
||||||
/gsd-core/bin/lib/check-command-router.cjs
|
/msd-core/bin/lib/check-command-router.cjs
|
||||||
/gsd-core/bin/lib/verify-command-grounding.cjs
|
/msd-core/bin/lib/verify-command-grounding.cjs
|
||||||
/gsd-core/bin/lib/frontmatter.cjs
|
/msd-core/bin/lib/frontmatter.cjs
|
||||||
/gsd-core/bin/lib/learnings.cjs
|
/msd-core/bin/lib/learnings.cjs
|
||||||
/gsd-core/bin/lib/gsd2-import.cjs
|
/msd-core/bin/lib/gsd2-import.cjs
|
||||||
/gsd-core/bin/lib/profile-pipeline.cjs
|
/msd-core/bin/lib/profile-pipeline.cjs
|
||||||
/gsd-core/bin/lib/roadmap-upgrade.cjs
|
/msd-core/bin/lib/roadmap-upgrade.cjs
|
||||||
/gsd-core/bin/lib/phases-command-router.cjs
|
/msd-core/bin/lib/phases-command-router.cjs
|
||||||
/gsd-core/bin/lib/verify-command-router.cjs
|
/msd-core/bin/lib/verify-command-router.cjs
|
||||||
/gsd-core/bin/lib/eval.cjs
|
/msd-core/bin/lib/eval.cjs
|
||||||
/gsd-core/bin/lib/eval-command-router.cjs
|
/msd-core/bin/lib/eval-command-router.cjs
|
||||||
/gsd-core/bin/lib/init-command-router.cjs
|
/msd-core/bin/lib/init-command-router.cjs
|
||||||
/gsd-core/bin/lib/onboard-projection.cjs
|
/msd-core/bin/lib/onboard-projection.cjs
|
||||||
/gsd-core/bin/lib/agent-command-router.cjs
|
/msd-core/bin/lib/agent-command-router.cjs
|
||||||
/gsd-core/bin/lib/agent-install-check.cjs
|
/msd-core/bin/lib/agent-install-check.cjs
|
||||||
/gsd-core/bin/lib/codex-agent-toml.cjs
|
/msd-core/bin/lib/codex-agent-toml.cjs
|
||||||
/gsd-core/bin/lib/task-command-router.cjs
|
/msd-core/bin/lib/task-command-router.cjs
|
||||||
/gsd-core/bin/lib/validate-command-router.cjs
|
/msd-core/bin/lib/validate-command-router.cjs
|
||||||
/gsd-core/bin/lib/workstream-inventory.cjs
|
/msd-core/bin/lib/workstream-inventory.cjs
|
||||||
/gsd-core/bin/lib/roadmap-command-router.cjs
|
/msd-core/bin/lib/roadmap-command-router.cjs
|
||||||
/gsd-core/bin/lib/state-command-router.cjs
|
/msd-core/bin/lib/state-command-router.cjs
|
||||||
/gsd-core/bin/lib/config.cjs
|
/msd-core/bin/lib/config.cjs
|
||||||
/gsd-core/bin/lib/profile-output.cjs
|
/msd-core/bin/lib/profile-output.cjs
|
||||||
/gsd-core/bin/lib/template.cjs
|
/msd-core/bin/lib/template.cjs
|
||||||
/gsd-core/bin/lib/commands.cjs
|
/msd-core/bin/lib/commands.cjs
|
||||||
/gsd-core/bin/lib/state.cjs
|
/msd-core/bin/lib/state.cjs
|
||||||
/gsd-core/bin/lib/milestone.cjs
|
/msd-core/bin/lib/milestone.cjs
|
||||||
/gsd-core/bin/lib/phase.cjs
|
/msd-core/bin/lib/phase.cjs
|
||||||
/gsd-core/bin/lib/verify.cjs
|
/msd-core/bin/lib/verify.cjs
|
||||||
/gsd-core/bin/lib/init.cjs
|
/msd-core/bin/lib/init.cjs
|
||||||
/gsd-core/bin/lib/uat.cjs
|
/msd-core/bin/lib/uat.cjs
|
||||||
/gsd-core/bin/lib/coverage.cjs
|
/msd-core/bin/lib/coverage.cjs
|
||||||
/gsd-core/bin/lib/uat-predicate.cjs
|
/msd-core/bin/lib/uat-predicate.cjs
|
||||||
/gsd-core/bin/lib/workstream.cjs
|
/msd-core/bin/lib/workstream.cjs
|
||||||
/gsd-core/bin/lib/roadmap.cjs
|
/msd-core/bin/lib/roadmap.cjs
|
||||||
/gsd-core/bin/lib/audit.cjs
|
/msd-core/bin/lib/audit.cjs
|
||||||
/gsd-core/bin/lib/git-base-branch.cjs
|
/msd-core/bin/lib/git-base-branch.cjs
|
||||||
/gsd-core/bin/lib/host-runtime-detection.cjs
|
/msd-core/bin/lib/host-runtime-detection.cjs
|
||||||
/gsd-core/bin/lib/task-content-resolution.cjs
|
/msd-core/bin/lib/task-content-resolution.cjs
|
||||||
/gsd-core/bin/lib/tdd-red-evidence.cjs
|
/msd-core/bin/lib/tdd-red-evidence.cjs
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.pyc
|
*.pyc
|
||||||
.venv/
|
.venv/
|
||||||
@@ -325,10 +325,10 @@ venv/
|
|||||||
target/
|
target/
|
||||||
vendor/
|
vendor/
|
||||||
# Vendored third-party artifacts under version control on purpose — see
|
# 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
|
# (installed trees ship with no node_modules), so this one directory is a
|
||||||
# deliberate, tracked exception to the blanket `vendor/` ignore above.
|
# 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
|
# Source-side twin (tsc resolves a .cts module's relative imports against
|
||||||
# src/, not the output dir) of the same vendored artifact — see
|
# src/, not the output dir) of the same vendored artifact — see
|
||||||
# scripts/lint-vendored-deps.cjs, which keeps both copies in sync.
|
# scripts/lint-vendored-deps.cjs, which keeps both copies in sync.
|
||||||
@@ -349,7 +349,7 @@ entities.json
|
|||||||
claude-test-command.md
|
claude-test-command.md
|
||||||
|
|
||||||
# Observability audit trail (issue #177) — append-only, local only
|
# Observability audit trail (issue #177) — append-only, local only
|
||||||
.planning/.gsd-trace.jsonl
|
.planning/.msd-trace.jsonl
|
||||||
|
|
||||||
# Mutation testing artifacts (issue #454)
|
# Mutation testing artifacts (issue #454)
|
||||||
.stryker-tmp/
|
.stryker-tmp/
|
||||||
|
|||||||
@@ -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
|
* Architecture: SUBPROCESS REUSE. Instead of re-implementing hook logic inside
|
||||||
* the plugin, this file is a thin adapter that spawns the existing Claude Code
|
* 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)
|
* - block → throw Error (OpenCode returns the error to the model)
|
||||||
* - advisory → output.metadata + console.error (best-effort surfacing)
|
* - 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.
|
* via require(), keeping the single source of truth.
|
||||||
*
|
*
|
||||||
* ── Two distribution shapes, one adapter (issue #1914) ─────────────────────
|
* ── Two distribution shapes, one adapter (issue #1914) ─────────────────────
|
||||||
* This single file serves both distribution paths, distinguished at load time
|
* This single file serves both distribution paths, distinguished at load time
|
||||||
* by REPO_ROOT (path.resolve(__dirname, "../..")):
|
* by REPO_ROOT (path.resolve(__dirname, "../..")):
|
||||||
*
|
*
|
||||||
* • Option 1 — file copy (the supported GSD path). `bin/install.js` copies
|
* • Option 1 — file copy (the supported MSD path). `bin/install.js` copies
|
||||||
* this file to <opencodeConfigDir>/plugins/gsd-core.js, so REPO_ROOT is the
|
* this file to <opencodeConfigDir>/plugins/msd-core.js, so REPO_ROOT is the
|
||||||
* OpenCode config dir. GSD's own install already stages `hooks/*.js` and
|
* OpenCode config dir. MSD's own install already stages `hooks/*.js` and
|
||||||
* `gsd-core/` there (ADR-857 skips hook *registration* for OpenCode, not the
|
* `msd-core/` there (ADR-857 skips hook *registration* for OpenCode, not the
|
||||||
* file copy), so the hook bridge and content rewriting resolve natively.
|
* 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
|
* this mode, so the plugin's own config-hook registration is redundant and is
|
||||||
* SKIPPED (see IS_PACKAGE_TREE) to avoid double-registration.
|
* SKIPPED (see IS_PACKAGE_TREE) to avoid double-registration.
|
||||||
*
|
*
|
||||||
* • Option 2 — package / git-spec. When loaded from the package tree (npm
|
* • 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
|
* `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.
|
* plugin IS the sole registrar, so it registers commands/agents/skills too.
|
||||||
*
|
*
|
||||||
* IS_PACKAGE_TREE keys off the presence of the SOURCE command layout
|
* 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
|
* config dir (that uses the flattened command/ layout). The hook bridge and
|
||||||
* Read-time content rewriting run in BOTH modes; only the config-hook
|
* Read-time content rewriting run in BOTH modes; only the config-hook
|
||||||
* registration of commands/agents/skills is gated.
|
* registration of commands/agents/skills is gated.
|
||||||
*
|
*
|
||||||
* Runtime-specific hooks are deliberately excluded:
|
* Runtime-specific hooks are deliberately excluded:
|
||||||
* - gsd-statusline.js / gsd-update-banner.js (Claude Code statusline)
|
* - msd-statusline.js / msd-update-banner.js (Claude Code statusline)
|
||||||
* - gsd-cursor-*.js (Cursor-specific)
|
* - msd-cursor-*.js (Cursor-specific)
|
||||||
* - *.sh scripts (invoked directly by commands/agents, not hook events)
|
* - *.sh scripts (invoked directly by commands/agents, not hook events)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -51,12 +51,12 @@ const fs = require("fs");
|
|||||||
const os = require("os");
|
const os = require("os");
|
||||||
const { spawnSync } = require("child_process");
|
const { spawnSync } = require("child_process");
|
||||||
|
|
||||||
// Resolve REPO_ROOT to the directory that actually holds the GSD payload
|
// Resolve REPO_ROOT to the directory that actually holds the MSD payload
|
||||||
// (hooks/ + gsd-core/). This must work across three physical layouts because a
|
// (hooks/ + msd-core/). This must work across three physical layouts because a
|
||||||
// single adapter file serves both distribution shapes (see header):
|
// single adapter file serves both distribution shapes (see header):
|
||||||
// • package/git-spec tree: <root>/.opencode/plugins/gsd-core.js → <root>
|
// • package/git-spec tree: <root>/.opencode/plugins/msd-core.js → <root>
|
||||||
// • global file-copy: ~/.config/opencode/plugins/gsd-core.js → ~/.config/opencode
|
// • global file-copy: ~/.config/opencode/plugins/msd-core.js → ~/.config/opencode
|
||||||
// • local file-copy: <proj>/.opencode/plugins/gsd-core.js → <proj>/.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
|
// A fixed "../.." only works for the first; the copied layouts sit one level
|
||||||
// shallower. Walking up to the first ancestor containing BOTH payload markers
|
// shallower. Walking up to the first ancestor containing BOTH payload markers
|
||||||
// resolves all three deterministically. Falls back to the package-tree
|
// resolves all three deterministically. Falls back to the package-tree
|
||||||
@@ -66,7 +66,7 @@ function resolveRepoRoot(startDir) {
|
|||||||
for (let i = 0; i < 6; i++) {
|
for (let i = 0; i < 6; i++) {
|
||||||
if (
|
if (
|
||||||
fs.existsSync(path.join(dir, "hooks")) &&
|
fs.existsSync(path.join(dir, "hooks")) &&
|
||||||
fs.existsSync(path.join(dir, "gsd-core"))
|
fs.existsSync(path.join(dir, "msd-core"))
|
||||||
) {
|
) {
|
||||||
return dir;
|
return dir;
|
||||||
}
|
}
|
||||||
@@ -84,16 +84,16 @@ function resolveRepoRoot(startDir) {
|
|||||||
// CJS: __dirname is a global, no need to derive from import.meta.url
|
// CJS: __dirname is a global, no need to derive from import.meta.url
|
||||||
const REPO_ROOT = resolveRepoRoot(__dirname);
|
const REPO_ROOT = resolveRepoRoot(__dirname);
|
||||||
const HOOKS_DIR = path.join(REPO_ROOT, "hooks");
|
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 AGENTS = path.join(REPO_ROOT, "agents");
|
||||||
const SKILLS = path.join(REPO_ROOT, "skills");
|
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
|
// 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
|
// 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
|
// 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);
|
const IS_PACKAGE_TREE = fs.existsSync(COMMANDS);
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -198,7 +198,7 @@ function mapToolInput(args) {
|
|||||||
* - exit 2: block (Claude convention; reason in stdout JSON)
|
* - exit 2: block (Claude convention; reason in stdout JSON)
|
||||||
* - any error: exit 0 silently (hooks swallow their own errors)
|
* - 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} payload stdin JSON (hook_event_name, tool_name, ...)
|
||||||
* @param {object} [opts]
|
* @param {object} [opts]
|
||||||
* @param {number} [opts.timeout=8000] spawn timeout in ms
|
* @param {number} [opts.timeout=8000] spawn timeout in ms
|
||||||
@@ -217,9 +217,9 @@ function runHook(hookFile, payload, opts = {}) {
|
|||||||
if (!warnedMissingHooks.has(hookFile)) {
|
if (!warnedMissingHooks.has(hookFile)) {
|
||||||
warnedMissingHooks.add(hookFile);
|
warnedMissingHooks.add(hookFile);
|
||||||
console.error(
|
console.error(
|
||||||
`[gsd-core] hook script missing: ${hookPath} — ${hookFile} is NOT ` +
|
`[msd-core] hook script missing: ${hookPath} — ${hookFile} is NOT ` +
|
||||||
"enforced. The GSD install may be incomplete; reinstall (or run " +
|
"enforced. The MSD install may be incomplete; reinstall (or run " +
|
||||||
"/gsd-update) to restage the hooks/ bundle.",
|
"/msd-update) to restage the hooks/ bundle.",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return { stdout: "", exitCode: 0, timedOut: false };
|
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
|
* In-process check for whether context-usage warnings are disabled in project
|
||||||
* config. Mirrors the exact semantics of the same check inside
|
* 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
|
* `config.hooks.context_warnings === false` disables them; a missing or
|
||||||
* unparseable .planning/config.json keeps them enabled (the default).
|
* 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.
|
* 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
|
* - 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
|
* - Silent → no-op
|
||||||
*
|
*
|
||||||
* @param {{ stdout: string, exitCode: number }} hookResult
|
* @param {{ stdout: string, exitCode: number }} hookResult
|
||||||
@@ -301,7 +301,7 @@ function handleHookResult(hookResult, output) {
|
|||||||
const isBlock = exitCode === 2 || (parsed && parsed.decision === "block");
|
const isBlock = exitCode === 2 || (parsed && parsed.decision === "block");
|
||||||
if (isBlock) {
|
if (isBlock) {
|
||||||
const reason =
|
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);
|
throw new Error(reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,10 +317,10 @@ function handleHookResult(hookResult, output) {
|
|||||||
// sequence (prompt guard, read guard, worktree guard, workflow guard).
|
// sequence (prompt guard, read guard, worktree guard, workflow guard).
|
||||||
// Storing a scalar would let a later advisory clobber an earlier one, so
|
// Storing a scalar would let a later advisory clobber an earlier one, so
|
||||||
// collect them all.
|
// collect them all.
|
||||||
if (!Array.isArray(output.metadata._gsdAdvisory)) {
|
if (!Array.isArray(output.metadata._msdAdvisory)) {
|
||||||
output.metadata._gsdAdvisory = [];
|
output.metadata._msdAdvisory = [];
|
||||||
}
|
}
|
||||||
output.metadata._gsdAdvisory.push(advisory);
|
output.metadata._msdAdvisory.push(advisory);
|
||||||
}
|
}
|
||||||
// Best-effort visibility when metadata isn't surfaced to the model
|
// Best-effort visibility when metadata isn't surfaced to the model
|
||||||
console.error(advisory);
|
console.error(advisory);
|
||||||
@@ -347,7 +347,7 @@ function parseFrontmatter(content) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Rewrite @~/.claude/ includes to point at the repo root.
|
// 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).
|
// transform from scripts/fix-slash-commands.cjs (single source of truth).
|
||||||
function rewriteRefs(content) {
|
function rewriteRefs(content) {
|
||||||
let out = content.replace(/@~\/\.claude\//g, `@${REPO_ROOT}/`);
|
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
|
// refs. When the model reads these via the Read tool, we transparently rewrite
|
||||||
// both so OpenCode sees correct paths and hyphen-form command names.
|
// both so OpenCode sees correct paths and hyphen-form command names.
|
||||||
const GSD_MANAGED_DIRS = [
|
const MSD_MANAGED_DIRS = [
|
||||||
path.join(GSD_CORE, "workflows"),
|
path.join(MSD_CORE, "workflows"),
|
||||||
path.join(GSD_CORE, "references"),
|
path.join(MSD_CORE, "references"),
|
||||||
path.join(GSD_CORE, "templates"),
|
path.join(MSD_CORE, "templates"),
|
||||||
path.join(GSD_CORE, "contexts"),
|
path.join(MSD_CORE, "contexts"),
|
||||||
COMMANDS,
|
COMMANDS,
|
||||||
AGENTS,
|
AGENTS,
|
||||||
SKILLS,
|
SKILLS,
|
||||||
];
|
];
|
||||||
|
|
||||||
function isGsdManagedFile(filePath) {
|
function isMsdManagedFile(filePath) {
|
||||||
if (!filePath) return false;
|
if (!filePath) return false;
|
||||||
const resolved = path.resolve(filePath);
|
const resolved = path.resolve(filePath);
|
||||||
return GSD_MANAGED_DIRS.some(
|
return MSD_MANAGED_DIRS.some(
|
||||||
(dir) => resolved === dir || resolved.startsWith(dir + path.sep),
|
(dir) => resolved === dir || resolved.startsWith(dir + path.sep),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rewrite content for OpenCode consumption:
|
// Rewrite content for OpenCode consumption:
|
||||||
// 1. @-include paths: @~/.claude/ → @<REPO_ROOT>/
|
// 1. @-include paths: @~/.claude/ → @<REPO_ROOT>/
|
||||||
// 2. plain-text paths: ~/.claude/gsd-core/ → <GSD_CORE>/
|
// 2. plain-text paths: ~/.claude/msd-core/ → <MSD_CORE>/
|
||||||
// 3. namespace: gsd:xxx → gsd-xxx (via fix-slash-commands.cjs)
|
// 3. namespace: msd:xxx → msd-xxx (via fix-slash-commands.cjs)
|
||||||
function rewriteContent(content) {
|
function rewriteContent(content) {
|
||||||
let out = content;
|
let out = content;
|
||||||
out = out.replace(/@~\/\.claude\//g, `@${REPO_ROOT}/`);
|
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();
|
const transform = getNamespaceConverter();
|
||||||
if (transform && _cmdNames && _cmdNames.length) {
|
if (transform && _cmdNames && _cmdNames.length) {
|
||||||
out = transform(out, _cmdNames);
|
out = transform(out, _cmdNames);
|
||||||
@@ -415,18 +415,18 @@ function rewriteContent(content) {
|
|||||||
//
|
//
|
||||||
// OpenCode's skill loader reads SKILL.md files directly from disk and resolves
|
// OpenCode's skill loader reads SKILL.md files directly from disk and resolves
|
||||||
// @-includes internally — this bypasses our tool.execute hooks. To make
|
// @-includes internally — this bypasses our tool.execute hooks. To make
|
||||||
// @~/.claude/gsd-core/... includes resolve, we copy all SKILL.md files to a
|
// @~/.claude/msd-core/... includes resolve, we copy all SKILL.md files to a
|
||||||
// cache directory with paths rewritten to the actual GSD_CORE location.
|
// cache directory with paths rewritten to the actual MSD_CORE location.
|
||||||
//
|
//
|
||||||
// Only used in package-tree mode (Option 2). In an installed OpenCode config
|
// 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).
|
// copy, so we never register skills from the plugin (see IS_PACKAGE_TREE).
|
||||||
|
|
||||||
const SKILLS_CACHE = path.join(
|
const SKILLS_CACHE = path.join(
|
||||||
os.homedir(),
|
os.homedir(),
|
||||||
".cache",
|
".cache",
|
||||||
"opencode",
|
"opencode",
|
||||||
"gsd-skills",
|
"msd-skills",
|
||||||
);
|
);
|
||||||
|
|
||||||
function prepareSkillsCache() {
|
function prepareSkillsCache() {
|
||||||
@@ -439,8 +439,8 @@ function prepareSkillsCache() {
|
|||||||
// Rewrite @-include paths only; namespace conversion is handled at
|
// Rewrite @-include paths only; namespace conversion is handled at
|
||||||
// Read-time via tool.execute.after for workflow/reference files.
|
// Read-time via tool.execute.after for workflow/reference files.
|
||||||
const rewritten = raw
|
const rewritten = raw
|
||||||
.replace(/@~\/\.claude\/gsd-core\//g, `@${GSD_CORE}/`)
|
.replace(/@~\/\.claude\/msd-core\//g, `@${MSD_CORE}/`)
|
||||||
.replace(/~\/\.claude\/gsd-core\//g, `${GSD_CORE}/`);
|
.replace(/~\/\.claude\/msd-core\//g, `${MSD_CORE}/`);
|
||||||
const destDir = path.join(SKILLS_CACHE, dir);
|
const destDir = path.join(SKILLS_CACHE, dir);
|
||||||
fs.mkdirSync(destDir, { recursive: true });
|
fs.mkdirSync(destDir, { recursive: true });
|
||||||
fs.writeFileSync(path.join(destDir, "SKILL.md"), rewritten);
|
fs.writeFileSync(path.join(destDir, "SKILL.md"), rewritten);
|
||||||
@@ -452,25 +452,25 @@ function prepareSkillsCache() {
|
|||||||
// Plugin entry
|
// Plugin entry
|
||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
|
|
||||||
const GsdCorePlugin = async ({ directory } = {}) => {
|
const MsdCorePlugin = async ({ directory } = {}) => {
|
||||||
if (directory) currentCwd = directory;
|
if (directory) currentCwd = directory;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// ── Config: register commands / agents / skills paths ──────────────
|
// ── Config: register commands / agents / skills paths ──────────────
|
||||||
// Only in package-tree mode (Option 2). In an installed config dir
|
// 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.
|
// plugin stays out of registration to avoid double-registering.
|
||||||
config: async (config) => {
|
config: async (config) => {
|
||||||
if (!IS_PACKAGE_TREE) return;
|
if (!IS_PACKAGE_TREE) return;
|
||||||
|
|
||||||
// Commands (commands/gsd/*.md → gsd-<name>)
|
// Commands (commands/msd/*.md → msd-<name>)
|
||||||
config.command = config.command || {};
|
config.command = config.command || {};
|
||||||
const cmds = loadDir(
|
const cmds = loadDir(
|
||||||
COMMANDS,
|
COMMANDS,
|
||||||
(f) => "gsd-" + f.slice(0, -3),
|
(f) => "msd-" + f.slice(0, -3),
|
||||||
(body, fm, name) => ({
|
(body, fm, name) => ({
|
||||||
template: rewriteRefs(body.trim()),
|
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)) {
|
for (const [k, v] of Object.entries(cmds)) {
|
||||||
@@ -484,7 +484,7 @@ const GsdCorePlugin = async ({ directory } = {}) => {
|
|||||||
(f) => f.slice(0, -3),
|
(f) => f.slice(0, -3),
|
||||||
(body, fm, name) => ({
|
(body, fm, name) => ({
|
||||||
prompt: rewriteRefs(body.trim()),
|
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",
|
mode: fm.mode || "subagent",
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@@ -508,7 +508,7 @@ const GsdCorePlugin = async ({ directory } = {}) => {
|
|||||||
// ── shell.env ───────────────────────────────────────────────────────
|
// ── shell.env ───────────────────────────────────────────────────────
|
||||||
"shell.env": async (_input, output) => {
|
"shell.env": async (_input, output) => {
|
||||||
output.env = output.env || {};
|
output.env = output.env || {};
|
||||||
output.env.GSD_DIR = GSD_CORE;
|
output.env.MSD_DIR = MSD_CORE;
|
||||||
},
|
},
|
||||||
|
|
||||||
// ── tool.execute.before — PreToolUse hooks ─────────────────────────
|
// ── tool.execute.before — PreToolUse hooks ─────────────────────────
|
||||||
@@ -517,14 +517,14 @@ const GsdCorePlugin = async ({ directory } = {}) => {
|
|||||||
const toolInput = mapToolInput(output.args || {});
|
const toolInput = mapToolInput(output.args || {});
|
||||||
const cwd = currentCwd;
|
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
|
// so the model can read workflow/reference/template files that SKILL.md
|
||||||
// and command templates reference via the canonical Claude path.
|
// and command templates reference via the canonical Claude path.
|
||||||
if (claudeTool === "Read" && toolInput.file_path) {
|
if (claudeTool === "Read" && toolInput.file_path) {
|
||||||
const original = toolInput.file_path;
|
const original = toolInput.file_path;
|
||||||
const rewritten = original
|
const rewritten = original
|
||||||
.replace(/^~\/\.claude\/gsd-core\//, GSD_CORE + "/")
|
.replace(/^~\/\.claude\/msd-core\//, MSD_CORE + "/")
|
||||||
.replace(/(?:.*)\/\.claude\/gsd-core\//, GSD_CORE + "/");
|
.replace(/(?:.*)\/\.claude\/msd-core\//, MSD_CORE + "/");
|
||||||
if (rewritten !== original) {
|
if (rewritten !== original) {
|
||||||
const args = output.args || {};
|
const args = output.args || {};
|
||||||
if (args.filePath) args.filePath = rewritten;
|
if (args.filePath) args.filePath = rewritten;
|
||||||
@@ -539,7 +539,7 @@ const GsdCorePlugin = async ({ directory } = {}) => {
|
|||||||
cwd,
|
cwd,
|
||||||
};
|
};
|
||||||
// NOTE: session_id intentionally omitted for PreToolUse hooks.
|
// 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.
|
// session and skips its advisory. On OpenCode we WANT the advisory.
|
||||||
const prePayload = (overrides = {}) => ({
|
const prePayload = (overrides = {}) => ({
|
||||||
...basePayload,
|
...basePayload,
|
||||||
@@ -550,42 +550,42 @@ const GsdCorePlugin = async ({ directory } = {}) => {
|
|||||||
|
|
||||||
const isWriteLike = ["Write", "Edit", "MultiEdit"].includes(claudeTool);
|
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") {
|
if (claudeTool === "Write" || claudeTool === "Edit") {
|
||||||
const r = runHook("gsd-prompt-guard.js", prePayload());
|
const r = runHook("msd-prompt-guard.js", prePayload());
|
||||||
handleHookResult(r, output);
|
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") {
|
if (claudeTool === "Write" || claudeTool === "Edit") {
|
||||||
const r = runHook("gsd-read-guard.js", prePayload());
|
const r = runHook("msd-read-guard.js", prePayload());
|
||||||
handleHookResult(r, output);
|
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) {
|
if (isWriteLike) {
|
||||||
const r = runHook("gsd-worktree-path-guard.js", prePayload());
|
const r = runHook("msd-worktree-path-guard.js", prePayload());
|
||||||
handleHookResult(r, output);
|
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)
|
// .planning/ artifacts (ROADMAP.md, milestones/*-ROADMAP.md, STATE.md)
|
||||||
if (claudeTool === "Write") {
|
if (claudeTool === "Write") {
|
||||||
const r = runHook("gsd-write-guard.js", prePayload());
|
const r = runHook("msd-write-guard.js", prePayload());
|
||||||
handleHookResult(r, output);
|
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)
|
// (covers Write/Edit/MultiEdit AND Bash force-add detection)
|
||||||
if (isWriteLike || claudeTool === "Bash") {
|
if (isWriteLike || claudeTool === "Bash") {
|
||||||
const r = runHook("gsd-workflow-guard.js", prePayload());
|
const r = runHook("msd-workflow-guard.js", prePayload());
|
||||||
handleHookResult(r, output);
|
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)
|
// .secrets via Read (file_path), Grep (path or glob) and Bash (command)
|
||||||
if (["Read", "Grep", "Bash"].includes(claudeTool)) {
|
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);
|
handleHookResult(r, output);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -598,12 +598,12 @@ const GsdCorePlugin = async ({ directory } = {}) => {
|
|||||||
const toolInput = mapToolInput(input.args || {});
|
const toolInput = mapToolInput(input.args || {});
|
||||||
const cwd = currentCwd;
|
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.
|
// BEFORE injection scanning so the scanner sees the final content.
|
||||||
if (
|
if (
|
||||||
claudeTool === "Read" &&
|
claudeTool === "Read" &&
|
||||||
output.output &&
|
output.output &&
|
||||||
isGsdManagedFile(toolInput.file_path)
|
isMsdManagedFile(toolInput.file_path)
|
||||||
) {
|
) {
|
||||||
const content =
|
const content =
|
||||||
typeof output.output === "string"
|
typeof output.output === "string"
|
||||||
@@ -612,7 +612,7 @@ const GsdCorePlugin = async ({ directory } = {}) => {
|
|||||||
output.output = rewriteContent(content);
|
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 (
|
if (
|
||||||
claudeTool === "Read" ||
|
claudeTool === "Read" ||
|
||||||
claudeTool === "WebFetch" ||
|
claudeTool === "WebFetch" ||
|
||||||
@@ -625,12 +625,12 @@ const GsdCorePlugin = async ({ directory } = {}) => {
|
|||||||
tool_response: output.output,
|
tool_response: output.output,
|
||||||
cwd,
|
cwd,
|
||||||
};
|
};
|
||||||
const r = runHook("gsd-read-injection-scanner.js", payload);
|
const r = runHook("msd-read-injection-scanner.js", payload);
|
||||||
handleHookResult(r, output);
|
handleHookResult(r, output);
|
||||||
return;
|
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).
|
// Only meaningful when a session_id is tracked (writes metrics sentinel).
|
||||||
// #2697: skip the subprocess spawn entirely when context warnings are
|
// #2697: skip the subprocess spawn entirely when context warnings are
|
||||||
// explicitly disabled in project config — the hook would exit early anyway,
|
// explicitly disabled in project config — the hook would exit early anyway,
|
||||||
@@ -644,7 +644,7 @@ const GsdCorePlugin = async ({ directory } = {}) => {
|
|||||||
session_id: currentSessionId,
|
session_id: currentSessionId,
|
||||||
cwd,
|
cwd,
|
||||||
};
|
};
|
||||||
const r = runHook("gsd-context-monitor.js", payload);
|
const r = runHook("msd-context-monitor.js", payload);
|
||||||
handleHookResult(r, output);
|
handleHookResult(r, output);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -657,13 +657,13 @@ const GsdCorePlugin = async ({ directory } = {}) => {
|
|||||||
session_id: currentSessionId,
|
session_id: currentSessionId,
|
||||||
cwd: currentCwd,
|
cwd: currentCwd,
|
||||||
};
|
};
|
||||||
const r = runHook("gsd-context-monitor.js", payload);
|
const r = runHook("msd-context-monitor.js", payload);
|
||||||
handleHookResult(r, output);
|
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 = output.context || [];
|
||||||
output.context.push(
|
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;
|
info?.id || event.sessionID || event.session_id || null;
|
||||||
if (info?.directory) currentCwd = info.directory;
|
if (info?.directory) currentCwd = info.directory;
|
||||||
|
|
||||||
// gsd-ensure-canonical-path.js — no stdin dependency; silent
|
// msd-ensure-canonical-path.js — no stdin dependency; silent
|
||||||
runHook("gsd-ensure-canonical-path.js", {
|
runHook("msd-ensure-canonical-path.js", {
|
||||||
hook_event_name: "SessionStart",
|
hook_event_name: "SessionStart",
|
||||||
session_id: currentSessionId,
|
session_id: currentSessionId,
|
||||||
cwd: currentCwd,
|
cwd: currentCwd,
|
||||||
});
|
});
|
||||||
// gsd-check-update.js — spawns its own background worker; no stdin
|
// msd-check-update.js — spawns its own background worker; no stdin
|
||||||
runHook("gsd-check-update.js", {
|
runHook("msd-check-update.js", {
|
||||||
hook_event_name: "SessionStart",
|
hook_event_name: "SessionStart",
|
||||||
session_id: currentSessionId,
|
session_id: currentSessionId,
|
||||||
cwd: currentCwd,
|
cwd: currentCwd,
|
||||||
@@ -709,17 +709,17 @@ const GsdCorePlugin = async ({ directory } = {}) => {
|
|||||||
event: "change",
|
event: "change",
|
||||||
cwd,
|
cwd,
|
||||||
};
|
};
|
||||||
const r = runHook("gsd-config-reload.js", payload);
|
const r = runHook("msd-config-reload.js", payload);
|
||||||
// Advisory-only (additionalContext); surface to logs
|
// Advisory-only (additionalContext); surface to logs
|
||||||
handleHookResult(r);
|
handleHookResult(r);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// session.idle ↔ Claude Stop lifecycle point (#1682 Slice 1b/c).
|
// 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
|
// Stop equivalent — the opencode-subset lifecycle peer of compaction
|
||||||
// (compaction preserves state across context-window summarization; idle
|
// (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
|
// persisted to .planning/), but it MUST be recognized so the declared
|
||||||
// opencode-subset surface is fully wired and a future Stop-class hook can
|
// opencode-subset surface is fully wired and a future Stop-class hook can
|
||||||
// attach without a plugin change.
|
// attach without a plugin change.
|
||||||
@@ -728,9 +728,9 @@ const GsdCorePlugin = async ({ directory } = {}) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// permission.asked / permission.replied — OpenCode permission lifecycle
|
// 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
|
// 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
|
// so these are recognized sentinels — wired so a future permission-aware
|
||||||
// gate can attach without a plugin change (the engine owns phase
|
// gate can attach without a plugin change (the engine owns phase
|
||||||
// sequencing; this host bus is session/tool/permission-scoped, never
|
// sequencing; this host bus is session/tool/permission-scoped, never
|
||||||
@@ -739,7 +739,7 @@ const GsdCorePlugin = async ({ directory } = {}) => {
|
|||||||
return;
|
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/);
|
// hook fires here today (loop state is already persisted to .planning/);
|
||||||
// recognized so the declared extension-event surface is fully wired and a
|
// recognized so the declared extension-event surface is fully wired and a
|
||||||
// future error-class hook can attach without a plugin change.
|
// 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
|
// 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
|
// CommonJS file, `mod` may be the raw `module.exports` OR an ESM namespace of
|
||||||
// the form `{ default: module.exports, ...syntheticNamedExports }`. A plain
|
// 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-
|
// appearing in `Object.values(mod)` (as a raw property, or as a lexer-
|
||||||
// synthesized named export) — which would trip the throw. Two defenses:
|
// synthesized named export) — which would trip the throw. Two defenses:
|
||||||
// 1. `id` is defined NON-ENUMERABLE, so it never appears in Object.values yet
|
// 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` =
|
// Result: raw-CJS `Object.values` = `[server]`; ESM `Object.values` =
|
||||||
// `[{server, <id non-enum>}]` — both fully extractable. Test-only helpers hang
|
// `[{server, <id non-enum>}]` — both fully extractable. Test-only helpers hang
|
||||||
// off the `server` FUNCTION (`server._internals`), never as a sibling export.
|
// off the `server` FUNCTION (`server._internals`), never as a sibling export.
|
||||||
GsdCorePlugin._internals = {
|
MsdCorePlugin._internals = {
|
||||||
REPO_ROOT,
|
REPO_ROOT,
|
||||||
IS_PACKAGE_TREE,
|
IS_PACKAGE_TREE,
|
||||||
mapToolName,
|
mapToolName,
|
||||||
mapToolInput,
|
mapToolInput,
|
||||||
parseFrontmatter,
|
parseFrontmatter,
|
||||||
rewriteContent,
|
rewriteContent,
|
||||||
isGsdManagedFile,
|
isMsdManagedFile,
|
||||||
handleHookResult,
|
handleHookResult,
|
||||||
GsdCorePlugin,
|
MsdCorePlugin,
|
||||||
};
|
};
|
||||||
|
|
||||||
const gsdCorePluginExport = { server: GsdCorePlugin };
|
const msdCorePluginExport = { server: MsdCorePlugin };
|
||||||
Object.defineProperty(gsdCorePluginExport, "id", {
|
Object.defineProperty(msdCorePluginExport, "id", {
|
||||||
value: "gsd-core",
|
value: "msd-core",
|
||||||
enumerable: false,
|
enumerable: false,
|
||||||
writable: false,
|
writable: false,
|
||||||
configurable: false,
|
configurable: false,
|
||||||
});
|
});
|
||||||
module.exports = gsdCorePluginExport;
|
module.exports = msdCorePluginExport;
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
"branch": "feat/3677-quick-batch-hardening-acceptance",
|
"branch": "feat/3677-quick-batch-hardening-acceptance",
|
||||||
"base_revision": "114dfcb739",
|
"base_revision": "114dfcb739",
|
||||||
"base_ref": "origin/next",
|
"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,
|
"prior_summary_reverified": true,
|
||||||
"step1_conclusion": "crash-window gap CONFIRMED REAL — see 40-design.md Open Question 1 / Resolution",
|
"step1_conclusion": "crash-window gap CONFIRMED REAL — see 40-design.md Open Question 1 / Resolution",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -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
|
A prior research pass produced a design doc + test matrix in this same
|
||||||
directory, but its worktree was garbage-collected before those files were
|
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,
|
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,
|
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
|
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
|
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
|
status/depends_on logic; it has no awareness of `PLAN.md`/`SUMMARY.md` on
|
||||||
disk.
|
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
|
`completeQuickItem` (Step 9) is "the ONLY writer of a 'Quick Tasks
|
||||||
Completed' STATE.md row" — i.e. the STATE.md row `hasQuickTaskRow` checks
|
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
|
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
|
(verification) both succeed. A crash between Step 6 and Step 7 crashes
|
||||||
before any STATE.md row exists, so `resumeBatch`'s only recovery signal
|
before any STATE.md row exists, so `resumeBatch`'s only recovery signal
|
||||||
never fires for this window.
|
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
|
`--resume`, `eligible` items flow straight into the SAME per-round loop
|
||||||
Step 3/planner-wave/worktree-dispatch use for a fresh batch — "the DAG-
|
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`
|
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."
|
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
|
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
|
`${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
|
whose PLAN.md already exists (planned before the crash) is correctly
|
||||||
skipped here — planning is NOT re-run. This is the file-existence guard
|
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
|
the prior summary described as absent; it is present, but only at the
|
||||||
PLANNING layer.
|
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
|
"Dispatch rounds") — re-derives eligibility every round via `quick-batch
|
||||||
resume --batch "$BATCH_ID" --raw` (same primitive as above, same blind
|
resume --batch "$BATCH_ID" --raw` (same primitive as above, same blind
|
||||||
spot), then spawns an executor for every item in `$spawn` (backpressure-
|
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 never issued this round's dispatch in the first place; a NEW
|
||||||
coordinator process re-deriving eligibility from scratch has no round
|
coordinator process re-deriving eligibility from scratch has no round
|
||||||
history to consult.
|
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
|
OWN mergeable-wave criterion is independent of the `eligible`/`spawn` list
|
||||||
entirely: "items that are `status == 'pending'` with a `SUMMARY.md` on
|
entirely: "items that are `status == 'pending'` with a `SUMMARY.md` on
|
||||||
disk... and NOT yet merged." This is correct and sufficient FOR MERGE — it
|
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,
|
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
|
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` +
|
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
|
`SUMMARY.md`) is never referenced again by anything — not cleaned up, not
|
||||||
merged via its own record, simply orphaned. If both executors happen to
|
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
|
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 |
|
| # | 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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
|
## 3. Prior-art grounding for new tests
|
||||||
|
|
||||||
- Hostile worktree-ownership test: follows the REAL-git-fixture pattern
|
- 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`,
|
(`initRepo`/`addWorktree`, real `executeWorktreeWaveCleanupPlan`,
|
||||||
`WORKTREE_AGENT_BRANCH_RE` branch-name validation already enforced at
|
`WORKTREE_AGENT_BRANCH_RE` branch-name validation already enforced at
|
||||||
`src/worktree-safety.cts:512`) — a manifest entry naming a path/branch
|
`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`
|
(`src/worktree-safety.cts:921-...`, `WAVE_CLEANUP_WARNING.SCOPE_OUT_OF_DECLARED`
|
||||||
at `:879-884`) end-to-end through a REAL git diff via
|
at `:879-884`) end-to-end through a REAL git diff via
|
||||||
`executeWorktreeWaveCleanupPlan`, mirroring the merge-conflict/undeclared-
|
`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
|
path outside `files_modified` and assert the merge still SUCCEEDS
|
||||||
(advisory, never blocking) while a warning with the frozen code is
|
(advisory, never blocking) while a warning with the frozen code is
|
||||||
produced.
|
produced.
|
||||||
@@ -164,7 +164,7 @@ the same pipeline for the same reason.
|
|||||||
separate, already-covered pre-dispatch decision, not a merge-time block).
|
separate, already-covered pre-dispatch decision, not a merge-time block).
|
||||||
- Crash-window regression test: structural assertion on
|
- Crash-window regression test: structural assertion on
|
||||||
`worktree-dispatch.md`'s prose, following the SAME established convention
|
`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
|
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
|
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,
|
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:
|
None of the new tests duplicate existing coverage:
|
||||||
- The merge-conflict/undeclared-deletion real-git tests already in
|
- 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
|
add sibling `describe` blocks for DIFFERENT manifest-entry shapes
|
||||||
(foreign ownership, out-of-scope-but-declared-nothing-wrong path,
|
(foreign ownership, out-of-scope-but-declared-nothing-wrong path,
|
||||||
submodule-bearing repo) using the same helpers, not modifying existing
|
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
|
## 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.
|
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).
|
(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
|
blocks: worktree-ownership tampering, advisory scope-drift, submodule
|
||||||
integration.
|
integration.
|
||||||
- `docs/how-to/batch-quick-tasks.md` — extend the "Resuming and failure
|
- `docs/how-to/batch-quick-tasks.md` — extend the "Resuming and failure
|
||||||
recovery" section with a preserved-worktree diagnosis subsection.
|
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.
|
mapping every #3344 AC bullet to its evidence.
|
||||||
- No `src/*.cts` production module changes required — the one functional
|
- No `src/*.cts` production module changes required — the one functional
|
||||||
fix lands entirely in workflow prose.
|
fix lands entirely in workflow prose.
|
||||||
@@ -241,7 +241,7 @@ None of the new tests duplicate existing coverage:
|
|||||||
itself needs crash-recovery semantics.
|
itself needs crash-recovery semantics.
|
||||||
4. **Skip the submodule/scope-drift/ownership tests as "already implied" by
|
4. **Skip the submodule/scope-drift/ownership tests as "already implied" by
|
||||||
unit-level coverage.** Rejected per this repo's own established
|
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`/
|
comment): pure-function assertions on `routeMergeOutcome`/
|
||||||
`planWaveScopeConformance` were previously judged insufficient without a
|
`planWaveScopeConformance` were previously judged insufficient without a
|
||||||
REAL git fixture proving the underlying primitive agrees; the same
|
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
|
### 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
|
§1's fix only asserted `readStep('worktree-dispatch.md')` + regex matches
|
||||||
against the MARKDOWN — proving the documentation says the right thing,
|
against the MARKDOWN — proving the documentation says the right thing,
|
||||||
never that the runtime condition (pending status + on-disk SUMMARY.md +
|
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
|
successful merge. Both real worktrees, their branches, and item 2's real
|
||||||
uncommitted-to-main commit survive completely untouched by either attempt.
|
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
|
("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
|
sibling's real BRANCH name is blocked") supplements (does not replace) the
|
||||||
original two tests, which still prove real, distinct boundaries
|
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
|
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
|
("`$WT_PATH`/`$WT_BRANCH`/`$EXPECTED_BASE` per item come from the recorded
|
||||||
`$QUICK_BATCH_WORKTREE_MANIFEST` entry Step 6 wrote for that `agent_id`")
|
`$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_WORKTREE_MANIFEST=$(mktemp ...)`) revealed that
|
||||||
`$QUICK_BATCH_WORKTREE_MANIFEST` — quick-batch explicitly models it on the
|
`$QUICK_BATCH_WORKTREE_MANIFEST` — quick-batch explicitly models it on the
|
||||||
SAME mechanism — is a fresh, PER-PROCESS `mktemp` file, not a durable
|
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
|
clear → a SUBSEQUENT `loadBatch` still succeeds even though the path no
|
||||||
longer exists) in `tests/quick-batch.test.cjs`'s new "durable
|
longer exists) in `tests/quick-batch.test.cjs`'s new "durable
|
||||||
worktree-recovery fields (#3677)" describe block, plus structural wiring
|
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)
|
### 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
|
- `src/quick-batch-dispatch.cts` — new `filterAlreadyExecuted` pure
|
||||||
function + `FilterAlreadyExecutedResult` type.
|
function + `FilterAlreadyExecutedResult` type.
|
||||||
- `src/quick-batch-command-router.cts` — new `filter-executed` CLI verb.
|
- `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
|
now calls `quick-batch filter-executed` instead of describing the split
|
||||||
only in prose; a new durable-persistence step after recording the
|
only in prose; a new durable-persistence step after recording the
|
||||||
ephemeral manifest entry.
|
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
|
for `$WT_PATH`/`$WT_BRANCH`/`$EXPECTED_BASE`; clears the triple on a
|
||||||
successful merge; fails closed when no record exists anywhere.
|
successful merge; fails closed when no record exists anywhere.
|
||||||
- Test files: `tests/quick-batch.test.cjs`, `tests/quick-batch-dispatch.test.cjs`,
|
- Test files: `tests/quick-batch.test.cjs`, `tests/quick-batch-dispatch.test.cjs`,
|
||||||
`tests/quick-batch-command-router.test.cjs`,
|
`tests/quick-batch-command-router.test.cjs`,
|
||||||
`tests/gsd-quick-batch-workflow.test.cjs`,
|
`tests/msd-quick-batch-workflow.test.cjs`,
|
||||||
`tests/gsd-quick-batch-merge-integration.test.cjs` — all gain new,
|
`tests/msd-quick-batch-merge-integration.test.cjs` — all gain new,
|
||||||
independently-verified (real fixture / real git, not merely prose-proxy)
|
independently-verified (real fixture / real git, not merely prose-proxy)
|
||||||
coverage per §9.1-9.3.
|
coverage per §9.1-9.3.
|
||||||
- §5's "No `src/*.cts` production module changes required" is SUPERSEDED —
|
- §5's "No `src/*.cts` production module changes required" is SUPERSEDED —
|
||||||
@@ -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 |
|
| 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" |
|
| 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/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" |
|
| 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/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" |
|
| 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/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" |
|
| 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" |
|
| 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
|
## Boundary coverage note
|
||||||
|
|
||||||
@@ -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
|
Maps every acceptance-criterion bullet in #3344 to its evidence. Phases 1-4
|
||||||
(#4190, #4212, and their prerequisite dispatch/wave-partitioner PRs) are
|
(#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 |
|
| 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` |
|
| 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/gsd/quick-batch.md` frontmatter tests; `docs/how-to/batch-quick-tasks.md` "Flags" |
|
| `--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/gsd-quick-batch-workflow.test.cjs` "objective documents --discuss/--full as rejected" |
|
| 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) |
|
| 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` |
|
| 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`) |
|
| 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
|
## 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`) |
|
| 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` |
|
| 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 |
|
| 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
|
## Isolation and Git safety
|
||||||
|
|
||||||
| AC bullet | Evidence |
|
| 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) |
|
| 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. |
|
| 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 | `gsd-core/workflows/quick-batch/steps/merge-wave.md` Step 7 design; `tests/quick-batch.test.cjs` wave recompute tests |
|
| 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/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) |
|
| 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 | `gsd-core/workflows/quick-batch/steps/worktree-dispatch.md` "ONE AT A TIME" serialization test |
|
| 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/gsd-quick-batch-merge-integration.test.cjs` (`--no-ff` real-git merges preserve commit history) |
|
| 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/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) |
|
| 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
|
## State, failure, and resume
|
||||||
|
|
||||||
| AC bullet | Evidence |
|
| 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 |
|
| 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`) |
|
| 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 |
|
| 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 |
|
| Invalid/corrupt batch manifest fails closed, no guessing | `tests/quick-batch.test.cjs` `loadBatch` malformed-JSON tests |
|
||||||
|
|
||||||
## Security, portability, and project quality
|
## Security, portability, and project quality
|
||||||
|
|
||||||
| AC bullet | Evidence |
|
| 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) |
|
| 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 |
|
| 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) |
|
| 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) |
|
| 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 |
|
| 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 `gsd-test` before this PR ships (not run as part of this dispatch — reported separately) |
|
| `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)
|
## #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 |
|
| Outcome propagation; blocked dependents; independent continuation | Phase 3, unchanged |
|
||||||
| Docs: v1 limits | Phase 4, unchanged (`docs/how-to/batch-quick-tasks.md`) |
|
| 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) |
|
| 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 |
|
| 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 |
|
| Real-PR-number changeset; no hand-edited CHANGELOG | Added after PR creation, per repo convention |
|
||||||
| Final verification maps evidence to #3344 | This document |
|
| 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 |
|
| RED/GREEN/REFACTOR commits; closes #3677 only | This PR's commit history; PR body closes #3677, references #3344 without closing it |
|
||||||
@@ -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
|
* Architecture: SUBPROCESS REUSE. Instead of re-implementing hook logic inside
|
||||||
* the plugin, this file is a thin adapter that spawns the existing Claude Code
|
* 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)
|
* - block → throw Error (OpenCode returns the error to the model)
|
||||||
* - advisory → output.metadata + console.error (best-effort surfacing)
|
* - 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.
|
* via require(), keeping the single source of truth.
|
||||||
*
|
*
|
||||||
* ── Two distribution shapes, one adapter (issue #1914) ─────────────────────
|
* ── Two distribution shapes, one adapter (issue #1914) ─────────────────────
|
||||||
* This single file serves both distribution paths, distinguished at load time
|
* This single file serves both distribution paths, distinguished at load time
|
||||||
* by REPO_ROOT (path.resolve(__dirname, "../..")):
|
* by REPO_ROOT (path.resolve(__dirname, "../..")):
|
||||||
*
|
*
|
||||||
* • Option 1 — file copy (the supported GSD path). `bin/install.js` copies
|
* • Option 1 — file copy (the supported MSD path). `bin/install.js` copies
|
||||||
* this file to <opencodeConfigDir>/plugins/gsd-core.js, so REPO_ROOT is the
|
* this file to <opencodeConfigDir>/plugins/msd-core.js, so REPO_ROOT is the
|
||||||
* OpenCode config dir. GSD's own install already stages `hooks/*.js` and
|
* OpenCode config dir. MSD's own install already stages `hooks/*.js` and
|
||||||
* `gsd-core/` there (ADR-857 skips hook *registration* for OpenCode, not the
|
* `msd-core/` there (ADR-857 skips hook *registration* for OpenCode, not the
|
||||||
* file copy), so the hook bridge and content rewriting resolve natively.
|
* 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
|
* this mode, so the plugin's own config-hook registration is redundant and is
|
||||||
* SKIPPED (see IS_PACKAGE_TREE) to avoid double-registration.
|
* SKIPPED (see IS_PACKAGE_TREE) to avoid double-registration.
|
||||||
*
|
*
|
||||||
* • Option 2 — package / git-spec. When loaded from the package tree (npm
|
* • 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
|
* `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.
|
* plugin IS the sole registrar, so it registers commands/agents/skills too.
|
||||||
*
|
*
|
||||||
* IS_PACKAGE_TREE keys off the presence of the SOURCE command layout
|
* 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
|
* config dir (that uses the flattened command/ layout). The hook bridge and
|
||||||
* Read-time content rewriting run in BOTH modes; only the config-hook
|
* Read-time content rewriting run in BOTH modes; only the config-hook
|
||||||
* registration of commands/agents/skills is gated.
|
* registration of commands/agents/skills is gated.
|
||||||
*
|
*
|
||||||
* Runtime-specific hooks are deliberately excluded:
|
* Runtime-specific hooks are deliberately excluded:
|
||||||
* - gsd-statusline.js / gsd-update-banner.js (Claude Code statusline)
|
* - msd-statusline.js / msd-update-banner.js (Claude Code statusline)
|
||||||
* - gsd-cursor-*.js (Cursor-specific)
|
* - msd-cursor-*.js (Cursor-specific)
|
||||||
* - *.sh scripts (invoked directly by commands/agents, not hook events)
|
* - *.sh scripts (invoked directly by commands/agents, not hook events)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -51,12 +51,12 @@ const fs = require("fs");
|
|||||||
const os = require("os");
|
const os = require("os");
|
||||||
const { spawnSync } = require("child_process");
|
const { spawnSync } = require("child_process");
|
||||||
|
|
||||||
// Resolve REPO_ROOT to the directory that actually holds the GSD payload
|
// Resolve REPO_ROOT to the directory that actually holds the MSD payload
|
||||||
// (hooks/ + gsd-core/). This must work across three physical layouts because a
|
// (hooks/ + msd-core/). This must work across three physical layouts because a
|
||||||
// single adapter file serves both distribution shapes (see header):
|
// single adapter file serves both distribution shapes (see header):
|
||||||
// • package/git-spec tree: <root>/.opencode/plugins/gsd-core.js → <root>
|
// • package/git-spec tree: <root>/.opencode/plugins/msd-core.js → <root>
|
||||||
// • global file-copy: ~/.config/opencode/plugins/gsd-core.js → ~/.config/opencode
|
// • global file-copy: ~/.config/opencode/plugins/msd-core.js → ~/.config/opencode
|
||||||
// • local file-copy: <proj>/.opencode/plugins/gsd-core.js → <proj>/.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
|
// A fixed "../.." only works for the first; the copied layouts sit one level
|
||||||
// shallower. Walking up to the first ancestor containing BOTH payload markers
|
// shallower. Walking up to the first ancestor containing BOTH payload markers
|
||||||
// resolves all three deterministically. Falls back to the package-tree
|
// resolves all three deterministically. Falls back to the package-tree
|
||||||
@@ -66,7 +66,7 @@ function resolveRepoRoot(startDir) {
|
|||||||
for (let i = 0; i < 6; i++) {
|
for (let i = 0; i < 6; i++) {
|
||||||
if (
|
if (
|
||||||
fs.existsSync(path.join(dir, "hooks")) &&
|
fs.existsSync(path.join(dir, "hooks")) &&
|
||||||
fs.existsSync(path.join(dir, "gsd-core"))
|
fs.existsSync(path.join(dir, "msd-core"))
|
||||||
) {
|
) {
|
||||||
return dir;
|
return dir;
|
||||||
}
|
}
|
||||||
@@ -84,16 +84,16 @@ function resolveRepoRoot(startDir) {
|
|||||||
// CJS: __dirname is a global, no need to derive from import.meta.url
|
// CJS: __dirname is a global, no need to derive from import.meta.url
|
||||||
const REPO_ROOT = resolveRepoRoot(__dirname);
|
const REPO_ROOT = resolveRepoRoot(__dirname);
|
||||||
const HOOKS_DIR = path.join(REPO_ROOT, "hooks");
|
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 AGENTS = path.join(REPO_ROOT, "agents");
|
||||||
const SKILLS = path.join(REPO_ROOT, "skills");
|
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
|
// 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
|
// 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
|
// 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);
|
const IS_PACKAGE_TREE = fs.existsSync(COMMANDS);
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -198,7 +198,7 @@ function mapToolInput(args) {
|
|||||||
* - exit 2: block (Claude convention; reason in stdout JSON)
|
* - exit 2: block (Claude convention; reason in stdout JSON)
|
||||||
* - any error: exit 0 silently (hooks swallow their own errors)
|
* - 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} payload stdin JSON (hook_event_name, tool_name, ...)
|
||||||
* @param {object} [opts]
|
* @param {object} [opts]
|
||||||
* @param {number} [opts.timeout=8000] spawn timeout in ms
|
* @param {number} [opts.timeout=8000] spawn timeout in ms
|
||||||
@@ -217,9 +217,9 @@ function runHook(hookFile, payload, opts = {}) {
|
|||||||
if (!warnedMissingHooks.has(hookFile)) {
|
if (!warnedMissingHooks.has(hookFile)) {
|
||||||
warnedMissingHooks.add(hookFile);
|
warnedMissingHooks.add(hookFile);
|
||||||
console.error(
|
console.error(
|
||||||
`[gsd-core] hook script missing: ${hookPath} — ${hookFile} is NOT ` +
|
`[msd-core] hook script missing: ${hookPath} — ${hookFile} is NOT ` +
|
||||||
"enforced. The GSD install may be incomplete; reinstall (or run " +
|
"enforced. The MSD install may be incomplete; reinstall (or run " +
|
||||||
"/gsd-update) to restage the hooks/ bundle.",
|
"/msd-update) to restage the hooks/ bundle.",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return { stdout: "", exitCode: 0, timedOut: false };
|
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
|
* In-process check for whether context-usage warnings are disabled in project
|
||||||
* config. Mirrors the exact semantics of the same check inside
|
* 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
|
* `config.hooks.context_warnings === false` disables them; a missing or
|
||||||
* unparseable .planning/config.json keeps them enabled (the default).
|
* 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.
|
* 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
|
* - 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
|
* - Silent → no-op
|
||||||
*
|
*
|
||||||
* @param {{ stdout: string, exitCode: number }} hookResult
|
* @param {{ stdout: string, exitCode: number }} hookResult
|
||||||
@@ -301,7 +301,7 @@ function handleHookResult(hookResult, output) {
|
|||||||
const isBlock = exitCode === 2 || (parsed && parsed.decision === "block");
|
const isBlock = exitCode === 2 || (parsed && parsed.decision === "block");
|
||||||
if (isBlock) {
|
if (isBlock) {
|
||||||
const reason =
|
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);
|
throw new Error(reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,10 +317,10 @@ function handleHookResult(hookResult, output) {
|
|||||||
// sequence (prompt guard, read guard, worktree guard, workflow guard).
|
// sequence (prompt guard, read guard, worktree guard, workflow guard).
|
||||||
// Storing a scalar would let a later advisory clobber an earlier one, so
|
// Storing a scalar would let a later advisory clobber an earlier one, so
|
||||||
// collect them all.
|
// collect them all.
|
||||||
if (!Array.isArray(output.metadata._gsdAdvisory)) {
|
if (!Array.isArray(output.metadata._msdAdvisory)) {
|
||||||
output.metadata._gsdAdvisory = [];
|
output.metadata._msdAdvisory = [];
|
||||||
}
|
}
|
||||||
output.metadata._gsdAdvisory.push(advisory);
|
output.metadata._msdAdvisory.push(advisory);
|
||||||
}
|
}
|
||||||
// Best-effort visibility when metadata isn't surfaced to the model
|
// Best-effort visibility when metadata isn't surfaced to the model
|
||||||
console.error(advisory);
|
console.error(advisory);
|
||||||
@@ -347,7 +347,7 @@ function parseFrontmatter(content) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Rewrite @~/.claude/ includes to point at the repo root.
|
// 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).
|
// transform from scripts/fix-slash-commands.cjs (single source of truth).
|
||||||
function rewriteRefs(content) {
|
function rewriteRefs(content) {
|
||||||
let out = content.replace(/@~\/\.claude\//g, `@${REPO_ROOT}/`);
|
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
|
// refs. When the model reads these via the Read tool, we transparently rewrite
|
||||||
// both so OpenCode sees correct paths and hyphen-form command names.
|
// both so OpenCode sees correct paths and hyphen-form command names.
|
||||||
const GSD_MANAGED_DIRS = [
|
const MSD_MANAGED_DIRS = [
|
||||||
path.join(GSD_CORE, "workflows"),
|
path.join(MSD_CORE, "workflows"),
|
||||||
path.join(GSD_CORE, "references"),
|
path.join(MSD_CORE, "references"),
|
||||||
path.join(GSD_CORE, "templates"),
|
path.join(MSD_CORE, "templates"),
|
||||||
path.join(GSD_CORE, "contexts"),
|
path.join(MSD_CORE, "contexts"),
|
||||||
COMMANDS,
|
COMMANDS,
|
||||||
AGENTS,
|
AGENTS,
|
||||||
SKILLS,
|
SKILLS,
|
||||||
];
|
];
|
||||||
|
|
||||||
function isGsdManagedFile(filePath) {
|
function isMsdManagedFile(filePath) {
|
||||||
if (!filePath) return false;
|
if (!filePath) return false;
|
||||||
const resolved = path.resolve(filePath);
|
const resolved = path.resolve(filePath);
|
||||||
return GSD_MANAGED_DIRS.some(
|
return MSD_MANAGED_DIRS.some(
|
||||||
(dir) => resolved === dir || resolved.startsWith(dir + path.sep),
|
(dir) => resolved === dir || resolved.startsWith(dir + path.sep),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rewrite content for OpenCode consumption:
|
// Rewrite content for OpenCode consumption:
|
||||||
// 1. @-include paths: @~/.claude/ → @<REPO_ROOT>/
|
// 1. @-include paths: @~/.claude/ → @<REPO_ROOT>/
|
||||||
// 2. plain-text paths: ~/.claude/gsd-core/ → <GSD_CORE>/
|
// 2. plain-text paths: ~/.claude/msd-core/ → <MSD_CORE>/
|
||||||
// 3. namespace: gsd:xxx → gsd-xxx (via fix-slash-commands.cjs)
|
// 3. namespace: msd:xxx → msd-xxx (via fix-slash-commands.cjs)
|
||||||
function rewriteContent(content) {
|
function rewriteContent(content) {
|
||||||
let out = content;
|
let out = content;
|
||||||
out = out.replace(/@~\/\.claude\//g, `@${REPO_ROOT}/`);
|
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();
|
const transform = getNamespaceConverter();
|
||||||
if (transform && _cmdNames && _cmdNames.length) {
|
if (transform && _cmdNames && _cmdNames.length) {
|
||||||
out = transform(out, _cmdNames);
|
out = transform(out, _cmdNames);
|
||||||
@@ -415,18 +415,18 @@ function rewriteContent(content) {
|
|||||||
//
|
//
|
||||||
// OpenCode's skill loader reads SKILL.md files directly from disk and resolves
|
// OpenCode's skill loader reads SKILL.md files directly from disk and resolves
|
||||||
// @-includes internally — this bypasses our tool.execute hooks. To make
|
// @-includes internally — this bypasses our tool.execute hooks. To make
|
||||||
// @~/.claude/gsd-core/... includes resolve, we copy all SKILL.md files to a
|
// @~/.claude/msd-core/... includes resolve, we copy all SKILL.md files to a
|
||||||
// cache directory with paths rewritten to the actual GSD_CORE location.
|
// cache directory with paths rewritten to the actual MSD_CORE location.
|
||||||
//
|
//
|
||||||
// Only used in package-tree mode (Option 2). In an installed OpenCode config
|
// 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).
|
// copy, so we never register skills from the plugin (see IS_PACKAGE_TREE).
|
||||||
|
|
||||||
const SKILLS_CACHE = path.join(
|
const SKILLS_CACHE = path.join(
|
||||||
os.homedir(),
|
os.homedir(),
|
||||||
".cache",
|
".cache",
|
||||||
"opencode",
|
"opencode",
|
||||||
"gsd-skills",
|
"msd-skills",
|
||||||
);
|
);
|
||||||
|
|
||||||
function prepareSkillsCache() {
|
function prepareSkillsCache() {
|
||||||
@@ -439,8 +439,8 @@ function prepareSkillsCache() {
|
|||||||
// Rewrite @-include paths only; namespace conversion is handled at
|
// Rewrite @-include paths only; namespace conversion is handled at
|
||||||
// Read-time via tool.execute.after for workflow/reference files.
|
// Read-time via tool.execute.after for workflow/reference files.
|
||||||
const rewritten = raw
|
const rewritten = raw
|
||||||
.replace(/@~\/\.claude\/gsd-core\//g, `@${GSD_CORE}/`)
|
.replace(/@~\/\.claude\/msd-core\//g, `@${MSD_CORE}/`)
|
||||||
.replace(/~\/\.claude\/gsd-core\//g, `${GSD_CORE}/`);
|
.replace(/~\/\.claude\/msd-core\//g, `${MSD_CORE}/`);
|
||||||
const destDir = path.join(SKILLS_CACHE, dir);
|
const destDir = path.join(SKILLS_CACHE, dir);
|
||||||
fs.mkdirSync(destDir, { recursive: true });
|
fs.mkdirSync(destDir, { recursive: true });
|
||||||
fs.writeFileSync(path.join(destDir, "SKILL.md"), rewritten);
|
fs.writeFileSync(path.join(destDir, "SKILL.md"), rewritten);
|
||||||
@@ -452,25 +452,25 @@ function prepareSkillsCache() {
|
|||||||
// Plugin entry
|
// Plugin entry
|
||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
|
|
||||||
const GsdCorePlugin = async ({ directory } = {}) => {
|
const MsdCorePlugin = async ({ directory } = {}) => {
|
||||||
if (directory) currentCwd = directory;
|
if (directory) currentCwd = directory;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// ── Config: register commands / agents / skills paths ──────────────
|
// ── Config: register commands / agents / skills paths ──────────────
|
||||||
// Only in package-tree mode (Option 2). In an installed config dir
|
// 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.
|
// plugin stays out of registration to avoid double-registering.
|
||||||
config: async (config) => {
|
config: async (config) => {
|
||||||
if (!IS_PACKAGE_TREE) return;
|
if (!IS_PACKAGE_TREE) return;
|
||||||
|
|
||||||
// Commands (commands/gsd/*.md → gsd-<name>)
|
// Commands (commands/msd/*.md → msd-<name>)
|
||||||
config.command = config.command || {};
|
config.command = config.command || {};
|
||||||
const cmds = loadDir(
|
const cmds = loadDir(
|
||||||
COMMANDS,
|
COMMANDS,
|
||||||
(f) => "gsd-" + f.slice(0, -3),
|
(f) => "msd-" + f.slice(0, -3),
|
||||||
(body, fm, name) => ({
|
(body, fm, name) => ({
|
||||||
template: rewriteRefs(body.trim()),
|
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)) {
|
for (const [k, v] of Object.entries(cmds)) {
|
||||||
@@ -484,7 +484,7 @@ const GsdCorePlugin = async ({ directory } = {}) => {
|
|||||||
(f) => f.slice(0, -3),
|
(f) => f.slice(0, -3),
|
||||||
(body, fm, name) => ({
|
(body, fm, name) => ({
|
||||||
prompt: rewriteRefs(body.trim()),
|
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",
|
mode: fm.mode || "subagent",
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@@ -508,7 +508,7 @@ const GsdCorePlugin = async ({ directory } = {}) => {
|
|||||||
// ── shell.env ───────────────────────────────────────────────────────
|
// ── shell.env ───────────────────────────────────────────────────────
|
||||||
"shell.env": async (_input, output) => {
|
"shell.env": async (_input, output) => {
|
||||||
output.env = output.env || {};
|
output.env = output.env || {};
|
||||||
output.env.GSD_DIR = GSD_CORE;
|
output.env.MSD_DIR = MSD_CORE;
|
||||||
},
|
},
|
||||||
|
|
||||||
// ── tool.execute.before — PreToolUse hooks ─────────────────────────
|
// ── tool.execute.before — PreToolUse hooks ─────────────────────────
|
||||||
@@ -517,14 +517,14 @@ const GsdCorePlugin = async ({ directory } = {}) => {
|
|||||||
const toolInput = mapToolInput(output.args || {});
|
const toolInput = mapToolInput(output.args || {});
|
||||||
const cwd = currentCwd;
|
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
|
// so the model can read workflow/reference/template files that SKILL.md
|
||||||
// and command templates reference via the canonical Claude path.
|
// and command templates reference via the canonical Claude path.
|
||||||
if (claudeTool === "Read" && toolInput.file_path) {
|
if (claudeTool === "Read" && toolInput.file_path) {
|
||||||
const original = toolInput.file_path;
|
const original = toolInput.file_path;
|
||||||
const rewritten = original
|
const rewritten = original
|
||||||
.replace(/^~\/\.claude\/gsd-core\//, GSD_CORE + "/")
|
.replace(/^~\/\.claude\/msd-core\//, MSD_CORE + "/")
|
||||||
.replace(/(?:.*)\/\.claude\/gsd-core\//, GSD_CORE + "/");
|
.replace(/(?:.*)\/\.claude\/msd-core\//, MSD_CORE + "/");
|
||||||
if (rewritten !== original) {
|
if (rewritten !== original) {
|
||||||
const args = output.args || {};
|
const args = output.args || {};
|
||||||
if (args.filePath) args.filePath = rewritten;
|
if (args.filePath) args.filePath = rewritten;
|
||||||
@@ -539,7 +539,7 @@ const GsdCorePlugin = async ({ directory } = {}) => {
|
|||||||
cwd,
|
cwd,
|
||||||
};
|
};
|
||||||
// NOTE: session_id intentionally omitted for PreToolUse hooks.
|
// 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.
|
// session and skips its advisory. On OpenCode we WANT the advisory.
|
||||||
const prePayload = (overrides = {}) => ({
|
const prePayload = (overrides = {}) => ({
|
||||||
...basePayload,
|
...basePayload,
|
||||||
@@ -550,42 +550,42 @@ const GsdCorePlugin = async ({ directory } = {}) => {
|
|||||||
|
|
||||||
const isWriteLike = ["Write", "Edit", "MultiEdit"].includes(claudeTool);
|
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") {
|
if (claudeTool === "Write" || claudeTool === "Edit") {
|
||||||
const r = runHook("gsd-prompt-guard.js", prePayload());
|
const r = runHook("msd-prompt-guard.js", prePayload());
|
||||||
handleHookResult(r, output);
|
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") {
|
if (claudeTool === "Write" || claudeTool === "Edit") {
|
||||||
const r = runHook("gsd-read-guard.js", prePayload());
|
const r = runHook("msd-read-guard.js", prePayload());
|
||||||
handleHookResult(r, output);
|
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) {
|
if (isWriteLike) {
|
||||||
const r = runHook("gsd-worktree-path-guard.js", prePayload());
|
const r = runHook("msd-worktree-path-guard.js", prePayload());
|
||||||
handleHookResult(r, output);
|
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)
|
// .planning/ artifacts (ROADMAP.md, milestones/*-ROADMAP.md, STATE.md)
|
||||||
if (claudeTool === "Write") {
|
if (claudeTool === "Write") {
|
||||||
const r = runHook("gsd-write-guard.js", prePayload());
|
const r = runHook("msd-write-guard.js", prePayload());
|
||||||
handleHookResult(r, output);
|
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)
|
// (covers Write/Edit/MultiEdit AND Bash force-add detection)
|
||||||
if (isWriteLike || claudeTool === "Bash") {
|
if (isWriteLike || claudeTool === "Bash") {
|
||||||
const r = runHook("gsd-workflow-guard.js", prePayload());
|
const r = runHook("msd-workflow-guard.js", prePayload());
|
||||||
handleHookResult(r, output);
|
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)
|
// .secrets via Read (file_path), Grep (path or glob) and Bash (command)
|
||||||
if (["Read", "Grep", "Bash"].includes(claudeTool)) {
|
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);
|
handleHookResult(r, output);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -598,12 +598,12 @@ const GsdCorePlugin = async ({ directory } = {}) => {
|
|||||||
const toolInput = mapToolInput(input.args || {});
|
const toolInput = mapToolInput(input.args || {});
|
||||||
const cwd = currentCwd;
|
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.
|
// BEFORE injection scanning so the scanner sees the final content.
|
||||||
if (
|
if (
|
||||||
claudeTool === "Read" &&
|
claudeTool === "Read" &&
|
||||||
output.output &&
|
output.output &&
|
||||||
isGsdManagedFile(toolInput.file_path)
|
isMsdManagedFile(toolInput.file_path)
|
||||||
) {
|
) {
|
||||||
const content =
|
const content =
|
||||||
typeof output.output === "string"
|
typeof output.output === "string"
|
||||||
@@ -612,7 +612,7 @@ const GsdCorePlugin = async ({ directory } = {}) => {
|
|||||||
output.output = rewriteContent(content);
|
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 (
|
if (
|
||||||
claudeTool === "Read" ||
|
claudeTool === "Read" ||
|
||||||
claudeTool === "WebFetch" ||
|
claudeTool === "WebFetch" ||
|
||||||
@@ -625,12 +625,12 @@ const GsdCorePlugin = async ({ directory } = {}) => {
|
|||||||
tool_response: output.output,
|
tool_response: output.output,
|
||||||
cwd,
|
cwd,
|
||||||
};
|
};
|
||||||
const r = runHook("gsd-read-injection-scanner.js", payload);
|
const r = runHook("msd-read-injection-scanner.js", payload);
|
||||||
handleHookResult(r, output);
|
handleHookResult(r, output);
|
||||||
return;
|
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).
|
// Only meaningful when a session_id is tracked (writes metrics sentinel).
|
||||||
// #2697: skip the subprocess spawn entirely when context warnings are
|
// #2697: skip the subprocess spawn entirely when context warnings are
|
||||||
// explicitly disabled in project config — the hook would exit early anyway,
|
// explicitly disabled in project config — the hook would exit early anyway,
|
||||||
@@ -644,7 +644,7 @@ const GsdCorePlugin = async ({ directory } = {}) => {
|
|||||||
session_id: currentSessionId,
|
session_id: currentSessionId,
|
||||||
cwd,
|
cwd,
|
||||||
};
|
};
|
||||||
const r = runHook("gsd-context-monitor.js", payload);
|
const r = runHook("msd-context-monitor.js", payload);
|
||||||
handleHookResult(r, output);
|
handleHookResult(r, output);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -657,13 +657,13 @@ const GsdCorePlugin = async ({ directory } = {}) => {
|
|||||||
session_id: currentSessionId,
|
session_id: currentSessionId,
|
||||||
cwd: currentCwd,
|
cwd: currentCwd,
|
||||||
};
|
};
|
||||||
const r = runHook("gsd-context-monitor.js", payload);
|
const r = runHook("msd-context-monitor.js", payload);
|
||||||
handleHookResult(r, output);
|
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 = output.context || [];
|
||||||
output.context.push(
|
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;
|
info?.id || event.sessionID || event.session_id || null;
|
||||||
if (info?.directory) currentCwd = info.directory;
|
if (info?.directory) currentCwd = info.directory;
|
||||||
|
|
||||||
// gsd-ensure-canonical-path.js — no stdin dependency; silent
|
// msd-ensure-canonical-path.js — no stdin dependency; silent
|
||||||
runHook("gsd-ensure-canonical-path.js", {
|
runHook("msd-ensure-canonical-path.js", {
|
||||||
hook_event_name: "SessionStart",
|
hook_event_name: "SessionStart",
|
||||||
session_id: currentSessionId,
|
session_id: currentSessionId,
|
||||||
cwd: currentCwd,
|
cwd: currentCwd,
|
||||||
});
|
});
|
||||||
// gsd-check-update.js — spawns its own background worker; no stdin
|
// msd-check-update.js — spawns its own background worker; no stdin
|
||||||
runHook("gsd-check-update.js", {
|
runHook("msd-check-update.js", {
|
||||||
hook_event_name: "SessionStart",
|
hook_event_name: "SessionStart",
|
||||||
session_id: currentSessionId,
|
session_id: currentSessionId,
|
||||||
cwd: currentCwd,
|
cwd: currentCwd,
|
||||||
@@ -709,17 +709,17 @@ const GsdCorePlugin = async ({ directory } = {}) => {
|
|||||||
event: "change",
|
event: "change",
|
||||||
cwd,
|
cwd,
|
||||||
};
|
};
|
||||||
const r = runHook("gsd-config-reload.js", payload);
|
const r = runHook("msd-config-reload.js", payload);
|
||||||
// Advisory-only (additionalContext); surface to logs
|
// Advisory-only (additionalContext); surface to logs
|
||||||
handleHookResult(r);
|
handleHookResult(r);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// session.idle ↔ Claude Stop lifecycle point (#1682 Slice 1b/c).
|
// 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
|
// Stop equivalent — the opencode-subset lifecycle peer of compaction
|
||||||
// (compaction preserves state across context-window summarization; idle
|
// (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
|
// persisted to .planning/), but it MUST be recognized so the declared
|
||||||
// opencode-subset surface is fully wired and a future Stop-class hook can
|
// opencode-subset surface is fully wired and a future Stop-class hook can
|
||||||
// attach without a plugin change.
|
// attach without a plugin change.
|
||||||
@@ -728,9 +728,9 @@ const GsdCorePlugin = async ({ directory } = {}) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// permission.asked / permission.replied — OpenCode permission lifecycle
|
// 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
|
// 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
|
// so these are recognized sentinels — wired so a future permission-aware
|
||||||
// gate can attach without a plugin change (the engine owns phase
|
// gate can attach without a plugin change (the engine owns phase
|
||||||
// sequencing; this host bus is session/tool/permission-scoped, never
|
// sequencing; this host bus is session/tool/permission-scoped, never
|
||||||
@@ -739,7 +739,7 @@ const GsdCorePlugin = async ({ directory } = {}) => {
|
|||||||
return;
|
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/);
|
// hook fires here today (loop state is already persisted to .planning/);
|
||||||
// recognized so the declared extension-event surface is fully wired and a
|
// recognized so the declared extension-event surface is fully wired and a
|
||||||
// future error-class hook can attach without a plugin change.
|
// 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
|
// 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
|
// CommonJS file, `mod` may be the raw `module.exports` OR an ESM namespace of
|
||||||
// the form `{ default: module.exports, ...syntheticNamedExports }`. A plain
|
// 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-
|
// appearing in `Object.values(mod)` (as a raw property, or as a lexer-
|
||||||
// synthesized named export) — which would trip the throw. Two defenses:
|
// synthesized named export) — which would trip the throw. Two defenses:
|
||||||
// 1. `id` is defined NON-ENUMERABLE, so it never appears in Object.values yet
|
// 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` =
|
// Result: raw-CJS `Object.values` = `[server]`; ESM `Object.values` =
|
||||||
// `[{server, <id non-enum>}]` — both fully extractable. Test-only helpers hang
|
// `[{server, <id non-enum>}]` — both fully extractable. Test-only helpers hang
|
||||||
// off the `server` FUNCTION (`server._internals`), never as a sibling export.
|
// off the `server` FUNCTION (`server._internals`), never as a sibling export.
|
||||||
GsdCorePlugin._internals = {
|
MsdCorePlugin._internals = {
|
||||||
REPO_ROOT,
|
REPO_ROOT,
|
||||||
IS_PACKAGE_TREE,
|
IS_PACKAGE_TREE,
|
||||||
mapToolName,
|
mapToolName,
|
||||||
mapToolInput,
|
mapToolInput,
|
||||||
parseFrontmatter,
|
parseFrontmatter,
|
||||||
rewriteContent,
|
rewriteContent,
|
||||||
isGsdManagedFile,
|
isMsdManagedFile,
|
||||||
handleHookResult,
|
handleHookResult,
|
||||||
GsdCorePlugin,
|
MsdCorePlugin,
|
||||||
};
|
};
|
||||||
|
|
||||||
const gsdCorePluginExport = { server: GsdCorePlugin };
|
const msdCorePluginExport = { server: MsdCorePlugin };
|
||||||
Object.defineProperty(gsdCorePluginExport, "id", {
|
Object.defineProperty(msdCorePluginExport, "id", {
|
||||||
value: "gsd-core",
|
value: "msd-core",
|
||||||
enumerable: false,
|
enumerable: false,
|
||||||
writable: false,
|
writable: false,
|
||||||
configurable: false,
|
configurable: false,
|
||||||
});
|
});
|
||||||
module.exports = gsdCorePluginExport;
|
module.exports = msdCorePluginExport;
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
Move config-gated prose out of `agents/*.md` into `agents/templates/*.md.tmpl`,
|
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
|
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).
|
(deterministic code) instead of at inference time (LLM interpretation).
|
||||||
|
|
||||||
Three named benefits:
|
Three named benefits:
|
||||||
@@ -20,7 +20,7 @@ Three named benefits:
|
|||||||
Cites PR #2279 (Codex/OpenCode model embedding at install time) as direct
|
Cites PR #2279 (Codex/OpenCode model embedding at install time) as direct
|
||||||
precedent for compile-time embedding.
|
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
|
### 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
|
are a determinism failure surface. The actual patterns in the codebase today are
|
||||||
already heavily mitigated:
|
already heavily mitigated:
|
||||||
|
|
||||||
- The `use_worktrees` branch in `gsd-executor` is resolved deterministically via
|
- The `use_worktrees` branch in `msd-executor` is resolved deterministically via
|
||||||
`gsd-sdk query config-get` in bash — it is not LLM-interpreted.
|
`msd-sdk query config-get` in bash — it is not LLM-interpreted.
|
||||||
- "Skip if `workflow.X` is `false`" prose patterns are short, stable, and
|
- "Skip if `workflow.X` is `false`" prose patterns are short, stable, and
|
||||||
follow a uniform "missing key = enabled" convention. There is no documented
|
follow a uniform "missing key = enabled" convention. There is no documented
|
||||||
history of LLMs running disabled checks or skipping enabled ones because of
|
history of LLMs running disabled checks or skipping enabled ones because of
|
||||||
this prose.
|
this prose.
|
||||||
|
|
||||||
A theoretical failure surface should not be traded for a real, high-risk
|
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
|
admission "the highest-risk piece of the change"). The reporter was asked for
|
||||||
documented evidence; none was provided.
|
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
|
The codebase has roughly 5 `workflow.*` toggle references in agent files and
|
||||||
~20 "Skip if" conditional-prose patterns total — most 1–2 sentences. The
|
~20 "Skip if" conditional-prose patterns total — most 1–2 sentences. The
|
||||||
"real spend across multi-phase milestones" claim was not measured against
|
"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
|
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
|
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.
|
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
|
### 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
|
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
|
solely to absorb a contributor-workflow shift — the user-facing surface is
|
||||||
unchanged. Risk that flows entirely from internal restructuring, where the
|
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:
|
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
|
representative all-toggles-off config, and the delta is materially larger
|
||||||
than what extending PR #2279's orchestrator-embedding path one toggle at a
|
than what extending PR #2279's orchestrator-embedding path one toggle at a
|
||||||
time would produce.
|
time would produce.
|
||||||
@@ -100,5 +100,5 @@ This may be revisited if a contributor:
|
|||||||
precedent for deterministic compile-time embedding into agent files)
|
precedent for deterministic compile-time embedding into agent files)
|
||||||
- v1.37.0 release notes — shared-boilerplate extraction (reference files for
|
- v1.37.0 release notes — shared-boilerplate extraction (reference files for
|
||||||
mandatory-initial-read, project-skills-discovery)
|
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)
|
spawn (the path of least friction for incremental deterministic gating)
|
||||||
|
|||||||
@@ -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)
|
**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
|
**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)
|
## Policy (standing, not case-by-case)
|
||||||
|
|
||||||
**GSD is not accepting new add-ons as first-party, maintainer-owned work at this
|
**MSD 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
|
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
|
maintain a new distribution surface is declined regardless of how well-executed
|
||||||
the implementation is; the supported path is community-maintained distribution
|
the implementation is; the supported path is community-maintained distribution
|
||||||
through the EoS Registry or the Capability system, where the author owns the
|
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
|
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
|
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
|
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."
|
pre-proposal filed."
|
||||||
|
|
||||||
## Proposal summary
|
## 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/
|
skills and MCP server: a read-only project control center (milestone/phase/plan/
|
||||||
verification/blocker status), a UAT workbench (review outstanding checks, record
|
verification/blocker status), a UAT workbench (review outstanding checks, record
|
||||||
pass/issue results), and structured MCP output for non-visual clients. It claims
|
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
|
to reuse the existing CLI, stdio MCP server, resource catalog, and npm package
|
||||||
with no new runtime dependency, hosted backend, duplicate command layer, or
|
with no new runtime dependency, hosted backend, duplicate command layer, or
|
||||||
persistent marketplace config. A working implementation allegedly exists on the
|
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.
|
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
|
- **This repo has an established pre-proposal convention for first-party
|
||||||
plugin/marketplace-surface work that this issue skipped entirely.** The
|
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
|
## 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:
|
work.** It does not deny, and must never be cited against:
|
||||||
|
|
||||||
- **Shipping this as a community-maintained EoS host-plugin or Capability.**
|
- **Shipping this as a community-maintained EoS host-plugin or Capability.**
|
||||||
Everything the proposal describes (control-center views, UAT workbench, MCP
|
Everything the proposal describes (control-center views, UAT workbench, MCP
|
||||||
output) can be built and distributed by the reporter today via the same path
|
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
|
as `msd-cursor`/`msd-omp`/`msd-reasonix`, listed in the EoS Registry — with no
|
||||||
gsd-core changes and no maintainer packaging commitment.
|
msd-core changes and no maintainer packaging commitment.
|
||||||
- **The underlying idea of packaging GSD for Codex.** No judgment is made on
|
- **The underlying idea of packaging MSD for Codex.** No judgment is made on
|
||||||
whether the idea is good — only that gsd-core will not be the one building,
|
whether the idea is good — only that msd-core will not be the one building,
|
||||||
packaging, and maintaining it.
|
packaging, and maintaining it.
|
||||||
- **The reporter's fork implementation itself**, which was not reviewed as part
|
- **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
|
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
|
## 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
|
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.
|
"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
|
- Separately, and only if that policy changes: a pre-proposal doc filed under
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
Reporter proposed an opt-in, Codex-only supervision adapter layered on the existing negotiated
|
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
|
`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
|
exactly one external `codex exec --cd <worktree>` worker and surfaces evidence-backed progress in
|
||||||
Codex's native subagent UI as three strict states:
|
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
|
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.
|
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
|
- **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,
|
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
|
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
|
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.
|
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`
|
- **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
|
## 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,
|
native subagent UI.** Its keyword surface — supervisor, observability, worker state, lifecycle,
|
||||||
subagent, Codex, orchestrator-worktree — overlaps requests this decision deliberately does not
|
subagent, Codex, orchestrator-worktree — overlaps requests this decision deliberately does not
|
||||||
deny. Do not apply this entry to:
|
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
|
ground for this decision
|
||||||
- [ADR-857](../docs/adr/857-capability-system.md) — the capability system and its 12 loop extension
|
- [ADR-857](../docs/adr/857-capability-system.md) — the capability system and its 12 loop extension
|
||||||
points
|
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
|
- `capabilities/codex/capability.json` — existing Codex runtime support, unaffected
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ skipped verdict as fresh.
|
|||||||
|
|
||||||
This entry denies **the `commit_gates` config as filed.** It does not deny the underlying need.
|
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
|
- **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
|
[#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`,
|
- **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
|
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
|
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
|
- **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
|
`commit:pre` loop point today.** The 12 canonical loop points
|
||||||
(`src/loop-resolver.cts` `CANONICAL_POINTS`: the `:pre`/`:post` pairs for `discuss`, `plan`,
|
(`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).
|
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
|
- **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`
|
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
|
full fix will likely *use* a commit-point gate does not make the `commit_gates` config the right
|
||||||
home for the gate mechanism.
|
home for the gate mechanism.
|
||||||
- **New `check.predicate` kinds** added to the existing capability gate evaluator — a separate,
|
- **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
|
reference
|
||||||
- [`docs/reference/capability-manifest.md`](../docs/reference/capability-manifest.md) — the 12
|
- [`docs/reference/capability-manifest.md`](../docs/reference/capability-manifest.md) — the 12
|
||||||
closed/additive-only loop points
|
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)
|
||||||
|
|||||||
@@ -6,12 +6,12 @@
|
|||||||
|
|
||||||
## Policy (standing, not case-by-case)
|
## 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
|
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
|
already community-maintained gets the same disposition: redirect to the EoS
|
||||||
Registry (new host/runtime identity) or the Capability system (new toggleable
|
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
|
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
|
ask for a new runtime or add-on in-tree", not "is this particular one well
|
||||||
executed."
|
executed."
|
||||||
@@ -20,36 +20,36 @@ executed."
|
|||||||
|
|
||||||
#4033 asked to add `crush` (Charm's terminal AI coding agent) as a **first-party,
|
#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
|
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-name-policy.cts`, `src/runtime-artifact-layout.cts`,
|
||||||
`src/runtime-artifact-conversion.cts`, and `bin/install.js`, following `zcode` as
|
`src/runtime-artifact-conversion.cts`, and `bin/install.js`, following `zcode` as
|
||||||
the reference runtime. The reporter explicitly flagged five open questions about
|
the reference runtime. The reporter explicitly flagged five open questions about
|
||||||
crush's agent-artifact format, permission model, frontmatter tolerance, MCP
|
crush's agent-artifact format, permission model, frontmatter tolerance, MCP
|
||||||
support, and install-scope conventions that could not be answered from inside
|
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
|
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
|
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,
|
runtime is a permanent maintenance obligation across the registry, installer,
|
||||||
artifact conversion, agent discovery, model routing, dispatch isolation,
|
artifact conversion, agent discovery, model routing, dispatch isolation,
|
||||||
golden install-parity fixtures, and localized capability matrices — carried
|
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
|
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).
|
[`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
|
- **The supported direction is the Embeddable Orchestration System (EoS), and it
|
||||||
is already available.** [ADR-1239](../docs/adr/1239-gsd-embeddable-orchestration-engine.md)
|
is already available.** [ADR-1239](../docs/adr/1239-msd-embeddable-orchestration-engine.md)
|
||||||
exists precisely so a host embeds GSD through a stable negotiated interface and
|
exists precisely so a host embeds MSD through a stable negotiated interface and
|
||||||
a thin host-plugin authored against the published Host-Integration SDK
|
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))
|
([`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`,
|
[EoS Registry](../docs/registries/eos-registry.md) (`docs/registries/eos.json`,
|
||||||
`type: "eos"`), via a docs PR (`npm run gen:registry`). Existing entries
|
`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
|
actual need is narrower — a loop-behavior addition rather than a whole new
|
||||||
host — the [Capability](../docs/how-to/develop-a-capability.md) path
|
host — the [Capability](../docs/how-to/develop-a-capability.md) path
|
||||||
(`role: "feature"`, ADR-1244) is the other supported out-of-tree route; which
|
(`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:
|
does not deny, and must never be cited against:
|
||||||
|
|
||||||
- **Shipping an out-of-tree host-plugin for crush.** This is welcome and
|
- **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
|
Host-Integration SDK and is listed in `docs/registries/eos.json` is exactly
|
||||||
the path this decision points to.
|
the path this decision points to.
|
||||||
- **A crush integration built as a Capability**, if what's actually needed is a
|
- **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
|
- **Fixing defects that surface through a non-registered runtime**, or improving
|
||||||
the documented override/SDK contracts a host plugin depends on.
|
the documented override/SDK contracts a host plugin depends on.
|
||||||
- **Migrations of already-supported runtimes** onto the EoS architecture. Those
|
- **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.**
|
- **Any existing runtime's support tier.**
|
||||||
|
|
||||||
## Re-open criteria
|
## 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
|
changes the maintenance calculus, or third-party `role: "runtime"` descriptors
|
||||||
become loadable from outside the repo (ADR-857 D8's deferred purely-additive
|
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
|
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
|
ground
|
||||||
- [`eos-registry-not-in-tree-runtime.md`](./eos-registry-not-in-tree-runtime.md) —
|
- [`eos-registry-not-in-tree-runtime.md`](./eos-registry-not-in-tree-runtime.md) —
|
||||||
sibling decision (Reasonix), same ground, same redirect
|
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)
|
an Embeddable Orchestration Engine (EoS)
|
||||||
- [`docs/how-to/author-a-host-plugin.md`](../docs/how-to/author-a-host-plugin.md) —
|
- [`docs/how-to/author-a-host-plugin.md`](../docs/how-to/author-a-host-plugin.md) —
|
||||||
the supported out-of-tree authoring path
|
the supported out-of-tree authoring path
|
||||||
|
|||||||
@@ -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)
|
**Source:** [#4286](https://github.com/open-gsd/gsd-core/issues/4286)
|
||||||
**Decision:** wontfix — closed as unspecified, revisit if a concrete design is proposed
|
**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
|
`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`,
|
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
|
`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
|
them, so a capability cannot contribute a prompt fragment to `msd-doc-writer` or
|
||||||
`gsd-roadmapper` at any hook point — the capability validator rejects any contribution naming
|
`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
|
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`/
|
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
|
`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
|
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
|
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.
|
(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
|
- **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
|
read of `references/loop-hook-dispatch.md`: `msd-roadmapper` is dispatched only from the
|
||||||
`new-project` / `new-milestone` / `ingest-docs` workflows, and `gsd-doc-writer` only from
|
`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
|
`docs-update` — none of which are among the 12 loop points the capability-contribution
|
||||||
mechanism (`activeHooks` / `byLoopPoint`) actually reaches. Admitting `doc-writer`/`roadmapper`
|
mechanism (`activeHooks` / `byLoopPoint`) actually reaches. Admitting `doc-writer`/`roadmapper`
|
||||||
as `agentRoles` at `plan:pre`/`plan:post` etc. would not actually let a capability contribute
|
as `agentRoles` at `plan:pre`/`plan:post` etc. would not actually let a capability contribute
|
||||||
|
|||||||
@@ -8,29 +8,29 @@
|
|||||||
|
|
||||||
#3346 asked to add a `reasonix` runtime as a **first-party, in-tree** integration: a
|
#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
|
`capabilities/reasonix/capability.json` descriptor merged into the generated runtime
|
||||||
`bin/lib/capability-registry.cjs`, so `gsd-tools` dispatch/isolation/effort queries resolve
|
`bin/lib/capability-registry.cjs`, so `msd-tools` dispatch/isolation/effort queries resolve
|
||||||
when GSD runs inside "Reasonix." The stated motivation was that launcher skills picked up by
|
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.
|
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
|
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
|
permanent maintenance obligation across the registry, installer, artifact conversion, agent
|
||||||
discovery, model routing, dispatch isolation, golden install-parity fixtures, and localized
|
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)).
|
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
|
- **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
|
available.** [ADR-1239](../docs/adr/1239-msd-embeddable-orchestration-engine.md) exists
|
||||||
precisely so a host embeds GSD through a stable negotiated interface and a thin **host-plugin**
|
precisely so a host embeds MSD through a stable negotiated interface and a thin **host-plugin**
|
||||||
authored against the published Host-Integration SDK
|
authored against the published Host-Integration SDK
|
||||||
([`docs/how-to/author-a-host-plugin.md`](../docs/how-to/author-a-host-plugin.md)) — **without
|
([`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"`),
|
[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
|
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
|
- **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
|
([#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
|
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:
|
and must never be cited against:
|
||||||
|
|
||||||
- **Shipping an out-of-tree host-plugin for Reasonix, or for any other host.** This is welcome
|
- **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
|
Host-Integration SDK and is listed in `docs/registries/eos.json` is exactly the path this
|
||||||
decision points to.
|
decision points to.
|
||||||
- **Feature capabilities** (`role: "feature"`) published out-of-tree under ADR-1244 — a different
|
- **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
|
- **Fixing defects that surface through a non-registered runtime**, or improving the documented
|
||||||
override/SDK contracts a host plugin depends on.
|
override/SDK contracts a host plugin depends on.
|
||||||
- **Migrations of *already-supported* runtimes** onto the EoS architecture (the #2086/#2095/#2096/
|
- **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.
|
onboardings, and are unaffected by this decision.
|
||||||
- **Any existing runtime's support tier.**
|
- **Any existing runtime's support tier.**
|
||||||
|
|
||||||
## Re-open criteria
|
## 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
|
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
|
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.
|
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
|
- [`omp-runtime-in-core.md`](./omp-runtime-in-core.md) — sibling decision; same ground (new host
|
||||||
as in-tree runtime), same redirect to EoS
|
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)
|
Orchestration Engine (EoS)
|
||||||
- [`docs/how-to/author-a-host-plugin.md`](../docs/how-to/author-a-host-plugin.md) — the supported
|
- [`docs/how-to/author-a-host-plugin.md`](../docs/how-to/author-a-host-plugin.md) — the supported
|
||||||
out-of-tree authoring path
|
out-of-tree authoring path
|
||||||
|
|||||||
@@ -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>`
|
mismatch, let the executor **repair itself** — `git reset --hard <orchestrator HEAD>`
|
||||||
on its own branch — and proceed, converting the halt into a self-heal.
|
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
|
- **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
|
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
|
reintroduces precisely this: the executor mutating its own worktree state in response
|
||||||
to a detected mismatch, on the sub-agent side.
|
to a detected mismatch, on the sub-agent side.
|
||||||
- **The shipped design is live in current source, not just historically decided.**
|
- **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
|
*"`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 —
|
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."*
|
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
|
## Related
|
||||||
|
|
||||||
- [#48](https://github.com/open-gsd/gsd-core/issues/48) — the decision this proposal reverses
|
- [#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
|
- [#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
|
- [#4415](https://github.com/open-gsd/gsd-core/issues/4415) — adjacent cleanup-wave gap, unaffected by this decision
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
**Decision:** wontfix — routed to the capability ecosystem, closed on scope ownership
|
**Decision:** wontfix — routed to the capability ecosystem, closed on scope ownership
|
||||||
**Date:** 2026-07-24
|
**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,
|
modules — prose instructing an agent *how to think* (epistemic hygiene,
|
||||||
confidence framing, assumption surfacing, reasoning style) that is not attached
|
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
|
ecosystem, authored and distributed by their authors, not in the core skill
|
||||||
layer.
|
layer.
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ Read this scope boundary before applying the entry — the keyword surface below
|
|||||||
decision deliberately does **not** deny:
|
decision deliberately does **not** deny:
|
||||||
|
|
||||||
- **Fixing an existing first-party agent's own language at a specific loop
|
- **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
|
its prompt". That is command/loop-step-attached and is ordinary bug-fix or
|
||||||
enhancement work. This entry denies *standalone, unattached* modules only.
|
enhancement work. This entry denies *standalone, unattached* modules only.
|
||||||
- **Objectively-measured or externally-triggered calibration** — anything
|
- **Objectively-measured or externally-triggered calibration** — anything
|
||||||
@@ -37,7 +37,7 @@ apply to it.
|
|||||||
|
|
||||||
### 1. `skills/` is a generated projection, not an authoring surface
|
### 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
|
`scripts/gen-plugin-skills.cjs` — 71 commands to 71 skills, identical
|
||||||
membership — and `npm run lint:generated-sync` runs `gen-plugin-skills.cjs
|
membership — and `npm run lint:generated-sync` runs `gen-plugin-skills.cjs
|
||||||
--check`, which fails whenever the committed tree diverges from generator
|
--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
|
### 3. Delivering it as a flag on existing commands is strictly worse
|
||||||
|
|
||||||
Evaluated and rejected as the alternative. Flag-gated prose injection is an
|
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
|
instruction block under `${MVP_MODE === 'true' ? … : ''}`), but the cost
|
||||||
multiplies by subset size: each command needs frontmatter `argument-hint`, a
|
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`
|
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 —
|
Self-judged confidence reporting — the usual centerpiece of these proposals —
|
||||||
was measured in this project and found weak.
|
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
|
'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
|
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
|
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
|
Self-reported improvement, anecdotes, or gains only on
|
||||||
already-noticed ambiguity do not meet this bar — that is precisely the
|
already-noticed ambiguity do not meet this bar — that is precisely the
|
||||||
result the existing evidence already produced.
|
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
|
`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
|
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.
|
this entry must be re-derived from reasons 2-4 alone.
|
||||||
|
|||||||
@@ -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)
|
**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)
|
**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)
|
## 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
|
## 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.
|
#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.
|
- **`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
|
## 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:
|
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 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 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 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.
|
- **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.
|
- **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.**
|
- **Any existing runtime's support tier.**
|
||||||
|
|
||||||
## Re-open criteria
|
## 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).
|
- 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
|
## 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
|
- [`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
|
- [`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
|
- [`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/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
|
- [`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
|
||||||
|
|||||||
@@ -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
|
`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.
|
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 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.
|
- **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.
|
||||||
|
|||||||
@@ -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
|
`capabilities/omp/capability.json`, no `omp` entry in the runtime registry, no
|
||||||
`omp` alias canonicalization, and no installer runtime selection for it.
|
`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
|
## 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
|
to *reduce* the number of supported runtimes, not grow it, absent funded
|
||||||
development. Each first-class runtime is a permanent maintenance obligation
|
development. Each first-class runtime is a permanent maintenance obligation
|
||||||
across the registry, installer, artifact conversion, agent discovery, model
|
across the registry, installer, artifact conversion, agent discovery, model
|
||||||
@@ -18,14 +18,14 @@ the proposals that have asked for it.
|
|||||||
not control.
|
not control.
|
||||||
- **Host integration is the supported direction, and it is already available.**
|
- **Host integration is the supported direction, and it is already available.**
|
||||||
The Embeddable Orchestration System (ADR-1239) exists precisely so a host can
|
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
|
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
|
*any* runtime name (`src/agent-install-check.cts`, `getAgentsDir`), so a plugin
|
||||||
can own its filesystem layout without core knowing the runtime exists.
|
can own its filesystem layout without core knowing the runtime exists.
|
||||||
- **The ask as filed also carried a defect.** #3037 proposed canonicalizing
|
- **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`, `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
|
([`capabilities/pi/capability.json`](../capabilities/pi/capability.json), home
|
||||||
`~/.pi/agent`, tier 2). That alias list would relocate an existing shipped
|
`~/.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
|
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:
|
not deny, and should never be cited against:
|
||||||
|
|
||||||
- **Shipping an out-of-tree host plugin for OMP, or for any other host.** This
|
- **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;
|
[`docs/registries/eos.json`](../docs/registries/eos.json) and remains listed;
|
||||||
registry inclusion is explicitly non-endorsement and is unaffected by this
|
registry inclusion is explicitly non-endorsement and is unaffected by this
|
||||||
decision.
|
decision.
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# Clone-Portable `<execution_context>` in Committed PLAN.md
|
# 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
|
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.
|
that a committed plan reads identically across developers, machines, or runtimes.
|
||||||
|
|
||||||
## Why this is out of scope
|
## 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
|
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)
|
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
|
(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
|
`msd-planner` and consumed in place by `msd-executor`, `msd-plan-checker`, and
|
||||||
`gsd-verifier`. There is no documented step in which a plan is read on another
|
`msd-verifier`. There is no documented step in which a plan is read on another
|
||||||
machine after `git clone` without a local GSD install.
|
machine after `git clone` without a local MSD install.
|
||||||
|
|
||||||
Under that model, `<execution_context>`'s `@` references point at the reader's
|
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,
|
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
|
and the executor loads those workflows from its own installed copy — it never
|
||||||
consumes the paths a *different* machine wrote into a committed plan.
|
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
|
orchestrator's installed workflow (`workflows/execute-phase.md`), so the block a
|
||||||
planner writes into a committed plan does not gate execution anywhere.
|
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
|
cross-developer document — the boundary #2158 declined to cross — for a block that
|
||||||
no consumer reads across machines.
|
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
|
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>`
|
`git clone` without a local install — at which point `<execution_context>`
|
||||||
portability becomes in scope.
|
portability becomes in scope.
|
||||||
|
|
||||||
## Prior requests
|
## 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
|
## Related
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Human-Readable Rendering of PLAN.md
|
# 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
|
`<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.
|
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
|
- `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
|
structured document that tells an executor agent exactly what to build and how
|
||||||
to verify it was built correctly."*
|
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
|
implement without interpretation. Plans are prompts, not documents that become
|
||||||
prompts."*
|
prompts."*
|
||||||
|
|
||||||
PLAN.md is produced by `gsd-planner` and consumed by `gsd-executor`,
|
PLAN.md is produced by `msd-planner` and consumed by `msd-executor`,
|
||||||
`gsd-plan-checker`, `gsd-verifier`, and cross-AI review agents. There is no
|
`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
|
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
|
PLAN.md — unlike `SUMMARY.md` / `VERIFICATION.md`, which are produced for human
|
||||||
validation.
|
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
|
frontmatter breaking rendered markdown tables): that too is a human-render
|
||||||
concern for a machine artifact.
|
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
|
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.
|
PLAN.md gains a documented human audience and its rendering becomes in-scope.
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
Reporter observed 436 of 556 dirty `git status` entries in a real project coming from agent
|
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 —
|
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
|
`.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
|
`.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
|
`__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
|
The underlying complaint is real and well-evidenced: continuously-rewritten runtime state buried
|
||||||
296 genuine changed files under 436 runtime entries.
|
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
|
- **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
|
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
|
"only two entries" nor installed anywhere. No copy manifest, installer path, or workflow ships
|
||||||
it into a user project.
|
it into a user project.
|
||||||
- **The only project-`.gitignore` write GSD performs is a single `.planning/` line**, and only
|
- **The only project-`.gitignore` write MSD performs is a single `.planning/` line**, and only
|
||||||
when the operator answers `commit_docs = No` at init (`gsd-core/workflows/new-project.md:638`,
|
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.
|
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/`,
|
- **`.omc` and `.omo` are not MSD artifacts.** Zero occurrences across `src/`, `bin/`,
|
||||||
`gsd-core/`, `commands/`, `agents/`, `capabilities/`, `docs/`, and every shipped `.md`, `.json`
|
`msd-core/`, `commands/`, `agents/`, `capabilities/`, `docs/`, and every shipped `.md`, `.json`
|
||||||
and `.yml`. GSD neither creates, reads, nor has any knowledge of those directories. Ignoring
|
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 GSD-authored ignore list naming
|
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 GSD would
|
third-party paths would silently rot as those tools rename their directories, and MSD would
|
||||||
have no signal that it had.
|
have no signal that it had.
|
||||||
- **The one GSD-owned path named in the report is already governed.** `.planning/forensics/` is
|
- **The one MSD-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
|
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`
|
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.
|
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
|
## 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
|
`.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:
|
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.
|
live defect, and this entry is not a precedent against fixing it.
|
||||||
- Making the existing `.planning/` ignore write more robust — idempotency, ordering, handling a
|
- Making the existing `.planning/` ignore write more robust — idempotency, ordering, handling a
|
||||||
missing or malformed `.gitignore`.
|
missing or malformed `.gitignore`.
|
||||||
- Ignore-list handling for directories a **GSD capability** creates.
|
- Ignore-list handling for directories a **MSD capability** creates.
|
||||||
- Documentation telling users which paths their own toolchain should ignore alongside a GSD
|
- Documentation telling users which paths their own toolchain should ignore alongside a MSD
|
||||||
project, as prose rather than as a generated file.
|
project, as prose rather than as a generated file.
|
||||||
|
|
||||||
## Re-open criteria
|
## Re-open criteria
|
||||||
|
|
||||||
Concrete and checkable:
|
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.
|
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.
|
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;
|
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
|
## Related
|
||||||
|
|
||||||
- `gsd-core/workflows/new-project.md` — the `commit_docs` decision and the `.planning/` ignore write
|
- `msd-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/forensics.md` — writes `.planning/forensics/`, under the `.planning/` umbrella
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Statusline Account / Usage Segment (credential-reading, external API)
|
# 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,
|
display account-level resource state (5-hour / 7-day rate-limit utilization,
|
||||||
usage windows, plan quotas).
|
usage windows, plan quotas).
|
||||||
|
|
||||||
@@ -9,7 +9,7 @@ usage windows, plan quotas).
|
|||||||
The statusline draws its data boundary at **local, read-only** sources — see
|
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).
|
[`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,
|
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
|
- read Claude Code's OAuth credentials (`.credentials.json`, or the macOS login
|
||||||
Keychain via `security`), or
|
Keychain via `security`), or
|
||||||
@@ -27,10 +27,10 @@ Reasons:
|
|||||||
- **Scope.** Surfacing account/rate-limit state is a platform (Claude Code)
|
- **Scope.** Surfacing account/rate-limit state is a platform (Claude Code)
|
||||||
concern. This matches the prior in
|
concern. This matches the prior in
|
||||||
[`temporal-context.md`](./temporal-context.md): *"Statusline / TUI re-entry is
|
[`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
|
**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.
|
available. That would move usage display out of the excluded tier.
|
||||||
|
|
||||||
## Prior requests
|
## Prior requests
|
||||||
|
|||||||
@@ -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
|
`expectedArtifacts` declarations, a `watchdog.*` config block, and bounded chunk resume
|
||||||
that preserves already-committed chunks. Explicitly not `ps aux`, explicitly no auto-kill.
|
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.**
|
- **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
|
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`
|
periodic surveillance loop (`:755-762`) gated on `executor.stall_detect_interval_minutes`
|
||||||
and `executor.stall_threshold_minutes` (read at `:100-101`; both registered in
|
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
|
rearchitecture. Accepting #2699 would mean building the larger system on top of a
|
||||||
foundation that has not landed.
|
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
|
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
|
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
|
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
|
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.
|
resolve by picking a different host.
|
||||||
|
|
||||||
- **The heartbeat has no place to live.** Agents emitting JSON every 30–60 seconds
|
- **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
|
exposes. Absent a wrapper, the spawned agent would have to interleave heartbeat
|
||||||
emission with its actual work, competing for the same turn.
|
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.
|
denied by nothing here.
|
||||||
- **Orphaned OS processes, containers, or bench resources.** Leaked test-runner containers
|
- **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
|
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.
|
says nothing about them.
|
||||||
|
|
||||||
## Re-open criteria
|
## Re-open criteria
|
||||||
@@ -107,7 +107,7 @@ no longer sufficient — not before.
|
|||||||
|
|
||||||
## Related
|
## 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
|
- `src/config.cts` — `SCHEMA_DEFAULTS`, where `executor.stall_*` keys are registered
|
||||||
- `docs/reference/host-integration-capability-matrix.md` — per-runtime `hookBus` / `stateIO` surfaces
|
- `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
|
- [#2650](https://github.com/open-gsd/gsd-core/issues/2650) — the confirmed defect this was redirected to
|
||||||
|
|||||||
@@ -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)
|
**Source:** [#2756](https://github.com/open-gsd/gsd-core/issues/2756)
|
||||||
**Decision:** wontfix — closed without further engagement
|
**Decision:** wontfix — closed without further engagement
|
||||||
@@ -7,29 +7,29 @@
|
|||||||
## Proposal summary
|
## Proposal summary
|
||||||
|
|
||||||
Reporter proposed treating idle-time-between-turns as a first-class context signal in
|
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
|
1. **Passive** — block at session resume injecting "you've been idle Nh, here's what was
|
||||||
open" into the orchestrator prompt.
|
open" into the orchestrator prompt.
|
||||||
2. **Active** — `/resume-context` slash command.
|
2. **Active** — `/resume-context` slash command.
|
||||||
3. **Retrospective** — `HANDOFF.json` written at session end, read at next start.
|
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.
|
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
|
- **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
|
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.
|
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,
|
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
|
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.
|
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
|
- **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 GSD's phase
|
idle time belongs in Claude Code itself or in a thin user plugin, not in MSD's phase
|
||||||
machinery.
|
machinery.
|
||||||
- **Scope is unstable.** Reporter agreed with the narrowed minimum ask ("doc mention
|
- **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
|
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
|
## Related
|
||||||
|
|
||||||
- `.planning/state/` — existing session-continuity artifacts
|
- `.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
|
||||||
|
|||||||
@@ -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)
|
**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)
|
**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)
|
## 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
|
## 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.
|
- **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
|
## 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:
|
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 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 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 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.
|
- **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.
|
- **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.**
|
- **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
|
## 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).
|
- 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
|
## 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
|
- [`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
|
- [`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
|
- [`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/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
|
- [`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
|
||||||
|
|||||||
@@ -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.
|
**Line 5391-5392** — After `fs.copyFileSync`, add `fs.chmodSync(destFile, 0o755)` for `.sh` files.
|
||||||
|
|
||||||
### Fix 2: Fix Codex hook path and filename (CRITICAL)
|
### 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 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 `gsd-check-update`.
|
**Line 5492** — Update dedup check to use `msd-check-update`.
|
||||||
|
|
||||||
### Fix 3: Fix stale cache invalidation path (CRITICAL)
|
### 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)
|
### Fix 4: Track .sh hooks in manifest (MEDIUM)
|
||||||
**Line 4972** — Change filter from `file.endsWith('.js')` to `(file.endsWith('.js') || file.endsWith('.sh'))`.
|
**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)
|
### Fix 5: Add msd-workflow-guard.js to uninstall hook list (MEDIUM)
|
||||||
**Line 4404** — Add `'gsd-workflow-guard.js'` to the `gsdHooks` array.
|
**Line 4404** — Add `'msd-workflow-guard.js'` to the `msdHooks` array.
|
||||||
|
|
||||||
### Fix 6: Add community hooks to uninstall settings.json cleanup (MEDIUM)
|
### 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)
|
### Fix 7: Remove phantom msd-check-update.sh from uninstall list (LOW)
|
||||||
**Line 4404** — Remove `'gsd-check-update.sh'` from `gsdHooks` array.
|
**Line 4404** — Remove `'msd-check-update.sh'` from `msdHooks` array.
|
||||||
|
|
||||||
### Fix 8: Remove dead isCursor/isWindsurf branches in uninstall (LOW)
|
### Fix 8: Remove dead isCursor/isWindsurf branches in uninstall (LOW)
|
||||||
Remove the unreachable duplicate `else if (isCursor)` and `else if (isWindsurf)` branches.
|
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
|
- .sh files tracked in manifest
|
||||||
- settings.json hook paths match installed files
|
- settings.json hook paths match installed files
|
||||||
- uninstall removes community hooks from settings.json
|
- uninstall removes community hooks from settings.json
|
||||||
- uninstall removes gsd-workflow-guard.js
|
- uninstall removes msd-workflow-guard.js
|
||||||
- Codex hook uses correct filename
|
- Codex hook uses correct filename
|
||||||
- Cache path resolves correctly
|
- Cache path resolves correctly
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
#!/usr/bin/env bash
|
#!/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
|
# Checks every 15 minutes, writes new release info to a signal file
|
||||||
|
|
||||||
REPO="open-gsd/gsd-core"
|
REPO="golem15com/msd-core"
|
||||||
SIGNAL_FILE="/tmp/gsd-new-release.json"
|
SIGNAL_FILE="/tmp/msd-new-release.json"
|
||||||
STATE_FILE="/tmp/gsd-monitor-last-tag"
|
STATE_FILE="/tmp/msd-monitor-last-tag"
|
||||||
LOG_FILE="/tmp/gsd-monitor.log"
|
LOG_FILE="/tmp/msd-monitor.log"
|
||||||
|
|
||||||
# Initialize with current latest
|
# Initialize with current latest
|
||||||
echo "v1.25.1" > "$STATE_FILE"
|
echo "v1.25.1" > "$STATE_FILE"
|
||||||
|
|||||||
@@ -23,10 +23,10 @@
|
|||||||
# Lint: scripts/secret-scan-lint.sh --file .secretscanignore
|
# Lint: scripts/secret-scan-lint.sh --file .secretscanignore
|
||||||
# Strict scan: scripts/secret-scan.sh --diff origin/main --strict
|
# 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"
|
# 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"
|
||||||
gsd-core/workflows/plan-phase.md
|
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"
|
# 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"
|
||||||
gsd-core/references/verification-patterns.md
|
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"
|
# 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
|
docs/zh-CN/references/verification-patterns.md
|
||||||
|
|||||||
406
CONTEXT.md
406
CONTEXT.md
File diff suppressed because one or more lines are too long
106
CONTRIBUTING.md
106
CONTRIBUTING.md
@@ -1,11 +1,11 @@
|
|||||||
# Contributing to GSD Core
|
# Contributing to MSD Core
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Clone the repo
|
# Clone the repo
|
||||||
git clone https://github.com/open-gsd/gsd-core.git
|
git clone https://github.com/golem15com/msd-core.git
|
||||||
cd gsd-core
|
cd msd-core
|
||||||
|
|
||||||
# Activate the pinned Node version from .nvmrc
|
# Activate the pinned Node version from .nvmrc
|
||||||
nvm use
|
nvm use
|
||||||
@@ -31,7 +31,7 @@ environment validator, daily commands, and troubleshooting.
|
|||||||
|
|
||||||
## Types of Contributions
|
## 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)
|
### 🐛 Fix (Bug Report)
|
||||||
|
|
||||||
@@ -72,11 +72,11 @@ A feature adds something new — a new command, a new workflow, a new concept, a
|
|||||||
**Process:**
|
**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.
|
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.
|
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.
|
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.
|
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)
|
## 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
|
and `next` (integration for the upcoming release). **Almost every PR targets
|
||||||
`next`.** Full guide: [`docs/branching.md`](docs/branching.md).
|
`next`.** Full guide: [`docs/branching.md`](docs/branching.md).
|
||||||
|
|
||||||
@@ -142,7 +142,7 @@ git checkout next
|
|||||||
git pull --ff-only origin next
|
git pull --ff-only origin next
|
||||||
git checkout -b fix/3187-config-corruption
|
git checkout -b fix/3187-config-corruption
|
||||||
# ... commit, push
|
# ... 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`
|
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
|
**But `next` does still require "up-to-date before merging".** Branch
|
||||||
protection has `required_status_checks.strict = true`; check it yourself with
|
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
|
If another PR lands while yours is open, yours goes `BEHIND` and must be
|
||||||
rebased before it can merge.
|
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.
|
- **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.
|
- **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.
|
- **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.
|
- 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
|
- **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
|
- **No drive-by formatting** — don't reformat code unrelated to your change
|
||||||
@@ -206,14 +206,14 @@ Contributor requirements (summary):
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run changeset -- --type Fixed --pr <YOUR_PR_NUMBER> \
|
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`.
|
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.
|
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:
|
> **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
|
```bash
|
||||||
node scripts/release-notes/format-github-release-notes.cjs \
|
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
|
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:
|
Import helpers from `tests/helpers.cjs` instead of inlining temp directory creation:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const { createTempProject, createTempGitProject, createTempDir, cleanup, runGsdTools } = require('./helpers.cjs');
|
const { createTempProject, createTempGitProject, createTempDir, cleanup, runMsdTools } = require('./helpers.cjs');
|
||||||
```
|
```
|
||||||
|
|
||||||
| Helper | Creates | Use When |
|
| 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 |
|
| `createTempGitProject(prefix?)` | Same + git init + initial commit | Testing git-dependent features |
|
||||||
| `createTempDir(prefix?)` | Bare temp directory | Testing features that don't need `.planning/` |
|
| `createTempDir(prefix?)` | Bare temp directory | Testing features that don't need `.planning/` |
|
||||||
| `cleanup(tmpDir)` | Removes directory recursively | Always use in `afterEach` |
|
| `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
|
### 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
|
#### 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:
|
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).
|
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
|
#### Filesystem writes and installers
|
||||||
|
|
||||||
@@ -825,7 +825,7 @@ Generator tests should run in temp fixtures and assert atomic output behavior. D
|
|||||||
```javascript
|
```javascript
|
||||||
// BAD — source-grep theater
|
// BAD — source-grep theater
|
||||||
const configSrc = fs.readFileSync(
|
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(
|
assert.ok(
|
||||||
configSrc.includes("'workflow.plan_bounce'"),
|
configSrc.includes("'workflow.plan_bounce'"),
|
||||||
@@ -843,7 +843,7 @@ test('config-set accepts workflow.plan_bounce', (t) => {
|
|||||||
const tmpDir = createTempProject();
|
const tmpDir = createTempProject();
|
||||||
t.after(() => cleanup(tmpDir));
|
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}`);
|
assert.ok(result.success, `config-set should accept workflow.plan_bounce: ${result.error}`);
|
||||||
|
|
||||||
const configPath = path.join(tmpDir, '.planning', 'config.json');
|
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. |
|
| `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. |
|
| `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. |
|
| `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. |
|
| `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
|
**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
|
```javascript
|
||||||
// BAD — substring match on text written by the code under test
|
// 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');
|
assert.ok(cmdContent.includes(`@node ${jsonQuoted} %*`), '.cmd embeds shim path');
|
||||||
|
|
||||||
// BAD — regex match on a child process's human-readable stdout formatter
|
// 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
|
#### 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
|
#### 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.
|
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.
|
- 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.
|
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
|
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`
|
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
|
values derived from its `*_COMMAND_ALIASES` table, in order, and each router must
|
||||||
reference its own list. The surface is enumerated once in
|
reference its own list. The surface is enumerated once in
|
||||||
`scripts/lib/alias-drift-families.cjs`.
|
`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
|
command definition — requires **zero manual fixture regeneration**. There is no
|
||||||
committed path→hash manifest or per-file size baseline to update by hand; the
|
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
|
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):
|
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
|
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
|
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
|
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
|
`tests/workflow-size-budget.test.cjs` / `tests/agent-size-budget.test.cjs` are unaffected
|
||||||
and still apply.
|
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
|
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
|
commits. Note the two key spaces, because the message says which one applies: an
|
||||||
unattributable **hash** ripple is keyed on the emitted path
|
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
|
(`skills/msd-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
|
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
|
structurally distinct — a `Growth` trailer never excuses a `Hash` ripple, even when the key
|
||||||
text happens to match.
|
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:
|
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
|
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
|
```bash
|
||||||
# set locally in your shell profile (example)
|
# 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,
|
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`
|
### Every `commit` invocation in shipped content must declare `--files`
|
||||||
|
|
||||||
`tests/commit-files-pathspec.test.cjs` scans every `.md` under `gsd-core/workflows/`,
|
`tests/commit-files-pathspec.test.cjs` scans every `.md` under `msd-core/workflows/`,
|
||||||
`gsd-core/references/`, `agents/`, `commands/`, `skills/` and `docs/` for invocations of
|
`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`
|
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
|
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),
|
`.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:
|
hit while editing shipped content, and the failure output names both:
|
||||||
|
|
||||||
**A prose mention that runs into its sentence is flagged.** Nothing distinguishes
|
**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
|
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.
|
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:
|
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
|
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
|
### 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/`,
|
`tests/commit-docs-bypass.test.cjs` scans every `.md` under `msd-core/workflows/`,
|
||||||
`gsd-core/references/`, `agents/`, `commands/` and `skills/` and fails if a `git add` that could
|
`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.
|
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.
|
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 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
|
```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
|
if [ "$COMMIT_DOCS" != "false" ]; then
|
||||||
git add "${ARTIFACT}"
|
git add "${ARTIFACT}"
|
||||||
fi
|
fi
|
||||||
```
|
```
|
||||||
|
|
||||||
Both polarities are accepted (`!= "false"` and `= "true"`). The `|| echo "true"` fallback is
|
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.
|
planning docs for someone who wants them.
|
||||||
|
|
||||||
Three consequences worth knowing before you edit shipped content:
|
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`
|
**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
|
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.
|
the check and the `git add` in the same block.
|
||||||
|
|
||||||
**An unresolvable path is treated as reaching `.planning/`.** `git add "${ARTIFACT}"` is flagged,
|
**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
|
**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.
|
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
|
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
|
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
|
(`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,
|
**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
|
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)
|
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
|
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
|
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
|
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 |
|
| 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 — 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-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) |
|
| `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
|
## Code Style
|
||||||
|
|
||||||
- **CommonJS** (`.cjs`) — the project uses `require()`, not ESM `import`
|
- **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
|
- **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/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).
|
- **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
|
## File Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
bin/install.js — Installer (multi-runtime)
|
bin/install.js — Installer (multi-runtime)
|
||||||
gsd-core/
|
msd-core/
|
||||||
bin/lib/ — Core library modules (.cjs)
|
bin/lib/ — Core library modules (.cjs)
|
||||||
workflows/ — Workflow definitions (.md)
|
workflows/ — Workflow definitions (.md)
|
||||||
Large workflows split per progressive-disclosure
|
Large workflows split per progressive-disclosure
|
||||||
@@ -1397,14 +1397,14 @@ gsd-core/
|
|||||||
requires an Emitted-Drift-Ack-Growth commit trailer
|
requires an Emitted-Drift-Ack-Growth commit trailer
|
||||||
(ADR-3942), no committed snapshot to regenerate. Loose tier
|
(ADR-3942), no committed snapshot to regenerate. Loose tier
|
||||||
hard caps remain in tests/workflow-size-budget.test.cjs.
|
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 +
|
tests/agent-size-budget.test.cjs). Full how-to +
|
||||||
reference in docs/TESTING-SUITES.md (Workflow &
|
reference in docs/TESTING-SUITES.md (Workflow &
|
||||||
agent size budget); see issue #1074.
|
agent size budget); see issue #1074.
|
||||||
references/ — Reference documentation (.md)
|
references/ — Reference documentation (.md)
|
||||||
templates/ — File templates
|
templates/ — File templates
|
||||||
agents/ — Agent definitions (.md) — CANONICAL SOURCE
|
agents/ — Agent definitions (.md) — CANONICAL SOURCE
|
||||||
commands/gsd/ — Slash command definitions (.md)
|
commands/msd/ — Slash command definitions (.md)
|
||||||
tests/ — Test files (.test.cjs)
|
tests/ — Test files (.test.cjs)
|
||||||
helpers.cjs — Shared test utilities
|
helpers.cjs — Shared test utilities
|
||||||
docs/ — User-facing documentation
|
docs/ — User-facing documentation
|
||||||
@@ -1412,13 +1412,13 @@ docs/ — User-facing documentation
|
|||||||
|
|
||||||
### Source of truth for agents
|
### 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 |
|
| Path | Gitignored | What it is |
|
||||||
|------|-----------|------------|
|
|------|-----------|------------|
|
||||||
| `.claude/agents/` | Yes (`.gitignore:9`) | Local Claude Code runtime sync |
|
| `.claude/agents/` | Yes (`.gitignore:9`) | Local Claude Code runtime sync |
|
||||||
| `.cursor/agents/` | Yes (`.gitignore:12`) | Local Cursor IDE bundle |
|
| `.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.
|
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.
|
||||||
|
|
||||||
|
|||||||
36
GEMINI.md
36
GEMINI.md
@@ -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
|
> **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
|
> 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).
|
> `GEMINI.md`, inherited from the shared Gemini 3 backend).
|
||||||
|
|
||||||
This context gives Antigravity the operating context for
|
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.
|
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
|
resumable workflow: **explore → plan → execute → verify → ship**. Work is
|
||||||
organised into milestones and phases under a `.planning/` directory, with each
|
organised into milestones and phases under a `.planning/` directory, with each
|
||||||
phase carrying a SPEC, a PLAN, and verification criteria. The system favours
|
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)
|
## The slash commands (installed separately)
|
||||||
|
|
||||||
> **This file ships only the context above — not the slash commands.** To
|
> **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:
|
> run the dedicated installer:
|
||||||
>
|
>
|
||||||
> ```bash
|
> ```bash
|
||||||
> npx gsd-core --antigravity --global
|
> npx msd-core --antigravity --global
|
||||||
> ```
|
> ```
|
||||||
>
|
>
|
||||||
> The commands below are available only once that installer has run.
|
> 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-*`
|
If you have installed the msd commands, the workflow is driven by these `/msd-*`
|
||||||
slash commands (Antigravity registers gsd's commands under a hyphenated
|
slash commands (Antigravity registers msd's commands under a hyphenated
|
||||||
namespace):
|
namespace):
|
||||||
|
|
||||||
- `/gsd-new-project` — initialise a project and gather deep context.
|
- `/msd-new-project` — initialise a project and gather deep context.
|
||||||
- `/gsd-progress` — the unified situational command: check progress, advance the
|
- `/msd-progress` — the unified situational command: check progress, advance the
|
||||||
workflow, or dispatch a freeform intent.
|
workflow, or dispatch a freeform intent.
|
||||||
- `/gsd-plan-phase <N>` — produce a detailed phase plan with a verification loop.
|
- `/msd-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.
|
- `/msd-execute-phase <N>` — execute a phase's plans with wave-based parallelism.
|
||||||
- `/gsd-verify-work` — validate built features through conversational UAT.
|
- `/msd-verify-work` — validate built features through conversational UAT.
|
||||||
- `/gsd-ship` — open a PR, run review, and prepare for merge.
|
- `/msd-ship` — open a PR, run review, and prepare for merge.
|
||||||
- `/gsd-help` — list every available command.
|
- `/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
|
- Treat `.planning/` as the source of truth for project state — read it before
|
||||||
acting, and keep it current as work progresses.
|
acting, and keep it current as work progresses.
|
||||||
- Prefer the smallest change that satisfies the phase's verification criteria.
|
- Prefer the smallest change that satisfies the phase's verification criteria.
|
||||||
- Run the project's tests and linters before declaring a phase done.
|
- 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.
|
is the situational entry point.
|
||||||
|
|
||||||
Learn more: <https://github.com/open-gsd/gsd-core>
|
Learn more: <https://github.com/golem15com/msd-core>
|
||||||
|
|||||||
1
LICENSE
1
LICENSE
@@ -1,6 +1,7 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2026 Open GSD
|
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
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -1,27 +1,27 @@
|
|||||||
<div align="center">
|
<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)
|
[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 などに対応した、軽量なメタプロンプティング・コンテキストエンジニアリング・仕様駆動開発システムです。**
|
**Claude Code、OpenCode、Antigravity CLI、Kimi CLI、Kilo、Codex、Copilot、Cursor、Windsurf などに対応した、軽量なメタプロンプティング・コンテキストエンジニアリング・仕様駆動開発システムです。**
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/@opengsd/gsd-core)
|
[](https://www.npmjs.com/package/@golem15/msd-core)
|
||||||
[](https://www.npmjs.com/package/@opengsd/gsd-core)
|
[](https://www.npmjs.com/package/@golem15/msd-core)
|
||||||
[](https://github.com/open-gsd/gsd-core/actions/workflows/test.yml)
|
[](https://github.com/open-gsd/gsd-core/actions/workflows/test.yml)
|
||||||
[](https://discord.gg/mYgfVNfA2r)
|
[](https://discord.gg/mYgfVNfA2r)
|
||||||
[](https://github.com/open-gsd/gsd-core)
|
[](https://github.com/golem15com/msd-core)
|
||||||
[](LICENSE)
|
[](LICENSE)
|
||||||
|
|
||||||
</div>
|
</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
|
```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/` からファイルを直接コピーしないでください。
|
インストーラーはランタイム(Claude Code、OpenCode、Antigravity CLI、Kimi CLI、Kilo、Codex、Copilot、Cursor、Windsurf など)とグローバルインストールかローカルインストールかを尋ねます。クロスランタイム互換性のためにインストーラーが必要です。`agents/` や `commands/` からファイルを直接コピーしないでください。
|
||||||
@@ -50,8 +50,8 @@ npx @opengsd/gsd-core@latest
|
|||||||
インストール後、新規プロジェクトを開始するか、既存リポジトリをオンボーディングします。
|
インストール後、新規プロジェクトを開始するか、既存リポジトリをオンボーディングします。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
/gsd-new-project # グリーンフィールドプロジェクト
|
/msd-new-project # グリーンフィールドプロジェクト
|
||||||
/gsd-onboard # 既存コードベース
|
/msd-onboard # 既存コードベース
|
||||||
```
|
```
|
||||||
|
|
||||||
初めての方は [はじめてのプロジェクト](docs/ja-JP/tutorials/your-first-project.md) で、インストールから最初のフェーズ出荷までのガイド付きチュートリアルをご覧ください。既存リポジトリの場合は [既存コードベースのオンボーディング](docs/ja-JP/tutorials/onboarding-an-existing-codebase.md) を参照してください。
|
初めての方は [はじめてのプロジェクト](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) を参照してください。
|
トラブルシューティングは [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>
|
<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: 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=open-gsd/gsd-core&type=Date" />
|
<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=open-gsd/gsd-core&type=Date" />
|
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=golem15com/msd-core&type=Date" />
|
||||||
</picture>
|
</picture>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
@@ -121,6 +121,6 @@ MIT ライセンス。詳細は [LICENSE](LICENSE) を参照してください
|
|||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
|
|
||||||
**Claude Code は強力です。GSD Core はそれを信頼できるものにします。**
|
**Claude Code は強力です。MSD Core はそれを信頼できるものにします。**
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,27 +1,27 @@
|
|||||||
<div align="center">
|
<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) · **한국어**
|
[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 등을 위한 경량 메타 프롬프팅, 컨텍스트 엔지니어링, 스펙 기반 개발 시스템.**
|
**Claude Code, OpenCode, Antigravity CLI, Kimi CLI, Kilo, Codex, Copilot, Cursor, Windsurf 등을 위한 경량 메타 프롬프팅, 컨텍스트 엔지니어링, 스펙 기반 개발 시스템.**
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/@opengsd/gsd-core)
|
[](https://www.npmjs.com/package/@golem15/msd-core)
|
||||||
[](https://www.npmjs.com/package/@opengsd/gsd-core)
|
[](https://www.npmjs.com/package/@golem15/msd-core)
|
||||||
[](https://github.com/open-gsd/gsd-core/actions/workflows/test.yml)
|
[](https://github.com/open-gsd/gsd-core/actions/workflows/test.yml)
|
||||||
[](https://discord.gg/mYgfVNfA2r)
|
[](https://discord.gg/mYgfVNfA2r)
|
||||||
[](https://github.com/open-gsd/gsd-core)
|
[](https://github.com/golem15com/msd-core)
|
||||||
[](LICENSE)
|
[](LICENSE)
|
||||||
|
|
||||||
</div>
|
</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
|
```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/`에서 파일을 직접 복사하지 마세요.
|
설치 프로그램이 런타임(Claude Code, OpenCode, Antigravity CLI, Kimi CLI, Kilo, Codex, Copilot, Cursor, Windsurf 등)과 전역/로컬 설치 여부를 묻습니다. 크로스 런타임 호환성을 위해 설치 프로그램을 사용해야 합니다 — `agents/` 또는 `commands/`에서 파일을 직접 복사하지 마세요.
|
||||||
@@ -50,8 +50,8 @@ npx @opengsd/gsd-core@latest
|
|||||||
설치 후 새 프로젝트를 시작하거나 기존 저장소를 온보딩합니다:
|
설치 후 새 프로젝트를 시작하거나 기존 저장소를 온보딩합니다:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
/gsd-new-project # 그린필드 프로젝트
|
/msd-new-project # 그린필드 프로젝트
|
||||||
/gsd-onboard # 기존 코드베이스
|
/msd-onboard # 기존 코드베이스
|
||||||
```
|
```
|
||||||
|
|
||||||
처음 사용하시나요? [첫 번째 프로젝트](docs/ko-KR/tutorials/your-first-project.md)를 따라 설치부터 첫 단계 출시까지 안내받으세요. 기존 저장소라면 [기존 코드베이스 온보딩](docs/ko-KR/tutorials/onboarding-an-existing-codebase.md)을 참고하세요.
|
처음 사용하시나요? [첫 번째 프로젝트](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)를 확인하세요.
|
문제가 발생했나요? [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>
|
<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: 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=open-gsd/gsd-core&type=Date" />
|
<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=open-gsd/gsd-core&type=Date" />
|
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=golem15com/msd-core&type=Date" />
|
||||||
</picture>
|
</picture>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
@@ -121,6 +121,6 @@ MIT 라이선스. 자세한 내용은 [LICENSE](LICENSE)를 참조하세요.
|
|||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
|
|
||||||
**Claude Code는 강력합니다. GSD Core가 그걸 신뢰할 수 있게 만듭니다.**
|
**Claude Code는 강력합니다. MSD Core가 그걸 신뢰할 수 있게 만듭니다.**
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
34
README.md
34
README.md
@@ -1,27 +1,27 @@
|
|||||||
<div align="center">
|
<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)
|
**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.**
|
**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.**
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/@opengsd/gsd-core)
|
[](https://www.npmjs.com/package/@golem15/msd-core)
|
||||||
[](https://www.npmjs.com/package/@opengsd/gsd-core)
|
[](https://www.npmjs.com/package/@golem15/msd-core)
|
||||||
[](https://github.com/open-gsd/gsd-core/actions/workflows/test.yml)
|
[](https://github.com/open-gsd/gsd-core/actions/workflows/test.yml)
|
||||||
[](https://discord.gg/mYgfVNfA2r)
|
[](https://discord.gg/mYgfVNfA2r)
|
||||||
[](https://github.com/open-gsd/gsd-core)
|
[](https://github.com/golem15com/msd-core)
|
||||||
[](LICENSE)
|
[](LICENSE)
|
||||||
|
|
||||||
</div>
|
</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
|
## Quickstart
|
||||||
|
|
||||||
```bash
|
```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.
|
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:
|
Once installed, start a new project or onboard an existing repo:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
/gsd-new-project # greenfield project
|
/msd-new-project # greenfield project
|
||||||
/gsd-onboard # existing codebase
|
/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.
|
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
|
## 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).
|
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
|
## Star History
|
||||||
|
|
||||||
<a href="https://star-history.com/#open-gsd/gsd-core&Date">
|
<a href="https://star-history.com/#golem15com/msd-core&Date">
|
||||||
<picture>
|
<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: 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=open-gsd/gsd-core&type=Date" />
|
<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=open-gsd/gsd-core&type=Date" />
|
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=golem15com/msd-core&type=Date" />
|
||||||
</picture>
|
</picture>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
@@ -133,6 +133,6 @@ MIT License. See [LICENSE](LICENSE) for details.
|
|||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
|
|
||||||
**Claude Code is powerful. GSD Core makes it reliable.**
|
**Claude Code is powerful. MSD Core makes it reliable.**
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,27 +1,27 @@
|
|||||||
<div align="center">
|
<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)
|
[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.**
|
**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.**
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/@opengsd/gsd-core)
|
[](https://www.npmjs.com/package/@golem15/msd-core)
|
||||||
[](https://www.npmjs.com/package/@opengsd/gsd-core)
|
[](https://www.npmjs.com/package/@golem15/msd-core)
|
||||||
[](https://github.com/open-gsd/gsd-core/actions/workflows/test.yml)
|
[](https://github.com/open-gsd/gsd-core/actions/workflows/test.yml)
|
||||||
[](https://discord.gg/mYgfVNfA2r)
|
[](https://discord.gg/mYgfVNfA2r)
|
||||||
[](https://github.com/open-gsd/gsd-core)
|
[](https://github.com/golem15com/msd-core)
|
||||||
[](LICENSE)
|
[](LICENSE)
|
||||||
|
|
||||||
</div>
|
</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
|
## Início rápido
|
||||||
|
|
||||||
```bash
|
```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/`.
|
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:
|
Após a instalação, inicie um projeto novo ou integre um repositório existente:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
/gsd-new-project # projeto greenfield
|
/msd-new-project # projeto greenfield
|
||||||
/gsd-onboard # base de código existente
|
/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).
|
É 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
|
## 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).
|
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
|
## 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>
|
<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: 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=open-gsd/gsd-core&type=Date" />
|
<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=open-gsd/gsd-core&type=Date" />
|
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=golem15com/msd-core&type=Date" />
|
||||||
</picture>
|
</picture>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
@@ -121,6 +121,6 @@ Licença MIT. Consulte [LICENSE](LICENSE) para detalhes.
|
|||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
|
|
||||||
**Claude Code é poderoso. GSD Core o torna confiável.**
|
**Claude Code é poderoso. MSD Core o torna confiável.**
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,27 +1,27 @@
|
|||||||
<div align="center">
|
<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)
|
[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 编程工具。**
|
**一套轻量级的元提示、上下文工程与规范驱动开发系统,适用于 Claude Code、OpenCode、Antigravity CLI、Kimi CLI、Kilo、Codex、Copilot、Cursor、Windsurf 等 AI 编程工具。**
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/@opengsd/gsd-core)
|
[](https://www.npmjs.com/package/@golem15/msd-core)
|
||||||
[](https://www.npmjs.com/package/@opengsd/gsd-core)
|
[](https://www.npmjs.com/package/@golem15/msd-core)
|
||||||
[](https://github.com/open-gsd/gsd-core/actions/workflows/test.yml)
|
[](https://github.com/open-gsd/gsd-core/actions/workflows/test.yml)
|
||||||
[](https://discord.gg/mYgfVNfA2r)
|
[](https://discord.gg/mYgfVNfA2r)
|
||||||
[](https://github.com/open-gsd/gsd-core)
|
[](https://github.com/golem15com/msd-core)
|
||||||
[](LICENSE)
|
[](LICENSE)
|
||||||
|
|
||||||
</div>
|
</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
|
```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/` 目录复制文件。
|
安装程序会提示选择运行时(Claude Code、OpenCode、Antigravity CLI、Kimi CLI、Kilo、Codex、Copilot、Cursor、Windsurf 等)以及是全局安装还是本地安装。跨运行时兼容性需要使用安装程序——请勿直接从 `agents/` 或 `commands/` 目录复制文件。
|
||||||
@@ -50,8 +50,8 @@ npx @opengsd/gsd-core@latest
|
|||||||
安装完成后,启动一个新项目或接入现有仓库:
|
安装完成后,启动一个新项目或接入现有仓库:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
/gsd-new-project # 新建项目
|
/msd-new-project # 新建项目
|
||||||
/gsd-onboard # 现有代码库
|
/msd-onboard # 现有代码库
|
||||||
```
|
```
|
||||||
|
|
||||||
初次使用?请按照[你的第一个项目](docs/zh-CN/tutorials/your-first-project.md)进行引导式操作,从安装到完成第一个交付阶段。对于现有仓库,请参阅[接入现有代码库](docs/zh-CN/tutorials/onboarding-an-existing-codebase.md)。
|
初次使用?请按照[你的第一个项目](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)。
|
遇到问题?请参阅 [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
|
## Star History
|
||||||
|
|
||||||
<a href="https://star-history.com/#open-gsd/gsd-core&Date">
|
<a href="https://star-history.com/#golem15com/msd-core&Date">
|
||||||
<picture>
|
<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: 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=open-gsd/gsd-core&type=Date" />
|
<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=open-gsd/gsd-core&type=Date" />
|
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=golem15com/msd-core&type=Date" />
|
||||||
</picture>
|
</picture>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
@@ -121,6 +121,6 @@ MIT 许可证。详情请参阅 [LICENSE](LICENSE)。
|
|||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
|
|
||||||
**Claude Code 功能强大。GSD Core 让它更可靠。**
|
**Claude Code 功能强大。MSD Core 让它更可靠。**
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ Include:
|
|||||||
|
|
||||||
## Scope
|
## Scope
|
||||||
|
|
||||||
Security issues in the GSD codebase that could:
|
Security issues in the MSD codebase that could:
|
||||||
- Execute arbitrary code on user machines
|
- Execute arbitrary code on user machines
|
||||||
- Expose sensitive data (API keys, credentials)
|
- Expose sensitive data (API keys, credentials)
|
||||||
- Compromise the integrity of generated plans/code
|
- 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
|
### 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 |
|
| Code | Meaning |
|
||||||
|--:|---|
|
|--:|---|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Test Examples
|
# 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.
|
The examples are intentionally small. Copy the pattern, not the exact assertion text.
|
||||||
|
|
||||||
@@ -51,13 +51,13 @@ const cases = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
for (const scenario of 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-');
|
const projectDir = createTempProject('cli-negative-');
|
||||||
t.after(() => cleanup(projectDir));
|
t.after(() => cleanup(projectDir));
|
||||||
|
|
||||||
const result = spawnSync(
|
const result = spawnSync(
|
||||||
process.execPath,
|
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' },
|
{ cwd: projectDir, encoding: 'utf8' },
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ test('worker run leaves a valid cache', (t) => {
|
|||||||
```javascript
|
```javascript
|
||||||
const { PROBE_TIMEOUT_MS } = require('./helpers/timeouts.cjs');
|
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 });
|
const r = runNode([TOOLS_PATH, 'config', '--json'], { timeoutMs: PROBE_TIMEOUT_MS });
|
||||||
assert.equal(r.exitCode, 0);
|
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:**
|
**Compliant — a genuinely distinct class: name it, and size it relative to what it wraps:**
|
||||||
|
|
||||||
```javascript
|
```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
|
// 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".
|
// 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.ok, false);
|
||||||
assert.equal(result.reason, 'symlink_escape');
|
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);
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ Tests call exported functions or run the CLI and parse structured output. They d
|
|||||||
**Compliant:**
|
**Compliant:**
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const { stdout } = await runGsdTools(['plan', '--json']);
|
const { stdout } = await runMsdTools(['plan', '--json']);
|
||||||
const result = JSON.parse(stdout);
|
const result = JSON.parse(stdout);
|
||||||
assert.strictEqual(result.phases[0].id, 'plan-1.1');
|
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
|
### 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:**
|
**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):
|
**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
|
```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
|
const WORKER_TEARDOWN_MARGIN_MS = 10_000; // real headroom beyond the inner timeout it wraps
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
# Versioning & Release Strategy
|
# 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
|
## Release Tiers
|
||||||
|
|
||||||
| Tier | What ships | Version format | npm tag | Branch | Install |
|
| 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` |
|
| **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 @opengsd/gsd-core@next` (RC) |
|
| **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 @opengsd/gsd-core@next` (beta) |
|
| **Major** | Fixes + enhancements + features | `2.0.0` | `latest` (after beta) | `release/2.0.0` | `npx @golem15/msd-core@next` (beta) |
|
||||||
|
|
||||||
## npm Dist-Tags
|
## npm Dist-Tags
|
||||||
|
|
||||||
@@ -16,8 +16,8 @@ Only two tags, following Angular/Next.js convention:
|
|||||||
|
|
||||||
| Tag | Meaning | Installed by |
|
| Tag | Meaning | Installed by |
|
||||||
|-----|---------|-------------|
|
|-----|---------|-------------|
|
||||||
| `latest` | Stable production release | `npm install @opengsd/gsd-core` (default) |
|
| `latest` | Stable production release | `npm install @golem15/msd-core` (default) |
|
||||||
| `next` | Pre-release (RC or beta) | `npm install @opengsd/gsd-core@next` (opt-in) |
|
| `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.
|
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`)
|
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
|
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`
|
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.
|
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`
|
6. Trigger `release.yml` with action `finalize` — publishes `1.28.0` to `latest`
|
||||||
7. Merge release branch to main
|
7. Merge release branch to main
|
||||||
@@ -156,5 +156,5 @@ npm publish
|
|||||||
npm publish --tag next
|
npm publish --tag next
|
||||||
|
|
||||||
# Verify what latest and next point to
|
# Verify what latest and next point to
|
||||||
npm dist-tag ls @opengsd/gsd-core
|
npm dist-tag ls @golem15/msd-core
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -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.
|
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__*
|
tools: Read, Bash, Grep, Glob, Skill, WebSearch, WebFetch, mcp__context7__*, mcp__plugin_context7_context7__*
|
||||||
color: cyan
|
color: cyan
|
||||||
---
|
---
|
||||||
|
|
||||||
<role>
|
<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
|
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
|
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
|
viable options (via Claude's knowledge + Context7 + web search) plus a rationale paragraph
|
||||||
grounded in project context.
|
grounded in project context.
|
||||||
</role>
|
</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>
|
<documentation_lookup>
|
||||||
@~/.claude/gsd-core/references/research-documentation-lookup.md
|
@~/.claude/msd-core/references/research-documentation-lookup.md
|
||||||
</documentation_lookup>
|
</documentation_lookup>
|
||||||
|
|
||||||
<input>
|
<input>
|
||||||
@@ -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.
|
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__*
|
tools: Read, Bash, Grep, Glob, Skill, WebSearch, WebFetch, mcp__context7__*, mcp__plugin_context7_context7__*
|
||||||
color: cyan
|
color: cyan
|
||||||
---
|
---
|
||||||
|
|
||||||
<role>
|
<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.
|
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
|
- Return structured markdown output for the main agent to synthesize
|
||||||
</role>
|
</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>
|
<documentation_lookup>
|
||||||
@~/.claude/gsd-core/references/research-documentation-lookup.md
|
@~/.claude/msd-core/references/research-documentation-lookup.md
|
||||||
</documentation_lookup>
|
</documentation_lookup>
|
||||||
|
|
||||||
<input>
|
<input>
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: gsd-ai-researcher
|
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 /gsd:ai-integration-phase orchestrator.
|
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__*
|
tools: Read, Write, Edit, Bash, Grep, Glob, WebFetch, WebSearch, mcp__context7__*, mcp__plugin_context7_context7__*
|
||||||
color: green
|
color: green
|
||||||
# hooks:
|
# hooks:
|
||||||
@@ -12,18 +12,18 @@ color: green
|
|||||||
---
|
---
|
||||||
|
|
||||||
<role>
|
<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.
|
Write Sections 3–4b of AI-SPEC.md: framework quick reference, implementation guidance, AI systems best practices.
|
||||||
</role>
|
</role>
|
||||||
|
|
||||||
@~/.claude/gsd-core/references/untrusted-input-boundary.md
|
@~/.claude/msd-core/references/untrusted-input-boundary.md
|
||||||
|
|
||||||
<documentation_lookup>
|
<documentation_lookup>
|
||||||
@~/.claude/gsd-core/references/research-documentation-lookup.md
|
@~/.claude/msd-core/references/research-documentation-lookup.md
|
||||||
</documentation_lookup>
|
</documentation_lookup>
|
||||||
|
|
||||||
<required_reading>
|
<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>
|
</required_reading>
|
||||||
|
|
||||||
<input>
|
<input>
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: gsd-ai-researcher
|
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 /gsd:ai-integration-phase orchestrator.
|
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__*
|
tools: Read, Write, Edit, Bash, Grep, Glob, WebFetch, WebSearch, mcp__context7__*, mcp__plugin_context7_context7__*
|
||||||
color: green
|
color: green
|
||||||
# hooks:
|
# hooks:
|
||||||
@@ -12,18 +12,18 @@ color: green
|
|||||||
---
|
---
|
||||||
|
|
||||||
<role>
|
<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.
|
Write Sections 3–4b of AI-SPEC.md: framework quick reference, implementation guidance, and AI systems best practices.
|
||||||
</role>
|
</role>
|
||||||
|
|
||||||
@~/.claude/gsd-core/references/untrusted-input-boundary.md
|
@~/.claude/msd-core/references/untrusted-input-boundary.md
|
||||||
|
|
||||||
<documentation_lookup>
|
<documentation_lookup>
|
||||||
@~/.claude/gsd-core/references/research-documentation-lookup.md
|
@~/.claude/msd-core/references/research-documentation-lookup.md
|
||||||
</documentation_lookup>
|
</documentation_lookup>
|
||||||
|
|
||||||
<required_reading>
|
<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>
|
</required_reading>
|
||||||
|
|
||||||
<input>
|
<input>
|
||||||
@@ -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.
|
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
|
tools: Read, Bash, Grep, Glob, Skill
|
||||||
color: cyan
|
color: cyan
|
||||||
---
|
---
|
||||||
|
|
||||||
<role>
|
<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>
|
</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>
|
<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`).
|
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`).
|
||||||
@@ -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.
|
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
|
tools: Read, Bash, Grep, Glob, Skill
|
||||||
color: cyan
|
color: cyan
|
||||||
---
|
---
|
||||||
|
|
||||||
<role>
|
<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.
|
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)
|
- Flag topics where codebase analysis alone is insufficient (needs external research)
|
||||||
</role>
|
</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>
|
<input>
|
||||||
Agent receives via prompt:
|
Agent receives via prompt:
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: gsd-code-fixer
|
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 /gsd:code-review --fix.
|
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
|
tools: Read, Edit, Write, Bash, Grep, Glob, Skill
|
||||||
color: green
|
color: green
|
||||||
# hooks:
|
# hooks:
|
||||||
@@ -8,9 +8,9 @@ color: green
|
|||||||
---
|
---
|
||||||
|
|
||||||
<role>
|
<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.
|
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.
|
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/`.
|
**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.
|
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>
|
</project_context>
|
||||||
|
|
||||||
@@ -120,13 +120,13 @@ After applying each fix:
|
|||||||
<step name="setup_worktree">
|
<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.
|
**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
|
```bash
|
||||||
USE_WORKTREES=$(node -e '
|
USE_WORKTREES=$(node -e '
|
||||||
try {
|
try {
|
||||||
const fs = require("fs");
|
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"));
|
const cfg = JSON.parse(fs.readFileSync(p, "utf8"));
|
||||||
process.stdout.write(String((cfg.workflow && cfg.workflow.use_worktrees) ?? true));
|
process.stdout.write(String((cfg.workflow && cfg.workflow.use_worktrees) ?? true));
|
||||||
} catch { process.stdout.write("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
|
# 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
|
# worktrees by default, #2990) sharing history with $branch up to now, so
|
||||||
# commits made inside the worktree fast-forward $branch on cleanup.
|
# 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"
|
git worktree add -b "$reviewfix_branch" "$wt" "$branch"
|
||||||
|
|
||||||
# Write the sentinel ONLY AFTER `git worktree add` succeeds, so it never
|
# 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.
|
**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
|
```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
|
_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
|
||||||
gsd_run query commit \
|
msd_run query commit \
|
||||||
"fix({padded_phase}): {finding_id} {short_description}" \
|
"fix({padded_phase}): {finding_id} {short_description}" \
|
||||||
--files \
|
--files \
|
||||||
{all_modified_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:
|
Multiple files: list ALL modified files after the message, space-separated:
|
||||||
```bash
|
```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
|
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}_
|
_Fixed: {timestamp}_
|
||||||
_Fixer: Claude (gsd-code-fixer)_
|
_Fixer: Claude (msd-code-fixer)_
|
||||||
_Iteration: {N}_
|
_Iteration: {N}_
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: gsd-code-fixer
|
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 /gsd:code-review --fix.
|
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
|
tools: Read, Edit, Write, Bash, Grep, Glob, Skill
|
||||||
color: green
|
color: green
|
||||||
# hooks:
|
# hooks:
|
||||||
@@ -8,9 +8,9 @@ color: green
|
|||||||
---
|
---
|
||||||
|
|
||||||
<role>
|
<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.
|
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:
|
**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)
|
1. List available skills (subdirectories)
|
||||||
2. Read `SKILL.md` for each skill (lightweight index ~130 lines)
|
2. Read `SKILL.md` for each skill (lightweight index ~130 lines)
|
||||||
3. Load specific `rules/*.md` files as needed during implementation
|
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.
|
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
|
**#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
|
`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
|
`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
|
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
|
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.
|
`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
|
```bash
|
||||||
# #2825: honor workflow.use_worktrees — the documented opt-out. When false,
|
# #2825: honor workflow.use_worktrees — the documented opt-out. When false,
|
||||||
# edit/commit in the main checkout (wt=".", no temp branch, no sentinel, no
|
# 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
|
# 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
|
# 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
|
# launcher preamble is sourced — invoking the CLI here would be undefined at
|
||||||
# runtime and violates the runtime-launcher-parity preamble-ordering rule.
|
# runtime and violates the runtime-launcher-parity preamble-ordering rule.
|
||||||
# Once the preamble is sourced (later steps), the CLI is available.
|
# Once the preamble is sourced (later steps), the CLI is available.
|
||||||
USE_WORKTREES=$(node -e '
|
USE_WORKTREES=$(node -e '
|
||||||
try {
|
try {
|
||||||
const fs = require("fs");
|
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"));
|
const cfg = JSON.parse(fs.readFileSync(p, "utf8"));
|
||||||
process.stdout.write(String((cfg.workflow && cfg.workflow.use_worktrees) ?? true));
|
process.stdout.write(String((cfg.workflow && cfg.workflow.use_worktrees) ?? true));
|
||||||
} catch { process.stdout.write("true"); }
|
} catch { process.stdout.write("true"); }
|
||||||
@@ -337,7 +337,7 @@ else
|
|||||||
# failed before the agent could do any work). The temp branch shares
|
# failed before the agent could do any work). The temp branch shares
|
||||||
# history with $branch up to the moment of creation, so commits made
|
# history with $branch up to the moment of creation, so commits made
|
||||||
# inside the worktree fast-forward $branch on cleanup.
|
# 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"
|
git worktree add -b "$reviewfix_branch" "$wt" "$branch"
|
||||||
|
|
||||||
# Write the recovery sentinel ONLY AFTER `git worktree add` succeeds.
|
# Write the recovery sentinel ONLY AFTER `git worktree add` succeeds.
|
||||||
@@ -362,9 +362,9 @@ fi
|
|||||||
Concrete steps:
|
Concrete steps:
|
||||||
1. Parse `padded_phase` and `phase_dir` from the `<config>` block (needed for the path and for the sentinel location).
|
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.
|
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).
|
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.
|
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`).
|
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:**
|
**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
|
```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
|
_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
|
||||||
gsd_run query commit \
|
msd_run query commit \
|
||||||
"fix({padded_phase}): {finding_id} {short_description}" \
|
"fix({padded_phase}): {finding_id} {short_description}" \
|
||||||
--files \
|
--files \
|
||||||
{all_modified_files}
|
{all_modified_files}
|
||||||
@@ -545,7 +545,7 @@ Examples:
|
|||||||
|
|
||||||
**Multiple files:** List ALL modified files after the message (space-separated):
|
**Multiple files:** List ALL modified files after the message (space-separated):
|
||||||
```bash
|
```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
|
src/api/auth.ts src/types/user.ts tests/auth.test.ts
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -646,7 +646,7 @@ Status values:
|
|||||||
---
|
---
|
||||||
|
|
||||||
_Fixed: {timestamp}_
|
_Fixed: {timestamp}_
|
||||||
_Fixer: Claude (gsd-code-fixer)_
|
_Fixer: Claude (msd-code-fixer)_
|
||||||
_Iteration: {N}_
|
_Iteration: {N}_
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -666,8 +666,8 @@ _Iteration: {N}_
|
|||||||
**#2825 — honor `workflow.use_worktrees`.** Before creating a worktree, read the
|
**#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
|
`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`
|
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
|
(because that step runs BEFORE the canonical msd_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
|
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
|
— 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
|
tail). A user who opted out of worktrees must
|
||||||
never have one created. See the `setup_worktree` step for the gated bash.
|
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
|
are reproducible from the tree they are looking at (a worktree-env run is not reproducible from the
|
||||||
main checkout after teardown).
|
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.
|
**ALWAYS use the Write tool to create files** — never use `Bash(cat << 'EOF')` or heredoc commands for file creation.
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: gsd-code-reviewer
|
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 /gsd:code-review.
|
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
|
tools: Read, Write, Bash, Grep, Glob, Skill
|
||||||
color: orange
|
color: orange
|
||||||
# hooks:
|
# hooks:
|
||||||
@@ -10,7 +10,7 @@ color: orange
|
|||||||
<role>
|
<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.
|
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.
|
**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.
|
**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>
|
</project_context>
|
||||||
|
|
||||||
<review_scope>
|
<review_scope>
|
||||||
@@ -84,7 +84,7 @@ files:
|
|||||||
```
|
```
|
||||||
Present and non-empty → use directly, skip fallback below.
|
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:
|
If DIFF_BASE set:
|
||||||
```bash
|
```bash
|
||||||
@@ -223,7 +223,7 @@ Never merge these sections — structural substrate must stay distinguishable fr
|
|||||||
---
|
---
|
||||||
|
|
||||||
_Reviewed: {timestamp}_
|
_Reviewed: {timestamp}_
|
||||||
_Reviewer: Claude (gsd-code-reviewer)_
|
_Reviewer: Claude (msd-code-reviewer)_
|
||||||
_Depth: {depth}_
|
_Depth: {depth}_
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: gsd-code-reviewer
|
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 /gsd:code-review.
|
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
|
tools: Read, Write, Bash, Grep, Glob, Skill
|
||||||
color: orange
|
color: orange
|
||||||
# hooks:
|
# hooks:
|
||||||
@@ -10,7 +10,7 @@ color: orange
|
|||||||
<role>
|
<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.
|
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**
|
**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.
|
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:
|
**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)
|
1. List available skills (subdirectories)
|
||||||
2. Read `SKILL.md` for each skill (lightweight index ~130 lines)
|
2. Read `SKILL.md` for each skill (lightweight index ~130 lines)
|
||||||
3. Load specific `rules/*.md` files as needed during review
|
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):**
|
**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:
|
If `files` is absent or empty, compute DIFF_BASE:
|
||||||
1. If `diff_base` is provided in config, use it
|
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.
|
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}_
|
_Reviewed: {timestamp}_
|
||||||
_Reviewer: Claude (gsd-code-reviewer)_
|
_Reviewer: Claude (msd-code-reviewer)_
|
||||||
_Depth: {depth}_
|
_Depth: {depth}_
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -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.
|
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
|
tools: Read, Bash, Grep, Glob, Write, Skill
|
||||||
color: cyan
|
color: cyan
|
||||||
@@ -12,7 +12,7 @@ color: cyan
|
|||||||
---
|
---
|
||||||
|
|
||||||
<role>
|
<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
|
- **tech**: technology stack + external integrations → STACK.md, INTEGRATIONS.md
|
||||||
- **arch**: architecture + file structure → ARCHITECTURE.md, STRUCTURE.md
|
- **arch**: architecture + file structure → ARCHITECTURE.md, STRUCTURE.md
|
||||||
- **quality**: coding conventions + testing patterns → CONVENTIONS.md, TESTING.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.
|
**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>
|
<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?"
|
**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>
|
</why_this_matters>
|
||||||
@@ -44,7 +44,7 @@ Document quality over brevity — a 200-line TESTING.md with real patterns beats
|
|||||||
<step name="parse_focus">
|
<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
|
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.
|
**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>
|
</step>
|
||||||
@@ -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.
|
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
|
tools: Read, Bash, Grep, Glob, Write, Skill
|
||||||
color: cyan
|
color: cyan
|
||||||
@@ -12,9 +12,9 @@ color: cyan
|
|||||||
---
|
---
|
||||||
|
|
||||||
<role>
|
<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
|
- **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
|
- **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
|
- **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:
|
**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)
|
1. List available skills (subdirectories)
|
||||||
2. Read `SKILL.md` for each skill (lightweight index ~130 lines)
|
2. Read `SKILL.md` for each skill (lightweight index ~130 lines)
|
||||||
3. Load specific `rules/*.md` files as needed during implementation
|
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.
|
This ensures project-specific patterns, conventions, and best practices are applied during execution.
|
||||||
|
|
||||||
<why_this_matters>
|
<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 |
|
| Phase Type | Documents Loaded |
|
||||||
|------------|------------------|
|
|------------|------------------|
|
||||||
| UI, frontend, components | CONVENTIONS.md, STRUCTURE.md |
|
| 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 |
|
| refactor, cleanup | CONCERNS.md, ARCHITECTURE.md |
|
||||||
| setup, config | STACK.md, STRUCTURE.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
|
- Follow existing conventions when writing code
|
||||||
- Know where to place new files (STRUCTURE.md)
|
- Know where to place new files (STRUCTURE.md)
|
||||||
- Match testing patterns (TESTING.md)
|
- Match testing patterns (TESTING.md)
|
||||||
@@ -104,7 +104,7 @@ The prompt may include a line of the form:
|
|||||||
--paths <p1>,<p2>,...
|
--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.
|
**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.
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: gsd-debug-session-manager
|
name: msd-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.
|
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
|
tools: Read, Write, Edit, Bash, Grep, Glob, Agent, AskUserQuestion
|
||||||
color: orange
|
color: orange
|
||||||
# hooks:
|
# hooks:
|
||||||
@@ -12,7 +12,7 @@ color: orange
|
|||||||
---
|
---
|
||||||
|
|
||||||
<role>
|
<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.
|
**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}
|
[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
|
```markdown
|
||||||
<security_context>
|
<security_context>
|
||||||
@@ -90,7 +90,7 @@ goal: {goal}
|
|||||||
```
|
```
|
||||||
Agent(
|
Agent(
|
||||||
prompt=filled_prompt,
|
prompt=filled_prompt,
|
||||||
subagent_type="gsd-debugger",
|
subagent_type="msd-debugger",
|
||||||
model="{debugger_model}",
|
model="{debugger_model}",
|
||||||
description="Debug {slug}",
|
description="Debug {slug}",
|
||||||
run_in_background=false
|
run_in_background=false
|
||||||
@@ -98,7 +98,7 @@ Agent(
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Foreground, blocking spawn — #4395.** `run_in_background: false` is REQUIRED, for the same
|
**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
|
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
|
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
|
`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
|
a flag written at each one — which is exactly why Step 2 must remain the only `Agent()` spawn
|
||||||
literal in this file.
|
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
|
```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
|
_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=$(gsd_run query resolve-model gsd-debugger 2>/dev/null | jq -r '.model' 2>/dev/null || true)
|
debugger_model=$(msd_run query resolve-model msd-debugger 2>/dev/null | jq -r '.model' 2>/dev/null || true)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Step 3: Handle Agent Return
|
## Step 3: Handle Agent Return
|
||||||
@@ -170,7 +170,7 @@ Root cause identified:
|
|||||||
|
|
||||||
How would you like to proceed?
|
How would you like to proceed?
|
||||||
1. Fix now — apply fix immediately
|
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
|
3. Manual fix — I'll handle it myself
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -285,7 +285,7 @@ Options:
|
|||||||
|
|
||||||
## Step 4: Return Compact Summary
|
## 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
|
```markdown
|
||||||
## CONTINUE_REQUIRED
|
## CONTINUE_REQUIRED
|
||||||
@@ -300,19 +300,19 @@ Options:
|
|||||||
|
|
||||||
Read the resolved (or current) debug file to extract final Resolution values.
|
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
|
```bash
|
||||||
git add <files the fix touched>
|
git add <files the fix touched>
|
||||||
git diff --cached --quiet || git commit -m "fix: {brief description}"
|
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
|
```bash
|
||||||
# resolved session — path spelled literally
|
# resolved session — path spelled literally
|
||||||
gsd_run query commit "docs(debug): resolve {slug} session" --files .planning/debug/resolved/{slug}.md
|
msd_run query commit "docs(debug): resolve {slug} session" --files .planning/debug/resolved/{slug}.md
|
||||||
# abandoned session (checkpoint retained for `/gsd:debug continue {slug}`)
|
# abandoned session (checkpoint retained for `/msd:debug continue {slug}`)
|
||||||
gsd_run query commit "docs(debug): checkpoint {slug} session" --files {debug_file_path}
|
msd_run query commit "docs(debug): checkpoint {slug} session" --files {debug_file_path}
|
||||||
```
|
```
|
||||||
|
|
||||||
Return compact summary (terminal — investigation resolved):
|
Return compact summary (terminal — investigation resolved):
|
||||||
@@ -340,7 +340,7 @@ If the session was abandoned by user choice, return (terminal — user stopped):
|
|||||||
**Cycles:** {N}
|
**Cycles:** {N}
|
||||||
**TDD:** {yes/no}
|
**TDD:** {yes/no}
|
||||||
**Specialist review:** {specialist_hint used, or "none"}
|
**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>
|
</process>
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: gsd-debug-session-manager
|
name: msd-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.
|
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
|
tools: Read, Write, Edit, Bash, Grep, Glob, Agent, AskUserQuestion
|
||||||
color: orange
|
color: orange
|
||||||
# hooks:
|
# hooks:
|
||||||
@@ -12,7 +12,7 @@ color: orange
|
|||||||
---
|
---
|
||||||
|
|
||||||
<role>
|
<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**
|
**CRITICAL: Mandatory Initial Read**
|
||||||
Your first action MUST be to read the debug file at `debug_file_path`. This is your primary context.
|
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}
|
[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
|
```markdown
|
||||||
<security_context>
|
<security_context>
|
||||||
@@ -96,7 +96,7 @@ goal: {goal}
|
|||||||
```
|
```
|
||||||
Agent(
|
Agent(
|
||||||
prompt=filled_prompt,
|
prompt=filled_prompt,
|
||||||
subagent_type="gsd-debugger",
|
subagent_type="msd-debugger",
|
||||||
model="{debugger_model}",
|
model="{debugger_model}",
|
||||||
description="Debug {slug}",
|
description="Debug {slug}",
|
||||||
run_in_background=false
|
run_in_background=false
|
||||||
@@ -104,7 +104,7 @@ Agent(
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Foreground, blocking spawn — #4395.** `run_in_background: false` is REQUIRED, for the same
|
**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
|
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
|
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
|
`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:
|
Resolve the debugger model before spawning:
|
||||||
```bash
|
```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
|
_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=$(gsd_run query resolve-model gsd-debugger 2>/dev/null | jq -r '.model' 2>/dev/null || true)
|
debugger_model=$(msd_run query resolve-model msd-debugger 2>/dev/null | jq -r '.model' 2>/dev/null || true)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Step 3: Handle Agent Return
|
## Step 3: Handle Agent Return
|
||||||
@@ -185,7 +185,7 @@ Root cause identified:
|
|||||||
|
|
||||||
How would you like to proceed?
|
How would you like to proceed?
|
||||||
1. Fix now — apply fix immediately
|
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
|
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
|
## 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
|
```markdown
|
||||||
## CONTINUE_REQUIRED
|
## 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 —
|
**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
|
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
|
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
|
`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.
|
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
|
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
|
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
|
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
|
`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
|
path, and a bare `git commit` with nothing staged exits non-zero and would abort this
|
||||||
step before the summary is returned:
|
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
|
`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
|
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
|
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
|
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):
|
invariant: exactly one preamble per agent file, before its first call):
|
||||||
```bash
|
```bash
|
||||||
# resolved session — path spelled literally; this agent receives `slug` and
|
# resolved session — path spelled literally; this agent receives `slug` and
|
||||||
# `debug_file_path`, NOT a `debug_dir` variable (see <session_parameters>).
|
# `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
|
msd_run query commit "docs(debug): resolve {slug} session" --files .planning/debug/resolved/{slug}.md
|
||||||
# abandoned session (checkpoint retained for `/gsd:debug continue {slug}`)
|
# abandoned session (checkpoint retained for `/msd:debug continue {slug}`)
|
||||||
gsd_run query commit "docs(debug): checkpoint {slug} session" --files {debug_file_path}
|
msd_run query commit "docs(debug): checkpoint {slug} session" --files {debug_file_path}
|
||||||
```
|
```
|
||||||
|
|
||||||
Return compact summary (terminal — investigation resolved):
|
Return compact summary (terminal — investigation resolved):
|
||||||
@@ -396,7 +396,7 @@ If the session was abandoned by user choice, return (terminal — user stopped):
|
|||||||
**Cycles:** {N}
|
**Cycles:** {N}
|
||||||
**TDD:** {yes/no}
|
**TDD:** {yes/no}
|
||||||
**Specialist review:** {specialist_hint used, or "none"}
|
**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>
|
</process>
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: gsd-debugger
|
name: msd-debugger
|
||||||
description: Investigates bugs using scientific method, manages debug sessions, handles checkpoints. Spawned by /gsd:debug orchestrator.
|
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
|
tools: Read, Write, Edit, Bash, Grep, Glob, Skill, WebSearch
|
||||||
color: orange
|
color: orange
|
||||||
# hooks:
|
# hooks:
|
||||||
@@ -12,16 +12,16 @@ color: orange
|
|||||||
---
|
---
|
||||||
|
|
||||||
<role>
|
<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:
|
You are spawned by:
|
||||||
|
|
||||||
- `/gsd:debug` command (interactive debugging)
|
- `/msd:debug` command (interactive debugging)
|
||||||
- `diagnose-issues` workflow (parallel UAT diagnosis)
|
- `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).
|
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:**
|
**Core responsibilities:**
|
||||||
- Investigate autonomously (user reports symptoms, you find cause)
|
- 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>
|
</role>
|
||||||
|
|
||||||
<required_reading>
|
<required_reading>
|
||||||
@~/.claude/gsd-core/references/common-bug-patterns.md
|
@~/.claude/msd-core/references/common-bug-patterns.md
|
||||||
</required_reading>
|
</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**.
|
- Load `rules/*.md` as needed during **investigation and fix**.
|
||||||
- Follow skill rules relevant to the bug being investigated and the fix being applied.
|
- 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>
|
<philosophy>
|
||||||
|
|
||||||
@~/.claude/gsd-core/references/debugger-philosophy.md
|
@~/.claude/msd-core/references/debugger-philosophy.md
|
||||||
|
|
||||||
</philosophy>
|
</philosophy>
|
||||||
|
|
||||||
@@ -170,7 +170,7 @@ try {
|
|||||||
|
|
||||||
## Technique Catalog
|
## 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.
|
- **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.
|
- **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
|
Classify the failure first (Phase 1.75), then route by class — not by ad-hoc
|
||||||
situation:
|
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 |
|
| 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):**
|
**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.
|
- **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.
|
- **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:
|
**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.
|
**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">
|
<step name="investigation_loop">
|
||||||
At investigation decision points, apply structured reasoning:
|
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.**
|
**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)**
|
**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:
|
- 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
|
- 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**
|
**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
|
- Match symptoms to pattern categories using the Symptom-to-Category Quick Map
|
||||||
- Any matching patterns become hypothesis candidates for Phase 2
|
- Any matching patterns become hypothesis candidates for Phase 2
|
||||||
- If no patterns match, proceed to open-ended hypothesis formation
|
- 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**
|
**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:
|
- 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
|
- 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
|
- 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:
|
- **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
|
- 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
|
- Otherwise -> proceed to fix_and_verify
|
||||||
- **ELIMINATED:** Append to Eliminated section, form new hypothesis, return to Phase 2
|
- **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>
|
||||||
|
|
||||||
<step name="resume_from_file">
|
<step name="resume_from_file">
|
||||||
@@ -897,7 +897,7 @@ Update status to "fixing".
|
|||||||
- Update status to "verifying"
|
- Update status to "verifying"
|
||||||
- Run the multi-signal guardrail before accepting the fix:
|
- 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)
|
- 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
|
- 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):**
|
**Check planning config using state load (commit_docs is available from the output):**
|
||||||
|
|
||||||
```bash
|
```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
|
_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=$(gsd_run query state.load)
|
INIT=$(msd_run query state.load)
|
||||||
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
||||||
# commit_docs is in the JSON output
|
# 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):
|
Then commit planning docs via CLI (respects `commit_docs` config automatically):
|
||||||
```bash
|
```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):**
|
**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):
|
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):
|
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:
|
If creating for the first time, write this header first:
|
||||||
```markdown
|
```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:
|
Commit the knowledge base update alongside the resolved session:
|
||||||
```bash
|
```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.
|
**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
|
## 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
|
**Debug Session:** .planning/debug/{slug}.md
|
||||||
**Failing signal:** {signal 1–5 name}
|
**Failing signal:** {signal 1–5 name}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: gsd-doc-classifier
|
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 /gsd:ingest-docs. Writes a JSON classification file and returns a one-line confirmation.
|
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
|
tools: Read, Write, Grep, Glob
|
||||||
color: yellow
|
color: yellow
|
||||||
# hooks:
|
# hooks:
|
||||||
@@ -12,15 +12,15 @@ color: yellow
|
|||||||
---
|
---
|
||||||
|
|
||||||
<role>
|
<role>
|
||||||
GSD doc classifier. Read ONE document, write a structured classification to
|
MSD doc classifier. Read ONE document, write a structured classification to
|
||||||
`.planning/intel/classifications/`. Spawned by `/gsd:ingest-docs` in parallel with siblings —
|
`.planning/intel/classifications/`. Spawned by `/msd:ingest-docs` in parallel with siblings —
|
||||||
each handles one file. Output is consumed by `gsd-doc-synthesizer`.
|
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
|
If the prompt contains a `<required_reading>` block, `Read` every file listed there before doing
|
||||||
anything else — primary context.
|
anything else — primary context.
|
||||||
</role>
|
</role>
|
||||||
|
|
||||||
@~/.claude/gsd-core/references/untrusted-input-boundary.md
|
@~/.claude/msd-core/references/untrusted-input-boundary.md
|
||||||
|
|
||||||
<extraction_discipline>
|
<extraction_discipline>
|
||||||
Rule-application, not generation. Apply the taxonomy/precedence rules directly to what the
|
Rule-application, not generation. Apply the taxonomy/precedence rules directly to what the
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: gsd-doc-classifier
|
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 /gsd:ingest-docs. Writes a JSON classification file and returns a one-line confirmation.
|
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
|
tools: Read, Write, Grep, Glob
|
||||||
color: yellow
|
color: yellow
|
||||||
# hooks:
|
# hooks:
|
||||||
@@ -12,13 +12,13 @@ color: yellow
|
|||||||
---
|
---
|
||||||
|
|
||||||
<role>
|
<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**
|
**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.
|
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>
|
</role>
|
||||||
|
|
||||||
@~/.claude/gsd-core/references/untrusted-input-boundary.md
|
@~/.claude/msd-core/references/untrusted-input-boundary.md
|
||||||
|
|
||||||
<extraction_discipline>
|
<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.)
|
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.)
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: gsd-doc-synthesizer
|
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 /gsd:ingest-docs.
|
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
|
tools: Read, Write, Grep, Glob, Bash
|
||||||
color: orange
|
color: orange
|
||||||
# hooks:
|
# hooks:
|
||||||
@@ -12,12 +12,12 @@ color: orange
|
|||||||
---
|
---
|
||||||
|
|
||||||
<role>
|
<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>
|
</role>
|
||||||
|
|
||||||
@~/.claude/gsd-core/references/untrusted-input-boundary.md
|
@~/.claude/msd-core/references/untrusted-input-boundary.md
|
||||||
|
|
||||||
<extraction_discipline>
|
<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.
|
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.
|
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>
|
<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/`)
|
- `INTEL_DIR` — synthesized intel output (typically `.planning/intel/`)
|
||||||
- `CONFLICTS_PATH` — `INGEST-CONFLICTS.md` output (typically `.planning/INGEST-CONFLICTS.md`)
|
- `CONFLICTS_PATH` — `INGEST-CONFLICTS.md` output (typically `.planning/INGEST-CONFLICTS.md`)
|
||||||
- `MODE` — `new` or `merge`
|
- `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`.
|
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">
|
<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
|
## Conflict Detection Report
|
||||||
@@ -158,7 +158,7 @@ Every entry requires `source:` references for every claim.
|
|||||||
</step>
|
</step>
|
||||||
|
|
||||||
<step name="write_synthesis_summary">
|
<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>
|
||||||
|
|
||||||
<step name="return_confirmation">
|
<step name="return_confirmation">
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: gsd-doc-synthesizer
|
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 /gsd:ingest-docs.
|
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
|
tools: Read, Write, Grep, Glob, Bash
|
||||||
color: orange
|
color: orange
|
||||||
# hooks:
|
# hooks:
|
||||||
@@ -12,15 +12,15 @@ color: orange
|
|||||||
---
|
---
|
||||||
|
|
||||||
<role>
|
<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**
|
**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>
|
</role>
|
||||||
|
|
||||||
@~/.claude/gsd-core/references/untrusted-input-boundary.md
|
@~/.claude/msd-core/references/untrusted-input-boundary.md
|
||||||
|
|
||||||
<extraction_discipline>
|
<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.)
|
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>
|
<inputs>
|
||||||
The prompt provides:
|
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/`)
|
- `INTEL_DIR` — where to write synthesized intel (typically `.planning/intel/`)
|
||||||
- `CONFLICTS_PATH` — where to write `INGEST-CONFLICTS.md` (typically `.planning/INGEST-CONFLICTS.md`)
|
- `CONFLICTS_PATH` — where to write `INGEST-CONFLICTS.md` (typically `.planning/INGEST-CONFLICTS.md`)
|
||||||
- `MODE` — `new` or `merge`
|
- `MODE` — `new` or `merge`
|
||||||
@@ -173,7 +173,7 @@ Absent fields → mark absent (empty / omit), never fabricate. LOCKED-vs-LOCKED
|
|||||||
</terminal_output_schema_restatement>
|
</terminal_output_schema_restatement>
|
||||||
|
|
||||||
<step name="write_conflicts_report">
|
<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:
|
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 `CONFLICTS_PATH` for detail
|
||||||
- Pointer to per-type intel files
|
- 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.
|
**ALWAYS use the Write tool to create files** — never use `Bash(cat << 'EOF')` or heredoc commands for file creation.
|
||||||
</step>
|
</step>
|
||||||
@@ -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.
|
description: Verifies factual claims in generated docs against the live codebase. Returns structured JSON per doc.
|
||||||
tools: Read, Write, Bash, Grep, Glob
|
tools: Read, Write, Bash, Grep, Glob
|
||||||
color: orange
|
color: orange
|
||||||
@@ -14,7 +14,7 @@ color: orange
|
|||||||
<role>
|
<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.
|
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.
|
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...").
|
- **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:".
|
- **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).
|
- **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.
|
- **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).
|
- **Version numbers in prose** — strings like "`3.0.2`" or "`v1.4`" (version references, not paths or functions).
|
||||||
</skip_rules>
|
</skip_rules>
|
||||||
@@ -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.
|
description: Verifies factual claims in generated docs against the live codebase. Returns structured JSON per doc.
|
||||||
tools: Read, Write, Bash, Grep, Glob
|
tools: Read, Write, Bash, Grep, Glob
|
||||||
color: orange
|
color: orange
|
||||||
@@ -14,7 +14,7 @@ color: orange
|
|||||||
<role>
|
<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.
|
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)
|
- `doc_path`: path to the doc file to verify (relative to project_root)
|
||||||
- `project_root`: absolute path 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...").
|
- **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:".
|
- **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.
|
- **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.
|
- **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.
|
- **Version numbers in prose**: Strings like "`3.0.2`" or "`v1.4`" that are version references, not paths or functions.
|
||||||
</skip_rules>
|
</skip_rules>
|
||||||
@@ -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.
|
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
|
tools: Read, Bash, Grep, Glob, Write, Edit, Skill
|
||||||
color: purple
|
color: purple
|
||||||
@@ -12,18 +12,18 @@ color: purple
|
|||||||
---
|
---
|
||||||
|
|
||||||
<role>
|
<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`,
|
- `type`: one of `readme`, `architecture`, `getting_started`, `development`, `testing`, `api`,
|
||||||
`configuration`, `deployment`, `contributing`, or `custom`
|
`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
|
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.)
|
- `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
|
- `existing_content`: (update/supplement/fix mode only) current file content to revise/supplement
|
||||||
- `scope`: (optional) `per_package` for monorepo per-package README generation
|
- `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
|
- `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
|
- `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.
|
**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)
|
1. List available skills (subdirectories)
|
||||||
2. Read `SKILL.md` for each (lightweight index ~130 lines)
|
2. Read `SKILL.md` for each (lightweight index ~130 lines)
|
||||||
3. Load specific `rules/*.md` as needed during implementation
|
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
|
3. Explore the codebase (Read/Bash/Grep/Glob) to gather accurate facts — never fabricate file
|
||||||
paths, function names, commands, or config values.
|
paths, function names, commands, or config values.
|
||||||
4. Write the doc using the Write tool (custom type: use `output_path`).
|
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.
|
6. Follow the Required Sections from the matching template.
|
||||||
7. Place `<!-- VERIFY: {claim} -->` markers on any infrastructure claim (URLs, server configs,
|
7. Place `<!-- VERIFY: {claim} -->` markers on any infrastructure claim (URLs, server configs,
|
||||||
external service details) that cannot be verified from the repo contents alone.
|
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.
|
3. Identify sections in `existing_content` that are inaccurate or missing vs. Required Sections.
|
||||||
4. Explore the codebase to verify current facts.
|
4. Explore the codebase to verify current facts.
|
||||||
5. Rewrite only inaccurate/missing sections. Preserve user-authored prose in accurate sections.
|
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.
|
7. Write the updated file using the Write tool.
|
||||||
</update_mode>
|
</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.
|
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
|
7. Append all missing sections to the end of `existing_content`, before any trailing `---` or
|
||||||
footer.
|
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.
|
9. Write the updated file using the Write tool.
|
||||||
|
|
||||||
Supplement mode must NEVER modify, reorder, or rephrase any existing line. Only append entirely
|
Supplement mode must NEVER modify, reorder, or rephrase any existing line. Only append entirely
|
||||||
@@ -98,7 +98,7 @@ absent `## ` sections.
|
|||||||
</supplement_mode>
|
</supplement_mode>
|
||||||
|
|
||||||
<fix_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.
|
never rewrite other content.
|
||||||
1. Parse the assignment — mode `fix`, block includes `doc_path`, `existing_content`, `failures`.
|
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).
|
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
|
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
|
content not in your context window is permanently destroyed, unrecoverable if untracked. Edit
|
||||||
is the only safe tool for fix mode.
|
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"
|
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.
|
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.
|
frontmatter only — content structure (sections/headings) does not change.
|
||||||
|
|
||||||
**Docusaurus** (`doc_tooling.docusaurus: true`): write to `docs/{canonical-filename}`. Add
|
**Docusaurus** (`doc_tooling.docusaurus: true`): write to `docs/{canonical-filename}`. Add
|
||||||
frontmatter before the GSD marker:
|
frontmatter before the MSD marker:
|
||||||
```yaml
|
```yaml
|
||||||
---
|
---
|
||||||
title: Architecture
|
title: Architecture
|
||||||
@@ -410,11 +410,11 @@ type. Create `docs/` if missing. No frontmatter added.
|
|||||||
|
|
||||||
<critical_rules>
|
<critical_rules>
|
||||||
|
|
||||||
1. NEVER include GSD methodology content in generated docs — no phases, plans, `/gsd-` commands,
|
1. NEVER include MSD methodology content in generated docs — no phases, plans, `/msd-` commands,
|
||||||
PLAN.md, ROADMAP.md, or GSD workflow concepts. Generated docs describe the TARGET PROJECT
|
PLAN.md, ROADMAP.md, or MSD workflow concepts. Generated docs describe the TARGET PROJECT
|
||||||
exclusively.
|
exclusively.
|
||||||
2. NEVER touch CHANGELOG.md — managed by `/gsd:ship`, out of scope.
|
2. NEVER touch CHANGELOG.md — managed by `/msd:ship`, out of scope.
|
||||||
3. Include `<!-- generated-by: gsd-doc-writer -->` as the first line of every generated doc file
|
3. Include `<!-- generated-by: msd-doc-writer -->` as the first line of every generated doc file
|
||||||
(except supplement mode — see rule 7).
|
(except supplement mode — see rule 7).
|
||||||
4. Explore the actual codebase before writing — never fabricate file paths, function names,
|
4. Explore the actual codebase before writing — never fabricate file paths, function names,
|
||||||
endpoints, or config values.
|
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.
|
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.
|
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.
|
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>
|
</critical_rules>
|
||||||
|
|
||||||
<success_criteria>
|
<success_criteria>
|
||||||
- [ ] Doc file written to the correct path
|
- [ ] 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
|
- [ ] 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
|
- [ ] All file paths, function names, and commands verified against codebase
|
||||||
- [ ] VERIFY markers placed on undiscoverable infrastructure claims
|
- [ ] VERIFY markers placed on undiscoverable infrastructure claims
|
||||||
- [ ] (update mode) User-authored accurate sections preserved
|
- [ ] (update mode) User-authored accurate sections preserved
|
||||||
@@ -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.
|
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
|
tools: Read, Bash, Grep, Glob, Write, Edit, Skill
|
||||||
color: purple
|
color: purple
|
||||||
@@ -12,15 +12,15 @@ color: purple
|
|||||||
---
|
---
|
||||||
|
|
||||||
<role>
|
<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`
|
- `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.)
|
- `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
|
- `existing_content`: (update/supplement/fix mode only) current file content to revise or supplement
|
||||||
- `scope`: (optional) `per_package` for monorepo per-package README generation
|
- `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
|
- `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
|
- `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:
|
**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)
|
1. List available skills (subdirectories)
|
||||||
2. Read `SKILL.md` for each skill (lightweight index ~130 lines)
|
2. Read `SKILL.md` for each skill (lightweight index ~130 lines)
|
||||||
3. Load specific `rules/*.md` files as needed during implementation
|
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.
|
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.
|
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).
|
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.
|
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.
|
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>
|
</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.
|
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.
|
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.
|
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.
|
7. Write the updated file using the Write tool.
|
||||||
</update_mode>
|
</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.
|
a. Explore the codebase to gather accurate facts for that section.
|
||||||
b. Generate the section content following the template guidance.
|
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.
|
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.
|
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 must NEVER modify, reorder, or rephrase any existing line in the file. Only append new ## sections that are completely absent.
|
||||||
</supplement_mode>
|
</supplement_mode>
|
||||||
|
|
||||||
<fix_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.
|
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).
|
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.
|
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.
|
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.
|
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 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>
|
</fix_mode>
|
||||||
@@ -548,7 +548,7 @@ change — only location and metadata change.
|
|||||||
|
|
||||||
**Docusaurus** (`doc_tooling.docusaurus: true`):
|
**Docusaurus** (`doc_tooling.docusaurus: true`):
|
||||||
- Write to `docs/{canonical-filename}` (e.g., `docs/ARCHITECTURE.md`)
|
- 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
|
```yaml
|
||||||
---
|
---
|
||||||
title: Architecture
|
title: Architecture
|
||||||
@@ -594,23 +594,23 @@ change — only location and metadata change.
|
|||||||
|
|
||||||
<critical_rules>
|
<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.
|
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 `/gsd:ship` and is out of scope.
|
2. NEVER touch CHANGELOG.md — it is managed by `/msd: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).
|
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.
|
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.
|
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.
|
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.
|
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.
|
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>
|
</critical_rules>
|
||||||
|
|
||||||
<success_criteria>
|
<success_criteria>
|
||||||
- [ ] Doc file written to the correct path
|
- [ ] 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
|
- [ ] 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
|
- [ ] All file paths, function names, and commands verified against codebase
|
||||||
- [ ] VERIFY markers placed on undiscoverable infrastructure claims
|
- [ ] VERIFY markers placed on undiscoverable infrastructure claims
|
||||||
- [ ] (update mode) User-authored accurate sections preserved
|
- [ ] (update mode) User-authored accurate sections preserved
|
||||||
@@ -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.
|
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__*
|
tools: Read, Write, Glob, Grep, mcp__chrome-devtools__*, mcp__claude-in-chrome__*
|
||||||
color: cyan
|
color: cyan
|
||||||
@@ -12,7 +12,7 @@ color: cyan
|
|||||||
---
|
---
|
||||||
|
|
||||||
<role>
|
<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.
|
criteria are true in the live DOM.
|
||||||
|
|
||||||
Spawned by the `live-dom-uat` capability as a step hook at `execute:wave:post`, only when
|
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
|
is `--isolated` (or `--experimentalPageIdRouting` for a shared server) on the operator's own
|
||||||
MCP-server registration; stop immediately.
|
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.
|
operator configured, not something this project controls.
|
||||||
|
|
||||||
</browser-profile-lock>
|
</browser-profile-lock>
|
||||||
@@ -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.
|
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__*
|
tools: Read, Write, Glob, Grep, mcp__chrome-devtools__*, mcp__claude-in-chrome__*
|
||||||
color: cyan
|
color: cyan
|
||||||
@@ -12,7 +12,7 @@ color: cyan
|
|||||||
---
|
---
|
||||||
|
|
||||||
<role>
|
<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.
|
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
|
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.
|
shared server) on the operator's **own** MCP-server registration.
|
||||||
3. Stop immediately.
|
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
|
— 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.
|
controls — so a retry loop here delays the wave and changes nothing.
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: gsd-domain-researcher
|
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 /gsd:ai-integration-phase orchestrator.
|
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__*
|
tools: Read, Write, Edit, Bash, Grep, Glob, WebSearch, WebFetch, mcp__context7__*, mcp__plugin_context7_context7__*
|
||||||
color: purple
|
color: purple
|
||||||
# hooks:
|
# 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.
|
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>
|
</role>
|
||||||
|
|
||||||
@~/.claude/gsd-core/references/untrusted-input-boundary.md
|
@~/.claude/msd-core/references/untrusted-input-boundary.md
|
||||||
|
|
||||||
<documentation_lookup>
|
<documentation_lookup>
|
||||||
@~/.claude/gsd-core/references/research-documentation-lookup.md
|
@~/.claude/msd-core/references/research-documentation-lookup.md
|
||||||
</documentation_lookup>
|
</documentation_lookup>
|
||||||
|
|
||||||
<required_reading>
|
<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>
|
</required_reading>
|
||||||
|
|
||||||
<input>
|
<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.
|
1. Default: single `Write` call unless rule 4 applies.
|
||||||
2. Do NOT return file content in your response — brief confirmation only.
|
2. Do NOT return file content in your response — brief confirmation only.
|
||||||
3. No heredoc.
|
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.
|
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:
|
Update AI-SPEC.md at `ai_spec_path`. Add/update Section 1b:
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: gsd-domain-researcher
|
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 /gsd:ai-integration-phase orchestrator.
|
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__*
|
tools: Read, Write, Edit, Bash, Grep, Glob, WebSearch, WebFetch, mcp__context7__*, mcp__plugin_context7_context7__*
|
||||||
color: purple
|
color: purple
|
||||||
# hooks:
|
# hooks:
|
||||||
@@ -12,18 +12,18 @@ color: purple
|
|||||||
---
|
---
|
||||||
|
|
||||||
<role>
|
<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.
|
Research the business domain — not the technical framework. Write Section 1b of AI-SPEC.md.
|
||||||
</role>
|
</role>
|
||||||
|
|
||||||
@~/.claude/gsd-core/references/untrusted-input-boundary.md
|
@~/.claude/msd-core/references/untrusted-input-boundary.md
|
||||||
|
|
||||||
<documentation_lookup>
|
<documentation_lookup>
|
||||||
@~/.claude/gsd-core/references/research-documentation-lookup.md
|
@~/.claude/msd-core/references/research-documentation-lookup.md
|
||||||
</documentation_lookup>
|
</documentation_lookup>
|
||||||
|
|
||||||
<required_reading>
|
<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>
|
</required_reading>
|
||||||
|
|
||||||
<input>
|
<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.
|
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.
|
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:
|
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 -->`.
|
- `Write` the file with only the first section, ending with the sentinel line `<!-- msd: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`.
|
- `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.
|
- 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.
|
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.
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: gsd-eval-auditor
|
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 /gsd:eval-review orchestrator.
|
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
|
tools: Read, Write, Bash, Grep, Glob, Skill
|
||||||
color: red
|
color: red
|
||||||
# hooks:
|
# hooks:
|
||||||
@@ -25,12 +25,12 @@ Scan the codebase, score each dimension COVERED/PARTIAL/MISSING, write EVAL-REVI
|
|||||||
</adversarial_stance>
|
</adversarial_stance>
|
||||||
|
|
||||||
<required_reading>
|
<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>
|
</required_reading>
|
||||||
|
|
||||||
**Context budget:** load project skills first (lightweight); read implementation files incrementally — only what each check requires.
|
**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>
|
<input>
|
||||||
- `ai_spec_path`: path to AI-SPEC.md (planned eval strategy)
|
- `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:
|
Do NOT compute scores by hand. Call the deterministic verb with your audited inputs:
|
||||||
|
|
||||||
```bash
|
```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
|
_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
|
||||||
gsd_run query eval.score --covered <covered_count> --total <total_dimensions> --infra <tooling>,<dataset>,<cicd>,<guardrails>,<tracing> --raw
|
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.
|
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.
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: gsd-eval-auditor
|
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 /gsd:eval-review orchestrator.
|
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
|
tools: Read, Write, Bash, Grep, Glob, Skill
|
||||||
color: red
|
color: red
|
||||||
# hooks:
|
# hooks:
|
||||||
@@ -33,14 +33,14 @@ Every planned eval dimension must resolve to COVERED, PARTIAL (WARNING), or MISS
|
|||||||
</adversarial_stance>
|
</adversarial_stance>
|
||||||
|
|
||||||
<required_reading>
|
<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>
|
</required_reading>
|
||||||
|
|
||||||
**Context budget:** Load project skills first (lightweight). Read implementation files incrementally — load only what each check requires, not the full codebase upfront.
|
**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:
|
**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)
|
1. List available skills (subdirectories)
|
||||||
2. Read `SKILL.md` for each skill (lightweight index ~130 lines)
|
2. Read `SKILL.md` for each skill (lightweight index ~130 lines)
|
||||||
3. Load specific `rules/*.md` files as needed during implementation
|
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:
|
Do NOT compute scores by hand. Call the deterministic verb with your audited inputs:
|
||||||
|
|
||||||
```bash
|
```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
|
_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
|
||||||
gsd_run query eval.score --covered <covered_count> --total <total_dimensions> --infra <tooling>,<dataset>,<cicd>,<guardrails>,<tracing> --raw
|
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.
|
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.
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: gsd-eval-planner
|
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 /gsd:ai-integration-phase orchestrator.
|
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
|
tools: Read, Write, Edit, Bash, Grep, Glob, AskUserQuestion
|
||||||
color: orange
|
color: orange
|
||||||
# hooks:
|
# hooks:
|
||||||
@@ -12,11 +12,11 @@ color: orange
|
|||||||
---
|
---
|
||||||
|
|
||||||
<role>
|
<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>
|
</role>
|
||||||
|
|
||||||
<required_reading>
|
<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>
|
</required_reading>
|
||||||
|
|
||||||
<input>
|
<input>
|
||||||
@@ -31,7 +31,7 @@ Read `~/.claude/gsd-core/references/ai-evals.md` first — your evaluation frame
|
|||||||
<execution_flow>
|
<execution_flow>
|
||||||
|
|
||||||
<step name="read_phase_context">
|
<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>
|
||||||
|
|
||||||
<step name="select_eval_dimensions">
|
<step name="select_eval_dimensions">
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user