Skip to content
Development
Command

/push

Push direction: ports local mechanism-script fixes back to the hub as a reviewed PR. Opposite of /update.

From plugin
shiploop
97 skills3 agents7 commands
> /plugin marketplace add anshss/shiploop
> /plugin install shiploop@shiploop

Command definition

push.md
description: Push direction: ports local mechanism-script fixes back to the hub as a reviewed PR. Opposite of /update.
allowed-tools: Bash, Read

/shiploop:push

**The push direction of the harness-code update channel.** Reconciles the hub against improvements you've made locally to mechanism scripts inside THIS workspace. Think of it as `git push` for harness code: `sync-port.sh` is the machinery (already generalized in v1.2.0), this command wraps it into a one-command action for interactive use.

Companion to `/shiploop:update` (pull). The two commands close the loop on fleet drift.

What it does (procedure)

1. **Preconditions:** `GOVERN_UPSTREAM_HARNESS_REPO` set in `workspace.sh`; the workspace scaffolded from v1.2.0 or later (so `scripts/govern/sync-port.sh` is present); a local hub clone reachable. 2. **Drift detection** via `scripts/govern/sync-templates.sh --check` — mirrored files you've changed vs the last sync marker. 3. If drift → **invoke `scripts/govern/sync-port.sh`** (the existing porter). It:

  • Cuts a branch off `origin/main` in the hub clone.
  • Spawns a headless porter that genericizes your changes (strips your identity strings, adds

placeholders like `__META_NAME__`, `__GITHUB_ORG__`).

  • Validates: `bash -n` on changed shell files + forbidden-identity-strings gate on ADDED lines +

scaffold-test-suite baseline diff.

  • On any gate failure, files an escalation and exits non-zero. NEVER pushes an unvalidated port.
  • On pass, opens a PR **against the canonical hub** for **HUMAN review** — routing by your access

posture (see below): a same-repo PR when you can push to the hub, otherwise a cross-repo PR from your fork (auto-created via `gh repo fork` when you don't already have one). 4. **Report** the PR URL (if any) and the marker state.

The three access postures (push v2 — the contribution funnel)

`sync-port.sh` derives where the branch lands and where the PR opens from **git + GitHub**, not from workspace config — it reads the templates clone's `origin`, finds the canonical hub as that repo's `parent` (falling back to `origin` itself when there is no parent), and checks your push permission. So the PR **always** targets the real canonical hub, never stranding inside your own fork:

| Posture | Your templates clone | What `/push` does | |---|---|---| | **direct-access** | you can push to `origin`, and `origin` **is** the hub (the maintainer) | push the branch to `origin`, open a **same-repo** PR (bare head). Historical behavior — unchanged. | | **fork** | `origin` is **your fork** of the hub (has a `parent`), you can push to it | push to `origin` (your fork), open a **cross-repo** PR against the hub (`<you>:<branch>`). | | **plain-clone** | a clone of the hub with **no push access** (the common adopter) | `gh repo fork --clone=false` creates your fork, the branch is pushed there, and a **cross-repo** PR opens against the hub. No manual fork step needed. |

If GitHub can't resolve the clone's repo (offline, a non-GitHub remote), sync-port **degrades safely** to the historical direct-to-origin push — it only takes the fork funnel on an *affirmative* no-push signal, never on an unknown one.

Why HUMAN review, never auto-merge

`sync-port.sh` in v1.2.0 gained a `--no-merge` mode for safe first rollouts. `/push` invokes it with `--no-merge` unconditionally — this is an INTERACTIVE command driven by an operator, and the whole point is a human reviews the genericized port before it lands on the global skill. Even if `--no-merge` weren't set, the hub's three-factor auto-merge guard (own-author + own-branch-pattern

  • no-forks) would block the governor from merging it. Both belts, both suspenders.

Workspace-specific files (`scripts/lib/workspace.sh`, `package.json`, repo lists, `governor/` operator-data files) are intentionally NEVER pushed. `sync-templates.sh` filters them out at the git-pathspec level. This command's summary tells the operator so — no surprises.

Phase 0 — Preconditions

Must be in a meta-repo workspace

`scripts/lib/workspace.sh` exists AND `scripts/govern/sync-port.sh` + `scripts/govern/sync-templates.sh` exist. If either sync script is missing, the workspace was scaffolded before v1.2.0 — instruct the operator:

This workspace is missing scripts/govern/sync-{port,templates}.sh — scaffold predates v1.2.0.
Run /shiploop:update first to install the sync channel, then re-run /shiploop:push.

`GOVERN_UPSTREAM_HARNESS_REPO` must be set

Source `scripts/lib/workspace.sh` (in a subshell) and check. If empty, STOP and print:

GOVERN_UPSTREAM_HARNESS_REPO not set in scripts/lib/workspace.sh — the sync channel is inert.

To enable /shiploop:push:
  1. Get a local clone of the hub to port INTO. Either is fine (push v2 handles both):
       • a PLAIN clone of https://github.com/anshss/shiploop  — no fork needed; /push auto-forks
         on your behalf if you lack push access, and
       • a clone of YOUR fork of the hub                      — /push opens a cross-repo PR from it.
     Call its path $HUB_DIR.
  2. Edit scripts/lib/workspace.sh and set:
       GOVERN_UPSTREAM_HARNESS_REPO="shiploop"
       GOVERN_UPSTREAM_HARNESS_DIR="$HUB_DIR"
  3. Re-run /shiploop:push.

Local hub clone must be reachable

`sync-port.sh` reads `GOVERN_UPSTREAM_HARNESS_DIR` (or `wsp_repo_localdir` from workspace.sh) to locate the templates repo working dir. If the resolved directory isn't a git repo, `sync-port.sh` will itself escalate with a clear reason. That's fine — surface its output.

`gh` must be authenticated

`gh auth status` must succeed. `sync-port.sh` calls `gh pr create` and errors out clean if not.

Phase 1 — Dry-run first (recommended by default)

Unless the operator passed `--run` or `--yes` in `$ARGUMENTS`, run the dry-run first:

bash scripts/govern/sync-port.sh --dry-run

The dry-run prints the plan: drifted mirrored files, the branch it WOULD cut, the forbidden

Read more
@anshss
Ships withshiploop

You like claude code? You like shipping products? You love shiploop! ❤️

91 skill3 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
9
Star history of anshss/shiploop on GitHub, a chart by star-history.com

Other commands on shiploop.

compress

compress

Command

Compress this workspace's CLAUDE.md by moving mechanically-triggered rules into just-in-time rule packs. Operator-triggered,…

@anshss@anshssInstall Command
flows

flows

Command

Flow registry: extract inventories flows, list shows status, file queues validation tickets.

@anshss@anshssInstall Command
setup

setup

Command

Scaffold a new shiploop workspace or upgrade one. Routine bumps -> /update; push fixes upstream -> /push.

@anshss@anshssInstall Command
statusline

statusline

Command

Show the governor fleet in your Claude Code statusline. Explicit, opt-in, and chains — it never replaces an existing statusline.

@anshss@anshssInstall Command
update

update

Command

Pull direction: bumps this workspace's scripts to match the latest hub template. Opposite of /push.

@anshss@anshssInstall Command
validated

validated

Command

Record durable, git-tracked evidence that a ticket was actually validated (interactive-session twin of the governor's…

@anshss@anshssInstall Command

More commands from other plugins.

build
Auto-invoked

build

Command

Implement tasks incrementally — build, test, verify, commit. Add "auto" to run the whole plan in one approved pass.

@addyosmani@addyosmaniInstall Command