Skip to content

refactor(runtime): delete legacy SQLite state adoption - #837

Merged
ScriptedAlchemy merged 2 commits into
mainfrom
legacy/sqlite
Sep 25, 2026
Merged

ScriptedAlchemy merged 2 commits into
mainfrom
legacy/sqlite

Conversation

@ScriptedAlchemy

@ScriptedAlchemy ScriptedAlchemy commented Sep 25, 2026 •

Copy link
Copy Markdown
Owner

Summary

Delete the two pre-1.0 compatibility paths createSqliteStateDriver gained in #201. The owner has approved breaking changes for old on-disk stores, so neither path gets a fallback reader or a migration shim.

  • The root-mode opener no longer looks for <sanitized id>-<first 12 hex of utf8(id)>.sqlite or renames it and its -wal/-shm sidecars to <sanitized id>-<sha256(id)[0:16]>.sqlite. An old file stays on disk untouched and a fresh store opens beside it.
  • agent_state_journal.result_state is now NOT NULL in the CREATE TABLE. The PRAGMA table_info + ALTER TABLE ... ADD COLUMN upgrade, the row.result_state ?? row.state read fallback, the replay-to-revision fallback in #committedState, and the "legacy journal row ... has no recoverable committed result" migration-failure branch are gone.
  • One generic schema check replaces the ALTER: after CREATE TABLE IF NOT EXISTS, initialize compares each table's PRAGMA table_info column list with the current schema and fails closed with AgentStateError('corrupt', ...). Without it an old journal opened cleanly and the first dispatch surfaced a raw SQLite "no column named result_state" as unavailable. The check names no old format.

Kept as-is: kernel formats 1/2, the 'compact' row stored as 'reset', the pending-migration loop that migrates result_state between schema versions, and the notice ledger migrations under src/notices/** (another PR).

Removal matrix

Removed Callers migrated Deleted surface
legacySanitizedFileName none remained after the adopter was deleted private helper in src/state/sqlite.ts
Rename-on-open adopter (legacy file + -wal/-shm sidecars) open() now returns resolve(join(root, sanitizedFileName(id))) existsSync/renameSync imports, two ENOENT/race branches
PRAGMA table_info + ALTER TABLE agent_state_journal ADD COLUMN result_state CREATE TABLE declares result_state TEXT NOT NULL; a generic column-list check fails closed in-place journal upgrade
row.result_state ?? row.state fallback JournalRow.result_state: string; #committedByKey reads it directly replay-to-revision fallback in #committedState, its db parameter
"legacy journal row ... has no recoverable committed result" recovery migration loop reads row.result_state unconditionally migration-failure branch and head-row recovery branch
Test adopts the legacy root database and live WAL sidecars none legacyFileName, currentFileName, holdUncheckpointedLegacyEvent
Tests fails closed when a non-head legacy event..., migrates a legacy journal-head result..., preserves legacy reset input... replaced by keeps the original commit input while migrating each committed result (current writer, v1 → v2 open) createLegacyMigrationDatabase, clearLegacyEventResults, createLegacyHeadOnlyDatabase, valueCounterDefinition

Added test: fails closed with a typed corrupt error when a table does not match the current schema (drops result_state from a current store and asserts the corrupt error names table agent_state_journal).

Consequence for old stores

Measured on the built dist with a hand-seeded pre-#201 database:

  • Old filename under root: open() creates probe-counter-271e964079f6c266.sqlite and reads { revision: 0, state: initial }; probe-counter-70726f62652f.sqlite keeps its mtime and is never opened.
  • Journal without result_state (any path): open() rejects with AgentStateError code corrupt, message State 'probe/counter' table agent_state_journal at '<file>' does not match the current schema (has revision, kind, name, payload, state, to_version, idempotency_key, committed_at; expected revision, kind, name, payload, state, result_state, to_version, idempotency_key, committed_at).

Delete or recreate such stores before upgrading. No docs page under docs/, packages/rsc-runtime/README.md, or website/docs/{en,zh} described either legacy behavior (grepped for the filename scheme, result_state, and adoption prose), so the changeset is the only prose change.

Verification

Run in this worktree on top of origin/main (64492dd):

  • pnpm build: pass.
  • pnpm typecheck: pass.
  • pnpm lint: pass (1518 files, 88 rules).
  • pnpm test:unit: 4486 passed, 0 failed, 6 skipped. packages/rsc-runtime/tests/state-sqlite.test.ts alone: 55 passed.
  • pnpm test:integration:run packages/rsc-runtime/tests/notices-sqlite-cross-process.test.ts packages/rsc-runtime/tests/state-packaging.test.ts packages/rsc-runtime/tests/state-sqlite-cross-process.test.ts: 10 passed, 0 failed.
  • pnpm test:packed packages/agent-bundle/tests/packed-readonly-state-root.test.ts: 1 passed.
  • pnpm docs:site:build not run: no public export or website page changed.

Follow-up

Codex threads addressed in #850. The P2 nullable-column case now fails at open: the schema check compares each column's NOT NULL flag. The P1 docs gap is closed in reference/runtime-environment.mdx (en, zh), which says pre-current stores are not read or migrated and how to recover.

@changeset-bot

changeset-bot Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 05c5f1e

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@agent-bundle/runtime Minor
create-agent-bundle Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-25T00:38:14.833045Z 2e34d54 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2e34d54156

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .changeset/remove-legacy-sqlite-state.md Outdated
Comment thread packages/rsc-runtime/src/state/sqlite.ts
@pkg-pr-new

pkg-pr-new Bot commented Sep 25, 2026

Copy link
Copy Markdown
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle@837
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle/create-agent-bundle@837
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle/rsc-markdown-stream@837
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle/@agent-bundle/runtime@837

commit: 05c5f1e

@ScriptedAlchemy
ScriptedAlchemy merged commit 349aa1a into main Sep 25, 2026
6 checks passed
@github-actions github-actions Bot mentioned this pull request Sep 25, 2026
@ScriptedAlchemy
ScriptedAlchemy deleted the legacy/sqlite branch September 25, 2026 03:51
ScriptedAlchemy added a commit that referenced this pull request Sep 25, 2026
…file (#854)

* feat(runtime)!: refuse to open a fresh SQLite store beside a pre-#201 file

* chore: changeset for #854

* chore: align the #837 changeset recovery wording
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant