Skip to content

[Agentic DX] libtmux: consolidated roadmap (core + async + engines) #629

Open
0 of 7 issues completed
Open

Description

@tony

Current preparation status — 2026-11-01. Seven independent PRs are open across Python and TypeScript, with every required hosted check passing at their recorded heads; the existing Python ownership PR is reused. Each new PR builds from current master with sibling branches absent. This records PR preparation and bounded qualification, not completion of the feature train. Every unresolved canonical issue remains open.

Verified bases: Python 886b1cd4862cbddcadffe3d82db0495f4e0594f8; TypeScript d2b149beddb84326d79d3fabbdb99429646f22e5. No new generic engine contracts or merge dependencies were added. Python seconds/code-point counts and TypeScript milliseconds/UTF-16 or filtered-UTF-8 units remain explicitly named by each API.

Canonical scope Action and evidence Remaining
Opt-in command deadline Prepared PR #807 · PASS at 6b928758 · evidence Async and broader roadmap stay open.
Native async cancellation Keep canonical gap · PARTIAL · evidence Extract canonical engine values and prove native cleanup independently.
Ordinary channel deadline Prepared PR #809 · PASS at 04148dd9 · evidence Keep broader channel/cancellation requirements.
Borrowed-server survival Reuse PR #728 · PARTIAL broader verification · evidence Existing PR remains open; broader local suite has baseline failures.
Connected-daemon admission Keep canonical gap · UNVERIFIED · evidence Selected-backend admission and daemon replacement remain unqualified.
Visible/cooperative waits Keep canonical gap · PARTIAL · evidence Worker cleanup and selected observer route fail stronger controls.
Immutable capture cursor Keep canonical gap · PARTIAL · evidence Reset/gap/unknown, lifetime and serialization qualification.
Trim ambiguity evidence Prepared PR #808 · PASS at a16ccaf5 · evidence Runtime diagnostic classification and qualified counter handling.
Immutable pane value Prepared PR #810 · PASS at 041e23da · evidence Graph, serialization and wider observations stay open.
Retained wait evidence Keep canonical gap · PARTIAL · evidence Bounded existing-path wait and retained typed causes/no-sample evidence.
Bounded recorder Keep canonical gap · UNVERIFIED · evidence Declared sources, redaction, eviction and export remain unverified.
Owned byte subscription Keep canonical gap · PARTIAL · evidence Wrong-daemon observation; owned native cleanup/queue qualification.
Sampled text frames Keep canonical gap · PARTIAL · evidence Nested mutation and cleanup/routing failures; independent text-only driver.
Qualified cells Keep canonical gap · PARTIAL · evidence Qualified grammar plus immutable values and hard transport bounds.
Ordered pane operations Keep canonical gap · PARTIAL · evidence Native attributed outcomes and independently bounded lifecycle.
Exact owned create/reuse Keep canonical gap · PARTIAL · evidence Concurrent disposition and replacement-safe cleanup on master.
Lease qualification Keep canonical gap · PARTIAL · evidence Cross-process arbitration and suspension remain unverified.

The remaining helpers receive concrete qualification findings rather than a production PR under the limited delivery rule. Current-master TypeScript probes retain the original three failures (mutable frames, pending disposal, stringified errors); private repairs pass all 16 declared assertions on Bun 1.4.2 and emitted Node 22.23.3 with the recorded tmux 3.8a binary. The first Node bundle had a missing-fixture packaging failure before feature assertions; that failure remains recorded, and the identical fixture was placed beside the moved bundle without changing assertions or timers.

The refreshed Python private consumer passes its 13 declared cases, while stronger controls fail native worker cleanup, selected-engine observer routing and nested frame immutability. Earlier 12-trial receipts remain tied to their original hashes; the changed current Python prototype was tested separately. No prototype PASS is treated as merged implementation. Local complete Python suites retain the same 18 failures reproduced on unchanged master; new PR-head hosted lanes pass.

