feat(engine): daemon-minted event sequencing and a bounded live journal - #509
feat(engine): daemon-minted event sequencing and a bounded live journal#509Zerlight wants to merge 4 commits into
Conversation
|
Your Claude subscription has hit its usage limit. It resets at 11:30am (UTC). Re-trigger Pullfrog after the reset, or add an Add repo secret → · Model settings → · Setup docs → · Ask in Discord →
|
Greptile SummaryThis PR introduces persisted per-session event epochs, daemon-minted sequence numbers, stale-run gating, and bounded in-memory journals for live conversation events.
Confidence Score: 4/5The PR should not merge until stale replaced adapters are prevented from mutating current session-global state; the remaining journal concerns are non-blocking but should also be hardened. A replaced adapter can still overwrite the current session title or generate current-session notifications through event types omitted from the stale-run gate. Journal deletion and send-failure ordering also leave narrower consistency risks. Files Needing Attention: packages/host/engine/src/session/session-event-processor.ts, packages/host/engine/src/session/orchestrator.ts
|
| Filename | Overview |
|---|---|
| packages/host/engine/src/session/session-event-processor.ts | Centralizes event stamping and journaling, but stale turn events retain session-global side effects and failed sends can diverge the journal from the wire. |
| packages/host/engine/src/session/orchestrator.ts | Integrates journals with LiveSession lifecycle; the final unguarded drop in concurrent deletion can remove a replacement run's journal. |
| packages/host/engine/src/conversation/live-journal.ts | Implements byte/event-bounded retention, watermark tails, and gap detection with comprehensive cap and ordering tests. |
| packages/host/engine/src/session/session-record-registry.ts | Adds boot and launch epoch increments plus an awaited persistence operation for relaunches. |
| packages/host/engine/src/session/lifecycle-service.ts | Initializes epochs for new records and durably flushes bumped epochs before relaunching adapters. |
| apps/daemon/src/session-store.ts | Correctly maps the new event epoch between persisted rows and session records. |
| apps/daemon/src/db/schema.ts | Adds the non-null, default-zero event epoch column corresponding to the generated migration. |
| packages/foundation/schema/src/model/conversation.ts | Adds a straightforward lexicographic comparator for epoch and sequence watermarks. |
Sequence Diagram
sequenceDiagram
participant A as Agent adapter
participant P as SessionEventProcessor
participant R as SessionRecordRegistry
participant L as LiveSession
participant J as Live journal
participant T as Transport
A->>P: AgentEvent
P->>R: isCurrentRun(sessionId, runId)
alt stale session-scoped event
P-->>A: Drop event
else accepted event
P->>L: nextSeq()
L-->>P: (epoch, seq)
P->>J: append stamped event
P->>T: send agent.event
end
Reviews (1): Last reviewed commit: "fix(engine): make the launch epoch durab..." | Re-trigger Greptile
893a66f to
ec51b31
Compare
There was a problem hiding this comment.
Greptile has paused reviews on this repository — it used its 100 free open-source review credits for this billing period. Reviews resume automatically on September 23. To continue before then, an organization admin can keep reviews running past the free credits — those bill as normal usage.
|
Your Claude subscription has hit its usage limit. It resets at 11:30am (UTC). Re-trigger Pullfrog after the reset, or add an Add repo secret → · Model settings → · Setup docs → · Ask in Discord →
|
There was a problem hiding this comment.
🔵 Needs a closer look
It changes core engine event ordering/journaling and persists new sequencing state that affects wire semantics and session lifecycle behavior.
Pull request overview
Implements daemon-minted ordering for agent.event frames by introducing a per-session eventEpoch and per-adapter monotone seq, plus a bounded in-memory per-session live journal that records exactly what is sent over the wire (including attribution fields).
Changes:
- Add durable
eventEpochto session records and bump it on run launches (and in-memory on boot), ensuring replacement adapters mint above stale runs. - Stamp every
agent.eventwire frame with(runId, turnId?, epoch, seq)at a single “stamped exit” and append the same stamped events into a bounded live journal. - Add tests covering wire stamping, epoch durability before minting, stale-run gating, and live-journal boundedness/gap semantics.
File summaries
| File | Description |
|---|---|
| packages/host/engine/src/session/session-record-registry.ts | Adds eventEpoch bumping semantics and an awaited flush() for launch-time durability. |
| packages/host/engine/src/session/session-input-dispatcher.ts | Threads LiveSession into event broadcasting/rejection so stamps/journaling are consistent. |
| packages/host/engine/src/session/session-event-processor.ts | Centralizes stamping (epoch, seq) + journaling for every agent.event frame and gates session-scoped stale-run events. |
| packages/host/engine/src/session/orchestrator.ts | Wires in ConversationLiveJournals, drops journals on teardown/delete, and updates broadcast call sites. |
| packages/host/engine/src/session/live-session.ts | Adds per-adapter seq minting and carries launch-captured epoch. |
| packages/host/engine/src/session/lifecycle-service.ts | Ensures launch path awaits a durable eventEpoch save before constructing a LiveSession. |
| packages/host/engine/src/engine.ts | Instantiates and injects ConversationLiveJournals into the session subsystem. |
| packages/host/engine/src/conversation/turn-service.ts | Exposes runningTurnId() for event attribution on the broadcast path. |
| packages/host/engine/src/conversation/live-journal.ts | Introduces the bounded per-session live journal and registry (open/get/drop). |
| packages/host/engine/src/tests/session-record-registry.test.ts | Adds coverage for epoch bumping on launch and in-memory boot bump persisted on next launch. |
| packages/host/engine/src/tests/session-event-sequencing.test.ts | New: validates wire stamping, epoch bumps across relaunch, durable pre-mint save ordering, and stale-run behavior. |
| packages/host/engine/src/tests/engine-turn-tracking.test.ts | Updates test fixtures for new eventEpoch field. |
| packages/host/engine/src/tests/engine-session-records.test.ts | Updates session record fixtures to include eventEpoch. |
| packages/host/engine/src/tests/engine-session-lifecycle.test.ts | Updates LiveSession construction sites for new constructor signature. |
| packages/host/engine/src/tests/engine-session-input.test.ts | Relaxes assertions to account for optional new envelope fields on agent.event. |
| packages/host/engine/src/tests/conversation-live-journal.test.ts | New: tests watermark merge rules, caps, and tailAfter() gap semantics. |
| packages/foundation/schema/src/model/session/record.ts | Extends SessionRecordSchema with durable eventEpoch. |
| packages/foundation/schema/src/model/conversation.ts | Adds compareConversationWatermarks() helper for lexicographic (epoch, seq) ordering. |
| packages/client/workbench/src/mock/dev-mock-host.ts | Updates dev-mock session record creation for new schema field. |
| apps/daemon/src/session-store.ts | Persists/loads eventEpoch in the SQLite session store mapping. |
| apps/daemon/src/db/schema.ts | Adds event_epoch column to sessions table schema. |
| apps/daemon/src/tests/session-store.test.ts | Extends store roundtrip test to include eventEpoch. |
| apps/daemon/drizzle/meta/0013_snapshot.json | Updates Drizzle snapshot metadata to include the new column. |
| apps/daemon/drizzle/meta/_journal.json | Registers the new migration entry. |
| apps/daemon/drizzle/0013_famous_randall.sql | Adds migration to introduce event_epoch to sessions. |
Review details
- Files reviewed: 25/25 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
ec51b31 to
201fc5a
Compare
|
Your Claude subscription has hit its usage limit. It resets at 11:30am (UTC). Re-trigger Pullfrog after the reset, or add an Add repo secret → · Model settings → · Setup docs → · Ask in Discord →
|
|
Review round (2026-09-07). Verified every Copilot and Greptile finding against the branch. Fixed — Declined, with the reasoning on each thread: the stale-run gate's scope (teardown unsubscribes the adapter before any replacement run exists, so a dead run's events never reach the processor), journal-before-send ordering (the hub's |

Summary
Phase 1 of CODE-627 — Conversation turn graph & immutable attachment store. Linear: https://linear.app/arcbox/issue/CODE-630/featengine-daemon-minted-event-sequencing-and-a-bounded-live-journal
Stack: #508 ← this PR (
ruocheng/code-630, baseruocheng/code-629) ← #510. Merge bottom-up; this PR's diff is only its own commits.The daemon owns event ordering: a persisted per-session
epochbumped on every run launch and boot,seqminted onto theagent.eventbroadcast path, a bounded per-session live journal (byte and event caps, truncation marker), and run-gated session-scoped events so a replaced adapter's stragglers never paint the session.Commits
Verification
Every commit passed
pnpm check:ciandpnpm testat its own tip; the stack tip (1d942a62; the same tree as the originally gated73fc5ff2plus the two review fixes below on 628/629) is atpnpm check:ci0 errors,pnpm test3408 passed / 1 skipped. Adversarial reviewers (one per axis, isolated read-only worktrees) reviewed the branch; each P1/P2 was reproduced with a failing test or a probe step before its fix — the round-by-round record is in the Linear issue's comments.Checklist
pnpm check:ciandpnpm testboth pass (no Rust changes)AGENTS.mdand module docs in this branch)