Agent skill

maestro:revert

Git-aware revert of feature, phase, or individual task. Safely undoes implementation with task state rollback.

Stars 26
Forks 4

Install this agent skill to your Project

npx add-skill https://github.com/ReinaMacCredy/maestro/tree/main/skills/built-in/maestro:revert

SKILL.md

Revert -- Git-Aware Undo

Overview

Revert undoes implementation work at feature, phase, or task granularity. It creates NEW revert commits -- original history is never destroyed. After reverting, maestro task state is rolled back so tasks can be re-implemented.

Core principle: git revert is additive. It records the undo as new history. The original commits remain reachable via reflog and git log. This is the safe default.

If you are thinking about git reset --hard, stop. Read the Danger Zones section first. There are almost always safer alternatives.

When to Use

Situation Scope Command
Task produced wrong result --task <name> Revert that task's commits
Phase approach was wrong --phase <N> Revert all commits in phase N
Feature needs complete restart No scope flag Revert entire feature
Single bad commit (known SHA) Manual git revert --no-edit <sha>

Exceptions (ask your human partner):

  • Commits contain secrets or credentials (need history rewrite, not revert)
  • Revert would create unresolvable conflicts (consider branch recreation)
  • Work was never pushed (local-only reset may be simpler)

Decision Tree: revert vs reset vs branch recreation

Start here: Have the commits been pushed to a remote that others pull from?

Commits pushed to shared remote?
  |
  +-- YES --> Use `git revert` (ALWAYS)
  |           Creates new commits that undo the old ones.
  |           Safe for shared history. No force push needed.
  |
  +-- NO (local only) --> How clean do you need it?
        |
        +-- Keep changes staged --> `git reset --soft <target>`
        |   Files stay in index. You can re-commit differently.
        |
        +-- Keep changes unstaged --> `git reset --mixed <target>` (default)
        |   Files in working tree, not staged. Review before re-committing.
        |
        +-- Destroy changes completely --> `git reset --hard <target>`
        |   [DESTRUCTIVE] Working tree matches target. Changes are GONE.
        |   Requires explicit user confirmation. See Danger Zones.
        |
        +-- History is tangled beyond repair --> Branch recreation
            Create new branch from known-good point, cherry-pick what to keep.
            See reference/git-operations.md for branch recreation protocol.

Decision summary:

Strategy Pushed? Preserves history? Risk level
git revert Yes or No Yes (additive) Safe
git reset --soft No only Partial (moves HEAD) Low
git reset --mixed No only Partial (moves HEAD) Low
git reset --hard No only No (destroys changes) DESTRUCTIVE
Branch recreation Either Yes (new branch) Complex

Default: always use git revert unless you have a specific reason not to. The other strategies exist for edge cases, not convenience.

Safety Pre-Checks (MANDATORY)

Before ANY revert operation, run these checks. Do not skip them.

1. Clean worktree

bash
git status --porcelain

If output is non-empty: STOP. Uncommitted changes will complicate the revert.

  • Stash them: git stash push -m "pre-revert backup"
  • Or commit them: git add -A && git commit -m "wip: save before revert"
  • Then proceed.

2. Verify branch

bash
git branch --show-current

Confirm you are on the branch where the revert should happen. Reverting on the wrong branch is recoverable but messy.

3. Check remote state

bash
git log --oneline origin/$(git branch --show-current)..HEAD 2>/dev/null

If this shows commits: you have local-only work. A git reset might be appropriate (see Decision Tree). If this shows nothing: all commits are pushed. Use git revert only.

If the remote tracking branch does not exist, treat all commits as local-only but confirm with the user.

4. Create backup tag

bash
git tag pre-revert-$(date +%Y%m%d-%H%M%S)

This lightweight tag marks the current HEAD. If anything goes wrong, you can return here:

bash
git reset --hard pre-revert-<timestamp>

5. Verify no in-progress operations

bash
test -d .git/rebase-merge -o -d .git/rebase-apply && echo "REBASE IN PROGRESS"
test -f .git/MERGE_HEAD && echo "MERGE IN PROGRESS"
test -f .git/CHERRY_PICK_HEAD && echo "CHERRY-PICK IN PROGRESS"

If any operation is in progress: STOP. Complete or abort it first.

See reference/safety-checks.md for extended pre-flight validation (submodules, CI state, stash management).

Arguments

$ARGUMENTS

  • <feature>: Feature name (optional -- if omitted, enter Guided Selection)
  • --phase <N>: Revert only phase N (optional)
  • --task <name>: Revert only a specific task (optional)
  • No scope flag: revert the entire feature

Step-by-Step Workflow

Step 1: Parse Target Scope

