Files
msd-core/docs/how-to/diagnose-a-foreign-gsd-tools.md
Tom Boucher b956bb7c67 fix(#4834): gate the launcher PATH arm on runtime identity and prefer config-home installs (#4902)
* test(#4834): failing-first launcher hijack regressions

* fix(#4834): gate the launcher PATH arm on runtime identity and prefer config-home installs

A gsd_run on PATH that cannot prove it is @opengsd/gsd-core (a foreign package, or a
release older than the runtime-identity verb) is no longer accepted by the launcher
snippet's PATH arm; resolution falls through to the hard error when no path-based
candidate matches. The runtime-config-home arm now precedes the PATH arm, restoring
the documented prefer-local-over-PATH order, so an installer-managed install wins
even against a genuine global. The 16-home probe list is factored into _gsd_homes()
and the identity gate into _gsd_id_ok(), keeping the per-copy delta at +141 bytes.

The files whose frozen ceilings had no headroom (gsd-executor, gsd-plan-checker,
gsd-verifier, gsd-planner, execute-phase, execute-plan) now load the resolver by
@-include from gsd-core/references/gsd-run-resolver.md (the onboard.md pattern)
instead of carrying an inline copy. Propagated to all other inlined workflow/agent
copies via scripts/sync-runtime-launcher.cjs; the resolver reference re-copied
byte-equal (parity B2); the hard-error text, docs/how-to/diagnose-a-foreign-gsd-tools.md,
and the CONTEXT.md launcher predicate updated to match (#4834); the quick-batch row-48
guard gains the canonical-preamble sweep carve-out (#4834, per its own #3730/#2529
precedents); the compact-content benchmark baseline regenerated.

Emitted-Drift-Ack-Growth: add-backlog.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: add-phase.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: add-tests.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: add-todo.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: ai-integration-phase.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: audit-fix.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: audit-milestone.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: audit-uat.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: autonomous.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: check-todos.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: cleanup.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: code-review-fix.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: code-review.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: complete-milestone.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: debug.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: diagnose-issues.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: discuss-phase-assumptions.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: discuss-phase.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: do.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: docs-update.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: edit-phase.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: eval-review.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: explore.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: extract-learnings.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: fast.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: forensics.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: graduation.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: gsd-code-fixer.compact.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: gsd-code-fixer.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: gsd-debug-session-manager.compact.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: gsd-debug-session-manager.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: gsd-debugger.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: gsd-eval-auditor.compact.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: gsd-eval-auditor.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: gsd-intel-updater.compact.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: gsd-intel-updater.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: gsd-phase-researcher.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: gsd-project-researcher.compact.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: gsd-project-researcher.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: gsd-research-synthesizer.compact.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: gsd-research-synthesizer.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: gsd-ui-researcher.compact.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: gsd-ui-researcher.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: health.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: import.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: inbox.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: ingest-docs.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: insert-phase.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: list-seeds.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: list-workspaces.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: manager.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: map-codebase.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: milestone-summary.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: mvp-phase.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: new-milestone.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: new-project.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: new-workspace.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: next.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: pause-work.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: plan-phase.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: plan-review-convergence.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: plant-seed.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: pr-branch.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: profile-user.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: progress.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: quick-batch.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: quick.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: remove-phase.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: remove-workspace.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: resume-project.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: review.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: scan.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: secure-phase.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: settings-advanced.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: settings-integrations.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: settings.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: ship.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: sketch-wrap-up.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: sketch.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: smart-entry.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: spec-phase.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: spike-wrap-up.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: spike.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: stats.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: sync-skills.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: thread.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: transition.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: ui-phase.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: ui-review.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: ultraplan-phase.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: undo.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: validate-phase.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)
Emitted-Drift-Ack-Growth: verify-work.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834)

* docs(#4834): backfill the changeset PR number

* test(#4834): regenerate the compact-content benchmark baseline after the rebase

---------

Co-authored-by: sim <sim@local>
2026-09-21 02:27:36 -04:00

169 lines
6.4 KiB
Markdown

# How to diagnose which `gsd-tools` is running
Two packages publish a binary called `gsd-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 `gsd-tools.cjs not found … and no identity-proving gsd_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 `gsd-tools` from `PATH` at all — they resolve `gsd_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 `gsd_run` found on `PATH` when that binary proves it is
`@opengsd/gsd-core` (#4834): a foreign or too-old `gsd_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 `@opengsd/gsd-core`.
If you got here from that warning, it looks like this:
```text
WARNING: "/some/path/gsd-tools.cjs" did not prove it is @opengsd/gsd-core - it is either a
different package or an @opengsd/gsd-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
gsd-tools runtime-identity
```
A healthy GSD runtime prints:
```json
{
"packageName": "@opengsd/gsd-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 `gsd-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 gsd-core](#it-is-an-old-gsd-core). |
| Nothing runs at all | Nothing named `gsd-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 gsd-tools)"
```
## A different package owns it
The resolved path contains `get-shit-done-cc`, or the identity probe printed a `gsd-sdk`
usage screen.
Workflows will not reach it — they resolve `gsd_run`, which that package does not publish —
so this is no longer dangerous. It is still worth resolving, because *you* invoking
`gsd-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 `gsd-tools runtime-identity` and confirm it reports `@opengsd/gsd-core`.
## It is an old gsd-core
The resolved path is inside `@opengsd/gsd-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 @opengsd/gsd-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 `gsd_run is not on PATH`
The resolver found nothing it could use: no project-local or config-directory install
matched, and either nothing named `gsd_run` is on `PATH` or the only entry could not prove
it is `@opengsd/gsd-core`. It stops rather than guessing — falling back to an arbitrary
`gsd-tools` is exactly the behavior that caused #3129.
This is expected in one specific case: an installation old enough to predate the `gsd_run`
binary ([#381](https://github.com/open-gsd/gsd-core/issues/381)). Upgrade:
```bash
npm install -g @opengsd/gsd-core@latest
```
Confirm the binary is now present:
```bash
command -v gsd_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
`gsd-core/bin/gsd-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 gsd_run || echo "gsd_run: NOT FOUND"
command -v gsd-tools || echo "gsd-tools: NOT FOUND"
```
- **`gsd_run` found** — workflows resolve correctly, whatever `gsd-tools` says.
- **`gsd_run` missing, `gsd-tools` present** — the likely collision case. Run
`readlink -f "$(command -v gsd-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' "$GSD_IDENTITY_STATUS"
```
- `ok` — the resolved tool proved it is `@opengsd/gsd-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 `gsd_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