← back to Cli Printing Press
fix(skills): emit PRINTING_PRESS_BIN marker so later phases survive PATH non-inheritance (#1399)
2698690ee63c41016fa0f9f86470631ee55e0a8b · 2026-05-14 12:08:48 -0700 · Trevin Chow
* fix(skills): emit PRINTING_PRESS_BIN marker so later phases survive PATH non-inheritance
The Printing Press skills' preflight contracts did `export PATH=...` to
prefer the local repo build, but `export` only affects the single Bash
tool call it runs in. Subsequent Bash tool calls open a fresh shell where
the user's default PATH resolves bare `printing-press` to whatever was
last `go install`-ed globally, silently shadowing the local build the
preflight just chose.
Resolve the absolute binary path in preflight and emit it as a captured
`PRINTING_PRESS_BIN=<abs-path>` marker the agent substitutes into every
later invocation. Add an optional `[binary-shadow]` advisory in the main
skill that surfaces version drift between the local build and a global
on disk. Apply the same minimal change to catalog/publish/score sibling
skills, which share the identical defective pattern.
Document the marker and absolute-path rule in references/setup-checks.md
as section 6 (unconditional, applies every run).
Closes #1259
* fix(skills): capture PRINTING_PRESS_BIN in setup-checks preamble before sections 3 and 4
The original section ordering had the version-check sections (3 min-binary-version,
4 standalone-upgrade confirmation) run before section 6 introduced the absolute-path
rule. An agent following sections in order would invoke `printing-press version --json`
through the user's default PATH for those checks, which is the exact shadow bug the
PR fixes.
Move the unconditional PRINTING_PRESS_BIN capture into a Preamble block that runs
before any numbered section, and update sections 3 and 4 to explicitly invoke
`<PRINTING_PRESS_BIN> version --json`. Section 6 now covers only the optional
`[binary-shadow]` advisory.
Surfaced by Greptile on #1399.
* fix(skills): re-resolve PRINTING_PRESS_BIN after section 4 go install
After the user accepts the standalone upgrade, `go install` writes to
`$(go env GOBIN)` or `$(go env GOPATH)/bin`, which may not be the same
path the contract captured at preflight (e.g. the pre-upgrade binary
lived at /opt/homebrew/bin/printing-press). Without re-resolution the
agent kept invoking the stale pre-upgrade binary while reporting a
successful upgrade.
Add a one-shot Bash snippet in section 4 that re-emits
`PRINTING_PRESS_BIN=<abs-path>` from `go env GOBIN/GOPATH`, falling back
to `command -v printing-press`. The agent captures the new value and
overrides the preamble capture for the rest of the run.
Surfaced by Greptile on #1399.
Files touched
M skills/printing-press-catalog/SKILL.mdM skills/printing-press-publish/SKILL.mdM skills/printing-press-score/SKILL.mdM skills/printing-press/SKILL.mdM skills/printing-press/references/setup-checks.md
Diff
commit 2698690ee63c41016fa0f9f86470631ee55e0a8b
Author: Trevin Chow <trevin@trevinchow.com>
Date: Thu May 14 12:08:48 2026 -0700
fix(skills): emit PRINTING_PRESS_BIN marker so later phases survive PATH non-inheritance (#1399)
* fix(skills): emit PRINTING_PRESS_BIN marker so later phases survive PATH non-inheritance
The Printing Press skills' preflight contracts did `export PATH=...` to
prefer the local repo build, but `export` only affects the single Bash
tool call it runs in. Subsequent Bash tool calls open a fresh shell where
the user's default PATH resolves bare `printing-press` to whatever was
last `go install`-ed globally, silently shadowing the local build the
preflight just chose.
Resolve the absolute binary path in preflight and emit it as a captured
`PRINTING_PRESS_BIN=<abs-path>` marker the agent substitutes into every
later invocation. Add an optional `[binary-shadow]` advisory in the main
skill that surfaces version drift between the local build and a global
on disk. Apply the same minimal change to catalog/publish/score sibling
skills, which share the identical defective pattern.
Document the marker and absolute-path rule in references/setup-checks.md
as section 6 (unconditional, applies every run).
Closes #1259
* fix(skills): capture PRINTING_PRESS_BIN in setup-checks preamble before sections 3 and 4
The original section ordering had the version-check sections (3 min-binary-version,
4 standalone-upgrade confirmation) run before section 6 introduced the absolute-path
rule. An agent following sections in order would invoke `printing-press version --json`
through the user's default PATH for those checks, which is the exact shadow bug the
PR fixes.
Move the unconditional PRINTING_PRESS_BIN capture into a Preamble block that runs
before any numbered section, and update sections 3 and 4 to explicitly invoke
`<PRINTING_PRESS_BIN> version --json`. Section 6 now covers only the optional
`[binary-shadow]` advisory.
Surfaced by Greptile on #1399.
* fix(skills): re-resolve PRINTING_PRESS_BIN after section 4 go install
After the user accepts the standalone upgrade, `go install` writes to
`$(go env GOBIN)` or `$(go env GOPATH)/bin`, which may not be the same
path the contract captured at preflight (e.g. the pre-upgrade binary
lived at /opt/homebrew/bin/printing-press). Without re-resolution the
agent kept invoking the stale pre-upgrade binary while reporting a
successful upgrade.
Add a one-shot Bash snippet in section 4 that re-emits
`PRINTING_PRESS_BIN=<abs-path>` from `go env GOBIN/GOPATH`, falling back
to `command -v printing-press`. The agent captures the new value and
overrides the preamble capture for the rest of the run.
Surfaced by Greptile on #1399.
---
skills/printing-press-catalog/SKILL.md | 19 +++++++++-
skills/printing-press-publish/SKILL.md | 19 +++++++++-
skills/printing-press-score/SKILL.md | 19 +++++++++-
skills/printing-press/SKILL.md | 46 ++++++++++++++++++++++--
skills/printing-press/references/setup-checks.md | 44 ++++++++++++++++++++---
5 files changed, 138 insertions(+), 9 deletions(-)
diff --git a/skills/printing-press-catalog/SKILL.md b/skills/printing-press-catalog/SKILL.md
index aaeab8f5..2432d8d4 100644
--- a/skills/printing-press-catalog/SKILL.md
+++ b/skills/printing-press-catalog/SKILL.md
@@ -46,7 +46,9 @@ _scope_dir="$(git rev-parse --show-toplevel 2>/dev/null || echo "$PWD")"
_scope_dir="$(cd "$_scope_dir" && pwd -P)"
# Prefer local build when running from inside the printing-press repo.
+_press_repo=false
if [ -x "$_scope_dir/printing-press" ] && [ -d "$_scope_dir/cmd/printing-press" ]; then
+ _press_repo=true
export PATH="$_scope_dir:$PATH"
echo "Using local build: $_scope_dir/printing-press"
elif ! command -v printing-press >/dev/null 2>&1; then
@@ -60,6 +62,19 @@ elif ! command -v printing-press >/dev/null 2>&1; then
return 1 2>/dev/null || exit 1
fi
+# Resolve and emit the absolute path the agent must use for every later
+# `printing-press` invocation. `export PATH` above only affects this one
+# Bash tool call; subsequent calls open a fresh shell and resolve bare
+# `printing-press` against the user's default PATH, where a stale global
+# can silently shadow the local build. The agent captures this marker and
+# substitutes the absolute path into every later invocation.
+if [ "$_press_repo" = "true" ]; then
+ PRINTING_PRESS_BIN="$_scope_dir/printing-press"
+else
+ PRINTING_PRESS_BIN="$(command -v printing-press 2>/dev/null || true)"
+fi
+echo "PRINTING_PRESS_BIN=$PRINTING_PRESS_BIN"
+
PRESS_BASE="$(basename "$_scope_dir" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9_-]/-/g; s/^-+//; s/-+$//')"
if [ -z "$PRESS_BASE" ]; then
PRESS_BASE="workspace"
@@ -74,7 +89,9 @@ mkdir -p "$PRESS_RUNSTATE" "$PRESS_LIBRARY"
```
<!-- PRESS_SETUP_CONTRACT_END -->
-After running the setup contract, check binary version compatibility. Read the `min-binary-version` field from this skill's YAML frontmatter. Run `printing-press version --json` and parse the version from the output. Compare it to `min-binary-version` using semver rules. If the installed binary is older than the minimum, stop immediately and tell the user: "printing-press binary vX.Y.Z is older than the minimum required vA.B.C. Run `go install github.com/mvanhorn/cli-printing-press/v4/cmd/printing-press@latest` to update."
+After running the setup contract, capture the `PRINTING_PRESS_BIN=<abs-path>` line from stdout. **Every subsequent `printing-press ...` invocation in this skill must use that absolute path** (substitute the value, not the literal `$PRINTING_PRESS_BIN` token) — `export PATH` above only affects the single Bash tool call it runs in, so later calls open a fresh shell where bare `printing-press` resolves against the user's default `PATH` and a stale global can shadow the local build.
+
+After capturing the binary path, check binary version compatibility. Read the `min-binary-version` field from this skill's YAML frontmatter. Run `<PRINTING_PRESS_BIN> version --json` and parse the version from the output. Compare it to `min-binary-version` using semver rules. If the installed binary is older than the minimum, stop immediately and tell the user: "printing-press binary vX.Y.Z is older than the minimum required vA.B.C. Run `go install github.com/mvanhorn/cli-printing-press/v4/cmd/printing-press@latest` to update."
Generated CLIs are published to `$PRESS_LIBRARY/`, not to the repo.
diff --git a/skills/printing-press-publish/SKILL.md b/skills/printing-press-publish/SKILL.md
index 6a891c31..958945c7 100644
--- a/skills/printing-press-publish/SKILL.md
+++ b/skills/printing-press-publish/SKILL.md
@@ -46,7 +46,9 @@ _scope_dir="$(git rev-parse --show-toplevel 2>/dev/null || echo "$PWD")"
_scope_dir="$(cd "$_scope_dir" && pwd -P)"
# Prefer local build when running from inside the printing-press repo.
+_press_repo=false
if [ -x "$_scope_dir/printing-press" ] && [ -d "$_scope_dir/cmd/printing-press" ]; then
+ _press_repo=true
export PATH="$_scope_dir:$PATH"
echo "Using local build: $_scope_dir/printing-press"
elif ! command -v printing-press >/dev/null 2>&1; then
@@ -60,6 +62,19 @@ elif ! command -v printing-press >/dev/null 2>&1; then
return 1 2>/dev/null || exit 1
fi
+# Resolve and emit the absolute path the agent must use for every later
+# `printing-press` invocation. `export PATH` above only affects this one
+# Bash tool call; subsequent calls open a fresh shell and resolve bare
+# `printing-press` against the user's default PATH, where a stale global
+# can silently shadow the local build. The agent captures this marker and
+# substitutes the absolute path into every later invocation.
+if [ "$_press_repo" = "true" ]; then
+ PRINTING_PRESS_BIN="$_scope_dir/printing-press"
+else
+ PRINTING_PRESS_BIN="$(command -v printing-press 2>/dev/null || true)"
+fi
+echo "PRINTING_PRESS_BIN=$PRINTING_PRESS_BIN"
+
PRESS_BASE="$(basename "$_scope_dir" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9_-]/-/g; s/^-+//; s/-+$//')"
if [ -z "$PRESS_BASE" ]; then
PRESS_BASE="workspace"
@@ -76,7 +91,9 @@ mkdir -p "$PRESS_RUNSTATE" "$PRESS_LIBRARY" "$PRESS_MANUSCRIPTS" "$PRESS_CURRENT
```
<!-- PRESS_SETUP_CONTRACT_END -->
-After running the setup contract, check binary version compatibility. Read the `min-binary-version` field from this skill's YAML frontmatter. Run `printing-press version --json` and parse the version from the output. Compare it to `min-binary-version` using semver rules. If the installed binary is older than the minimum, stop immediately and tell the user: "printing-press binary vX.Y.Z is older than the minimum required vA.B.C. Run `go install github.com/mvanhorn/cli-printing-press/v4/cmd/printing-press@latest` to update."
+After running the setup contract, capture the `PRINTING_PRESS_BIN=<abs-path>` line from stdout. **Every subsequent `printing-press ...` invocation in this skill must use that absolute path** (substitute the value, not the literal `$PRINTING_PRESS_BIN` token) — `export PATH` above only affects the single Bash tool call it runs in, so later calls open a fresh shell where bare `printing-press` resolves against the user's default `PATH` and a stale global can shadow the local build.
+
+After capturing the binary path, check binary version compatibility. Read the `min-binary-version` field from this skill's YAML frontmatter. Run `<PRINTING_PRESS_BIN> version --json` and parse the version from the output. Compare it to `min-binary-version` using semver rules. If the installed binary is older than the minimum, stop immediately and tell the user: "printing-press binary vX.Y.Z is older than the minimum required vA.B.C. Run `go install github.com/mvanhorn/cli-printing-press/v4/cmd/printing-press@latest` to update."
## Configuration
diff --git a/skills/printing-press-score/SKILL.md b/skills/printing-press-score/SKILL.md
index 3dc14556..f883361c 100644
--- a/skills/printing-press-score/SKILL.md
+++ b/skills/printing-press-score/SKILL.md
@@ -42,7 +42,9 @@ _scope_dir="$(git rev-parse --show-toplevel 2>/dev/null || echo "$PWD")"
_scope_dir="$(cd "$_scope_dir" && pwd -P)"
# Prefer local build when running from inside the printing-press repo.
+_press_repo=false
if [ -x "$_scope_dir/printing-press" ] && [ -d "$_scope_dir/cmd/printing-press" ]; then
+ _press_repo=true
export PATH="$_scope_dir:$PATH"
echo "Using local build: $_scope_dir/printing-press"
elif ! command -v printing-press >/dev/null 2>&1; then
@@ -56,6 +58,19 @@ elif ! command -v printing-press >/dev/null 2>&1; then
return 1 2>/dev/null || exit 1
fi
+# Resolve and emit the absolute path the agent must use for every later
+# `printing-press` invocation. `export PATH` above only affects this one
+# Bash tool call; subsequent calls open a fresh shell and resolve bare
+# `printing-press` against the user's default PATH, where a stale global
+# can silently shadow the local build. The agent captures this marker and
+# substitutes the absolute path into every later invocation.
+if [ "$_press_repo" = "true" ]; then
+ PRINTING_PRESS_BIN="$_scope_dir/printing-press"
+else
+ PRINTING_PRESS_BIN="$(command -v printing-press 2>/dev/null || true)"
+fi
+echo "PRINTING_PRESS_BIN=$PRINTING_PRESS_BIN"
+
PRESS_BASE="$(basename "$_scope_dir" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9_-]/-/g; s/^-+//; s/-+$//')"
if [ -z "$PRESS_BASE" ]; then
PRESS_BASE="workspace"
@@ -72,7 +87,9 @@ mkdir -p "$PRESS_RUNSTATE" "$PRESS_LIBRARY" "$PRESS_MANUSCRIPTS" "$PRESS_CURRENT
```
<!-- PRESS_SETUP_CONTRACT_END -->
-After running the setup contract, check binary version compatibility. Read the `min-binary-version` field from this skill's YAML frontmatter. Run `printing-press version --json` and parse the version from the output. Compare it to `min-binary-version` using semver rules. If the installed binary is older than the minimum, stop immediately and tell the user: "printing-press binary vX.Y.Z is older than the minimum required vA.B.C. Run `go install github.com/mvanhorn/cli-printing-press/v4/cmd/printing-press@latest` to update."
+After running the setup contract, capture the `PRINTING_PRESS_BIN=<abs-path>` line from stdout. **Every subsequent `printing-press ...` invocation in this skill must use that absolute path** (substitute the value, not the literal `$PRINTING_PRESS_BIN` token) — `export PATH` above only affects the single Bash tool call it runs in, so later calls open a fresh shell where bare `printing-press` resolves against the user's default `PATH` and a stale global can shadow the local build.
+
+After capturing the binary path, check binary version compatibility. Read the `min-binary-version` field from this skill's YAML frontmatter. Run `<PRINTING_PRESS_BIN> version --json` and parse the version from the output. Compare it to `min-binary-version` using semver rules. If the installed binary is older than the minimum, stop immediately and tell the user: "printing-press binary vX.Y.Z is older than the minimum required vA.B.C. Run `go install github.com/mvanhorn/cli-printing-press/v4/cmd/printing-press@latest` to update."
Current-run state is resolved from `$PRESS_RUNSTATE`. Published CLIs are resolved from `$PRESS_LIBRARY`. Archived manuscripts are resolved from `$PRESS_MANUSCRIPTS`.
diff --git a/skills/printing-press/SKILL.md b/skills/printing-press/SKILL.md
index 216d234a..4db82b1e 100644
--- a/skills/printing-press/SKILL.md
+++ b/skills/printing-press/SKILL.md
@@ -177,6 +177,46 @@ if ! command -v go >/dev/null 2>&1; then
return 1 2>/dev/null || exit 1
fi
+# Resolve and emit the absolute path the agent must use for every later
+# `printing-press` invocation. `export PATH` above only affects this one
+# Bash tool call; subsequent calls open a fresh shell and resolve bare
+# `printing-press` against the user's default PATH. When a global is
+# installed at a stale version, that silently shadows the local build the
+# preflight just chose. Handing the agent an absolute path eliminates the
+# shadow.
+if [ "$_press_repo" = "true" ] && [ -x "$_scope_dir/printing-press" ]; then
+ PRINTING_PRESS_BIN="$_scope_dir/printing-press"
+else
+ PRINTING_PRESS_BIN="$(command -v printing-press 2>/dev/null || true)"
+fi
+echo "PRINTING_PRESS_BIN=$PRINTING_PRESS_BIN"
+
+# Shadow detector (advisory). When a local build is in use, surface any
+# differing global so the user can see at a glance that the two binaries
+# disagree. Detect-only: the absolute path emitted above is the one the
+# agent will actually invoke; this warning does not change selection.
+if [ "$_press_repo" = "true" ] && [ -x "$_scope_dir/printing-press" ]; then
+ _global_bin=""
+ for _candidate in "$HOME/go/bin/printing-press" "/usr/local/bin/printing-press" "/opt/homebrew/bin/printing-press"; do
+ if [ -x "$_candidate" ] && [ "$_candidate" != "$_scope_dir/printing-press" ]; then
+ _global_bin="$_candidate"
+ break
+ fi
+ done
+ if [ -n "$_global_bin" ]; then
+ _local_v="$("$_scope_dir/printing-press" version --json 2>/dev/null | sed -nE 's/.*"version"[[:space:]]*:[[:space:]]*"([^"]+)".*/\1/p')"
+ _global_v="$("$_global_bin" version --json 2>/dev/null | sed -nE 's/.*"version"[[:space:]]*:[[:space:]]*"([^"]+)".*/\1/p')"
+ if [ -n "$_local_v" ] && [ -n "$_global_v" ] && [ "$_local_v" != "$_global_v" ]; then
+ echo ""
+ echo "[binary-shadow] local build v$_local_v differs from global v$_global_v at $_global_bin"
+ echo "PRESS_BIN_LOCAL_VERSION=$_local_v"
+ echo "PRESS_BIN_GLOBAL_VERSION=$_global_v"
+ echo "PRESS_BIN_GLOBAL_PATH=$_global_bin"
+ echo ""
+ fi
+ fi
+fi
+
PRESS_BASE="$(basename "$_scope_dir" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9_-]/-/g; s/^-+//; s/-+$//')"
if [ -z "$PRESS_BASE" ]; then
PRESS_BASE="workspace"
@@ -333,9 +373,11 @@ CODEX_CONSECUTIVE_FAILURES=0
```
<!-- PRESS_SETUP_CONTRACT_END -->
-**MANDATORY: Read and apply [references/setup-checks.md](references/setup-checks.md) immediately after the setup contract bash block runs, before any other action.** It handles five signals the contract emits to stdout: `[setup-error]` (refuse to run, surface the install instructions), `[repo-upgrade-available]` (interactive `AskUserQuestion` prompt + optional repo pull), the min-binary-version compatibility check (hard stop if binary is too old), `[upgrade-available]` (interactive `AskUserQuestion` prompt + optional standalone binary upgrade), and `[browser-tools-missing]` (interactive `AskUserQuestion` prompt + optional install of browser-use and/or agent-browser). Skipping the reference will cause the skill to proceed with a missing or out-of-date binary, or hit a mid-flight install prompt if browser-sniff is later needed. Do not skip.
+**MANDATORY: Read and apply [references/setup-checks.md](references/setup-checks.md) immediately after the setup contract bash block runs, before any other action.** It handles six signals the contract emits to stdout: `[setup-error]` (refuse to run, surface the install instructions), `[repo-upgrade-available]` (interactive `AskUserQuestion` prompt + optional repo pull), the min-binary-version compatibility check (hard stop if binary is too old), `[upgrade-available]` (interactive `AskUserQuestion` prompt + optional standalone binary upgrade), `[browser-tools-missing]` (interactive `AskUserQuestion` prompt + optional install of browser-use and/or agent-browser), and the `PRINTING_PRESS_BIN=<abs-path>` marker plus optional `[binary-shadow]` warning (capture the path; use it for every subsequent `printing-press` invocation). Skipping the reference will cause the skill to proceed with a missing or out-of-date binary, hit a mid-flight install prompt if browser-sniff is later needed, or invoke the wrong binary because a stale global on `PATH` shadowed the local build. Do not skip.
+
+**Absolute-path rule.** The preflight contract always emits `PRINTING_PRESS_BIN=<absolute path>` to stdout. Capture this value and substitute it (the resolved absolute path, not the literal `$PRINTING_PRESS_BIN` token) for every subsequent `printing-press ...` invocation in this skill, references, and any sub-skill you delegate to. The `export PATH=...` line inside the contract only affects the single Bash tool call it runs in; later Bash tool calls open fresh shells and resolve bare `printing-press` against the user's default `PATH`, where a stale globally-installed binary (`$HOME/go/bin/printing-press`, Homebrew copy, etc.) will silently shadow the local build the preflight just chose. Bash code examples below are written `printing-press generate ...` for readability — replace `printing-press` with the captured absolute path each time you actually run one.
-Only after preflight completes successfully (no `[setup-error]`; any `[repo-upgrade-available]`, `[upgrade-available]`, or `[browser-tools-missing]` was offered to the user) should you proceed to the Orientation & Briefing section below.
+Only after preflight completes successfully (no `[setup-error]`; any `[repo-upgrade-available]`, `[upgrade-available]`, or `[browser-tools-missing]` was offered to the user; `PRINTING_PRESS_BIN` is captured) should you proceed to the Orientation & Briefing section below.
## Orientation & Briefing
diff --git a/skills/printing-press/references/setup-checks.md b/skills/printing-press/references/setup-checks.md
index d550c511..d7214a40 100644
--- a/skills/printing-press/references/setup-checks.md
+++ b/skills/printing-press/references/setup-checks.md
@@ -1,8 +1,16 @@
# Setup Checks
-Post-contract checks the skill must run after executing the bash setup contract block in `SKILL.md`. These handle five signals the contract emits to stdout: `[setup-error]`, `[repo-upgrade-available]`, `[upgrade-available]`, `[browser-tools-missing]`, and the `min-binary-version` compatibility check.
+Post-contract checks the skill must run after executing the bash setup contract block in `SKILL.md`. These handle six signals the contract emits to stdout: `[setup-error]`, `[repo-upgrade-available]`, the `min-binary-version` compatibility check, `[upgrade-available]`, `[browser-tools-missing]`, and the always-emitted `PRINTING_PRESS_BIN=<abs-path>` marker (with optional `[binary-shadow]` advisory).
-Apply these in order. Each section is conditional — do nothing if its trigger isn't present.
+Apply these in order. The preamble below runs unconditionally; each numbered section after it is conditional — do nothing if its trigger isn't present.
+
+## Preamble: Capture the absolute binary path (unconditional)
+
+Before applying any numbered section below, capture the `PRINTING_PRESS_BIN=<absolute path to the binary>` line the contract emitted to stdout. Every `printing-press ...` invocation referenced anywhere below — including the `version --json` calls in sections 3 and 4 — must be made using that absolute path (substitute the captured value, not the literal `$PRINTING_PRESS_BIN` token). The contract's `export PATH=...` line only affects the single Bash tool call it runs in; later Bash tool calls open fresh shells where bare `printing-press` resolves against the user's default `PATH`, and a stale globally-installed binary (`$HOME/go/bin/printing-press` from an earlier `go install`, a Homebrew copy, etc.) will silently shadow the local repo build the contract selected. Using the absolute path eliminates the shadow.
+
+If `PRINTING_PRESS_BIN` was emitted as an empty value (`PRINTING_PRESS_BIN=`), the contract was unable to resolve a binary; this should have already been surfaced as `[setup-error]` (handled in section 1 below). Treat an empty value here as a setup-error fallback and stop.
+
+This rule applies to *all* `printing-press` references in the rest of this document. Where sections below write `printing-press version --json` or similar, read that as shorthand for `<PRINTING_PRESS_BIN> version --json` with the captured value substituted.
## 1. Refusal: missing prerequisite
@@ -56,7 +64,7 @@ If no `[repo-upgrade-available]` line was emitted, skip this section entirely.
## 3. Min-binary-version compatibility
-Check binary version compatibility against the skill's declared minimum. Read the `min-binary-version` field from the skill's YAML frontmatter. Run `printing-press version --json` and parse the version from the output. Compare it to `min-binary-version` using semver rules.
+Check binary version compatibility against the skill's declared minimum. Read the `min-binary-version` field from the skill's YAML frontmatter. Run `<PRINTING_PRESS_BIN> version --json` (using the absolute path captured in the preamble — not bare `printing-press`, which would resolve against the user's default `PATH` and could interrogate a stale global) and parse the version from the output. Compare it to `min-binary-version` using semver rules.
If the installed binary is older than the minimum, stop the skill immediately and tell the user:
@@ -86,7 +94,19 @@ If the user picks **Yes**, run:
go install github.com/mvanhorn/cli-printing-press/v4/cmd/printing-press@latest
```
-After it completes, confirm with `printing-press version --json` and tell the user `"Upgraded to v<new>."` **Continue this current setup run with the freshly installed binary on disk — do not stop, do not reload the session, do not skip the remaining checks (min-binary-version compatibility, etc.).**
+After `go install` completes, **re-resolve `PRINTING_PRESS_BIN`** before confirming. `go install` writes to `$(go env GOBIN)` if set, otherwise `$(go env GOPATH)/bin` — which may not be the same path the contract originally captured (e.g. when the pre-upgrade binary was at `/opt/homebrew/bin/printing-press` or `/usr/local/bin/printing-press`, the new binary lives at `$GOPATH/bin/printing-press` and the old one is unchanged). Run this re-resolution in a single Bash call so its stdout becomes the new captured value:
+
+```bash
+_gobin="$(go env GOBIN 2>/dev/null)"
+[ -z "$_gobin" ] && _gobin="$(go env GOPATH 2>/dev/null)/bin"
+if [ -x "$_gobin/printing-press" ]; then
+ echo "PRINTING_PRESS_BIN=$_gobin/printing-press"
+else
+ echo "PRINTING_PRESS_BIN=$(command -v printing-press 2>/dev/null || true)"
+fi
+```
+
+Capture the new `PRINTING_PRESS_BIN=<abs-path>` value and use it for every subsequent `printing-press ...` invocation in the rest of this run, overriding the value captured in the preamble. Then confirm with `<PRINTING_PRESS_BIN> version --json` and tell the user `"Upgraded to v<new>."` **Continue this current setup run with the freshly installed binary on disk — do not stop, do not reload the session, do not skip the remaining checks (min-binary-version compatibility, etc.).**
Separately, as out-of-band advice for the user's *next* session (not a stop signal for this run), tell them they can also refresh their installed skill files outside the repo checkout by running one of:
@@ -165,3 +185,19 @@ If an install command fails (no Python, no Node.js, network error), surface the
If the user picks **Skip for this run**, continue without prompting further this run. The decision is not cached — the prompt re-fires on the next run if the tool is still missing.
If no `[browser-tools-missing]` line was emitted, skip this section entirely.
+
+## 6. Optional shadow advisory
+
+If the setup contract output contains a line starting with `[binary-shadow]`, parse the follow-up lines:
+
+- `PRESS_BIN_LOCAL_VERSION=<version reported by the local build>`
+- `PRESS_BIN_GLOBAL_VERSION=<version reported by the differing global on PATH>`
+- `PRESS_BIN_GLOBAL_PATH=<absolute path to the differing global>`
+
+Surface a single-line note to the user before continuing — informational only, do not prompt:
+
+> "Note: a global printing-press v`<global>` is installed at `<path>` but the local repo build is v`<local>`. This run will use the local build (the absolute path the preflight selected); the global is unchanged."
+
+Then continue. Do not modify or remove the global. The note exists so the user can reconcile the divergence on their own time (typically with `go install ...@latest` once they want the new version everywhere).
+
+If no `[binary-shadow]` line was emitted, skip the advisory and continue.
← ac83f0fd fix(generator): support single-env basic auth credentials (#
·
back to Cli Printing Press
·
fix(cli): isolate typed-table upsert failures with per-item 89f38c4c →