Ship
jg-push
Commit the current task's changes, signed when signing is set up, and push the current branch.
- May change
- Commits and pushes
- Usage
/jg-push
When to use it
Use it when a reviewed change is ready to publish. In a checkout shared with other agents, run it in the session that made the change, so it commits only that task's files.
Example
Invoke the skill by name in your coding agent, followed by any text it should consider.
/jg-push
Commits this task's files, or every change when there is no task, signing the commit when signing is set up, and pushes the current branch.
SKILL.md
What the agent reads
The complete instructions your agent loads when you invoke jg-push.
Invocation
This skill runs only when the developer invokes it. Execute its workflow with the available tools. Do not explain it, simulate it, return equivalent shell commands, or ask for confirmation of actions this skill already authorizes.
Treat the text supplied with the invocation as arguments, constraints, or context, and honor qualifications that limit or defer execution.
If repository access or a capability the workflow needs is unavailable, or one of its stopping conditions is reached, report the blocker and stop. Never simulate success.
Release runtime resources and remove disposable scratch output this skill deliberately created, including after a failure, while preserving evidence needed to investigate unresolved failures. Report anything retained within this skill’s output format. This cleanup is a narrow exception to the skill’s write limits. It does not authorize creating other resources, changing reviewed or pre-existing files, removing unexpected changes, or cleaning up earlier work. Every other write is defined by this skill’s workflow.
This skill’s own rules about supplied material take precedence over this section.
Task scope
- The task’s files are the files created, modified, renamed, or deleted for the current task in this conversation, counting both paths of a rename, plus any files the developer names or confirms. Planning files under
coding-agent-planning/, such asplan.mdandmilestones.md, count only when the developer names or confirms them. - Only paths Git reports as changed count. Ignored files, such as build and test output, and files with no net change against
HEAD, such as scratch files created and then removed, are left out. - Without a task in this conversation, the scope is the complete uncommitted change, except planning files the developer hasn’t named or confirmed. When such planning files are changed, the scope’s other changed paths count as the task’s files.
- A scope supplied as empty, such as by
jg-executefor a push-only run, stays empty; it never falls back to the complete uncommitted change. - If the task’s files can’t be established confidently, for example after context compaction, list the likely paths and ask the developer to confirm them before going further.
- The scope’s fingerprint is the tree it would commit, which doesn’t depend on what is staged. With
GIT_INDEX_FILEpointing at a temporary file outside the worktree, rungit read-tree HEAD, orgit read-tree --emptywhen the branch has no commits yet, thengit --literal-pathspecs add -A -- <paths>(git add -Awithout a task), with every path quoted for the shell, so neither the shell nor Git reads a bracket or asterisk in a path as a pattern, thengit write-tree. The tree ID it prints is the fingerprint. Delete the temporary file afterwards. Also record the whole worktree’s fingerprint, the same steps withgit add -A, so later steps can tell whether anything outside the scope changed. - For a task, every rule in this skill that refers to the uncommitted change, the worktree, or what
git add -Awould stage applies to the task’s files instead. Uncommitted changes outside the scope are reported, but they are never reviewed, staged, or committed. When they could affect the checks, such as edits to shared code, configuration, dependencies, or tests, readiness needs the checks run against the exact proposed tree in isolation, such as the fingerprint tree written out withgit checkout-index -a --prefix=<temporary directory>/from a temporary index loaded bygit read-tree <tree>, nevergit archive, which drops files markedexport-ignore; without that, verification is incomplete. - Changes in a file the developer named or confirmed count as the task’s own. A file in scope that also holds changes neither made for the task nor confirmed by the developer is a blocker: report it, and do not treat those changes as part of the task.
Workflow
Execute the repository-publication workflow through completion unless one of the blocking conditions below requires stopping. jg-push is a skill, not the literal git push shell command, and it must not be reduced to running git push, generating shell commands, or describing what the user should run.
The mandatory execution sequence is:
- Resolve the active branch’s exact push remote and destination branch before changing Git state.
- When the scope has uncommitted changes, inspect them as required below, then stage exactly the scope. For a task, stage its files with
git --literal-pathspecs add -- <paths>, quoting each path for the shell, and leaving out any path whose deletion is already staged, including the old path of a staged rename; that path stays in the commit’s pathspec. Without a task, stage the complete worktree withgit add -A, including all staged, unstaged, untracked, deleted, and renamed changes. Never stage part of the scope or anything outside it. - Create the new commit from the staged scope using the rules under
## Commit rules. For a task, limit the commit to its files withgit --literal-pathspecs commit … -- <paths>; without a task, commit the complete staged state. Add-sand-Sas## Commit rulesdecides. - Push only the active branch’s current
HEADto the resolved remote and destination branch using an explicit one-branch refspec. Do not rely on an implicit or multi-ref push.
These steps are the authoritative meaning of jg-push; the detailed rules below only determine how to perform them safely and when execution must stop. When the scope has no uncommitted changes, including when the scope is empty, do not create an empty commit and use the push-only path only for the exact intended unpublished commits established under the rules below.
Reuse repository context, change analysis, and successful verification only when the exact commits, current HEAD, destination, and applicable state evidence still match. A previous Ready to commit verdict from jg-review is conclusive readiness evidence while its exact HEAD, reviewed paths, scope fingerprint, and whole-worktree fingerprint all still match; do not repeat the review in that case. Discard stale positive readiness evidence, but retain previously reported blocking findings or incomplete conditions until the affected current state has been inspected specifically to confirm their resolution. Do not perform a full review, broad repository exploration, or repeat checks solely because this skill was invoked.
- Locate the repository root and gather, in as few read-only Git invocations as practical, the active branch or detached
HEADstate, current Git operation and conflict state, complete worktree status (to separate the scope from other changes), configured upstream and remotes, existing local commits not represented by relevant known remote-tracking refs, and recent commit messages only when needed to infer the commit convention or whether the branch uses sign-offs. Inspect submodule details only when the worktree or unpublished commit range contains a submodule change. Reuse information already established during the current task instead of rediscovering it. - Resolve the active branch’s intended push remote and destination branch from branch-specific push configuration, repository-level push configuration, the configured upstream, repository context, and any existing remote branch; do not assume that the tracking upstream is always the push destination. Require one unambiguous remote and destination branch before staging, committing, or pushing.
- Establish one execution path:
- Use the commit-and-push path when the scope has uncommitted changes. Treat any existing unpublished commits as a separate push range rather than part of the new commit’s cohesive purpose.
- Use the push-only path when the scope has no uncommitted changes and the exact local commit or commit range is already established as intended for the resolved destination. This includes the exact verified commit preserved after a previous execution of this skill failed to push to the same destination.
- When an unpublished commit or commit range has not already been established as expected for the resolved destination, inspect its exact hashes, complete commit messages, and the changed contents represented by each commit, using a commit-by-commit diff or equivalent history inspection in as few invocations as practical. Use the cumulative diff to understand the final effect, but do not use it as the sole security inspection because content introduced and later removed remains in the pushed history. Proceed only when every unpublished commit is intentional for the destination and the inspected history contains no secrets or sensitive data. The range may contain multiple independently cohesive commits and does not need one shared purpose.
- When neither uncommitted changes in scope nor expected unpublished commits exist, report that there is nothing to commit or push and stop without treating it as a failure.
- For the commit-and-push path, when matching reusable analysis already covers the uncommitted change’s cohesive purpose, unintended files, and possible secrets or sensitive data, confirm the current state fingerprint and inspect only the concise path and diff summary needed to compose the commit message and confirm the expected scope. Otherwise, inspect the scope’s uncommitted change once, including staged and unstaged changes, deleted and renamed paths, untracked-file contents, and relevant submodule changes. Independently, for any unpublished commit range in either execution path, reuse prior analysis only when it covers the exact commit hashes and destination; otherwise inspect it as required by item 3. Do not require the complete unpublished range to share one purpose. Do not expand either inspection into the correctness and readiness analysis owned by
jg-review, and do not reread the rootREADME.mdor repository documentation unless the commit convention, expected commit range, or destination cannot otherwise be resolved. - Stop before committing or pushing when there are unresolved conflicts or an in-progress merge, rebase, cherry-pick, or revert;
HEADis detached; a changed or unpublished submodule state cannot be safely represented and published; the scope’s uncommitted change or any unpublished commit history appears to contain secrets or sensitive data; a file in scope holds changes that were neither made for the task nor confirmed by the developer; a relevant verification failure is known; signing is set up or required and the test signature fails; a previously reported blocking review finding or incomplete condition remains unresolved for the state being published; the destination is ambiguous; any unpublished commit is not established as intentional for that destination; or the scope’s changes cannot form one cohesive new commit. - This skill itself adds no new verification requirements and must not initiate tests, linting, typechecking, formatting, builds, or the
jg-reviewworkflow. Reuse successful relevant checks associated with the exact affected inputs or commit tree. If verification already required by the task, the repository’s coding instructions (such asAGENTS.mdorCLAUDE.md), or an explicit repository commit or push workflow is missing, stale, or failed, stop before staging, committing, or pushing and report the specific blocker; do not run or waive the check. A failure thatjg-reviewtreated as non-blocking does not count as failed verification. Checks assigned to commit or push hooks run through those hooks, not separately in advance; do not disable hooks or bypass their failures. - For the commit-and-push path, after publication prerequisites are satisfied, establish the exact expected commit state. Decide signing and sign-off under
## Commit rules, and when the commit will be signed, create a test signature before staging, such asgit commit-tree -S -m 'signing check' 4b825dc642cb6eb9a060e54bf8d69288fbee4904, which signs a throwaway commit of the empty tree. Record the currentHEADcommit, or that the branch has no commits yet, and reuse the most recently confirmed state fingerprint only when no applicable input has changed since it was computed; otherwise recompute the fingerprint as## Task scopedefines it. From the repository root, stage the scope as mandatory step 2 describes. Do not stage part of the scope or omit changes in it. - For the commit-and-push path, recompute the fingerprint after staging and require it to equal the expected commit state. If it differs, do not commit; discard stale analysis and inspect the changed content before re-establishing the expected state. When it matches, compose the message under
## Commit rules, and create the commit as mandatory step 3 describes, with one or two-marguments as appropriate. Inspect the created commit once and confirm its hash, expected message, the sign-off trailer when one was added, a parent exactly matching theHEADrecorded before staging, or no parent when the branch had no commits, and a tree ID equal to the fingerprint. For a signed commit, also confirm a good signature withgit verify-commit, or, when SSH signing has nogpg.ssh.allowedSignersFileso Git can’t verify it locally, agpgsigheader in the commit, and report it as signed but not verifiable here. Without a task, also confirm a clean worktree. For a task, also confirm that nothing in scope is left uncommitted and that everything outside the scope, including other staged entries, is untouched; report what remains outside the scope. If signing, hooks, or tooling fail; the commit parent, tree, paths, or metadata differ from the expected state; or hooks leave additional uncommitted changes in scope, do not push and report the blocker without bypassing or amending the failure. - Push only the active branch’s current
HEADto the single resolved destination using an explicit one-branch refspec. Explicitly prevent tag-following or configured multi-ref behavior from publishing additional refs, and pass--recurse-submodules=check, so a configured submodule push can’t publish other repositories. If no upstream exists, establish it only as part of the same explicit push when the remote and destination branch are unambiguous. Do not fetch as a separate precondition; rely on the normal push to enforce the remote fast-forward requirement. Never assume a remote or branch, switch branches, merge, rebase, reset, stash, clean, amend, bypass hooks with--no-verify, or use--forceor--force-with-lease. - Report whether this skill used the commit-and-push or push-only path, the created commit hash and subject when applicable, whether the commit is signed and verified, signed but not verifiable here, or unsigned, and whether it carries a sign-off, the pushed
HEADhash, active branch, remote destination, and push result. If the push is rejected or otherwise fails, preserve all local commits and clearly report the exactHEADand destination so a later unchanged invocation can identify and execute the push-only retry safely.
Commit rules
Follow the repository’s established commit conventions. Otherwise use Conventional Commits <type>(<scope>): <summary>, deriving the type and scope from repository evidence and omitting the scope when none is accurate. Use one -m when the subject fully explains the change, or a subject plus one explanatory -m body when durable context is needed. The message must describe every change in the commit as one cohesive purpose. Sign the commit with -S when signing is set up, meaning commit.gpgSign is true or user.signingKey is set, or when the repository’s coding instructions require signed commits. Add the sign-off -s when the coding instructions require one, recent commits on the branch carry Signed-off-by trailers, or the contributing guide asks for sign-offs. A requirement in the coding instructions is mandatory: never drop it or retry without it. When signing is set up or required and the test signature fails, stop before staging and report the error; never fall back to an unsigned commit. Otherwise, leave out whichever doesn’t apply without asking the developer. Put -s and -S before any -- pathspec.