Files
msd-core/docs/how-to/diagnose-a-foreign-msd-tools.md
Jakub Zych a9a7a328e6 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.
2026-10-06 01:47:40 +02:00

6.4 KiB

How to diagnose which msd-tools is running

Two packages publish a binary called msd-tools: this one, and the predecessor get-shit-done-cc. They answer some of the same verb names with different behavior. This guide tells you which one you have and how to fix a bad resolution.

Use it when:

  • a workflow behaves unlike its documentation,
  • a workflow stops with msd-tools.cjs not found … and no identity-proving msd_run is on PATH,
  • or you simply want to confirm which tool a project is running against.

Why this matters

#3129 is the worked example. phases.clear archives your phase directories under this package and deletes them under the predecessor. Both print success-shaped output, and .planning/ is gitignored by default, so the difference is invisible until the directories are gone.

Shipped workflows no longer resolve msd-tools from PATH at all — they resolve msd_run, which only this package publishes. That closes the path that caused #3129. The resolver prefers its path-based branches — a project-local install, then a runtime config directory — and only falls back to a msd_run found on PATH when that binary proves it is @golem15/msd-core (#4834): a foreign or too-old msd_run on PATH is passed over, not used with a warning. The path-based branches are still checked by assertion after resolution: the launcher probes whatever it resolved and warns when the tool cannot prove it is @golem15/msd-core.

If you got here from that warning, it looks like this:

WARNING: "/some/path/msd-tools.cjs" did not prove it is @golem15/msd-core - it is either a
different package or an @golem15/msd-core older than the runtime-identity verb.

The two causes need opposite fixes, and the warning cannot tell them apart — the sections below can. The steps that follow are for confirming your setup and for fixing the cases the resolver refuses outright.

Ask the tool what it is

msd-tools runtime-identity

A healthy MSD runtime prints:

{
  "packageName": "@golem15/msd-core",
  "version": "1.12.0"
}

Three other outcomes are possible, and they mean different things:

What you see What it means
The JSON above This is our tool. Nothing to do.
A usage screen mentioning msd-sdk, exit 1 This is the predecessor's binary. See A different package owns it.
Error: Unknown command: runtime-identity This is our tool, but older than the verb. See It is an old msd-core.
Nothing runs at all Nothing named msd-tools is on your PATH. That is fine — workflows do not need it.

Then find out which package owns the file:

readlink -f "$(command -v msd-tools)"

A different package owns it

The resolved path contains get-shit-done-cc, or the identity probe printed a msd-sdk usage screen.

Workflows will not reach it — they resolve msd_run, which that package does not publish — so this is no longer dangerous. It is still worth resolving, because you invoking msd-tools by hand will reach the wrong tool.

If you no longer use the predecessor:

npm uninstall -g get-shit-done-cc

If you need both installed, put this package's bin directory first on PATH:

export PATH="$(npm prefix -g)/bin:$PATH"

Re-run msd-tools runtime-identity and confirm it reports @golem15/msd-core.

It is an old msd-core

The resolved path is inside @golem15/msd-core, but runtime-identity is not a known command. That version predates the verb. Nothing is wrong beyond being out of date:

npm install -g @golem15/msd-core@latest

Since #4834, a copy this old on your PATH can no longer be picked up by a workflow's launcher — the resolver requires the identity proof the verb provides, so the global copy is passed over in favor of a project-local or config-directory install. You can still reach it by hand, which is why upgrading matters.

A workflow says msd_run is not on PATH

The resolver found nothing it could use: no project-local or config-directory install matched, and either nothing named msd_run is on PATH or the only entry could not prove it is @golem15/msd-core. It stops rather than guessing — falling back to an arbitrary msd-tools is exactly the behavior that caused #3129.

This is expected in one specific case: an installation old enough to predate the msd_run binary (#381). Upgrade:

npm install -g @golem15/msd-core@latest

Confirm the binary is now present:

command -v msd_run

If you deliberately pin an old version, invoke workflows from a project or config directory where the path-based resolution branches apply — a local install under msd-core/bin/msd-tools.cjs, or your runtime's config directory — rather than relying on PATH.

Tell "not installed" apart from "wrong one installed"

These two look similar and have opposite fixes:

command -v msd_run   || echo "msd_run:   NOT FOUND"
command -v msd-tools || echo "msd-tools: NOT FOUND"
  • msd_run found — workflows resolve correctly, whatever msd-tools says.
  • msd_run missing, msd-tools present — the likely collision case. Run readlink -f "$(command -v msd-tools)" and follow the matching section above.
  • Both missing — nothing is installed globally; workflows will use a local or config-directory install if one exists.

Check the assertion's own verdict

Inside a workflow shell — that is, after the launcher preamble has run — the outcome is a variable, not just a message:

printf '%s\n' "$MSD_IDENTITY_STATUS"
  • ok — the resolved tool proved it is @golem15/msd-core. Nothing to do.
  • unverified — it did not. Work the two sections above, in that order: rule out a foreign package first, then upgrade an old one.

The warn phase does not stop the workflow. A later release turns unverified into a refusal, so treat it as something to fix now rather than something to live with.

  • Runtime identity — why the launcher resolves msd_run, and why it also asserts identity on the branches that resolution alone cannot make safe
  • runtime-identity — the verb's exact output
  • #3129 — the incident this prevents