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

@@ -2,8 +2,8 @@
'use strict';
/**
* gen-loop-host-contract.cjs — generates gsd-core/bin/lib/loop-host-contract.cjs
* from the <!-- gsd:loop-host ... --> blocks in the five step workflows.
* gen-loop-host-contract.cjs — generates msd-core/bin/lib/loop-host-contract.cjs
* from the <!-- msd:loop-host ... --> blocks in the five step workflows.
*
* Usage:
* node scripts/gen-loop-host-contract.cjs # print to stdout
@@ -20,12 +20,12 @@ const fs = require('node:fs');
const path = require('node:path');
const { ExitError, runMain } = require('./lib/cli-exit.cjs');
const { escapeRegex: escapeRegExp } = require('../gsd-core/bin/lib/pattern.cjs');
const { normalizeEol } = require('../gsd-core/bin/lib/text-lines.cjs');
const { escapeRegex: escapeRegExp } = require('../msd-core/bin/lib/pattern.cjs');
const { normalizeEol } = require('../msd-core/bin/lib/text-lines.cjs');
const ROOT = path.resolve(__dirname, '..');
const WORKFLOWS_DIR = path.join(ROOT, 'gsd-core', 'workflows');
const CONTRACT_PATH = path.join(ROOT, 'gsd-core', 'bin', 'lib', 'loop-host-contract.cjs');
const WORKFLOWS_DIR = path.join(ROOT, 'msd-core', 'workflows');
const CONTRACT_PATH = path.join(ROOT, 'msd-core', 'bin', 'lib', 'loop-host-contract.cjs');
// The five step workflows in pipeline order
const STEP_WORKFLOWS = [
@@ -69,13 +69,13 @@ const EXPECTED_POINTS_BY_STEP = {
// Role → agent-name mapping used for cross-check.
// Each non-orchestrator role must correspond to an actual agent reference in
// the workflow file (e.g. gsd-planner, gsd-executor, gsd-verifier, etc.).
// the workflow file (e.g. msd-planner, msd-executor, msd-verifier, etc.).
const ROLE_TO_AGENT = {
researcher: 'gsd-phase-researcher',
planner: 'gsd-planner',
checker: 'gsd-plan-checker',
executor: 'gsd-executor',
verifier: 'gsd-verifier',
researcher: 'msd-phase-researcher',
planner: 'msd-planner',
checker: 'msd-plan-checker',
executor: 'msd-executor',
verifier: 'msd-verifier',
};
// #4740 — Role → family mapping. Three families: orchestration, planning,
@@ -98,12 +98,12 @@ const EXPECTED_FAMILY_BY_STEP = {
// ─── Parser ───────────────────────────────────────────────────────────────────
/**
* Parse a single <!-- gsd:loop-host ... --> block from file content.
* Parse a single <!-- msd:loop-host ... --> block from file content.
* Returns a plain object with keys: step, points[], agentRoles[], produces[], consumes[].
* Throws a descriptive error if the block is malformed or missing.
*
* Block format (one key: value per line, comma-separated list values):
* <!-- gsd:loop-host
* <!-- msd:loop-host
* step: plan
* points: plan:pre, plan:post
* agent-roles: researcher, planner, checker
@@ -119,14 +119,14 @@ const EXPECTED_FAMILY_BY_STEP = {
*/
function parseLoopHostBlock(content, fileName) {
// FIX 2: Detect ALL marker blocks — more than one is a hard error.
const blockRe = /<!--\s*gsd:loop-host\s*([\s\S]*?)-->/g;
const blockRe = /<!--\s*msd:loop-host\s*([\s\S]*?)-->/g;
const allMatches = Array.from(content.matchAll(blockRe));
if (allMatches.length === 0) {
throw new Error(fileName + ': missing <!-- gsd:loop-host ... --> block');
throw new Error(fileName + ': missing <!-- msd:loop-host ... --> block');
}
if (allMatches.length > 1) {
throw new Error(
fileName + ': expected exactly one gsd:loop-host marker block, found ' + allMatches.length,
fileName + ': expected exactly one msd:loop-host marker block, found ' + allMatches.length,
);
}
@@ -146,7 +146,7 @@ function parseLoopHostBlock(content, fileName) {
}
for (const key of RECOGNIZED_KEYS) {
if (keyCounts[key] > 1) {
throw new Error(fileName + ': duplicate key \'' + key + '\' in gsd:loop-host marker');
throw new Error(fileName + ': duplicate key \'' + key + '\' in msd:loop-host marker');
}
}
@@ -165,7 +165,7 @@ function parseLoopHostBlock(content, fileName) {
return raw.split(',').map((s) => s.trim()).filter((s) => s.length > 0);
}
}
throw new Error(fileName + ': gsd:loop-host block missing required field "' + key + '"');
throw new Error(fileName + ': msd:loop-host block missing required field "' + key + '"');
}
function parseScalar(key) {
@@ -176,12 +176,12 @@ function parseLoopHostBlock(content, fileName) {
const colonIdx = trimmed.indexOf(':');
const val = trimmed.slice(colonIdx + 1).trim();
if (val === '') {
throw new Error(fileName + ': gsd:loop-host block field "' + key + '" must be a non-empty string');
throw new Error(fileName + ': msd:loop-host block field "' + key + '" must be a non-empty string');
}
return val;
}
}
throw new Error(fileName + ': gsd:loop-host block missing required field "' + key + '"');
throw new Error(fileName + ': msd:loop-host block missing required field "' + key + '"');
}
const step = parseScalar('step');
@@ -191,10 +191,10 @@ function parseLoopHostBlock(content, fileName) {
const consumes = parseField('consumes');
if (points.length === 0) {
throw new Error(fileName + ': gsd:loop-host block "points" must have at least one value');
throw new Error(fileName + ': msd:loop-host block "points" must have at least one value');
}
if (agentRoles.length === 0) {
throw new Error(fileName + ': gsd:loop-host block "agent-roles" must have at least one value');
throw new Error(fileName + ': msd:loop-host block "agent-roles" must have at least one value');
}
return {
@@ -227,8 +227,8 @@ function crossCheckRoles(content, agentRoles, fileName) {
);
continue;
}
// FIX 3: Use word-boundary match so "gsd-plan-checker-v2" does NOT satisfy a required
// "gsd-plan-checker". Treat '-' as part of the token: boundary = start/end of string or
// FIX 3: Use word-boundary match so "msd-plan-checker-v2" does NOT satisfy a required
// "msd-plan-checker". Treat '-' as part of the token: boundary = start/end of string or
// a character that is neither \w nor '-'.
// Note: this is a presence check (any reference in the file), not a spawn-site check —
// a known limitation; spawn-site checks would require AST-level analysis.
@@ -385,7 +385,7 @@ function buildContract(workflowsDir) {
// Validate the declared step matches the expected step for this file
if (entry.step !== step) {
allErrors.push(
file + ': gsd:loop-host block declares step "' + entry.step +
file + ': msd:loop-host block declares step "' + entry.step +
'" but expected "' + step + '"',
);
}
@@ -488,7 +488,7 @@ function main() {
if (!fs.existsSync(CONTRACT_PATH)) {
process.stderr.write(
'gsd-core/bin/lib/loop-host-contract.cjs does not exist. Run:\n' +
'msd-core/bin/lib/loop-host-contract.cjs does not exist. Run:\n' +
' node scripts/gen-loop-host-contract.cjs --write\n',
);
throw new ExitError(1);
@@ -498,13 +498,13 @@ function main() {
// FIX 4: Compare full content (no generated-by stripping) so header drift is caught.
if (normalizeEol(committed) !== normalizeEol(live)) {
process.stderr.write(
'gsd-core/bin/lib/loop-host-contract.cjs is stale. Run:\n' +
'msd-core/bin/lib/loop-host-contract.cjs is stale. Run:\n' +
' node scripts/gen-loop-host-contract.cjs --write\n',
);
throw new ExitError(1);
}
process.stdout.write('gsd-core/bin/lib/loop-host-contract.cjs is up to date.\n');
process.stdout.write('msd-core/bin/lib/loop-host-contract.cjs is up to date.\n');
} else if (flag === '--write') {
let contract;
try {
@@ -539,8 +539,8 @@ function main() {
* a separate hardcoded list.
*/
const HOST_LOOP_FILES = STEP_WORKFLOWS.flatMap(({ file, auxiliaryHosts = [] }) => [
'gsd-core/workflows/' + file,
...auxiliaryHosts.map((host) => 'gsd-core/workflows/' + host.file),
'msd-core/workflows/' + file,
...auxiliaryHosts.map((host) => 'msd-core/workflows/' + host.file),
]);
/**
@@ -577,7 +577,7 @@ const HOOK_KINDS = ['contribution', 'step', 'gate'];
* call site, up to the next call site or the region cap, judged LINE by line:
*
* - A deferral line (one carrying an `@`-included path to the generic
* contract, e.g. `@gsd-core/references/loop-hook-dispatch.md`) that names a
* contract, e.g. `@msd-core/references/loop-hook-dispatch.md`) that names a
* kind (`kind == "step"`) covers that kind; a deferral line with no kind
* discriminator ("apply each entry") covers every kind only when no role
* target is required. With `expectedInto`, the same segment must explicitly