## What
Single-command wrapper that **removes the operator's choice to skip the
discipline.** Auto-detects inventory-touching changes (skills/,
skills-codex/, docs/contracts/, schemas/, etc.) and forces the FULL
pre-push gate. Runs regen sweep (sync-skill-counts, codex-hashes,
domain-map, context-map, registry, sync-hooks) preemptively for
inventory PRs.
## Why
Closes the operator-discipline gap named in
[`ship-loop/references/anti-patterns.md`
#1](https://github.com/boshu2/agentops/blob/main/skills/ship-loop/references/anti-patterns.md):
*"Running --fast pre-push on an inventory-touching PR."* Observed cost
on PR #332: ~90 min of CI cycles burning through 15 inventory validators
that the fast gate skipped.
Before this PR: operator had to remember to run
`scripts/pre-push-gate.sh` (no `--fast`) for inventory PRs. The skill
names the rule; nothing enforced it.
After this PR: `scripts/ship.sh` is the canonical entry. It detects
inventory touch and routes to the right gate. **No operator choice.**
## Files
| File | Change |
|---|---|
| `scripts/ship.sh` (NEW, 212 lines) | Detection + regen + gate routing
|
| `tests/scripts/ship.bats` (NEW, 98 lines) | 10 structural tests (10/10
PASS) |
| `skills/ship-loop/SKILL.md` | Step 5 promotes `ship.sh` as recommended
entry |
| `skills-codex/ship-loop/SKILL.md` | Codex twin mirrored |
| `skills-codex/.agentops-manifest.json`,
`skills-codex/ship-loop/.agentops-generated.json` | Hash regen |
| `registry.json` | Auto-regenerated |
## Recursive close
Three PRs to fix one operator-discipline gap:
| PR | Role |
|---|---|
| #332 | Burned ~90 min on anti-pattern #1; surfaced it |
| #331 | Documented it as a durable learning |
| **This PR** | Makes it mechanically impossible to hit |
The compounding tax is now paid. Future sessions inherit `ship.sh` as
the default and the anti-pattern stops costing time.
## Validation
- ✅ `shellcheck scripts/ship.sh`: clean
- ✅ `bats tests/scripts/ship.bats`: 10/10 PASS
- ✅ **Dogfood**: ran `ship.sh` on this very PR. Correctly detected
inventory touch (skills/, skills-codex/, registry.json) and routed to
full gate. The wrapper closing the discipline gap shipped through
itself.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Codex <codex@example.invalid>