Skip to content

fix(session): migrate legacy session statuses - #3159

Merged
Astro-Han merged 7 commits into
apache:mainfrom
Sun-GLiang:fix/3058-session-status-migration
Aug 17, 2026
Merged

fix(session): migrate legacy session statuses#3159
Astro-Han merged 7 commits into
apache:mainfrom
Sun-GLiang:fix/3058-session-status-migration

Conversation

@Sun-GLiang

Copy link
Copy Markdown
Contributor

Summary

  • migrate persisted review and done session statuses to active in SQLite schema v25
  • narrow the core and UI session-status model to the six current states
  • keep new Desktop clients compatible with old Runtime Hosts by normalizing the two legacy wire values in catalog and continuity decoders
  • retain strict rejection for every other unknown status without changing the compatibility epoch or wire shape

Fixes #3058

Verification

  • npm --workspace @maka/core run build
  • npm --workspace @maka/storage run build
  • npm --workspace @maka/runtime-host run build
  • npm --workspace @maka/ui run build
  • focused core status test: 1/1 passed
  • focused SQLite metadata-store suite: 41/41 passed
  • focused Runtime Host protocol suites: 40/40 passed
  • npm run format:check
  • npm run lint
  • npm run typecheck

Full npm test passes in every workspace except @maka/runtime, where the pre-existing node-pty-write-lifecycle test times out after 10 seconds with ETIMEDOUT. The same failure reproduces on the branch base and standalone; this PR does not touch that test or PTY implementation.

Migration

Opening an existing workspace upgrades session metadata from schema v24 to v25 in the existing transaction. Rows with review or done in either persisted status representation are normalized to active, their metadata revision is advanced once, and statusUpdatedAt is preserved. Downgrade-opening the migrated database with older binaries is not supported.

AI use

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Tool(s) and scope: OpenAI Codex implemented the migration, compatibility decoder, status cleanup, and tests under human direction. Each affected commit includes a Generated-by: Codex trailer.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

@hqhq1025
hqhq1025 requested a lite review from Copilot August 17, 2026 09:23
@coderabbitai

coderabbitai Bot commented Aug 17, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 7689e826-d6d1-4425-9c01-b07e5575873a

📥 Commits

Reviewing files that changed from the base of the PR and between 23a2a56 and 91057e0.

📒 Files selected for processing (1)
  • packages/storage/src/sqlite-session-metadata-schema.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/storage/src/sqlite-session-metadata-schema.ts

Included review availability: Your plan includes up to 3 reviews per rolling hour; 2 remain after this review.


📝 Walkthrough

Summary

This PR removes legacy review and done statuses from the core and UI models. It migrates persisted values to active in SQLite schema v25. It also normalizes these values in catalog and continuity protocol decoders for compatibility with older Runtime Hosts. Other unknown statuses remain rejected.

The PR extends the existing sources of truth. Core defines the current status union. The shared decodeSessionStatus helper provides one compatibility path for both protocol decoders. SQLite migration v25 updates existing workspaces within the existing transaction.

This is the smallest coherent solution. The migration protects persisted data. The shared decoder avoids duplicate validation logic. The migration uses one clock read to preserve timestamp precision and consistency. No code or test can be removed without weakening behavior or regression coverage.

Validation and risks

Focused tests cover the status contract, protocol normalization and rejection, SQLite v24-to-v25 migration, metadata revision updates, timestamp preservation, catalog listing, and reopen behavior. Builds, formatting, linting, type checking, and focused tests reportedly pass. The full test suite has a pre-existing timeout in @maka/runtime. Required checks remain unverified here because no direct check output is available.

The migration updates affected metadata revisions and commit timestamps once. It preserves statusUpdatedAt. Downgrade-opening a migrated database with older binaries is unsupported.

Review-relevant risks

  • The public SessionStatus type and SESSION_STATUSES collection remove review and done. This can affect API consumers and requires independent human review under repository policy.
  • UI labels and status presentation for review and done are removed. This changes user-visible behavior and requires independent human review under repository policy.
  • SQLite schema version 25 changes persisted data and prevents supported downgrade-opening with older binaries. This affects release and upgrade compatibility and requires independent human review under repository policy.
  • Runtime Host protocol decoders normalize legacy values and reject other unknown values. This affects wire compatibility and requires independent human review under repository policy.

The person performing the merge reviews the final diff. A maintainer makes the final determination.

Walkthrough

