#18856: fix(cron): reject past timestamps in createJob (defense-in-depth)
size: S
Cluster:
Cron Job Stability Fixes
## Summary
- Adds `validateScheduleTimestamp()` call inside `createJob()` as a defense-in-depth guard against `kind="at"` schedules with past timestamps
- The gateway already validates at the API level, but this catches any code path that bypasses the gateway (direct service calls, store migrations, future internal callers)
- Adds comprehensive test suite for `validateScheduleTimestamp` covering 9 scenarios including the LLM timestamp bug (wrong year computation)
### Context
We discovered that LLMs (particularly smaller models) frequently compute incorrect Unix timestamps when creating `kind="at"` cron jobs — often off by ~1 year. While the gateway-level validation in `src/gateway/server-methods/cron.ts` catches this for normal API calls, `createJob()` itself had no validation, leaving internal callers unprotected.
## Test plan
- [x] 9 new test cases in `src/cron/validate-timestamp.test.ts`
- [ ] Existing cron tests still pass
- [ ] `validateScheduleTimestamp` correctly rejects past timestamps (>1 min grace)
- [ ] `validateScheduleTimestamp` correctly rejects far-future timestamps (>10 years)
- [ ] `validateScheduleTimestamp` passes through `kind="every"` and `kind="cron"` without checking timestamps
- [ ] Error messages are descriptive and actionable
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Adds defense-in-depth validation to reject `kind="at"` cron schedules with past timestamps directly in `createJob()`. The gateway already validates at the API level (`src/gateway/server-methods/cron.ts:87`), but this additional guard protects against direct service calls, store migrations, or future internal callers that might bypass the gateway. Includes comprehensive test suite covering edge cases including the LLM year-computation bug.
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with minimal risk
- The changes follow defense-in-depth security principles by adding validation at the service layer. The implementation is straightforward, error messages are clear and actionable, and test coverage is comprehensive with 9 test cases covering all edge cases including the specific LLM timestamp bug mentioned in the PR description.
- No files require special attention
<sub>Last reviewed commit: cb1476f</sub>
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#17561: fix(cron): add runtime staleness guard for runningAtMs (#17554)
by robbyczgw-cla · 2026-02-15
79.0%
#13065: fix(cron): Fix "every" schedule not re-arming after gateway restart
by trevorgordon981 · 2026-02-10
79.0%
#16132: fix(cron): prevent duplicate job fires via MIN_REFIRE_GAP_MS guard
by widingmarcus-cyber · 2026-02-14
78.3%
#9060: Fix: Preserve scheduled cron jobs after gateway restart
by vishaltandale00 · 2026-02-04
77.6%
#18743: Cron Tool Hardening: Normalize Gateway Params and Enforce Valid Sch...
by cccat6 · 2026-02-17
77.5%
#18144: fix(cron): clear stuck runningAtMs after timeout and add maintenanc...
by taw0002 · 2026-02-16
77.4%
#8698: fix(cron): default enabled to true for new jobs
by emmick4 · 2026-02-04
77.3%
#17064: fix(cron): prevent control-plane starvation during startup catch-up...
by donggyu9208 · 2026-02-15
76.6%
#12303: fix(cron): correct nextRunAtMs calculation and prevent timer stall
by colddonkey · 2026-02-09
76.6%
#8034: fix(cron): run past-due one-shot jobs immediately on startup
by FelixFoster · 2026-02-03
76.6%