GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — feat(coderd/schedule/cron): add Standard schedule constructor by ThomasK33 · Pull Request #32063 · coder/coder

Conversation

@ThomasK33

@ThomasK33 ThomasK33 commented Nov 11, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

Why

Automations store a five-field cron expression and an IANA time zone. The scheduler and the management API will parse both with coderd/schedule/cron, as the "Schedules" section of the Automations RFC says. This adds the parser they will call.

Part of CODAGT-1135.

What changed

  • cron.Standard(spec, timeZone) parses a five-field spec that runs on the wall clock of an IANA zone. Every field can be restricted. It returns an error for an empty spec, a wrong field count, a CRON_TZ= or TZ= prefix, an empty or unknown zone, a zone name with an empty, . or .. segment such as ./localtime, a name that starts with posix/ or right/ (directories of zone data that some hosts have, with other versions of the zones), Local (a Go name for the host's zone), a name whose last segment is localtime, posixrules or Factory (files in a host's zone data that are not zones), and a spec that never runs, such as 0 0 30 2 *.
  • Next on a Standard schedule follows the RFC's daylight saving rule. A repeated local time runs once, at its first instance. A nonexistent local time runs at the first local time after the change. robfig/cron does neither: in America/New_York it runs 30 1 * * * twice on 2026-11-01 and skips 30 2 * * * on 2026-03-08. So Standard walks the matching wall-clock readings and resolves each one to an instant from the zone's UTC offsets. Every loop has a fixed bound, and Next always returns a later time for a Standard schedule. It searches at least 16 years ahead, past the eight years between two leap days across 2100. Weekly, Daily and TimeRange keep their behavior.
  • Schedule.MinInterval() returns the shortest distance between two times of day at which the schedule runs, counted around the clock. One time of day gives 24 hours. The management API will compare it with the deployment's minimum interval.

Scope

This PR adds no minimum interval policy and no configuration. Nothing calls the new code yet. The scheduler loop and the API come in later PRs.

Tradeoffs

  • MinInterval reads only the hour and minute fields, with no calendar. The RFC allows a minimum interval of one minute to 24 hours, so the value only has to be right below 24 hours, and a scan over the calendar kept missing cases. While the zone's UTC offset does not change, no two runs are closer than the value. The doc comment states two limits, and a test pins each.
    • A change of the UTC offset (daylight saving) can shorten a gap that spans it by up to the size of the change: 1,58 1,3 * * * in America/New_York gives 57 minutes, and its runs on 2026-03-08 are 3 minutes apart.
    • A pair of times across midnight counts even when the day fields never match two days in a row: 0,58 0,23 * * 1 gives 2 minutes, but its runs are 58 minutes apart at least, so a check can reject a schedule that the minimum allows.
  • The RFC rule, read as written, means a wildcard schedule such as */15 * * * * does not run during the second pass of a repeated hour. In America/New_York on 2026-11-01 it runs at 01:45 EDT and next at 02:00 EST.
  • Standard resolves a reading from the zone's offsets and does not use Go's zone period bounds, which are wrong after the last transition in a zone's data.

Live check

None. This is a library that nothing calls yet.


Generated with xum • Model: anthropic:claude-sonnet-5-5 • Thinking: xhigh

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

chatgpt-codex-connector[bot] reacted with thumbs up emoji
All reactions
  • 👍 1 reaction
ThomasK33 added 2 commits November 11, 2026 21:11
@ThomasK33
feat(coderd/schedule/cron): add Standard constructor for five-field s…
50b7b87
…chedules

Automations store a five-field cron expression and an IANA time zone.
Standard parses both and gives a repeated local time one run and a
nonexistent local time one run after the clock change, which the
robfig/cron Next used by Weekly and Daily does not do. MinInterval returns
the shortest gap between runs for the API check, because Min only samples
one week from 1970-01-01.
@ThomasK33
chore(coderd/schedule/cron): clarify MinInterval and never-runs comments
c265185
@linear-code

linear-code Bot commented Nov 11, 2026

Copy link
Copy Markdown

CODAGT-1135

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ThomasK33
ThomasK33 temporarily deployed to main November 11, 2026 21:23 — with GitHub Actions Inactive
@ThomasK33
ThomasK33 temporarily deployed to main November 11, 2026 21:23 — with GitHub Actions Inactive
@ThomasK33

ThomasK33 commented Nov 11, 2026

Copy link
Copy Markdown
Member Author

@codex review

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@github-actions github-actions Bot assigned ThomasK33 Nov 11, 2026
@ThomasK33

ThomasK33 commented Nov 11, 2026

Copy link
Copy Markdown
Member Author

@codex security review

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 11, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-12T01:55:09.555307Z ca0cbb2 Manual request
🔒 Security Review ✅ Completed 2026-11-12T01:54:12.809117Z ca0cbb2 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 11, 2026

Copy link
Copy Markdown

🛡️ Codex Security Review

Security review completed. No security issues were found in this pull request.

Reviewed commit: c265185114

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

chatgpt-codex-connector[bot]
chatgpt-codex-connector Bot reviewed Nov 11, 2026
View reviewed changes

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c265185114

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread coderd/schedule/cron/standard.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread coderd/schedule/cron/standard.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread coderd/schedule/cron/standard.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

ThomasK33 added 5 commits November 11, 2026 22:00
@ThomasK33
fix(coderd/schedule/cron): search past robfig limits for Standard and…
f0484bf
… MinInterval

Next searches again when robfig/cron gives up after five years, so a leap day schedule keeps running across 2100. The zone period walk starts 26 hours before the reading, so historic offsets above 14 hours still find the first instance of a repeated time. MinInterval scans 28 years, which holds every calendar a year can have, so schedules that set both day fields get their true shortest gap. It stops once it sees two days in a row, and searches from midnight, so common schedules take microseconds.
@ThomasK33
fix(coderd/schedule/cron): resolve wall-clock readings from zone offsets
3da8ace
Go reports wrong zone period bounds after the last transition in a zone's data, so the walk over zone periods never ended on December 31 of a leap year. A reading is now resolved from the offsets of the zone around it, with fixed bounds on every loop, and Next returns the zero time instead of spinning when a step does not move forward.

MinInterval drops the calendar scan and returns the shortest distance between two times of day around the clock. Standard rejects the zone data files localtime, posixrules and Factory.
@ThomasK33
test(coderd/schedule/cron): model Standard schedules against zone dat…
7c35115
…a through 2100

The differential test runs over every clock change of five zones and December 31 in years up to 2100, with the zone data of the host and the data that Go embeds. Every Next call in the termination test has a deadline. The model of cron comes from robfig/cron, not from the code under test.
@ThomasK33
test(coderd/schedule/cron): state only what the zone data comparison …
3761057
…shows
@ThomasK33
docs(coderd/schedule/cron): state when MinInterval holds and its two …
c5d42a7
…limits

No two runs are closer than MinInterval while the UTC offset of the zone does not change. An offset change can shorten a gap that spans it, and a pair across midnight counts without days in a row. Tests pin both.
@ThomasK33
ThomasK33 temporarily deployed to main November 11, 2026 23:58 — with GitHub Actions Inactive
@ThomasK33
ThomasK33 temporarily deployed to main November 11, 2026 23:58 — with GitHub Actions Inactive
@ThomasK33

ThomasK33 commented Nov 11, 2026

Copy link
Copy Markdown
Member Author

@codex review

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ThomasK33

ThomasK33 commented Nov 11, 2026

Copy link
Copy Markdown
Member Author

@codex security review

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 12, 2026

Copy link
Copy Markdown

🛡️ Codex Security Review

Security review completed. No security issues were found in this pull request.

Reviewed commit: c5d42a7d45

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 12, 2026

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🚀

Reviewed commit: c5d42a7d45

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ThomasK33
fix(coderd/schedule/cron): reject zone paths and pin the reading bound
46606d4
A zone name with an empty, dot or dot-dot segment is rejected, because time.LoadLocation cleans the path and ./localtime reached the host file. Tests start Next inside repeated periods of up to a whole day, so the bound on the readings that Next walks is pinned, and a test from a zone with a local mean time offset above 15 hours pins the range of offsets that Next reads. The comment on the search for later runs now states 16 years, which is what robfig's year limit gives.
@ThomasK33
ThomasK33 temporarily deployed to main November 12, 2026 01:15 — with GitHub Actions Inactive
@ThomasK33
ThomasK33 temporarily deployed to main November 12, 2026 01:15 — with GitHub Actions Inactive
@ThomasK33

ThomasK33 commented Nov 12, 2026

Copy link
Copy Markdown
Member Author

@codex review

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ThomasK33

ThomasK33 commented Nov 12, 2026

Copy link
Copy Markdown
Member Author

@codex security review

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 12, 2026

Copy link
Copy Markdown

🛡️ Codex Security Review

Security review completed. No security issues were found in this pull request.

Reviewed commit: 46606d4ef5

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 12, 2026

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

Reviewed commit: 46606d4ef5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ThomasK33
fix(coderd/schedule/cron): reject posix and right zone data and name …
ca0cbb2
…the zone once

A zone name is rejected when its first segment is posix or right, because right counts leap seconds and gives wrong runs on hosts that have it. The files that are not zones are rejected in any directory. The error for an unknown zone holds the name once. A test starts Next in Juneau, where the walk visits 1,441 readings, one more than the repeated day of Sitka.
@ThomasK33
ThomasK33 temporarily deployed to main November 12, 2026 01:51 — with GitHub Actions Inactive
@ThomasK33
ThomasK33 temporarily deployed to main November 12, 2026 01:51 — with GitHub Actions Inactive
@ThomasK33

