Reset Stage
SkillCommunicationReset the stage branch from main and re-merge all "on stage" PRs. Auto-resolves merge conflicts by accepting incoming changes (-X theirs). Posts a Slack notification only when an --apply run produced conflicts. Use when stage has conflicts, drift, or needs a clean rebuild.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Reset Stage skill
What this skill tells your AI
The instructions your AI receives, as published by jesusfilm/core in .cursor/skills/reset-stage/SKILL.md and read by ahel’s review.
Automates the stage branch reset process documented in
apps/docs/docs/04-engineering-practices/02-deployment/index.md.
When to use
- User says "reset stage", "rebuild stage", "stage is broken"
- User says "what if stage reset" or "dry run stage"
- Stage branch has conflicts preventing new PR merges
- Stage has drifted from main due to closed/stale PRs
Steps
-
Ensure the working tree is clean. If dirty, ask the user to stash or commit.
-
Run the script. Default is dry-run (safe, no changes):
# Dry run — default, safe, no changes (never posts to Slack) ./tools/scripts/reset-stage.sh # Actual reset (destructive, prompts for confirmation). # Posts to Slack only if the run produced conflicts. ./tools/scripts/reset-stage.sh --apply # Hard opt-out: never post to Slack, even if conflicts occur. ./tools/scripts/reset-stage.sh --apply --no-slack -
Show the full output to the user.
-
If
--applywas used, remind the user:- Stage deploy workflows will trigger automatically on push
- Slack was notified only if the run had auto-resolved or failed conflicts. Clean apply runs and dry runs stay silent — this is by design (ENG-3679) so the channel only fires when someone's on-stage PR may have actually been touched.
- Any truly unresolvable PRs (very rare) need their authors to investigate
Trigger phrases
- "reset stage"
- "rebuild stage"
- "stage is broken"
- "what if stage reset"
- "dry run stage"
How conflict resolution works
The problem
Resetting stage from main and re-merging all "on stage" PRs used to
replay the exact same conflicts that caused the reset in the first place.
The reset didn't actually get you unstuck.
The solution: accept incoming changes (-X theirs)
The script uses a two-phase merge for each PR:
- Try a clean merge —
git merge origin/<branch> --no-ff - If that conflicts — abort, retry with
git merge -X theirs - If -X theirs still fails (rare; e.g. modify/delete conflicts) — force-resolve remaining files by checking out the PR's version
-X theirs tells Git to resolve conflicted hunks by taking the incoming
(PR branch) side. Non-conflicting changes from both sides are still merged
normally via 3-way merge — it only overrides the conflicted parts.
Why this is safe
- Stage is ephemeral. It exists purely for integration testing and gets force-pushed on every reset. Nobody branches off it.
- PR branches are the source of truth. Each feature branch goes through
proper code review before merging to
main. Stage is just a preview. - Worst case is a broken stage build. Which is the same outcome as a bad manual conflict resolution — and the fix is to run the reset again.
- The PR branch is never modified. Only the stage branch is affected.
Merge order
PRs are merged newest-first (highest PR number). When two PRs modify the same lines, the one merged second "wins" for those hunks. This is deterministic — same PR set + same order = same result.
Report categories
| Category | Meaning |
|---|---|
| Clean merge | No conflicts at all |
| Auto-resolved | Had conflicts, resolved automatically via -X theirs |
| Failed | Could not be resolved even with force (very rare) |
| Missing branch | Remote branch no longer exists |
Recovery
If stage is broken after a reset
Run the reset again. The script resets stage to main and force-pushes,
so every reset starts completely fresh.
If an engineer's PR is causing problems on stage
- The engineer's PR branch is never touched — only stage is affected.
- The engineer rebases their branch against
mainand pushes. - The next stage reset picks up the fixed version automatically.
- No manual merge conflict resolution is ever needed on the stage branch.
If you need to exclude a specific PR
Remove the "on stage" label from that PR before running the reset. The script only merges PRs that currently have the label.
Prerequisites
ghCLI must be authenticated (gh auth login)- Doppler must be authenticated for Slack notifications (
doppler login)- Secrets:
STAGE_RESET_SLACK_BOT_TOKEN,SLACK_ENGINEERING_CHANNEL_ID - Location: Doppler project
core, configdev
- Secrets:
- If Doppler is not authenticated, the script runs but skips Slack
- A confirmation prompt prevents accidental real resets (
--apply)
Signals
- GitHub stars
- 25
- Forks
- 15
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
reset-stage- Source
- github.com/jesusfilm/core