Contents

Sessions

Inspect session liveness, work ownership and steering communication.

Sessions

Web dashboard Sessions lists harness sessions against this universe: who is running, what item they hold, and whether each is Working, Waiting or Ended.

Held item IDs show Frozen and Blocked pills from the item's own state. If both apply, Frozen appears first and colors the active workflow segment ice blue; Blocked remains visible beside it. Blocked alone colors that segment red. Completed and upcoming segments retain their normal colors. A parked or idle session does not, by itself, mark its item Frozen or Blocked.

The server computes one status for the Sessions page, Frontier, Machines and yoke sessions list: Working, Waiting or Ended. Working means a live tool call, or an unfinished turn with a recent sign of life. A finished turn is Waiting. End stamps make a session Ended. A native process exit does not change status: a session can resume after that process exits.

The recent window is the project's session_idle_minutes (20 minutes by default). active uses the latest tool call, heartbeat, prompt/stop marker or recorded turn end. The status comes from the server, never a browser clock.

The roster has independent status toggle chips: Working and Waiting start on; Ended starts off. Selecting Ended loads cursor-paged history. Any combination, including none, is allowed. Filter the CLI before pagination with yoke sessions list --status working|waiting|ended. yoke sessions get SESSION-ID --full keeps the diagnostic fields.

Cards show one status and active age. The header's (i) reveals the session's reason, presence, activity, intent and its reason, next actor and the tool, prompt/stop, turn-end and heartbeat times. Holdings and steering keep their own sections. A stored native chat title adds a line when it differs from the launch item's ref and title and the session has no steering claim; the harness name stays in the header. Machines count working, waiting and held sessions. An older server without status, active time or reason asks you to refresh after the server upgrade instead of guessing a status.

Frontier chips show the same three statuses and open the holding session's card. They do not repeat its intent or the item's next-action sentence. Reclaim sessions still uses the server's reclaimable flag and rechecks protection before acting; a claim remains protected regardless of status.

The steering fleet report, fleet-delta alarms, message liveness, reclaim, liveness, last-tool ages in session labels, and raw reason codes in CLI Frontier and item reads retain their separate presence/activity/intent rules.

Yoke resumes a session headlessly only when Yoke launched it and the surface allows native wakes. Each session stores launch_origin: yoke after launch binding, otherwise operator. Hand-started sessions on every harness and surface keep messages pending for their next hook, even after their process exits. Yoke sends the existing operator-wake notice; QA, deploy and Inbox answers never override that rule.

Every session card offers Message, including ended sessions. For sessions whose wake belongs to the operator, the next hook delivers messages after you open the chat and start a turn. A missing relay leaves messaging available; hook delivery can proceed and automatic wake waits for the relay to reconnect. Cards and Message tooltips do not claim that a message is queued.

The relay never resumes a CLI session while a live interactive process holds it, including after an Inbox answer or an explicit wake request. A matching process anchor with the same PID start time keeps the message pending for that process's next hook. Wake attempts report native_turn_running with running_native_source=process_anchor; bounded deferral refunds and escalation still apply. Claude CLI and Cursor CLI write anchors; Codex CLI does too. Codex desktop and editor surfaces do not write these CLI anchors.

Native wake routes that refuse delivery spend a bounded retry budget. Exhaustion sends the named failure and recovery to the covering steering seat. The original sender is not notified; the message state is their record. Read yoke messages get MESSAGE-ID for the receipt and attempts. Operator-driven hook delivery keeps its own wait without spending that budget. A relay wake whose lease expires before any report gives its charge back. Broker attempts closed as broker_hook_lease_expired, broker_lost or broker_timeout also give it back, so an explicit wake survives a relay outage and the relay can claim it again after recovery. Relay and broker losses share one limit of three refunds per recipient. Further losses keep their charge and record their own result code as the escalation; Fleet shows that code as last attempt failed. broker_target_changed and broker_state_invalid never refund. Recover with yoke session-control session wake SESSION-ID once the relay reports again.

An explicit yoke session-control session wake SESSION-ID returns its queued receipt after about one second if no relay or broker claims it. A claimed attempt can wait up to ten seconds total for its result. A queued or unfinished receipt includes yoke messages get MESSAGE-ID to inspect later delivery. Detached turns keep their capture current while waiting on a command. If the relay contains a native, verified custody death reopens pending wakes held by that exact process and retires Fleet's old native_turn_running label.

The relay releases an unstarted job when stopping or when all settlement workers are busy. Its report records relay_stopping or relay_workers_busy; the job becomes eligible for the next poll without waiting for lease expiry. A failed release report stays in the machine's pending reports and retries before new claims. Launch closure evidence calls claim time attempt_claimed_at; native_started_at records an observed native spawn.

