# Snapshot Import Worker

Status: Frozen architecture note
Owner: Search Platform Architecture

## 1. Scope

This document explains the internal execution design of `Snapshot Import Worker`, the offline-import worker that operates behind the canonical snapshot-sync RPC lifecycle.

This document is subordinate to the canonical owner stack:
- machine-readable contract: `api/proto/searchfabric/v1/search_fabric.proto`
- internal owner file for this boundary: `api/proto/searchfabric/v1/snapshot_import_worker.proto`
- ingest/query semantics: `docs/specs/core/search-fabric-api.md`
- system topology and state ownership: `docs/specs/core/search-fabric-architecture.md`
- canonical error registry: `docs/specs/core/error-codes.md`

It must not redefine public snapshot RPC semantics, request/response carriers, or manifest-visibility ownership defined by those documents.

## 2. Canonical Position

The public contract for snapshot import remains:

```text
StartSnapshotSync
  -> UploadSnapshotChunks
  -> CommitSnapshotSync
```

`Snapshot Import Worker` is an internal executor behind that contract:

```text
Snapshot Client
  -> StartSnapshotSync
  -> UploadSnapshotChunks
  -> Snapshot Import Worker
  -> CommitSnapshotSync
  -> Manifest Publisher
```

The worker operates only on an admitted snapshot session that is already bound to:
- `CollectionRef`
- `snapshot_ts`
- `schema_version`
- `schema_generation_token`

The worker does not:
- accept `MutationBatch` directly,
- emit `MutationAck`,
- invent its own session fence or cutover API,
- publish reader visibility outside `CommitSnapshotSync` and manifest CAS.

## 3. Contract Binding

The worker is subordinate to the canonical snapshot carriers:
- `StartSnapshotSyncRequest`
- `SnapshotUploadRequest`
- `SnapshotChunkAck`
- `CommitSnapshotSyncRequest`
- `AbortSnapshotSyncRequest`
- `SnapshotSyncProgressSuccessResponse`

Important public contract facts that the worker must obey:
- chunk payload is a length-delimited `RowMutation` stream,
- session identity is `sync_session_id`,
- upload resume is driven by canonical `resume_token` plus `next_expected_seq`,
- commit/cutover is owned by `CommitSnapshotSync`,
- client-visible status is session/chunk based rather than `MutationAck`/item-outcome based.

## 4. Responsibilities

`Snapshot Import Worker` is responsible for internal snapshot-session execution only:

1. Consume admitted snapshot chunks for one bound session.
2. Materialize immutable metadata and/or semantic artifacts from the uploaded snapshot payload.
3. Stage internal temporary artifacts under session-owned object-store scope.
4. Maintain session-owned build progress, checksums, and cutover-preparation metadata.
5. Hand the prepared artifact set to downstream commit/publish logic used by `CommitSnapshotSync`.

It is not responsible for:
- canonical `MutationBatch` execution,
- public per-entry outcome reconstruction,
- stream-lane WAL durability semantics,
- public manifest mutation semantics,
- long-term orphan cleanup outside session/lifecycle ownership.

## 5. Execution Model

### 5.1 Session Fence Ownership

The worker must treat the `StartSnapshotSync` binder tuple as immutable admitted input:
- `collection`
- `snapshot_ts`
- `schema_version`
- `schema_generation_token`

The worker must not mint or replace those values locally.

### 5.2 Chunk Intake and Session-Owned Staging

`UploadSnapshotChunks` is the only admitted cross-boundary upload surface.

Behind that surface the worker may:
- buffer chunk payloads,
- decode the length-delimited `RowMutation` stream,
- stage temporary build state in RAM, local NVMe, or object-store temporary objects owned by the admitted session,
- maintain session-local progress/checksum state needed for `SnapshotChunkAck` and later commit validation.

Any such staging remains internal:
- it is not a second public protocol,
- it is not a public manifest-intent surface,
- it must remain deletable/repairable by session lifecycle without becoming visibility truth.

### 5.3 External Sort and Range Partitioning

Because snapshot import is session/chunk/cutover based rather than `MutationAck`/item-outcome based, the worker may use offline-import techniques that are not appropriate for the public `MutationBatch` batch lane, including:
- external sort,
- range partitioning,
- staged multi-pass artifact assembly.

Those techniques remain subject to the canonical session fence:
- they are scoped to one admitted snapshot session,
- they must not redefine public per-entry ACK order,
- they must not be described as semantics of `INGEST_MODE_BATCH`.

### 5.4 Cutover and Visibility

Raw artifact upload is not visibility.

Reader-visible cutover still requires the canonical commit path:
1. upload/session state reaches commit-admissible completion,
2. `CommitSnapshotSync` validates the admitted session root/checksums,
3. `Manifest Publisher` writes/publishes the committed manifest state,
4. committed-manifest CAS defines visibility.

The worker therefore prepares a cutover candidate; it does not define a second publish boundary. The post-validation cutover handoff is pinned separately by `api/proto/searchfabric/v1/manifest_publisher_snapshot.proto`.

## 6. Scheduling and Isolation

Snapshot import is an offline sessionized path.

Implementations may use dedicated worker pools, large temporary spill budgets, or batch-oriented placement for this path, but those are internal scheduling choices only. They must not:
- redefine the public snapshot RPC lifecycle,
- leak worker-local handles into the public API,
- collapse snapshot import into `MutationBatch` batch-lane semantics.

## 7. Failure Handling

Failure handling remains session-driven:
- upload retry/resume uses canonical `resume_token` semantics,
- expired resume-token recovery is to start a fresh `StartSnapshotSync` session,
- invalid commit/cutover attempts remain `CommitSnapshotSync` conflicts,
- temporary artifacts from abandoned sessions are cleanup inputs for session/lifecycle management rather than committed state.

Crash recovery must be session-pointer-driven:
- load admitted session state,
- trust only canonical accepted chunk progress and commit metadata,
- ignore unpublished temporary leftovers that are not referenced by the current admitted session state.

Implementation tuning may still vary for chunk-to-artifact build sizing, local-spill versus object-staging thresholds, range-partition fanout, metadata-only versus semantic-enabled specialization, and cleanup pacing for expired or aborted session staging, but any such choice must preserve the canonical snapshot RPC lifecycle and committed-manifest visibility contract described above.
