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 SatisfyWaitAll,
765 StartOp,
766 TerminateOp,
767 ],
768 RunExecutionLifecycle => [
769 AcknowledgeTerminal,
770 CallbackPending,
771 AdvanceAgentCompletionCursor,
772 AdvanceRuntimeInjectedCompletionCursor,
773 AdvanceRuntimeObservedCompletionCursor,
774 BoundaryComplete,
775 BoundaryContinue,
776 ClassifyAssistantOutput,
777 ClassifyCallTimeout,
778 ClassifyTurnTerminalCauseClass,
779 ClassifyTurnTerminality,
780 ClearSessionLlmState,
781 Commit,
782 Fail,
783 HydrateSessionLlmState,
784 LlmReturnedTerminal,
785 LlmReturnedToolCalls,
786 Prepare,
787 PrimitiveApplied,
788 RecordBoundarySeq,
789 ResolveLiveBoundaryContextReceipt,
790 ResolveRuntimeCompletionCleanup,
791 ResolveRuntimeCompletionResult,
792 ResolveRuntimeCompletionWaitFailure,
793 ResolveTurnSurfaceResult,
794 RollbackRun,
795 RunCompleted,
796 RunFailed,
797 RuntimeExecutorExited,
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 AuthorizeDeferredSessionSystemContextAppend,
914 BeginDeferredSessionArchive,
915 BeginDeferredSessionPromotion,
916 DropDeferredSession,
917 FinishDeferredSessionArchive,
918 FinishDeferredSessionPromotion,
919 RestoreDeferredSessionArchive,
920 StageDeferredSession,
921 UpdateDeferredSessionKeepAlive,
922 UpdateDeferredSessionLlmIdentity,
923 ],
924 ExtractionLifecycle => [
925 EnterExtraction,
926 ExtractionFailed,
927 ExtractionStart,
928 ExtractionValidationFailed,
929 ExtractionValidationPassed,
930 ],
931 McpServerLifecycle => [
932 McpServerConnectPending,
933 McpServerConnected,
934 McpServerDisconnected,
935 McpServerFailed,
936 McpServerReload,
937 ],
938 ModelRoutingLifecycle => [
939 CommitStickyModelFallback,
940 ModelRoutingStatus,
941 RequestFiniteSwitchTurn,
942 RequestUntilChangedSwitchTurn,
943 SetModelRoutingBaseline,
944 ],
945 ExternalSurfaceLifecycle => [
946 AdmitSurfaceRequest,
947 CancelSurfaceRequest,
948 ClassifySurfaceRequestTerminal,
949 FinishSurfaceRequestUnpublished,
950 PublishOrCancelSurfaceRequest,
951 PublishSurfaceRequest,
952 RecordLiveWebrtcAnswerAccepted,
953 RecordLiveWebrtcTokenIssued,
954 RecordLiveWebsocketTokenIssued,
955 ResolveLiveWebrtcAnswerAdmission,
956 ResolveLiveWebsocketTokenAdmission,
957 SurfaceApplyBoundary,
958 SurfaceCallFinished,
959 SurfaceCallStarted,
960 SurfaceFinalizeRemovalClean,
961 SurfaceFinalizeRemovalForced,
962 SurfaceMarkPendingFailed,
963 SurfaceMarkPendingSucceeded,
964 SurfaceRegister,
965 SurfaceShutdown,
966 SurfaceSnapshotAligned,
967 SurfaceStageAdd,
968 SurfaceStageReload,
969 SurfaceStageRemove,
970 ],
971 FailureRecoveryLifecycle => [
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 ServiceTurnCommitted,
1462 ContainsSession,
1463 SessionHasExecutor,
1464 SessionHasComms,
1465 OpsLifecycleRegistry,
1466 PrepareBindings,
1467 InputState,
1468 ListActiveInputs,
1469 ReconfigureSessionLlmIdentity,
1470 StagePersistentFilter,
1471 RequestDeferredTools,
1472 PublishCommittedVisibleSet,
1473 SetPeerIngressContext,
1474 NotifyDrainExited,
1475 AbortAll,
1476 Abort,
1477 Wait,
1478 Ingest,
1479 PublishEvent,
1480 Retire,
1481 Recycle,
1482 Reset,
1483 Recover,
1484 Destroy,
1485 RuntimeState,
1486 ModelRoutingStatus,
1487 SetModelRoutingBaseline,
1488 RequestFiniteSwitchTurn,
1489 RequestUntilChangedSwitchTurn,
1490 AdmitModelRoutingAssistantTurn,
1491 BeginImageOperation,
1492 DenyImageOperationPlan,
1493 ActivateImageOperationOverride,
1494 ClassifyImageOperationTerminal,
1495 CompleteImageOperation,
1496 RestoreImageOperationOverride,
1497 LoadBoundaryReceipt,
1498 AcceptWithCompletion,
1499 AcceptWithoutWake,
1500}
1501
1502impl MeerkatMachineCatalogInput {
1503 pub const ALL: &'static [Self] = &[
1504 Self::RegisterSession,
1505 Self::UnregisterSession,
1506 Self::EnsureSessionWithExecutor,
1507 Self::SetSilentIntents,
1508 Self::CancelAfterBoundary,
1509 Self::StopRuntimeExecutor,
1510 Self::ServiceTurnCommitted,
1511 Self::ContainsSession,
1512 Self::SessionHasExecutor,
1513 Self::SessionHasComms,
1514 Self::OpsLifecycleRegistry,
1515 Self::PrepareBindings,
1516 Self::InputState,
1517 Self::ListActiveInputs,
1518 Self::ReconfigureSessionLlmIdentity,
1519 Self::StagePersistentFilter,
1520 Self::RequestDeferredTools,
1521 Self::PublishCommittedVisibleSet,
1522 Self::SetPeerIngressContext,
1523 Self::NotifyDrainExited,
1524 Self::AbortAll,
1525 Self::Abort,
1526 Self::Wait,
1527 Self::Ingest,
1528 Self::PublishEvent,
1529 Self::Retire,
1530 Self::Recycle,
1531 Self::Reset,
1532 Self::Recover,
1533 Self::Destroy,
1534 Self::RuntimeState,
1535 Self::ModelRoutingStatus,
1536 Self::SetModelRoutingBaseline,
1537 Self::RequestFiniteSwitchTurn,
1538 Self::RequestUntilChangedSwitchTurn,
1539 Self::AdmitModelRoutingAssistantTurn,
1540 Self::BeginImageOperation,
1541 Self::DenyImageOperationPlan,
1542 Self::ActivateImageOperationOverride,
1543 Self::ClassifyImageOperationTerminal,
1544 Self::CompleteImageOperation,
1545 Self::RestoreImageOperationOverride,
1546 Self::LoadBoundaryReceipt,
1547 Self::AcceptWithCompletion,
1548 Self::AcceptWithoutWake,
1549 ];
1550
1551 #[must_use]
1552 pub const fn input_variant(self) -> MeerkatMachineInputVariant {
1553 match self {
1554 Self::RegisterSession => MeerkatMachineInputVariant::RegisterSession,
1555 Self::UnregisterSession => MeerkatMachineInputVariant::UnregisterSession,
1556 Self::EnsureSessionWithExecutor => {
1557 MeerkatMachineInputVariant::EnsureSessionWithExecutor
1558 }
1559 Self::SetSilentIntents => MeerkatMachineInputVariant::SetSilentIntents,
1560 Self::CancelAfterBoundary => MeerkatMachineInputVariant::CancelAfterBoundary,
1561 Self::StopRuntimeExecutor => MeerkatMachineInputVariant::StopRuntimeExecutor,
1562 Self::ServiceTurnCommitted => MeerkatMachineInputVariant::ServiceTurnCommitted,
1563 Self::ContainsSession => MeerkatMachineInputVariant::ContainsSession,
1564 Self::SessionHasExecutor => MeerkatMachineInputVariant::SessionHasExecutor,
1565 Self::SessionHasComms => MeerkatMachineInputVariant::SessionHasComms,
1566 Self::OpsLifecycleRegistry => MeerkatMachineInputVariant::OpsLifecycleRegistry,
1567 Self::PrepareBindings => MeerkatMachineInputVariant::PrepareBindings,
1568 Self::InputState => MeerkatMachineInputVariant::InputState,
1569 Self::ListActiveInputs => MeerkatMachineInputVariant::ListActiveInputs,
1570 Self::ReconfigureSessionLlmIdentity => {
1571 MeerkatMachineInputVariant::ReconfigureSessionLlmIdentity
1572 }
1573 Self::StagePersistentFilter => MeerkatMachineInputVariant::StagePersistentFilter,
1574 Self::RequestDeferredTools => MeerkatMachineInputVariant::RequestDeferredTools,
1575 Self::PublishCommittedVisibleSet => {
1576 MeerkatMachineInputVariant::PublishCommittedVisibleSet
1577 }
1578 Self::SetPeerIngressContext => MeerkatMachineInputVariant::SetPeerIngressContext,
1579 Self::NotifyDrainExited => MeerkatMachineInputVariant::NotifyDrainExited,
1580 Self::AbortAll => MeerkatMachineInputVariant::AbortAll,
1581 Self::Abort => MeerkatMachineInputVariant::Abort,
1582 Self::Wait => MeerkatMachineInputVariant::Wait,
1583 Self::Ingest => MeerkatMachineInputVariant::Ingest,
1584 Self::PublishEvent => MeerkatMachineInputVariant::PublishEvent,
1585 Self::Retire => MeerkatMachineInputVariant::Retire,
1586 Self::Recycle => MeerkatMachineInputVariant::Recycle,
1587 Self::Reset => MeerkatMachineInputVariant::Reset,
1588 Self::Recover => MeerkatMachineInputVariant::Recover,
1589 Self::Destroy => MeerkatMachineInputVariant::Destroy,
1590 Self::RuntimeState => MeerkatMachineInputVariant::RuntimeState,
1591 Self::ModelRoutingStatus => MeerkatMachineInputVariant::ModelRoutingStatus,
1592 Self::SetModelRoutingBaseline => MeerkatMachineInputVariant::SetModelRoutingBaseline,
1593 Self::RequestFiniteSwitchTurn => MeerkatMachineInputVariant::RequestFiniteSwitchTurn,
1594 Self::RequestUntilChangedSwitchTurn => {
1595 MeerkatMachineInputVariant::RequestUntilChangedSwitchTurn
1596 }
1597 Self::AdmitModelRoutingAssistantTurn => {
1598 MeerkatMachineInputVariant::AdmitModelRoutingAssistantTurn
1599 }
1600 Self::BeginImageOperation => MeerkatMachineInputVariant::BeginImageOperation,
1601 Self::DenyImageOperationPlan => MeerkatMachineInputVariant::DenyImageOperationPlan,
1602 Self::ActivateImageOperationOverride => {
1603 MeerkatMachineInputVariant::ActivateImageOperationOverride
1604 }
1605 Self::ClassifyImageOperationTerminal => {
1606 MeerkatMachineInputVariant::ClassifyImageOperationTerminal
1607 }
1608 Self::CompleteImageOperation => MeerkatMachineInputVariant::CompleteImageOperation,
1609 Self::RestoreImageOperationOverride => {
1610 MeerkatMachineInputVariant::RestoreImageOperationOverride
1611 }
1612 Self::LoadBoundaryReceipt => MeerkatMachineInputVariant::LoadBoundaryReceipt,
1613 Self::AcceptWithCompletion => MeerkatMachineInputVariant::AcceptWithCompletion,
1614 Self::AcceptWithoutWake => MeerkatMachineInputVariant::AcceptWithoutWake,
1615 }
1616 }
1617
1618 #[must_use]
1619 pub const fn as_str(self) -> &'static str {
1620 match self {
1621 Self::RegisterSession => "RegisterSession",
1622 Self::UnregisterSession => "UnregisterSession",
1623 Self::EnsureSessionWithExecutor => "EnsureSessionWithExecutor",
1624 Self::SetSilentIntents => "SetSilentIntents",
1625 Self::CancelAfterBoundary => "CancelAfterBoundary",
1626 Self::StopRuntimeExecutor => "StopRuntimeExecutor",
1627 Self::ServiceTurnCommitted => "ServiceTurnCommitted",
1628 Self::ContainsSession => "ContainsSession",
1629 Self::SessionHasExecutor => "SessionHasExecutor",
1630 Self::SessionHasComms => "SessionHasComms",
1631 Self::OpsLifecycleRegistry => "OpsLifecycleRegistry",
1632 Self::PrepareBindings => "PrepareBindings",
1633 Self::InputState => "InputState",
1634 Self::ListActiveInputs => "ListActiveInputs",
1635 Self::ReconfigureSessionLlmIdentity => "ReconfigureSessionLlmIdentity",
1636 Self::StagePersistentFilter => "StagePersistentFilter",
1637 Self::RequestDeferredTools => "RequestDeferredTools",
1638 Self::PublishCommittedVisibleSet => "PublishCommittedVisibleSet",
1639 Self::SetPeerIngressContext => "SetPeerIngressContext",
1640 Self::NotifyDrainExited => "NotifyDrainExited",
1641 Self::AbortAll => "AbortAll",
1642 Self::Abort => "Abort",
1643 Self::Wait => "Wait",
1644 Self::Ingest => "Ingest",
1645 Self::PublishEvent => "PublishEvent",
1646 Self::Retire => "Retire",
1647 Self::Recycle => "Recycle",
1648 Self::Reset => "Reset",
1649 Self::Recover => "Recover",
1650 Self::Destroy => "Destroy",
1651 Self::RuntimeState => "RuntimeState",
1652 Self::ModelRoutingStatus => "ModelRoutingStatus",
1653 Self::SetModelRoutingBaseline => "SetModelRoutingBaseline",
1654 Self::RequestFiniteSwitchTurn => "RequestFiniteSwitchTurn",
1655 Self::RequestUntilChangedSwitchTurn => "RequestUntilChangedSwitchTurn",
1656 Self::AdmitModelRoutingAssistantTurn => "AdmitModelRoutingAssistantTurn",
1657 Self::BeginImageOperation => "BeginImageOperation",
1658 Self::DenyImageOperationPlan => "DenyImageOperationPlan",
1659 Self::ActivateImageOperationOverride => "ActivateImageOperationOverride",
1660 Self::ClassifyImageOperationTerminal => "ClassifyImageOperationTerminal",
1661 Self::CompleteImageOperation => "CompleteImageOperation",
1662 Self::RestoreImageOperationOverride => "RestoreImageOperationOverride",
1663 Self::LoadBoundaryReceipt => "LoadBoundaryReceipt",
1664 Self::AcceptWithCompletion => "AcceptWithCompletion",
1665 Self::AcceptWithoutWake => "AcceptWithoutWake",
1666 }
1667 }
1668}
1669
1670impl MeerkatMachineCommandVariant {
1671 #[must_use]
1672 pub const fn catalog_input(self) -> Option<MeerkatMachineCatalogInput> {
1673 match self {
1674 Self::ConfigureModelRoutingBaseline
1675 | Self::RequestSwitchTurn
1676 | Self::ResolvedSessionLlmCapabilities
1677 | Self::SessionModelRoutingStatus
1678 | Self::PrepareLocalSessionBindings => None,
1679 Self::RegisterSession => Some(MeerkatMachineCatalogInput::RegisterSession),
1680 Self::UnregisterSession => Some(MeerkatMachineCatalogInput::UnregisterSession),
1681 Self::EnsureSessionWithExecutor => {
1682 Some(MeerkatMachineCatalogInput::EnsureSessionWithExecutor)
1683 }
1684 Self::SetSilentIntents => Some(MeerkatMachineCatalogInput::SetSilentIntents),
1685 Self::CancelAfterBoundary => Some(MeerkatMachineCatalogInput::CancelAfterBoundary),
1686 Self::StopRuntimeExecutor => Some(MeerkatMachineCatalogInput::StopRuntimeExecutor),
1687 Self::CommitServiceTurnTerminalReceipt => {
1688 Some(MeerkatMachineCatalogInput::ServiceTurnCommitted)
1689 }
1690 Self::ContainsSession => Some(MeerkatMachineCatalogInput::ContainsSession),
1691 Self::SessionHasExecutor => Some(MeerkatMachineCatalogInput::SessionHasExecutor),
1692 Self::SessionHasComms => Some(MeerkatMachineCatalogInput::SessionHasComms),
1693 Self::OpsLifecycleRegistry => Some(MeerkatMachineCatalogInput::OpsLifecycleRegistry),
1694 Self::PrepareBindings => Some(MeerkatMachineCatalogInput::PrepareBindings),
1695 Self::InputState => Some(MeerkatMachineCatalogInput::InputState),
1696 Self::InputStateByIdempotencyKey => Some(MeerkatMachineCatalogInput::InputState),
1699 Self::InteractionTerminalStatus => Some(MeerkatMachineCatalogInput::InputState),
1703 Self::RunTerminalStatus => Some(MeerkatMachineCatalogInput::InputState),
1704 Self::ListActiveInputs => Some(MeerkatMachineCatalogInput::ListActiveInputs),
1705 Self::ReconfigureSessionLlmIdentity => {
1706 Some(MeerkatMachineCatalogInput::ReconfigureSessionLlmIdentity)
1707 }
1708 Self::StagePersistentFilter => Some(MeerkatMachineCatalogInput::StagePersistentFilter),
1709 Self::RequestDeferredTools => Some(MeerkatMachineCatalogInput::RequestDeferredTools),
1710 Self::PublishCommittedVisibleSet => {
1711 Some(MeerkatMachineCatalogInput::PublishCommittedVisibleSet)
1712 }
1713 Self::SetPeerIngressContext => Some(MeerkatMachineCatalogInput::SetPeerIngressContext),
1714 Self::NotifyDrainExited => Some(MeerkatMachineCatalogInput::NotifyDrainExited),
1715 Self::AbortAll => Some(MeerkatMachineCatalogInput::AbortAll),
1716 Self::Abort => Some(MeerkatMachineCatalogInput::Abort),
1717 Self::Wait => Some(MeerkatMachineCatalogInput::Wait),
1718 Self::Ingest => Some(MeerkatMachineCatalogInput::Ingest),
1719 Self::PublishEvent => Some(MeerkatMachineCatalogInput::PublishEvent),
1720 Self::Retire => Some(MeerkatMachineCatalogInput::Retire),
1721 Self::Recycle => Some(MeerkatMachineCatalogInput::Recycle),
1722 Self::Reset => Some(MeerkatMachineCatalogInput::Reset),
1723 Self::Recover => Some(MeerkatMachineCatalogInput::Recover),
1724 Self::Destroy => Some(MeerkatMachineCatalogInput::Destroy),
1725 Self::RuntimeState => Some(MeerkatMachineCatalogInput::RuntimeState),
1726 Self::AdmitModelRoutingAssistantTurn => {
1727 Some(MeerkatMachineCatalogInput::AdmitModelRoutingAssistantTurn)
1728 }
1729 Self::BeginImageOperation => Some(MeerkatMachineCatalogInput::BeginImageOperation),
1730 Self::DenyImageOperationPlan => {
1731 Some(MeerkatMachineCatalogInput::DenyImageOperationPlan)
1732 }
1733 Self::ActivateImageOperationOverride => {
1734 Some(MeerkatMachineCatalogInput::ActivateImageOperationOverride)
1735 }
1736 Self::ClassifyImageOperationTerminal => {
1737 Some(MeerkatMachineCatalogInput::ClassifyImageOperationTerminal)
1738 }
1739 Self::CompleteImageOperation => {
1740 Some(MeerkatMachineCatalogInput::CompleteImageOperation)
1741 }
1742 Self::RestoreImageOperationOverride => {
1743 Some(MeerkatMachineCatalogInput::RestoreImageOperationOverride)
1744 }
1745 Self::LoadBoundaryReceipt => Some(MeerkatMachineCatalogInput::LoadBoundaryReceipt),
1746 Self::AcceptWithCompletion => Some(MeerkatMachineCatalogInput::AcceptWithCompletion),
1747 Self::AcceptWithoutWake => Some(MeerkatMachineCatalogInput::AcceptWithoutWake),
1748 }
1749 }
1750}
1751
1752#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1753pub enum MeerkatMachineShellMechanicReason {
1754 ModelRoutingShellConfiguration,
1755 TurnControlOverlayRequest,
1756 RealtimeTransportObservation,
1757 SessionModelRoutingObservation,
1758 LocalSessionBindingBootstrap,
1759}
1760
1761#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1762pub struct MeerkatMachineCommandClassificationRecord {
1763 pub command: MeerkatMachineCommandVariant,
1764 pub classification: MeerkatMachineCommandClassification,
1765}
1766
1767#[doc(hidden)]
1768#[must_use]
1769pub fn canonical_meerkat_machine_command_classifications()
1770-> Vec<MeerkatMachineCommandClassificationRecord> {
1771 MeerkatMachineCommand::command_variant_manifest()
1772 .iter()
1773 .copied()
1774 .map(|variant| MeerkatMachineCommandClassificationRecord {
1775 command: variant,
1776 classification: meerkat_machine_command_classification(variant),
1777 })
1778 .collect()
1779}
1780
1781const fn meerkat_machine_command_classification(
1782 variant: MeerkatMachineCommandVariant,
1783) -> MeerkatMachineCommandClassification {
1784 match variant {
1785 MeerkatMachineCommandVariant::ConfigureModelRoutingBaseline => {
1786 MeerkatMachineCommandClassification::CatalogInput(
1787 MeerkatMachineCatalogInput::SetModelRoutingBaseline,
1788 )
1789 }
1790 MeerkatMachineCommandVariant::RequestSwitchTurn => {
1791 MeerkatMachineCommandClassification::CatalogInputs(&[
1792 MeerkatMachineCatalogInput::RequestFiniteSwitchTurn,
1793 MeerkatMachineCatalogInput::RequestUntilChangedSwitchTurn,
1794 ])
1795 }
1796 MeerkatMachineCommandVariant::ResolvedSessionLlmCapabilities => {
1797 MeerkatMachineCommandClassification::ShellMechanic(
1798 MeerkatMachineShellMechanicReason::SessionModelRoutingObservation,
1799 )
1800 }
1801 MeerkatMachineCommandVariant::SessionModelRoutingStatus => {
1802 MeerkatMachineCommandClassification::CatalogInput(
1803 MeerkatMachineCatalogInput::ModelRoutingStatus,
1804 )
1805 }
1806 MeerkatMachineCommandVariant::PrepareLocalSessionBindings => {
1807 MeerkatMachineCommandClassification::ShellMechanic(
1808 MeerkatMachineShellMechanicReason::LocalSessionBindingBootstrap,
1809 )
1810 }
1811 MeerkatMachineCommandVariant::RegisterSession => {
1812 MeerkatMachineCommandClassification::CatalogInput(
1813 MeerkatMachineCatalogInput::RegisterSession,
1814 )
1815 }
1816 MeerkatMachineCommandVariant::UnregisterSession => {
1817 MeerkatMachineCommandClassification::CatalogInput(
1818 MeerkatMachineCatalogInput::UnregisterSession,
1819 )
1820 }
1821 MeerkatMachineCommandVariant::EnsureSessionWithExecutor => {
1822 MeerkatMachineCommandClassification::CatalogInput(
1823 MeerkatMachineCatalogInput::EnsureSessionWithExecutor,
1824 )
1825 }
1826 MeerkatMachineCommandVariant::SetSilentIntents => {
1827 MeerkatMachineCommandClassification::CatalogInput(
1828 MeerkatMachineCatalogInput::SetSilentIntents,
1829 )
1830 }
1831 MeerkatMachineCommandVariant::CancelAfterBoundary => {
1832 MeerkatMachineCommandClassification::CatalogInput(
1833 MeerkatMachineCatalogInput::CancelAfterBoundary,
1834 )
1835 }
1836 MeerkatMachineCommandVariant::StopRuntimeExecutor => {
1837 MeerkatMachineCommandClassification::CatalogInput(
1838 MeerkatMachineCatalogInput::StopRuntimeExecutor,
1839 )
1840 }
1841 MeerkatMachineCommandVariant::CommitServiceTurnTerminalReceipt => {
1842 MeerkatMachineCommandClassification::CatalogInput(
1843 MeerkatMachineCatalogInput::ServiceTurnCommitted,
1844 )
1845 }
1846 MeerkatMachineCommandVariant::ContainsSession => {
1847 MeerkatMachineCommandClassification::CatalogInput(
1848 MeerkatMachineCatalogInput::ContainsSession,
1849 )
1850 }
1851 MeerkatMachineCommandVariant::SessionHasExecutor => {
1852 MeerkatMachineCommandClassification::CatalogInput(
1853 MeerkatMachineCatalogInput::SessionHasExecutor,
1854 )
1855 }
1856 MeerkatMachineCommandVariant::SessionHasComms => {
1857 MeerkatMachineCommandClassification::CatalogInput(
1858 MeerkatMachineCatalogInput::SessionHasComms,
1859 )
1860 }
1861 MeerkatMachineCommandVariant::OpsLifecycleRegistry => {
1862 MeerkatMachineCommandClassification::CatalogInput(
1863 MeerkatMachineCatalogInput::OpsLifecycleRegistry,
1864 )
1865 }
1866 MeerkatMachineCommandVariant::PrepareBindings => {
1867 MeerkatMachineCommandClassification::CatalogInput(
1868 MeerkatMachineCatalogInput::PrepareBindings,
1869 )
1870 }
1871 MeerkatMachineCommandVariant::InputState => {
1872 MeerkatMachineCommandClassification::CatalogInput(
1873 MeerkatMachineCatalogInput::InputState,
1874 )
1875 }
1876 MeerkatMachineCommandVariant::InputStateByIdempotencyKey => {
1880 MeerkatMachineCommandClassification::CatalogInput(
1881 MeerkatMachineCatalogInput::InputState,
1882 )
1883 }
1884 MeerkatMachineCommandVariant::InteractionTerminalStatus
1888 | MeerkatMachineCommandVariant::RunTerminalStatus => {
1889 MeerkatMachineCommandClassification::CatalogInput(
1890 MeerkatMachineCatalogInput::InputState,
1891 )
1892 }
1893 MeerkatMachineCommandVariant::ListActiveInputs => {
1894 MeerkatMachineCommandClassification::CatalogInput(
1895 MeerkatMachineCatalogInput::ListActiveInputs,
1896 )
1897 }
1898 MeerkatMachineCommandVariant::ReconfigureSessionLlmIdentity => {
1899 MeerkatMachineCommandClassification::CatalogInput(
1900 MeerkatMachineCatalogInput::ReconfigureSessionLlmIdentity,
1901 )
1902 }
1903 MeerkatMachineCommandVariant::StagePersistentFilter => {
1904 MeerkatMachineCommandClassification::CatalogInput(
1905 MeerkatMachineCatalogInput::StagePersistentFilter,
1906 )
1907 }
1908 MeerkatMachineCommandVariant::RequestDeferredTools => {
1909 MeerkatMachineCommandClassification::CatalogInput(
1910 MeerkatMachineCatalogInput::RequestDeferredTools,
1911 )
1912 }
1913 MeerkatMachineCommandVariant::PublishCommittedVisibleSet => {
1914 MeerkatMachineCommandClassification::CatalogInput(
1915 MeerkatMachineCatalogInput::PublishCommittedVisibleSet,
1916 )
1917 }
1918 MeerkatMachineCommandVariant::SetPeerIngressContext => {
1919 MeerkatMachineCommandClassification::CatalogInput(
1920 MeerkatMachineCatalogInput::SetPeerIngressContext,
1921 )
1922 }
1923 MeerkatMachineCommandVariant::NotifyDrainExited => {
1924 MeerkatMachineCommandClassification::CatalogInput(
1925 MeerkatMachineCatalogInput::NotifyDrainExited,
1926 )
1927 }
1928 MeerkatMachineCommandVariant::AbortAll => {
1929 MeerkatMachineCommandClassification::CatalogInput(MeerkatMachineCatalogInput::AbortAll)
1930 }
1931 MeerkatMachineCommandVariant::Abort => {
1932 MeerkatMachineCommandClassification::CatalogInput(MeerkatMachineCatalogInput::Abort)
1933 }
1934 MeerkatMachineCommandVariant::Wait => {
1935 MeerkatMachineCommandClassification::CatalogInput(MeerkatMachineCatalogInput::Wait)
1936 }
1937 MeerkatMachineCommandVariant::Ingest => {
1938 MeerkatMachineCommandClassification::CatalogInput(MeerkatMachineCatalogInput::Ingest)
1939 }
1940 MeerkatMachineCommandVariant::PublishEvent => {
1941 MeerkatMachineCommandClassification::CatalogInput(
1942 MeerkatMachineCatalogInput::PublishEvent,
1943 )
1944 }
1945 MeerkatMachineCommandVariant::Retire => {
1946 MeerkatMachineCommandClassification::CatalogInput(MeerkatMachineCatalogInput::Retire)
1947 }
1948 MeerkatMachineCommandVariant::Recycle => {
1949 MeerkatMachineCommandClassification::CatalogInput(MeerkatMachineCatalogInput::Recycle)
1950 }
1951 MeerkatMachineCommandVariant::Reset => {
1952 MeerkatMachineCommandClassification::CatalogInput(MeerkatMachineCatalogInput::Reset)
1953 }
1954 MeerkatMachineCommandVariant::Recover => {
1955 MeerkatMachineCommandClassification::CatalogInput(MeerkatMachineCatalogInput::Recover)
1956 }
1957 MeerkatMachineCommandVariant::Destroy => {
1958 MeerkatMachineCommandClassification::CatalogInput(MeerkatMachineCatalogInput::Destroy)
1959 }
1960 MeerkatMachineCommandVariant::RuntimeState => {
1961 MeerkatMachineCommandClassification::CatalogInput(
1962 MeerkatMachineCatalogInput::RuntimeState,
1963 )
1964 }
1965 MeerkatMachineCommandVariant::AdmitModelRoutingAssistantTurn => {
1966 MeerkatMachineCommandClassification::CatalogInput(
1967 MeerkatMachineCatalogInput::AdmitModelRoutingAssistantTurn,
1968 )
1969 }
1970 MeerkatMachineCommandVariant::BeginImageOperation => {
1971 MeerkatMachineCommandClassification::CatalogInput(
1972 MeerkatMachineCatalogInput::BeginImageOperation,
1973 )
1974 }
1975 MeerkatMachineCommandVariant::DenyImageOperationPlan => {
1976 MeerkatMachineCommandClassification::CatalogInput(
1977 MeerkatMachineCatalogInput::DenyImageOperationPlan,
1978 )
1979 }
1980 MeerkatMachineCommandVariant::ActivateImageOperationOverride => {
1981 MeerkatMachineCommandClassification::CatalogInput(
1982 MeerkatMachineCatalogInput::ActivateImageOperationOverride,
1983 )
1984 }
1985 MeerkatMachineCommandVariant::ClassifyImageOperationTerminal => {
1986 MeerkatMachineCommandClassification::CatalogInput(
1987 MeerkatMachineCatalogInput::ClassifyImageOperationTerminal,
1988 )
1989 }
1990 MeerkatMachineCommandVariant::CompleteImageOperation => {
1991 MeerkatMachineCommandClassification::CatalogInput(
1992 MeerkatMachineCatalogInput::CompleteImageOperation,
1993 )
1994 }
1995 MeerkatMachineCommandVariant::RestoreImageOperationOverride => {
1996 MeerkatMachineCommandClassification::CatalogInput(
1997 MeerkatMachineCatalogInput::RestoreImageOperationOverride,
1998 )
1999 }
2000 MeerkatMachineCommandVariant::LoadBoundaryReceipt => {
2001 MeerkatMachineCommandClassification::CatalogInput(
2002 MeerkatMachineCatalogInput::LoadBoundaryReceipt,
2003 )
2004 }
2005 MeerkatMachineCommandVariant::AcceptWithCompletion => {
2006 MeerkatMachineCommandClassification::CatalogInput(
2007 MeerkatMachineCatalogInput::AcceptWithCompletion,
2008 )
2009 }
2010 MeerkatMachineCommandVariant::AcceptWithoutWake => {
2011 MeerkatMachineCommandClassification::CatalogInput(
2012 MeerkatMachineCatalogInput::AcceptWithoutWake,
2013 )
2014 }
2015 }
2016}
2017
2018#[derive(Debug, Clone, PartialEq, Eq)]
2022pub struct MeerkatCompletionWaiterSnapshot {
2023 pub input_id: InputId,
2024 pub waiter_count: usize,
2025}
2026
2027#[derive(Debug, Clone, PartialEq, Eq)]
2032pub struct MeerkatCompletionWaitersSnapshot {
2033 pub input_count: usize,
2034 pub waiter_count: usize,
2035 pub waiting_inputs: Vec<MeerkatCompletionWaiterSnapshot>,
2036}
2037
2038#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2040pub enum MeerkatDriverKind {
2041 Ephemeral,
2042 Persistent,
2043}
2044
2045#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2047pub struct MeerkatCursorSnapshot {
2048 pub agent_applied_cursor: u64,
2049 pub runtime_observed_seq: u64,
2050 pub runtime_last_injected_seq: u64,
2051}
2052
2053#[derive(Debug, Clone)]
2055pub struct MeerkatBindingSnapshot {
2056 pub session_id: SessionId,
2057 pub runtime_id: LogicalRuntimeId,
2058 pub driver_kind: MeerkatDriverKind,
2059 pub driver_present: bool,
2060 pub completions_present: bool,
2061 pub ops_registry_present: bool,
2062 pub epoch_id: RuntimeEpochId,
2063 pub cursor_state: MeerkatCursorSnapshot,
2064}
2065
2066#[derive(Debug, Clone)]
2068pub struct MeerkatControlSnapshot {
2069 pub phase: RuntimeState,
2070 pub current_run_id: Option<RunId>,
2071 pub pre_run_phase: Option<RuntimeState>,
2072}
2073
2074#[derive(Debug, Clone, PartialEq, Eq)]
2076pub struct MeerkatAdmittedInputSnapshot {
2077 pub input_id: InputId,
2078 pub content_shape: Option<ContentShape>,
2079 pub request_id: Option<RequestId>,
2080 pub reservation_key: Option<ReservationKey>,
2081 pub handling_mode: Option<HandlingMode>,
2082 pub live_interrupt_required: bool,
2086 pub lifecycle: Option<InputLifecycleState>,
2087 pub terminal_outcome: Option<InputTerminalOutcome>,
2088 pub last_run_id: Option<RunId>,
2089 pub last_boundary_sequence: Option<u64>,
2090 pub is_prompt: bool,
2091}
2092
2093#[derive(Debug, Clone, PartialEq, Eq)]
2095pub struct MeerkatInputsSnapshot {
2096 pub admission_order: Vec<MeerkatAdmittedInputSnapshot>,
2097 pub queue: Vec<InputId>,
2098 pub steer_queue: Vec<InputId>,
2099 pub current_run_id: Option<RunId>,
2100 pub current_run_contributors: Vec<InputId>,
2101 pub post_admission_signal: String,
2102 pub silent_intent_overrides: Vec<String>,
2103}
2104
2105#[derive(Debug, Clone)]
2111pub struct MeerkatArchiveSnapshot {
2112 pub control: MeerkatControlSnapshot,
2113 pub queue: Vec<InputId>,
2114 pub steer_queue: Vec<InputId>,
2115 pub completion_waiters: MeerkatCompletionWaitersSnapshot,
2116}
2117
2118#[derive(Debug, Clone)]
2124pub struct MeerkatLedgerSnapshot {
2125 pub input_count: usize,
2126 pub non_terminal_count: usize,
2127 pub accepted_count: usize,
2128 pub queued_count: usize,
2129 pub staged_count: usize,
2130 pub applied_count: usize,
2131 pub applied_pending_consumption_count: usize,
2132 pub consumed_count: usize,
2133 pub superseded_count: usize,
2134 pub coalesced_count: usize,
2135 pub abandoned_count: usize,
2136}
2137
2138#[derive(Debug, Clone)]
2140pub struct MeerkatOpsSnapshot {
2141 pub operation_count: usize,
2142 pub active_count: usize,
2143 pub wait_request_id: Option<WaitRequestId>,
2144 pub pending_wait_present: bool,
2145 pub pending_wait_request_id: Option<WaitRequestId>,
2146 pub wait_operation_ids: Vec<OperationId>,
2147 pub operations: Vec<OperationLifecycleSnapshot>,
2148}
2149
2150#[derive(Debug, Clone)]
2155pub struct MeerkatDrainSnapshot {
2156 pub slot_present: bool,
2157 pub phase: Option<CommsDrainPhase>,
2158 pub mode: Option<CommsDrainMode>,
2159 pub handle_present: bool,
2160}
2161
2162#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
2169pub struct MeerkatFormalStateProjection {
2170 pub available_fields: BTreeMap<String, String>,
2172 pub unavailable_fields: Vec<String>,
2174}
2175
2176#[derive(Debug, Clone)]
2181pub struct MeerkatMachineSpineSnapshot {
2182 pub binding: MeerkatBindingSnapshot,
2183 pub control: MeerkatControlSnapshot,
2184 pub inputs: MeerkatInputsSnapshot,
2185 pub ledger: MeerkatLedgerSnapshot,
2186 pub completion_waiters: MeerkatCompletionWaitersSnapshot,
2187 pub ops: MeerkatOpsSnapshot,
2188 pub drain: MeerkatDrainSnapshot,
2189 pub formal_state: MeerkatFormalStateProjection,
2190}
2191
2192impl MeerkatMachineSpineSnapshot {
2193 pub fn validate_spine_invariants(&self) -> Result<(), Vec<String>> {
2199 let mut violations = Vec::new();
2200
2201 if self.control.phase == RuntimeState::Running && self.control.current_run_id.is_none() {
2205 violations
2206 .push("RunningHasActiveRunInvariant: phase is Running but no active run_id".into());
2207 }
2208
2209 if self.control.current_run_id.is_some()
2211 && !matches!(
2212 self.control.phase,
2213 RuntimeState::Running | RuntimeState::Retired
2214 )
2215 {
2216 violations.push(format!(
2217 "ActiveRunPhaseInvariant: active run_id present but phase is {:?}",
2218 self.control.phase
2219 ));
2220 }
2221
2222 if self.control.phase == RuntimeState::Destroyed {
2224 if !self.inputs.queue.is_empty() {
2225 violations.push("DestroyedShapeInvariant: Destroyed but queue is non-empty".into());
2226 }
2227 if !self.inputs.steer_queue.is_empty() {
2228 violations
2229 .push("DestroyedShapeInvariant: Destroyed but steer_queue is non-empty".into());
2230 }
2231 if self.completion_waiters.input_count > 0 {
2232 violations.push(
2233 "DestroyedShapeInvariant: Destroyed but completion waiters remain".into(),
2234 );
2235 }
2236 }
2237
2238 let queue_set: std::collections::HashSet<_> = self.inputs.queue.iter().collect();
2242 let steer_set: std::collections::HashSet<_> = self.inputs.steer_queue.iter().collect();
2243 if !queue_set.is_disjoint(&steer_set) {
2244 violations
2245 .push("QueueSteerDisjointInvariant: queue and steer_queue share entries".into());
2246 }
2247
2248 for qid in &self.inputs.queue {
2250 if let Some(snap) = self
2251 .inputs
2252 .admission_order
2253 .iter()
2254 .find(|a| &a.input_id == qid)
2255 {
2256 if snap.handling_mode != Some(HandlingMode::Queue) {
2257 violations.push(format!(
2258 "QueueHandlingInvariant: queue entry {qid} has handling_mode {:?}",
2259 snap.handling_mode
2260 ));
2261 }
2262 if snap.lifecycle != Some(InputLifecycleState::Queued) {
2263 violations.push(format!(
2264 "QueueHandlingInvariant: queue entry {qid} has lifecycle {:?}",
2265 snap.lifecycle
2266 ));
2267 }
2268 }
2269 }
2270
2271 for sid in &self.inputs.steer_queue {
2273 if let Some(snap) = self
2274 .inputs
2275 .admission_order
2276 .iter()
2277 .find(|a| &a.input_id == sid)
2278 {
2279 if snap.handling_mode != Some(HandlingMode::Steer) {
2280 violations.push(format!(
2281 "SteerHandlingInvariant: steer_queue entry {sid} has handling_mode {:?}",
2282 snap.handling_mode
2283 ));
2284 }
2285 if snap.lifecycle != Some(InputLifecycleState::Queued) {
2286 violations.push(format!(
2287 "SteerHandlingInvariant: steer_queue entry {sid} has lifecycle {:?}",
2288 snap.lifecycle
2289 ));
2290 }
2291 }
2292 }
2293
2294 for cid in &self.inputs.current_run_contributors {
2297 if let Some(snap) = self
2298 .inputs
2299 .admission_order
2300 .iter()
2301 .find(|a| &a.input_id == cid)
2302 && !matches!(
2303 snap.lifecycle,
2304 Some(
2305 InputLifecycleState::Staged
2306 | InputLifecycleState::Applied
2307 | InputLifecycleState::AppliedPendingConsumption
2308 )
2309 )
2310 {
2311 violations.push(format!(
2312 "ContributorLifecycleInvariant: contributor {cid} has lifecycle {:?}",
2313 snap.lifecycle
2314 ));
2315 }
2316 }
2317
2318 for snap in &self.inputs.admission_order {
2320 if snap.terminal_outcome.is_some() {
2321 if queue_set.contains(&snap.input_id) {
2322 violations.push(format!(
2323 "TerminalInputsNotQueuedInvariant: terminal input {} in queue",
2324 snap.input_id
2325 ));
2326 }
2327 if steer_set.contains(&snap.input_id) {
2328 violations.push(format!(
2329 "TerminalInputsNotQueuedInvariant: terminal input {} in steer_queue",
2330 snap.input_id
2331 ));
2332 }
2333 }
2334 }
2335
2336 if self.control.current_run_id.is_some() && self.inputs.current_run_contributors.is_empty()
2338 {
2339 violations
2340 .push("CurrentRunContributorsInvariant: active run but no contributors".into());
2341 }
2342
2343 if let Some(control_run_id) = &self.control.current_run_id {
2347 for cid in &self.inputs.current_run_contributors {
2348 if let Some(snap) = self
2349 .inputs
2350 .admission_order
2351 .iter()
2352 .find(|a| &a.input_id == cid)
2353 && snap.last_run_id.as_ref() != Some(control_run_id)
2354 {
2355 violations.push(format!(
2356 "ContributorRunIdentityInvariant: contributor {cid} has last_run_id {:?}, expected {:?}",
2357 snap.last_run_id, control_run_id
2358 ));
2359 }
2360 }
2361 }
2362
2363 let wait_active = self.ops.wait_request_id.is_some();
2367 if wait_active && self.ops.wait_operation_ids.is_empty() {
2368 violations
2369 .push("WaitAllAlignmentInvariant: wait_active but no wait_operation_ids".into());
2370 }
2371 if !wait_active && !self.ops.wait_operation_ids.is_empty() {
2372 violations.push(
2373 "WaitAllAlignmentInvariant: wait_operation_ids present but no wait_request_id"
2374 .into(),
2375 );
2376 }
2377
2378 if let Some(phase) = self.drain.phase
2382 && phase != CommsDrainPhase::Inactive
2383 && self.drain.mode.is_none()
2384 {
2385 violations.push("DrainModeInvariant: drain.phase is active but mode is None".into());
2386 }
2387
2388 if violations.is_empty() {
2389 Ok(())
2390 } else {
2391 Err(violations)
2392 }
2393 }
2394}