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

@@ -8,7 +8,7 @@
*
* Enhancement shape approved at triage: a new default-off key on the EXISTING
* `ui` capability (ADR-894's one-owner invariant — `ui` already owns
* gsd-ui-auditor, so no new capability directory may claim it), with the
* msd-ui-auditor, so no new capability directory may claim it), with the
* auditor's <screenshot_approach> branching on it and falling back to today's
* Playwright-only path when the key is off or no Chrome binary resolves.
*
@@ -27,8 +27,8 @@
* 5. The gitignore gate covers the capture directory as a whole, and an
* existing .gitignore is upgraded rather than left as written.
*
* The auditor carries no gsd_run resolver, so the key travels through the
* <config> block /gsd-ui-review builds; the fence under test consumes the
* The auditor carries no msd_run resolver, so the key travels through the
* <config> block /msd-ui-review builds; the fence under test consumes the
* INTERACTION_CAPTURE, SCREENSHOT_DIR and DEV_URL variables the surrounding
* prose defines and is executed here under bash with a stub driver on PATH.
*/
@@ -39,31 +39,31 @@ const fs = require('node:fs');
const os = require('node:os');
const path = require('node:path');
const { spawnSync } = require('node:child_process');
const { splitLines } = require('../gsd-core/bin/lib/text-lines.cjs');
const { createTempProject, cleanup, runGsdTools } = require('./helpers.cjs');
const { splitLines } = require('../msd-core/bin/lib/text-lines.cjs');
const { createTempProject, cleanup, runMsdTools } = require('./helpers.cjs');
const { PROBE_TIMEOUT_MS } = require('./helpers/timeouts.cjs');
// The stub driver never blocks, so one fence run is a handful of sh spawns; distinct
// from PROBE (a single probe) and BUILD (a compiler) — its own class, bounded generously.
const FENCE_RUN_TIMEOUT_MS = 30000;
const realRegistry = require('../gsd-core/bin/lib/capability-registry.cjs');
const { isValidConfigKey } = require('../gsd-core/bin/lib/config-schema.cjs');
const { loadConfig } = require('../gsd-core/bin/lib/config-loader.cjs');
const realRegistry = require('../msd-core/bin/lib/capability-registry.cjs');
const { isValidConfigKey } = require('../msd-core/bin/lib/config-schema.cjs');
const { loadConfig } = require('../msd-core/bin/lib/config-loader.cjs');
const REPO_ROOT = path.join(__dirname, '..');
const CAP_ID = 'ui';
const KEY = 'workflow.ui_interaction_capture';
const AGENT = 'gsd-ui-auditor';
const AGENT = 'msd-ui-auditor';
const AUDITOR_PATH = path.join(REPO_ROOT, 'agents', `${AGENT}.md`);
const UI_REVIEW_PATH = path.join(REPO_ROOT, 'gsd-core', 'workflows', 'ui-review.md');
const UI_REVIEW_PATH = path.join(REPO_ROOT, 'msd-core', 'workflows', 'ui-review.md');
const MANIFEST_PATH = path.join(REPO_ROOT, 'capabilities', CAP_ID, 'capability.json');
const DOCS_CONFIG_PATH = path.join(REPO_ROOT, 'docs', 'CONFIGURATION.md');
const HOWTO_PATH = path.join(REPO_ROOT, 'docs', 'how-to', 'enable-ui-interaction-capture.md');
const OPEN_ANCHOR = '<!-- gsd:ui-interaction-capture -->';
const CLOSE_ANCHOR = '<!-- /gsd:ui-interaction-capture -->';
const OPEN_ANCHOR = '<!-- msd:ui-interaction-capture -->';
const CLOSE_ANCHOR = '<!-- /msd:ui-interaction-capture -->';
const FENCE = '`'.repeat(3);
function readManifest() {
@@ -114,7 +114,7 @@ describe('ui capability owns workflow.ui_interaction_capture', () => {
test('theKeyLivesOnTheCapabilityThatAlreadyOwnsTheAuditor', () => {
// ADR-894 one-owner invariant: a NEW capability directory could not also
// claim gsd-ui-auditor, which is why triage required the existing manifest.
// claim msd-ui-auditor, which is why triage required the existing manifest.
const cap = readManifest();
assert.ok(cap.agents.includes(AGENT), `${CAP_ID} must own ${AGENT}`);
assert.equal(realRegistry.byAgent[AGENT], CAP_ID, 'the generated registry must agree on the owner');
@@ -140,7 +140,7 @@ describe('config layer round-trips the key', () => {
test('configSetAcceptsAndPersistsTrue', (t) => {
const tmpDir = createTempProject();
t.after(() => cleanup(tmpDir));
const result = runGsdTools(`config-set ${KEY} true`, tmpDir);
const result = runMsdTools(`config-set ${KEY} true`, tmpDir);
assert.ok(result.success, `config-set must accept ${KEY}: ${result.error}`);
const cfg = JSON.parse(fs.readFileSync(path.join(tmpDir, '.planning', 'config.json'), 'utf8'));
assert.equal(cfg.workflow?.ui_interaction_capture, true);
@@ -149,7 +149,7 @@ describe('config layer round-trips the key', () => {
test('configSetRejectsANonBoolean', (t) => {
const tmpDir = createTempProject();
t.after(() => cleanup(tmpDir));
const result = runGsdTools(`config-set ${KEY} banana`, tmpDir);
const result = runMsdTools(`config-set ${KEY} banana`, tmpDir);
assert.ok(!result.success, 'a boolean slice must reject a non-boolean');
});
@@ -171,10 +171,10 @@ describe('config layer round-trips the key', () => {
}
});
describe('/gsd-ui-review hands the key to the auditor', () => {
describe('/msd-ui-review hands the key to the auditor', () => {
test('orchestratorReadsTheKeyAndPassesItInTheConfigBlock', () => {
const src = fs.readFileSync(UI_REVIEW_PATH, 'utf8');
assert.ok(src.includes(`config-get ${KEY}`), 'ui-review.md must read the key through gsd_run');
assert.ok(src.includes(`config-get ${KEY}`), 'ui-review.md must read the key through msd_run');
// Lowercase placeholder, like the block's `{phase_dir}` / `{padded_phase}` siblings —
// the block is a prompt template the orchestrator fills, not a bash heredoc.
assert.ok(src.includes('interaction_capture: {interaction_capture}'),
@@ -185,12 +185,12 @@ describe('/gsd-ui-review hands the key to the auditor', () => {
});
test('auditorNeverReadsConfigItself', () => {
// The auditor carries no gsd_run resolver; the key must arrive by value.
// The auditor carries no msd_run resolver; the key must arrive by value.
const src = fs.readFileSync(AUDITOR_PATH, 'utf8');
// Prose may NAME gsd_run (this section explains why it is absent); an invocation
// Prose may NAME msd_run (this section explains why it is absent); an invocation
// or a resolver definition is what must not appear.
assert.ok(!/gsd_run (query|runtime-identity)|gsd_run\(\)/.test(src),
'gsd-ui-auditor.md must not grow a gsd_run dependency for this');
assert.ok(!/msd_run (query|runtime-identity)|msd_run\(\)/.test(src),
'msd-ui-auditor.md must not grow a msd_run dependency for this');
assert.ok(src.includes('interaction_capture'), 'the auditor must name the <config> field it consumes');
});
});