The primary state database is local to the machine, not placed automatically on a scanned removable or network volume.
- macOS:
~/Library/Application Support/optiflow/state.sqlite3 - Linux:
$XDG_STATE_HOME/optiflow/state.sqlite3 - Linux fallback:
~/.local/state/optiflow/state.sqlite3
The database uses the rollback journal and FULL synchronization. This avoids
assuming SQLite WAL shared-memory behavior is safe on arbitrary scanned
filesystems. A busy timeout handles short contention without hiding persistent
ownership conflicts.
| Table | Purpose |
|---|---|
schema_migrations |
Applied database schema versions |
scan_runs |
Run lifecycle and final manifest/report JSON |
observations |
Queryable path, size, hash, and complete observation JSON |
duplicate_groups |
Derived group JSON for each completed run |
file_cache |
Reusable unchanged-path analysis |
The cache key is:
native path + filesystem id + file id + size_bytes + modified_unix_ns + changed_unix_ns
Any mismatch causes re-analysis. Missing filesystem identity or metadata-change time disables cache lookup and insertion for that observation. Cache rows from older migrations have null handle-signature fields and are therefore not reused. A cache hit is accepted only inside a fresh, stable handle-bound observation window.
If a cached file previously had no full hash but becomes a size-based duplicate candidate, OptiFlow calculates and stores its full hash during the new scan.
Probe-enabled cache lookup also binds the resolved provider's version, canonical path, binary digest, and invocation fingerprint. A cached missing-media result from an available provider is not reused; later scans retry the provider. The probe-disabled path does not reuse a provider-bearing cache row, so unrequested media facts never lose their provider provenance. The derived media-profile document is recomputed from accepted observations and the current effective evidence-policy fingerprint, then stored only inside the immutable report. No database migration or profile-specific cache table is introduced.
The cache recognizes unchanged filesystem objects at unchanged native paths. Content-addressed recognition after arbitrary moves is a later enhancement because non-candidate files are not all hashed in the MVP.
- Insert a
runningscan row. - Perform discovery and analysis.
- Validate and stage
effective-policy.json,run.json,report.json, and their digest-bearing commit marker. - Flush the members and marker, then publish the directory with one rename.
- Store observations and groups in one database transaction.
- Mark the run
completedand attach final JSON.
Handled interruptions mark rows interrupted; internal failures mark rows
failed; a hard process failure may leave recoverable running state. None is
returned as a completed report. A still-running row with a committed v5 run
and v6 report artifact set is recovered idempotently when state is next opened. Stale staging
directories are removed; incomplete or incompatible final sets are never
promoted.
The effective-policy sidecar is referenced through the existing immutable run
artifact directory, so migrations 0001–0003 and v1-v4 run/report schemas are
unchanged. Historical runs without a sidecar have unknown policy evidence; the
current resolver never fabricates a snapshot for them.
See the artifact-set commit protocol for marker, reader-state, plan-handshake, crash-recovery, and durability semantics.