Skip to content

feat(schedule): tinyflows-schedule crate (schedule model + next-run logic) - #98

Merged
senamakel merged 5 commits into
oh-extract-flows-voicefrom
oh-extract-cron
Sep 30, 2026
Merged

senamakel merged 5 commits into
oh-extract-flows-voicefrom
oh-extract-cron

Conversation

@senamakel

Copy link
Copy Markdown
Member

Stacked on #97 (oh-extract-flows-voice, itself stacked on #96 move-openhuman-flow-logic); retarget to main once those land.

Extracted from OpenHuman's cron domain: a new crates/tinyflows-schedule crate holding only pure scheduling logic.

  • types: Schedule, ActiveHours, DeliveryConfig, JobType, SessionTarget, CronJob, CronRun, CronJobPatch.
  • schedule: cron-expression normalisation, time-zone and active-window aware next_run_for_schedule, validate_schedule, runs_closer_than / validate_agent_schedule (cadence floor).
  • No runtime, store, clock or config. Deps: serde, chrono, chrono-tz, cron, anyhow, tracing.

Serde shapes are unchanged (they are persisted in the host job store and cross RPC); wire_tests.rs pins them with literal JSON, including the bare-string Schedule shorthand and the agent_id double-option patch semantics.

Not moved (stays in OpenHuman): the scheduler runtime, store, ops, RPC, and the scheduler gate (its Policy/config types live in tinymemory-api and its signal sampler is host probing).

Verification: cargo fmt --check, cargo clippy --all-targets -- -D warnings, cargo test -p tinyflows-schedule (62 tests).

senamakel and others added 3 commits September 30, 2026 08:35
Fixed a bug where the schedule gap detection logic incorrectly identified overlapping time windows as gaps. The issue occurred when adjacent windows shared a boundary time, causing the gap checker to treat them as non-contiguous. This change ensures that windows with matching start and end times are properly recognized as overlapping rather than gapped.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Introduce a new `tinyflows-schedule` crate that provides cron expression parsing and timezone-aware scheduling, replacing the previous gate-based test infrastructure. The old gate tests have been removed as the scheduling logic has been reimplemented using the `cron` and `chrono-tz` crates, which offer more robust and standard-compliant time handling. The schedule tests have been updated to accommodate the new implementation's error message formatting.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Co-authored-by: Medulla <medulla@tinyhumans.ai>
@coderabbitai

coderabbitai Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: c439d88e-3fe5-4d07-89a5-856e69d01c02

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Codex Review Summary

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

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-30T08:40:21.838896Z 66dc1e4 New commits
ℹ️ 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.

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

Copy link
Copy Markdown

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: 5aca914b93

ℹ️ 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".

Comment thread crates/tinyflows-schedule/src/types.rs Outdated
Comment thread crates/tinyflows-schedule/src/schedule.rs
@tinysweeper

tinysweeper Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Tiny Sweeper review

Tiny Sweeper reviewed this change across 6 lane(s) and found 1 active actionable finding(s). Detailed lane evidence and any incomplete work are listed below.

State: Incomplete
Priority: medium
Reviewed head: 66dc1e4b74ed
Updated: 1790758750 (Unix time)

Review snapshot

Change surface Files Review signal Count
Production 3 Active findings 3
Tests 4 Noted findings 0
Documentation 2 Resolved findings 0
Configuration 1 Pending checks/questions 19

Completeness: Incomplete
Test assessment: No supported feature-to-test mapping was available; this does not mean tests are absent or passed.

What changed

The review could not produce a supported behavioral summary; inspect the cited changed surface and lane details below.

Features

None identified with supported citations.

Tests

No supported feature-to-test mapping was produced. Test execution is not inferred.

