# /grid:resume - Resume Interrupted Mission

---
name: grid:resume
description: Resume an interrupted Grid mission from last checkpoint
argument-hint: "[--validate | --from block-N | --rollback]"
allowed-tools:
  - Read
  - Glob
  - Grep
  - Bash
  - Task
---

## Mission State to Resume
!`cat .grid/STATE.md 2>/dev/null || echo "No mission to resume"`

## Last Checkpoint
!`cat .grid/CHECKPOINT.md 2>/dev/null || echo "No checkpoint found"`

## Warmth Context
!`cat .grid/WARMTH.md 2>/dev/null || echo "No warmth accumulated"`

---

Resume an interrupted Grid mission. Reconstructs full context from `.grid/` files and continues execution from the exact stopping point.

## USAGE

```
/grid:resume              # Auto-detect and resume
/grid:resume --validate   # Validate state only, don't resume
/grid:resume --from block-02  # Resume from specific block
/grid:resume --rollback   # Rollback last partial work, then resume
```

## BEHAVIOR

### Step 1: State Detection

Check if resumable state exists:

```python
def detect_state():
    """Detect if there's a resumable state."""

    if not file_exists(".grid/STATE.md"):
        return {"status": "no_state", "message": "No Grid state found"}

    state = parse_yaml(read(".grid/STATE.md"))

    if state.get("status") == "completed":
        return {"status": "completed", "message": "Mission already completed"}

    if state.get("status") == "active":
        # Check staleness (no update in 10+ minutes)
        updated = parse_datetime(state.get("updated_at"))
        if datetime.now() - updated > timedelta(minutes=10):
            return {"status": "stale", "state": state}
        else:
            return {"status": "active", "message": "Mission still active"}

    if state.get("status") in ["checkpoint", "interrupted"]:
        return {"status": "resumable", "state": state}

    if state.get("status") == "failed":
        return {"status": "failed", "state": state}

    return {"status": "unknown", "state": state}
```

### Step 2: Display Resume Prompt

Show the user what will be resumed:

```
GRID RESUME
===========

Mission: {cluster_name}
Status: {status}
Last Activity: {updated_at}

PROGRESS
--------
Phase: {phase}/{phase_total} ({phase_name})
Block: {block}/{block_total}
Wave: {wave}/{wave_total}

Progress: [{progress_bar}] {percent}%

COMPLETED WORK
--------------
{list of completed blocks with commits}

RESUME POINT
------------
{description of where execution will continue}

WARMTH AVAILABLE
----------------
- {N} codebase patterns
- {N} gotchas
- {N} user preferences

Ready to resume?
Type 'continue' to proceed or 'status' for more details.

End of Line.
```

### Step 3: State Validation

Validate state consistency before resuming:

```python
def validate_state(state):
    """Validate state is consistent and resumable."""

    validations = []

    # 1. Verify claimed commits exist
    completed_blocks = glob(".grid/phases/*/SUMMARY.md")
    for summary_path in completed_blocks:
        summary = parse_yaml(read(summary_path))
        for commit in summary.get("commits", []):
            exists = bash(f"git cat-file -t {commit['hash']} 2>/dev/null")
            if not exists:
                validations.append({
                    "check": "commit_exists",
                    "status": "FAIL",
                    "detail": f"Commit {commit['hash']} not found",
                })
            else:
                validations.append({
                    "check": "commit_exists",
                    "status": "PASS",
                    "detail": f"Commit {commit['hash']} verified",
                })

    # 2. Verify claimed files exist
    for summary_path in completed_blocks:
        summary = parse_yaml(read(summary_path))
        for artifact in summary.get("artifacts_created", []):
            if file_exists(artifact["path"]):
                validations.append({
                    "check": "file_exists",
                    "status": "PASS",
                    "detail": f"File {artifact['path']} exists",
                })
            else:
                validations.append({
                    "check": "file_exists",
                    "status": "FAIL",
                    "detail": f"File {artifact['path']} missing",
                })

    # 3. Verify plans exist for pending blocks
    current_block = state["position"]["block"]
    total_blocks = state["position"]["block_total"]
    for block_num in range(current_block, total_blocks + 1):
        plan_path = f".grid/plans/*-block-{block_num:02d}.md"
        if glob(plan_path):
            validations.append({
                "check": "plan_exists",
                "status": "PASS",
                "detail": f"Plan for block {block_num} exists",
            })
        else:
            validations.append({
                "check": "plan_exists",
                "status": "FAIL",
                "detail": f"Plan for block {block_num} missing",
            })

    # 4. Check for conflicting checkpoints
    checkpoint_files = glob(".grid/CHECKPOINT*.md")
    if len(checkpoint_files) > 1:
        validations.append({
            "check": "single_checkpoint",
            "status": "FAIL",
            "detail": f"Multiple checkpoint files found: {checkpoint_files}",
        })

    return validations
```