Determine what to revert:

  • Feature-level: No --phase or --task flag. Revert all commits in the feature.
  • Phase-level: --phase N specified. Revert commits from phase N only.
  • Task-level: --task <name> specified. Revert a single task's commit(s).

If no <feature> argument, proceed to Guided Selection:

  1. Call maestro feature-list (MCP) or maestro feature-list (CLI) and review recent git history: git log --oneline --since="7 days ago" --grep="maestro"
  2. Present a menu grouped by feature: name, description, status, completed task count
  3. If user provides a custom feature name, use that

Step 2: Locate Feature

Match feature argument against maestro feature-list output. If not found: report and stop.

Read the feature's plan.md and feature.json to understand structure.

Step 3: Resolve Commit SHAs

Goal: Build the complete list of commits to revert for the target scope.

Task state source: Call maestro task-list or maestro status --json to get all tasks and their summaries. Task summaries from maestro task-done include commit SHAs for traceability.

BR-enhanced path (if feature.json has beads_epic_id):

bash
br list --status closed --parent {epic_id} --all --json

Parse close_reason for SHAs (format: sha:{7char}). Scope by labels for --phase/--task.

Task summary path: Parse commit SHAs from maestro task-done summaries stored in task state. Scope by phase or task name as needed.

Plan-update commits (always check):

bash
git log --oneline --all --grep="maestro(plan): mark task" -- .maestro/features/{feature-name}/plan.md

Feature creation commit (feature-level revert only):

bash
git log --oneline --all --grep="chore(maestro): " -- .maestro/features/{feature-name}/

If no SHAs found in scope: report "No completed tasks found in the specified scope. Nothing to revert." and stop.

See reference/git-operations.md for the full SHA resolution protocol with edge cases.

Step 4: Git Reconciliation

For each SHA, verify it exists:

bash
git cat-file -t {sha}

Missing SHA (rebased/squashed/force-pushed):

bash
# Try to find replacement by commit message
git log --all --oneline --grep="{original commit message}"

If found: offer replacement. If not: skip and warn.

Merge commit detection:

bash
git cat-file -p {sha}  # Check for multiple "parent" lines

If merge commit found, ask user: Proceed with -m 1, skip merge commits, or cancel.

Cherry-pick duplicate detection: Compare commit messages. For identical subjects, compare patches. Remove older duplicate from revert list.

See reference/git-operations.md for full reconciliation protocol and edge cases.

Step 5: Present Execution Plan

## Revert Plan

**Scope**: {feature | phase N | task name}
**Feature**: {feature_description} ({feature-name})

**Commits to revert** (reverse chronological order):
1. `{sha7}` -- {commit message}
2. `{sha7}` -- {commit message} [plan-update]
3. `{sha7}` -- {commit message} [feature creation]

**Affected files**:
{list of files changed by these commits}

**Task state updates**:
- {task_name}: done --> pending

**Safety**: Backup tag created at `pre-revert-{timestamp}`

Step 6: Confirm

Confirmation 1 -- Target: "Revert {scope} of feature '{description}'? This will undo {N} commits."

  • Yes, continue
  • Cancel

Confirmation 2 -- Final: "Ready to execute? This will create revert commits (original commits are preserved in history)."

  • Execute revert
  • Revise plan (exclude specific commits)
  • Cancel

See reference/confirmation-and-plan.md for the revision loop and summary format.

Step 7: Execute Reverts

Revert in reverse chronological order (newest first):

bash
# Standard commits
git revert --no-edit {sha_newest}
git revert --no-edit {sha_next}
# ...continue for each SHA

# Merge commits (if user approved)
git revert --no-edit -m 1 {merge_sha}

CRITICAL: Validate each git revert succeeds before continuing to the next.

On conflict:

  1. Report: "Merge conflict during revert of {sha}."
  2. Show conflicting files: git diff --name-only --diff-filter=U
  3. Ask user:
    • Help me resolve -- Show conflict markers and guide resolution
    • Abort remaining -- Stop here (already-reverted commits stay)
    • Accept theirs -- Keep current version for conflicting files: git checkout --theirs {file} && git add {file}

After resolving: git revert --continue

Steps 8-10: Update Task State, Feature State, Verify

Task state -- For each reverted task, the task needs to be reset to pending. Since maestro v2 does not have a direct "reset to pending" for done tasks via MCP, the orchestrator should note which tasks were reverted. If maestro task-block / maestro task-unblock can be used to cycle the state, use that. Otherwise, manually update the task state files in .maestro/features/{feature-name}/tasks/.

bash
git add .maestro/features/{feature-name}/
git commit -m "maestro(revert): update task state for reverted {scope}"

