Feat: negotiate the sessions database schema version and add an in-place upgrade step - #836
Open
AmaadMartin wants to merge 3 commits into
Open
Feat: negotiate the sessions database schema version and add an in-place upgrade step#836AmaadMartin wants to merge 3 commits into
AmaadMartin wants to merge 3 commits into
Conversation
added 3 commits
August 8, 2026 20:21
DatabaseSessionService pinned the stored version to exactly '1', so a future bump would throw at init() for every existing deployment with no way to recover. schema_version.ts now owns an accepted-version set, the version this build stamps, and upgradeSessionDatabaseSchema() to move a database up in place.
Records the steps for the next version bump, the backward-compatibility window carried over from adk-python, and why this package keeps one MikroORM entity set instead of one per version.
…uard SUPPORTED_SCHEMA_VERSIONS has one member and it is LATEST_SCHEMA_VERSION, so the SUPPORTED state could never occur and both callers passed the same two constants. A membership check replaces the enum and the classifier. Behaviour is unchanged on every reachable input.
AmaadMartin
force-pushed
the
feat/session-db-schema-version-negotiation
branch
from
August 9, 2026 03:23
e280399 to
3d291af
Compare
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.
Please ensure you have read the contribution guide before creating a pull request.
Link to Issue or Description of Change
N/A
Problem:
DatabaseSessionServiceaccepts exactly one stored schema version,'1'. Bumping that constant would makeinit()throw for every existing deployment, and nothing can re-stamp the row. The failure comes frominit(), so an operator cannot even build a working service to repair the database from.Solution:
core/src/sessions/db/schema_version.tsnow owns a set of accepted versions, the version this build stamps, andupgradeSessionDatabaseSchema(), which applies the additive DDL and re-stamps a database in place. The upgrade step opens its own connection, so it does not depend oninit()succeeding. Behaviour is unchanged for every database today, because the set has one member and it is the latest.Collision check:
gh pr listover all 300 open fork PRs found no PR implementing schema-version negotiation. #740 (events cascade foreign key) and #797 (MikroORM v7) also editoperations.tsandschema.ts, but onlyensureDatabaseCreated,StorageSessionandStorageEvent. Both targetmain, so this branches frommaintoo.Design notes:
assertCompatibleVersion()membership check guards both entry points. An earlier revision modelled four states in an enum with a parameterized classifier; the complexity review showed the supported-but-older state cannot occur while the accepted set has one member, so that state machine was removed. The next bump adds the constant, adds it to the set, repointsLATEST_SCHEMA_VERSION, and adds onelogger.warnline, which is step 6 of the README runbook.schemas/v0.pyandschemas/v1.pyat runtime; MikroORM freezes entity metadata atinit(), so the equivalent needs a pre-init probe connection and an indirection object over every query.core/src/sessions/db/README.mdrecords the decision, its cost, and the additive-bump alternative that replaces it.upgrade()refuses in-place migration because it rewrites pickled rows into JSON; this package has no pickle legacy.ADK Database schema version <v> is not compatible.is preserved verbatim, so the two pre-existing tests that assert it pass unedited.Testing Plan
Unit Tests:
core/test/sessions/db/schema_version_test.tsreaches 100% statement, branch, function and line coverage ofschema_version.ts(v8), with thefinallykept. The threevalidateDatabaseSchemaVersioncases moved verbatim fromoperations_test.ts; no assertion changed.Proof the tests can fail. Each mutation was applied to
schema_version.ts, the tests were run, then the mutation was reverted.assertCompatibleVersionnever throwsDatabaseSessionService > should fail with incompatible schema versionpromise resolved "undefined" instead of rejectingvalidateDatabaseSchemaVersionstamps a present row instead of a missing oneshould initialize schema version if missing,keeps a single version row when called twiceexpected +0 to be 1upgradeSessionDatabaseSchemanever reaches the stampupgradeSessionDatabaseSchemacasesexpected [] to have a length of 1 but got +0em.createinstampSchemaVersionreplaces the stored value instead of adding a rowexpected '1' to be '2'finally { await orm.close(); }closes the connection when the stored version is rejectedexpected "close" to be called 1 times, but got 0 timesis not compatibleprefixexpected [Function] to throw error including 'ADK Database schema version 999 is no…'Every remaining test pins a reachable behaviour: each of the six mutations kills at least one.
Manual End-to-End (E2E) Tests:
Run against the built package (
npm run build) with a real SQLite file, reading the metadata row with thesqlite3client rather than the ORM:Transcript:
Step 5 is the important one: the upgrade step refuses an unknown version instead of stamping over it.
Checklist
CI note: green on
3d291af3—run-testson Linux, macOS and Windows, plus cross-language and the license check. The branch is rebased onto currentmain, which now carries #602;operations.tskeeps itsredactUriPasswordcall and this PR only trims the imports the moved function used.Two unrelated flakes needed a re-run on an earlier head: an
app_loaderintegration timeout on macOS and aprebuild-installnetwork timeout forsqlite3. Neither touches this diff.