No new issues, closures or merge dependencies result from this pass. No macOS jobs, runners, fixture lanes, debugging or qualification work are added; existing support and coverage remain, and unrun behavior is UNVERIFIED without becoming a gate. Python's core minimum stays 3.2a; its minimum-version issue #777 and proposal PR #779 are outside scope. NEVER write to tmux/tmux; references use pinned source code only.

Linked trackers: Python roadmap, Python project, environment profiles, TypeScript roadmap, TypeScript project. Each gap has its canonical issue or explicit research owner; no aliases become extra feature requests.

Context

The previous issues #630, #631, #632, and #633 came from local worktree experiments and should be treated as one consolidated roadmap with core libtmux API work.

This issue is the canonical tracker for Agentic/DX improvements across:

  • core API contracts
  • async support direction
  • concurrency/state semantics
  • engine/backend architecture

Goal

Strengthen API contracts and machine-readable behavior for agent-safe automation without fragmenting the project into parallel tracks.

Low-lift ideas

  • Publish explicit stable API boundary and deprecation schedule (safe public imports and behaviors).
  • Add a concise exception/error contract table for command failures.
  • Publish sync-vs-async parity notes (supported / planned / out-of-scope).
  • Define/document engine selection semantics and baseline capability fields.

Medium-lift ideas

  • Add contract tests for public behavior and tmux-version compatibility.
  • Add async cancellation/timeout/backpressure semantics and tests.
  • Clarify concurrency/state refresh guarantees for pane/window/session objects.
  • Add shared response/event parsing contracts across subprocess/control-mode backends.

High-lift ideas

  • Publish machine-readable capability metadata (tmux version matrix + backend capabilities).
  • Add versioned structured contracts for machine output/diagnostics.
  • Add inspect/plan-style, non-mutating orchestration preview interfaces.

Done when

  • Public API and compatibility expectations are explicit.
  • Async + concurrency + backend behaviors are documented and regression-tested.
  • Automation clients can rely on stable, machine-readable contracts.

Consolidation note

Supersedes and consolidates:


Delivery plan

The independent-PR contract below supersedes any earlier implication of a required merge sequence.

Deliver rmux-inspired helpers through stock tmux capabilities, with explicit observation, cancellation, ownership, and recovery contracts. Track the work in the libtmux project. This plan reuses twelve existing issues and adds six focused proposals.

Area Deliverable Issues
Foundation Optional deadlines, async cancellation, attributed replies, ownership, and capability admission #689, #732, #724, #778
Observation Current-screen predicates, cooperative completion, future bytes, capture cursors, and immutable values #673, #800, #740, #671, #370
Composition Sampled surfaces, qualified cells, ordered multi-pane results, and retained wait diagnostics #801, #802, #803, #584
Creation Create/reuse disposition and cleanup of resources created by the operation #804
Retention and lifecycle Recording with coverage boundaries; experimental session leases #420, #805
Qualification Controlled fixtures, application adapters, and best-effort user environments #456

Work can proceed independently where its required contract exists. Text surfaces do not wait for styled cells. A minimal immutable observation can unblock wait diagnostics before a full snapshot graph. The cancellation and reply-correlation slice of #689 can land before its broader workspace, lazy-operation, and MCP work.

Research basis and limits

The audit classified 558 explicit rmux SDK declarations into 22 capability families. That inventory includes constructors and conversions; it is not a target of 558 Python methods. Source evidence is pinned to rmux 1f4571e7, tmux 3.8 at 7f2a35ad, and the Python baseline at 886b1cd4.

Local prototypes exercised Python and TypeScript against tmux 3.8 and a pinned development checkout, with twelve declared trials. Those are exploratory observations, not public implementation acceptance: the fixtures and results must be included in reviewable implementation work before closing these issues. The stronger TypeScript byte-identity contract failed through its decoded string stream; that belongs in the TypeScript port. Engine cancellation implementations were inspected, but their suites were not rerun for this planning audit.

The source evidence establishes different guarantees:

