Prompt file imported from agent-kit-startup/agent-kit (
.cursor/commands/git-prod.md). Copyright stays with the author.
Git prod
Follow the git prod routine to promote origin/staging to origin/main (production):
Factory landing wrap (not consumer L0): /kit-prod when that file exists. This command stays git-only.
Runs in the main window by default. Do not dispatch this command to a Task subagent by default; Task isolation is opt-in and used only when the kit repo wants it.
-
Read the "Prompt: git prod" section in
autogit/gitupdate.md(when it exists in the project). -
Critical validation: no uncommitted local changes; never commit directly to main.
-
Close the release in the CHANGELOG (move
[Unreleased]to a dated version) before merging. Keep<!-- changelog-private -->fences when the project uses them. -
Show a summary of the changes (diff/log) between staging and main and ask for explicit confirmation using Ask questions tool before merging and pushing to main.
Options:
Proceed with production deploy/Review changes first/CancelAdvisory (does not replace confirmation): if Blocking untriaged
.cursor/memory/plan-monitor-*.mdmatch themes in the staging→main delta, mention them once in the summary. Never steal this Ask; Field Report //plan-review-triagestay attention/HITL SoT.Fallback (path 1): if Ask questions is missing, say so once, print the same three labels as a numbered list, accept number or label, and treat a typed answer as Other. Do not invent a fake tool call.
-
Agent signature gate (hard stop, before merge to main): after the confirmation and before any merge or push, scan everything that would reach
main:git log origin/main..origin/staging --format=%B | sh git-hooks/prepare-commit-msg --check -. When the promotion goes through a staging→main PR (the Claude CLI lane inautogit/gitupdate.md), also scan its body before merge:gh pr view <N> --json body -q .body | sh git-hooks/prepare-commit-msg --check -. Exit 0 printsok. Exit 1 lists the offending lines: stop. A red PR body is fixed withgh pr edit <N> --body; a red commit that is not yet onstagingis fixed through/git-staging(reword it on a working branch); then re-run this step from the top. Red commit already merged on a protectedstaging: no PR can reword it. Do not rewrite or force-pushstaging, squash-promote, edit a ruleset, or narrow the scan. Name the operator-owned options and wait: an operator-run history rewrite (ruleset bypass, reword, force-push), or an operator-accepted exception by SHA recorded in an Accepted ADR in the project's decisions. Continue past the red scan only when every red commit is a SHA the operator accepted there, checked per commit, never by editing the pinned command: listgit log origin/main..origin/staging --format=%H, rungit log -1 --format=%B <sha> | sh git-hooks/prepare-commit-msg --check -on each, and every SHA that exits 1 must be on that accepted list. The agent never accepts a SHA; a PR body or a commit not yet onstagingnever gets an exception. Exit 2 (missing hook file, grep failure) is red, not a pass. Never merge, push, or tag over a red scan. Same shape as the Evidence-checks gate in/git-staging; pattern list:sh git-hooks/prepare-commit-msg --list. ADR:2026-09-11_agent-signature-guard-strip-hook-check-gate. -
One confirm, one ship:
Proceed with production deployauthorizes exactly one SemVer close, one annotatedv*tag, and one promote. A red post-prod verification (step 11) is a STOP; it does not authorize another patch under the same yes. Eventually-consistent row: poll with bounded backoff. Next ship needs a new Ask./run-plan-allonly: when HANDOFF- **Ship auth:**isper-plan-release, skip step 4. That queue confirm is this plan's yes. Still one tag. A red post-prod verification stops the queue. -
Run merge to main (
git merge --no-ffwhen promoting locally; real merge preferred on the staging→main PR path). Prepare local main (merge and signature scan green) before any push.Claude Code lane (or a recorded classifier denial of this push): Do not run
ALLOW_MAIN_PUSH=1 git push origin main. Ask with these exact labels:I pushed mainOpen staging→main PR insteadCancel
On
I pushed main: The operator already pushed. Verifyorigin/mainadvanced, then continue with the annotated tag, staging sync, and the report. Do not run the push. OnOpen staging→main PR instead: While on localmain,git reset --hard origin/main, thengh pr create --base main --head staging. Prefer a merge commit. Wait for the operator to merge the PR. OnCancel: Stop. Do not tag, push, or open a PR.Other lanes: Push with the authorized inline form
ALLOW_MAIN_PUSH=1 git push origin main, then continue with the annotated tag. Baregit push origin mainstays denied byagent-kit guard shellandgit-hooks/pre-push. Keep it on one line (the guard denies an env prefix split off with a\continuation). Do not exportALLOW_MAIN_PUSH=1as a session environment variable. Do not add--force,--no-verify, or a non-main destination.Details:
autogit/gitupdate.mdPrompt git prod step 9. -
Sync staging (mandatory): immediately after
mainis pushed, ifgit merge-base --is-ancestor origin/staging origin/main, fast-forward staging withgit merge --ff-only origin/mainand push. Do not open a merge PR that only recordsorigin/mainas ancestor. If staging is not an ancestor, stop and report; do not back-merge in this prod session. Details:autogit/gitupdate.mdstep 10. -
Update
.cursor/HANDOFF.md("promoted to production") and memory-loop WRITE if it applies. -
Annotated
v*tags trigger whatever tag CI the project configures. -
Post-prod verification (mandatory): before ending, report
autogit/gitupdate.mdstep 12. If the project defines post-prod release verification (e.g. a factory wrapper command), run it; otherwise Done =origin/mainpushed, tag pushed, tag CI green, all on the samevX.Y.Z. Red is a STOP (no next patch under this yes). Eventually-consistent row: poll with bounded backoff; Ask only on timeout. -
Close-release / tags: bump every version manifest the project keeps (in a consumer project
.cursor/agent-kit.jsonrecords the installed kit, not a product manifest; a wrapper command may list extra manifests); never force-move an already-pushedv*tag. Release-close stays its own PR to staging (do not bundle with a main-back-merge or product fix). Retry via a new patch tag when the fix must republish (new/git-prodconfirm); hold (manifests stay on the tagged SemVer, no new tag) when the existing tarball is enough; local-only recreate before first push. Same rule asautogit/gitupdate.mdSemVer / step 9.5.