BR mirror (if beads_epic_id exists):

bash
br update {issue_id} --status open --json

Feature state (feature-level revert only): Update feature.json status back to approved or executing as appropriate.

Verify:

bash
CI=true {test_command}

Report pass/fail. If tests fail: warn user and offer to debug.

Step 11: Summary

## Revert Complete

**Scope**: {scope}
**Feature**: {feature_description}
**Commits reverted**: {count} ({impl} implementation, {plan} plan-update, {feature} feature creation)
**Tests**: {pass | fail}
**Backup tag**: pre-revert-{timestamp}

**Task state updated**: {N} tasks reset to pending

**Next**:
- `maestro:implement {feature-name}` -- Re-implement reverted tasks
- `maestro status --json` / `maestro status` -- Check overall progress
- To undo this revert: see Rollback-of-Rollback below

Concrete Examples

Example 1: Task-Level Revert (simplest)

A single task "add validation" needs to be undone.

bash
# Safety pre-checks
git status --porcelain              # Must be empty
git branch --show-current           # Confirm correct branch
git tag pre-revert-20250315-1430    # Backup

# Resolve: maestro task-list shows task "03-add-validation" is done, summary includes "sha: a1b2c3d"
# Reconcile
git cat-file -t a1b2c3d            # Verify exists

# Execute
git revert --no-edit a1b2c3d

# Update task state: reset task to pending in .maestro/features/{feature-name}/tasks/
git add .maestro/features/auth/
git commit -m "maestro(revert): update task state for reverted task 'add validation'"

# Verify
bun test

Example 2: Phase-Level Revert (multiple commits)

Phase 2 of the "payments" feature had 3 completed tasks. All must be undone.

bash
# Safety pre-checks (same as above)
git tag pre-revert-20250315-1445

# Resolve: maestro task-list shows 3 done tasks in phase 2
# SHAs from task summaries: d4e5f6g (newest), b2c3d4e, f7g8h9i (oldest)

# Execute in reverse chronological order
git revert --no-edit d4e5f6g
git revert --no-edit b2c3d4e
git revert --no-edit f7g8h9i

# Update task state for all 3 tasks: reset to pending
git add .maestro/features/payments/
git commit -m "maestro(revert): update task state for reverted phase 2"

bun test

Example 3: Feature-Level Revert (full teardown)

The entire "notifications" feature needs to be undone, including feature creation.

bash
# Safety pre-checks
git tag pre-revert-20250315-1500

# Resolve: 5 implementation commits + 2 plan-update commits + 1 feature creation
# Order by date, newest first

# Execute all reverts
git revert --no-edit {sha1}  # newest implementation
git revert --no-edit {sha2}
git revert --no-edit {sha3}
git revert --no-edit {sha4}
git revert --no-edit {sha5}  # oldest implementation
git revert --no-edit {sha6}  # plan-update
git revert --no-edit {sha7}  # plan-update
git revert --no-edit {sha8}  # feature creation

# Task state: all tasks reset to pending
# Feature state: status reset to "approved"
git add .maestro/features/
git commit -m "maestro(revert): reset feature 'notifications' fully"

bun test

Danger Zones

Operations that destroy data or rewrite history. Each requires explicit user confirmation before execution.

Operation What it does Destructive? Confirmation required
git revert Creates new undo commit No (additive) Standard 2-phase
git reset --soft Moves HEAD, keeps staged Moderate "Confirm local-only reset"
git reset --mixed Moves HEAD, unstages Moderate "Confirm local-only reset"
git reset --hard Moves HEAD, destroys working tree YES "I understand this destroys uncommitted work"
git push --force Overwrites remote history YES Double confirm + backup tag verified
git branch -D Deletes branch (even unmerged) YES Confirm branch is not needed

Rules for destructive operations

  1. Never git reset --hard without a backup tag. The tag must exist BEFORE the reset.
  2. Never git push --force to a shared branch. If others have pulled, their history diverges.
  3. Never delete a branch without verifying it is merged (or confirming the user accepts the loss).
  4. Reflog is your safety net -- but it expires (default: 90 days for reachable, 30 days for unreachable). Do not rely on reflog for long-term recovery.
  5. If in doubt, use git revert. It is always safe. The "ugly" revert commits in history are a small price for safety.

Recovery from destructive operations

bash
# Find lost commits via reflog
git reflog --all | head -20

# Recover to a reflog entry
git reset --hard HEAD@{N}

# Recover a deleted branch
git reflog | grep "checkout: moving from {branch}"
git checkout -b {branch} {sha_from_reflog}

See reference/danger-zones.md for the full destructive operations catalog with confirmation dialog templates and recovery procedures for each operation.


