Implement clone-scoped ID allocation to prevent N-way collisions

## Problem
Current ID allocation uses per-clone atomic counters (issue_counters table) that sync based on local database state. In N-way collision scenarios:
- Clone B sees {test-1} locally, allocates test-2
- Clone D sees {test-1, test-2, test-3} locally, allocates test-4
- When same content gets assigned test-2 and test-4, convergence fails

Root cause: Each clone independently allocates IDs without global coordination, leading to overlapping assignments for the same content.

## Solution
Add clone UUID to ID allocation to make every ID globally unique:

**Current format:** `test-1`, `test-2`, `test-3`
**New format:** `test-1-a7b3`, `test-2-a7b3`, `test-3-c4d9`

Where suffix is first 4 chars of clone UUID.

## Implementation

### 1. Add clone_identity table
```sql
CREATE TABLE clone_identity (
    clone_uuid TEXT PRIMARY KEY,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
```

### 2. Modify getNextIDForPrefix()
```go
func (s *SQLiteStorage) getNextIDForPrefix(ctx context.Context, prefix string) (string, error) {
    cloneUUID := s.getOrCreateCloneUUID(ctx)
    shortUUID := cloneUUID[:4]

    nextNum := s.getNextCounterForPrefix(ctx, prefix)
    return fmt.Sprintf("%s-%d-%s", prefix, nextNum, shortUUID), nil
}
```

### 3. Update ID parsing logic
All places that parse IDs (utils.ExtractIssueNumber, etc.) need to handle new format.

### 4. Migration strategy
- Existing IDs remain unchanged (no suffix)
- New IDs get clone suffix automatically
- Display layer can hide suffix in UI: `bd-cb64c226.3-a7b3` → `#42`

## Benefits
- **Zero collision risk**: Same content in different clones gets different IDs
- **Maintains readability**: Still sequential numbering within clone
- **No coordination needed**: Works offline, no central authority
- **Scales to 100+ clones**: 4-char hex = 65,536 unique clones

## Concerns
- ID format change may break existing integrations
- Need migration path for existing databases
- Display logic needs update to hide/show suffixes appropriately

## Success Criteria
- 10+ clone collision test passes without failures
- Existing issues continue to work (backward compatibility)
- Documentation updated with new ID format
- Migration guide for v1.x → v2.x

## Timeline
Medium-term (v1.1-v1.2), 2-3 weeks implementation

## References
- Related to bd-e6d71828 (immediate fix)
- See beads_nway_test.go for failing N-way tests


Delete skipped tests for "old buggy behavior"

Three test functions are permanently skipped with comments indicating they test behavior that was fixed in GH#120. These tests will never run again and should be deleted.

Test functions to remove:

1. `cmd/bd/import_collision_test.go:228`
   ```go
   t.Skip("Test expects old buggy behavior - needs rewrite for GH#120 fix")
   ```

2. `cmd/bd/import_collision_test.go:505`
   ```go
   t.Skip("Test expects old buggy behavior - needs rewrite for GH#120 fix")
   ```

3. `internal/storage/sqlite/collision_test.go:919`
   ```go
   t.Skip("Test expects old buggy behavior - needs rewrite for GH#120 fix")
   ```

Impact: Removes ~150 LOC of permanently skipped tests


Parent: bd-imj

Ensure deletions.jsonl is tracked in git (not ignored).

Update bd init and gitignore upgrade logic to:
1. NOT add deletions.jsonl to .gitignore
2. Ensure it is committed alongside beads.jsonl

The file must be in git for cross-clone propagation to work.

Acceptance criteria:
- bd init does not ignore deletions.jsonl
- Existing .gitignore files are not broken
- File appears in git status when modified


Week 1 task


Test issue 2


Add --yes flag to bd doctor --fix

bd doctor --fix prompts for confirmation, which blocks automation (CI/CD, scripts, hooks).

Requirements:
1. Add --yes or -y flag to bd doctor command
2. When --yes is passed, skip confirmation prompts
3. Still log what's being fixed (don't go completely silent)


CRITICAL: bd sync exports before pull, allowing stale DB to corrupt JSONL statuses

## Root Cause

The fix in bd-53c (reverse ZFC check) only checks COUNTS, not content. The real corruption happens when:

1. Polecat A has stale DB with old status values (e.g., status=closed for issues that are now open on remote)
2. Polecat A runs bd sync:
   - **Export FIRST**: DB (status=closed) → JSONL (overwrites correct status=open)
   - Commit: Stale JSONL committed
   - Pull: 3-way merge with remote
   - Merge uses 'closed wins' rule → status stays closed
3. Polecat A pushes → Remote now corrupted with status=closed

## Why bd-53c didn't fix it

The reverse ZFC check compares COUNTS:
```go
if jsonlCount > dbCount  // Only catches count mismatch
```

But in the corruption scenario:
- JSONL count = 5, DB count = 5 (same count!)
- Only the STATUS field differs

## The Real Fix

**PULL BEFORE EXPORT**. The sync order must be:
1. Pull from remote (get latest state)
2. Import merged JSONL to DB
3. THEN export DB changes (if any)