The session status contract removes review and done. Protocol decoding maps these legacy values to active. SQLite migration 25 rewrites persisted legacy values. Tests cover contract validation, protocol compatibility, and migration behavior. UI definitions remove both values.

Changes

Session status compatibility

Layer / File(s) Summary
Narrow the session status contract
packages/core/src/session.ts, packages/core/src/__tests__/session-status.test.ts
SESSION_STATUSES and SessionStatus now exclude review and done. Tests verify ordering and validation.
Normalize legacy protocol statuses
packages/runtime-host/src/protocol/session-status.ts, packages/runtime-host/src/protocol/session-catalog.ts, packages/runtime-host/src/protocol/session-continuity.ts, packages/runtime-host/src/__tests__/protocol.test.ts, packages/runtime-host/src/__tests__/session-catalog-protocol.test.ts
A shared decoder maps legacy values to active and rejects unknown values. Catalog and continuity tests cover both outcomes.
Migrate persisted legacy statuses
packages/storage/src/sqlite-session-metadata-schema.ts, packages/storage/src/__tests__/sqlite-session-metadata-store.test.ts
Schema version 25 normalizes legacy values in both stored status representations and updates metadata. Tests verify catalog reads and idempotent reopening.
Remove legacy UI status definitions
packages/ui/src/conversation-copy.ts, packages/ui/src/session-status-presentation.ts, packages/ui/stories/session-list-panel.stories.tsx
UI copy, status semantics, and story fixtures no longer define review or done.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Merge Risk: ⚪ Minimal · up to 91057

This change normalizes legacy session statuses during migration and compatibility decoding while preserving strict handling of other unknown values. No actionable merge-blocking risk remains after normal checks and review.

Sequence Diagram(s)

sequenceDiagram
  participant ProtocolClient
  participant SessionCatalog
  participant SessionContinuity
  participant decodeSessionStatus
  ProtocolClient->>SessionCatalog: send session status
  SessionCatalog->>decodeSessionStatus: decode status
  ProtocolClient->>SessionContinuity: send continuity status
  SessionContinuity->>decodeSessionStatus: decode status
  decodeSessionStatus-->>SessionCatalog: normalized or validated status
  decodeSessionStatus-->>SessionContinuity: normalized or validated status
Loading

Possibly related PRs

Suggested reviewers: m4n5ter

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the primary change: migrating legacy session statuses.
Description check ✅ Passed The description follows the template and documents scope, verification, migration behavior, AI use, checklist, and the known unrelated test timeout.
Linked Issues check ✅ Passed The changes satisfy issue #3058 by migrating legacy values, preserving compatibility, narrowing status types, and rejecting other unknown values.
Out of Scope Changes check ✅ Passed The code and test changes remain focused on legacy session-status migration, compatibility decoding, status cleanup, and regression coverage.
Ai Use Disclosure ✅ Passed The PR selects substantive generative use, names OpenAI Codex and its scope, and all 7 introduced commits contain a valid standalone Generated-by: Codex trailer.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR narrows the session-status domain to the six current values and makes legacy review/done statuses safe to read by migrating persisted SQLite rows and normalizing those legacy wire values during protocol decoding.

Changes:

  • Bumps the SQLite session metadata schema to v25 and migrates stored review/done statuses to active.
  • Removes review/done from core and UI session-status models/copy/presentation.
  • Adds Runtime Host decode-only compatibility that maps legacy review/done to active, while still rejecting all other unknown statuses; includes focused tests.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated no comments.

Show a summary per file
File Description
packages/ui/stories/session-list-panel.stories.tsx Removes legacy-status story fixtures now that the UI model no longer includes them.
packages/ui/src/session-status-presentation.ts Drops review/done presentation mapping to match the narrowed status union.
packages/ui/src/conversation-copy.ts Removes legacy status labels from both zh/en copy maps.
packages/storage/src/sqlite-session-metadata-schema.ts Bumps schema to v25 and adds migration rewriting persisted legacy statuses to active.
packages/storage/src/tests/sqlite-session-metadata-store.test.ts Adds migration regression test ensuring legacy statuses normalize once and preserve statusUpdatedAt.
packages/runtime-host/src/protocol/session-status.ts Introduces decode helper that normalizes legacy wire values to active and rejects others.
packages/runtime-host/src/protocol/session-continuity.ts Switches continuity decoding to use the new legacy-normalizing decoder.
packages/runtime-host/src/protocol/session-catalog.ts Switches catalog decoding to use the new legacy-normalizing decoder.
packages/runtime-host/src/tests/session-catalog-protocol.test.ts Adds tests for legacy normalization and strict rejection in catalog projections.
packages/runtime-host/src/tests/protocol.test.ts Adds tests for legacy normalization and strict rejection in continuity snapshots.
packages/core/src/session.ts Removes review/done from SESSION_STATUSES.
packages/core/src/tests/session-status.test.ts Adds a contract test asserting only the current six statuses are accepted.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/runtime-host/src/protocol/session-catalog.ts (1)

