feat(reins): gate the per-base transition behind an explicit opt-in - #50
Merged
Conversation
The one-time migration off the shared pool provisions a LightRAG instance per base and re-ingests every source through the LLM. Today it starts itself on application bootstrap as soon as retrieval is configured — an upgrade silently begins a run that costs real money and, if instance provisioning fails midway, leaves every source requeued: the base shows '0 searchable' and query() answers no_relevant_content even though the shared pool still holds the content. New installation-level flag knowledge/instance_isolation (settings key, env fallback REINS_INSTANCE_ISOLATION), off by default. It gates the boot-time migration, the start-up instance reconciliation and per-base provisioning on create; while off, every base keeps reading and writing the shared pool exactly as before. Deleting a base still terminates an instance the record remembers, so flipping the flag back off cannot leak one. The admin 'being re-processed' notice now shows only for an actually running migration — notStarted is the permanent healthy state while the flag is off.
maksymhryzodub-prog
force-pushed
the
feat/instance-isolation-opt-in
branch
from
September 2, 2026 10:08
79b6717 to
ac3d91a
Compare
Assert on the jest.fn consts directly instead of reaching through the casted gateway objects, and mock with Promise.resolve instead of async arrows that never await.
Fixed: upgrading to the isolation release no longer starts the per-base transition by itself. The boot-time migration used to requeue every source and, when instance provisioning failed midway, left bases at '0 searchable' answering no_relevant_content while the shared pool still held the content — and a successful run silently re-ingested everything through the LLM at the operator's expense. The transition now runs only after an operator flips the new knowledge/instance_isolation setting (env fallback REINS_INSTANCE_ISOLATION); until then every base keeps the shared pool behavior, and the admin no longer warns about bases that were never meant to migrate.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The one-time migration off the shared retrieval pool starts itself on application bootstrap as soon as retrieval is configured. That has two sharp edges:
migrateBaserequeues every source before re-ingesting (correctly, as a resume marker) — but if instance provisioning then fails, the base is left with every sourcequeuedandmigrationState='failed'. The UI shows N sources · 0 searchable andquery()short-circuits tono_relevant_contentwithout ever asking LightRAG, even though the shared pool still holds all the content. We hit exactly this on a 260-source base.Change
New installation-level flag
knowledge/instance_isolation(settings key; env fallbackREINS_INSTANCE_ISOLATION=true), off by default. It gates:MigrationService.onApplicationBootstrap),create().While off, every base keeps reading and writing the shared pool exactly as before —
routeLightragConfigalready sends unmigrated bases there, so nothing else changes. Deleting a base still terminates an instance the record remembers (instanceState !== 'absent'), so flipping the flag back off cannot leak one.The admin “being re-processed” notice now shows only for
migrationState === 'inProgress': with the flag off,notStartedis the permanent healthy state of every base and not worth a warning.Rollout
Existing deployments are unaffected until an operator flips the flag (
PUT /settings/knowledge/instance_isolation→true) and restarts; the migration then runs on the next boot with the shared deployment as rollback, as designed.Tests
migration.service.spec.tspins the gate: with the flag off, the migration never reads the bases,create()provisions nothing, reconciliation touches no instances; with it on, the migration proceeds. Full api suite green (242 tests),nuxt typecheckclean in admin.