Display validation results:

```
STATE VALIDATION
================

[PASS] Commit abc123 verified
[PASS] Commit def456 verified
[PASS] File package.json exists
[PASS] File astro.config.mjs exists
[PASS] Plan for block 02 exists
[PASS] Plan for block 03 exists
[WARN] Scratchpad has stale entries (>10 min old)

Validation: 6 PASS, 0 FAIL, 1 WARN

State is valid. Ready to resume.

End of Line.
```

### Step 4: Context Reconstruction

Build full context from state files:

```python
def reconstruct_context():
    """Reconstruct execution context from .grid/ files."""

    context = {}

    # 1. Load central state
    state = parse_yaml(read(".grid/STATE.md"))
    context["cluster"] = state["cluster"]
    context["position"] = state["position"]
    context["mode"] = state.get("mode", "autopilot")

    # 2. Load checkpoint if exists (PRIMARY RESUME SOURCE)
    if file_exists(".grid/CHECKPOINT.md"):
        checkpoint = parse_yaml(read(".grid/CHECKPOINT.md"))
        context["checkpoint"] = checkpoint

        # Extract position from checkpoint (more accurate than STATE.md)
        if checkpoint.get("position"):
            context["position"] = checkpoint["position"]

        # Extract completed threads
        context["completed_threads"] = checkpoint.get("completed_threads", [])

        # Determine resume point from current_thread
        current = checkpoint.get("current_thread", {})
        context["resume_thread"] = current.get("id", 1)
        context["resume_status"] = current.get("status", "unknown")
        context["last_action"] = current.get("last_action", "")
        context["partial_work"] = current.get("partial_work", "")
        context["files_touched"] = current.get("files_touched", [])

        # Extract checkpoint reason for handling strategy
        context["checkpoint_reason"] = checkpoint.get("reason", "unknown")
        context["checkpoint_type"] = checkpoint.get("checkpoint_details", {}).get("type", "unknown")

        # Extract warmth from checkpoint (fresher than WARMTH.md)
        checkpoint_warmth = checkpoint.get("warmth", {})
        context["checkpoint_warmth"] = checkpoint_warmth
    else:
        context["checkpoint"] = None
        context["completed_threads"] = []
        context["resume_thread"] = 1
        context["checkpoint_reason"] = None
        context["checkpoint_type"] = None

    # 3. Collect completed block summaries
    context["completed_blocks"] = []
    for summary_path in sorted(glob(".grid/phases/*/SUMMARY.md")):
        summary = parse_yaml(read(summary_path))
        context["completed_blocks"].append(summary)

    # 4. Load warmth
    if file_exists(".grid/WARMTH.md"):
        context["warmth"] = read(".grid/WARMTH.md")
    else:
        context["warmth"] = None

    # 5. Load decisions
    if file_exists(".grid/DECISIONS.md"):
        context["decisions"] = read(".grid/DECISIONS.md")
    else:
        context["decisions"] = None

    # 6. Load pending plan for current block
    current_block = context["position"]["block"]
    plan_files = glob(f".grid/plans/*-block-{current_block:02d}.md")
    if plan_files:
        context["current_plan"] = read(plan_files[0])
    else:
        context["current_plan"] = None

    # 7. Load plan summary for wave structure
    plan_summary_files = glob(".grid/plans/*-PLAN-SUMMARY.md")
    if plan_summary_files:
        context["plan_summary"] = read(plan_summary_files[0])
    else:
        context["plan_summary"] = None

    return context
```

### Step 5: Resume Execution

Spawn continuation based on state:

#### Case A: Checkpoint Resume

