Skip to content

A machine with both installs silently runs the older one: PATH wins over CLAUDE_PLUGIN_ROOT #483

Description

@MongLong0214

Found running RELEASE-GATE.md §4 against a fresh clone during the 0.7.0 release.

Reproduction

Fresh clone of a 0.7.0 tree, on a machine with a 0.6.0 CLI install on PATH:

$ node dist/commitlore.mjs --version
0.7.0

$ CLAUDE_PLUGIN_ROOT="$PWD" sh scripts/commitlore-run.sh --version
0.6.0

The plugin entry point runs a different build than the plugin it was given.

Why

scripts/commitlore-run.sh resolves in this order:

  1. commitlore on PATH
  2. $CLAUDE_PLUGIN_ROOT/dist/commitlore.mjs
  3. $CLAUDE_PLUGIN_ROOT/dist/cli.js

PATH wins, and the script says why: the installer's wrapper execs node itself, so it runs without this script having to find node — which is a real advantage on the hook hot path, where a missing node means no context at all.

The ordering is defensible. Its silence is not. A user who installed the CLI once and later added the plugin gets the CLI's version forever, with nothing saying so.

This is #433's shape, inverted

#433 was the plugin cache pinned three releases behind the repository. This is the mirror image: the plugin is current and the thing it actually executes is stale. Same user-visible outcome — a fix that shipped does not reach the person who installed it.

What the release gate misses

§4 says:

| plugin entry point resolves | CLAUDE_PLUGIN_ROOT=<clone> scripts/commitlore-run.sh --version | exit 0 |

It passed. It exits 0 while reporting the wrong version, because the check asks whether something resolved, not whether the right thing did.

What doctor could have caught, and why it did not here

inject-version exists for exactly this comparison. On the fresh clone it reported:

skipped  PreToolUse hook version — no installed hook to compare against 0.7.0

Correct — the clone has no installed hook — but it means the check cannot see this case in the shape a release gate exercises it.

Options, none chosen here

  • Make the gate assert the version matches the clone's, not merely exit 0.
  • Have commitlore-run.sh prefer CLAUDE_PLUGIN_ROOT when it is set, on the grounds that an explicitly-passed root is a stronger signal than PATH. The node-resolution advantage that motivated the current order would need re-examining.
  • Leave the order and make the mismatch loud: the run script already writes to stderr on failure, and a version disagreement is a diagnosable condition.

The third is the smallest and probably right, but it belongs in a decision rather than a patch: ADR-0011 is what makes dist/ shipping in the repository the whole installation, and this touches how that interacts with the installer.

Not a 0.7.0 blocker

§4's stated pass condition is met. Filed rather than fixed in the release, because changing hook resolution between a CI pass and a tag is the shape of change this project has learned to refuse.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions