fix(shared): stop fired one-shot crons resolving to next year - #386
Open
tommy0103 wants to merge 1 commit into
Open
fix(shared): stop fired one-shot crons resolving to next year#386tommy0103 wants to merge 1 commit into
tommy0103 wants to merge 1 commit into
Conversation
The scheduled-tasks panel derives pending tasks from the Cron*/ScheduleWakeup tool_call items in history and anchors a one-shot cron's single fire time at the owning turn's endedAt. Cron-fire follow-up turns are runtime-internal steers, so one history entry can aggregate several runtime turns and its endedAt keeps advancing — past the one-shot's fire minute. The resolver then skips to the next matching year, and a job that already fired (and was auto-deleted by the scheduler) shows "fires in 364 days" forever, because the phantom fire time is in the future and the fired-row filter can never catch it. - history-apply stamps scheduling tool calls with recordedAtMs, the first-persisted wall-clock sighting; merges keep the first stamp so replayed/retried updates cannot move it. - The deriver resolves a one-shot cron by preferring the runtime-committed nextFireAt line from the persisted output (exact, and also heals existing history), then recordedAtMs, then the turn's START — endedAt is now the last resort. Wakeups anchor at recordedAtMs as well. Model: kimi-code/k3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related issue
Closes #385
Problem / pressure
The scheduled-tasks chip above the composer showed a one-shot cron as "fires in ~364 days" long after it had fired and been auto-deleted by the runtime. The deriver anchors a one-shot's single fire time at the owning history entry's
endedAt; cron-fire follow-up turns are runtime-internal steers that keep extending the same entry, soendedAtcan land past the fire minute and the resolver skips to the next matching year — a future timestamp the fired-row filter can never hide.Summary
history-apply.tsstamps the four scheduling tools'tool_callitems withrecordedAtMs(first-persisted wall-clock sighting); merges keep the first stamp so replayed or retried updates cannot move it.scheduled-tasks-from-history.tsresolves a one-shot cron by preferring the runtime-committednextFireAtline persisted in the tool output, thenrecordedAtMs, then the turn's start;endedAtdrops to last resort. Wakeups anchor atrecordedAtMstoo.ai.ts/message-schemas.tsadd the optionalrecordedAtMsfield;schema.tsandapps/cli/src/lib/AGENTS.mddocument the updated contract.Before / after
endedAtpast its fire minute resolves to next year; chip shows "~364 days" forevernextFireAt(or the call'srecordedAtMs), lands in the past once fired, and the row hidesrecordedAtMspersisted at first sighting, stable across replaysTest plan
packages/shared:pnpm run typecheckclean; fullvitest run1025 passed, including new cases intests/scheduled-tasks-from-history.test.ts(committednextFireAtwins over a lateendedAt;recordedAtMsanchor; turn-start legacy fallback; recurring jobs ignorenextFireAt; wakeup anchoring) andtests/acp-history-apply.test.ts(stamp written once and never moved; non-scheduling tools unstamped).apps/cli: typecheck clean;tests/acp-history.test.ts37 passed.packages/components: typecheck clean;tests/scheduled-tasks-panel-fire-time.test.ts3 passed (existing anchor contract preserved).oxlinton changed files: 0 errors;prettier --checkclean;check:public-boundary,check:platform-boundaries,lint:i18nall pass.pnpm check(heavy CI matrix); no UI code changed.Context handoff
Instructions for reviewing agents
packages/shared/src/scheduled-tasks-from-history.ts(anchor priority and thenextFireAtparse) andhistory-apply.tsstampSchedulingToolCallplus its merge preservation.nextFireAtfrom the persisted output text instead of extending the ACP contract; preferring turn-start overendedAtas the legacy anchor; stamping at first sighting rather than at tool completion.nextFireAt:line fall back to the turn-start anchor, which can mis-resolve unpinned interval one-shots (e.g.*/5 * * * *withrecurring: false) into the turn window; replay imports stamp import time asrecordedAtMs.Authoring context
recordedAtMsis a new optional field on persistedtool_callitems (additive, backward compatible); the legacy anchor order changed from end-first to start-first, deliberately trading interval one-shot accuracy for never rolling date-pinned one-shots into the next year.resolveFireMs) is unchanged and covered by existing suites.