# AO Update Reference

Detailed reference for the ao-update skill.

## File Categories

### Protected Files (Never Touched)

These files are NEVER modified by ao-update:

| Path | Purpose |
|------|---------|
| `.agent/ops/constitution.md` | Project-specific constitution |
| `.agent/ops/memory.md` | Project-specific learnings |
| `.agent/ops/focus.json` | Current session state |
| `.agent/ops/issues/*.md` | Project's issue backlog |
| `.agent/ops/issues/references/*` | Issue reference files |
| `.agent/ops/baseline.md` | Project's test baseline |
| `.agent/ops/time-tracking.jsonl` | Session time tracking (append-only events) |
| `.agent/ops/tools.json` | Tool configuration |
| `CLAUDE.md` | User's Claude Code configuration (project root) |
| `AGENTS.md` | User's agent documentation (project root) |

**CRITICAL**: Any file matching `.agent/ops/*` or named `CLAUDE.md` or `AGENTS.md` at project root is protected.

### Mergeable Files

These files are merged to preserve your settings:

| Path | Merge Strategy |
|------|----------------|
| `.ao/skills/*/preferences.md` | Your keys win on conflict |
| `.ao/skills/*/preferences.pattern` | Your patterns preserved |

**Merge logic:**
1. Start with the new (source) file
2. For each key that exists in your (target) file:
   - Keep your value (your keys win)
3. For each key that only exists in source:
   - Add the new key to your file
4. Preserve any custom keys you added that aren't in source

### Overwritable Files

These files are copied from the new AO version:

- `.ao/skills/*/*.md` - Core AO skills
- `.ao/prompts/*.md` - AO prompts
- `.ao/agents/*.md` - AO agent definitions
- `.ao/reference/*.md` - Reference documentation
- `.github/agents/*.md` - GitHub agents
- `.github/prompts/*.md` - GitHub prompts
- `.claude/commands/ao-*.md` - Claude Code commands
- `.claude/agents/ao-*.md` - Claude Code agents
- `.opencode/commands/ao-*.md` - OpenCode commands

**Note:** Files with local modifications (detected via git diff) will prompt for confirmation before overwriting.

### Orphaned Files

Files in your project that don't exist in the source AO version are **preserved** (not deleted). These may be:
- Custom skills you created
- Project-specific command overrides
- Local customizations

## Rollback

If the update causes problems:

1. **Return to main branch:**
   ```bash
   git checkout main
   ```

2. **Delete the update branch:**
   ```bash
   git branch -D ao-update-*
   ```

3. **Verify your state is restored:**
   ```bash
   git status
   cat .agent/ops/constitution.md  # Should be unchanged
   ```

Your project state is preserved in the main branch.

## Pre-flight Checks

Before updating, ao-update verifies:

1. **Git repository** - Must be in a git repository for safety
2. **Source folder exists** - The specified source folder must exist
3. **Source is AO repo** - Source must contain `.ao/` or `.github/agents/`
4. **MANDATORY: Clean working tree** - **ABORTS if dirty** (see below)

### MANDATORY: Clean Git Status Check

**CRITICAL FOR ROLLBACK SAFETY**

```bash
# Check BEFORE any update operation
git status --porcelain
```

**If any output (dirty working tree):**

**ABORT IMMEDIATELY with this exact message:**

```
✗ ERROR: Working tree is dirty
✗ Cannot proceed with update (safety check failed)

Dirty files:
  M .agent/ops/focus.json
  M CLAUDE.md

Instructions:
  1. Commit or stash your changes
  2. Re-run ao-update

Reason: Clean working tree required for safe rollback.
```

**IMPORTANT:**
- NEVER auto-stash (risk of silent data loss)
- NEVER proceed with dirty state (breaks rollback)
- ALWAYS abort with instructions
- This check is NON-NEGOTIABLE

**Why This Is Mandatory:**

The ao-update uses a branch-based pattern for rollback:
1. Create branch `ao-update-{timestamp}`
2. Apply updates on branch
3. User reviews via `git diff main`
4. Rollback via `git checkout main`

If working tree is dirty:
- Rollback becomes impossible or dangerous
- User could lose uncommitted work
- Branch switching can fail or cause conflicts

## Update Process

### 1. Create Branch
```bash
# Branch name format: ao-update-{timestamp}
BRANCH_NAME="ao-update-$(date +%s)"
git checkout -b "$BRANCH_NAME"
```