Findings

  • medium · description · Add #![forbid(unsafe_code)] and #![warn(missing_docs)] to the crate root — The repository's coding rules require `#![forbid(unsafe_code)]` and `#![warn(missing_docs)]` in every crate root. This crate has neither. Add them before the crate-level doc commen (\(pull request description\))
  • medium · e2e · Add `#![forbid(unsafe_code)]` and `#![warn(missing_docs)]` to the new crate root — The repository coding rules (from `untrusted-repo-rules`) require `#![forbid(unsafe_code)]` and `#![warn(missing_docs)]` on every crate root. The new `tinyflows-schedule` crate is (crates/tinyflows\-schedule/src/lib\.rs:1)

Previously reported and still active

  • Add `#![forbid(unsafe_code)]` and `#![warn(missing_docs)]` to the crate root

Could not review: CHANGELOG.md, CLAUDE.md, crates/tinyflows-schedule/Cargo.toml, crates/tinyflows-schedule/src/lib.rs, crates/tinyflows-schedule/src/schedule.rs, crates/tinyflows-schedule/src/schedule_gap_tests.rs, crates/tinyflows-schedule/src/schedule_tests.rs, crates/tinyflows-schedule/src/types.rs, crates/tinyflows-schedule/src/types_tests.rs, crates/tinyflows-schedule/src/wire_tests.rs

Before merge

  • Address carried finding Add `#![forbid(unsafe_code)]` and `#![warn(missing_docs)]` to the crate root.
  • Complete the critique review for CHANGELOG.md, CLAUDE.md, crates/tinyflows-schedule/Cargo.toml, crates/tinyflows-schedule/src/lib.rs, crates/tinyflows-schedule/src/schedule.rs, crates/tinyflows-schedule/src/schedule_tests.rs, crates/tinyflows-schedule/src/schedule_gap_tests.rs, crates/tinyflows-schedule/src/types.rs, crates/tinyflows-schedule/src/types_tests.rs, crates/tinyflows-schedule/src/wire_tests.rs.
  • Complete the security review for CLAUDE.md, crates/tinyflows-schedule/Cargo.toml, crates/tinyflows-schedule/src/lib.rs, crates/tinyflows-schedule/src/schedule.rs, crates/tinyflows-schedule/src/schedule_tests.rs, crates/tinyflows-schedule/src/schedule_gap_tests.rs, crates/tinyflows-schedule/src/types.rs, crates/tinyflows-schedule/src/types_tests.rs, crates/tinyflows-schedule/src/wire_tests.rs.
Agent review details

critique

  • Conclusion: Neutral
  • Scope reviewed: incomplete; unanswered: CHANGELOG.md, CLAUDE.md, crates/tinyflows-schedule/Cargo.toml, crates/tinyflows-schedule/src/lib.rs, crates/tinyflows-schedule/src/schedule.rs, crates/tinyflows-schedule/src/schedule_tests.rs, crates/tinyflows-schedule/src/schedule_gap_tests.rs, crates/tinyflows-schedule/src/types.rs, crates/tinyflows-schedule/src/types_tests.rs, crates/tinyflows-schedule/src/wire_tests.rs
  • Lane summary: Reviewed 0 files; 0 findings. 10 files could not be reviewed: CHANGELOG.md, CLAUDE.md, crates/tinyflows-schedule/Cargo.toml, crates/tinyflows-schedule/src/lib.rs, crates/tinyflows-schedule/src/schedule.rs, crates/tinyflows-schedule/src/schedule_tests.rs, crates/tinyflows-schedule/src/schedule_gap_tests.rs, crates/tinyflows-schedule/src/types.rs, crates/tinyflows-schedule/src/types_tests.rs, crates/tinyflows-schedule/src/wire_tests.rs.

