Skip to content
SCShipcheck
Product Standards

Ship products, not prototypes.

27 hard gates, 4 soft gates, a structured error contract, and an adoption guide. Define what "done" means before anything ships.

Quick start

# 1. Read the adoption guide cat ADOPTION.md # 2. Copy the gate into your repo cp templates/SHIP_GATE.md ./SHIP_GATE.md # 3. Check off items, mark N/A with SKIP: # 4. Ship when all hard gates pass

Error shape

// Tier 1: mandatory for all user-facing errors { "code": "INPUT_TEXT_EMPTY", "message": "Text must not be empty", "hint": "Provide at least one character", "retryable": false }

Gate summary

# Hard gates (block release): A. Security Baseline 4 + 4 items B. Error Handling 6 items C. Operator Docs 7 items D. Shipping Hygiene 9 items # Soft gate (defines "whole"): E. Identity 4 items

Why shipcheck

"Done" used to mean the code works. That's not enough.

What, not how

The gate says what must be true, not how to implement it. TypeScript, Python, .NET, Go — the standard is language-agnostic.

No checkbox shame

Applicability tags ([all], [npm], [mcp], [cli], [desktop]) let you skip what doesn't apply. A standards repo doesn't need error handling gates.

30-minute adoption

ADOPTION.md walks you through applying shipcheck to any repo in under 30 minutes. Copy the gate, check items, ship.

Standards

Everything a product needs to be "done."

StandardWhat it covers
Ship Gate27 hard-gate + 4 soft-gate checks across all repo types
Error ContractTier 1: error shape (all repos) / Tier 2: base type + exit codes (CLI/MCP/desktop)
Security BaselineReport email, response timeline, threat scope template
HandbookOperational field manual for complex tools
ScorecardPre/post remediation scoring for tracking maturity

Get started

Copy the gate

# Copy SHIP_GATE.md into your repo root
cp templates/SHIP_GATE.md ./SHIP_GATE.md

# Check off items as you go:
# - [x] `[all]` SECURITY.md exists (2026-02-27)
# - [ ] SKIP: not a CLI tool
# - [ ] unchecked = needs work

Error shape (Tier 1)

// Every user-facing error must have:
interface StructuredError {
  code: string;      // e.g. "INPUT_TEXT_EMPTY"
  message: string;   // human-readable
  hint: string;      // actionable guidance
  cause?: string;    // upstream error
  retryable?: boolean;
}

Exit codes (Tier 2)

// For CLI, MCP, and desktop apps:
// 0 = OK
// 1 = User error (bad input, missing config)
// 2 = Runtime error (crash, backend failure)
// 3 = Partial success (some items succeeded)

// Codes use namespaced prefixes:
// IO_, CONFIG_, PERM_, DEP_,
// RUNTIME_, PARTIAL_, INPUT_, STATE_

Reference repo

# mcp-voice-soundboard scored 46/50
# after applying shipcheck:
#
# A. Security      10/10
# B. Error Handling  8/10
# C. Operator Docs   9/10
# D. Shipping        9/10
# E. Identity       10/10