Sessions own work claims. Implementation lanes require an active claim and a registered worktree. A persisted active work claim keeps its session live through stale, idle, parked, process-gone, and startup sweeps. This includes release waits. Parking records delivery wake routing; claims own retention. Before parking on another item, record its dependency. Claim release, completion, cancellation, and authorized operator termination free ownership. Any session holding a live steering seat on any project may terminate a session on any project, and termination releases every claim the target holds, steering seats and their paired document locks included. Logical termination cancels messages immediately and queues one physical reap. The relay retains identity-bound process/group custody until verified exit: TERM has a 2-second grace, followed by KILL and a bounded 2-second exit check. Missing custody, signal denial, and unverified exit remain unresolved. Inspect machine custody and permissions, then explicitly repeat yoke sessions terminate SESSION-ID --reason R to retry a failed reap; prior failed evidence is retained in the existing reap record. A pending attempt is not duplicated and a verified success stays a no-op. Claude's native job stop has a separate 20-second command timeout. Registration transfers custody only after adoption succeeds; a failed adoption keeps the registered native protected in supervision. Explicit session end releases the claims it still holds. A claim conflict names its holder and requires one of those explicit actions rather than a heartbeat timeout.

An active steering scope appears on the generated board with its holder, project and held strategy documents, claim age, liveness, steering-launched worker count, and unacknowledged report count. In Web dashboard, Steering badges show the same scope, steering-launched workers group under their holder, and each of those workers shows whether its latest deliberate report was sent or acknowledged. Every worker reaches the seat deliberately with yoke say --steering; ending a turn sends no Fleet message. Workers reserve those messages for something the seat must act on — a failure, blocker, conflict, decision, question, or terminal outcome — and keep progress in their own visible output. A substantive peer request addresses its intended worker with --item (or an exact listed --session when no claim addresses the recipient) and copies the relevant seat by adding --steering; those anchors union. The recipient replies to the original requesting session and also copies steering, particularly to accept or refuse, report a scope conflict or blocker, or ask for a decision. A rejection sent only to steering leaves the requester uninformed. When the sender holds no applicable item, it supplies the explicit scope with --steering-scope '{"project_id": N}'. Session IDs are always copied whole from a listing, never guessed or reconstructed. Acknowledgement records receipt, not acceptance or implementation. A report addressed to the role has a recipient whether or not a seat is live, so sending, previewing, reading, and listing one all report that recipient's own state: awaiting_seat with the scope it is queued for, delivered naming the seat holding it, or acknowledged. A queued report is therefore never a message that went nowhere. The next seat covering the sender's item takes queued reports when it is acquired: each gets that seat's ordinary session receipt and injects through the same hook as a live send, and acquire prints each message id with its acknowledge command. The fleet report's awaiting-seat count reads the same coverage. A document seat covers every item linked to its document, so it takes and counts those items' reports even when another project owns the item. These views derive from existing claims, document locks, launch provenance, and message-recipient receipts; they do not create separate state.

A session belongs to the project whose registered folder it started in, else to its organization (shown as Outside any project), and keeps that scope. Its ID comes from the harness; never invent one. A session may claim items in any project it can access.

yoke sessions hook-overhead [--hours N] summarizes hourly PreToolUse and PostToolUse client wall time, evaluator time, and their remainder, then shows completed tool-call latency beside timed/total coverage globally and per harness. Tool latency re-reads repaired session_tool_calls owner timestamps; a start or client wall still inside the pending-delivery window is pending, not incomplete. Missing durations outside that window stay unknown rather than becoming zero. The --hours observation cutoff and the pending window are explicit on the JSON result. The distinct-session ACTIVE* count is a fixed-hour activity proxy, not the live roster or proof of simultaneous execution. Add --json for the registered result envelope.

yoke hook benchmark --samples 5 [--json] runs the harmless system true command between normal PreToolUse and PostToolUse checks. It records direct pre/command/post/envelope wall times and reads evaluator/client-wall phases from durable HookDispatchTelemetry, with exact timing coverage, harness, surface, revisions when available, time window, run count, and separately defined live-roster and running-session proxy counts. A phase still in flight is pending delivery, not incomplete coverage. Save a JSON report and compare it with --compare REPORT.json; mismatched identity, revisions, command, or sample count, pending delivery, and incomplete evaluator/client-wall coverage, are labelled incomparable.

Park until something changes

yoke sessions touch --mode parked --reason "awaiting a decision" records an intentional wait. A prompt or a turn that only reads or acknowledges messages keeps that park and reason. Successful work or an explicit --mode wait ends it. Capacity recovery skips parked sessions.

For time or traffic evidence, schedule the earliest useful recheck before parking: yoke sessions wake schedule --at 2026-12-01T12:00:00Z --reason "check traffic evidence". The instant must include a UTC offset and be in the future. The durable message cannot arrive early through another prompt; when due it follows the surface's existing message wake route. A new message or dependency change can still wake the holder. A release takeover alone does not repeat an unchanged manual QA notice.

Timed rechecks

session_scheduled_wakes stores a calling session's future evidence recheck: wake_id, session_id, actor_id, due_at, reason, created_at, and nullable message_id. Session, due instant, and reason uniquely identify a timer. The relay locks due rows and records their Fleet message in the same transaction; message delivery owns retries after that. Before the due instant there is no pending message, so an older serving process cannot deliver it early. yoke sessions wake schedule --at INSTANT --reason TEXT returns wake_id and scheduled_at; inspect the durable timer and message link with yoke db read.

Sessions · Yoke