security

  • Conclusion: Neutral
  • Scope reviewed: incomplete; unanswered: CLAUDE.md, crates/tinyflows-schedule/Cargo.toml, crates/tinyflows-schedule/src/lib.rs, crates/tinyflows-schedule/src/schedule.rs, crates/tinyflows-schedule/src/schedule_tests.rs, crates/tinyflows-schedule/src/schedule_gap_tests.rs, crates/tinyflows-schedule/src/types.rs, crates/tinyflows-schedule/src/types_tests.rs, crates/tinyflows-schedule/src/wire_tests.rs
  • Lane summary: Reviewed 0 files; 0 findings. 9 files could not be reviewed: CLAUDE.md, crates/tinyflows-schedule/Cargo.toml, crates/tinyflows-schedule/src/lib.rs, crates/tinyflows-schedule/src/schedule.rs, crates/tinyflows-schedule/src/schedule_tests.rs, crates/tinyflows-schedule/src/schedule_gap_tests.rs, crates/tinyflows-schedule/src/types.rs, crates/tinyflows-schedule/src/types_tests.rs, crates/tinyflows-schedule/src/wire_tests.rs. 1 file was not security-reviewed: CHANGELOG.md (prose or tabular data).

tests

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Lane summary: The change adds a test that asserts `first_rule`'s `agent_id` is `Some(Some("welcome"))` after merging a settings rule. The behavior is unchanged — this is a test-only change — so no regression test is required beyond what is added. The test pins the invariant that the agent_id from the merged rule is preserved through the merge; if it regresses, the test fails. Looks sound to me, though I was not able to verify that the test actually fails without the fix, since the diff is test-only and no production code changed. (1 earlier finding(s) still open) _The code index is behind this pull request (indexed at `ae194e602745`), so retrieved context may be out of date._ _Memory was unavailable (model: cortex: v1/recall: timed out after 10s), so this review ran without it._

commits

  • Conclusion: Neutral
  • Scope reviewed: all assigned evidence
  • Lane summary: Nothing sensitive found in what this pull request commits.

description

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Lane summary: This pull request adds a new `tinyflows-schedule` crate with schedule types, next-run logic, and wire tests. The code is well-structured and the logic appears correct, but two issues remain: the crate root is missing the required `#![forbid(unsafe_code)]` and `#![warn(missing_docs)]` attributes, and a log message (and the corresponding error message) hardcode an incorrect candidate limit (100,000) instead of using the actual constant (600,000). The earlier finding about the missing attributes has not been fixed. (1 earlier finding(s) still open) _The code index is behind this pull request (indexed at `ae194e602745`), so retrieved context may be out of date._ _Memory was unavailable (model: cortex: v1/recall: timed out after 10s), so this review ran without it._
  • Evidence: \(pull request description\) — Add #![forbid(unsafe_code)] and #![warn(missing_docs)] to the crate root

e2e

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Lane summary: The new `tinyflows-schedule` crate is a self-contained, pure-logic extraction with thorough unit and wire-format tests. No end-to-end harness can reach it (it has no runtime, store or config), so no e2e gap exists. However, the crate root is missing the `#![forbid(unsafe_code)]` and `#![warn(missing_docs)]` attributes that the repository’s coding rules require. That finding from the earlier cycle still stands. (1 earlier finding(s) still open) _The code index is behind this pull request (indexed at `ae194e602745`), so retrieved context may be out of date._ _Memory was unavailable (model: cortex: v1/recall: timed out after 10s), so this review ran without it._
  • Evidence: crates/tinyflows\-schedule/src/lib\.rs — Add `#![forbid(unsafe_code)]` and `#![warn(missing_docs)]` to the new crate root
Evidence and run details
  • Models: ladder/vectors, deepseek/deepseek-v4-flash
  • Spend: $0.009814
  • Tokens: 125903 input · 8564 output · 32437 cached · 1146 embedding
Head State Pass summary
66dc1e4b74ed incomplete 1 active finding(s), 0 resolved finding(s) (at 1790757423)
66dc1e4b74ed incomplete 2 active finding(s), 0 resolved finding(s) (at 1790758750)

tinysweeper 0.1.0

Add validation in `validate_schedule` to reject `Every` intervals whose conversion to milliseconds would overflow or fail to advance the clock, matching the same arithmetic used when computing the next run. This prevents persisted schedules from becoming stuck. Also add `skip_serializing_if` to `CronJobPatch::agent_id` so absent fields are omitted from JSON output while explicitly cleared fields remain as `null`.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>

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

Copy link
Copy Markdown

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: 00d292275f

