Fixes#3318
Previously, cron schedules without an explicit `tz` field would use
the system timezone, which could cause confusion if the server is in
a different timezone than the user.
Now, `agents.defaults.userTimezone` from the config is used as the
default timezone for cron schedule computations when the schedule
doesn't specify its own `tz`.
Changes:
- Added `defaultTimezone` option to `computeNextRunAtMs()`
- Added `defaultTimezone` to `CronServiceDeps`
- Gateway passes `userTimezone` from config to cron service
- All job computations now respect the default timezone
When anchorMs is not provided (always in production), the schedule
computed nextRunAtMs as nowMs, causing jobs to fire immediately and
repeatedly instead of at the configured interval.
- Change nowMs <= anchor to nowMs < anchor to prevent early return
- Add Math.max(1, ...) to ensure steps is always at least 1
- Add test for anchorMs not provided case