[object Object]

← back to Cli Printing Press

fix(skills): correct update preflight compatibility (#854)

4b29a634250a80f9c80bc2d91a69d72dd71291cd · 2026-05-09 15:15:54 -0700 · Trevin Chow

* fix(skills): correct update preflight compatibility

* docs(skills): clarify update preflight review notes

* docs(skills): clarify standalone upgrade preflight

* docs(skills): clarify setup-checks Section 4 stop signal

Address PR review feedback (#854): the previous wording of Section 4's
post-install guidance let an agent reading linearly hit "reload or
restart the agent session" before the disambiguation, which could be
misread as a stop signal mid-run. Re-order so the "continue this run
with the new binary" directive lands first, then frame the
gh skill update / npx skills update commands as out-of-band advice
for the user's next session.

Files touched

Diff

commit 4b29a634250a80f9c80bc2d91a69d72dd71291cd
Author: Trevin Chow <trevin@trevinchow.com>
Date:   Sat May 9 15:15:54 2026 -0700

    fix(skills): correct update preflight compatibility (#854)
    
    * fix(skills): correct update preflight compatibility
    
    * docs(skills): clarify update preflight review notes
    
    * docs(skills): clarify standalone upgrade preflight
    
    * docs(skills): clarify setup-checks Section 4 stop signal
    
    Address PR review feedback (#854): the previous wording of Section 4's
    post-install guidance let an agent reading linearly hit "reload or
    restart the agent session" before the disambiguation, which could be
    misread as a stop signal mid-run. Re-order so the "continue this run
    with the new binary" directive lands first, then frame the
    gh skill update / npx skills update commands as out-of-band advice
    for the user's next session.
---
 internal/cli/release_test.go                     | 32 ++++++++
 skills/printing-press-catalog/SKILL.md           |  6 +-
 skills/printing-press-polish/SKILL.md            | 11 +++
 skills/printing-press-publish/SKILL.md           |  6 +-
 skills/printing-press-score/SKILL.md             |  6 +-
 skills/printing-press/SKILL.md                   | 97 ++++++++++++++++++------
 skills/printing-press/references/setup-checks.md | 78 ++++++++++++++++---
 7 files changed, 191 insertions(+), 45 deletions(-)

diff --git a/internal/cli/release_test.go b/internal/cli/release_test.go
index 269b703b..888fe72e 100644
--- a/internal/cli/release_test.go
+++ b/internal/cli/release_test.go
@@ -78,6 +78,38 @@ func TestVersionConsistencyAcrossFiles(t *testing.T) {
 		"plugin.json and version.go hardcoded version must match")
 }
 
+func TestInternalSkillMinimumBinaryVersionsTrackMajor(t *testing.T) {
+	// Skill frontmatter `version` values are not release-managed. The
+	// executable compatibility contract is `min-binary-version`; keep the
+	// frontmatter and the duplicated setup-contract comment in sync.
+	want := fmt.Sprintf("%d.0.0", majorVersion(t, version.Version))
+	paths := []string{
+		"../../skills/printing-press/SKILL.md",
+		"../../skills/printing-press-catalog/SKILL.md",
+		"../../skills/printing-press-polish/SKILL.md",
+		"../../skills/printing-press-publish/SKILL.md",
+		"../../skills/printing-press-score/SKILL.md",
+	}
+
+	frontmatterRe := regexp.MustCompile(`(?m)^min-binary-version:\s*"?([^"\n]+)"?\s*$`)
+	commentRe := regexp.MustCompile(`(?m)^# min-binary-version:\s*([^\s]+)\s*$`)
+	for _, path := range paths {
+		t.Run(path, func(t *testing.T) {
+			data, err := os.ReadFile(path)
+			require.NoError(t, err)
+			content := string(data)
+
+			frontmatter := frontmatterRe.FindStringSubmatch(content)
+			require.Len(t, frontmatter, 2, "skill must declare min-binary-version frontmatter")
+			assert.Equal(t, want, frontmatter[1])
+
+			comment := commentRe.FindStringSubmatch(content)
+			require.Len(t, comment, 2, "setup contract must duplicate min-binary-version")
+			assert.Equal(t, frontmatter[1], comment[1])
+		})
+	}
+}
+
 func TestMarketplaceJSONHasNoPluginVersion(t *testing.T) {
 	// Guard against a reviewer (or release-please misconfiguration) re-adding
 	// a per-plugin version field to marketplace.json. Plugin versions live
diff --git a/skills/printing-press-catalog/SKILL.md b/skills/printing-press-catalog/SKILL.md
index f71fcf5e..aaeab8f5 100644
--- a/skills/printing-press-catalog/SKILL.md
+++ b/skills/printing-press-catalog/SKILL.md
@@ -2,7 +2,7 @@
 name: printing-press-catalog
 description: Browse and install pre-built Go CLIs for popular APIs from the catalog
 version: 0.4.0
-min-binary-version: "0.2.0"
+min-binary-version: "4.0.0"
 deprecated: true
 allowed-tools:
   - Bash
@@ -39,7 +39,7 @@ Before any other commands, run the setup contract to verify the printing-press b
 
 <!-- PRESS_SETUP_CONTRACT_START -->
 ```bash
-# min-binary-version: 0.2.0
+# min-binary-version: 4.0.0
 
 # Derive scope first — needed for local build detection
 _scope_dir="$(git rev-parse --show-toplevel 2>/dev/null || echo "$PWD")"
@@ -74,7 +74,7 @@ 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, warn 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." Continue anyway but surface the warning prominently.
+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."
 
 Generated CLIs are published to `$PRESS_LIBRARY/`, not to the repo.
 
diff --git a/skills/printing-press-polish/SKILL.md b/skills/printing-press-polish/SKILL.md
index 94db19b0..083596b6 100644
--- a/skills/printing-press-polish/SKILL.md
+++ b/skills/printing-press-polish/SKILL.md
@@ -9,6 +9,7 @@ description: >
   phrases: "polish", "improve the CLI", "fix verify", "make it publish-ready",
   "clean up the CLI", "get this ready to ship".
 context: fork
+min-binary-version: "4.0.0"
 allowed-tools:
   - Bash
   - Read
@@ -44,10 +45,20 @@ Can also be run standalone on any CLI in `~/printing-press/library/`.
 ## Setup
 
 ```bash
+# min-binary-version: 4.0.0
+
 PRESS_HOME="$HOME/printing-press"
 PRESS_LIBRARY="$PRESS_HOME/library"
+
+if ! command -v printing-press >/dev/null 2>&1; then
+  echo "printing-press binary not found."
+  echo "Install with:  go install github.com/mvanhorn/cli-printing-press/v4/cmd/printing-press@latest"
+  return 1 2>/dev/null || exit 1
+fi
 ```
 
+After setup, 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."
+
 ### Public-library hint
 
 If the user's request includes phrasing like "polish notion **in the
diff --git a/skills/printing-press-publish/SKILL.md b/skills/printing-press-publish/SKILL.md
index 63e9985b..648a0480 100644
--- a/skills/printing-press-publish/SKILL.md
+++ b/skills/printing-press-publish/SKILL.md
@@ -2,7 +2,7 @@
 name: printing-press-publish
 description: Publish a generated CLI to the printing-press-library repo
 version: 0.1.0
-min-binary-version: "0.5.0"
+min-binary-version: "4.0.0"
 allowed-tools:
   - Bash
   - Read
@@ -39,7 +39,7 @@ Before doing anything else:
 
 <!-- PRESS_SETUP_CONTRACT_START -->
 ```bash
-# min-binary-version: 0.5.0
+# min-binary-version: 4.0.0
 
 # Derive scope first — needed for local build detection
 _scope_dir="$(git rev-parse --show-toplevel 2>/dev/null || echo "$PWD")"
@@ -76,7 +76,7 @@ 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, warn 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." Continue anyway but surface the warning prominently.
+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."
 
 ## Configuration
 
diff --git a/skills/printing-press-score/SKILL.md b/skills/printing-press-score/SKILL.md
index d76f3519..3dc14556 100644
--- a/skills/printing-press-score/SKILL.md
+++ b/skills/printing-press-score/SKILL.md
@@ -2,7 +2,7 @@
 name: printing-press-score
 description: Score a generated CLI against the Steinberger bar, compare two CLIs side-by-side
 version: 0.1.0
-min-binary-version: "0.3.0"
+min-binary-version: "4.0.0"
 allowed-tools:
   - Bash
   - Read
@@ -35,7 +35,7 @@ Before any other commands, run the setup contract to verify the printing-press b
 
 <!-- PRESS_SETUP_CONTRACT_START -->
 ```bash
-# min-binary-version: 0.3.0
+# min-binary-version: 4.0.0
 
 # Derive scope first — needed for local build detection
 _scope_dir="$(git rev-parse --show-toplevel 2>/dev/null || echo "$PWD")"
@@ -72,7 +72,7 @@ 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, warn 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." Continue anyway but surface the warning prominently.
+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."
 
 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 a19ca967..9a3b2c69 100644
--- a/skills/printing-press/SKILL.md
+++ b/skills/printing-press/SKILL.md
@@ -2,7 +2,7 @@
 name: printing-press
 description: Generate a ship-ready CLI for an API with a lean research -> generate -> build -> shipcheck loop.
 version: 2.0.0
-min-binary-version: "0.3.0"
+min-binary-version: "4.0.0"
 allowed-tools:
   - Bash
   - Read
@@ -117,16 +117,21 @@ During Phase 5.6 (archiving) and before publishing, read and apply
 
 <!-- PRESS_SETUP_CONTRACT_START -->
 ```bash
-# min-binary-version: 0.3.0
+# min-binary-version: 4.0.0
 
 # Derive scope first — needed for local build detection
 _scope_dir="$(git rev-parse --show-toplevel 2>/dev/null || echo "$PWD")"
 _scope_dir="$(cd "$_scope_dir" && pwd -P)"
 
+_press_repo=false
+if [ -d "$_scope_dir/cmd/printing-press" ] && [ -f "$_scope_dir/go.mod" ]; then
+  _press_repo=true
+fi
+
 # Prefer local build when running from inside the printing-press repo.
 # The lefthook build hook keeps ./printing-press current after every commit/pull,
 # so it's always newer than the go-install version.
-if [ -x "$_scope_dir/printing-press" ] && [ -d "$_scope_dir/cmd/printing-press" ]; then
+if [ "$_press_repo" = "true" ] && [ -x "$_scope_dir/printing-press" ]; then
   export PATH="$_scope_dir:$PATH"
   echo "Using local build: $_scope_dir/printing-press"
 elif ! command -v printing-press >/dev/null 2>&1; then
@@ -169,11 +174,9 @@ PRESS_CURRENT="$PRESS_RUNSTATE/current"
 
 mkdir -p "$PRESS_RUNSTATE" "$PRESS_LIBRARY" "$PRESS_MANUSCRIPTS" "$PRESS_CURRENT"
 
-# --- Latest-version advisory (throttled, fail-open) ---
-# Once per 24h, check whether a newer printing-press release exists and print a
-# one-line notice if so. Uses `go list` through the public module proxy. Runs in
-# every context — devs ahead of latest stay silent (comparison handles it), devs
-# behind latest get the same nudge anyone else does.
+# --- Latest-version advisory (fail-open) ---
+# Repo checkouts track origin/main because their skills and local binary come
+# from the checkout. Standalone installs track the latest released Go module.
 PRESS_VERCHECK_FILE="$PRESS_HOME/.version-check"
 PRESS_VERCHECK_TTL=86400
 _now_ts=$(date +%s)
@@ -185,26 +188,70 @@ if [ -f "$PRESS_VERCHECK_FILE" ] && [ -z "$PRESS_VERCHECK_FORCE" ]; then
   fi
 fi
 
-if [ "$_should_check" = "true" ] && command -v go >/dev/null 2>&1; then
-  _installed=$(printing-press version --json 2>/dev/null | sed -nE 's/.*"version"[[:space:]]*:[[:space:]]*"([^"]+)".*/\1/p')
-  _latest=$(go list -m -versions github.com/mvanhorn/cli-printing-press/v4 2>/dev/null | awk '{print $NF}' | sed 's/^v//')
-
-  if [ -n "$_installed" ] && [ -n "$_latest" ] && [ "$_installed" != "$_latest" ]; then
-    # sort -V is not fully semver-aware: it ranks "3.0.0-rc1" above "3.0.0" instead of below.
-    # Acceptable today (we don't ship pre-release tags); revisit if we ever do.
-    _newer=$(printf "v%s\nv%s\n" "$_installed" "$_latest" | sort -V | tail -1 | sed 's/^v//')
-    if [ "$_newer" = "$_latest" ]; then
-      # Marker for the skill prose below to detect and offer an interactive upgrade.
-      # The skill reads PRESS_UPGRADE_AVAILABLE / PRESS_UPGRADE_INSTALLED from this output.
+if [ "$_press_repo" = "true" ]; then
+  # Repo mode checks origin/main every run because the checkout and local build
+  # move quickly; skipped_repo_main suppresses repeated prompts for one SHA.
+  if git -C "$_scope_dir" remote get-url origin >/dev/null 2>&1 &&
+     git -C "$_scope_dir" fetch --quiet origin main >/dev/null 2>&1; then
+    _head_rev=$(git -C "$_scope_dir" rev-parse HEAD 2>/dev/null || true)
+    _main_rev=$(git -C "$_scope_dir" rev-parse origin/main 2>/dev/null || true)
+    _skipped_repo_main=""
+    if [ -f "$PRESS_VERCHECK_FILE" ] && [ -z "$PRESS_VERCHECK_FORCE" ]; then
+      _skipped_repo_main=$(awk -F= '/^skipped_repo_main=/{value=$2} END{print value}' "$PRESS_VERCHECK_FILE" 2>/dev/null)
+    fi
+    if [ -n "$_head_rev" ] && [ -n "$_main_rev" ] &&
+       [ "$_head_rev" != "$_main_rev" ] &&
+       [ "$_skipped_repo_main" != "$_main_rev" ] &&
+       git -C "$_scope_dir" merge-base --is-ancestor "$_head_rev" "$_main_rev" 2>/dev/null; then
       echo ""
-      echo "[upgrade-available] printing-press v$_latest is available (you have v$_installed)"
-      echo "PRESS_UPGRADE_AVAILABLE=$_latest"
-      echo "PRESS_UPGRADE_INSTALLED=$_installed"
+      echo "[repo-upgrade-available] origin/main has newer Printing Press changes"
+      echo "PRESS_REPO_DIR=$_scope_dir"
+      echo "PRESS_REPO_HEAD=$_head_rev"
+      echo "PRESS_REPO_MAIN=$_main_rev"
       echo ""
     fi
+
+    printf "last_check=%s\nlatest=%s\nmode=repo\nskipped_repo_main=%s\n" "$_now_ts" "${_main_rev:-unknown}" "$_skipped_repo_main" > "$PRESS_VERCHECK_FILE" 2>/dev/null || true
+  fi
+elif [ "$_should_check" = "true" ] && command -v go >/dev/null 2>&1; then
+  _installed=$(printing-press version --json 2>/dev/null | sed -nE 's/.*"version"[[:space:]]*:[[:space:]]*"([^"]+)".*/\1/p')
+  _latest=""
+
+  if [ -n "$_installed" ]; then
+    _latest=$(go list -m -json github.com/mvanhorn/cli-printing-press/v4@latest 2>/dev/null | awk '
+      /"Version":/ {
+        version=$2
+        gsub(/[",]/, "", version)
+        sub(/^v/, "", version)
+        print version
+        exit
+      }
+    ')
+  fi
+
+  if [ -n "$_installed" ] && [ -n "$_latest" ] &&
+     awk -v installed="$_installed" -v latest="$_latest" 'BEGIN {
+       split(installed, a, ".")
+       split(latest, b, ".")
+       # Integer truncation means pre-release suffixes (e.g. "4.0.0-rc.1") are
+       # treated as equal to their GA counterpart. Acceptable while we do not
+       # ship pre-release tags; revisit if that changes.
+       for (i = 1; i <= 3; i++) {
+         if ((a[i] + 0) < (b[i] + 0)) exit 0
+         if ((a[i] + 0) > (b[i] + 0)) exit 1
+       }
+       exit 1
+     }'; then
+    # Marker for the skill prose below to detect and offer an interactive upgrade.
+    # The skill reads PRESS_UPGRADE_AVAILABLE / PRESS_UPGRADE_INSTALLED from this output.
+    echo ""
+    echo "[upgrade-available] printing-press v$_latest is available (you have v$_installed)"
+    echo "PRESS_UPGRADE_AVAILABLE=$_latest"
+    echo "PRESS_UPGRADE_INSTALLED=$_installed"
+    echo ""
   fi
 
-  printf "last_check=%s\nlatest=%s\n" "$_now_ts" "${_latest:-unknown}" > "$PRESS_VERCHECK_FILE" 2>/dev/null || true
+  printf "last_check=%s\nlatest=%s\nmode=standalone\n" "$_now_ts" "${_latest:-$_installed}" > "$PRESS_VERCHECK_FILE" 2>/dev/null || true
 fi
 
 # --- Codex mode detection (must run as part of setup, not a separate step) ---
@@ -240,9 +287,9 @@ 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 three signals the contract emits to stdout: `[setup-error]` (refuse to run, surface the install instructions), `[upgrade-available]` (interactive `AskUserQuestion` prompt + optional upgrade), and the min-binary-version compatibility check. Skipping the reference will cause the skill to proceed with a missing or out-of-date binary. 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 four 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), and `[upgrade-available]` (interactive `AskUserQuestion` prompt + optional standalone binary upgrade). Skipping the reference will cause the skill to proceed with a missing or out-of-date binary. Do not skip.
 
-Only after preflight completes successfully (no `[setup-error]`; any `[upgrade-available]` 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]` or `[upgrade-available]` was offered to the user) 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 14dba379..cd7cfb05 100644
--- a/skills/printing-press/references/setup-checks.md
+++ b/skills/printing-press/references/setup-checks.md
@@ -1,6 +1,6 @@
 # Setup Checks
 
-Post-contract checks the skill must run after executing the bash setup contract block in `SKILL.md`. These handle three signals the contract emits to stdout: `[setup-error]`, `[upgrade-available]`, 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 four signals the contract emits to stdout: `[setup-error]`, `[repo-upgrade-available]`, `[upgrade-available]`, and the `min-binary-version` compatibility check.
 
 Apply these in order. Each section is conditional — do nothing if its trigger isn't present.
 
@@ -12,7 +12,59 @@ If the setup contract output contains a line starting with `[setup-error]`, the
 
 The user must install the binary in their terminal before re-running. Do not offer to auto-install — the README's two-step install is the source of truth, and silent auto-install hides failure modes (network, wrong GOPATH) inside an opaque skill invocation.
 
-## 2. Interactive upgrade prompt
+## 2. Interactive repo upgrade prompt
+
+If the setup contract output contains a line starting with `[repo-upgrade-available]`, parse the follow-up lines:
+
+- `PRESS_REPO_DIR=<absolute repo path>`
+- `PRESS_REPO_HEAD=<current HEAD sha>`
+- `PRESS_REPO_MAIN=<origin/main sha>`
+
+Then ask the user via `AskUserQuestion` before continuing setup:
+
+- **question:** `"origin/main has newer Printing Press changes. Pull the latest main now? After this, reload the skill with /reload-plugin."`
+- **header:** `"Update repo"`
+- **multiSelect:** `false`
+- **options:**
+  1. **Yes — pull main** — `"Run git pull --ff-only origin main in the Printing Press repo, then stop so you can reload the skill."`
+  2. **Skip — keep current checkout** — `"Continue with the current checkout."`
+
+If the user picks **Yes**, run:
+
+```bash
+git -C "$PRESS_REPO_DIR" pull --ff-only origin main
+```
+
+After it completes, tell the user:
+
+> "Updated the Printing Press checkout. Run `/reload-plugin`, then re-run `/printing-press` so the refreshed skill and rebuilt local binary are used."
+
+Then stop the skill immediately. Do not continue the current run, because the skill text that is executing may now be stale.
+
+If the pull fails, surface the failure to the user and continue with the current checkout. Do not attempt a non-fast-forward merge, rebase, reset, stash, or branch switch from the skill preflight.
+
+If the user picks **Skip**, record the skipped target SHA so the same update is not prompted again:
+
+```bash
+mkdir -p "$HOME/printing-press"
+printf "last_check=%s\nmode=repo\nskipped_repo_main=%s\n" "$(date +%s)" "$PRESS_REPO_MAIN" > "$HOME/printing-press/.version-check"
+```
+
+Prompt again only when `origin/main` advances to a different SHA.
+
+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.
+
+If the installed binary is older than the minimum, stop the skill 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."
+
+Do not proceed to research, scoring, publishing, or any other workflow when the binary is below `min-binary-version`. This is the compatibility floor, not a freshness advisory.
+
+## 4. Interactive standalone binary upgrade prompt
 
 If the setup contract output contains a line starting with `[upgrade-available]`, parse the two follow-up lines for the version values:
 
@@ -25,7 +77,7 @@ Then ask the user via `AskUserQuestion` before continuing setup:
 - **header:** `"Update available"`
 - **multiSelect:** `false`
 - **options:**
-  1. **Yes — upgrade now** — `"Run go install and use the latest version for this session."`
+  1. **Yes — upgrade now** — `"Run go install and use the latest released binary for this session."`
   2. **Skip — keep current version** — `"Continue with the current binary."`
 
 If the user picks **Yes**, run:
@@ -34,18 +86,22 @@ 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>."` Then continue setup.
+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.).**
 
-If the upgrade command fails (network error, auth error, etc.), surface the failure to the user and continue with the current binary — do not block the run on a failed upgrade. The user can re-run later.
+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:
 
-If no `[upgrade-available]` line was emitted, skip this section entirely.
+```bash
+gh skill update
+```
 
-## 3. Min-binary-version compatibility
+or:
 
-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.
+```bash
+npx skills update
+```
 
-If the installed binary is older than the minimum, warn the user:
+These two commands update skill files that live outside the repo; they only take effect after the user reloads or restarts the agent session, which they should do *after* the current run finishes. Frame this clearly to the user as "for next time" guidance, then continue setup with the newly installed binary.
 
-> "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."
+If the upgrade command fails (network error, auth error, etc.), surface the failure to the user and continue with the current binary — do not block the run on a failed upgrade. The user can re-run later.
 
-Continue anyway but surface the warning prominently. (Note: if the user just declined the optional upgrade in section 2, they may still pass min-version compatibility here — that's fine. The two checks have different bars.)
+If no `[upgrade-available]` line was emitted, skip this section entirely.

← 1a8f68ee fix(generator): scope caches by auth identity (#853)  ·  back to Cli Printing Press  ·  chore(main): release 4.2.2 (#840) 26442897 →