ThomasK33 commented Nov 12, 2026

Copy link
Copy Markdown
Member Author

@codex review

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ThomasK33

ThomasK33 commented Nov 12, 2026

Copy link
Copy Markdown
Member Author

@codex security review

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 12, 2026

Copy link
Copy Markdown

🛡️ Codex Security Review

Security review completed. No security issues were found in this pull request.

Reviewed commit: ca0cbb2646

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 12, 2026

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🚀

Reviewed commit: ca0cbb2646

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ThomasK33
ThomasK33 temporarily deployed to main November 12, 2026 02:17 — with GitHub Actions Inactive
@ThomasK33
ThomasK33 requested review from deansheather, ethanndickson, jakehwll and snagles November 12, 2026 02:30
ethanndickson
ethanndickson reviewed Nov 12, 2026
View reviewed changes

@ethanndickson ethanndickson left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The RFC says the browser previews unsaved schedules with cron-parser (4.9.0 in site/package.json), and the server stays authoritative. cron-parser accepts these specs, but Standard rejects them:

  • 0 9 * * 7 (7 as Sunday)
  • 0 9 L * * (last day of the month)
  • 0 9 * * 1#2 (second Monday)
  • 0 0 9 * * * (six fields: cron-parser reads the first field as seconds and previews daily at 09:00)

For each of these, the user sees a valid preview, and then the save fails.

On clock-change days, the previewed times also differ from the times the server runs. In America/New_York:

  • 30 2 * * * on 2026-03-08: the preview shows 03:30 EDT, but the server runs at 03:00 EDT.
  • */15 * * * * on 2026-11-01: the preview shows runs at 01:00 EST, 01:15 EST and so on, but the server runs nothing between 01:45 EDT and 02:00 EST.

This is not a bug in this PR, but this PR sets the syntax and the daylight saving rules that the server uses. Is there a plan to keep the browser preview and the server in agreement?

🤖

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@ThomasK33

ThomasK33 commented Nov 12, 2026

Copy link
Copy Markdown
Member Author

Thanks, this is a real gap, and the RFC does not close it. It says "The browser previews the next runs of an unsaved schedule with the cron-parser library" and "The server stays authoritative: it validates the schedule on save and computes every run." It does not say how the two stay in agreement.

The plan:

  1. Shared test vectors, in a follow-up PR right after this one. A file under coderd/schedule/cron/testdata/ lists specs that Standard accepts and rejects, and expected run times around clock changes. Your four specs and your two America/New_York cases go into it. A Go test in this package reads the file. The editor's tests can read the same file, so a difference between the preview and the server fails CI on one side.
  2. The management API returns the reason. The create and update handlers (a later PR in this stack) return the validation error from Standard, so a spec that the preview accepted fails the save with a message that names the cause.
  3. The editor PR is not in this stack. It has to do two things before it previews: refuse what the server refuses (the four forms in your list), and apply the RFC's two clock-change rules on top of cron-parser, which resolves those days in its own way. The RFC dropped the server-side preview of unsaved schedules, so the vectors are how the editor proves that it matches. I am recording this as a requirement for that PR.

I did not change the server's syntax here. Standard takes what the package's existing parser takes for five fields, and widening it (for example 7 for Sunday) is a product decision for the RFC, not for this PR.


Generated with xum • Model: anthropic:claude-fable-5-2 • Thinking: high

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ThomasK33 ThomasK33 mentioned this pull request Nov 12, 2026
feat: add get, list and delete routes for chat automations #32079
Open
ethanndickson
ethanndickson approved these changes Nov 12, 2026
View reviewed changes
@ThomasK33
ThomasK33 merged commit 871eb9b into main Nov 12, 2026
37 checks passed

Uh oh!

There was an error while loading. Please reload this page.

@ThomasK33
ThomasK33 deleted the tk/automations-cron-standard branch November 12, 2026 13:32
@ThomasK33
ThomasK33 temporarily deployed to main November 12, 2026 13:32 — with GitHub Actions Inactive
@github-actions github-actions Bot locked and limited conversation to collaborators Nov 12, 2026

This branch was previously deployed

1 inactive deployment
main — ca0cbb26 Deployed Nov 12, 2026 by ThomasK33 via cla #254936
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Reviewers

@chatgpt-codex-connector chatgpt-codex-connector[bot] chatgpt-codex-connector[bot] left review comments
@ethanndickson ethanndickson ethanndickson approved these changes
@deansheather deansheather Awaiting requested review from deansheather
@snagles snagles Awaiting requested review from snagles
@jakehwll jakehwll Awaiting requested review from jakehwll

Uh oh!

There was an error while loading. Please reload this page.

Assignees

@ThomasK33 ThomasK33

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

2 participants

@ThomasK33 @ethanndickson
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.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.