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