From d9d9bf58cb275aa0a6ef74afef1144445f8f443a Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Wed, 21 Oct 2026 16:37:04 +0000 Subject: [PATCH 1/9] chore: files changed crates/tinyflows-bus/src/schedule/mod.rs,crates/tinyflows-bus/src/schedule/iden Auto-committed-on: cuttlefish Co-authored-by: Medulla --- .../src/schedule/identity_tests.rs | 78 +++++++++++++++++++ crates/tinyflows-bus/src/schedule/mod.rs | 3 + 2 files changed, 81 insertions(+) create mode 100644 crates/tinyflows-bus/src/schedule/identity_tests.rs diff --git a/crates/tinyflows-bus/src/schedule/identity_tests.rs b/crates/tinyflows-bus/src/schedule/identity_tests.rs new file mode 100644 index 00000000..7188eabd --- /dev/null +++ b/crates/tinyflows-bus/src/schedule/identity_tests.rs @@ -0,0 +1,78 @@ +use super::*; +use serde_json::json; + +fn channel_identity() -> ChannelSessionIdentity { + ChannelSessionIdentity { + tenant_key: "tenant-1".into(), + agent_id: "agent-1".into(), + session_key: "session-1".into(), + provider: "telegram".into(), + account_id: Some("account-1".into()), + conversation: ChannelConversationIdentity { + kind: "group".into(), + id: "chat-1".into(), + scope_id: Some("tenant-1".into()), + parent_id: None, + thread_id: Some("thread-1".into()), + topic_id: Some("topic-1".into()), + }, + } +} + +#[test] +fn channel_session_identity_roundtrips_with_conversation_scope() { + let identity = channel_identity(); + let value = serde_json::to_value(&identity).unwrap(); + + assert_eq!( + value, + json!({ + "tenant_key": "tenant-1", + "agent_id": "agent-1", + "session_key": "session-1", + "provider": "telegram", + "account_id": "account-1", + "conversation": { + "kind": "group", + "id": "chat-1", + "scope_id": "tenant-1", + "thread_id": "thread-1", + "topic_id": "topic-1" + } + }) + ); + assert_eq!(serde_json::from_value::(value).unwrap(), identity); +} + +#[test] +fn channel_job_origin_carries_optional_session_identity_without_changing_legacy_wire() { + let origin = JobOrigin::Channel { + channel: "telegram".into(), + reply_target: "chat-1".into(), + history_key: "telegram:chat-1".into(), + sender: None, + thread_id: None, + session_identity: Some(channel_identity()), + }; + let value = serde_json::to_value(&origin).unwrap(); + assert_eq!(value["kind"], "channel"); + assert_eq!(value["session_identity"]["session_key"], "session-1"); + assert_eq!(serde_json::from_value::(value).unwrap(), origin); + + let legacy = json!({ + "kind": "channel", + "channel": "discord", + "reply_target": "room-1", + "history_key": "discord:room-1" + }); + let parsed: JobOrigin = serde_json::from_value(legacy.clone()).unwrap(); + assert_eq!(parsed, JobOrigin::Channel { + channel: "discord".into(), + reply_target: "room-1".into(), + history_key: "discord:room-1".into(), + sender: None, + thread_id: None, + session_identity: None, + }); + assert_eq!(serde_json::to_value(parsed).unwrap(), legacy); +} diff --git a/crates/tinyflows-bus/src/schedule/mod.rs b/crates/tinyflows-bus/src/schedule/mod.rs index 6ad7b883..c998556c 100644 --- a/crates/tinyflows-bus/src/schedule/mod.rs +++ b/crates/tinyflows-bus/src/schedule/mod.rs @@ -271,5 +271,8 @@ pub const DOCUMENT_METHOD: &str = "Document"; #[path = "mod_tests.rs"] mod tests; #[cfg(test)] +#[path = "identity_tests.rs"] +mod identity_tests; +#[cfg(test)] #[path = "wire_tests.rs"] mod wire_tests; From 8acfbf75ec3fa6645c9a215a88a5e36ce359c3e3 Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Wed, 21 Oct 2026 16:37:18 +0000 Subject: [PATCH 2/9] chore: files changed crates/tinyflows-bus/src/schedule/mod.rs,crates/tinyflows-bus/src/schedule/mod_ Auto-committed-on: cuttlefish Co-authored-by: Medulla --- crates/tinyflows-bus/src/schedule/identity.rs | 43 +++++++++++++++++++ crates/tinyflows-bus/src/schedule/mod.rs | 10 ++++- .../tinyflows-bus/src/schedule/mod_tests.rs | 4 +- crates/tinyflows-bus/src/schedule/types.rs | 5 +++ .../tinyflows-bus/src/schedule/types_tests.rs | 2 + .../tinyflows-bus/src/schedule/wire_tests.rs | 1 + 6 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 crates/tinyflows-bus/src/schedule/identity.rs diff --git a/crates/tinyflows-bus/src/schedule/identity.rs b/crates/tinyflows-bus/src/schedule/identity.rs new file mode 100644 index 00000000..d52bee28 --- /dev/null +++ b/crates/tinyflows-bus/src/schedule/identity.rs @@ -0,0 +1,43 @@ +//! Opaque channel-session identity captured by a host from validated inbound +//! channel metadata. TinyFlows stores and forwards it with job origins; the +//! host remains responsible for validating it before use. +use serde::{Deserialize, Serialize}; + +/// Stable identity of the channel session that created a scheduled job. +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +pub struct ChannelSessionIdentity { + /// Tenant or profile namespace selected by the host. + pub tenant_key: String, + /// Agent that owns the conversation. + pub agent_id: String, + /// Durable session key used to resume the transcript. + pub session_key: String, + /// Provider identifier, such as `telegram` or `slack`. + pub provider: String, + /// Account identity when the provider has multiple configured accounts. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub account_id: Option, + /// Provider-scoped conversation and thread identity. + pub conversation: ChannelConversationIdentity, +} + +/// Provider-scoped identity of a channel conversation. +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +pub struct ChannelConversationIdentity { + /// Conversation kind, such as `direct`, `group`, or `channel`. + pub kind: String, + /// Provider-defined conversation identifier. + pub id: String, + /// Optional tenant/workspace scope for providers whose ids are local. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub scope_id: Option, + /// Parent conversation identifier, when the provider has nested spaces. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub parent_id: Option, + /// Thread identifier, when the conversation is threaded. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub thread_id: Option, + /// Topic identifier for providers that model topics separately. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub topic_id: Option, +} diff --git a/crates/tinyflows-bus/src/schedule/mod.rs b/crates/tinyflows-bus/src/schedule/mod.rs index c998556c..be711ef9 100644 --- a/crates/tinyflows-bus/src/schedule/mod.rs +++ b/crates/tinyflows-bus/src/schedule/mod.rs @@ -3,12 +3,14 @@ use serde::{Deserialize, Serialize}; mod frequency; +mod identity; mod records; mod requests; mod store_types; pub mod types; pub use frequency::{MIN_AGENT_JOB_INTERVAL, TooFrequent, describe_gap}; +pub use identity::{ChannelConversationIdentity, ChannelSessionIdentity}; pub use records::{Attempt, Completion, RunRecord}; pub use requests::{ AcknowledgeManualRun, CheckOriginRequest, CheckPatchRequest, DeliveryProjection, @@ -44,8 +46,9 @@ pub const CALLBACK_INTERFACE: &str = "ai.tinyhumans.tinyflows.ScheduleHost"; /// send/terminal delivery phases. 6 adds prepared handles and host-owned /// lifecycle observation for detached manual workers. 7 adds `TickSchedulerAt`, /// a manual pass at a host-supplied calendar instant, so a host can step a -/// schedule forward instead of waiting for it. -pub const CONTRACT_VERSION: u32 = 7; +/// schedule forward instead of waiting for it. 8 adds optional validated +/// channel-session identity to channel job origins. +pub const CONTRACT_VERSION: u32 = 8; /// Exact advertised scheduler member set. pub const METHODS: &[&str] = &[ members::SCHEDULE_STORE, @@ -274,5 +277,8 @@ mod tests; #[path = "identity_tests.rs"] mod identity_tests; #[cfg(test)] +#[path = "identity_tests.rs"] +mod identity_tests; +#[cfg(test)] #[path = "wire_tests.rs"] mod wire_tests; diff --git a/crates/tinyflows-bus/src/schedule/mod_tests.rs b/crates/tinyflows-bus/src/schedule/mod_tests.rs index 4a1961be..46b1cd2c 100644 --- a/crates/tinyflows-bus/src/schedule/mod_tests.rs +++ b/crates/tinyflows-bus/src/schedule/mod_tests.rs @@ -6,8 +6,8 @@ fn every() -> Schedule { } #[test] -fn contract_is_version_seven_with_the_exact_member_set() { - assert_eq!(CONTRACT_VERSION, 7); +fn contract_is_version_eight_with_the_exact_member_set() { + assert_eq!(CONTRACT_VERSION, 8); assert_eq!(METHODS.len(), 23); let mut unique: Vec<_> = METHODS.to_vec(); unique.sort_unstable(); diff --git a/crates/tinyflows-bus/src/schedule/types.rs b/crates/tinyflows-bus/src/schedule/types.rs index bbe61623..7ae24a98 100644 --- a/crates/tinyflows-bus/src/schedule/types.rs +++ b/crates/tinyflows-bus/src/schedule/types.rs @@ -1,5 +1,6 @@ use chrono::{DateTime, Utc}; use serde::{Deserialize, Deserializer, Serialize}; +use super::identity::ChannelSessionIdentity; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)] #[serde(rename_all = "lowercase")] @@ -98,6 +99,10 @@ pub enum JobOrigin { /// Channel-side thread or topic within the chat. #[serde(default, skip_serializing_if = "Option::is_none")] thread_id: Option, + /// Validated durable session identity supplied by the channel host. + /// Older origins omit it and retain their existing wire shape. + #[serde(default, skip_serializing_if = "Option::is_none")] + session_identity: Option, }, } diff --git a/crates/tinyflows-bus/src/schedule/types_tests.rs b/crates/tinyflows-bus/src/schedule/types_tests.rs index f61533f9..3cb0edd2 100644 --- a/crates/tinyflows-bus/src/schedule/types_tests.rs +++ b/crates/tinyflows-bus/src/schedule/types_tests.rs @@ -317,6 +317,7 @@ fn job_origin_channel_roundtrips_with_and_without_optionals() { history_key: "telegram:chat-42".into(), sender: Some("alice".into()), thread_id: Some("topic-7".into()), + session_identity: None, }; let v = serde_json::to_value(&full).unwrap(); assert_eq!(v["kind"], "channel"); @@ -340,6 +341,7 @@ fn job_origin_channel_roundtrips_with_and_without_optionals() { history_key: "discord:c1".into(), sender: None, thread_id: None, + session_identity: None, } ); assert_eq!(serde_json::to_value(&parsed).unwrap(), minimal); diff --git a/crates/tinyflows-bus/src/schedule/wire_tests.rs b/crates/tinyflows-bus/src/schedule/wire_tests.rs index 0d5593e0..f773b71e 100644 --- a/crates/tinyflows-bus/src/schedule/wire_tests.rs +++ b/crates/tinyflows-bus/src/schedule/wire_tests.rs @@ -123,6 +123,7 @@ fn origin_wire_bytes() { history_key: "telegram:42".into(), sender: Some("alice".into()), thread_id: Some("7".into()), + session_identity: None, }, ); } From d02a32b3ccf66c1ac5c6fca1f26d435ec191043d Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Wed, 21 Oct 2026 16:37:23 +0000 Subject: [PATCH 3/9] chore: files changed crates/tinyflows-bus/src/schedule/mod.rs Auto-committed-on: cuttlefish Co-authored-by: Medulla --- crates/tinyflows-bus/src/schedule/mod.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/crates/tinyflows-bus/src/schedule/mod.rs b/crates/tinyflows-bus/src/schedule/mod.rs index be711ef9..329b1b02 100644 --- a/crates/tinyflows-bus/src/schedule/mod.rs +++ b/crates/tinyflows-bus/src/schedule/mod.rs @@ -277,8 +277,5 @@ mod tests; #[path = "identity_tests.rs"] mod identity_tests; #[cfg(test)] -#[path = "identity_tests.rs"] -mod identity_tests; -#[cfg(test)] #[path = "wire_tests.rs"] mod wire_tests; From 682cae4de15fb743c24e0af7bcaac6449e039ba4 Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Wed, 21 Oct 2026 16:37:37 +0000 Subject: [PATCH 4/9] chore: files changed crates/tinyflows-bus/src/schedule/wire_tests.rs,crates/tinyflows-module/tests/m Auto-committed-on: cuttlefish Co-authored-by: Medulla --- .../tinyflows-bus/src/schedule/wire_tests.rs | 33 +++++++++++++++++-- .../tests/module_artifact_tests.rs | 2 +- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/crates/tinyflows-bus/src/schedule/wire_tests.rs b/crates/tinyflows-bus/src/schedule/wire_tests.rs index f773b71e..79f1d9ec 100644 --- a/crates/tinyflows-bus/src/schedule/wire_tests.rs +++ b/crates/tinyflows-bus/src/schedule/wire_tests.rs @@ -4,8 +4,8 @@ //! stored job has been orphaned. use super::{ - ActiveHours, CronJob, CronJobPatch, CronRun, DeliveryConfig, DeliveryStatus, JobOrigin, - JobType, Schedule, SessionTarget, + ActiveHours, ChannelConversationIdentity, ChannelSessionIdentity, CronJob, CronJobPatch, + CronRun, DeliveryConfig, DeliveryStatus, JobOrigin, JobType, Schedule, SessionTarget, }; fn assert_bytes(json: &str, expected: &T) @@ -128,6 +128,35 @@ fn origin_wire_bytes() { ); } +#[test] +fn channel_origin_with_session_identity_wire_bytes() { + assert_bytes( + r#"{"kind":"channel","channel":"telegram","reply_target":"42","history_key":"telegram:42","session_identity":{"tenant_key":"tenant-1","agent_id":"agent-1","session_key":"session-1","provider":"telegram","conversation":{"kind":"group","id":"chat-1","thread_id":"thread-1"}}}"#, + &JobOrigin::Channel { + channel: "telegram".into(), + reply_target: "42".into(), + history_key: "telegram:42".into(), + sender: None, + thread_id: None, + session_identity: Some(ChannelSessionIdentity { + tenant_key: "tenant-1".into(), + agent_id: "agent-1".into(), + session_key: "session-1".into(), + provider: "telegram".into(), + account_id: None, + conversation: ChannelConversationIdentity { + kind: "group".into(), + id: "chat-1".into(), + scope_id: None, + parent_id: None, + thread_id: Some("thread-1".into()), + topic_id: None, + }, + }), + }, + ); +} + #[test] fn job_with_origin_and_run_with_delivery_status_wire_bytes() { let job_json = r#"{"id":"j1","expression":"0 9 * * *","schedule":{"kind":"cron","expr":"0 9 * * *","tz":null,"active_hours":null},"command":"","prompt":"brief","name":null,"job_type":"agent","session_target":"current","model":null,"agent_id":null,"enabled":true,"delivery":{"mode":"origin","channel":null,"to":null,"best_effort":true},"delete_after_run":false,"created_at":"2026-02-16T00:00:00Z","next_run":"2026-02-16T09:00:00Z","last_run":null,"last_status":null,"last_output":null,"origin":{"kind":"web","thread_id":"t1"}}"#; diff --git a/crates/tinyflows-module/tests/module_artifact_tests.rs b/crates/tinyflows-module/tests/module_artifact_tests.rs index d266e982..0d2c5448 100644 --- a/crates/tinyflows-module/tests/module_artifact_tests.rs +++ b/crates/tinyflows-module/tests/module_artifact_tests.rs @@ -79,7 +79,7 @@ async fn compiled_module_serves_validation_without_linking_engine_into_client() assert_eq!(tinyflows_bus::catalog::CONTRACT_VERSION, 6); assert_eq!(tinyflows_bus::runs::CONTRACT_VERSION, 6); assert_eq!(tinyflows_bus::portability::CONTRACT_VERSION, 4); - assert_eq!(tinyflows_bus::schedule::CONTRACT_VERSION, 7); + assert_eq!(tinyflows_bus::schedule::CONTRACT_VERSION, 8); assert_eq!(tinyflows_bus::runs::CAPS_CONTRACT_VERSION, 2); assert_eq!(tinyflows_bus::runs::CAPS_METHODS.len(), 20); let artifact = std::env::var_os("TINYFLOWS_MODULE_ARTIFACT") From 78922f9eb83d44d2b4e1b7d52a39a309df6fdb08 Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Wed, 21 Oct 2026 16:38:28 +0000 Subject: [PATCH 5/9] chore: files changed crates/tinyflows-bus/src/schedule/identity_tests.rs,crates/tinyflows-bus/src/sc Auto-committed-on: cuttlefish Co-authored-by: Medulla --- .../src/schedule/identity_tests.rs | 24 ++++++++++++------- crates/tinyflows-bus/src/schedule/mod.rs | 6 ++--- crates/tinyflows-bus/src/schedule/types.rs | 2 +- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/crates/tinyflows-bus/src/schedule/identity_tests.rs b/crates/tinyflows-bus/src/schedule/identity_tests.rs index 7188eabd..d0bd60f2 100644 --- a/crates/tinyflows-bus/src/schedule/identity_tests.rs +++ b/crates/tinyflows-bus/src/schedule/identity_tests.rs @@ -41,7 +41,10 @@ fn channel_session_identity_roundtrips_with_conversation_scope() { } }) ); - assert_eq!(serde_json::from_value::(value).unwrap(), identity); + assert_eq!( + serde_json::from_value::(value).unwrap(), + identity + ); } #[test] @@ -66,13 +69,16 @@ fn channel_job_origin_carries_optional_session_identity_without_changing_legacy_ "history_key": "discord:room-1" }); let parsed: JobOrigin = serde_json::from_value(legacy.clone()).unwrap(); - assert_eq!(parsed, JobOrigin::Channel { - channel: "discord".into(), - reply_target: "room-1".into(), - history_key: "discord:room-1".into(), - sender: None, - thread_id: None, - session_identity: None, - }); + assert_eq!( + parsed, + JobOrigin::Channel { + channel: "discord".into(), + reply_target: "room-1".into(), + history_key: "discord:room-1".into(), + sender: None, + thread_id: None, + session_identity: None, + } + ); assert_eq!(serde_json::to_value(parsed).unwrap(), legacy); } diff --git a/crates/tinyflows-bus/src/schedule/mod.rs b/crates/tinyflows-bus/src/schedule/mod.rs index 329b1b02..a48073a5 100644 --- a/crates/tinyflows-bus/src/schedule/mod.rs +++ b/crates/tinyflows-bus/src/schedule/mod.rs @@ -270,12 +270,12 @@ pub const DOCUMENT_INTERFACE: &str = "ai.tinyhumans.tinyflows.ScheduleDocuments" /// Exact document callback member used by the module. pub const DOCUMENT_METHOD: &str = "Document"; -#[cfg(test)] -#[path = "mod_tests.rs"] -mod tests; #[cfg(test)] #[path = "identity_tests.rs"] mod identity_tests; #[cfg(test)] +#[path = "mod_tests.rs"] +mod tests; +#[cfg(test)] #[path = "wire_tests.rs"] mod wire_tests; diff --git a/crates/tinyflows-bus/src/schedule/types.rs b/crates/tinyflows-bus/src/schedule/types.rs index 7ae24a98..8021e517 100644 --- a/crates/tinyflows-bus/src/schedule/types.rs +++ b/crates/tinyflows-bus/src/schedule/types.rs @@ -1,6 +1,6 @@ +use super::identity::ChannelSessionIdentity; use chrono::{DateTime, Utc}; use serde::{Deserialize, Deserializer, Serialize}; -use super::identity::ChannelSessionIdentity; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)] #[serde(rename_all = "lowercase")] From aa8d25803eeb594f5f81bf14ae93af78dc8de71b Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Wed, 21 Oct 2026 16:38:44 +0000 Subject: [PATCH 6/9] chore: files changed crates/tinyflows-bus/src/schedule/identity_tests.rs,crates/tinyflows-bus/src/sc Auto-committed-on: cuttlefish Co-authored-by: Medulla --- crates/tinyflows-bus/src/schedule/identity_tests.rs | 2 +- crates/tinyflows-bus/src/schedule/types.rs | 2 +- crates/tinyflows-bus/src/schedule/wire_tests.rs | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/tinyflows-bus/src/schedule/identity_tests.rs b/crates/tinyflows-bus/src/schedule/identity_tests.rs index d0bd60f2..7af2e442 100644 --- a/crates/tinyflows-bus/src/schedule/identity_tests.rs +++ b/crates/tinyflows-bus/src/schedule/identity_tests.rs @@ -55,7 +55,7 @@ fn channel_job_origin_carries_optional_session_identity_without_changing_legacy_ history_key: "telegram:chat-1".into(), sender: None, thread_id: None, - session_identity: Some(channel_identity()), + session_identity: Some(Box::new(channel_identity())), }; let value = serde_json::to_value(&origin).unwrap(); assert_eq!(value["kind"], "channel"); diff --git a/crates/tinyflows-bus/src/schedule/types.rs b/crates/tinyflows-bus/src/schedule/types.rs index 8021e517..f10cfcb1 100644 --- a/crates/tinyflows-bus/src/schedule/types.rs +++ b/crates/tinyflows-bus/src/schedule/types.rs @@ -102,7 +102,7 @@ pub enum JobOrigin { /// Validated durable session identity supplied by the channel host. /// Older origins omit it and retain their existing wire shape. #[serde(default, skip_serializing_if = "Option::is_none")] - session_identity: Option, + session_identity: Option>, }, } diff --git a/crates/tinyflows-bus/src/schedule/wire_tests.rs b/crates/tinyflows-bus/src/schedule/wire_tests.rs index 79f1d9ec..65c7e136 100644 --- a/crates/tinyflows-bus/src/schedule/wire_tests.rs +++ b/crates/tinyflows-bus/src/schedule/wire_tests.rs @@ -138,7 +138,7 @@ fn channel_origin_with_session_identity_wire_bytes() { history_key: "telegram:42".into(), sender: None, thread_id: None, - session_identity: Some(ChannelSessionIdentity { + session_identity: Some(Box::new(ChannelSessionIdentity { tenant_key: "tenant-1".into(), agent_id: "agent-1".into(), session_key: "session-1".into(), @@ -152,7 +152,7 @@ fn channel_origin_with_session_identity_wire_bytes() { thread_id: Some("thread-1".into()), topic_id: None, }, - }), + })), }, ); } From a201aeb3a73f5d133bde5f0f703784bb65f1c019 Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Wed, 21 Oct 2026 16:42:49 +0000 Subject: [PATCH 7/9] chore: files changed crates/tinyflows-schedule/src/validation_tests.rs,crates/tinyflows-schedule/src Auto-committed-on: cuttlefish Co-authored-by: Medulla --- crates/tinyflows-schedule/src/validation_tests.rs | 1 + crates/tinyflows-schedule/src/wire_tests.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/crates/tinyflows-schedule/src/validation_tests.rs b/crates/tinyflows-schedule/src/validation_tests.rs index 8de72843..2cee1a6f 100644 --- a/crates/tinyflows-schedule/src/validation_tests.rs +++ b/crates/tinyflows-schedule/src/validation_tests.rs @@ -48,6 +48,7 @@ fn origin_requires_conversation_and_announce_can_reply_to_its_asker() { history_key: "conversation".into(), sender: None, thread_id: None, + session_identity: None, }; assert!(validate_delivery(&delivery, Some(&origin), None).is_ok()); let announce = DeliveryConfig { diff --git a/crates/tinyflows-schedule/src/wire_tests.rs b/crates/tinyflows-schedule/src/wire_tests.rs index 71c0a700..03fbc2f6 100644 --- a/crates/tinyflows-schedule/src/wire_tests.rs +++ b/crates/tinyflows-schedule/src/wire_tests.rs @@ -123,6 +123,7 @@ fn origin_wire_bytes() { history_key: "telegram:42".into(), sender: Some("alice".into()), thread_id: Some("7".into()), + session_identity: None, }, ); } From ae889c8a1d3b650dbebd54eea483fdb6f894ecca Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Wed, 21 Oct 2026 16:43:07 +0000 Subject: [PATCH 8/9] chore: files changed crates/tinyflows-drivers/src/schedule/test_support.rs Auto-committed-on: cuttlefish Co-authored-by: Medulla --- crates/tinyflows-drivers/src/schedule/test_support.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/tinyflows-drivers/src/schedule/test_support.rs b/crates/tinyflows-drivers/src/schedule/test_support.rs index b07be5ee..45fe0059 100644 --- a/crates/tinyflows-drivers/src/schedule/test_support.rs +++ b/crates/tinyflows-drivers/src/schedule/test_support.rs @@ -38,6 +38,7 @@ pub(super) fn channel_origin() -> JobOrigin { history_key: "telegram:chat-42".into(), sender: Some("alice".into()), thread_id: None, + session_identity: None, } } From ca20f759c38b621338832fa45cdb927feba953e0 Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Wed, 21 Oct 2026 19:52:32 +0000 Subject: [PATCH 9/9] fix(schedule): re-export channel identity types Co-authored-by: Medulla --- crates/tinyflows-schedule/src/lib.rs | 1 + crates/tinyflows-schedule/src/validation_tests.rs | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/crates/tinyflows-schedule/src/lib.rs b/crates/tinyflows-schedule/src/lib.rs index e40e6c95..8debc119 100644 --- a/crates/tinyflows-schedule/src/lib.rs +++ b/crates/tinyflows-schedule/src/lib.rs @@ -27,6 +27,7 @@ pub use store::{ AgentJobSpec, ImportedJob, MAX_CRON_OUTPUT_BYTES, TRUNCATED_OUTPUT_MARKER, check_patch, truncate_cron_output, }; +pub use tinyflows_bus::schedule::{ChannelConversationIdentity, ChannelSessionIdentity}; pub use types::{ ActiveHours, CronJob, CronJobPatch, CronRun, DeliveryConfig, DeliveryStatus, JobOrigin, JobPolicy, JobType, Schedule, SessionTarget, delivery_mode, diff --git a/crates/tinyflows-schedule/src/validation_tests.rs b/crates/tinyflows-schedule/src/validation_tests.rs index 2cee1a6f..68f02d5c 100644 --- a/crates/tinyflows-schedule/src/validation_tests.rs +++ b/crates/tinyflows-schedule/src/validation_tests.rs @@ -1,5 +1,11 @@ use super::*; +#[test] +fn public_facade_reexports_channel_identity_types() { + let _: Option = None; + let _: Option = None; +} + #[test] fn delay_units_and_default_minutes_match_existing_jobs() { for (text, secs) in [