# Understanding the Agentsview Resync Process and Its Triggers

> Learn about the agentsview resync process a full SQLite database rebuild. Discover its triggers including CLI flags API calls and file changes for efficient data management.

- Repository: [Kenn Software/agentsview](https://github.com/kenn-io/agentsview)
- Tags: deep-dive
- Published: 2026-06-20

---

**The agentsview resync process is an atomic, heavyweight rebuild of the SQLite database that re-parses every session file from source, copies protection metadata to a temporary database, and swaps it into production, triggered by CLI flags, HTTP API calls, data-version changes, or file-watcher mass-change events.**

Agentsview stores session metadata in a SQLite database and normally performs incremental syncs using file fingerprints to skip unchanged content. When the database diverges from source files, after storage backend migrations, or when permanent exclusions need reconciliation, the **resync process** safely rebuilds the entire index without per-row deletion overhead.

## What Is the Agentsview Resync Process?

Unlike the standard `SyncAll` flow, which parses only changed files and updates the database incrementally, a **full resync** is a complete reconstruction that guarantees consistency between the filesystem and the database.

### The Eight-Step Atomic Rebuild

The implementation in [`internal/sync/engine.go`](https://github.com/kenn-io/agentsview/blob/main/internal/sync/engine.go) follows a strict pipeline to ensure safety and atomicity:

1. **Lock the sync pipeline** – The engine acquires `e.syncMu` to block concurrent sync operations for the duration of the rebuild.
   
   ```go
   e.syncMu.Lock()
   defer e.syncMu.Unlock()
   ```

2. **Create a temporary database** – The original database path is preserved while a new file at `<orig-path>-resync` is opened for the rebuild.
   
   ```go
   origPath := origDB.Path()
   tempPath := origPath + "-resync"
   newDB, err := db.Open(tempPath)
   ```

3. **Copy protection data** – Excluded session IDs and trashed sessions are copied from the original database via `CopyExcludedSessionsFrom` to ensure permanent deletions are respected in the new build.

4. **Disable full-text search (FTS) during bulk loading** – The temporary database drops its FTS index, processes all insertions via `syncWriteBulk`, then rebuilds the index once after bulk completion to avoid trigger overhead.

5. **Run full-file discovery and bulk parse** – The engine calls `e.syncAllLocked(..., syncWriteBulk, true)` to parse **every** discoverable session file, ignoring the skip-cache and treating the operation as a fresh import.

6. **Evaluate swap conditions** – After loading, the engine aborts the swap if the resync was cancelled, if discovery yielded no new data while the old database held non-OpenCode sessions, or if parse failures outnumbered successes. Certain "preserved-only" outcomes are allowed to proceed.

7. **Atomic database replacement** – Upon successful validation, the temporary file is renamed over the original database using atomic filesystem operations, and the original database handle is reopened. This avoids the performance cost of deleting and reinserting millions of rows.

8. **Restore runtime state** – The engine restores the in-memory skip-cache (or clears it if the resync succeeded), updates `lastSync` and `lastSyncStats`, and notifies the `Emitter` (SSE broadcaster) of completion.

## What Triggers the Agentsview Resync?

The resync process can be initiated through five distinct mechanisms, each targeting different operational scenarios.

### Manual CLI Invocation

Users can force a full rebuild via command-line flags. The [`cmd/agentsview/sync.go`](https://github.com/kenn-io/agentsview/blob/main/cmd/agentsview/sync.go) handler parses `--full` (or `--resync`) and forwards the request to `Engine.ResyncAll`.

```bash
agentsview sync --full

# Equivalent to:

agentsview sync --resync

```

The underlying Go invocation:

```go
engine.ResyncAll(ctx, nil)   // Full rebuild with no progress callback

```

### HTTP API Endpoint

The server exposes a synchronous endpoint at `POST /api/v1/sync` that accepts a `full` query parameter. When [`internal/server/sync.go`](https://github.com/kenn-io/agentsview/blob/main/internal/server/sync.go) detects `?full=true`, it invokes `engine.ResyncAll` instead of the standard sync.

```http
POST /api/v1/sync?full=true HTTP/1.1
Host: localhost:8080

```

### Periodic Data-Version Checks

A background ticker runs every 15 minutes in [`cmd/agentsview/serve_lifecycle.go`](https://github.com/kenn-io/agentsview/blob/main/cmd/agentsview/serve_lifecycle.go). Normally triggering `SyncAll`, it calls `ResyncAll` when the storage backend's data-version has changed (e.g., after migrations), detected via `engine.DataVersionChanged()`.

```go
// Runs every 15 minutes
if engine.DataVersionChanged() {
    engine.ResyncAll(ctx, nil) // Automatic full rebuild
}

```

### File-Watcher Mass-Change Detection

When the file-watcher detects a mass-change pattern (such as an entire directory being replaced), it sets `engine.forceParse` in [`internal/sync/engine.go`](https://github.com/kenn-io/agentsview/blob/main/internal/sync/engine.go). This forces a bulk parse operation functionally equivalent to a resync, clearing stale skip-cache entries to prevent missed updates.

### Crash Recovery and Corruption Handling

On startup, the engine checks for stale temporary databases (`*-resync`) from previous crashed resyncs and removes them via `removeTempDB(tempPath)`. If `e.db.IsCorrupt()` returns true, the server may automatically invoke `ResyncAll` to rebuild the database from source files rather than attempting repair.

## Summary

- **Atomic rebuild**: The agentsview resync process constructs a new database in a temporary file and performs an atomic rename to eliminate partial-state risks.
- **Protection preservation**: Excluded sessions and trash markers are explicitly copied to the temporary database before the swap.
- **Performance optimization**: FTS indexes are dropped during bulk loading and rebuilt once afterward to minimize trigger overhead.
- **Multiple triggers**: Resyncs can be initiated manually via CLI (`--full`), HTTP API (`?full=true`), periodic data-version checks, file-watcher mass-change detection, or automatic corruption recovery.
- **Concurrency safety**: The entire operation is guarded by `Engine.syncMu` to prevent race conditions with standard sync operations.

## Frequently Asked Questions

### How does agentsview ensure atomicity during a resync?

The engine writes to a temporary database file suffixed with `-resync` and performs a filesystem rename operation only after successful validation. This atomic swap ensures that the production database is never in a partially-rebuilt state, and concurrent readers see either the old complete database or the new complete database, never a hybrid.

### What happens if a resync is cancelled mid-operation?

If the context is cancelled or validation fails (such as when parse failures exceed successes), the engine aborts the swap and deletes the temporary database. The original database remains untouched and continues serving requests, preserving data integrity.

### Can I trigger a resync programmatically from Go code?

Yes. Import the sync package and call `ResyncAll` with a context and optional progress callback. This is useful for testing or building custom orchestration tools.

```go
ctx := context.Background()
stats := engine.ResyncAll(ctx, func(p sync.Progress) {
    fmt.Printf("resync %d of %d files\n", p.Done, p.Total)
})
if stats.Aborted {
    log.Fatalf("Resync failed: %v", stats.Warnings)
}

```

### Why does agentsview disable FTS during bulk loading?

Dropping the FTS index before bulk insertion and rebuilding it afterward prevents SQLite from executing per-row trigger updates during the millions of writes typical in a full resync. According to the [`internal/db/db.go`](https://github.com/kenn-io/agentsview/blob/main/internal/db/db.go) implementation, this strategy reduces total resync time significantly compared to incremental index maintenance.