### 2. Categorize Files
- Scan source and target directories
- Build file lists: protected, mergeable, overwritable
- Detect local modifications

### 3. Dry-Run Summary (Default)
Shows:
- Files that will be preserved (protected)
- Files that will be merged (preferences)
- Files that will be overwritten
- Local modifications that require confirmation

### 4. Execute (After Confirmation)
- Copy overwritable files from source
- Merge preference files (your keys win)
- Skip protected files entirely

### 5. Post-Update Summary
Shows:
- Branch name created
- Files changed (git diff --stat)
- Review command (git diff main)
- Commit/merge instructions
- Rollback instructions

## Environment Variables

| Variable | Purpose | Default |
|----------|---------|---------|
| `AO_UPDATE_SOURCE` | Default source directory | (none) |
| `AO_UPDATE_BRANCH_PREFIX` | Branch name prefix | `ao-update-` |
| `AO_UPDATE_YES` | Auto-confirm prompts | (empty) |
| `AO_UPDATE_DEFAULT_YES` | Skip confirmation in dry-run | (empty) |

## Exit Codes

| Code | Meaning |
|------|---------|
| 0 | Success |
| 1 | Error (see message for details) |
| 2 | Validation failed |
| 3 | User cancelled |

## Examples

### Basic Usage
```bash
# Clone latest AO
git clone https://github.com/weholt/ao.git /tmp/ao-latest

# Run update (shows what will change)
/ao-update /tmp/ao-latest

# Review and confirm when prompted
# [Shows summary and asks for confirmation]
```

### Dry-Run Only
```bash
# Just see what would change
/ao-update /tmp/ao-latest --dry-run
```

### Auto-Confirm
```bash
# Skip confirmation prompts
/ao-update /tmp/ao-latest --yes
```

### After Update
```bash
# Review the changes
git diff main

# If satisfied, commit and merge
git add -A
git commit -m "Update AO to latest version"
git checkout main
git merge ao-update-*

# Clean up
git branch -D ao-update-*
```

## Troubleshooting

### "Not in a git repository"
Initialize git first:
```bash
git init
git add .
git commit -m "Initial commit"
```

### "Source directory does not appear to be an AO repository"
Verify source folder structure:
```bash
ls -la /path/to/source/.ao
ls -la /path/to/source/.github/agents
```

### "Working tree has uncommitted changes"
Commit or stash your changes first:
```bash
git add .
git commit -m "WIP"
# or
git stash
```

### "Locally modified files will be overwritten"
Review the local modifications and decide:
```bash
# See what you changed
git diff path/to/file

# If you want to keep your changes, cancel and:
git stash
/ao-update /path/to/source
# Then manually re-apply your changes
```

## Advanced Usage

### Update from Local Clone
```bash
# Clone to persistent location
git clone https://github.com/weholt/ao.git ~/.ao-latest

# Update later
git -C ~/.ao-latest pull
/ao-update ~/.ao-latest
```

### Update from Specific Branch
```bash
# Clone specific branch
git clone --branch feature-x https://github.com/weholt/ao.git /tmp/ao-feature-x
/ao-update /tmp/ao-feature-x
```

### Custom Branch Name
```bash
AO_UPDATE_BRANCH_PREFIX="my-ao-update-" /ao-update /tmp/ao-latest
```

## File Operations Reference

### rsync vs cp

The skill prefers `rsync` when available for efficiency:

```bash
# rsync flags used:
rsync -av --checksum
# -a: archive mode (preserves permissions, times, etc.)
# -v: verbose
# --checksum: verify by checksum (not just timestamp)
```

Fallback to `cp -rv` if rsync not available.

### Preference Merge Pseudo-Code

```
function merge_preferences(target_file, source_file):
    user_keys = parse_frontmatter_keys(target_file)
    source_data = parse_frontmatter(source_file)

    result = source_data  # Start with new version

    for key in user_keys:
        if key in result:
            # User's value wins
            result[key] = user_keys[key]
        else:
            # Keep user's custom key
            result[key] = user_keys[key]

    write_frontmatter(target_file, result)
```

## Related Commands

| Command | Purpose |
|---------|---------|
| `/ao-help` | Show all available commands |
| `/ao-housekeeping` | Clean up project issues and clutter |
| `/ao-status` | Show current issue status |

## See Also

- [AO Workflow Guide](../../prompts/ao-help.prompt.md)
- [Issue Management](../ao-task/SKILL.md)
- [Git Operations](../ao-git/SKILL.md)