Current order is: Export → Commit → Pull → Import → Push

This is a fundamental architecture change to the sync flow.

## Workaround

Use --no-auto-flush and manually control the sync order, or disable daemon auto-export.

## Evidence

From user investigation:
- At 595b7943 (13:20:30): 5 open issues
- At 10239812 (13:28:39): 0 open issues
- All 5 issues had their status changed from open to closed
- Count stayed at 5 (not a deletion issue)


Add internal/ai package for LLM integration

Shared AI client for repair commands.

Providers:
- Anthropic (Claude)
- OpenAI (GPT)
- Ollama (local)

Env vars:
- BEADS_AI_PROVIDER
- BEADS_AI_API_KEY
- BEADS_AI_MODEL

Files: internal/ai/client.go (new)


bd doctor should recommend bd prime migration for existing repos

bd doctor should detect old beads integration patterns and recommend migrating to bd prime approach.

## Current behavior
- bd doctor checks if Claude hooks are installed globally
- Doesn't check project-level integration (AGENTS.md, CLAUDE.md)
- Doesn't recommend migration for repos using old patterns

## Desired behavior
bd doctor should detect and suggest:

1. **Old slash command pattern detected**
   - Check for /beads:* references in AGENTS.md, CLAUDE.md
   - Suggest: These slash commands are deprecated, use bd prime hooks instead

2. **No agent documentation**
   - Check if AGENTS.md or CLAUDE.md exists
   - Suggest: Run 'bd onboard' or 'bd setup claude' to document workflow

3. **Old MCP-only pattern**
   - Check for instructions to use MCP tools but no bd prime hooks
   - Suggest: Add bd prime hooks for better token efficiency

4. **Migration path**
   - Show: 'Run bd setup claude to add SessionStart/PreCompact hooks'
   - Show: 'Update AGENTS.md to reference bd prime instead of slash commands'

## Example output

⚠ Warning: Old beads integration detected in CLAUDE.md
  Found: /beads:* slash command references (deprecated)
  Recommend: Migrate to bd prime hooks for better token efficiency
  Fix: Run 'bd setup claude' and update CLAUDE.md

💡 Tip: bd prime + hooks reduces token usage by 80-99% vs slash commands
  MCP mode: ~50 tokens vs ~10.5k for full MCP scan
  CLI mode: ~1-2k tokens with automatic context recovery

## Benefits
- Helps existing repos adopt new best practices
- Clear migration path for users
- Better token efficiency messaging


Review and document rarely-used commands

Document use cases or consider deprecation for infrequently-used commands.

**Commands to review:**
1. bd rename-prefix - How often is this used? Document use cases
2. bd detect-pollution - Consider integrating into bd validate
3. bd migrate-hash-ids - One-time migration, keep but document as legacy

**For each command:**
- Document typical use cases
- Add examples to help text
- Consider if it should be a subcommand instead
- Add deprecation warning if appropriate

**Not changing:**
- duplicates ✓ (useful for data quality)
- repair-deps ✓ (useful for fixing broken refs)
- restore ✓ (critical for compacted issues)
- compact ✓ (performance feature)

**Deliverable:**
- Updated help text
- Documentation in ADVANCED.md
- Deprecation plan if needed


Add #nosec G304 comments to JSONL file reads in sync.go

sync.go:610 uses os.ReadFile(jsonlPath) without #nosec comment, inconsistent with other JSONL reads that have '// #nosec G304 - controlled path'.

Add comment for consistency with integrity.go:43 and import.go:316.


Implement topological sort for import ordering

Refactor upsertIssues() to sort issues by hierarchy depth before batch creation. Ensures parents are created before children, fixing latent bug where parent-child pairs in same batch can fail if ordered wrong. Sort by dot count, create in depth-order batches (0→1→2→3).


Add performance optimization to hasJSONLChanged with mtime fast-path

hasJSONLChanged() reads entire JSONL file to compute SHA256 hash on every check. For large databases (50MB+), this is expensive and called frequently by daemon.

