← back to Cli Printing Press
fix(skills): preflight Go toolchain before generation runs (#973)
0562bca80e8588b02130edeec8dab7d0a3b1ec1d · 2026-05-10 14:47:27 -0700 · Trevin Chow
* fix(skills): preflight Go toolchain before generation runs
Generation produced 10K+ lines of Go scaffolding before the post-generation
`go mod tidy` quality gate failed with "exec: 'go': executable file not found
in $PATH". A user installed via `go install` but their interactive shell PATH
had `~/go/bin/printing-press` without `go` itself (WSL setup quirk; common when
the binary is invoked directly).
The preflight already runs `command -v go` inside the binary-not-found error
fallback to pick between two install messages, but never when the binary is
present. Add an unconditional Go-toolchain check after binary detection so the
binary-present + Go-absent path aborts in 30 seconds with an actionable
`[setup-error] Go toolchain not found.` block, before any AskUserQuestion.
Generalize section 1 of references/setup-checks.md so the existing handler
covers either missing prerequisite. Lock the new check in with a contract test.
Closes #793
* fix(skills): correct test comment scope for Go-toolchain check
Files touched
M internal/pipeline/contracts_test.goM skills/printing-press/SKILL.mdM skills/printing-press/references/setup-checks.md
Diff
commit 0562bca80e8588b02130edeec8dab7d0a3b1ec1d
Author: Trevin Chow <trevin@trevinchow.com>
Date: Sun May 10 14:47:27 2026 -0700
fix(skills): preflight Go toolchain before generation runs (#973)
* fix(skills): preflight Go toolchain before generation runs
Generation produced 10K+ lines of Go scaffolding before the post-generation
`go mod tidy` quality gate failed with "exec: 'go': executable file not found
in $PATH". A user installed via `go install` but their interactive shell PATH
had `~/go/bin/printing-press` without `go` itself (WSL setup quirk; common when
the binary is invoked directly).
The preflight already runs `command -v go` inside the binary-not-found error
fallback to pick between two install messages, but never when the binary is
present. Add an unconditional Go-toolchain check after binary detection so the
binary-present + Go-absent path aborts in 30 seconds with an actionable
`[setup-error] Go toolchain not found.` block, before any AskUserQuestion.
Generalize section 1 of references/setup-checks.md so the existing handler
covers either missing prerequisite. Lock the new check in with a contract test.
Closes #793
* fix(skills): correct test comment scope for Go-toolchain check
---
internal/pipeline/contracts_test.go | 14 ++++++++++++++
skills/printing-press/SKILL.md | 17 +++++++++++++++++
skills/printing-press/references/setup-checks.md | 8 ++++----
3 files changed, 35 insertions(+), 4 deletions(-)
diff --git a/internal/pipeline/contracts_test.go b/internal/pipeline/contracts_test.go
index ed3bf55c..538525f5 100644
--- a/internal/pipeline/contracts_test.go
+++ b/internal/pipeline/contracts_test.go
@@ -96,6 +96,20 @@ func TestPrintingPressSkillUsesRunRootStateFile(t *testing.T) {
assert.Contains(t, skill, `"working_dir": "$CLI_WORK_DIR"`)
}
+func TestPrintingPressSkillPreflightChecksGoToolchain(t *testing.T) {
+ skillPath := filepath.Join("..", "..", "skills", "printing-press", "SKILL.md")
+ full := readContractFile(t, skillPath)
+ block := extractContractBlock(t, full)
+
+ // The Go-toolchain presence check fires after the binary detection block
+ // exits cleanly (binary found or PATH-augmented). It catches binary-present
+ // + Go-absent and fails fast instead of crashing 5+ minutes later in the
+ // post-generation `go mod tidy` quality gate.
+ assert.Contains(t, block, `if ! command -v go >/dev/null 2>&1; then`)
+ assert.Contains(t, block, `[setup-error] Go toolchain not found.`)
+ assert.Contains(t, block, `https://go.dev/dl/`)
+}
+
func TestPrintingPressSkillUsesRunstateForBuilds(t *testing.T) {
skill := readContractFile(t, filepath.Join("..", "..", "skills", "printing-press", "SKILL.md"))
diff --git a/skills/printing-press/SKILL.md b/skills/printing-press/SKILL.md
index 9a3b2c69..68e6fbe1 100644
--- a/skills/printing-press/SKILL.md
+++ b/skills/printing-press/SKILL.md
@@ -160,6 +160,23 @@ elif ! command -v printing-press >/dev/null 2>&1; then
fi
fi
+# Verify the Go toolchain is on PATH. Generation runs Go-based quality gates
+# (go mod tidy, go vet, etc.) after writing thousands of lines of scaffolding,
+# so a missing `go` only surfaces 5+ minutes in. Fail-fast costs one command -v
+# call when Go is present and converts a late, opaque failure into a 30-second
+# actionable abort.
+if ! command -v go >/dev/null 2>&1; then
+ echo ""
+ echo "[setup-error] Go toolchain not found."
+ echo ""
+ echo "The Printing Press generator runs Go-based quality gates after generation."
+ echo "Install Go 1.26.3 or newer from https://go.dev/dl/, then verify with:"
+ echo " go version"
+ echo "Then re-run /printing-press."
+ echo ""
+ return 1 2>/dev/null || exit 1
+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"
diff --git a/skills/printing-press/references/setup-checks.md b/skills/printing-press/references/setup-checks.md
index cd7cfb05..dfd71044 100644
--- a/skills/printing-press/references/setup-checks.md
+++ b/skills/printing-press/references/setup-checks.md
@@ -4,13 +4,13 @@ Post-contract checks the skill must run after executing the bash setup contract
Apply these in order. Each section is conditional — do nothing if its trigger isn't present.
-## 1. Refusal: missing binary
+## 1. Refusal: missing prerequisite
-If the setup contract output contains a line starting with `[setup-error]`, the printing-press binary is not installed and the contract has already exited non-zero.
+If the setup contract output contains a line starting with `[setup-error]`, a required prerequisite is missing (the printing-press binary or the Go toolchain) and the contract has already exited non-zero.
-**Stop the skill immediately.** Do not proceed to research, generation, or any other work. Surface the message the contract printed (it includes the exact `go install` command) verbatim to the user.
+**Stop the skill immediately.** Do not proceed to research, generation, or any other work. Surface the message the contract printed (it includes the exact install command or download URL) verbatim to the user.
-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.
+The user must install the missing prerequisite in their terminal before re-running. Do not offer to auto-install — the README's two-step install is the source of truth for the binary, and silent auto-install hides failure modes (network, wrong GOPATH, no Go toolchain) inside an opaque skill invocation.
## 2. Interactive repo upgrade prompt
← ab6edbef fix(cli): route explicit --csv/--quiet/--plain above piped-p
·
back to Cli Printing Press
·
fix(cli): preserve hand-edits to templated files on --force 618fa456 →