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:
@@ -30,9 +30,9 @@
|
||||
* stays hard-coded, so a dest change still fails loud.
|
||||
*
|
||||
* ── The trap this table exists to avoid ─────────────────────────────────────
|
||||
* The repo contains `skills/gsd-<stem>/SKILL.md` (71 dirs) that LOOK like the source
|
||||
* The repo contains `skills/msd-<stem>/SKILL.md` (71 dirs) that LOOK like the source
|
||||
* of the emitted `skills/` family. They are not: scripts/gen-plugin-skills.cjs
|
||||
* GENERATES them from commands/gsd/*.md, and the installer stages from commands/gsd/
|
||||
* GENERATES them from commands/msd/*.md, and the installer stages from commands/msd/
|
||||
* directly (src/install-profiles.cts:637-708). Attributing emitted skills to repo
|
||||
* skills/ would be false attribution that still passes totality — the exact residual
|
||||
* risk ADR-2719 records. The spot-check tests pin this pair.
|
||||
@@ -59,14 +59,14 @@ const { MANIFEST_FAMILIES, runMinimalInstall, buildParityManifest } = require('.
|
||||
const EXPECTED_MANIFEST_COUNT = MANIFEST_FAMILIES.length;
|
||||
|
||||
// ─── Emitted roots ────────────────────────────────────────────────────────────
|
||||
// Longest-first: `skills/gsd` (hermes category dir) must win over `skills` for
|
||||
// `skills/gsd/...`, and `.agents/skills` must win over `.agents`.
|
||||
// Longest-first: `skills/msd` (hermes category dir) must win over `skills` for
|
||||
// `skills/msd/...`, and `.agents/skills` must win over `.agents`.
|
||||
|
||||
const SKILLS_ROOTS = ['skills/gsd', '.agents/skills', 'skills'];
|
||||
const SKILLS_ROOTS = ['skills/msd', '.agents/skills', 'skills'];
|
||||
const HOOKS_ROOTS = ['.kimi-code/hooks', '.kimi/hooks', 'hooks'];
|
||||
|
||||
/** Source-of-truth command dir every skill/command surface converts from. */
|
||||
const COMMANDS_SRC = 'commands/gsd';
|
||||
const COMMANDS_SRC = 'commands/msd';
|
||||
|
||||
/** Installer source file that emits the Cline/AGENTS.md instruction bodies as
|
||||
* code literals (buildClineRulesBody / buildClineAgentsMdBody /
|
||||
@@ -168,7 +168,7 @@ const AGENT_TRANSFORM_SRCS = [
|
||||
// #3738: antigravity's global skills pass through the antigravity converter
|
||||
// (src/runtime-artifact-conversion.cts, mirrored hand-authored in bin/install.js
|
||||
// per ADR-1508), whose rewrites — e.g. ~/.claude/skills/ → ~/.gemini/config/skills/
|
||||
// — can move emitted bytes with NO commands/gsd source changing. Declaring the
|
||||
// — can move emitted bytes with NO commands/msd source changing. Declaring the
|
||||
// transform here attributes that ripple class permanently, the same way
|
||||
// AGENT_TRANSFORM_SRCS does for agents; scoped to runtime 'antigravity' so a
|
||||
// converter change never blankets the other skills runtimes' attribution.
|
||||
@@ -179,7 +179,7 @@ const ANTIGRAVITY_SKILL_TRANSFORM_SRCS = [
|
||||
|
||||
// #4002: zcode's command AND skill bodies flow through `_applyRuntimeRewrites`
|
||||
// (converter: null — the rewrite pass is their only path-rewriting step), so a
|
||||
// converter change moves emitted bytes with no commands/gsd source changing.
|
||||
// converter change moves emitted bytes with no commands/msd source changing.
|
||||
// Same permanent-attribution shape as ANTIGRAVITY_SKILL_TRANSFORM_SRCS (#3738),
|
||||
// scoped to runtime 'zcode' for the same reason.
|
||||
const ZCODE_BODY_TRANSFORM_SRCS = [
|
||||
@@ -214,7 +214,7 @@ const SOURCE_PREFIX_SUFFIX = '/';
|
||||
* stem (src/install-profiles.cts:696 joins `stem`, not `prefix + stem`).
|
||||
*/
|
||||
function stripSkillPrefix(dirName) {
|
||||
return dirName.startsWith('gsd-') ? dirName.slice(4) : dirName;
|
||||
return dirName.startsWith('msd-') ? dirName.slice(4) : dirName;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -227,10 +227,10 @@ function nativePluginDescriptor(runtime) {
|
||||
// rather than at module load for callers that never touch this family.
|
||||
let registry;
|
||||
try {
|
||||
registry = require('../../gsd-core/bin/lib/capability-registry.cjs');
|
||||
registry = require('../../msd-core/bin/lib/capability-registry.cjs');
|
||||
} catch (err) {
|
||||
throw new Error(
|
||||
'emitted-provenance: cannot load gsd-core/bin/lib/capability-registry.cjs ' +
|
||||
'emitted-provenance: cannot load msd-core/bin/lib/capability-registry.cjs ' +
|
||||
`(run \`npm run build\` first): ${err.message}`,
|
||||
);
|
||||
}
|
||||
@@ -282,18 +282,18 @@ function nativePluginDescriptor(runtime) {
|
||||
const PROVENANCE_RULES = [
|
||||
// ── Verbatim engine payload ────────────────────────────────────────────────
|
||||
{
|
||||
id: 'gsd-core-verbatim',
|
||||
id: 'msd-core-verbatim',
|
||||
// Markdown payloads pass through copyWithPathReplacement's audience
|
||||
// filter for non-Copilot runtimes. Non-Markdown payloads remain byte-for-
|
||||
// byte copies, but one rule has one kind; the match-specific transform
|
||||
// list below keeps the causal attribution precise.
|
||||
kind: 'derived',
|
||||
roots: ['gsd-core'],
|
||||
// Enumerated subdirs, NOT `.+`: a new gsd-core/<subdir> must fail totality
|
||||
roots: ['msd-core'],
|
||||
// Enumerated subdirs, NOT `.+`: a new msd-core/<subdir> must fail totality
|
||||
// loudly rather than being absorbed silently. Also keeps this mutually
|
||||
// exclusive with the two synthesized gsd-core top-level files below.
|
||||
// exclusive with the two synthesized msd-core top-level files below.
|
||||
pattern: /^(workflows|references|templates|contexts|bin)\/.+$/,
|
||||
sources: (m) => [`gsd-core/${m[0]}`],
|
||||
sources: (m) => [`msd-core/${m[0]}`],
|
||||
transforms: (m, ctx) => (
|
||||
m[0].endsWith('.md') && RUNTIME_NOTE_FILTERED_FAMILIES.has(ctx.runtime)
|
||||
? RUNTIME_NOTE_FILTER_TRANSFORM_SRCS
|
||||
@@ -301,17 +301,17 @@ const PROVENANCE_RULES = [
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'gsd-core-commands-corpus',
|
||||
id: 'msd-core-commands-corpus',
|
||||
kind: 'rewrite',
|
||||
roots: ['gsd-core'],
|
||||
pattern: /^commands\/gsd\/(.+)$/,
|
||||
sources: (m) => [`commands/gsd/${m[1]}`],
|
||||
roots: ['msd-core'],
|
||||
pattern: /^commands\/msd\/(.+)$/,
|
||||
sources: (m) => [`commands/msd/${m[1]}`],
|
||||
transforms: [INSTALL_ENGINE_SRC, INSTALLER_SRC],
|
||||
},
|
||||
{
|
||||
id: 'gsd-core-agents-corpus',
|
||||
id: 'msd-core-agents-corpus',
|
||||
kind: 'rewrite',
|
||||
roots: ['gsd-core'],
|
||||
roots: ['msd-core'],
|
||||
pattern: /^agents\/(.+)$/,
|
||||
sources: (m) => [`agents/${m[1]}`],
|
||||
transforms: [INSTALL_ENGINE_SRC, INSTALLER_SRC],
|
||||
@@ -330,7 +330,7 @@ const PROVENANCE_RULES = [
|
||||
id: 'agents-verbatim',
|
||||
// #2757 (was `identity`): measured against origin/next's own committed fixtures,
|
||||
// the SAME emitted agents/<name>.md hashes DIFFERENTLY per runtime (e.g. codex vs
|
||||
// claude for gsd-nyquist-auditor.md) — impossible for a true verbatim copy.
|
||||
// claude for msd-nyquist-auditor.md) — impossible for a true verbatim copy.
|
||||
// Verified empirically by installing every runtime and diffing the output against
|
||||
// the raw repo source: no runtime reproduces it byte-for-byte. Every one rewrites
|
||||
// frontmatter quoting and the hardcoded `.claude/` self-reference
|
||||
@@ -340,15 +340,15 @@ const PROVENANCE_RULES = [
|
||||
// per-runtime `kind`) and why this wholesale reclassification was chosen instead.
|
||||
kind: 'derived',
|
||||
roots: ['agents'],
|
||||
// Excludes `gsd.md`: that is Kimi's ROOT agent, built from a code literal and
|
||||
// Excludes `msd.md`: that is Kimi's ROOT agent, built from a code literal and
|
||||
// NOT a repo agent file. Without the exclusion it matched here and resolved to
|
||||
// `agents/gsd.md`, which does not exist — a false attribution that still passed
|
||||
// `agents/msd.md`, which does not exist — a false attribution that still passed
|
||||
// totality, i.e. the exact residual ADR-2719 records. Every repo agent is
|
||||
// `gsd-<name>.md`, so excluding the bare `gsd.md` is precise.
|
||||
// `msd-<name>.md`, so excluding the bare `msd.md` is precise.
|
||||
// `.agent.md` is likewise excluded — Copilot emits a RENAMED copy
|
||||
// (`<name>.agent.md`) whose source is `agents/<name>.md`; matching it here
|
||||
// resolved to a file that does not exist. Same false-attribution class.
|
||||
pattern: /^(?!gsd\.md$)(?!.*\.agent\.md$)[^/]+\.md$/,
|
||||
pattern: /^(?!msd\.md$)(?!.*\.agent\.md$)[^/]+\.md$/,
|
||||
sources: (m) => [`agents/${m[0]}`],
|
||||
transforms: AGENT_TRANSFORM_SRCS,
|
||||
},
|
||||
@@ -401,7 +401,7 @@ const PROVENANCE_RULES = [
|
||||
// Attribute to the REPO source a PR actually edits, not the build artifact.
|
||||
// Excludes Copilot's hook-registration JSON (next rule) — that is a code
|
||||
// literal, not a built script, and attributing it here resolved to a
|
||||
// nonexistent `hooks/gsd-session.json`. `package.json` is excluded for the
|
||||
// nonexistent `hooks/msd-session.json`. `package.json` is excluded for the
|
||||
// same reason (the #2544 `commonjs-marker` rule below): there is no
|
||||
// `hooks/package.json` in the repo to attribute to.
|
||||
//
|
||||
@@ -414,11 +414,11 @@ const PROVENANCE_RULES = [
|
||||
// (HOOKS_WINDOWS_SHIM_SRC, src/runtime-hooks-surface.cts). The `.cmd` bytes
|
||||
// are `@ECHO OFF\r\n@SETLOCAL\r\n@<runner> <script> %*\r\n` — built from the
|
||||
// install-time interpreter token and the absolute install path, plus a
|
||||
// hardcoded literal filename (e.g. `gsd-check-update.js`) baked into that
|
||||
// hardcoded literal filename (e.g. `msd-check-update.js`) baked into that
|
||||
// same source file. The wrapped `.js` file's NAME flows into the `.cmd`
|
||||
// bytes; its CONTENT never does — see the `sources` comment below for why
|
||||
// that rules out attributing to `hooks/<name>.js`.
|
||||
pattern: /^(?!gsd-session\.json$|package\.json$).+$/,
|
||||
pattern: /^(?!msd-session\.json$|package\.json$).+$/,
|
||||
// `package.json` (the CommonJS marker) is excluded here and owned by the
|
||||
// dedicated `commonjs-marker` rule below. #2717 attributed it inside THIS
|
||||
// rule, routing it to HOOKS_WINDOWS_SHIM_SRC because at that point
|
||||
@@ -447,11 +447,11 @@ const PROVENANCE_RULES = [
|
||||
{
|
||||
id: 'commonjs-marker',
|
||||
kind: 'code-derived',
|
||||
// Every root GSD stages its own `.js` files into and therefore pins to
|
||||
// Every root MSD stages its own `.js` files into and therefore pins to
|
||||
// CommonJS: the hooks roots, plus the native plugin/extension dirs.
|
||||
roots: [...HOOKS_ROOTS, 'plugins', 'extensions'],
|
||||
// #2544: a `{"type":"commonjs"}` module-type marker, written as a code
|
||||
// literal so Node's ancestor walk resolves GSD's staged `.js` files as
|
||||
// literal so Node's ancestor walk resolves MSD's staged `.js` files as
|
||||
// CommonJS under an ambient `"type": "module"`. Like the Copilot
|
||||
// registration JSON above it is emitted, never built — there is no
|
||||
// `hooks/package.json` or `plugins/package.json` in the repo, so the
|
||||
@@ -497,12 +497,12 @@ const PROVENANCE_RULES = [
|
||||
},
|
||||
{
|
||||
// #3023: pi renames the shared hooks bundle's staged directory from the
|
||||
// default `hooks/` to `gsd-hooks/` (hostBehaviors.sharedHooksDirName,
|
||||
// default `hooks/` to `msd-hooks/` (hostBehaviors.sharedHooksDirName,
|
||||
// bin/install.js's resolveSharedHooksDirName). Same family as `hooks-built`
|
||||
// above (built from hooks/ via scripts/build-hooks.js), staged under a
|
||||
// different root for exactly one runtime — a dedicated, `runtimes`-scoped
|
||||
// rule keeps that pi-only rename from ever being able to shadow another
|
||||
// host's `(rel, runtime)` pair, rather than folding 'gsd-hooks' into the
|
||||
// host's `(rel, runtime)` pair, rather than folding 'msd-hooks' into the
|
||||
// shared HOOKS_ROOTS list `hooks-built`/`commonjs-marker` both key off.
|
||||
// `package.json` (the CommonJS marker) is excluded here and owned by the
|
||||
// dedicated `pi-shared-hooks-commonjs-marker` rule below, mirroring how
|
||||
@@ -510,19 +510,19 @@ const PROVENANCE_RULES = [
|
||||
id: 'pi-shared-hooks-built',
|
||||
kind: 'derived',
|
||||
runtimes: new Set(['pi']),
|
||||
roots: ['gsd-hooks'],
|
||||
roots: ['msd-hooks'],
|
||||
pattern: /^(?!package\.json$).+$/,
|
||||
sources: (m) => [`hooks/${m[0]}`],
|
||||
},
|
||||
{
|
||||
// Companion to `pi-shared-hooks-built`: the CommonJS-mode marker written
|
||||
// into pi's renamed `gsd-hooks/` root by the same installSharedHooksBundle
|
||||
// into pi's renamed `msd-hooks/` root by the same installSharedHooksBundle
|
||||
// call the generic `commonjs-marker` rule attributes for the `hooks/`
|
||||
// family. Kept as its own pi-scoped rule for the same reason as above.
|
||||
id: 'pi-shared-hooks-commonjs-marker',
|
||||
kind: 'code-derived',
|
||||
runtimes: new Set(['pi']),
|
||||
roots: ['gsd-hooks'],
|
||||
roots: ['msd-hooks'],
|
||||
pattern: /^package\.json$/,
|
||||
sources: () => [COMMONJS_MARKER_SRC, INSTALLER_SRC],
|
||||
},
|
||||
@@ -534,11 +534,11 @@ const PROVENANCE_RULES = [
|
||||
// by HOOK_CONFIG_FILES because they embed a platform-varying node-runner
|
||||
// command), this one is platform-stable and stays in the manifest
|
||||
// (src/runtime-hooks-surface.cts:73,89).
|
||||
pattern: /^gsd-session\.json$/,
|
||||
pattern: /^msd-session\.json$/,
|
||||
sources: () => [CLINE_BODY_SRC],
|
||||
},
|
||||
|
||||
// ── Skill / command surfaces — all convert from commands/gsd/*.md ──────────
|
||||
// ── Skill / command surfaces — all convert from commands/msd/*.md ──────────
|
||||
{
|
||||
id: 'skills-from-commands',
|
||||
kind: 'rewrite',
|
||||
@@ -577,7 +577,7 @@ const PROVENANCE_RULES = [
|
||||
id: 'flat-commands-from-commands',
|
||||
kind: 'rewrite',
|
||||
roots: ['commands', 'command'],
|
||||
pattern: /^gsd-([^/]+)\.md$/,
|
||||
pattern: /^msd-([^/]+)\.md$/,
|
||||
sources: (m) => [`${COMMANDS_SRC}/${m[1]}.md`],
|
||||
// #4482: OpenCode command bodies pass through its command converter.
|
||||
// #4002: zcode command bodies pass through _applyRuntimeRewrites with
|
||||
@@ -596,7 +596,7 @@ const PROVENANCE_RULES = [
|
||||
roots: ['plugins', 'extensions'],
|
||||
pattern: /^[^/]+\.(js|cjs|mjs)$/,
|
||||
// Source is per-runtime (opencode -> .opencode/…, kilo -> .kilo/…,
|
||||
// pi -> pi/gsd.cjs), so attribution is a function of (rel, runtime).
|
||||
// pi -> pi/msd.cjs), so attribution is a function of (rel, runtime).
|
||||
sources: (m, ctx) => {
|
||||
const np = nativePluginDescriptor(ctx.runtime);
|
||||
if (!np || !np.source) {
|
||||
@@ -616,15 +616,15 @@ const PROVENANCE_RULES = [
|
||||
id: 'cline-rules-code-derived',
|
||||
kind: 'code-derived',
|
||||
roots: ['.clinerules'],
|
||||
pattern: /^(gsd\.md|hooks\/PreToolUse)$/,
|
||||
pattern: /^(msd\.md|hooks\/PreToolUse)$/,
|
||||
sources: () => [CLINE_BODY_SRC],
|
||||
},
|
||||
// #3547 removed `agents-md-code-derived` (roots: ['.agents'],
|
||||
// ^AGENTS\.md$) and `synthesized-gsd-defaults` (^\.gsd/defaults\.json$):
|
||||
// ^AGENTS\.md$) and `synthesized-msd-defaults` (^\.msd/defaults\.json$):
|
||||
// both paths only appeared in a manifest while the harness collapsed
|
||||
// configDir onto the sandbox HOME, walking HOME-level siblings
|
||||
// (cline's ~/.agents/AGENTS.md, every non-Claude runtime's
|
||||
// ~/.gsd/defaults.json). With the harness installing into each runtime's
|
||||
// ~/.msd/defaults.json). With the harness installing into each runtime's
|
||||
// real global subdirectory those files sit outside the walked configDir,
|
||||
// the rules matched nothing, and the totality guard's dead-rule arm fired
|
||||
// — exactly as designed. The files are still written, still covered by the
|
||||
@@ -633,7 +633,7 @@ const PROVENANCE_RULES = [
|
||||
{
|
||||
id: 'hermes-category-description',
|
||||
kind: 'code-derived',
|
||||
roots: ['skills/gsd'],
|
||||
roots: ['skills/msd'],
|
||||
pattern: /^DESCRIPTION\.md$/,
|
||||
sources: () => [INSTALLER_SRC],
|
||||
},
|
||||
@@ -645,7 +645,7 @@ const PROVENANCE_RULES = [
|
||||
// (src/runtime-artifact-layout.cts:303), and the YAML additionally enumerates
|
||||
// every staged subagent — so adding or removing an agents/*.md legitimately
|
||||
// moves this file too. Both sources are declared.
|
||||
pattern: /^gsd\.(yaml|md)$/,
|
||||
pattern: /^msd\.(yaml|md)$/,
|
||||
sources: () => [KIMI_ROOT_AGENT_SRC, 'agents/'],
|
||||
},
|
||||
|
||||
@@ -658,7 +658,7 @@ const PROVENANCE_RULES = [
|
||||
// `{"type":"commonjs"}` CommonJS-mode marker as the root one, written into
|
||||
// each Kimi product's separate hooks root (installSharedHooksBundle; the
|
||||
// per-runtime root split is #2755).
|
||||
pattern: /^(\.gsd-profile|package\.json|\.kimi(-code)?\/package\.json|gsd-core\/VERSION|gsd-core\/\.gsd-runtime)$/,
|
||||
pattern: /^(\.msd-profile|package\.json|\.kimi(-code)?\/package\.json|msd-core\/VERSION|msd-core\/\.msd-runtime)$/,
|
||||
sources: () => [],
|
||||
},
|
||||
{
|
||||
@@ -675,8 +675,8 @@ const PROVENANCE_RULES = [
|
||||
/**
|
||||
* Reject an emitted key that could escape the repo once turned into a source path.
|
||||
*
|
||||
* Two rules (`gsd-core-verbatim`, `scripts-verbatim`) capture a whole tail with
|
||||
* `.+` rather than `[^/]+`, so a key like `gsd-core/workflows/../../../etc/passwd`
|
||||
* Two rules (`msd-core-verbatim`, `scripts-verbatim`) capture a whole tail with
|
||||
* `.+` rather than `[^/]+`, so a key like `msd-core/workflows/../../../etc/passwd`
|
||||
* would otherwise produce a source path that `path.join(REPO_ROOT, src)` resolves
|
||||
* OUTSIDE the repo. Nothing reachable today exploits it — real manifest keys come
|
||||
* from installer output and the only consumer is an `fs.existsSync` probe — but
|
||||
|
||||
Reference in New Issue
Block a user