871-871: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Inline decodeSessionStatus.

Line 871 only forwards its value to decodeSessionStatus. Call decodeSessionStatus at the projection field and delete sessionStatus. This removes redundant indirection.

Proposed simplification
-    status: sessionStatus(record.status),
+    status: decodeSessionStatus(record.status),
...
-function sessionStatus(value: unknown): SessionStatus {
-  return decodeSessionStatus(value);
-}

As per path instructions, flag concrete cases where code can be deleted or simplified.

Source: Path instructions


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: d94dd8cb-a72b-4042-a8ed-a74e535d4810

📥 Commits

Reviewing files that changed from the base of the PR and between 85410e7 and 28c1b7c.

📒 Files selected for processing (12)
  • packages/core/src/__tests__/session-status.test.ts
  • packages/core/src/session.ts
  • packages/runtime-host/src/__tests__/protocol.test.ts
  • packages/runtime-host/src/__tests__/session-catalog-protocol.test.ts
  • packages/runtime-host/src/protocol/session-catalog.ts
  • packages/runtime-host/src/protocol/session-continuity.ts
  • packages/runtime-host/src/protocol/session-status.ts
  • packages/storage/src/__tests__/sqlite-session-metadata-store.test.ts
  • packages/storage/src/sqlite-session-metadata-schema.ts
  • packages/ui/src/conversation-copy.ts
  • packages/ui/src/session-status-presentation.ts
  • packages/ui/stories/session-list-panel.stories.tsx
💤 Files with no reviewable changes (3)
  • packages/core/src/session.ts
  • packages/ui/stories/session-list-panel.stories.tsx
  • packages/ui/src/session-status-presentation.ts

Included review availability: Your plan includes up to 3 reviews per rolling hour; 2 remain after this review.

Comment thread packages/storage/src/sqlite-session-metadata-schema.ts

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated no new comments.

Suppressed comments (1)

packages/storage/src/sqlite-session-metadata-schema.ts:912

  • committed_at is computed from two separate strftime(..., 'now') calls. If the second rolls over between the %s and %f evaluations, the combined millisecond timestamp can jump backwards by up to ~999ms (e.g., seconds from the previous tick with fractional seconds from the next), which can also make the new migration test flaky (committedAt >= migrationStartedAt). Prefer a single-source timestamp expression.
      committed_at = MAX(
        committed_at,
        CAST(strftime('%s', 'now') AS INTEGER) * 1000
          + CAST(substr(strftime('%f', 'now'), 4, 3) AS INTEGER)
      )

@hqhq1025
hqhq1025 requested a lite review from Copilot August 17, 2026 11:07
@jackwener

Copy link
Copy Markdown
Member

Maintainer follow-up pushed in 91057e0. The bug and migration are real, and the overall v25 + mixed-version decoder approach is the right authority boundary. I changed the migration timestamp to a single unixepoch(..., subsec) read: the previous %s and %f calls could straddle a second boundary and synthesize a timestamp nearly one second behind. Focused storage/core builds pass, the v24→v25 regression test passes, and Biome is clean. This schema migration and public status-contract narrowing still require independent human review before merge under CONTRIBUTING.md.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.

Comment thread packages/storage/src/sqlite-session-metadata-schema.ts
@Astro-Han

Copy link
Copy Markdown
Contributor

LGTM — merging. The migration is well-tested (revision advance, statusUpdatedAt preserved, legacy wire normalization without epoch bump), CI is green, and the AI-use disclosure is complete. Note for the parallel PRs: this PR takes schema v25 — #3165 and #3074 must renumber to v26 (and bump epoch past) when they rebase.

AI-assisted review disclosure: this review was produced with AI assistance (pi review subagent on ollama-cloud/deepseek-v4-flash); the human contributor reviewed the final diff and chose the fast path.

@Astro-Han
Astro-Han merged commit 2de6d6d into apache:main Aug 17, 2026
14 checks passed
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.

Narrowing SESSION_STATUSES needs a migration or a tolerant read

4 participants