← back to Cli Printing Press
fix(skills): gate polish ship verdict on publish validate (#789)
5e04776b8b0e943a1b30461884d339ee5e7e67ba · 2026-05-09 09:58:56 -0700 · Trevin Chow
Files touched
M internal/pipeline/contracts_test.goM skills/printing-press-polish/SKILL.md
Diff
commit 5e04776b8b0e943a1b30461884d339ee5e7e67ba
Author: Trevin Chow <trevin@trevinchow.com>
Date: Sat May 9 09:58:56 2026 -0700
fix(skills): gate polish ship verdict on publish validate (#789)
---
internal/pipeline/contracts_test.go | 10 ++++++++++
skills/printing-press-polish/SKILL.md | 13 +++++++++----
2 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/internal/pipeline/contracts_test.go b/internal/pipeline/contracts_test.go
index 6adad0b4..4b5cb846 100644
--- a/internal/pipeline/contracts_test.go
+++ b/internal/pipeline/contracts_test.go
@@ -155,6 +155,16 @@ func TestPublishSkillUsesLibraryTreeForCliSkillsMirror(t *testing.T) {
assert.Less(t, copyIntoLibrary, mirrorRun)
}
+func TestPolishSkillHardGatesPublishValidate(t *testing.T) {
+ skill := readContractFile(t, filepath.Join("..", "..", "skills", "printing-press-polish", "SKILL.md"))
+
+ assert.Contains(t, skill, `printing-press publish validate --dir "$CLI_DIR" --json`)
+ assert.Contains(t, skill, "Publish validation failures")
+ assert.Contains(t, skill, "The publish-validate leg is a hard ship-gate")
+ assert.Contains(t, skill, "phase5 acceptance")
+ assert.Contains(t, skill, "ship cannot fire while publish validate fails")
+}
+
func TestREADMEOutputContract(t *testing.T) {
readme := readContractFile(t, filepath.Join("..", "..", "README.md"))
diff --git a/skills/printing-press-polish/SKILL.md b/skills/printing-press-polish/SKILL.md
index 0625d9af..94db19b0 100644
--- a/skills/printing-press-polish/SKILL.md
+++ b/skills/printing-press-polish/SKILL.md
@@ -205,6 +205,7 @@ printing-press dogfood --dir "$CLI_DIR" $SPEC_FLAG $RESEARCH_FLAG 2>&1
printing-press verify --dir "$CLI_DIR" $SPEC_FLAG --json 2>&1
printing-press workflow-verify --dir "$CLI_DIR" --json > /tmp/polish-workflow-verify.json 2>&1 || true
printing-press verify-skill --dir "$CLI_DIR" --json > /tmp/polish-verify-skill.json 2>&1 || true
+printing-press publish validate --dir "$CLI_DIR" --json > /tmp/polish-publish-validate.json 2>&1 || true
# --live-check samples novel-feature outputs and populates
# live_check.features[].warnings (Wave B entity detection) — required for
# the "Output entity warnings" row below to have data to read.
@@ -214,7 +215,7 @@ printing-press tools-audit "$CLI_DIR" --json > /tmp/polish-tools-audit-before.js
go vet ./... 2>&1
```
-verify-skill and workflow-verify run alongside dogfood/verify/scorecard so polish catches the same class of failures the public-library CI catches. Polish hard-gates `ship` on `verify-skill` exit 0 (see ship logic at the end).
+verify-skill, workflow-verify, and publish-validate run alongside dogfood/verify/scorecard so polish catches the same class of failures the public-library CI catches. The publish-validate leg is a hard ship-gate: polish cannot recommend `ship` or `ship-with-gaps` while `printing-press publish validate` reports `passed: false`.
**If Phase 1 baseline reveals the underlying CLI needs re-discovery** — broken HTML/SSR extraction, sparse capture (fewer than 5 unique endpoints in the source manuscript), wrong endpoint shapes, missing GraphQL operation hashes, or any signal that the CLI was generated from incomplete capture — polish does not normally do browser capture itself, but the shared playbook at `skills/printing-press/references/browser-sniff-capture.md` covers all available capture backends including the Claude chrome-MCP (`mcp__claude-in-chrome__*`) and computer-use (`mcp__computer-use__*`) when the runtime exposes them. Read Step 1 (tool detection), Step 2c.5 (failure-recovery menu), and Step 2e (chrome-MCP capture playbook) of that reference before improvising. Re-discovery from polish is rare but real; when it happens, use the shared backends — do not invent a new capture flow.
@@ -225,6 +226,7 @@ Parse findings into categories:
| Verify failures | verify --json | Commands with score < 3 |
| SKILL static-check failures | verify-skill --json | Any `findings[]` with `severity=error` (flag-names, flag-commands, positional-args, unknown-command, canonical-sections). Hard ship-gate: ship cannot fire while these exist. |
| Workflow gaps | workflow-verify --json | Verdict `workflow-fail`. Soft gate: surface in `remaining_issues` and downgrade to `hold` when the workflow is the CLI's primary value. |
+| Publish validation failures | publish validate --json | `passed: false`. Hard ship-gate: ship cannot fire while publish validate fails. If the only failing check is missing phase5 acceptance, report `phase5 acceptance required` with the next-step command: authenticate, then run `printing-press dogfood --dir "$CLI_DIR" $SPEC_FLAG --live --level quick --write-acceptance <proofs-dir>/phase5-acceptance.json`. Use the proofs directory from the validate error when present. |
| Dead code | dogfood | Dead functions, dead flags |
| Stale files | dogfood | Unregistered commands |
| Description issues | dogfood | Boilerplate root Short |
@@ -465,19 +467,20 @@ printing-press dogfood --dir "$CLI_DIR" $SPEC_FLAG 2>&1
printing-press verify --dir "$CLI_DIR" $SPEC_FLAG --json 2>&1
printing-press workflow-verify --dir "$CLI_DIR" --json 2>&1
printing-press verify-skill --dir "$CLI_DIR" --json 2>&1
+printing-press publish validate --dir "$CLI_DIR" --json 2>&1
printing-press scorecard --dir "$CLI_DIR" $SPEC_FLAG 2>&1
printing-press tools-audit "$CLI_DIR" 2>&1
go vet ./... 2>&1
```
-Record the after scores. If verify-skill still has any `severity=error` findings or workflow-verify still reports `workflow-fail`, ship cannot fire (see ship logic below).
+Record the after scores. If verify-skill still has any `severity=error` findings, workflow-verify still reports `workflow-fail`, or publish-validate still reports `passed: false`, ship cannot fire (see ship logic below).
## Ship logic
Compute the ship recommendation:
-- **`ship`**: verify >= 80%, scorecard >= 75, no critical failures, **AND** verify-skill exits 0 (no SKILL/CLI mismatches), **AND** workflow-verify is not `workflow-fail`, **AND** tools-audit shows zero pending findings (every finding fixed or explicitly accepted with rationale). The SKILL/workflow gates are hard requirements: a CLI that ships with a SKILL that lies about it (verify-skill findings) gives agents broken instructions; a CLI whose primary workflow fails verification has not actually shipped.
-- **`ship-with-gaps`**: verify >= 65%, scorecard >= 65, non-critical gaps remain, **AND** the SKILL/workflow gates above hold, **AND** the README has a `## Known Gaps` block that lists the user-facing gaps. Reserved for the rare case where a refactor or external-dependency blocker prevents a clean fix.
+- **`ship`**: verify >= 80%, scorecard >= 75, no critical failures, **AND** verify-skill exits 0 (no SKILL/CLI mismatches), **AND** workflow-verify is not `workflow-fail`, **AND** publish-validate reports `passed: true`, **AND** tools-audit shows zero pending findings (every finding fixed or explicitly accepted with rationale). The SKILL/workflow/publish gates are hard requirements: a CLI that ships with a SKILL that lies about it (verify-skill findings) gives agents broken instructions; a CLI whose primary workflow fails verification has not actually shipped; a CLI that publish-validate rejects is not publishable.
+- **`ship-with-gaps`**: verify >= 65%, scorecard >= 65, non-critical gaps remain, **AND** the SKILL/workflow/publish gates above hold, **AND** the README has a `## Known Gaps` block that lists the user-facing gaps. Reserved for the rare case where a refactor or external-dependency blocker prevents a clean fix.
**README Known Gaps is mandatory for ship-with-gaps.** The published library copy is what downstream users see; if the verdict claims gaps exist but the README hides them, downstream users meet a CLI that misbehaves with no disclosure. Before emitting `ship_recommendation: ship-with-gaps`:
@@ -554,6 +557,8 @@ govet_before: <N>
govet_after: <N>
tools_audit_before: <N pending>
tools_audit_after: <N pending>
+publish_validate_before: <PASS|FAIL>
+publish_validate_after: <PASS|FAIL>
fixes_applied:
- <one-line description of each fix>
skipped_findings:
← d0086ffe fix(cli): handle Windows shipcheck paths (#783)
·
back to Cli Printing Press
·
fix(cli): use slash paths for embedded templates (#794) 0020b78a →