# 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](https://github.com/open-gsd/gsd-core/issues/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: ```text 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 ```bash msd-tools runtime-identity ``` A healthy MSD runtime prints: ```json { "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](#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](#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: ```bash 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: ```bash npm uninstall -g get-shit-done-cc ``` If you need both installed, put this package's bin directory first on `PATH`: ```bash 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: ```bash 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](https://github.com/open-gsd/gsd-core/issues/381)). Upgrade: ```bash npm install -g @golem15/msd-core@latest ``` Confirm the binary is now present: ```bash 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: ```bash 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: ```bash 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. ## Related - [Runtime identity](../FEATURES.md#168-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`](../COMMANDS.md#runtime-identity) — the verb's exact output - [#3129](https://github.com/open-gsd/gsd-core/issues/3129) — the incident this prevents