refactor: hard-fork GSD -> MSD (Make Software Done)

Mechanical rename produced by scripts/msd-rename.cjs: gsd/Gsd/GSD -> msd/Msd/MSD
across contents and paths, upstream package/repo coordinates -> @golem15/msd-core
and golem15com/msd-core. Deep links into upstream history, sibling upstream
packages, the GSD-2 import feature, CHANGELOG.md and .changeset/ are kept as-is.

Hand edits on top: MSD block-letter banner and logos, LICENSE copyright line,
package/plugin identity, regenerated lockfile, install-tree fixtures, derived
registries and benchmark baseline; migration checksum baseline re-locked
(MSD keeps its own install state, so no install had applied the old sums);
sort-order and regex-escaped expectations in tests adjusted.
This commit is contained in:
Jakub Zych
2026-10-06 01:47:40 +02:00
parent fe069b2a56
commit a9a7a328e6
2763 changed files with 78465 additions and 78434 deletions

View File

@@ -1,14 +1,14 @@
# Workflow fragments (reference)
> **Diátaxis quadrant:** Reference. This is the canonical specification of the
> in-file `<!-- gsd:section -->` marker grammar used to fragmentize GSD workflow
> in-file `<!-- msd:section -->` marker grammar used to fragmentize MSD workflow
> markdown for per-runtime emission. For the surrounding seam (why it exists and
> how it composes with the shared budget composer), see
> [Architecture: Workflow Fragmentization and Emission](../ARCHITECTURE.md#workflow-fragmentization-and-emission-srcworkflow-fragmentscts-adr-1671)
> and [ADR-1671](../adr/1671-dynamic-context-management-platform.md) (open
> questions 1 and 2).
Workflow authors can mark one or more sections of a `gsd-core/workflows/*.md` file
Workflow authors can mark one or more sections of a `msd-core/workflows/*.md` file
so that `bin/install.js`'s emission path can compose them per runtime, and so that
a separate init-time seam can select which sections apply to one concrete
invocation — see [The manifest artifact and per-workflow
@@ -20,13 +20,13 @@ An open marker is a line whose only content (after trimming leading/trailing
whitespace) is:
```html
<!-- gsd:section id="<id>" when="<when>" -->
<!-- msd:section id="<id>" when="<when>" -->
```
A close marker is a line whose only content is:
```html
<!-- /gsd:section -->
<!-- /msd:section -->
```
- Attribute order is free and inner spacing around `=` and between attributes
@@ -89,10 +89,10 @@ into the `--discuss`/`--research`/`--validate` facts before evaluation) and
| `state:needs-codebase-map` | Applicable when a codebase map is needed (init-computed). |
| `state:next-channel` | Applicable when `update.md`'s release channel is `next` — the workflow runs with `--next`, or its documented alias `--rc`. |
| `state:phase-mvp-mode` | Applicable when the current phase's `ROADMAP.md` entry declares `**Mode:** mvp`. |
| `state:plan-strategy-converge` | Applicable when `autonomous.md`'s planning step should route through plan-review convergence instead of `gsd-plan-phase` — the workflow runs with `--converge`, or its documented alias `--cross-ai` (`autonomous.md`'s own `PLAN_STRATEGY` resolver folds both). |
| `state:plan-strategy-converge` | Applicable when `autonomous.md`'s planning step should route through plan-review convergence instead of `msd-plan-phase` — the workflow runs with `--converge`, or its documented alias `--cross-ai` (`autonomous.md`'s own `PLAN_STRATEGY` resolver folds both). |
| `state:reviewer-instances-configured` | Applicable when `.planning/config.json`'s `review.reviewer_instances` is present AND non-empty. |
| `state:ui-phase-active` | Applicable when the phase's active `plan:pre` loop hooks include the `ui-phase` step, OR the phase directory already contains a `*-UI-SPEC.md` file — see [Compound conditions are resolved in the fact, never the grammar](#compound-conditions-are-resolved-in-the-fact-never-the-grammar) below. |
| `state:workstream-active` | Applicable when a workstream is active — `GSD_WORKSTREAM` env, falling back to the stored active-workstream pointer. |
| `state:workstream-active` | Applicable when a workstream is active — `MSD_WORKSTREAM` env, falling back to the stored active-workstream pointer. |
| `state:worktrees-enabled` | Applicable when `.planning/config.json`'s `workflow.use_worktrees` is enabled. |
This list is **closed by design** (Greenspun's Tenth Rule): left open-ended,
@@ -161,12 +161,12 @@ of the pre-existing `cmdInitNewMilestone`.
An entry point can also land **ahead of** the atom it will unblock. `#3149`
gives `debug` a dedicated `cmdInitDebug` (`init.debug`) with no vocabulary
change at all: `/gsd-debug` previously made three separate `gsd_run`
change at all: `/msd-debug` previously made three separate `msd_run`
round-trips and had no `cmdInit*` of its own, so gate (2) could never be
satisfied for any debug-scoped fact. Shipping the entry point first satisfies
gate (2) on its own schedule and leaves gate (1) — a consuming section of at
least 400 bytes — to the change that actually adds the section. `debug` has no
`<!-- gsd:section -->` markers yet, so it contributes no key to
`<!-- msd:section -->` markers yet, so it contributes no key to
`section-manifest.json` and `init.debug`'s `section_manifest` field degrades to
`null` (read everything) until it does.
@@ -197,7 +197,7 @@ of how reasonable a single compound condition looks in isolation.
`state:ui-phase-active` (#2994) is the same shape: `verify-work.md`'s
`automated_ui_verification` step originally computed its own OR at RUNTIME
(`UI_PHASE_ACTIVE` from `gsd_run loop render-hooks plan:pre` OR a `*-UI-SPEC.md`
(`UI_PHASE_ACTIVE` from `msd_run loop render-hooks plan:pre` OR a `*-UI-SPEC.md`
file check). `cmdInitVerifyWork` now resolves the identical disjunction ahead
of time — `resolveLoopHooks({point: 'plan:pre', ...}).activeHooks` filtered to
`kind === 'step' && ref.skill === 'ui-phase'`, OR'd with a `*-UI-SPEC.md`
@@ -217,7 +217,7 @@ never `--converge`/`--cross-ai` separately.
`discuss-phase-assumptions.md`'s own `auto_advance` step already resolves
`--auto` OR a consolidated `check auto-mode --pick active` fact (itself
`workflow._auto_chain_active` OR `workflow.auto_advance`) via a runtime
`gsd_run` call before deciding whether to dispatch. `cmdInitDiscussPhaseAssumptions`
`msd_run` call before deciding whether to dispatch. `cmdInitDiscussPhaseAssumptions`
mirrors that identical disjunction — `options['auto'] === true ||
readConfigJsonBoolean(cwd, ['workflow', '_auto_chain_active']) ||
readConfigJsonBoolean(cwd, ['workflow', 'auto_advance'])` — into
@@ -257,7 +257,7 @@ shared `context-composer.cjs` budget seam (every fragment uses the `verbatim`
strategy, so nothing is trimmed) → re-join fragment bodies in document order.
The marker lines themselves are never part of any fragment body, so the
composed output — and therefore every installed runtime artifact — contains
no `gsd:section` markers at all. An unmarked file composes to itself exactly;
no `msd:section` markers at all. An unmarked file composes to itself exactly;
a marked file composes to itself minus the marker line bytes.
Composition runs **before** the per-runtime converters (the `.claude/` →
@@ -280,8 +280,8 @@ that emits agent content:
All three compose **before** any path rewrite, for the same reason workflows do.
**What does not extend is `when=` gating.** Selection is read from
`gsd-core/workflows/section-manifest.json`, which `gen-section-manifest.cjs`
derives from `gsd-core/workflows/*.md` only — its shape is `{workflows: …}` and
`msd-core/workflows/section-manifest.json`, which `gen-section-manifest.cjs`
derives from `msd-core/workflows/*.md` only — its shape is `{workflows: …}` and
it has no per-agent key. There is no per-agent init entry point either, so an
agent atom has no fact to evaluate against and would fail the vocabulary's
second admission gate ("a fact the init seam demonstrably computes at a real
@@ -290,16 +290,16 @@ forever while *looking* like working gating — the precise failure the frozen
vocabulary exists to prevent.
Agents that need to shed bytes do so by extracting reference material to
`gsd-core/references/` behind an `@`-reference, the documented
`msd-core/references/` behind an `@`-reference, the documented
`DEFECT.AGENT-FILE-SIZE-CAP-BREACH` remedy — not by adding markers.
## Fenced and commented lookalikes are literal
A `<!-- gsd:section ... -->`-shaped line inside a fenced code block (three or
A `<!-- msd:section ... -->`-shaped line inside a fenced code block (three or
more backticks or tildes, CommonMark-style) is **not** a marker — it is
literal fence content, because workflows document their own marker syntax in
fenced examples (as in this page and in the workflow files themselves). The
same applies to a `gsd:section` mention inside an unrelated HTML comment, or
same applies to a `msd:section` mention inside an unrelated HTML comment, or
in prose/backtick text that never opens a real one-line comment. Fence and
comment detection run as a single interleaved left-to-right scan, mirroring
the discipline used by the `CONTEXT.md` predicate parser
@@ -308,18 +308,18 @@ can end it; while a comment is open, only `-->` can end it; an unclosed fence
running to end of file is not an error — everything after it is simply
literal.
The pre-existing `<!-- gsd:loop-host ... -->` marker family (consumed by
The pre-existing `<!-- msd:loop-host ... -->` marker family (consumed by
`scripts/gen-loop-host-contract.cjs`) is a different, already-established
marker and is never treated as a `gsd:section` marker.
marker and is never treated as a `msd:section` marker.
## The manifest artifact and per-workflow keying
`bin/install.js`'s emission path always composes every fragment into the
output regardless of its `when=` value — marker lines are stripped, nothing
else changes there. Applicability selection is a separate, later seam:
`scripts/gen-section-manifest.cjs --write` scans `gsd-core/workflows/*.md` for
`gsd:section` markers and generates a committed artifact,
`gsd-core/workflows/section-manifest.json`, shaped as
`scripts/gen-section-manifest.cjs --write` scans `msd-core/workflows/*.md` for
`msd:section` markers and generates a committed artifact,
`msd-core/workflows/section-manifest.json`, shaped as
`{"workflows": {"<workflow-name>": [{"id", "when", "read"}, ...], ...}}`,
where `<workflow-name>` is a source `.md` file's basename without extension
and `read` is the POSIX-normalized, repo-root-relative path of the step file
@@ -377,20 +377,20 @@ that were actually seen.
Fifteen workflows carry markers today, all of them the workflows with a
dedicated `cmdInit*` entry point (see [The manifest artifact](#the-manifest-artifact-and-per-workflow-keying)
above): `gsd-core/workflows/execute-phase.md` (the #2930/Phase-3 pilot),
`gsd-core/workflows/plan-phase.md` (#2993, epic #1671 Phase 6.2),
`gsd-core/workflows/progress.md`, `gsd-core/workflows/new-project.md`,
`gsd-core/workflows/quick.md`, `gsd-core/workflows/new-milestone.md` (those
four, #2994, epic #1671 Phase 6.3), `gsd-core/workflows/verify-work.md`
(also #2994, epic #1671 Phase 6.3), `gsd-core/workflows/code-review.md` /
`gsd-core/workflows/complete-milestone.md` (a further #2994 amendment, epic
#1671 Phase 6.3), `gsd-core/workflows/autonomous.md` (a still further
#2994 amendment, epic #1671 Phase 6.3), `gsd-core/workflows/review.md` /
`gsd-core/workflows/discuss-phase-assumptions.md` (a still further #2994
above): `msd-core/workflows/execute-phase.md` (the #2930/Phase-3 pilot),
`msd-core/workflows/plan-phase.md` (#2993, epic #1671 Phase 6.2),
`msd-core/workflows/progress.md`, `msd-core/workflows/new-project.md`,
`msd-core/workflows/quick.md`, `msd-core/workflows/new-milestone.md` (those
four, #2994, epic #1671 Phase 6.3), `msd-core/workflows/verify-work.md`
(also #2994, epic #1671 Phase 6.3), `msd-core/workflows/code-review.md` /
`msd-core/workflows/complete-milestone.md` (a further #2994 amendment, epic
#1671 Phase 6.3), `msd-core/workflows/autonomous.md` (a still further
#2994 amendment, epic #1671 Phase 6.3), `msd-core/workflows/review.md` /
`msd-core/workflows/discuss-phase-assumptions.md` (a still further #2994
amendment, epic #1671 Phase 6.3), and finally
`gsd-core/workflows/docs-update.md` / `gsd-core/workflows/update.md` /
`gsd-core/workflows/transition.md` (the LAST #2994 amendment, epic #1671
Phase 6.3 — none of these three carried a `gsd_run query init.*` call before
`msd-core/workflows/docs-update.md` / `msd-core/workflows/update.md` /
`msd-core/workflows/transition.md` (the LAST #2994 amendment, epic #1671
Phase 6.3 — none of these three carried a `msd_run query init.*` call before
this slice). Every one of the 13 workflows ADR-1671 targeted is now on the
fragment model; the marker grammar and composer seam remain general-purpose
across any future workflow file, but no further rollout is scheduled.
@@ -408,7 +408,7 @@ across any future workflow file, but no further rollout is scheduled.
`progress.md` marks two sections: `forensic-audit` (`flag:--forensic`, #2994
forensic audit) and `mvp-display` (`state:phase-mvp-mode`). `mvp-display`'s
own body used to re-resolve its own gating fact via a `gsd_run query
own body used to re-resolve its own gating fact via a `msd_run query
phase.mvp-mode` call — circular, since a section's body re-deriving the exact
condition that gated its own inclusion is self-disabling the moment the init
seam's computation and the body's computation drift. `cmdInitProgress` now
@@ -449,7 +449,7 @@ workstream mode) stays OUTSIDE the marker, directly after it, for the same
reason every other flag-absent/state-false fallback in this document does.
`cmdInitNewMilestone` computes both `workstreamActive` and `flatMode` from
the SAME authoritative source `cmdInitProgress` already established
(`GSD_WORKSTREAM` env, falling back to the stored active-workstream
(`MSD_WORKSTREAM` env, falling back to the stored active-workstream
pointer). Because Step 4 (where the marker lives) runs well before
`new-milestone.md`'s pre-existing `init.new-milestone` call (Step 7, kept
AFTER Step 6's phase archival so its `phase_dir_count`/`roadmap_exists`
@@ -469,7 +469,7 @@ guard) moves into the step file — the false-branch note ("When `MVP_MODE=false
directly after it, because gating it away with the rest of the section would
delete the exact text needed on every invocation where the atom is `false`
(the common, non-MVP case). Unlike `progress.md`'s `mvp-display`, `verify-work.md`
keeps its own `MVP_MODE=$(gsd_run query phase.mvp-mode ...)` runtime resolver
keeps its own `MVP_MODE=$(msd_run query phase.mvp-mode ...)` runtime resolver
(in the unconditional `initialize` step, not inside the gated section) — it is
not circular/self-disabling the way `progress.md`'s inline resolver was,
because the un-marked false-branch note and the step-file prose both still
@@ -478,7 +478,7 @@ consumer outside the gate.
`code-review.md` marks two sections: `structural-pre-pass` (`state:fallow-enabled`)
and `dispatch-fix` (`flag:--fix`). `structural-pre-pass`'s own body used to
re-resolve its own gating fact via four `gsd_run query config-get
re-resolve its own gating fact via four `msd_run query config-get
code_quality.fallow.*` calls — circular, for the same reason `progress.md`'s
pre-hoist `mvp-display` was: a section's body re-deriving the exact condition
that gated its own inclusion is self-disabling the moment the init seam's
@@ -501,7 +501,7 @@ than a raw `--fix` token scan.
`complete-milestone.md` marks one section: `git-tag` (`state:git-create-tag`).
The `git_tag` step's own `<config-check>` sub-tag used to re-resolve
`git.create_tag` via `gsd-tools.cjs query config-get` to decide whether to
`git.create_tag` via `msd-tools.cjs query config-get` to decide whether to
skip the step — again a section (here, a whole step) gating its own inclusion
on a fact its own body computed. `cmdInitCompleteMilestone` now resolves it
once (`detectGitCreateTag`, `src/init.cts`, fail-OPEN default `true` — an
@@ -597,13 +597,13 @@ divergence-prone workspace-glob scan — the SAME detector that already backs
`update.md` marks one section: `channel-banner` (`state:next-channel`) — the
"Only when `TAG=next`" channel-banner paragraph in `compare_versions`.
`update.md` previously called NO `init.*` command at all; it resolves
`gsd-tools.cjs` itself via a bespoke `PREFERRED_CONFIG_DIR`/
`PREFERRED_RUNTIME`-aware `$GSD_TOOLS` cascade (`get_installed_version`,
`msd-tools.cjs` itself via a bespoke `PREFERRED_CONFIG_DIR`/
`PREFERRED_RUNTIME`-aware `$MSD_TOOLS` cascade (`get_installed_version`,
~lines 13-45) because the update workflow must run before any install can be
assumed resolvable. The new `init.update` call REUSES that already-resolved
`$GSD_TOOLS` (dual `.cjs`/PATH-shim invocation style, matching the
`$MSD_TOOLS` (dual `.cjs`/PATH-shim invocation style, matching the
pre-existing `update-context` call) rather than copying the canonical
launcher preamble — both resolutions assign the identical `$GSD_TOOLS` shell
launcher preamble — both resolutions assign the identical `$MSD_TOOLS` shell
variable, and the canonical preamble would silently clobber the value later
steps (`backup_custom_files`, `restore_custom_files`) still depend on.
`cmdInitUpdate`'s `nextChannel` fact (`--next` OR its documented alias
@@ -612,17 +612,17 @@ steps (`backup_custom_files`, `restore_custom_files`) still depend on.
stays byte-identical — issue #815's regression test
(`tests/update-workflow.test.cjs`) asserts that literal
case-statement text remains in the workflow, since the npm dist-tag
selection has to run in the workflow's own shell before any `gsd_run`
selection has to run in the workflow's own shell before any `msd_run`
round-trip.
`transition.md` marks one section: `workstream-collision-check`
(`state:workstream-active`) — an internal workflow (it has no user-facing
slash command of its own) that previously called NO `init.*` command at
all. It already establishes `gsd_run()` via the canonical launcher preamble
all. It already establishes `msd_run()` via the canonical launcher preamble
in its `update_roadmap_and_state` step, before this call's insertion point
in `offer_next_phase`, so no second preamble copy is needed. The section's
body previously re-derived its own gating condition via an inline `gsd_run
query workstream.list --raw` call wrapped in `if [ -n "$GSD_WORKSTREAM" ]`
body previously re-derived its own gating condition via an inline `msd_run
query workstream.list --raw` call wrapped in `if [ -n "$MSD_WORKSTREAM" ]`
— the identical condition that now backs the section's own admission (the
same resolver-in-body hazard `code-review.md`'s `structural-pre-pass` and
`complete-milestone.md`'s `git-tag` documented). `cmdInitTransition` hoists
@@ -631,7 +631,7 @@ this via `getOtherActiveWorkstreamInventories` (`src/workstream-inventory.cts`
as the step's own prose described (excludes the current workstream and any
workstream whose status contains "milestone complete" or "archived",
case-insensitively), exposed as `other_active_workstreams`; the step body is
now a pure JSON consumer with no `gsd_run` call of its own.
now a pure JSON consumer with no `msd_run` call of its own.
**`plan-phase.md` was originally retargeted away from the #2930 pilot,
then fragmentized here once the blocker cleared.** Issue #2930's own
@@ -642,7 +642,7 @@ gate (`tests/phase6-capstone-conformance.test.cjs`'s `PRE_PHASE6`, an
ADR-857 Phase-6 completion property) and could not absorb any marker
overhead at all. #2993 resolves this **because fragmentizing is net-negative
on host source, not net-positive**: each gated body moves from always-inline
prose to a `gsd-core/workflows/plan-phase/steps/<id>.md` step file, leaving
prose to a `msd-core/workflows/plan-phase/steps/<id>.md` step file, leaving
only a ~200 B conditional-read stub behind — the six extractions trim
`plan-phase.md` from 94,483 B to 87,575 B, moving the file from 36 B of
`PRE_PHASE6` headroom to roughly 7,000 B, well clear of the cap.
@@ -672,6 +672,6 @@ question 1's resolution for the full record.
- `src/section-manifest.cts` — the pure `when=` evaluator (`selectSections`,
`InvocationFacts`) consumed by the init seam.
- `scripts/gen-section-manifest.cjs` — generates the committed
`gsd-core/workflows/section-manifest.json` artifact from markers.
`msd-core/workflows/section-manifest.json` artifact from markers.
- `src/init.cts` — `buildSectionManifestField` and the fifteen wired
`cmdInit*` entry points.