Neither bounded in-memory retention nor a captured frame establishes durability across arbitrary daemon restarts. Disk recording can preserve acknowledged records under a specified storage policy; missing observations remain gaps. Quiet output, a matched prompt, and successful key submission do not establish command completion in an arbitrary shell.

The train covers library work using current tmux capabilities. Complete hidden-state export, replay of never-recorded bytes, browser authentication/sharing, and a native Windows PTY backend remain outside this delivery scope. No upstream tracker changes are part of this work.

Disposition of all 22 capability families
Audited family Owner or disposition Scope in this train
Connection, startup, capabilities #689, #778 Engine ownership, deadlines, daemon/engine admission, observer epochs
Session ensure, reuse, tags #804 Creation disposition and exact identity; tags do not prove ownership
Discovery, tags, stale identities #803, #804; existing query APIs Freeze selection where required, preserve duplicates, reject stale/wrong-server identity
Launch, respawn, layout builders #804; #689 workspace work Reuse primitive operations; compensate only owned resources; no arbitrary shell rollback
Future byte and text matching #800, #673 Arm before trigger, bytes before decoding, cross-chunk matching, explicit loss
Visible text, regex, absence, any/all #673, #803 Predicate over an identified observation; absence is not historical absence
Quiet, stable, load state #673, #456 Declare observed fields and interval; application readiness remains conditional
Pane/process exit and command completion #673, #732 Separate pane process outcome from a cooperative command signal; missed status stays unknown
Raw output, line streams, bounded collection #800, #420 Live bytes, explicit line-tail policy, bounded queues, optional retained collection
Captures, regions, screenshots, cells #370, #802 Text first; qualified cell adapter; no universal native-state export claim
Text locators, filters, assertions #673, #802; #645 as adjacent search work Read-only predicates/regions are enabled; a full locator/action DSL is a later consumer
Keyboard, mouse, fill, detach helpers Existing input API, #803 for broadcast; qualified adapters later Submission success only; no universal fill or focus/processing guarantee
PaneSet batches, any/all, cleanup #803, #804 Per-target outcomes, bounded concurrency, losing-wait cleanup, ownership separate
Surface and rendered streams #801 Sampled current view, local revision, coalescing, reset; cells optional
Raw replay, recovery keyframes, reducers #420; exact hidden-state recovery excluded Replay only retained observations; no reconstruction of missing bytes or full parser state
State journals and lifecycle revisions #420, #800 Journal observed changes and gaps; not every overwritten server state
Ownership guards, leases, preserve, signals #724, #804, #805 Explicit ownership first; experimental fenced lease last
Foreground process and command metadata Existing formats; #712 for spawn provenance; qualified adapter later Preserve observed source/unknown values; no new universal process-truth API
Bounded action/input/snapshot traces #420, #584 Opt-in bounded diagnostics; persistence depends on sink contract
Browser sharing, permissions, expiry Separate service, outside train Terminal APIs can support a service; Python helper issues should not absorb browser authentication
Native Windows endpoint and PTY Different backend, outside train WSL qualification cannot establish native Windows support
Value types, diagnostics, conversions, command DTOs #689, #370, #584 Native Python types; avoid importing wire-only aliases without a consumer

Independent PR delivery and compatibility

Each bounded deliverable gets a minimal PR against master that builds, tests, and provides useful behavior with every other feature branch absent. Parent issues organize the work; cross-links identify shared contracts and later integration points. They do not impose a PR merge order.

Use existing trunk primitives and a small private adapter where a shared implementation has not landed. Do not import unmerged modules, vendor the engine framework, add another public CommandRequest or CommandResult, or require a foundation PR before delivering a helper. A needed public symbol has one owning issue; other features consume a narrow structural contract or preserve a private representation until a public consumer needs it.

Preserve these contracts across all PRs:

  • Existing synchronous methods, blocking defaults, return values, and exception behavior remain compatible. Deadlines are opt-in; async cancellation stays on explicit async operations.
  • At the engine boundary, preserve request argv, explicit connection ownership, timeout/input semantics, raw return code and output, and one attributable result per request. Reuse the selected engine's canonical request/result classes when available. Do not infer success from the mere presence of output or silently change the engine's error policy.
  • At the operation layer, map outcomes to complete, failed, skipped, or unknown. Cancellation before submission is skipped with a reason; an uncertain submitted mutation is unknown. Keep the underlying engine result available and never retry an uncertain mutation automatically.
  • Preserve bytes before decoding; scope identity to the server and pane lifetime; distinguish unsupported or unknown capabilities; invalidate observer continuity on loss. Sampled captures cannot become exact replay or complete terminal checkpoints through an adapter.
  • Cleanup affects only positively owned resources. Borrowed engines and servers remain usable; cancellation of a client does not imply cancellation of the pane's process.
  • Snapshot values are immutable; text offsets and terminal columns remain distinct. Optional future data needs a compatible extension path. Serialized records carry a version and an explicit policy for unknown event kinds and fields.

Before implementation, record the exact reviewed engine-ops, request-timeout, async-subprocess, and hardening refs and compare their real interfaces. Resolve differences in a contract note; an old issue's illustrative type or exception name is not an authoritative interface. Tests for each PR should validate its adapter against that recorded contract without requiring another feature PR to be installed.

The independence gate is a fresh checkout of the PR's actual master base plus only that PR's changes. Verify its focused tests, types, docs, and an end-to-end consumer there. Prove the critical test fails when its protection is removed. A sidecar check against the selected engine implementation is integration evidence, not a build dependency. Test interacting features once both exist, without making every unrelated pair a prerequisite.

Trim each first PR to the useful slice below. Keep the remaining issue criteria open and explicit. Later PRs may use functionality already merged into master; they must not depend on another unmerged branch.

Issue First independently useful PR Later scope retained on the issue
#689 Extract the smallest additive command-deadline/cancellation contract that preserves the classic facade; reconcile existing candidate PRs before creating another Broader engine families, operations, workspace, lazy planning, and MCP
#732 Add an optional deadline to the existing channel wait using an owned, bounded invocation Route through a shared engine implementation when it is already available
#724 Correct server-scope ownership with a regression proving a borrowed server survives New owned-resource abstractions
#778 Specify and expose optional-feature admission for the current daemon/engine; test refusal before effect Register independently delivered feature adapters as they become available
#673 Add bounded visible-text predicates and cooperative completion over existing primitives Future-byte predicates, broader adapters, and richer composition
#740 Add an immutable capture cursor with conservative reset/gap/unknown results Additional qualified continuity aids
#671 Document and reproduce trim ambiguity, with a narrow diagnostic classification where evidence permits Integration into capture consumers once their APIs are on trunk
#370 Add an immutable pane observation with explicit sampled provenance Full hierarchical snapshots and richer frame adapters
#584 Add immutable retained wait evidence and focused failure formatting to an existing wait path Integration into later wait APIs and optional full snapshots
#420 Add a bounded recorder for a declared observation source using existing capture/producer interfaces Raw-stream integration, persistent sinks, and crash qualification
#800 Add an owned byte-preserving subscription with readiness, bounded queues, gaps, and cleanup Shared-engine integration and additional consumers
#801 Add text-only sampled full frames, an initial reset, revisions, and close/cancellation using existing capture Output-driven wakeups, patches, and styled cells
#802 Add qualified cell parsing and direct capture into feature-owned immutable cell values Surface and locator consumers
#803 Add ordered multi-pane captures and explicit input submission with per-target outcomes Any/all waits and additional bounded-concurrency policies
#804 Add exact session create/reuse disposition and cleanup of sessions the helper created, without relying on the legacy server context manager Multi-step builders and optional leases
#805 Qualify an experimental lease on a session created by this helper using existing primitives Integration with owned-create helpers after they land; stronger guarantees only with evidence

#629 and #456 coordinate the roadmap and environment qualification. They do not require umbrella implementation PRs. Each feature PR carries its own controlled-fixture tests, declared environment limits, and relevant documentation. A passing first slice does not close the issue while deferred acceptance criteria remain.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    • Status
      In Progress

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions