1use std::collections::BTreeMap;
8use std::sync::Arc;
9
10use crate::meerkat_machine::{
11 CommsDrainMode, CommsDrainPhase, DrainExitReason, RuntimeExecutorAttachmentWitness, dsl,
12};
13use indexmap::IndexSet;
14use meerkat_core::RuntimeEpochId;
15use meerkat_core::agent::CommsRuntime;
16use meerkat_core::image_generation::{
17 ImageOperationApprovalReason, ImageOperationDenialReason, ImageOperationId,
18 ImageOperationPhase, ImageOperationTerminalClass, ImageProviderTerminalObservation,
19 ProviderTextDisposition, SessionModelRoutingStatus, SwitchTurnApprovalReason,
20 SwitchTurnControlResult, SwitchTurnIntent, SwitchTurnRequestId,
21};
22use meerkat_core::lifecycle::WaitRequestId;
23use meerkat_core::lifecycle::core_executor::CoreExecutor;
24use meerkat_core::lifecycle::run_primitive::{ModelId, TurnMetadataOverride};
25use meerkat_core::lifecycle::{InputId, RunId};
26use meerkat_core::lifecycle::{RunBoundaryReceipt, RunId as LifecycleRunId};
27use meerkat_core::ops::OperationId;
28use meerkat_core::ops_lifecycle::OperationLifecycleSnapshot;
29use meerkat_core::types::HandlingMode;
30use meerkat_core::types::SessionId;
31use meerkat_machine_derive::CommandManifest;
32use meerkat_machine_schema::catalog::dsl::meerkat_machine::MeerkatMachineInputVariant;
33use serde::{Deserialize, Serialize};
34
35use crate::AcceptOutcome;
36use crate::identifiers::LogicalRuntimeId;
37use crate::ingress_types::{ContentShape, RequestId, ReservationKey};
38use crate::input::Input;
39use crate::input_state::InputLifecycleState;
40use crate::input_state::InputTerminalOutcome;
41use crate::input_state::StoredInputState;
42use crate::runtime_event::RuntimeEventEnvelope;
43use crate::runtime_state::RuntimeState;
44use crate::traits::{
45 DestroyReport, RecoveryReport, RecycleReport, ResetReport, RetireReport,
46 RuntimeControlPlaneError, RuntimeDriverError,
47};
48
49#[derive(Debug, Clone, Serialize, PartialEq)]
56#[serde(rename_all = "snake_case")]
57pub struct SessionLlmReconfigureRequest {
58 #[serde(default, skip_serializing_if = "Option::is_none")]
59 pub model: Option<String>,
60 #[serde(default, skip_serializing_if = "Option::is_none")]
61 pub provider: Option<String>,
62 #[serde(default, skip_serializing_if = "Option::is_none")]
65 pub self_hosted_server_id: Option<String>,
66 #[serde(default, skip_serializing_if = "Option::is_none")]
67 pub provider_params: Option<
68 TurnMetadataOverride<meerkat_core::lifecycle::run_primitive::ProviderParamsOverride>,
69 >,
70 #[serde(default, skip_serializing_if = "Option::is_none")]
74 pub auth_binding: Option<TurnMetadataOverride<meerkat_core::AuthBindingRef>>,
75}
76
77#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Default)]
78#[serde(rename_all = "snake_case")]
79pub enum SessionLlmCapabilitySurfaceStatus {
80 Resolved,
81 #[default]
82 Unresolved,
83}
84
85#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
86#[serde(rename_all = "snake_case")]
87pub struct SessionLlmCapabilitySurface {
88 pub supports_temperature: bool,
89 pub supports_thinking: bool,
90 pub supports_reasoning: bool,
91 pub inline_video: bool,
92 pub vision: bool,
93 #[serde(default)]
94 pub image_input: bool,
95 pub image_tool_results: bool,
96 pub supports_web_search: bool,
97 #[serde(default)]
98 pub image_generation: bool,
99 #[serde(default)]
103 pub realtime: bool,
104 #[serde(default, skip_serializing_if = "Option::is_none")]
105 pub call_timeout_secs: Option<u64>,
106}
107
108impl SessionLlmCapabilitySurface {
109 #[must_use]
110 pub fn to_wire_resolved(&self) -> meerkat_contracts::WireResolvedModelCapabilities {
111 meerkat_contracts::WireResolvedModelCapabilities {
112 vision: self.vision,
113 image_input: self.image_input,
114 image_tool_results: self.image_tool_results,
115 inline_video: self.inline_video,
116 realtime: self.realtime,
117 web_search: self.supports_web_search,
118 image_generation: self.image_generation,
119 }
120 }
121}
122
123#[derive(Debug, Clone, PartialEq, Eq)]
124pub struct SessionLlmCapabilityDelta {
125 pub previous: Option<SessionLlmCapabilitySurface>,
126 pub current: Option<SessionLlmCapabilitySurface>,
127 pub changed: bool,
128}
129
130#[derive(Debug, Clone, PartialEq, Eq)]
131pub struct SessionToolVisibilityDelta {
132 pub previous_capability_base_filter: meerkat_core::ToolFilter,
133 pub current_capability_base_filter: meerkat_core::ToolFilter,
134 pub committed_visible_set_changed: bool,
135 pub revision_bumped: bool,
136}
137
138#[derive(Debug, Clone, PartialEq)]
139pub struct SessionLlmReconfigureReport {
140 pub previous_identity: meerkat_core::SessionLlmIdentity,
141 pub new_identity: meerkat_core::SessionLlmIdentity,
142 pub capability_delta: SessionLlmCapabilityDelta,
143 pub tool_visibility_delta: SessionToolVisibilityDelta,
144 pub rollback_occurred: bool,
145}
146
147#[derive(Debug, Clone)]
148pub struct HydratedSessionLlmState {
149 pub current_identity: meerkat_core::SessionLlmIdentity,
150 pub current_visibility_state: meerkat_core::SessionToolVisibilityState,
151 pub current_capability_surface: Option<SessionLlmCapabilitySurface>,
152 pub capability_surface_status: SessionLlmCapabilitySurfaceStatus,
153 pub base_tool_names: std::collections::BTreeSet<meerkat_core::ToolName>,
154}
155
156#[derive(Debug, Clone)]
157pub struct ResolvedSessionLlmReconfigure {
158 pub target_identity: meerkat_core::SessionLlmIdentity,
159 pub target_capability_surface: SessionLlmCapabilitySurface,
160}
161
162#[derive(Debug, Clone, Copy, PartialEq, Eq)]
163pub enum ModelRoutingApprovalDisposition {
164 NotRequired,
165 Approved,
166 DeniedByUser,
167 RequiredButUnavailable,
168}
169
170#[derive(Debug, Clone, Copy, PartialEq, Eq)]
171pub struct ModelRoutingRealtimePolicy {
172 pub target_realtime_capable: bool,
173 pub allow_realtime_detach: bool,
174}
175
176#[derive(Debug, Clone, PartialEq, Eq)]
177pub struct SwitchTurnRequest {
178 pub request_id: SwitchTurnRequestId,
179 pub intent: SwitchTurnIntent,
180 pub target_realtime: ModelRoutingRealtimePolicy,
181 pub approval: ModelRoutingApprovalDisposition,
182 pub approval_reason: Option<SwitchTurnApprovalReason>,
183}
184
185#[derive(Debug, Clone, PartialEq, Eq)]
186pub struct ImageOperationRoutingRequest {
187 pub operation_id: ImageOperationId,
188 pub target_model: ModelId,
189 pub target_realtime: ModelRoutingRealtimePolicy,
190 pub approval: ModelRoutingApprovalDisposition,
191 pub approval_reason: Option<ImageOperationApprovalReason>,
192 pub requires_scoped_override: bool,
193}
194
195#[derive(Debug, Clone, PartialEq, Eq)]
196pub enum ImageOperationRoutingResult {
197 Accepted {
198 operation_id: ImageOperationId,
199 phase: ImageOperationPhase,
200 },
201 Denied {
202 operation_id: ImageOperationId,
203 reason: ImageOperationDenialReason,
204 },
205}
206
207#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
208#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))]
209pub trait SessionLlmReconfigureHost: Send + Sync {
210 async fn acquire_turn_finalization_boundary(
215 &self,
216 _session_id: &SessionId,
217 ) -> Result<
218 Box<dyn meerkat_core::lifecycle::CoreExecutorTurnFinalizationGuard>,
219 RuntimeDriverError,
220 > {
221 Ok(Box::new(()))
222 }
223
224 async fn hydrate_session_llm_state(
225 &self,
226 session_id: &SessionId,
227 ) -> Result<HydratedSessionLlmState, RuntimeDriverError>;
228
229 async fn resolve_target_session_llm_identity(
230 &self,
231 request: &SessionLlmReconfigureRequest,
232 current_identity: &meerkat_core::SessionLlmIdentity,
233 ) -> Result<ResolvedSessionLlmReconfigure, RuntimeDriverError>;
234
235 async fn apply_live_session_llm_identity(
237 &self,
238 session_id: &SessionId,
239 identity: &meerkat_core::SessionLlmIdentity,
240 ) -> Result<(), RuntimeDriverError>;
241
242 async fn apply_live_session_tool_visibility_state(
244 &self,
245 session_id: &SessionId,
246 visibility_state: Option<meerkat_core::SessionToolVisibilityState>,
247 ) -> Result<(), RuntimeDriverError>;
248
249 async fn persist_live_session(&self, session_id: &SessionId) -> Result<(), RuntimeDriverError>;
251
252 async fn discard_live_session(&self, session_id: &SessionId) -> Result<(), RuntimeDriverError>;
254}
255
256#[derive(Debug, thiserror::Error)]
257pub(crate) enum MeerkatMachineCommandError {
258 #[error(transparent)]
259 Driver(#[from] RuntimeDriverError),
260 #[error(transparent)]
261 Control(#[from] RuntimeControlPlaneError),
262}
263
264#[derive(CommandManifest)]
270#[allow(clippy::large_enum_variant)]
271pub(crate) enum MeerkatMachineCommand {
272 RegisterSession {
273 session_id: SessionId,
274 },
275 #[cfg_attr(not(test), allow(dead_code))]
278 UnregisterSession {
279 session_id: SessionId,
280 },
281 EnsureSessionWithExecutor {
282 session_id: SessionId,
283 executor: Box<dyn CoreExecutor>,
284 },
285 SetSilentIntents {
286 session_id: SessionId,
287 intents: Vec<String>,
288 },
289 CancelAfterBoundary {
290 session_id: SessionId,
291 },
292 StopRuntimeExecutor {
293 session_id: SessionId,
294 reason: String,
295 },
296 #[cfg_attr(not(test), allow(dead_code))]
297 ContainsSession {
298 session_id: SessionId,
299 },
300 SessionHasExecutor {
301 session_id: SessionId,
302 },
303 SessionHasComms {
304 session_id: SessionId,
305 },
306 OpsLifecycleRegistry {
307 session_id: SessionId,
308 },
309 #[cfg_attr(not(test), allow(dead_code))]
312 PrepareBindings {
313 session_id: SessionId,
314 },
315 #[cfg_attr(not(test), allow(dead_code))]
318 PrepareLocalSessionBindings {
319 session_id: SessionId,
320 },
321 InputState {
322 session_id: SessionId,
323 input_id: InputId,
324 },
325 InputStateByIdempotencyKey {
332 session_id: SessionId,
333 idempotency_key: String,
334 },
335 InteractionTerminalStatus {
340 session_id: SessionId,
341 selector: crate::terminal_status::InteractionSelector,
342 },
343 RunTerminalStatus {
347 session_id: SessionId,
348 run_id: RunId,
349 },
350 ListActiveInputs {
351 session_id: SessionId,
352 },
353 ReconfigureSessionLlmIdentity {
354 session_id: SessionId,
355 previous_identity: Box<meerkat_core::SessionLlmIdentity>,
356 previous_visibility_state: Box<meerkat_core::SessionToolVisibilityState>,
357 previous_capability_surface: Option<SessionLlmCapabilitySurface>,
358 previous_capability_surface_status: SessionLlmCapabilitySurfaceStatus,
359 view_image_tool_available: bool,
360 previous_view_image_visible: bool,
361 next_view_image_visible: bool,
362 previous_active_visibility_revision: u64,
363 previous_staged_visibility_revision: u64,
364 target_identity: Box<meerkat_core::SessionLlmIdentity>,
365 target_capability_surface: Box<SessionLlmCapabilitySurface>,
366 next_visibility_state: Box<meerkat_core::SessionToolVisibilityState>,
367 next_capability_base_filter: meerkat_core::ToolFilter,
368 next_active_visibility_revision: u64,
369 tool_visibility_delta: Box<SessionToolVisibilityDelta>,
370 },
371 StagePersistentFilter {
372 session_id: SessionId,
373 filter: meerkat_core::ToolFilter,
374 witnesses:
375 std::collections::BTreeMap<meerkat_core::ToolName, meerkat_core::ToolVisibilityWitness>,
376 },
377 RequestDeferredTools {
378 session_id: SessionId,
379 authorities: Vec<meerkat_core::DeferredToolLoadAuthority>,
380 },
381 PublishCommittedVisibleSet {
387 session_id: SessionId,
388 visibility_state: Box<meerkat_core::SessionToolVisibilityState>,
389 },
390 SetPeerIngressContext {
391 session_id: SessionId,
392 keep_alive: bool,
393 comms_runtime: Option<Arc<dyn CommsRuntime>>,
394 expected_attachment: Option<crate::RuntimeExecutorAttachmentWitness>,
398 mob_id: Option<crate::meerkat_machine::dsl::MobId>,
402 },
403 NotifyDrainExited {
404 session_id: SessionId,
405 reason: DrainExitReason,
406 },
407 AbortAll,
408 Abort {
409 session_id: SessionId,
410 },
411 Wait {
412 session_id: SessionId,
413 },
414 Ingest {
415 runtime_id: LogicalRuntimeId,
416 input: Input,
417 },
418 PublishEvent {
419 event: RuntimeEventEnvelope,
420 },
421 Retire {
422 runtime_id: LogicalRuntimeId,
423 },
424 Recycle {
425 runtime_id: LogicalRuntimeId,
426 },
427 Reset {
428 runtime_id: LogicalRuntimeId,
429 },
430 Recover {
431 runtime_id: LogicalRuntimeId,
432 },
433 Destroy {
434 runtime_id: LogicalRuntimeId,
435 },
436 RuntimeState {
437 runtime_id: LogicalRuntimeId,
438 },
439 ResolvedSessionLlmCapabilities {
440 session_id: SessionId,
441 },
442 ConfigureModelRoutingBaseline {
443 session_id: SessionId,
444 baseline_model: ModelId,
445 realtime_capable: bool,
446 },
447 SessionModelRoutingStatus {
448 session_id: SessionId,
449 },
450 RequestSwitchTurn {
451 session_id: SessionId,
452 request: Box<SwitchTurnRequest>,
453 },
454 AdmitModelRoutingAssistantTurn {
455 session_id: SessionId,
456 },
457 BeginImageOperation {
458 session_id: SessionId,
459 request: Box<ImageOperationRoutingRequest>,
460 },
461 DenyImageOperationPlan {
462 session_id: SessionId,
463 operation_id: ImageOperationId,
464 reason: ImageOperationDenialReason,
465 },
466 ActivateImageOperationOverride {
467 session_id: SessionId,
468 operation_id: ImageOperationId,
469 },
470 ClassifyImageOperationTerminal {
471 session_id: SessionId,
472 operation_id: ImageOperationId,
473 observation: ImageProviderTerminalObservation,
474 provider_text: ProviderTextDisposition,
475 },
476 CompleteImageOperation {
477 session_id: SessionId,
478 operation_id: ImageOperationId,
479 terminal: ImageOperationTerminalClass,
480 },
481 RestoreImageOperationOverride {
482 session_id: SessionId,
483 operation_id: ImageOperationId,
484 },
485 LoadBoundaryReceipt {
486 runtime_id: LogicalRuntimeId,
487 run_id: LifecycleRunId,
488 sequence: u64,
489 },
490 AcceptWithCompletion {
491 session_id: SessionId,
492 input: Input,
493 register_completion: bool,
494 member_residency: MemberResidencyExpectation,
495 expected_attachment: Option<RuntimeExecutorAttachmentWitness>,
496 },
497 AcceptWithoutWake {
498 session_id: SessionId,
499 input: Input,
500 },
501}
502
503#[derive(Debug, Clone)]
504pub(crate) enum MemberResidencyExpectation {
505 Unfenced,
506 PeerOnly,
507 Placed(meerkat_contracts::wire::supervisor_bridge::BridgeMemberIncarnation),
508}
509
510#[derive(Debug, Clone)]
511pub(crate) struct MeerkatMachineRunFailure {
512 pub source: Option<dsl::RunFailureSourceKind>,
513 pub machine_terminal_failure_observed: bool,
514 pub machine_terminal_error: Option<meerkat_core::TurnErrorMetadata>,
515 pub error: String,
516}
517
518impl MeerkatMachineRunFailure {
519 pub(crate) fn from_machine_terminal_failure(error: meerkat_core::TurnErrorMetadata) -> Self {
520 let detail = error
521 .detail
522 .clone()
523 .unwrap_or_else(|| "machine terminal failure".to_string());
524 Self {
525 source: None,
526 machine_terminal_failure_observed: true,
527 machine_terminal_error: Some(error),
528 error: detail,
529 }
530 }
531}
532
533#[derive(Debug)]
534#[allow(clippy::large_enum_variant)]
535pub(crate) enum MeerkatMachineCommandResult {
536 AcceptOutcome(AcceptOutcome),
537 AcceptWithCompletion {
538 outcome: AcceptOutcome,
539 handle: Option<crate::completion::CompletionHandle>,
540 #[cfg_attr(not(test), allow(dead_code))]
541 admission_signal: crate::driver::ephemeral::PostAdmissionSignal,
542 },
543 Unit,
544 Bool(bool),
545 Spawned(bool),
546 OpsLifecycleRegistry(Option<Arc<crate::ops_lifecycle::RuntimeOpsLifecycleRegistry>>),
547 Bindings(meerkat_core::SessionRuntimeBindings),
548 InputState(Option<StoredInputState>),
549 InteractionTerminalStatus(
550 Option<crate::terminal_status::Sourced<crate::terminal_status::InteractionTerminalReport>>,
551 ),
552 RunTerminalStatus(crate::terminal_status::Sourced<crate::terminal_status::RunTerminalReport>),
553 ActiveInputs(Vec<InputId>),
554 LlmReconfigured(SessionLlmReconfigureReport),
555 VisibilityRevision(meerkat_core::ToolScopeRevision),
556 VisibilityPublished(meerkat_core::SessionToolVisibilityState),
557 RetireReport(RetireReport),
558 RecycleReport(RecycleReport),
559 ResetReport(ResetReport),
560 RecoveryReport(RecoveryReport),
561 DestroyReport(DestroyReport),
562 RuntimeState(RuntimeState),
563 ResolvedSessionLlmCapabilities(Option<SessionLlmCapabilitySurface>),
564 SessionModelRoutingStatus(SessionModelRoutingStatus),
565 SwitchTurnControlResult(SwitchTurnControlResult),
566 ImageOperationRoutingResult(ImageOperationRoutingResult),
567 ImageOperationPhase(ImageOperationPhase),
568 ImageOperationTerminalClass(ImageOperationTerminalClass),
569 BoundaryReceipt(Option<RunBoundaryReceipt>),
570}
571
572#[doc(hidden)]
573#[must_use]
574pub fn canonical_meerkat_machine_command_manifest() -> IndexSet<&'static str> {
575 canonical_meerkat_machine_command_input_variant_manifest()
576 .into_iter()
577 .map(|variant| variant.as_str())
578 .collect()
579}
580
581#[doc(hidden)]
582#[must_use]
583pub fn canonical_meerkat_machine_command_input_variant_manifest()
584-> IndexSet<MeerkatMachineInputVariant> {
585 canonical_meerkat_machine_command_classifications()
586 .into_iter()
587 .flat_map(|record| record.classification.catalog_input_variants())
588 .collect()
589}
590
591#[doc(hidden)]
592#[must_use]
593pub fn canonical_meerkat_machine_runtime_internal_manifest() -> IndexSet<&'static str> {
594 canonical_meerkat_machine_runtime_internal_input_variant_manifest()
595 .into_iter()
596 .map(|variant| variant.as_str())
597 .collect()
598}
599
600#[doc(hidden)]
601#[must_use]
602pub fn canonical_meerkat_machine_runtime_internal_input_variant_manifest()
603-> IndexSet<MeerkatMachineInputVariant> {
604 canonical_meerkat_machine_runtime_internal_classifications()
605 .into_iter()
606 .map(|record| record.input.input_variant())
607 .collect()
608}
609
610#[doc(hidden)]
611#[must_use]
612pub fn canonical_meerkat_machine_runtime_internal_fieldless_input_variant_manifest()
613-> IndexSet<MeerkatMachineInputVariant> {
614 MeerkatMachineFieldlessRuntimeInternalInput::ALL
615 .iter()
616 .copied()
617 .map(MeerkatMachineFieldlessRuntimeInternalInput::input_variant)
618 .collect()
619}
620
621macro_rules! meerkat_machine_runtime_internal_inputs {
622 ($($reason:ident => [$($variant:ident),+ $(,)?]),+ $(,)?) => {
623 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
624 pub enum MeerkatMachineRuntimeInternalInput {
625 $($($variant),+),+
626 }
627
628 impl MeerkatMachineRuntimeInternalInput {
629 pub const ALL: &'static [Self] = &[
630 $($(Self::$variant),+),+
631 ];
632
633 pub const CLASSIFICATIONS: &'static [MeerkatMachineRuntimeInternalClassificationRecord] = &[
634 $($(
635 MeerkatMachineRuntimeInternalClassificationRecord {
636 input: Self::$variant,
637 reason: MeerkatMachineRuntimeInternalReason::$reason,
638 },
639 )+)+
640 ];
641
642 #[must_use]
643 pub const fn input_variant(self) -> MeerkatMachineInputVariant {
644 match self {
645 $($(Self::$variant => MeerkatMachineInputVariant::$variant,)+)+
646 }
647 }
648
649 #[must_use]
650 pub const fn reason(self) -> MeerkatMachineRuntimeInternalReason {
651 match self {
652 $(
653 $(Self::$variant)|+ => MeerkatMachineRuntimeInternalReason::$reason,
654 )+
655 }
656 }
657 }
658 };
659}
660
661#[derive(Debug, Clone, Copy, PartialEq, Eq)]
662pub enum MeerkatMachineRuntimeInternalReason {
663 InputQueueLifecycle,
664 OperationLifecycle,
665 RunExecutionLifecycle,
666 CancellationLifecycle,
667 LiveTopologyReconfiguration,
668 InteractionStreamLifecycle,
669 EventStreamLifecycle,
670 CommsIngressLifecycle,
671 SupervisorTrustLifecycle,
672 MobOperatorAuthorityLifecycle,
673 PeerRequestLifecycle,
674 VisibilityAuthorityLifecycle,
675 DeferredSessionLifecycle,
676 ExtractionLifecycle,
677 McpServerLifecycle,
678 ModelRoutingLifecycle,
679 ExternalSurfaceLifecycle,
680 FailureRecoveryLifecycle,
681 UserInterruptDispatch,
682 SessionUnregisterDrainLifecycle,
683}
684
685#[derive(Debug, Clone, Copy, PartialEq, Eq)]
686pub struct MeerkatMachineRuntimeInternalClassificationRecord {
687 pub input: MeerkatMachineRuntimeInternalInput,
688 pub reason: MeerkatMachineRuntimeInternalReason,
689}
690
691meerkat_machine_runtime_internal_inputs!(
692 InputQueueLifecycle => [
693 AbandonInput,
694 AdvanceSessionContext,
695 ArchiveTerminalInput,
696 BudgetExhausted,
697 ChangeLane,
698 CoalesceInput,
699 ConsumeInput,
700 ConsumeOnAccept,
701 MarkApplied,
702 MarkAppliedPendingConsumption,
703 DeferInputBehindBacklog,
704 PrioritizeInput,
705 QueueAccepted,
706 RecoverAdmittedInput,
707 RecoverInputLifecycle,
708 ResolveAdmissionIdempotency,
709 ResolveAdmissionPlan,
710 ResolveAdmissionValidation,
711 ResolveInputPublicLifecycle,
712 ResolveInputPublicTerminalOutcome,
713 ResolveTranscriptEditAdmission,
714 RegisterAcceptedIdempotency,
715 ResolveStagedRollback,
716 RetryRequested,
717 RollbackStaged,
718 StageForRun,
719 StartConversationRun,
720 StartImmediateAppend,
721 SteerAccepted,
722 SupersedeInput,
723 AuthorizeStoredInputStateSeed,
724 ClassifyInputTerminality,
725 ClassifyRecoveredInputDurability,
726 ClassifyRuntimeLoopQueueAdmission,
727 NormalizeRecoveredInputLifecycle,
728 ],
729 OperationLifecycle => [
730 AbortOp,
731 CancelOp,
732 CancelWaitAll,
733 ClassifyOperationCompletionFeed,
734 ClassifyOperationCompletionWake,
735 ClassifyOperationDurability,
736 ClassifyOperationPublicResult,
737 ClassifyOperationTerminality,
738 ClassifyOperationTransitionIdempotence,
739 ClassifyRecoveredOperationRecord,
740 CollectCompletedOp,
741 CompleteOp,
742 EvictCompletedOp,
743 FailOp,
744 IncrementAttemptCount,
745 OpsBarrierSatisfied,
746 PeerReadyOp,
747 ProgressReportedOp,
748 RecoverCompletionFeedEntry,
749 RegisterOp,
750 RegisterPendingOps,
751 RecoverCompletionConsumerCursors,
752 RecoverOpRecord,
753 RecoverOpsCompletionCursor,
754 ResolveOpLifecycleTransitionRejection,
755 ResolveRuntimeOpsLifecycleDurability,
756 ResolveWaitAllAdmission,
757 RequestWaitAll,
758 RetireCompletedOp,
759 RetireRequestedOp,
760 RollbackUnreturnedOp,
761 SatisfyWaitAll,
762 StartOp,
763 TerminateOp,
764 ],
765 RunExecutionLifecycle => [
766 AcknowledgeTerminal,
767 CallbackPending,
768 AdvanceAgentCompletionCursor,
769 AdvanceRuntimeInjectedCompletionCursor,
770 AdvanceRuntimeObservedCompletionCursor,
771 BoundaryComplete,
772 BoundaryContinue,
773 ClassifyAssistantOutput,
774 ClassifyCallTimeout,
775 ClassifyTurnTerminalCauseClass,
776 ClassifyTurnTerminality,
777 ClearSessionLlmState,
778 Commit,
779 CommitTerminalBoundarySequence,
780 Fail,
781 HydrateSessionLlmState,
782 LlmReturnedTerminal,
783 LlmReturnedToolCalls,
784 LiveBoundaryUnavailable,
785 Prepare,
786 PrimitiveApplied,
787 RecordBoundarySeq,
788 ResolveLiveBoundaryContextReceipt,
789 ResolveRuntimeCompletionCleanup,
790 ResolveRuntimeCompletionResult,
791 ResolveRuntimeCompletionWaitFailure,
792 ResolveTurnSurfaceResult,
793 RollbackRun,
794 RunCompleted,
795 RunFailed,
796 RuntimeExecutorExited,
797 ServiceTurnCommitted,
798 TimeBudgetExceeded,
799 ToolCallsResolved,
800 TurnLimitReached,
801 ],
802 CancellationLifecycle => [
803 AbortCancelAfterBoundaryDispatch,
804 CancelNow,
805 CancelRun,
806 CancellationObserved,
807 ForceCancelNoRun,
808 RequestCancelAfterBoundary,
809 RunCancelled,
810 ],
811 LiveTopologyReconfiguration => [
812 AbandonLiveOpenAdmission,
813 CompleteUntilChangedSwitchTurnReconfigure,
814 RecordLiveChannelRequestRejected,
815 RecordLiveChannelStatus,
816 RecordLiveCloseClosed,
817 RecordLiveCommandAccepted,
818 RecordLiveCommandRejected,
819 RecordLiveRefreshQueued,
820 ResolveLiveOpenAdmission,
821 ],
822 InteractionStreamLifecycle => [
823 InteractionStreamAbandoned,
824 InteractionStreamAttached,
825 InteractionStreamClosedEarly,
826 InteractionStreamCompleted,
827 InteractionStreamExpired,
828 InteractionStreamReserved,
829 ],
830 EventStreamLifecycle => [
831 RecordMobEventStreamOpened,
832 RecordMobEventStreamTerminated,
833 RecordSessionEventStreamOpened,
834 RecordSessionEventStreamTerminated,
835 ResolveMobEventStreamClose,
836 ResolveSessionEventStreamClose,
837 ],
838 CommsIngressLifecycle => [
839 AddDirectPeerEndpoint,
840 ApplyMobPeerOverlay,
841 AttachMobIngress,
842 AttachSessionIngress,
843 AuthorizeSupervisorMobPeerOverlay,
844 BindSupervisor,
845 ClearLocalEndpoint,
846 DetachIngress,
847 PeerResponseRejected,
848 PublishLocalEndpoint,
849 RemoveDirectPeerEndpoint,
850 ResolvePeerIngressDequeue,
851 ResolvePeerIngressReceive,
852 ResolveSupervisorAuthorizeAdmission,
853 ResolveSupervisorBindAdmission,
854 ResolveSupervisorBindMaterialAdmission,
855 ResolveSupervisorBridgeCommandAdmission,
856 SpawnDrain,
857 StopDrain,
858 ],
859 SupervisorTrustLifecycle => [
860 AuthorizeSupervisor,
861 PrepareTerminalSupervisorCleanupBindings,
862 RecoverRevokedSupervisorReceipt,
863 RecoverSupervisorBinding,
864 RecoverSupervisorRevocationPending,
865 RecoverSupervisorRotationOperation,
866 RecoverSupervisorRotationTerminalReceipt,
867 RefreshSupervisorBindingRoute,
868 RequestSupervisorTrustPublish,
869 ResolveSupervisorCleanupCommandAdmission,
870 ResumeSupervisorRotation,
871 RevokeSupervisor,
872 SubmitSupervisorRotation,
873 SupervisorRotationNextPublished,
874 SupervisorRotationPreviousRevoked,
875 SupervisorTrustEdgePublishFailed,
876 SupervisorTrustEdgePublished,
877 SupervisorTrustEdgeRevokeFailed,
878 SupervisorTrustEdgeRevoked,
879 ObserveSupervisorRotation,
880 ],
881 MobOperatorAuthorityLifecycle => [
882 GrantMobOperatorManageMob,
883 ResolveMobOperatorCreateAuthority,
884 RestoreMobOperatorAuthority,
885 SetMobOperatorCreateAuthority,
886 SetMobOperatorProfileMutation,
887 SetMobOperatorSpawnProfilesInMob,
888 ],
889 PeerRequestLifecycle => [
890 PeerRequestReceived,
891 PeerRequestSendFailed,
892 PeerRequestSent,
893 PeerRequestTimedOut,
894 PeerResponseProgressArrived,
895 PeerResponseReplied,
896 PeerResponseTerminalArrived,
897 ],
898 VisibilityAuthorityLifecycle => [
899 CommitDeferredNames,
900 CommitVisibilityFilter,
901 ClearTurnToolOverlay,
902 ReplaceDeferredToolAuthorityCatalog,
903 ReplaceFilterToolAuthorityCatalog,
904 SetTurnToolOverlay,
905 StageDeferredNames,
906 StageVisibilityFilter,
907 SurfaceSetRemovalTimeout,
908 ReplaceVisibilityState,
909 ],
910 DeferredSessionLifecycle => [
911 AbandonDeferredSessionPromotion,
912 AuthorizeDeferredSessionMachineArchivedResume,
913 BeginDeferredSessionArchive,
914 BeginDeferredSessionPromotion,
915 DropDeferredSession,
916 FinishDeferredSessionArchive,
917 FinishDeferredSessionPromotion,
918 RestoreDeferredSessionArchive,
919 StageDeferredSession,
920 UpdateDeferredSessionKeepAlive,
921 UpdateDeferredSessionLlmIdentity,
922 ],
923 ExtractionLifecycle => [
924 EnterExtraction,
925 ExtractionFailed,
926 ExtractionStart,
927 ExtractionValidationFailed,
928 ExtractionValidationPassed,
929 ],
930 McpServerLifecycle => [
931 McpServerConnectPending,
932 McpServerConnected,
933 McpServerDisconnected,
934 McpServerFailed,
935 McpServerReload,
936 ],
937 ModelRoutingLifecycle => [
938 CommitStickyModelFallback,
939 ModelRoutingStatus,
940 RequestFiniteSwitchTurn,
941 RequestUntilChangedSwitchTurn,
942 SetModelRoutingBaseline,
943 ],
944 ExternalSurfaceLifecycle => [
945 AdmitSurfaceRequest,
946 CancelSurfaceRequest,
947 ClassifySurfaceRequestTerminal,
948 FinishSurfaceRequestUnpublished,
949 PublishOrCancelSurfaceRequest,
950 PublishSurfaceRequest,
951 RecordLiveWebrtcAnswerAccepted,
952 RecordLiveWebrtcTokenIssued,
953 RecordLiveWebsocketTokenIssued,
954 ResolveLiveWebrtcAnswerAdmission,
955 ResolveLiveWebsocketTokenAdmission,
956 SurfaceApplyBoundary,
957 SurfaceCallFinished,
958 SurfaceCallStarted,
959 SurfaceFinalizeRemovalClean,
960 SurfaceFinalizeRemovalForced,
961 SurfaceMarkPendingFailed,
962 SurfaceMarkPendingSucceeded,
963 SurfaceRegister,
964 SurfaceShutdown,
965 SurfaceSnapshotAligned,
966 SurfaceStageAdd,
967 SurfaceStageReload,
968 SurfaceStageRemove,
969 ],
970 FailureRecoveryLifecycle => [
971 AuthorizeDurableTailRecovery,
972 AuthorizeInteractionTerminalOutboxAdoption,
973 ClassifyLlmFailureRecovery,
974 ClassifyRuntimeAuthorityReconciliation,
975 ClassifyRuntimeLifecycleDurability,
976 ClassifyRuntimeLifecycleState,
977 FatalFailure,
978 RecoverableFailure,
979 RecoverRuntimeCompletionResultCorrelation,
980 ResolveVisibleRuntimePhase,
981 ],
982 UserInterruptDispatch => [
983 InterruptCurrentRun,
984 ResolveUserInterruptPublicResult,
985 ],
986 SessionUnregisterDrainLifecycle => [
987 BeginUnregisterUnservedAttachment,
988 BeginUnregisterSession,
989 CommsDrainExitedForUnregister,
990 CompletionWaitersResolvedForUnregister,
991 RuntimeLoopStoppedForUnregister,
992 ],
993);
994
995macro_rules! meerkat_machine_fieldless_runtime_internal_inputs {
996 ($($authority:ident => [$($variant:ident),+ $(,)?]),+ $(,)?) => {
997 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
998 pub enum MeerkatMachineFieldlessRuntimeInternalInput {
999 $($($variant),+),+
1000 }
1001
1002 impl MeerkatMachineFieldlessRuntimeInternalInput {
1003 pub const ALL: &'static [Self] = &[
1004 $($(Self::$variant),+),+
1005 ];
1006
1007 #[must_use]
1008 pub const fn runtime_internal_input(self) -> MeerkatMachineRuntimeInternalInput {
1009 match self {
1010 $($(Self::$variant => MeerkatMachineRuntimeInternalInput::$variant,)+)+
1011 }
1012 }
1013
1014 #[must_use]
1015 pub const fn input_variant(self) -> MeerkatMachineInputVariant {
1016 self.runtime_internal_input().input_variant()
1017 }
1018
1019 #[must_use]
1020 pub const fn authority(self) -> MeerkatMachineFieldlessRuntimeInternalAuthority {
1021 match self {
1022 $(
1023 $(Self::$variant)|+ => MeerkatMachineFieldlessRuntimeInternalAuthority::$authority,
1024 )+
1025 }
1026 }
1027
1028 #[must_use]
1029 pub const fn requires_typed_runtime_internal_stager(self) -> bool {
1030 matches!(
1031 self.authority(),
1032 MeerkatMachineFieldlessRuntimeInternalAuthority::UserInterruptDispatch
1033 )
1034 }
1035
1036 pub(crate) const fn dsl_input_variant(self) -> dsl::MeerkatMachineInputVariant {
1037 match self {
1038 $($(Self::$variant => dsl::MeerkatMachineInputVariant::$variant,)+)+
1039 }
1040 }
1041
1042 pub(crate) fn dsl_input(self) -> dsl::MeerkatMachineInput {
1043 match self {
1044 $($(Self::$variant => dsl::MeerkatMachineInput::$variant,)+)+
1045 }
1046 }
1047
1048 pub(crate) fn from_dsl_input_variant(
1049 variant: dsl::MeerkatMachineInputVariant,
1050 ) -> Option<Self> {
1051 Self::ALL
1052 .iter()
1053 .copied()
1054 .find(|input| input.dsl_input_variant() == variant)
1055 }
1056
1057 pub(crate) fn reject_raw_dsl_input(
1058 input: &dsl::MeerkatMachineInput,
1059 ) -> Result<(), String> {
1060 if let Some(fieldless) = Self::from_dsl_input_variant(input.variant())
1061 && fieldless.requires_typed_runtime_internal_stager()
1062 {
1063 let variant = fieldless.input_variant();
1064 return Err(format!(
1065 "fieldless runtime-internal input {variant:?} must use typed runtime-internal staging authority"
1066 ));
1067 }
1068 Ok(())
1069 }
1070 }
1071 };
1072}
1073
1074meerkat_machine_fieldless_runtime_internal_inputs!(
1075 RuntimeOwner => [
1076 RuntimeExecutorExited,
1077 ForceCancelNoRun,
1078 CancelWaitAll,
1079 StopDrain,
1080 SurfaceShutdown,
1081 DetachIngress,
1082 ClearLocalEndpoint,
1083 ],
1084 UserInterruptDispatch => [
1085 InterruptCurrentRun,
1086 ],
1087);
1088
1089#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1090pub enum MeerkatMachineFieldlessRuntimeInternalAuthority {
1091 RuntimeOwner,
1092 UserInterruptDispatch,
1093}
1094
1095#[doc(hidden)]
1096#[must_use]
1097pub fn canonical_meerkat_machine_runtime_internal_classifications()
1098-> Vec<MeerkatMachineRuntimeInternalClassificationRecord> {
1099 MeerkatMachineRuntimeInternalInput::CLASSIFICATIONS.to_vec()
1100}
1101
1102#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1115pub enum SupervisorBridgeCommandKind {
1116 BindMember,
1117 AuthorizeSupervisor,
1118 ObserveSupervisorRotation,
1119 RevokeSupervisor,
1120 DeliverMemberInput,
1121 ObserveMember,
1122 InterruptMember,
1123 HardCancelMember,
1124 CancelTrackedMemberInput,
1125 RetireMember,
1126 DestroyMember,
1127 WireMember,
1128 UnwireMember,
1129 DeclareMemberOutboundTaint,
1130 ReadMemberHistory,
1134 PollMemberEvents,
1135 OpenMemberLiveChannel,
1136 CloseMemberLiveChannel,
1137 MemberLiveChannelStatus,
1138 ControlMemberLiveChannel,
1139 BindHost,
1143 RebindHost,
1144 RevokeHost,
1145 MaterializeMember,
1146 ReleaseMember,
1147 InstallPeerTrust,
1148 RemovePeerTrust,
1149 HostStatus,
1150 MemberOperatorRequest,
1151}
1152
1153impl SupervisorBridgeCommandKind {
1154 pub const ALL: &'static [Self] = &[
1155 Self::BindMember,
1156 Self::AuthorizeSupervisor,
1157 Self::ObserveSupervisorRotation,
1158 Self::RevokeSupervisor,
1159 Self::DeliverMemberInput,
1160 Self::ObserveMember,
1161 Self::InterruptMember,
1162 Self::HardCancelMember,
1163 Self::CancelTrackedMemberInput,
1164 Self::RetireMember,
1165 Self::DestroyMember,
1166 Self::WireMember,
1167 Self::UnwireMember,
1168 Self::DeclareMemberOutboundTaint,
1169 Self::ReadMemberHistory,
1170 Self::PollMemberEvents,
1171 Self::OpenMemberLiveChannel,
1172 Self::CloseMemberLiveChannel,
1173 Self::MemberLiveChannelStatus,
1174 Self::ControlMemberLiveChannel,
1175 Self::BindHost,
1176 Self::RebindHost,
1177 Self::RevokeHost,
1178 Self::MaterializeMember,
1179 Self::ReleaseMember,
1180 Self::InstallPeerTrust,
1181 Self::RemovePeerTrust,
1182 Self::HostStatus,
1183 Self::MemberOperatorRequest,
1184 ];
1185
1186 #[must_use]
1188 pub const fn variant_name(self) -> &'static str {
1189 match self {
1190 Self::BindMember => "BindMember",
1191 Self::AuthorizeSupervisor => "AuthorizeSupervisor",
1192 Self::ObserveSupervisorRotation => "ObserveSupervisorRotation",
1193 Self::RevokeSupervisor => "RevokeSupervisor",
1194 Self::DeliverMemberInput => "DeliverMemberInput",
1195 Self::ObserveMember => "ObserveMember",
1196 Self::InterruptMember => "InterruptMember",
1197 Self::HardCancelMember => "HardCancelMember",
1198 Self::CancelTrackedMemberInput => "CancelTrackedMemberInput",
1199 Self::RetireMember => "RetireMember",
1200 Self::DestroyMember => "DestroyMember",
1201 Self::WireMember => "WireMember",
1202 Self::UnwireMember => "UnwireMember",
1203 Self::DeclareMemberOutboundTaint => "DeclareMemberOutboundTaint",
1204 Self::ReadMemberHistory => "ReadMemberHistory",
1205 Self::PollMemberEvents => "PollMemberEvents",
1206 Self::OpenMemberLiveChannel => "OpenMemberLiveChannel",
1207 Self::CloseMemberLiveChannel => "CloseMemberLiveChannel",
1208 Self::MemberLiveChannelStatus => "MemberLiveChannelStatus",
1209 Self::ControlMemberLiveChannel => "ControlMemberLiveChannel",
1210 Self::BindHost => "BindHost",
1211 Self::RebindHost => "RebindHost",
1212 Self::RevokeHost => "RevokeHost",
1213 Self::MaterializeMember => "MaterializeMember",
1214 Self::ReleaseMember => "ReleaseMember",
1215 Self::InstallPeerTrust => "InstallPeerTrust",
1216 Self::RemovePeerTrust => "RemovePeerTrust",
1217 Self::HostStatus => "HostStatus",
1218 Self::MemberOperatorRequest => "MemberOperatorRequest",
1219 }
1220 }
1221
1222 #[must_use]
1224 pub const fn admission_route(self) -> SupervisorBridgeCommandAdmissionRoute {
1225 match self {
1226 Self::BindMember => SupervisorBridgeCommandAdmissionRoute::SupervisorBind,
1227 Self::AuthorizeSupervisor => SupervisorBridgeCommandAdmissionRoute::SupervisorAuthorize,
1228 Self::ObserveSupervisorRotation => {
1229 SupervisorBridgeCommandAdmissionRoute::SupervisorRotationObservation
1230 }
1231 Self::RevokeSupervisor
1232 | Self::DeliverMemberInput
1233 | Self::ObserveMember
1234 | Self::InterruptMember
1235 | Self::HardCancelMember
1236 | Self::CancelTrackedMemberInput
1237 | Self::RetireMember
1238 | Self::DestroyMember
1239 | Self::WireMember
1240 | Self::UnwireMember
1241 | Self::DeclareMemberOutboundTaint
1242 | Self::ReadMemberHistory
1243 | Self::PollMemberEvents
1244 | Self::OpenMemberLiveChannel
1245 | Self::CloseMemberLiveChannel
1246 | Self::MemberLiveChannelStatus
1247 | Self::ControlMemberLiveChannel => {
1248 SupervisorBridgeCommandAdmissionRoute::SupervisorBridgeCommand
1249 }
1250 Self::BindHost
1251 | Self::RebindHost
1252 | Self::RevokeHost
1253 | Self::MaterializeMember
1254 | Self::ReleaseMember
1255 | Self::InstallPeerTrust
1256 | Self::RemovePeerTrust
1257 | Self::HostStatus
1258 | Self::MemberOperatorRequest => {
1259 SupervisorBridgeCommandAdmissionRoute::NotMemberAddressed
1260 }
1261 }
1262 }
1263
1264 #[must_use]
1267 pub const fn realization(self) -> SupervisorBridgeCommandRealization {
1268 match self {
1269 Self::BindMember
1270 | Self::AuthorizeSupervisor
1271 | Self::ObserveSupervisorRotation
1272 | Self::RevokeSupervisor
1273 | Self::DeliverMemberInput
1274 | Self::ObserveMember
1275 | Self::InterruptMember
1276 | Self::RetireMember
1277 | Self::DestroyMember
1278 | Self::WireMember
1279 | Self::UnwireMember
1280 | Self::DeclareMemberOutboundTaint
1281 | Self::HardCancelMember
1284 | Self::CancelTrackedMemberInput
1285 | Self::ReadMemberHistory
1286 | Self::PollMemberEvents
1287 | Self::OpenMemberLiveChannel
1291 | Self::CloseMemberLiveChannel
1292 | Self::MemberLiveChannelStatus
1293 | Self::ControlMemberLiveChannel => SupervisorBridgeCommandRealization::Realized,
1294 Self::BindHost
1301 | Self::RebindHost
1302 | Self::RevokeHost
1303 | Self::MaterializeMember
1304 | Self::ReleaseMember
1305 | Self::InstallPeerTrust
1306 | Self::RemovePeerTrust
1307 | Self::HostStatus => SupervisorBridgeCommandRealization::RealizedOffDrain {
1308 by: OffDrainResponder::HostDaemon,
1309 },
1310 Self::MemberOperatorRequest => SupervisorBridgeCommandRealization::RealizedOffDrain {
1314 by: OffDrainResponder::ControllingSupervisorInbox,
1315 },
1316 }
1317 }
1318}
1319
1320#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1323pub enum SupervisorBridgeCommandAdmissionRoute {
1324 SupervisorBind,
1328 SupervisorAuthorize,
1330 SupervisorRotationObservation,
1332 SupervisorBridgeCommand,
1340 NotMemberAddressed,
1344}
1345
1346impl SupervisorBridgeCommandAdmissionRoute {
1347 #[must_use]
1349 pub const fn admission_inputs(self) -> &'static [MeerkatMachineRuntimeInternalInput] {
1350 match self {
1351 Self::SupervisorBind => &[
1352 MeerkatMachineRuntimeInternalInput::ResolveSupervisorBindAdmission,
1353 MeerkatMachineRuntimeInternalInput::ResolveSupervisorBindMaterialAdmission,
1354 ],
1355 Self::SupervisorAuthorize => {
1356 &[MeerkatMachineRuntimeInternalInput::ResolveSupervisorAuthorizeAdmission]
1357 }
1358 Self::SupervisorRotationObservation => {
1359 &[MeerkatMachineRuntimeInternalInput::ObserveSupervisorRotation]
1360 }
1361 Self::SupervisorBridgeCommand => {
1362 &[MeerkatMachineRuntimeInternalInput::ResolveSupervisorBridgeCommandAdmission]
1363 }
1364 Self::NotMemberAddressed => &[],
1365 }
1366 }
1367}
1368
1369#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1373pub enum SupervisorBridgeCommandRealization {
1374 Realized,
1376 RealizedOffDrain { by: OffDrainResponder },
1382 FailClosedUnsupported,
1390}
1391
1392#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1394pub enum OffDrainResponder {
1395 HostDaemon,
1398 ControllingSupervisorInbox,
1402}
1403
1404#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1406pub struct SupervisorBridgeCommandClassificationRecord {
1407 pub kind: SupervisorBridgeCommandKind,
1408 pub route: SupervisorBridgeCommandAdmissionRoute,
1409 pub realization: SupervisorBridgeCommandRealization,
1410}
1411
1412#[doc(hidden)]
1413#[must_use]
1414pub fn canonical_supervisor_bridge_command_classifications()
1415-> Vec<SupervisorBridgeCommandClassificationRecord> {
1416 SupervisorBridgeCommandKind::ALL
1417 .iter()
1418 .copied()
1419 .map(|kind| SupervisorBridgeCommandClassificationRecord {
1420 kind,
1421 route: kind.admission_route(),
1422 realization: kind.realization(),
1423 })
1424 .collect()
1425}
1426
1427#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1428pub enum MeerkatMachineCommandClassification {
1429 CatalogInput(MeerkatMachineCatalogInput),
1430 CatalogInputs(&'static [MeerkatMachineCatalogInput]),
1431 ShellMechanic(MeerkatMachineShellMechanicReason),
1432}
1433
1434impl MeerkatMachineCommandClassification {
1435 #[must_use]
1436 pub fn catalog_inputs(self) -> Vec<MeerkatMachineCatalogInput> {
1437 match self {
1438 Self::CatalogInput(input) => vec![input],
1439 Self::CatalogInputs(inputs) => inputs.to_vec(),
1440 Self::ShellMechanic(_) => Vec::new(),
1441 }
1442 }
1443
1444 #[must_use]
1445 pub fn catalog_input_variants(self) -> Vec<MeerkatMachineInputVariant> {
1446 self.catalog_inputs()
1447 .into_iter()
1448 .map(MeerkatMachineCatalogInput::input_variant)
1449 .collect()
1450 }
1451}
1452
1453#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1454pub enum MeerkatMachineCatalogInput {
1455 RegisterSession,
1456 UnregisterSession,
1457 EnsureSessionWithExecutor,
1458 SetSilentIntents,
1459 CancelAfterBoundary,
1460 StopRuntimeExecutor,
1461 ContainsSession,
1462 SessionHasExecutor,
1463 SessionHasComms,
1464 OpsLifecycleRegistry,
1465 PrepareBindings,
1466 InputState,
1467 ListActiveInputs,
1468 ReconfigureSessionLlmIdentity,
1469 StagePersistentFilter,
1470 RequestDeferredTools,
1471 PublishCommittedVisibleSet,
1472 SetPeerIngressContext,
1473 NotifyDrainExited,
1474 AbortAll,
1475 Abort,
1476 Wait,
1477 Ingest,
1478 PublishEvent,
1479 Retire,
1480 Recycle,
1481 Reset,
1482 Recover,
1483 Destroy,
1484 RuntimeState,
1485 ModelRoutingStatus,
1486 SetModelRoutingBaseline,
1487 RequestFiniteSwitchTurn,
1488 RequestUntilChangedSwitchTurn,
1489 AdmitModelRoutingAssistantTurn,
1490 BeginImageOperation,
1491 DenyImageOperationPlan,
1492 ActivateImageOperationOverride,
1493 ClassifyImageOperationTerminal,
1494 CompleteImageOperation,
1495 RestoreImageOperationOverride,
1496 LoadBoundaryReceipt,
1497 AcceptWithCompletion,
1498 AcceptWithoutWake,
1499}
1500
1501impl MeerkatMachineCatalogInput {
1502 pub const ALL: &'static [Self] = &[
1503 Self::RegisterSession,
1504 Self::UnregisterSession,
1505 Self::EnsureSessionWithExecutor,
1506 Self::SetSilentIntents,
1507 Self::CancelAfterBoundary,
1508 Self::StopRuntimeExecutor,
1509 Self::ContainsSession,
1510 Self::SessionHasExecutor,
1511 Self::SessionHasComms,
1512 Self::OpsLifecycleRegistry,
1513 Self::PrepareBindings,
1514 Self::InputState,
1515 Self::ListActiveInputs,
1516 Self::ReconfigureSessionLlmIdentity,
1517 Self::StagePersistentFilter,
1518 Self::RequestDeferredTools,
1519 Self::PublishCommittedVisibleSet,
1520 Self::SetPeerIngressContext,
1521 Self::NotifyDrainExited,
1522 Self::AbortAll,
1523 Self::Abort,
1524 Self::Wait,
1525 Self::Ingest,
1526 Self::PublishEvent,
1527 Self::Retire,
1528 Self::Recycle,
1529 Self::Reset,
1530 Self::Recover,
1531 Self::Destroy,
1532 Self::RuntimeState,
1533 Self::ModelRoutingStatus,
1534 Self::SetModelRoutingBaseline,
1535 Self::RequestFiniteSwitchTurn,
1536 Self::RequestUntilChangedSwitchTurn,
1537 Self::AdmitModelRoutingAssistantTurn,
1538 Self::BeginImageOperation,
1539 Self::DenyImageOperationPlan,
1540 Self::ActivateImageOperationOverride,
1541 Self::ClassifyImageOperationTerminal,
1542 Self::CompleteImageOperation,
1543 Self::RestoreImageOperationOverride,
1544 Self::LoadBoundaryReceipt,
1545 Self::AcceptWithCompletion,
1546 Self::AcceptWithoutWake,
1547 ];
1548
1549 #[must_use]
1550 pub const fn input_variant(self) -> MeerkatMachineInputVariant {
1551 match self {
1552 Self::RegisterSession => MeerkatMachineInputVariant::RegisterSession,
1553 Self::UnregisterSession => MeerkatMachineInputVariant::UnregisterSession,
1554 Self::EnsureSessionWithExecutor => {
1555 MeerkatMachineInputVariant::EnsureSessionWithExecutor
1556 }
1557 Self::SetSilentIntents => MeerkatMachineInputVariant::SetSilentIntents,
1558 Self::CancelAfterBoundary => MeerkatMachineInputVariant::CancelAfterBoundary,
1559 Self::StopRuntimeExecutor => MeerkatMachineInputVariant::StopRuntimeExecutor,
1560 Self::ContainsSession => MeerkatMachineInputVariant::ContainsSession,
1561 Self::SessionHasExecutor => MeerkatMachineInputVariant::SessionHasExecutor,
1562 Self::SessionHasComms => MeerkatMachineInputVariant::SessionHasComms,
1563 Self::OpsLifecycleRegistry => MeerkatMachineInputVariant::OpsLifecycleRegistry,
1564 Self::PrepareBindings => MeerkatMachineInputVariant::PrepareBindings,
1565 Self::InputState => MeerkatMachineInputVariant::InputState,
1566 Self::ListActiveInputs => MeerkatMachineInputVariant::ListActiveInputs,
1567 Self::ReconfigureSessionLlmIdentity => {
1568 MeerkatMachineInputVariant::ReconfigureSessionLlmIdentity
1569 }
1570 Self::StagePersistentFilter => MeerkatMachineInputVariant::StagePersistentFilter,
1571 Self::RequestDeferredTools => MeerkatMachineInputVariant::RequestDeferredTools,
1572 Self::PublishCommittedVisibleSet => {
1573 MeerkatMachineInputVariant::PublishCommittedVisibleSet
1574 }
1575 Self::SetPeerIngressContext => MeerkatMachineInputVariant::SetPeerIngressContext,
1576 Self::NotifyDrainExited => MeerkatMachineInputVariant::NotifyDrainExited,
1577 Self::AbortAll => MeerkatMachineInputVariant::AbortAll,
1578 Self::Abort => MeerkatMachineInputVariant::Abort,
1579 Self::Wait => MeerkatMachineInputVariant::Wait,
1580 Self::Ingest => MeerkatMachineInputVariant::Ingest,
1581 Self::PublishEvent => MeerkatMachineInputVariant::PublishEvent,
1582 Self::Retire => MeerkatMachineInputVariant::Retire,
1583 Self::Recycle => MeerkatMachineInputVariant::Recycle,
1584 Self::Reset => MeerkatMachineInputVariant::Reset,
1585 Self::Recover => MeerkatMachineInputVariant::Recover,
1586 Self::Destroy => MeerkatMachineInputVariant::Destroy,
1587 Self::RuntimeState => MeerkatMachineInputVariant::RuntimeState,
1588 Self::ModelRoutingStatus => MeerkatMachineInputVariant::ModelRoutingStatus,
1589 Self::SetModelRoutingBaseline => MeerkatMachineInputVariant::SetModelRoutingBaseline,
1590 Self::RequestFiniteSwitchTurn => MeerkatMachineInputVariant::RequestFiniteSwitchTurn,
1591 Self::RequestUntilChangedSwitchTurn => {
1592 MeerkatMachineInputVariant::RequestUntilChangedSwitchTurn
1593 }
1594 Self::AdmitModelRoutingAssistantTurn => {
1595 MeerkatMachineInputVariant::AdmitModelRoutingAssistantTurn
1596 }
1597 Self::BeginImageOperation => MeerkatMachineInputVariant::BeginImageOperation,
1598 Self::DenyImageOperationPlan => MeerkatMachineInputVariant::DenyImageOperationPlan,
1599 Self::ActivateImageOperationOverride => {
1600 MeerkatMachineInputVariant::ActivateImageOperationOverride
1601 }
1602 Self::ClassifyImageOperationTerminal => {
1603 MeerkatMachineInputVariant::ClassifyImageOperationTerminal
1604 }
1605 Self::CompleteImageOperation => MeerkatMachineInputVariant::CompleteImageOperation,
1606 Self::RestoreImageOperationOverride => {
1607 MeerkatMachineInputVariant::RestoreImageOperationOverride
1608 }
1609 Self::LoadBoundaryReceipt => MeerkatMachineInputVariant::LoadBoundaryReceipt,
1610 Self::AcceptWithCompletion => MeerkatMachineInputVariant::AcceptWithCompletion,
1611 Self::AcceptWithoutWake => MeerkatMachineInputVariant::AcceptWithoutWake,
1612 }
1613 }
1614
1615 #[must_use]
1616 pub const fn as_str(self) -> &'static str {
1617 match self {
1618 Self::RegisterSession => "RegisterSession",
1619 Self::UnregisterSession => "UnregisterSession",
1620 Self::EnsureSessionWithExecutor => "EnsureSessionWithExecutor",
1621 Self::SetSilentIntents => "SetSilentIntents",
1622 Self::CancelAfterBoundary => "CancelAfterBoundary",
1623 Self::StopRuntimeExecutor => "StopRuntimeExecutor",
1624 Self::ContainsSession => "ContainsSession",
1625 Self::SessionHasExecutor => "SessionHasExecutor",
1626 Self::SessionHasComms => "SessionHasComms",
1627 Self::OpsLifecycleRegistry => "OpsLifecycleRegistry",
1628 Self::PrepareBindings => "PrepareBindings",
1629 Self::InputState => "InputState",
1630 Self::ListActiveInputs => "ListActiveInputs",
1631 Self::ReconfigureSessionLlmIdentity => "ReconfigureSessionLlmIdentity",
1632 Self::StagePersistentFilter => "StagePersistentFilter",
1633 Self::RequestDeferredTools => "RequestDeferredTools",
1634 Self::PublishCommittedVisibleSet => "PublishCommittedVisibleSet",
1635 Self::SetPeerIngressContext => "SetPeerIngressContext",
1636 Self::NotifyDrainExited => "NotifyDrainExited",
1637 Self::AbortAll => "AbortAll",
1638 Self::Abort => "Abort",
1639 Self::Wait => "Wait",
1640 Self::Ingest => "Ingest",
1641 Self::PublishEvent => "PublishEvent",
1642 Self::Retire => "Retire",
1643 Self::Recycle => "Recycle",
1644 Self::Reset => "Reset",
1645 Self::Recover => "Recover",
1646 Self::Destroy => "Destroy",
1647 Self::RuntimeState => "RuntimeState",
1648 Self::ModelRoutingStatus => "ModelRoutingStatus",
1649 Self::SetModelRoutingBaseline => "SetModelRoutingBaseline",
1650 Self::RequestFiniteSwitchTurn => "RequestFiniteSwitchTurn",
1651 Self::RequestUntilChangedSwitchTurn => "RequestUntilChangedSwitchTurn",
1652 Self::AdmitModelRoutingAssistantTurn => "AdmitModelRoutingAssistantTurn",
1653 Self::BeginImageOperation => "BeginImageOperation",
1654 Self::DenyImageOperationPlan => "DenyImageOperationPlan",
1655 Self::ActivateImageOperationOverride => "ActivateImageOperationOverride",
1656 Self::ClassifyImageOperationTerminal => "ClassifyImageOperationTerminal",
1657 Self::CompleteImageOperation => "CompleteImageOperation",
1658 Self::RestoreImageOperationOverride => "RestoreImageOperationOverride",
1659 Self::LoadBoundaryReceipt => "LoadBoundaryReceipt",
1660 Self::AcceptWithCompletion => "AcceptWithCompletion",
1661 Self::AcceptWithoutWake => "AcceptWithoutWake",
1662 }
1663 }
1664}
1665
1666impl MeerkatMachineCommandVariant {
1667 #[must_use]
1668 pub const fn catalog_input(self) -> Option<MeerkatMachineCatalogInput> {
1669 match self {
1670 Self::ConfigureModelRoutingBaseline
1671 | Self::RequestSwitchTurn
1672 | Self::ResolvedSessionLlmCapabilities
1673 | Self::SessionModelRoutingStatus
1674 | Self::PrepareLocalSessionBindings => None,
1675 Self::RegisterSession => Some(MeerkatMachineCatalogInput::RegisterSession),
1676 Self::UnregisterSession => Some(MeerkatMachineCatalogInput::UnregisterSession),
1677 Self::EnsureSessionWithExecutor => {
1678 Some(MeerkatMachineCatalogInput::EnsureSessionWithExecutor)
1679 }
1680 Self::SetSilentIntents => Some(MeerkatMachineCatalogInput::SetSilentIntents),
1681 Self::CancelAfterBoundary => Some(MeerkatMachineCatalogInput::CancelAfterBoundary),
1682 Self::StopRuntimeExecutor => Some(MeerkatMachineCatalogInput::StopRuntimeExecutor),
1683 Self::ContainsSession => Some(MeerkatMachineCatalogInput::ContainsSession),
1684 Self::SessionHasExecutor => Some(MeerkatMachineCatalogInput::SessionHasExecutor),
1685 Self::SessionHasComms => Some(MeerkatMachineCatalogInput::SessionHasComms),
1686 Self::OpsLifecycleRegistry => Some(MeerkatMachineCatalogInput::OpsLifecycleRegistry),
1687 Self::PrepareBindings => Some(MeerkatMachineCatalogInput::PrepareBindings),
1688 Self::InputState => Some(MeerkatMachineCatalogInput::InputState),
1689 Self::InputStateByIdempotencyKey => Some(MeerkatMachineCatalogInput::InputState),
1692 Self::InteractionTerminalStatus => Some(MeerkatMachineCatalogInput::InputState),
1696 Self::RunTerminalStatus => Some(MeerkatMachineCatalogInput::InputState),
1697 Self::ListActiveInputs => Some(MeerkatMachineCatalogInput::ListActiveInputs),
1698 Self::ReconfigureSessionLlmIdentity => {
1699 Some(MeerkatMachineCatalogInput::ReconfigureSessionLlmIdentity)
1700 }
1701 Self::StagePersistentFilter => Some(MeerkatMachineCatalogInput::StagePersistentFilter),
1702 Self::RequestDeferredTools => Some(MeerkatMachineCatalogInput::RequestDeferredTools),
1703 Self::PublishCommittedVisibleSet => {
1704 Some(MeerkatMachineCatalogInput::PublishCommittedVisibleSet)
1705 }
1706 Self::SetPeerIngressContext => Some(MeerkatMachineCatalogInput::SetPeerIngressContext),
1707 Self::NotifyDrainExited => Some(MeerkatMachineCatalogInput::NotifyDrainExited),
1708 Self::AbortAll => Some(MeerkatMachineCatalogInput::AbortAll),
1709 Self::Abort => Some(MeerkatMachineCatalogInput::Abort),
1710 Self::Wait => Some(MeerkatMachineCatalogInput::Wait),
1711 Self::Ingest => Some(MeerkatMachineCatalogInput::Ingest),
1712 Self::PublishEvent => Some(MeerkatMachineCatalogInput::PublishEvent),
1713 Self::Retire => Some(MeerkatMachineCatalogInput::Retire),
1714 Self::Recycle => Some(MeerkatMachineCatalogInput::Recycle),
1715 Self::Reset => Some(MeerkatMachineCatalogInput::Reset),
1716 Self::Recover => Some(MeerkatMachineCatalogInput::Recover),
1717 Self::Destroy => Some(MeerkatMachineCatalogInput::Destroy),
1718 Self::RuntimeState => Some(MeerkatMachineCatalogInput::RuntimeState),
1719 Self::AdmitModelRoutingAssistantTurn => {
1720 Some(MeerkatMachineCatalogInput::AdmitModelRoutingAssistantTurn)
1721 }
1722 Self::BeginImageOperation => Some(MeerkatMachineCatalogInput::BeginImageOperation),
1723 Self::DenyImageOperationPlan => {
1724 Some(MeerkatMachineCatalogInput::DenyImageOperationPlan)
1725 }
1726 Self::ActivateImageOperationOverride => {
1727 Some(MeerkatMachineCatalogInput::ActivateImageOperationOverride)
1728 }
1729 Self::ClassifyImageOperationTerminal => {
1730 Some(MeerkatMachineCatalogInput::ClassifyImageOperationTerminal)
1731 }
1732 Self::CompleteImageOperation => {
1733 Some(MeerkatMachineCatalogInput::CompleteImageOperation)
1734 }
1735 Self::RestoreImageOperationOverride => {
1736 Some(MeerkatMachineCatalogInput::RestoreImageOperationOverride)
1737 }
1738 Self::LoadBoundaryReceipt => Some(MeerkatMachineCatalogInput::LoadBoundaryReceipt),
1739 Self::AcceptWithCompletion => Some(MeerkatMachineCatalogInput::AcceptWithCompletion),
1740 Self::AcceptWithoutWake => Some(MeerkatMachineCatalogInput::AcceptWithoutWake),
1741 }
1742 }
1743}
1744
1745#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1746pub enum MeerkatMachineShellMechanicReason {
1747 ModelRoutingShellConfiguration,
1748 TurnControlOverlayRequest,
1749 RealtimeTransportObservation,
1750 SessionModelRoutingObservation,
1751 LocalSessionBindingBootstrap,
1752}
1753
1754#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1755pub struct MeerkatMachineCommandClassificationRecord {
1756 pub command: MeerkatMachineCommandVariant,
1757 pub classification: MeerkatMachineCommandClassification,
1758}
1759
1760#[doc(hidden)]
1761#[must_use]
1762pub fn canonical_meerkat_machine_command_classifications()
1763-> Vec<MeerkatMachineCommandClassificationRecord> {
1764 MeerkatMachineCommand::command_variant_manifest()
1765 .iter()
1766 .copied()
1767 .map(|variant| MeerkatMachineCommandClassificationRecord {
1768 command: variant,
1769 classification: meerkat_machine_command_classification(variant),
1770 })
1771 .collect()
1772}
1773
1774const fn meerkat_machine_command_classification(
1775 variant: MeerkatMachineCommandVariant,
1776) -> MeerkatMachineCommandClassification {
1777 match variant {
1778 MeerkatMachineCommandVariant::ConfigureModelRoutingBaseline => {
1779 MeerkatMachineCommandClassification::CatalogInput(
1780 MeerkatMachineCatalogInput::SetModelRoutingBaseline,
1781 )
1782 }
1783 MeerkatMachineCommandVariant::RequestSwitchTurn => {
1784 MeerkatMachineCommandClassification::CatalogInputs(&[
1785 MeerkatMachineCatalogInput::RequestFiniteSwitchTurn,
1786 MeerkatMachineCatalogInput::RequestUntilChangedSwitchTurn,
1787 ])
1788 }
1789 MeerkatMachineCommandVariant::ResolvedSessionLlmCapabilities => {
1790 MeerkatMachineCommandClassification::ShellMechanic(
1791 MeerkatMachineShellMechanicReason::SessionModelRoutingObservation,
1792 )
1793 }
1794 MeerkatMachineCommandVariant::SessionModelRoutingStatus => {
1795 MeerkatMachineCommandClassification::CatalogInput(
1796 MeerkatMachineCatalogInput::ModelRoutingStatus,
1797 )
1798 }
1799 MeerkatMachineCommandVariant::PrepareLocalSessionBindings => {
1800 MeerkatMachineCommandClassification::ShellMechanic(
1801 MeerkatMachineShellMechanicReason::LocalSessionBindingBootstrap,
1802 )
1803 }
1804 MeerkatMachineCommandVariant::RegisterSession => {
1805 MeerkatMachineCommandClassification::CatalogInput(
1806 MeerkatMachineCatalogInput::RegisterSession,
1807 )
1808 }
1809 MeerkatMachineCommandVariant::UnregisterSession => {
1810 MeerkatMachineCommandClassification::CatalogInput(
1811 MeerkatMachineCatalogInput::UnregisterSession,
1812 )
1813 }
1814 MeerkatMachineCommandVariant::EnsureSessionWithExecutor => {
1815 MeerkatMachineCommandClassification::CatalogInput(
1816 MeerkatMachineCatalogInput::EnsureSessionWithExecutor,
1817 )
1818 }
1819 MeerkatMachineCommandVariant::SetSilentIntents => {
1820 MeerkatMachineCommandClassification::CatalogInput(
1821 MeerkatMachineCatalogInput::SetSilentIntents,
1822 )
1823 }
1824 MeerkatMachineCommandVariant::CancelAfterBoundary => {
1825 MeerkatMachineCommandClassification::CatalogInput(
1826 MeerkatMachineCatalogInput::CancelAfterBoundary,
1827 )
1828 }
1829 MeerkatMachineCommandVariant::StopRuntimeExecutor => {
1830 MeerkatMachineCommandClassification::CatalogInput(
1831 MeerkatMachineCatalogInput::StopRuntimeExecutor,
1832 )
1833 }
1834 MeerkatMachineCommandVariant::ContainsSession => {
1835 MeerkatMachineCommandClassification::CatalogInput(
1836 MeerkatMachineCatalogInput::ContainsSession,
1837 )
1838 }
1839 MeerkatMachineCommandVariant::SessionHasExecutor => {
1840 MeerkatMachineCommandClassification::CatalogInput(
1841 MeerkatMachineCatalogInput::SessionHasExecutor,
1842 )
1843 }
1844 MeerkatMachineCommandVariant::SessionHasComms => {
1845 MeerkatMachineCommandClassification::CatalogInput(
1846 MeerkatMachineCatalogInput::SessionHasComms,
1847 )
1848 }
1849 MeerkatMachineCommandVariant::OpsLifecycleRegistry => {
1850 MeerkatMachineCommandClassification::CatalogInput(
1851 MeerkatMachineCatalogInput::OpsLifecycleRegistry,
1852 )
1853 }
1854 MeerkatMachineCommandVariant::PrepareBindings => {
1855 MeerkatMachineCommandClassification::CatalogInput(
1856 MeerkatMachineCatalogInput::PrepareBindings,
1857 )
1858 }
1859 MeerkatMachineCommandVariant::InputState => {
1860 MeerkatMachineCommandClassification::CatalogInput(
1861 MeerkatMachineCatalogInput::InputState,
1862 )
1863 }
1864 MeerkatMachineCommandVariant::InputStateByIdempotencyKey => {
1868 MeerkatMachineCommandClassification::CatalogInput(
1869 MeerkatMachineCatalogInput::InputState,
1870 )
1871 }
1872 MeerkatMachineCommandVariant::InteractionTerminalStatus
1876 | MeerkatMachineCommandVariant::RunTerminalStatus => {
1877 MeerkatMachineCommandClassification::CatalogInput(
1878 MeerkatMachineCatalogInput::InputState,
1879 )
1880 }
1881 MeerkatMachineCommandVariant::ListActiveInputs => {
1882 MeerkatMachineCommandClassification::CatalogInput(
1883 MeerkatMachineCatalogInput::ListActiveInputs,
1884 )
1885 }
1886 MeerkatMachineCommandVariant::ReconfigureSessionLlmIdentity => {
1887 MeerkatMachineCommandClassification::CatalogInput(
1888 MeerkatMachineCatalogInput::ReconfigureSessionLlmIdentity,
1889 )
1890 }
1891 MeerkatMachineCommandVariant::StagePersistentFilter => {
1892 MeerkatMachineCommandClassification::CatalogInput(
1893 MeerkatMachineCatalogInput::StagePersistentFilter,
1894 )
1895 }
1896 MeerkatMachineCommandVariant::RequestDeferredTools => {
1897 MeerkatMachineCommandClassification::CatalogInput(
1898 MeerkatMachineCatalogInput::RequestDeferredTools,
1899 )
1900 }
1901 MeerkatMachineCommandVariant::PublishCommittedVisibleSet => {
1902 MeerkatMachineCommandClassification::CatalogInput(
1903 MeerkatMachineCatalogInput::PublishCommittedVisibleSet,
1904 )
1905 }
1906 MeerkatMachineCommandVariant::SetPeerIngressContext => {
1907 MeerkatMachineCommandClassification::CatalogInput(
1908 MeerkatMachineCatalogInput::SetPeerIngressContext,
1909 )
1910 }
1911 MeerkatMachineCommandVariant::NotifyDrainExited => {
1912 MeerkatMachineCommandClassification::CatalogInput(
1913 MeerkatMachineCatalogInput::NotifyDrainExited,
1914 )
1915 }
1916 MeerkatMachineCommandVariant::AbortAll => {
1917 MeerkatMachineCommandClassification::CatalogInput(MeerkatMachineCatalogInput::AbortAll)
1918 }
1919 MeerkatMachineCommandVariant::Abort => {
1920 MeerkatMachineCommandClassification::CatalogInput(MeerkatMachineCatalogInput::Abort)
1921 }
1922 MeerkatMachineCommandVariant::Wait => {
1923 MeerkatMachineCommandClassification::CatalogInput(MeerkatMachineCatalogInput::Wait)
1924 }
1925 MeerkatMachineCommandVariant::Ingest => {
1926 MeerkatMachineCommandClassification::CatalogInput(MeerkatMachineCatalogInput::Ingest)
1927 }
1928 MeerkatMachineCommandVariant::PublishEvent => {
1929 MeerkatMachineCommandClassification::CatalogInput(
1930 MeerkatMachineCatalogInput::PublishEvent,
1931 )
1932 }
1933 MeerkatMachineCommandVariant::Retire => {
1934 MeerkatMachineCommandClassification::CatalogInput(MeerkatMachineCatalogInput::Retire)
1935 }
1936 MeerkatMachineCommandVariant::Recycle => {
1937 MeerkatMachineCommandClassification::CatalogInput(MeerkatMachineCatalogInput::Recycle)
1938 }
1939 MeerkatMachineCommandVariant::Reset => {
1940 MeerkatMachineCommandClassification::CatalogInput(MeerkatMachineCatalogInput::Reset)
1941 }
1942 MeerkatMachineCommandVariant::Recover => {
1943 MeerkatMachineCommandClassification::CatalogInput(MeerkatMachineCatalogInput::Recover)
1944 }
1945 MeerkatMachineCommandVariant::Destroy => {
1946 MeerkatMachineCommandClassification::CatalogInput(MeerkatMachineCatalogInput::Destroy)
1947 }
1948 MeerkatMachineCommandVariant::RuntimeState => {
1949 MeerkatMachineCommandClassification::CatalogInput(
1950 MeerkatMachineCatalogInput::RuntimeState,
1951 )
1952 }
1953 MeerkatMachineCommandVariant::AdmitModelRoutingAssistantTurn => {
1954 MeerkatMachineCommandClassification::CatalogInput(
1955 MeerkatMachineCatalogInput::AdmitModelRoutingAssistantTurn,
1956 )
1957 }
1958 MeerkatMachineCommandVariant::BeginImageOperation => {
1959 MeerkatMachineCommandClassification::CatalogInput(
1960 MeerkatMachineCatalogInput::BeginImageOperation,
1961 )
1962 }
1963 MeerkatMachineCommandVariant::DenyImageOperationPlan => {
1964 MeerkatMachineCommandClassification::CatalogInput(
1965 MeerkatMachineCatalogInput::DenyImageOperationPlan,
1966 )
1967 }
1968 MeerkatMachineCommandVariant::ActivateImageOperationOverride => {
1969 MeerkatMachineCommandClassification::CatalogInput(
1970 MeerkatMachineCatalogInput::ActivateImageOperationOverride,
1971 )
1972 }
1973 MeerkatMachineCommandVariant::ClassifyImageOperationTerminal => {
1974 MeerkatMachineCommandClassification::CatalogInput(
1975 MeerkatMachineCatalogInput::ClassifyImageOperationTerminal,
1976 )
1977 }
1978 MeerkatMachineCommandVariant::CompleteImageOperation => {
1979 MeerkatMachineCommandClassification::CatalogInput(
1980 MeerkatMachineCatalogInput::CompleteImageOperation,
1981 )
1982 }
1983 MeerkatMachineCommandVariant::RestoreImageOperationOverride => {
1984 MeerkatMachineCommandClassification::CatalogInput(
1985 MeerkatMachineCatalogInput::RestoreImageOperationOverride,
1986 )
1987 }
1988 MeerkatMachineCommandVariant::LoadBoundaryReceipt => {
1989 MeerkatMachineCommandClassification::CatalogInput(
1990 MeerkatMachineCatalogInput::LoadBoundaryReceipt,
1991 )
1992 }
1993 MeerkatMachineCommandVariant::AcceptWithCompletion => {
1994 MeerkatMachineCommandClassification::CatalogInput(
1995 MeerkatMachineCatalogInput::AcceptWithCompletion,
1996 )
1997 }
1998 MeerkatMachineCommandVariant::AcceptWithoutWake => {
1999 MeerkatMachineCommandClassification::CatalogInput(
2000 MeerkatMachineCatalogInput::AcceptWithoutWake,
2001 )
2002 }
2003 }
2004}
2005
2006#[derive(Debug, Clone, PartialEq, Eq)]
2010pub struct MeerkatCompletionWaiterSnapshot {
2011 pub input_id: InputId,
2012 pub waiter_count: usize,
2013}
2014
2015#[derive(Debug, Clone, PartialEq, Eq)]
2020pub struct MeerkatCompletionWaitersSnapshot {
2021 pub input_count: usize,
2022 pub waiter_count: usize,
2023 pub waiting_inputs: Vec<MeerkatCompletionWaiterSnapshot>,
2024}
2025
2026#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2028pub enum MeerkatDriverKind {
2029 Ephemeral,
2030 Persistent,
2031}
2032
2033#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2035pub struct MeerkatCursorSnapshot {
2036 pub agent_applied_cursor: u64,
2037 pub runtime_observed_seq: u64,
2038 pub runtime_last_injected_seq: u64,
2039}
2040
2041#[derive(Debug, Clone)]
2043pub struct MeerkatBindingSnapshot {
2044 pub session_id: SessionId,
2045 pub runtime_id: LogicalRuntimeId,
2046 pub driver_kind: MeerkatDriverKind,
2047 pub driver_present: bool,
2048 pub completions_present: bool,
2049 pub ops_registry_present: bool,
2050 pub epoch_id: RuntimeEpochId,
2051 pub cursor_state: MeerkatCursorSnapshot,
2052}
2053
2054#[derive(Debug, Clone)]
2056pub struct MeerkatControlSnapshot {
2057 pub phase: RuntimeState,
2058 pub current_run_id: Option<RunId>,
2059 pub pre_run_phase: Option<RuntimeState>,
2060}
2061
2062#[derive(Debug, Clone, PartialEq, Eq)]
2064pub struct MeerkatAdmittedInputSnapshot {
2065 pub input_id: InputId,
2066 pub content_shape: Option<ContentShape>,
2067 pub request_id: Option<RequestId>,
2068 pub reservation_key: Option<ReservationKey>,
2069 pub handling_mode: Option<HandlingMode>,
2070 pub live_interrupt_required: bool,
2074 pub lifecycle: Option<InputLifecycleState>,
2075 pub terminal_outcome: Option<InputTerminalOutcome>,
2076 pub last_run_id: Option<RunId>,
2077 pub last_boundary_sequence: Option<u64>,
2078 pub is_prompt: bool,
2079}
2080
2081#[derive(Debug, Clone, PartialEq, Eq)]
2083pub struct MeerkatInputsSnapshot {
2084 pub admission_order: Vec<MeerkatAdmittedInputSnapshot>,
2085 pub queue: Vec<InputId>,
2086 pub steer_queue: Vec<InputId>,
2087 pub current_run_id: Option<RunId>,
2088 pub current_run_contributors: Vec<InputId>,
2089 pub post_admission_signal: String,
2090 pub silent_intent_overrides: Vec<String>,
2091}
2092
2093#[derive(Debug, Clone)]
2099pub struct MeerkatArchiveSnapshot {
2100 pub control: MeerkatControlSnapshot,
2101 pub queue: Vec<InputId>,
2102 pub steer_queue: Vec<InputId>,
2103 pub completion_waiters: MeerkatCompletionWaitersSnapshot,
2104}
2105
2106#[derive(Debug, Clone)]
2112pub struct MeerkatLedgerSnapshot {
2113 pub input_count: usize,
2114 pub non_terminal_count: usize,
2115 pub accepted_count: usize,
2116 pub queued_count: usize,
2117 pub staged_count: usize,
2118 pub applied_count: usize,
2119 pub applied_pending_consumption_count: usize,
2120 pub consumed_count: usize,
2121 pub superseded_count: usize,
2122 pub coalesced_count: usize,
2123 pub abandoned_count: usize,
2124}
2125
2126#[derive(Debug, Clone)]
2128pub struct MeerkatOpsSnapshot {
2129 pub operation_count: usize,
2130 pub active_count: usize,
2131 pub wait_request_id: Option<WaitRequestId>,
2132 pub pending_wait_present: bool,
2133 pub pending_wait_request_id: Option<WaitRequestId>,
2134 pub wait_operation_ids: Vec<OperationId>,
2135 pub operations: Vec<OperationLifecycleSnapshot>,
2136}
2137
2138#[derive(Debug, Clone)]
2143pub struct MeerkatDrainSnapshot {
2144 pub slot_present: bool,
2145 pub phase: Option<CommsDrainPhase>,
2146 pub mode: Option<CommsDrainMode>,
2147 pub handle_present: bool,
2148}
2149
2150#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2157pub struct MeerkatFormalStateProjection {
2158 pub available_fields: BTreeMap<String, String>,
2160 pub unavailable_fields: Vec<String>,
2162}
2163
2164#[derive(Debug, Clone)]
2169pub struct MeerkatMachineSpineSnapshot {
2170 pub binding: MeerkatBindingSnapshot,
2171 pub control: MeerkatControlSnapshot,
2172 pub inputs: MeerkatInputsSnapshot,
2173 pub ledger: MeerkatLedgerSnapshot,
2174 pub completion_waiters: MeerkatCompletionWaitersSnapshot,
2175 pub ops: MeerkatOpsSnapshot,
2176 pub drain: MeerkatDrainSnapshot,
2177 pub formal_state: MeerkatFormalStateProjection,
2178}
2179
2180impl MeerkatMachineSpineSnapshot {
2181 pub fn validate_spine_invariants(&self) -> Result<(), Vec<String>> {
2187 let mut violations = Vec::new();
2188
2189 if self.control.phase == RuntimeState::Running && self.control.current_run_id.is_none() {
2193 violations
2194 .push("RunningHasActiveRunInvariant: phase is Running but no active run_id".into());
2195 }
2196
2197 if self.control.current_run_id.is_some()
2199 && !matches!(
2200 self.control.phase,
2201 RuntimeState::Running | RuntimeState::Retired
2202 )
2203 {
2204 violations.push(format!(
2205 "ActiveRunPhaseInvariant: active run_id present but phase is {:?}",
2206 self.control.phase
2207 ));
2208 }
2209
2210 if self.control.phase == RuntimeState::Destroyed {
2212 if !self.inputs.queue.is_empty() {
2213 violations.push("DestroyedShapeInvariant: Destroyed but queue is non-empty".into());
2214 }
2215 if !self.inputs.steer_queue.is_empty() {
2216 violations
2217 .push("DestroyedShapeInvariant: Destroyed but steer_queue is non-empty".into());
2218 }
2219 if self.completion_waiters.input_count > 0 {
2220 violations.push(
2221 "DestroyedShapeInvariant: Destroyed but completion waiters remain".into(),
2222 );
2223 }
2224 }
2225
2226 let queue_set: std::collections::HashSet<_> = self.inputs.queue.iter().collect();
2230 let steer_set: std::collections::HashSet<_> = self.inputs.steer_queue.iter().collect();
2231 if !queue_set.is_disjoint(&steer_set) {
2232 violations
2233 .push("QueueSteerDisjointInvariant: queue and steer_queue share entries".into());
2234 }
2235
2236 for qid in &self.inputs.queue {
2238 if let Some(snap) = self
2239 .inputs
2240 .admission_order
2241 .iter()
2242 .find(|a| &a.input_id == qid)
2243 {
2244 if snap.handling_mode != Some(HandlingMode::Queue) {
2245 violations.push(format!(
2246 "QueueHandlingInvariant: queue entry {qid} has handling_mode {:?}",
2247 snap.handling_mode
2248 ));
2249 }
2250 if snap.lifecycle != Some(InputLifecycleState::Queued) {
2251 violations.push(format!(
2252 "QueueHandlingInvariant: queue entry {qid} has lifecycle {:?}",
2253 snap.lifecycle
2254 ));
2255 }
2256 }
2257 }
2258
2259 for sid in &self.inputs.steer_queue {
2261 if let Some(snap) = self
2262 .inputs
2263 .admission_order
2264 .iter()
2265 .find(|a| &a.input_id == sid)
2266 {
2267 if snap.handling_mode != Some(HandlingMode::Steer) {
2268 violations.push(format!(
2269 "SteerHandlingInvariant: steer_queue entry {sid} has handling_mode {:?}",
2270 snap.handling_mode
2271 ));
2272 }
2273 if snap.lifecycle != Some(InputLifecycleState::Queued) {
2274 violations.push(format!(
2275 "SteerHandlingInvariant: steer_queue entry {sid} has lifecycle {:?}",
2276 snap.lifecycle
2277 ));
2278 }
2279 }
2280 }
2281
2282 for cid in &self.inputs.current_run_contributors {
2285 if let Some(snap) = self
2286 .inputs
2287 .admission_order
2288 .iter()
2289 .find(|a| &a.input_id == cid)
2290 && !matches!(
2291 snap.lifecycle,
2292 Some(
2293 InputLifecycleState::Staged
2294 | InputLifecycleState::Applied
2295 | InputLifecycleState::AppliedPendingConsumption
2296 )
2297 )
2298 {
2299 violations.push(format!(
2300 "ContributorLifecycleInvariant: contributor {cid} has lifecycle {:?}",
2301 snap.lifecycle
2302 ));
2303 }
2304 }
2305
2306 for snap in &self.inputs.admission_order {
2308 if snap.terminal_outcome.is_some() {
2309 if queue_set.contains(&snap.input_id) {
2310 violations.push(format!(
2311 "TerminalInputsNotQueuedInvariant: terminal input {} in queue",
2312 snap.input_id
2313 ));
2314 }
2315 if steer_set.contains(&snap.input_id) {
2316 violations.push(format!(
2317 "TerminalInputsNotQueuedInvariant: terminal input {} in steer_queue",
2318 snap.input_id
2319 ));
2320 }
2321 }
2322 }
2323
2324 if self.control.current_run_id.is_some() && self.inputs.current_run_contributors.is_empty()
2326 {
2327 violations
2328 .push("CurrentRunContributorsInvariant: active run but no contributors".into());
2329 }
2330
2331 if let Some(control_run_id) = &self.control.current_run_id {
2335 for cid in &self.inputs.current_run_contributors {
2336 if let Some(snap) = self
2337 .inputs
2338 .admission_order
2339 .iter()
2340 .find(|a| &a.input_id == cid)
2341 && snap.last_run_id.as_ref() != Some(control_run_id)
2342 {
2343 violations.push(format!(
2344 "ContributorRunIdentityInvariant: contributor {cid} has last_run_id {:?}, expected {:?}",
2345 snap.last_run_id, control_run_id
2346 ));
2347 }
2348 }
2349 }
2350
2351 let wait_active = self.ops.wait_request_id.is_some();
2355 if wait_active && self.ops.wait_operation_ids.is_empty() {
2356 violations
2357 .push("WaitAllAlignmentInvariant: wait_active but no wait_operation_ids".into());
2358 }
2359 if !wait_active && !self.ops.wait_operation_ids.is_empty() {
2360 violations.push(
2361 "WaitAllAlignmentInvariant: wait_operation_ids present but no wait_request_id"
2362 .into(),
2363 );
2364 }
2365
2366 if let Some(phase) = self.drain.phase
2370 && phase != CommsDrainPhase::Inactive
2371 && self.drain.mode.is_none()
2372 {
2373 violations.push("DrainModeInvariant: drain.phase is active but mode is None".into());
2374 }
2375
2376 if violations.is_empty() {
2377 Ok(())
2378 } else {
2379 Err(violations)
2380 }
2381 }
2382}