```python
if context["checkpoint"] and context["checkpoint"]["type"] in ["human_verify", "decision", "human_action"]:
    # Checkpoint was hit, check if user has responded
    user_response = context["checkpoint"].get("user_response")

    if not user_response:
        # Still waiting for user
        display_checkpoint_prompt(context["checkpoint"])
        return

    # User has responded, spawn continuation
    Task(
        prompt=f"""
First, read ~/.claude/agents/grid-executor.md for your role.

You are a **continuation executor**. A previous Program was interrupted at a checkpoint.

<warmth>
{context['warmth']}
</warmth>

<completed_threads>
{format_completed_threads(context['completed_threads'])}
</completed_threads>

<checkpoint_response>
User response: {user_response}
</checkpoint_response>

<resume_instructions>
Previous Program stopped at: Thread {context['resume_thread']}
Checkpoint type: {context['checkpoint']['type']}

CRITICAL: Verify previous commits exist before continuing:
```bash
git log --oneline -5
```

If commits are missing, STOP and report state corruption.

Continue execution from thread {context['resume_thread'] + 1}.
</resume_instructions>

<plan>
{context['current_plan']}
</plan>

Execute remaining threads. Document any deviations.
""",
        subagent_type="general-purpose",
        description=f"Resume block {context['position']['block']} from thread {context['resume_thread'] + 1}"
    )
```

#### Case B: Session Death Resume

```python
if context["checkpoint_reason"] in ["session_death", "timeout", "context_overflow", "user_interrupt"]:
    # Session died, need to assess partial work using checkpoint data

    # Build warmth from checkpoint (fresher) or fallback to WARMTH.md
    warmth_content = ""
    if context.get("checkpoint_warmth"):
        cw = context["checkpoint_warmth"]
        warmth_content = f"""
Codebase Patterns:
{yaml.dump(cw.get('codebase_patterns', []))}

Gotchas:
{yaml.dump(cw.get('gotchas', []))}

User Preferences:
{yaml.dump(cw.get('user_preferences', []))}

Almost Did (rejected decisions):
{yaml.dump(cw.get('almost_did', []))}

Fragile Areas:
{yaml.dump(cw.get('fragile_areas', []))}
"""
    elif context.get("warmth"):
        warmth_content = context["warmth"]

    Task(
        prompt=f"""
First, read ~/.claude/agents/grid-executor.md for your role.

You are a **recovery executor**. The previous session died unexpectedly.

<session_death_context>
Reason: {context['checkpoint_reason']}
Last Action: {context.get('last_action', 'Unknown')}
Files Touched: {context.get('files_touched', [])}
Partial Work: {context.get('partial_work', 'Unknown')}
</session_death_context>

<warmth>
{warmth_content}
</warmth>

<completed_threads>
{format_completed_threads(context['completed_threads'])}
</completed_threads>

<position>
Phase: {context['position'].get('phase', 1)}/{context['position'].get('phase_total', 1)}
Block: {context['position'].get('block', 1)}/{context['position'].get('block_total', 1)}
Wave: {context['position'].get('wave', 1)}
Thread: {context['resume_thread']}/{context['position'].get('thread_total', 1)}
</position>

<recovery_instructions>
1. **Verify completed work:**
   ```bash
   git log --oneline -10
   ```
   Check that commits from completed_threads exist. If missing, this is state corruption.

2. **Check for partial work:**
   ```bash
   git status
   git diff --stat
   ```
   - If clean: Previous thread completed but checkpoint wasn't cleared. Start from next thread.
   - If dirty with good changes: Commit them, continue.
   - If dirty with broken changes: `git checkout -- .` to discard.

3. **Assess files touched:**
   Files that were being worked on: {context.get('files_touched', [])}
   Verify these exist and are in a good state.

4. **Continue from recovery point:**
   - Last action was: "{context.get('last_action', 'Unknown')}"
   - Resume from thread {context['resume_thread']}
   - If thread was in progress, re-execute it
   - If thread completed (commit exists), start next thread

5. **Write checkpoint before each thread** for future recovery.
</recovery_instructions>

<plan>
{context['current_plan']}
</plan>

Recover and continue execution. Document your recovery assessment.
""",
        subagent_type="general-purpose",
        description=f"Recover from {context['checkpoint_reason']} and resume block {context['position'].get('block', 1)}"
    )
```

#### Case C: Failure Resume

```python
if context["checkpoint"] and context["checkpoint"]["type"] == "failure":
    # Previous attempt failed, present options

    display(f"""
FAILURE RECOVERY
================

Previous execution failed:

Block: {context['checkpoint']['block']}
Thread: {context['checkpoint']['thread']}
Error: {context['checkpoint'].get('error', 'Unknown')}

PARTIAL WORK
------------
{context['checkpoint'].get('partial_work', 'None recorded')}

OPTIONS
-------
1. retry     - Spawn fresh executor with failure context
2. rollback  - Revert partial work, restart block
3. skip      - Skip this block, continue to next
4. manual    - User will fix manually, then continue

Enter choice:
""")

    # Wait for user choice, then act accordingly
```

#### Case D: Wave Boundary Resume