Rollback-of-Rollback

Sometimes you revert and then realize the revert was wrong. Here is how to undo a revert.

Strategy 1: Revert the revert commit (safest)

bash
# Find the revert commit(s)
git log --oneline --grep="Revert" | head -5

# Revert the revert (re-applies original changes)
git revert --no-edit {revert_commit_sha}

This creates a new commit that re-applies the original changes. History shows: original --> revert --> re-apply. Clean and traceable.

Use when: You want to fully undo the revert and restore all original changes. Works whether or not the revert was pushed.

Strategy 2: Cherry-pick original commits

bash
# If you know the original SHAs (in chronological order, oldest first)
git cherry-pick {original_sha_oldest}
git cherry-pick {original_sha_next}
# ...continue for remaining commits

Use when: You want to re-apply only SOME of the original commits, not all. Or when the revert commit itself has been amended/squashed and reverting it would not cleanly restore the originals.

Strategy 3: Reset to backup tag (local-only)

bash
# If commits were never pushed and backup tag exists
git reset --hard pre-revert-{timestamp}
git tag -d pre-revert-{timestamp}  # Clean up tag after

Use when: The revert was local-only and you want to pretend it never happened. This is a destructive operation -- see Danger Zones.

After rollback-of-rollback

Update maestro task state to reflect re-applied work:

  • Reset tasks back to done state with updated summaries (use the new SHA if cherry-picked)
  • Update feature status if needed
  • Re-close BR issues if applicable: br update {issue_id} --status closed --json

Relationship to Other Commands

Recommended workflow:

  • maestro init --json / maestro init -- Initialize maestro for the project
  • maestro feature-create / maestro feature-create -- Create a new feature
  • maestro plan-write / maestro plan-write -- Write the implementation plan
  • maestro:implement -- Execute the implementation
  • maestro:review -- Verify implementation correctness
  • maestro status --json / maestro status -- Check progress
  • maestro:revert -- You are here. Undo implementation if needed

Revert is the safety valve for maestro:implement. It undoes commits and resets task state so you can re-implement with maestro:implement. Use maestro status --json after reverting to confirm the feature state is correct. Revert depends on atomic commits from implementation -- the cleaner the commit history, the more precise the revert.

Expand your agent's capabilities with these related and highly-rated skills.

ReinaMacCredy/maestro

maestro-skill-author

Create, update, or debug maestro built-in skills. Covers SKILL.md frontmatter, reference directory structure, step-file architecture, build-time embedding, naming conventions, alias management, and registry validation. Use when creating a new maestro built-in skill, modifying an existing SKILL.md, adding reference files, debugging skill loading failures, updating the skills registry, or working on the skills full port. Also use when frontmatter validation fails, skills don't appear in skill-list, or reference files fail to load.

26 4
Explore
ReinaMacCredy/maestro

maestro:brainstorming

Use before any creative work - creating features, building components, adding functionality, or modifying behavior. Explores user intent, requirements and design before implementation.

26 4
Explore
ReinaMacCredy/maestro

mcp-builder

Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK).

26 4
Explore
ReinaMacCredy/maestro

maestro:plan-review-loop

Deep-review any plan (maestro, Codex, Claude Code plan mode, or plain markdown) using iterative subagent review loops with BMAD-inspired adversarial edge-case discovery. Spawns reviewer subagents that find issues using pre-mortem, inversion, and red-team techniques, auto-fixes them with structured fix strategies, and re-reviews until the plan passes with zero actionable issues. Use when the user says 'review the plan', 'deep review', 'check the plan thoroughly', 'review loop', 'validate before approving', or wants rigorous plan validation before execution. Also use proactively before plan-approve when the plan is complex or high-risk.

26 4
Explore
ReinaMacCredy/maestro

maestro:research

Structured research workflow for maestro features. Guides tool selection across three tiers (codebase exploration, Context7 for library docs, NotebookLM for deep analysis), defines research patterns, finding organization via memory_write, and completion criteria. Use during the research pipeline stage after feature_create and before plan_write. Also use when investigating a problem space, comparing technical approaches, gathering context on unfamiliar code, or needing to understand external library APIs before making architectural decisions.

26 4
Explore
ReinaMacCredy/maestro

cli-for-agents

Designs or reviews CLIs so coding agents can run them reliably: non-interactive flags, layered --help with examples, stdin/pipelines, fast actionable errors, idempotency, dry-run, and predictable structure. Use when building a CLI, adding commands, writing --help, or when the user mentions agents, terminals, or automation-friendly CLIs.

26 4
Explore

Didn't find tool you were looking for?

Be as detailed as possible for better results