Skip to content

fix(scheduler): accept 5-field cron by padding seconds 0 (ADR-0021) - #167

Merged
chinkan merged 2 commits into
mainfrom
fix/cron-5field-155
Oct 6, 2026
Merged

chinkan merged 2 commits into
mainfrom
fix/cron-5field-155

Conversation

@chinkan

@chinkan chinkan commented Oct 6, 2026

Copy link
Copy Markdown
Owner

Closes #155. Implements ADR-0021 (docs/adr/0021-five-field-cron-seconds-pad.md). Timezone is out of scope (#166); crons are still evaluated in UTC.

Change

  • agent::normalize_cron_expr replaces validate_cron_expr: 5 fields → "0 " + fields; 6 fields pass through; 4/7 fields and @macros are rejected with a clear error.
  • Portal POST /api/tasks and PUT /api/tasks/{id} store the normalised 6-field value and echo it (triggerValue); 4/7 fields still return 400 invalid_cron.
  • schedule_task tool stores the normalised value and shows it in the success text; the trigger_value description now documents 5 or 6 fields, UTC, stored as 6.
  • Built-in [memory] summarize_cron / [learning] user_model_cron are normalised at boot; errors name the config key (still fail-fast).
  • Boot restore: ScheduledTaskStore::normalize_stored_cron rewrites legacy 5-field rows (info log Normalised 5-field cron for task …), leaves 6-field rows untouched, and never arms an invalid row (error log).
  • Portal: CRON_5_OR_6_FIELD heuristic; en / zh-HK copy says 5 or 6 fields with a 5-field example.

Tests

  • Unit: normalize pads 5 / passes 6 / rejects 4, 7, @daily; padded 0 9 * * * → next 09:00:00 UTC; restore heal (5 rewritten, 6 untouched, 7 refused, row unchanged).
  • Integration: portal POST 5-field stored + echoed; PUT 5-field stored, 4-field 400; tool 5-field stored + shown.
  • Web: vitest accepts 5/6, rejects 4/7.
  • cargo fmt --check, cargo clippy --all-targets -D warnings clean; cargo test: 929 passed; web: 41 passed.

QA matrix

  1. Portal and Telegram tool: 0 9 * * * → stored 0 0 9 * * *, fires 09:00 UTC (17:00 HKT).
  2. An existing 5-field row in the DB is healed at boot (log line + row rewritten) and fires.
  3. 9 * * *, 0 0 9 * * * 2026, @daily are rejected (portal 400 invalid_cron, tool error).
  4. Portal form accepts a 5-field cron; hint/labels say 5 or 6 fields.

Closes #155.

- normalize_cron_expr replaces validate_cron_expr: 5 fields get a leading
  '0', 6 fields pass through, 4/7 fields and @macros are rejected.
- Portal POST/PUT and the schedule_task tool store and echo the
  normalised 6-field value.
- Built-in [memory] summarize_cron / [learning] user_model_cron are
  normalised; errors name the config key.
- Boot restore heals legacy 5-field rows in the DB and never arms an
  invalid one.
- Portal heuristic and copy accept 5 or 6 fields.

chinkan commented Oct 6, 2026

Copy link
Copy Markdown
Owner Author

TL ACCEPT on tip 45cee9a (ADR-0021 / #155).

Verified: 5→6 seconds pad, 6 unchanged, reject 4/7/@macros, portal POST/PUT + tool + config crons store normalised 6-field, restore rewrites 5-field rows, portal en/zh-HK UTC hint, schedule_task already has Evaluated in UTC., no timezone behaviour change (#166 separate).

Non-blocking follow-ups (not this PR): rename triggerLooksValid per ADR §6; a few stale "6-field" docs/comments/placeholder; restore test could assert full arm path.

Waiting on Product GO + QA GO + CI green before merge. No tag.

@chinkan
chinkan merged commit 6a4573f into main Oct 6, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Accept 5-field cron by padding seconds as 0

1 participant