Skip to content

fix(runtime-host): preserve durable event order - #4445

Open
Colafornia wants to merge 1 commit into
apache:mainfrom
Colafornia:fix/durable-runtime-event-order
Open

fix(runtime-host): preserve durable event order#4445
Colafornia wants to merge 1 commit into
apache:mainfrom
Colafornia:fix/durable-runtime-event-order

Conversation

@Colafornia

Copy link
Copy Markdown
Contributor

Summary

Branch and revision copies used timestamp-sorted RuntimeEvents when validating history-compaction checkpoints. If timestamps differed from durable append order, valid checkpoints could be rejected or dropped.

Read RuntimeEvents in durable ordinal order for branch and revision copies, while keeping the existing inline-run boundary and side-conversation behavior.

Fixes #4103

Verification

  • npm run lint
  • npm run format:check
  • npm --workspace @maka/runtime-host run typecheck
  • npm --workspace @maka/runtime-host run test:dist: 1495 passed, 0 failed, 12 skipped
  • Knip checks passed for apps/desktop and packages/ui.
  • ASF headers and renderer architecture checks passed.
  • Full workspace typecheck remains blocked by unrelated existing UI/desktop type errors.
  • Native peer fmt/clippy checks were not run because cargo is unavailable in the environment.

AI use

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

Tool(s) and scope: OpenAI Codex — diagnosis, implementation, and tests.

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 — branch and revision copies now preserve durable RuntimeEvent order
  • No

@github-actions github-actions Bot added the effort/S Under 100 readable lines label Sep 1, 2026
Astro-Han

This comment was marked as duplicate.

@Astro-Han
Astro-Han dismissed their stale review September 1, 2026 17:18

Dismissing my own review state — the notes stand as comments, not as a merge block.

@Astro-Han Astro-Han 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.

(Reposting as a comment — I dismissed my own review state, none of this needs to block you.)

The reordering is real and worth fixing, but I don't think this is the owner, and one legacy path loses events.

P1 — backfilled runs disappear from the copy. runtime-read-model.ts:173-197: a terminal run whose durable ledger is empty gets its events reconstructed from stored messages and placed into view.events. Those events are not in runtimeEventStore. The new read only asks the store, so for such a session sourceEvents is empty for that run; conversation-copy.ts:623's fallback reads the store too and is also empty; assertConversationRuntimeLedgerCopySupported (:392) only checks continuation facts. The branch or revision copy is then written with runtimeEvents: [] for that run while copiedMessages still carries its messages — silently. Worth confirming what classifyTerminalRuntimeLedger does with an empty list; either way the copy shouldn't reach that state.

The ordering owner is one comparator. runtime-read-model.ts:245:

ordered.sort((a, b) =>
  a.event.ts - b.event.ts ||        // primary
  a.runIndex - b.runIndex ||        // durable order, tiebreak only
  a.eventIndex - b.eventIndex || )

view.messages is projected from that same sorted array (:301), and so is the replay plan (:361). So after this change one function holds three orderings: sourceEvents durable, copiedMessages still timestamp, side_conversation still timestamp. Demoting ts in that comparator fixes all three together, and then the kind === 'side_conversation' branch and the extra full-session read both go away rather than being added.

If ts is primary on purpose, I'd like to know why — that's the fact that decides this.

P3. readSessionRuntimeEventEntries loads the whole session while source.events is still held, so a long session holds two full ledgers.

@Colafornia
Colafornia force-pushed the fix/durable-runtime-event-order branch from 6274be7 to 5c4b757 Compare September 2, 2026 05:31
Use RuntimeReadModel events for conversation copies so backfilled events are retained without a duplicate session-ledger read. Preserve immutable session order across timestamp conflicts and surface durable-order reader failures.
@Colafornia
Colafornia force-pushed the fix/durable-runtime-event-order branch from 5c4b757 to 386afae Compare September 2, 2026 05:35
@Colafornia

Copy link
Copy Markdown
Contributor Author

@Astro-Han Thanks for the review. Changed the approach to enforce durable event ordering in RuntimeReadModel.
However, we cannot use runIndex globally because it is not a durable session ordinal and breaks graph revision ordering.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/S Under 100 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(runtime-host): preserve durable RuntimeEvent order in branch and revision copies

2 participants