Developer ReferenceBehavioral Specs

Operator console state machine — Behavioral Spec

Behavioral invariant contract for the host operator console state machine — primarily crates/jackin-console/src/tui/state/manager.rs and the screen update modules. Phase 2 console/view-model work and settings/editor unification must preserve every INV below.

Scope

Covers the console's stage/modal stack, service-poll → state handoff, launch prompts, list/editor/settings surfaces, and how background services report back into ManagerState. Does not cover capsule-side attach (see Capsule daemon) or the pure op-picker planning machine (see op_picker).

Coverage shape

manager.rs now has a sibling characterization suite (state/manager/tests.rs) for stage ownership, list modals, picker dismissal, and list/preview selection. Broader stage/poll and auth dialog coverage remains in tui/model/tests.rs and input suites.

Behavioral invariants

Stage stack / navigation

INVDescriptionVerify byTests
INV-C1ManagerState is the single stage owner: ConsoleManagerStageState / ManagerStage drive which surface is activetrait impls on ManagerState in manager.rsjackin_console::tui::state::manager::tests::manager_state_is_single_stage_owner jackin_console::tui::model::tests::console_manager_stage_routes_by_variant jackin_console::tui::model::tests::apply_manager_stage_updates_storage
INV-C2Opening a launch-agent prompt updates both app state and manager stage togetherlaunch prompt plan helpersjackin_console::tui::model::tests::open_launch_agent_prompt_plan_updates_app_and_manager
INV-C3Opening a launch-role prompt updates app + manager; clearing pending launch clears launch input only where intendedlaunch role plan helpersjackin_console::tui::model::tests::open_launch_role_prompt_plan_updates_app_and_manager jackin_console::tui::model::tests::clear_pending_launch_plan_clears_launch_state jackin_console::tui::model::tests::clear_pending_launch_role_plan_clears_only_role
INV-C4Taking a pending launch plan removes it from manager state (one-shot consume)take_pending_launch_plan / pair takejackin_console::tui::model::tests::take_pending_launch_plan_takes_input jackin_console::tui::model::tests::take_pending_launch_and_role_plan_takes_pair
INV-C5Opening a launch account picker updates app + manageraccount picker planjackin_console::tui::model::tests::open_launch_account_picker_plan_updates_app_and_manager
INVDescriptionVerify byTests
INV-C6Base surface is blocked while a modal is open (console_app_base_surface_unblocked_respects_modal_blockers)modal blocker checksjackin_console::tui::model::tests::console_app_base_surface_unblocked_respects_modal_blockers
INV-C7List modals (container info, error popup, github picker) open through ListModalState on the managerListModalState impljackin_console::tui::state::manager::tests::list_modals_open_through_list_modal_state
INV-C8Inline picker dismissal is owned by InlinePickerDismissalState so partial dismissals do not leave half-open pickersInlinePickerDismissalState impljackin_console::tui::state::manager::tests::inline_picker_dismissal_clears_only_targeted_slot

Service → state handoff

INVDescriptionVerify byTests
INV-C9Pending role-load / drift-check / isolation-cleanup / op-commit results are polled into manager state rather than written from background tasks directlypoll_pending_* methods on manager-facing traitsjackin_console::tui::state::manager::tests::list_stage_poll_pending_handoffs_are_empty jackin_console::tui::model::tests::console_manager_stage_polls_pending_role_load_from_editor_only jackin_console::tui::model::tests::console_manager_stage_polls_pending_drift_check_from_editor_only jackin_console::tui::model::tests::console_manager_stage_polls_pending_isolation_cleanup_from_editor_only jackin_console::tui::model::tests::console_manager_stage_polls_pending_op_commit_with_origin
INV-C10Instance refresh is throttled (InstanceRefreshThrottleState) so list polls do not stampede Dockerthrottle state in managerjackin_console::tui::subscriptions::tests::instance_refresh_throttle_plan_starts_when_due jackin_console::tui::subscriptions::tests::instance_refresh_throttle_plan_waits_while_in_flight_or_recent
INV-C11Mount-info cache refresh targets are explicit (MountInfoRefreshTarget) so screens do not re-fetch whole trees on every framemount cache fields on ManagerStatejackin_console::tui::message::tests::mount_info_refresh_source_plan_dedups_manager_sources jackin_console::tui::message::tests::mount_info_refresh_source_plan_keeps_screen_target

Workspace list / preview

INVDescriptionVerify byTests
INV-C12Workspace tree disclosure, list selection, hover, and scroll state are trait-split on ManagerState so list screens share one selection modeltrait impl block at manager.rsjackin_console::tui::state::manager::tests::workspace_list_selection_and_disclosure_live_on_manager
INV-C13Preview focus and pane cursor state live on the manager, not in ad-hoc screen localsPreviewFocusState / PreviewPaneCursorStatejackin_console::tui::state::manager::tests::preview_focus_and_pane_cursor_live_on_manager

Settings / editor

INVDescriptionVerify byTests
INV-C14Settings and editor expose stage-debug and footer-height facts through the same manager-facing traitssettings_stage_debug / editor_stage_debugjackin_console::tui::model::tests::console_manager_stage_reports_debug_stage jackin_console::tui::model::tests::console_manager_stage_reports_footer_height_facts
INV-C15Auth config editing goes through dialog-only flows (no free-form inline mutation of live config without a save plan)auth editor update pathsjackin_console::tui::input::global_mounts::auth::tests::cancelling_profile_folder_picker_restores_account_form jackin_console::tui::input::global_mounts::auth::tests::editing_api_key_preserves_identity_and_endpoint_settings jackin_console::tui::components::auth_panel::tests::auth_form_key_plan_routes_shared_focus_model

Test seams

  • Model plan functions — pure “plan” helpers exercised in tui/model/tests.rs that update app + manager without a live terminal.
  • Screen update modules — settings/op-picker/workspace update tests for local reducers.
  • Service poll traits — inject completed poll_pending_* results in future characterization tests (no harness yet on manager.rs).

Remaining coverage (worklist, risk-ordered)

  1. Service handoff depth — INV-C9/C10 have trait-level characterization; expand with fake service completion driving full stage transitions when refactors touch poll paths.
  2. Settings/editor unification — INV-C14/C15 pin dialog/debug contracts; keep them green through view-model extraction.
  3. Modal stack depth — no test that two modal open/close cycles restore the prior stage.

Asymmetry note

Compared with the capsule daemon, the console manager still has fewer integration-depth tests. Prefer expanding the manager characterization suite before large view-model refactors.

On this page