Files
Nicolò Boschi 2643186a85 feat(coding-agents): spread page refreshes with hashed cron fields (H) (#4208)
One `pageTriggerCron` is shared by every page in every bank running this
plugin, so a literal `"0 3 * * *"` does not schedule a refresh at 03:00 — it
schedules all of them at 03:00, ~5 page syntheses per bank, on the worker pool
that also serves retain. Moving the hour moves the pile.

Borrow Jenkins' `H`: a cron field written `H` is replaced, per page, by a value
hashed from bank + page name, so each page keeps its own stable slot.

    "H H * * *"       daily, at this page's own minute and hour
    "H * * * *"       hourly, at its own minute
    "H 3 * * *"       daily at 03:MM — spread inside the chosen hour
    "H H(0-5) * * *"  daily, spread across the night only
    "0 3 * * *"       unchanged

Spreading is a property of the schedule, so it lives in the expression rather
than in a new `pageTriggerType` member per period (`daily-staggered`, then
`hourly-staggered`, …), each of which would spell the period in the type name
and cost a config value, a branch and a docs row.

`H` never leaves the package: `expandCronHash` resolves it to an ordinary
5-field expression at page creation — the only point where the page's identity
exists — so the server parses plain cron and the control plane shows an
editable schedule. The field index is hashed alongside the seed so `H H * * *`
is worth 1440 slots rather than 60 correlated ones. A malformed `H` is refused
at config resolution, since `expandCronHash` deliberately leaves an expression
it cannot read alone rather than inventing a time nobody asked for.
2026-09-08 11:06:42 +02:00
..