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

@@ -10,7 +10,7 @@
* epic #1267; callers import resolvers from model-resolver.cjs directly.
*
* Dependencies (leaf modules only):
* - node:fs / node:path (read the per-install .gsd-runtime marker + project config for the #2297 omit gate)
* - node:fs / node:path (read the per-install .msd-runtime marker + project config for the #2297 omit gate)
* - ./runtime-name-policy.cjs (resolveRuntimeNameFromCandidates — canonicalize the active runtime)
* - ./planning-workspace.cjs (planningDir — workstream/project-aware project-config path)
* - ./config-loader.cjs (loadConfig)
@@ -48,18 +48,18 @@ const { planningDir } = planningWorkspaceMod;
// ─── #2297: per-install runtime identity for the resolve_model_ids:"omit" gate ─
//
// The installer writes `resolve_model_ids:"omit"` into the SHARED
// ~/.gsd/defaults.json for every runtime that lacks native model aliases (#1156).
// ~/.msd/defaults.json for every runtime that lacks native model aliases (#1156).
// Because that file is machine-wide, a non-Claude install would otherwise poison
// a Claude no-project resolution into returning '' — silently defeating Claude's
// adaptive tier aliases. The "omit" must therefore apply only when a runtime that
// genuinely lacks native aliases is the one resolving.
//
// In a no-project session there is no `.planning/config.json` (so config.runtime
// is null) and GSD_RUNTIME is not exported by gsd-core, so the only reliable
// is null) and MSD_RUNTIME is not exported by msd-core, so the only reliable
// current-runtime signal is the per-install marker the installer co-locates next
// to VERSION at <install>/gsd-core/.gsd-runtime (this file's dir is
// <install>/gsd-core/bin/lib). Precedence for the gate: project config.runtime →
// GSD_RUNTIME env (manual/CI override + test seam) → install marker → 'claude'.
// to VERSION at <install>/msd-core/.msd-runtime (this file's dir is
// <install>/msd-core/bin/lib). Precedence for the gate: project config.runtime →
// MSD_RUNTIME env (manual/CI override + test seam) → install marker → 'claude'.
//
// `claude` is currently the ONLY runtime with nativeModelAliases:true; a
// registry-parity test guards this set so a future alias-capable runtime fails
@@ -76,11 +76,11 @@ const RUNTIMES_WITH_NATIVE_ALIASES: ReadonlySet<string> = new Set(['claude']);
// The runtime whose install is actually resolving, canonicalized so an alias or
// case variant (e.g. "claude-code"/"Claude") cannot defeat the native-alias
// check below (#2297 review). Precedence mirrors resolveRuntime()
// (runtime-slash.cts): GSD_RUNTIME env → project config.runtime → per-install
// .gsd-runtime marker → 'claude'.
// (runtime-slash.cts): MSD_RUNTIME env → project config.runtime → per-install
// .msd-runtime marker → 'claude'.
function resolveActiveRuntime(config: Record<string, unknown>): string {
return resolveRuntimeNameFromCandidates(
process.env['GSD_RUNTIME'],
process.env['MSD_RUNTIME'],
config['runtime'],
readInstallRuntimeMarker(),
) || 'claude';
@@ -88,7 +88,7 @@ function resolveActiveRuntime(config: Record<string, unknown>): string {
// Did the PROJECT's own config (root `.planning/config.json` or the active
// workstream/project override) explicitly set resolve_model_ids to "omit"?
// Project config takes precedence over the shared ~/.gsd/defaults.json (#2297
// Project config takes precedence over the shared ~/.msd/defaults.json (#2297
// out-of-scope guard + #2517 finding #4): an explicit project "omit" is honored
// regardless of runtime, whereas an "omit" that came only from the global
// defaults is ignored by native-alias runtimes. Workstream/project-scope aware
@@ -153,7 +153,7 @@ function _resolveRuntimeTier(config: Record<string, unknown>, tier: string): Tie
return resolveTierEntry({
// #4505/#4495: TIER SELECTION follows the runtime that is actually
// resolving, not whatever the config file happens to say. `config.runtime`
// is frequently absent (the runtime is normally known from GSD_RUNTIME or
// is frequently absent (the runtime is normally known from MSD_RUNTIME or
// the per-install marker), and reading it raw made
// `model_profile_overrides.<runtime>.<tier>` silently inert for every
// install that did not also write the key by hand.
@@ -183,7 +183,7 @@ function _resolveRuntimeTier(config: Record<string, unknown>, tier: string): Tie
* `config['runtime']` and recorded that the value policy "must key off the
* config the operator wrote, NOT resolveActiveRuntime". That reading turned out
* to defeat #4192's own stated principle — that an explicit pin must not be
* silently UNPINNED. With `config.runtime` absent and GSD_RUNTIME=opencode, the
* silently UNPINNED. With `config.runtime` absent and MSD_RUNTIME=opencode, the
* config-keyed read treated the session as claude and collapsed an explicit
* `claude-opus-4-8` pin to the bare alias `opus`, which is a Claude-only token
* the actual runtime cannot spawn. The runtime is now the ACTIVE one, so the
@@ -233,7 +233,7 @@ function resolveClaudeTierOverrideModel(
}
// Reverse of the Claude tier-default IDs, plus the Fable alias which Claude
// Code's Agent tool accepts but which is not a GSD model-profile tier (#1133).
// Code's Agent tool accepts but which is not a MSD model-profile tier (#1133).
const CLAUDE_POLICY_ID_TO_ALIAS: Record<string, string> = {
...Object.fromEntries(
Object.entries(MODEL_ALIAS_MAP)
@@ -254,7 +254,7 @@ function warnModelPolicyUnmappable(agentType: string, policyModel: string, tier:
_modelPolicyUnmappableWarned.add(key);
// MUST go to stderr — resolve-model's JSON result is parsed from stdout.
process.stderr.write(
`gsd: warning — model_policy resolved "${policyModel}" for ${agentType}, ` +
`msd: warning — model_policy resolved "${policyModel}" for ${agentType}, ` +
`but it has no Claude agent alias; using "${tier}" instead.\n`,
);
}
@@ -278,7 +278,7 @@ function warnModelOverrideUnmappable(agentType: string, overrideValue: string):
// model's JSON result is parsed from stdout.
const safe = overrideValue.length > 64 ? overrideValue.slice(0, 64) + '…' : overrideValue;
process.stderr.write(
`gsd: warning — model_overrides value "${safe}" for ${agentType} is a fully-qualified ` +
`msd: warning — model_overrides value "${safe}" for ${agentType} is a fully-qualified ` +
`Claude model ID with no tier alias; passing it through verbatim. Claude Code setups ` +
`whose Agent tool accepts only tier aliases will not honor it. (#4192)\n`,
);
@@ -306,7 +306,7 @@ function _resetModelOverrideWarningCacheForTests(): void {
* for, the exact "profile can misrepresent what actually runs" defect #4192
* files. The documented contract ("any fully-qualified model ID",
* docs/CONFIGURATION.md § Per-Agent Overrides,
* gsd-core/references/model-profiles.md § Per-Agent Overrides) is restored:
* msd-core/references/model-profiles.md § Per-Agent Overrides) is restored:
* the pin is resolved as configured. Values that DO map to a current tier
* alias still collapse to that alias — byte-equivalent resolution, the #2041
* protection preserved — and a mappable pin never warns.
@@ -320,7 +320,7 @@ function mapClaudeOverrideForRuntime(
override: string,
// The ACTIVE runtime (#4505). Previously the raw `config['runtime']`, which
// made an explicit claude pin collapse to a bare alias whenever the runtime
// was declared via GSD_RUNTIME or the install marker rather than the config —
// was declared via MSD_RUNTIME or the install marker rather than the config —
// handing a Claude-only token to a runtime that cannot spawn it.
activeRuntime: string | null | undefined,
agentType: string,
@@ -400,7 +400,7 @@ function resolveModelPolicy(policy: Record<string, unknown> | null | undefined,
* #2229 — the profile/phase-type tier for (config, agentType).
*
* Extracted verbatim from resolveModelInternal's step 2 so the same expression can
* answer "which tier did GSD resolve?" without also resolving a model id. The
* answer "which tier did MSD resolve?" without also resolving a model id. The
* extraction is behaviour-preserving by construction: resolveModelInternal calls
* straight back into it.
*
@@ -438,7 +438,7 @@ function computeProfileTier(config: Record<string, unknown>, agentType: string):
/**
* #2229 — the effective model TIER for (config, agentType), as a signal a workflow can
* read: `gsd_run query resolve-model <agent> --pick tier`.
* read: `msd_run query resolve-model <agent> --pick tier`.
*
* Why this is not just "look at the resolved model": on every runtime the installer
* configures with `resolve_model_ids: "omit"` — which is every non-Claude runtime, see
@@ -561,7 +561,7 @@ function resolveModelInternal(cwd: string, agentType: string): string {
// question — which tier map to read, which value policy applies — now uses
// the active runtime (#4505).
const configRuntime = config['runtime'] as string | null | undefined;
// #4505/#4495: GSD_RUNTIME -> config.runtime -> per-install marker -> 'claude'.
// #4505/#4495: MSD_RUNTIME -> config.runtime -> per-install marker -> 'claude'.
// Never undefined, so the "no runtime declared anywhere" case still resolves
// 'claude' and step 3's deliberate claude skip (#1156/#2297/#4192) is
// unchanged for every existing install.
@@ -605,7 +605,7 @@ function resolveModelInternal(cwd: string, agentType: string): string {
// runtime in the project config outranks an omit.
// #4717 (user-sanctioned decision a — supersedes #2297 acceptance #4):
// a DETECTED runtime now constitutes that opt-in too. The identity
// fill in config-loader materializes GSD_RUNTIME / the per-install
// fill in config-loader materializes MSD_RUNTIME / the per-install
// marker into `config.runtime` when it is empty, so a genuinely
// installed non-Claude runtime resolves its own tier map instead of
// the omit's "". The shared "omit" remains a Claude protection:
@@ -643,9 +643,9 @@ function resolveModelInternal(cwd: string, agentType: string): string {
// PROJECT explicitly set it (user intent — project config wins, #2517 finding
// #4) OR when the active runtime genuinely lacks native model aliases. Only a
// native-alias runtime (Claude) ignores an "omit" that came solely from the
// SHARED ~/.gsd/defaults.json — the #2297 poisoning fix — and falls through to
// its tier aliases below. Active runtime: GSD_RUNTIME → config.runtime → the
// per-install .gsd-runtime marker → 'claude' (canonicalized).
// SHARED ~/.msd/defaults.json — the #2297 poisoning fix — and falls through to
// its tier aliases below. Active runtime: MSD_RUNTIME → config.runtime → the
// per-install .msd-runtime marker → 'claude' (canonicalized).
// NOTE: a non-Claude runtime that HAS a populated runtime-tier map already
// returned its own model id at step 3 above, before this gate — for those the
// explicit-project-omit honoring here is moot (step 3 wins, by #2517 design).