English | 中文
ShipGate is a read-only, fail-closed publication gate for macOS apps and Codex skills. It inventories the actual local or Git publication surface, scans configured high-risk indicators, validates split language README navigation and project evidence, verifies release assets, and emits path-safe Markdown and JSON reports. It never pushes, tags, creates releases, uploads assets, or changes authentication.
Runtime dependencies: Python 3.11+ standard library only.
Every project using ShipGate for a public push, tag, or release must have these exact root files:
README.md: English default page with a real Markdown link toREADME_ZH.mdin its first 10 content lines.README_ZH.md: Chinese page with a real Markdown link back toREADME.mdin its first 10 content lines.
Aliases, plain-text filename mentions, external links, anchors, path traversal, and one mixed bilingual page do not satisfy the gate. ShipGate proves this navigation structure; it does not claim to judge translation quality.
Clone or download this repository, then choose one explicit scope.
Repository scope, recommended for team reproducibility:
python3 scripts/install_skill.py --scope repo --repo <target-repository>User scope, available across repositories:
python3 scripts/install_skill.py --scope userLegacy CODEX_HOME compatibility scope:
python3 scripts/install_skill.py --scope codex-homeClaude Code user scope, available across repositories:
python3 scripts/install_skill.py --scope claude-userClaude Code repository scope, recommended for team-controlled projects:
python3 scripts/install_skill.py --scope claude-repo --repo <target-repository>Preview any installation without writing:
python3 scripts/install_skill.py --scope user --dry-runThe installer stages a bounded runtime copy and atomically replaces only a
validated shipgate target. It refuses unknown existing targets unless
--force is explicitly supplied, and still rejects broad or symlinked targets.
Current Codex skill locations and AGENTS.md behavior were checked against the
OpenAI Build skills and
AGENTS.md
documentation on 2026-07-12.
Install to repository or user scope, restart Codex if the skill list is stale,
then invoke $shipgate. Codex loads SKILL.md and runs the bundled checker from
the installed skill directory.
Use the repository-level AGENTS.md as the operational adapter. It requires the
same CLI, report review, and nonzero-exit stop rules.
Install with --scope claude-user for personal use or --scope claude-repo
for one repository. Restart Claude Code if the skill directory was created
while a session was already running, then invoke /shipgate or let Claude load
it automatically. CLAUDE.md remains the repository-level release adapter; the
installed skill and Codex both run the same checker.
Claude Code skill locations were checked against Anthropic's official skills documentation on 2026-07-18.
The compatibility entry point remains available:
python3 scripts/shipgate.py check <project> --project-type codex-skillInstalled package entry points are also available:
python3 -m shipgate --version
python3 -m shipgate check <project> --operation local| Operation | Publication source | Asset policy |
|---|---|---|
local |
Git tracked + untracked non-ignored working files, or a non-Git filesystem tree | not-applicable when none are supplied |
public-push |
Git working candidate plus reachable blobs, commit/tag metadata, refs, and historical paths | Assets normally not-applicable |
tag |
Clean HEAD or explicit git-ref, including reachable blobs and publication metadata |
Assets optional |
release |
Clean HEAD or explicit git-ref, including reachable blobs and publication metadata |
At least one asset, unless --source-only is explicit |
Public operations require a Git repository. Shallow history, unverified
submodules, missing refs, or Git read failures block the operation. tag and
release also require a clean working tree.
Examples:
python3 scripts/shipgate.py check . \
--operation public-push \
--project-type codex-skill \
--report-md build/shipgate/public-push.md \
--report-json build/shipgate/public-push.json
python3 scripts/shipgate.py check . \
--operation release \
--project-type macos-app \
--asset dist/App.dmg \
--asset dist/App.zip
python3 scripts/shipgate.py check . \
--operation release \
--project-type codex-skill \
--source-onlycodex-skill:SKILL.mdmust satisfy ShipGate's documented strict frontmatter subset. Ifagents/openai.yamlexists, its required interface metadata must be readable and complete.macos-app: Xcode project data must contain macOS platform evidence, orPackage.swiftmust declare macOS in its actualplatformsargument.
Auto detection returns candidates and evidence. Zero candidates or multiple candidates fail; explicitly selecting a type does not bypass missing evidence.
ShipGate uses one immutable inventory for all checks. It does not silently skip
.github, large files, UTF-16 text, binary ASCII indicators, broken links,
special files, or unreadable publication entries. Findings expose stable codes,
relative paths, optional line numbers, and safe fingerprints, never full matched
credentials.
Git checks also scan working/index/historical path names, ref names, commit and
annotated-tag messages, tag names, and typed author/committer/tagger names and
emails. Secret-bearing path or ref text is replaced by a deterministic label in
both report formats. Private paths copied into commit messages remain blocking;
this intentionally includes CI-host home paths such as /home/<CI-user>/...
and has no CI-host allowlist.
Configured redaction rules include dedicated GitHub, OpenAI, Anthropic, Slack, AWS access-key, private-key-header, private host-path, and RFC 1918 private IPv4 indicators. IPv4 classification uses the standard library and only blocks the three RFC 1918 ranges, rather than every address Python classifies as private.
Unix home-path detection has one bounded fixture exception: only .py or
.swift files under a tests or *Tests directory may use the synthetic
usernames alice and example. The same names outside test source, and every
other username inside test source, remain blocking.
Environment filenames are intentionally fail-closed. Any publication-surface
file named .env or beginning with .env. is blocked, including
.env.example; there is no filename allowlist. Publish a fully sanitized
template as env.example instead. An ignored, untracked local .env stays
outside the Git working surface. Git ignore does not exempt a .env-style path
once that path is present in the selected publication inventory.
Reports include schema/tool versions, operation, project evidence, source
commit and Git state, inventory counts/errors/exclusions, gates, assets and
recommendations. Project root is always represented as .; report writes are
atomic and deterministic.
Exit codes:
0: all applicable gates passed; warnings may remain.1: policy or gate failure.2: invalid CLI usage or parameter combination.3: trusted checking could not complete because of I/O or execution errors.
Any nonzero code is a hard stop for public release work.
Install the optional development tools into an isolated environment:
python3 -m venv .venv
.venv/bin/python -m pip install -e '.[dev]'
make validate PYTHON=.venv/bin/pythonmake validate runs compile checks, Ruff lint and format checks, mypy, unit and
integration tests, line/branch coverage thresholds, and ShipGate local
self-check. External official skill validation is deliberately separate:
make official-skill-validate \
QUICK_VALIDATE=<path-to-external-quick_validate.py> \
PYTHON=.venv/bin/pythonSee Architecture, Threat model, Report schema, and Code review.
After ShipGate passes, a person or host agent may separately verify GitHub auth and remote state, push, create an annotated tag, create a release, upload the verified assets, and compare downloaded SHA-256 values. Those writes are intentionally outside ShipGate.