ℹ️ 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".

Comment thread crates/tinyflows-schedule/src/schedule.rs
The `ACTIVE_WINDOW_CANDIDATE_LIMIT` and `RUN_GAP_SCAN_OCCURRENCES` constants were too low to reliably detect one-minute gaps caused by annual daylight saving time transitions. A full leap year at the minimum five-minute cadence produces up to 105,408 runs, so the scan limit is raised to 105,500 and the active window candidate limit is increased to 600,000 to ensure the gap detection works regardless of where the scan starts. A new test verifies that the scan finds the spring-forward gap across a full year.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>

@tinysweeper tinysweeper Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

tinysweeper found nothing blocking, but could not review everything, so this is not an approval: CHANGELOG.md, CLAUDE.md, crates/tinyflows-schedule/Cargo.toml, crates/tinyflows-schedule/src/lib.rs, crates/tinyflows-schedule/src/schedule.rs, crates/tinyflows-schedule/src/schedule_gap_tests.rs, crates/tinyflows-schedule/src/schedule_tests.rs, crates/tinyflows-schedule/src/types.rs and 2 more.

             $0.0123 · 151,611 in / 11,933 out · 5,888 cached (4%) · ladder/vectors, deepseek/deepseek-v4-flash · 1,146 embedded
tests:       $0.0032 · 34,035 in  / 2,260 out  · 3,072 cached (9%) · deepseek/deepseek-v4-flash
description: $0.0024 · 25,480 in  / 1,259 out  · 2,304 cached (9%) · deepseek/deepseek-v4-flash
e2e:         $0.0035 · 37,974 in  / 624 out    · 0 cached (0%)     · deepseek/deepseek-v4-flash

@tinysweeper tinysweeper Bot added the priority: p2 Soon. Real but survivable — a rough edge, a gap, a thing that will bite later. label Sep 30, 2026
@senamakel
senamakel merged commit a04a4c5 into oh-extract-flows-voice Sep 30, 2026
10 checks passed
@senamakel
senamakel deleted the oh-extract-cron branch September 30, 2026 08:41

@tinysweeper tinysweeper Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

tinysweeper found nothing blocking, but could not review everything, so this is not an approval: CHANGELOG.md, CLAUDE.md, crates/tinyflows-schedule/Cargo.toml, crates/tinyflows-schedule/src/lib.rs, crates/tinyflows-schedule/src/schedule.rs, crates/tinyflows-schedule/src/schedule_gap_tests.rs, crates/tinyflows-schedule/src/schedule_tests.rs, crates/tinyflows-schedule/src/types.rs and 2 more.

             $0.0098 · 125,903 in / 8,564 out · 32,437 cached (26%) · ladder/vectors, deepseek/deepseek-v4-flash · 1,146 embedded
tests:       $0.0002 · 34,357 in  / 131 out   · 30,389 cached (88%) · deepseek/deepseek-v4-flash
description: $0.0030 · 25,782 in  / 3,500 out · 0 cached (0%)       · deepseek/deepseek-v4-flash
e2e:         $0.0037 · 38,276 in  / 2,017 out · 1,536 cached (4%)   · deepseek/deepseek-v4-flash

@@ -0,0 +1,24 @@
//! Scheduling model and next-run computation for timed jobs.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

priority medium e2e confident

Add #![forbid(unsafe\_code)] and #![warn(missing\_docs)] to the new crate root

The repository coding rules (from untrusted-repo-rules) require #![forbid(unsafe_code)] and #![warn(missing_docs)] on every crate root. The new tinyflows-schedule crate is missing both. Without #![forbid(unsafe_code)] the crate could inadvertently introduce unsafe code without a compile-time guard, and without #![warn(missing_docs)] public items will silently lack documentation. Add both attributes at the top of crates/tinyflows-schedule/src/lib.rs, after the doc comment and before any module declarations.

[RULE] missing-crate-attributes ·

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

priority: p2 Soon. Real but survivable — a rough edge, a gap, a thing that will bite later.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant