From 5ecc1c2ac2de624af354bc515d5cb04f80df226c Mon Sep 17 00:00:00 2001 From: yu1128-L <2241397554@qq.com> Date: Fri, 9 Oct 2026 08:10:41 +0800 Subject: [PATCH] docs(events): document durable thread seq watermark (#6532) * docs(events): document durable thread seq watermark RUN_EVENT_STREAM.md described seq as monotonic but did not cover the durable per-thread high-water mark that keeps allocations monotonic after a run is deleted. Record that behavior in the Record Envelope section, including that thread deletion drops the mark only when no events remain. * test(scheduler): pin clock for scheduled-run timezone assertions --------- Co-authored-by: yu1128-L <296164533+yu1128-L@users.noreply.github.com> Co-authored-by: Willem Jiang --- backend/docs/RUN_EVENT_STREAM.md | 8 +++ .../scheduled-run-prompt.dom.test.tsx | 59 ++++++++++++++----- 2 files changed, 53 insertions(+), 14 deletions(-) diff --git a/backend/docs/RUN_EVENT_STREAM.md b/backend/docs/RUN_EVENT_STREAM.md index adf7662713..e89f65e68c 100644 --- a/backend/docs/RUN_EVENT_STREAM.md +++ b/backend/docs/RUN_EVENT_STREAM.md @@ -37,6 +37,14 @@ monotonically for their supported deployment modes. JSONL only provides this guarantee within one process; shared multi-process deployments must use the database store. +The database store additionally keeps a per-thread high-water mark +(`run_event_thread_seq`) that is independent of the event rows. Deleting a run +therefore never lowers the next allocated `seq`: values are not reused within a +thread, and a consumer whose `after_seq` cursor already advanced past a deleted +run does not miss later events. Thread deletion drops the mark only when no +events remain for the thread across every owner and category; surviving rows +retain the allocation floor. + ## Categories `category="message"` means an event is eligible for a message projection; it diff --git a/frontend/tests/unit/components/workspace/messages/scheduled-run-prompt.dom.test.tsx b/frontend/tests/unit/components/workspace/messages/scheduled-run-prompt.dom.test.tsx index e75ce6efc4..ac201513f5 100644 --- a/frontend/tests/unit/components/workspace/messages/scheduled-run-prompt.dom.test.tsx +++ b/frontend/tests/unit/components/workspace/messages/scheduled-run-prompt.dom.test.tsx @@ -1,4 +1,11 @@ -import { afterEach, describe, expect, rs, test } from "@rstest/core"; +import { + afterEach, + beforeEach, + describe, + expect, + rs, + test, +} from "@rstest/core"; import { cleanup, fireEvent, render, screen } from "@testing-library/react"; import type { ReactNode } from "react"; @@ -135,7 +142,13 @@ describe("ScheduledRunPrompt", () => { }); describe("run time zone follows the tasks page", () => { + beforeEach(() => { + rs.useFakeTimers({ toFake: ["Date"] }); + rs.setSystemTime(new Date("2026-10-07T12:00:00Z")); + }); + afterEach(() => { + rs.useRealTimers(); rs.restoreAllMocks(); }); @@ -170,21 +183,39 @@ describe("ScheduledRunPrompt", () => { "en-US", ); const block = screen.getByTestId("scheduled-run-prompt"); - expect(block.textContent).toContain("09:00"); + expect(block.textContent).toContain("Today 09:00"); expect(block.textContent).not.toContain("your time"); }); - test("a cron task saved in UTC reads in UTC, with the viewer's time beside it", () => { - viewerIn("Asia/Shanghai"); - const { origin } = launch(); - renderPrompt( - at({ ...origin, schedule_type: "cron", timezone: "UTC" }), - "en-US", - ); - const block = screen.getByTestId("scheduled-run-prompt"); - // Between 16:00 and 24:00 UTC the two zones are on different days, so - // the viewer's time carries its own day ("Today 09:00 your time"). - expect(block.textContent).toMatch(/01:00 · (?:\S+ )?09:00 your time/); - }); + test.each([ + { + label: "both zones have the same relative day", + now: "2026-10-07T12:00:00Z", + expected: "Today 01:00 · 09:00 your time", + }, + { + label: "the viewer is on the next day", + now: "2026-10-07T20:00:00Z", + expected: "Today 01:00 · Yesterday 09:00 your time", + }, + { + label: "the viewer needs an absolute date", + now: "2026-10-08T23:00:00Z", + expected: "Yesterday 01:00 · Oct 7 09:00 your time", + }, + ])( + "a cron task saved in UTC shows the viewer's time when $label", + ({ now, expected }) => { + rs.setSystemTime(new Date(now)); + viewerIn("Asia/Shanghai"); + const { origin } = launch(); + renderPrompt( + at({ ...origin, schedule_type: "cron", timezone: "UTC" }), + "en-US", + ); + const block = screen.getByTestId("scheduled-run-prompt"); + expect(block.textContent).toContain(expected); + }, + ); }); });