Omniscio documentation
Browse all documentation
  1. Getting Started13
  2. Sessions & Agents115
  3. Inbox & Notifications59
  4. Projects & Tasks95
  5. Automation & Scheduling75
  6. Knowledge & Memory26
  7. AI Features60
  8. Integrations100
  9. Plugins & Marketplace33
  10. Cloud & Teams56
  11. Settings & Customization58
  12. Account & Billing28
  13. Troubleshooting84
  14. CLI & API Reference22
  15. Legal & Policies4
  16. Uncategorised22

Fresh-install starting point (why a new install does not replay the migration ladder)

A brand-new install has no database, so it used to build one by replaying every migration — about 1,170 of them, measured at ~9.2 seconds on a fresh machine against 362 ms on an already-migrated one, paid once by every new user. It now starts from a committed, generated image of the finished schema instead, and falls back to the ladder whenever that image no longer matches the migrations the build ships.

What it is

When Omniscio starts and finds no database, it has to create one — 672 tables, 1,489 indexes and 847 triggers, plus the handful of rows the migrations seed. Until 2026-09-28 it did that the only way it could: by running every migration in order. That is about 1,170 steps and measured at roughly 9.2 seconds on a fresh machine, against 362 ms when the database already exists. Every new user paid it once, on their very first launch.

Now a new install copies a ready-made database into place instead. The ladder still runs — it simply finds nothing left to do, and finishes in milliseconds. The wall a user sees is a file copy.

Where to find it

There is nothing to switch on and nothing to look at: a fresh install only meets this while it is deciding how to build its database, before any window appears. You see the result rather than the mechanism — a first launch that finishes in the time it takes to copy a file. When the image is declined the install simply takes the ordinary path and pays the seconds it was meant to save; nothing on screen says which road was taken, and each refusal is logged with its reason.

How it behaves

On a database that does not exist yet, the app copies a ready-made image into place and then runs the migration ladder anyway — the ladder finds nothing left to do and finishes in milliseconds, so a new user pays a file copy instead of about 1,170 migration steps. The image is used only while it can prove it is a prefix of the migrations this build ships; anything else is a refusal, and a refusal always means building the database the ordinary way.

Why it is safe

The whole promise rests on one claim: the image is exactly what a full replay would have produced. Three things hold that up.

  • The image is generated by running the real ladder, not by transcribing it. npm run db:build-fresh-start runs the same runMigrations the app calls, on an empty in-memory database, and serializes the result. A generated SQL script was rejected for this reason: reproducing FTS5 shadow tables, virtual tables, views and blobs by hand is where a wrong schema would come from, and there would be no way to be sure.
  • A test compares the two, every build. One database is created from the committed image, another by a full replay, and they must agree on every schema object, the applied-migration set, the recorded versions and every table's content. That test is what turns "it should be identical" into something the build enforces.
  • The image carries its own record of what it contains. Its applied_migrations table is its manifest, so there is no second file that could drift out of step with it.

The rule it follows

The image may stand in for the ladder only while it can prove it is a prefix of the migrations this build ships:

  • every shipped migration at or below the image's newest entry is already applied in the image; and
  • the image holds no applied migration this build does not have.

Anything else is a refusal, and refusing is always correct — it means building the database the ordinary way, which is exactly what happened before this feature existed. The cases that land there:

  • a migration that landed late carrying an older timestamp — it sorts below the image's newest entry, so the image appears to cover it while never having applied it;
  • a migration that was deleted after the image was built;
  • a truncated, foreign or missing image.

Each refusal is logged with its reason, so a shortcut that quietly stopped firing can never look healthy.

What it deliberately does not do

  • It never touches an existing install. A database file that already exists is not read, replaced or re-stamped; that install applies its pending migrations exactly as it always has.
  • It does not unfreeze anything. The numbered baseline and the target version are untouched, and a migration that lands after the image is simply pending — the ordinary runner applies it on top.
  • It carries the seeded rows, not just the structure. Only 14 tables hold real rows in a fresh database — the default Tasks inbox list, the saved-prompt catalogue, a few singleton settings — and a schema-only starting point would have left every new user without them.
  • It does not spend a pre-migration snapshot. That snapshot exists to roll an upgrade back; a database being created has nothing to roll back to.

Where it bites

  • A stale image is a slow install, not a wrong one. If the image stops matching the ladder, the app declines it and pays the seconds it was meant to save. The build guard in tests/integration/fresh-start-equivalence.test.ts is what stops that reaching users in the first place.
  • The image is a committed binary. It is regenerated by npm run db:build-fresh-start, and editing it by hand is a defect — exactly like hand-editing a migration's timestamp.
  • One residual, stated rather than hidden. A migration written later that depends on a seeded row's exact value (a hard-coded id, say) could behave differently on a fresh install than on an upgraded one. The comparison test covers structure and normalised content, so it would not catch that; it is mitigated by the "a later migration still runs on top" test and the empty-folder boot in tests/perf/boot-trace.spec.ts, not eliminated.

For agents

The image, its generator, the refusal rule and the build test are all named below.

Where to look

  • The rule: .claude/memory/contracts/migration-ledger-contract.md, a-fresh-install-may-start-from-a-generated-image.
  • The generator: scripts/build-fresh-start-schema.ts, run by npm run db:build-fresh-start.
  • The runtime decision and the copy: src/main/db/fresh-start-schema.ts.
  • The committed image: resources/fresh-start/fresh-start-schema.sqlite.

Related

What a brand-new install walks you through is on First-time setup and the installer itself on Windows installer. The other thing that grows a user's disk is covered by Git storage compaction and Database compaction, and the wider "my computer feels slow" question starts at Slow computer.

Last verified 2026-10-06