```python
if not context["checkpoint"]:
    # No checkpoint, resume from wave/block boundary

    Task(
        prompt=f"""
First, read ~/.claude/agents/grid-executor.md for your role.

Resuming mission from block boundary.

<warmth>
{context['warmth']}
</warmth>

<completed_blocks>
{format_completed_blocks(context['completed_blocks'])}
</completed_blocks>

<current_position>
Starting block: {context['position']['block']}
Wave: {context['position']['wave']}
</current_position>

<plan>
{context['current_plan']}
</plan>

Execute the full block plan.
""",
        subagent_type="general-purpose",
        description=f"Execute block {context['position']['block']}"
    )
```

## OUTPUT FORMATS

### No State Found

```
GRID RESUME
===========

No Grid state found in current directory.

Either:
  1. Initialize a new mission: /grid
  2. Change to a directory with .grid/

End of Line.
```

### Mission Completed

```
GRID RESUME
===========

Mission already completed.

Cluster: {cluster_name}
Completed: {completed_at}
Blocks: {total_blocks}
Commits: {total_commits}

To start a new mission, run /grid

End of Line.
```

### Stale State Detected

```
GRID RESUME
===========

Stale state detected.

Cluster: {cluster_name}
Last Activity: {updated_at} ({time_ago} ago)
Status: {status}

The previous session appears to have died unexpectedly.

RECOVERY OPTIONS
----------------
1. continue   - Attempt to continue from last known state
2. validate   - Validate state before continuing
3. rollback   - Rollback to last complete block
4. inspect    - Show detailed state for manual assessment

Enter choice:

End of Line.
```

### Validation Failed

```
GRID RESUME
===========

State validation failed.

ISSUES FOUND
------------
[FAIL] Commit abc123 not found in git history
[FAIL] File src/components/Header.astro missing

POSSIBLE CAUSES
---------------
- Git history was rewritten (rebase, reset)
- Files were manually deleted
- Different branch checked out

RECOVERY OPTIONS
----------------
1. rebuild  - Rebuild from last valid checkpoint
2. inspect  - Show full state for manual assessment
3. abort    - Clear state and start fresh

Enter choice:

End of Line.
```

### Resuming

```
GRID RESUME
===========

Resuming mission...

Cluster: {cluster_name}
Resume Point: Block {block}, Thread {thread}
Warmth: {warmth_count} patterns loaded

Spawning continuation executor...

End of Line.
```

## STATE UPDATES

After successful resume:

1. Update `STATE.md`:
   - Set status: active
   - Update updated_at timestamp
   - Set session_id to new value

2. Clear checkpoint if consumed:
   - Move CHECKPOINT.md to CHECKPOINT_ARCHIVE.md
   - Or delete if no longer needed

3. Archive scratchpad:
   - Append old entries to SCRATCHPAD_ARCHIVE.md
   - Clear SCRATCHPAD.md for new session

## EDGE CASES

### Multiple Grid Directories

If `.grid/` exists in both current directory and parent:

```
GRID RESUME
===========

Multiple Grid states found:

1. ./grid/ - "blog" cluster (45% complete)
2. ../.grid/ - "api" cluster (80% complete)

Which mission to resume? Enter 1 or 2:
```

### Corrupted State

If STATE.md is unparseable:

```
GRID RESUME
===========

State file corrupted.

Attempting recovery from artifacts...

Found:
- 2 SUMMARY.md files (blocks 01, 02 complete)
- 15 commits matching Grid patterns
- Plan files for blocks 01-06

Reconstructed state:
- Cluster: blog (inferred)
- Position: Block 03 (inferred)
- Progress: ~33% (estimated)

Accept reconstructed state? (yes/no)
```

### Conflicting Git State

If working directory has uncommitted changes:

```
GRID RESUME
===========

Uncommitted changes detected.

Modified files:
- src/components/Header.astro
- src/layouts/BaseLayout.astro

These may be partial work from the previous session.

OPTIONS
-------
1. commit   - Commit changes and continue
2. stash    - Stash changes and continue from last commit
3. discard  - Discard changes and continue from last commit
4. inspect  - Show diff for manual review

Enter choice:
```

## IMPLEMENTATION NOTES

### MC Context Budget

Resume command should:
1. Stay under 30% context for state reading
2. Spawn executor for actual work
3. Not read source code files directly

### Warmth Injection

Always inject warmth when spawning continuation:
- Prevents repeating mistakes
- Applies learned codebase patterns
- Respects user preferences

### Checkpoint Cleanup

After successful continuation:
- Archive checkpoint to prevent re-resuming
- Update state to reflect progress
- Clear scratchpad for fresh session

End of Line.