Optimization: Check mtime first as fast-path. Only compute hash if mtime changed. This catches git operations (mtime changes but content doesn't) while avoiding expensive hash computation in common case (mtime unchanged = content unchanged).

Performance impact: 99% of checks will use fast path, only git operations need slow path.


Implement alias conflict resolution

Handle alias conflicts when multiple clones assign same alias to different issues.

## Scenario
```
Clone A: Creates bd-a1b2c3d4, assigns alias #42
Clone B: Creates bd-e5f6a7b8, assigns alias #42
After sync: Conflict! Which issue gets #42?
```

## Resolution Strategy: Content-Hash Ordering
Deterministic, same result on all clones:
```go
func ResolveAliasConflicts(conflicts []AliasConflict) []AliasRemapping {
    for _, conflict := range conflicts {
        // Sort by hash ID (lexicographic)
        sort.Strings(conflict.IssueIDs)

        // Winner: lowest hash ID (arbitrary but deterministic)
        winner := conflict.IssueIDs[0]

        // Losers: reassign to next available aliases
        for _, loser := range conflict.IssueIDs[1:] {
            newAlias := getNextAlias()
            remappings = append(remappings, AliasRemapping{
                IssueID:  loser,
                OldAlias: conflict.Alias,
                NewAlias: newAlias,
            })
        }
    }
    return remappings
}
```

## Detection During Import
File: internal/importer/importer.go
```go
func handleAliasConflicts(imported []Issue, existing []Issue) error {
    // Build alias map from imported issues
    aliasMap := make(map[int][]string)  // alias → issue IDs

    for _, issue := range imported {
        aliasMap[issue.Alias] = append(aliasMap[issue.Alias], issue.ID)
    }

    // Check against existing aliases
    for alias, importedIDs := range aliasMap {
        existingID := storage.GetIssueIDByAlias(alias)
        if existingID != "" {
            // Conflict! Resolve it
            allIDs := append(importedIDs, existingID)
            conflicts = append(conflicts, AliasConflict{
                Alias:    alias,
                IssueIDs: allIDs,
            })
        }
    }

    // Resolve and apply
    remappings := ResolveAliasConflicts(conflicts)
    applyAliasRemappings(remappings)
}
```

## Alternative Strategies (For Future Consideration)

### Priority-Based
```go
// Higher priority keeps alias
if issueA.Priority < issueB.Priority {
    winner = issueA
}
```

### Timestamp-Based (Last-Write-Wins)
```go
// Newer issue keeps alias
if issueA.UpdatedAt.After(issueB.UpdatedAt) {
    winner = issueA
}
```

### Manual Resolution
```bash
bd resolve-aliases --manual
# Interactive prompt for each conflict
```

## User Notification
```bash
$ bd sync
✓ Synced 5 issues
⚠ Alias conflicts resolved:
  - Issue bd-e5f6a7b8: alias changed from #42 to #100
  - Issue bd-9a8b7c6d: alias changed from #15 to #101
```

## Files to Create/Modify
- internal/storage/sqlite/alias_conflicts.go (new)
- internal/importer/importer.go (detect conflicts)
- cmd/bd/sync.go (show conflict notifications)

## Testing
- Test two clones assign same alias to different issues
- Test conflict resolution is deterministic (same on all clones)
- Test loser gets new alias
- Test winner keeps original alias
- Test multiple conflicts resolved in one import


Fix GH #227: bd edit broken pipe errors

bd edit command gets "broken pipe" errors when using daemon mode because editing can take minutes and the daemon connection times out.

Solution: Force bd edit to always use direct mode (--no-daemon) since it's human-only and interactive.

Fixed by checking cmd.Name() == "edit" in main.go PersistentPreRun and setting noDaemon = true.


Stealth mode global gitignore should use absolute project path

**GitHub Issue:** #538

**Problem:**
`bd init --stealth` adds `.beads/` to the global gitignore, which ignores ALL `.beads/` folders across all repositories. Users who want stealth mode in one project but open beads usage in others are blocked.

**Solution:**
Change stealth mode to use absolute paths instead of generic patterns:

**Before (current):**
```
# Beads stealth mode configuration (added by bd init --stealth)
.beads/
.claude/settings.local.json
```

**After (proposed):**
```
# Beads stealth mode: /Users/foo/work-project (added by bd init --stealth)
/Users/foo/work-project/.beads/
/Users/foo/work-project/.claude/settings.local.json
```

**Implementation:**
1. Modify `setupGlobalGitIgnore()` in `cmd/bd/init.go`
2. Get current working directory (absolute path)
3. Use absolute path patterns instead of generic ones
4. Update comment to show which project the entry is for

**Tradeoffs:**
- If project directory moves, gitignore entry becomes stale (acceptable - user can re-run `bd init --stealth`)
- Multiple stealth projects = multiple entries (works correctly)

**Testing:**
- Verify absolute path is added to global gitignore
- Verify other projects' .beads/ folders are NOT ignored
- Test with existing global gitignore file
- Test creating new global gitignore file


CLI tests (cli_fast_test.go) are slow and should be integration tests

The TestCLI_* tests in cmd/bd/cli_fast_test.go are taking 4-5 seconds each (40+ seconds total), making them the slowest part of the fast test suite.

Current timings:
- TestCLI_Import: 4.73s
- TestCLI_Blocked: 4.33s
- TestCLI_DepTree: 4.15s
- TestCLI_Close: 3.59s
- TestCLI_DepAdd: 3.50s
- etc.

These tests compile the bd binary once in init(), but then execute it multiple times per test with filesystem operations. Despite being named "fast", they're actually end-to-end CLI integration tests.

Options:
1. Tag with //go:build integration (move to integration suite)
2. Optimize: Use in-memory databases, reduce exec calls, better parallelization
3. Keep as-is but understand they're the baseline for "fast" tests

Total test suite currently: 13.8s (cmd/bd alone is 12.8s, and most of that is these CLI tests)

Fixed by reusing existing bd binary from repo root instead of rebuilding.

Before: 15+ minutes (rebuilding binary for every test package)
After: ~12 seconds (reuses pre-built binary)

The init() function now checks for ../../bd first before falling back to building. This means `go build && go test` is now fast.