pub struct TearSession {
pub id: SessionId,
pub name: String,
pub windows: BTreeMap<WindowId, TearWindow>,
pub panes: BTreeMap<PaneId, TearPane>,
pub active_window: WindowId,
pub state: SessionState,
pub created_at_unix: u64,
pub description: String,
pub source: SessionSource,
pub freio: Freio,
}Expand description
One session: the top-level entity in the multiplexer hierarchy. A session owns a set of windows; each window owns a layout tree of panes. Sessions persist across client attach/detach cycles — this is what makes tear (and tmux) a multiplexer rather than a shell wrapper.
Fields§
§id: SessionId§name: StringOperator-visible session name ("work", "infra",
"deploy-staging"). Stable across renames? No — tear rename
mutates without minting a new ID.
windows: BTreeMap<WindowId, TearWindow>Windows belonging to this session, keyed by id. BTreeMap so the wire format orders deterministically.
panes: BTreeMap<PaneId, TearPane>Panes belonging to this session, keyed by id. Stored flat at
the session level so a pane can move between windows without
changing its address (tmux’s join-pane semantics).
active_window: WindowIdCurrently-focused window id. Must exist in windows.
state: SessionStateLifecycle state.
created_at_unix: u64Unix-seconds-since-epoch when this session was created.
description: StringOptional operator-set description / notes — surfaced by
tear list and by the status bar.
source: SessionSourceProvenance — who/what created this session. Lets operators
audit at a glance whether a session was opened by a human
shell, by an AI agent (via mado MCP / direct UDS), or by a
named automation. tear list --source agent filters; mado
MCP tools default to Source::Agent so an operator’s
tear list separates “what I started” from “what the agent
started behind my back”. Default = Source::Human (the
safe assumption when nothing said otherwise — pre-#6
sessions deserialise as Human).
freio: FreioThe operator’s brake. #[serde(default)] → Freio::Released,
which is what every pre-freio session record already means, so
landing this field changes no existing behaviour.
Implementations§
Source§impl TearSession
impl TearSession
Sourcepub fn admits(&self, pane: PaneId) -> Option<Admission>
pub fn admits(&self, pane: PaneId) -> Option<Admission>
What input a pane ACTUALLY accepts right now.
The only way to answer this question. Note what deliberately
does not exist: a TearPane::admits(). A pane alone cannot answer
it — the brake lives on the session — and a method that pretended
otherwise is exactly how a pane comes to report Free while
refusing input. The absent method is the seal.
This also JOINS two gates that already exist rather than adding a
third: the Locked check inside tear-core::send_keys and the
Leader check in the daemon’s serve loop. Two authorities over one
question was already one too many; freio must not make it three.
§The ordering is the design
The brake is consulted BEFORE the policy lattice. That is what
makes it non-advisory: a pane explicitly pinned to Free still
cannot escape a brake, because the brake is answered before the pin
is ever read.
Sourcepub fn unbrakable(&self) -> Vec<PaneId>
pub fn unbrakable(&self) -> Vec<PaneId>
Panes this session’s brake would NOT stop, because their provenance is unknown.
Exists so the miss above is reportable. An operator pressing a panic button must be told what it did not reach — silence here would let them believe everything stopped.
Trait Implementations§
Source§impl Clone for TearSession
impl Clone for TearSession
Source§fn clone(&self) -> TearSession
fn clone(&self) -> TearSession
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more