|
8 | 8 | recomputeNextRunsForMaintenance, |
9 | 9 | } from "./service/jobs.js"; |
10 | 10 | import type { CronServiceState } from "./service/state.js"; |
11 | | -import type { CronJob, CronJobPatch } from "./types.js"; |
| 11 | +import type { CronJob, CronJobCreate, CronJobPatch } from "./types.js"; |
12 | 12 |
|
13 | 13 | const DEFAULT_TOP_OF_HOUR_STAGGER_MS = 5 * 60 * 1000; |
14 | 14 |
|
@@ -67,6 +67,19 @@ describe("applyJobPatch", () => { |
67 | 67 | expect(job.delivery).toBeUndefined(); |
68 | 68 | }); |
69 | 69 |
|
| 70 | + it("ignores caller-supplied schedule activation state", () => { |
| 71 | + const job = createIsolatedAgentTurnJob("job-activation-owner", undefined, { |
| 72 | + state: { scheduleActivatedAtMs: 456 }, |
| 73 | + }); |
| 74 | + const patch = { |
| 75 | + state: { scheduleActivatedAtMs: 123 }, |
| 76 | + } as unknown as CronJobPatch; |
| 77 | + |
| 78 | + applyJobPatch(job, patch); |
| 79 | + |
| 80 | + expect(job.state.scheduleActivatedAtMs).toBe(456); |
| 81 | + }); |
| 82 | + |
70 | 83 | it("keeps webhook delivery when switching to main session", () => { |
71 | 84 | const job = createIsolatedAgentTurnJob("job-webhook", { |
72 | 85 | mode: "webhook", |
@@ -597,6 +610,26 @@ function createMockState(now: number, opts?: { defaultAgentId?: string }): CronS |
597 | 610 | } as unknown as CronServiceState; |
598 | 611 | } |
599 | 612 |
|
| 613 | +describe("createJob schedule activation ownership", () => { |
| 614 | + it("uses the service clock instead of caller-supplied state", () => { |
| 615 | + const now = Date.parse("2026-06-16T06:00:00.000Z"); |
| 616 | + const state = createMockState(now); |
| 617 | + const input = { |
| 618 | + name: "activation-owned", |
| 619 | + enabled: true, |
| 620 | + schedule: { kind: "cron" as const, expr: "0 * * * *", tz: "UTC" }, |
| 621 | + sessionTarget: "main" as const, |
| 622 | + wakeMode: "now" as const, |
| 623 | + payload: { kind: "systemEvent" as const, text: "tick" }, |
| 624 | + state: { scheduleActivatedAtMs: now - 60_000 }, |
| 625 | + } as unknown as CronJobCreate; |
| 626 | + |
| 627 | + const job = createJob(state, input); |
| 628 | + |
| 629 | + expect(job.state.scheduleActivatedAtMs).toBe(now); |
| 630 | + }); |
| 631 | +}); |
| 632 | + |
600 | 633 | describe("createJob rejects sessionTarget main for non-default agents", () => { |
601 | 634 | const now = Date.parse("2026-02-28T12:00:00.000Z"); |
602 | 635 |
|
|
0 commit comments