This unpublished Elixir package is under implementation. Pure foundation tests, packed-core import checks and owned real-tmux checks are available. WRITING.md governs prose, comments, and commits.

Setup

Use mise with the ranges in .tool-versions: Erlang/OTP 29.x and Elixir 1.20.x. The Mix project requires at least Elixir 1.20.4. Linux builds also require a C11 compiler and Linux headers for the owned I/O helper. No NIF or third-party runtime package is required. CC may name one compiler executable. Install prerequisites before timing checks:

$ mise install

To install newer releases within those ranges without editing the file:

$ mise upgrade erlang elixir

With mise active in your shell, verify that Elixir runs on OTP 29 and was compiled for OTP 29:

$ elixir --version

Mise selects the newest OTP build for an Elixir prefix; the prefix does not lock the OTP suffix. If a future 1.20 patch adds a newer OTP build, select its exact 1.20.x-otp-29 version. asdf requires exact versions and cannot consume these floating ranges directly.

CI reads both ranges from .tool-versions and passes them to setup-beam in loose mode, which selects the Elixir build for the installed OTP major. The action's direct version-file mode requires exact versions.

The native Linux matrix reads exact tmux source revisions and the reference Elixir/OTP pair from priv/tmux/support.json. It also tests the resolved .tool-versions pair with the newest listed tmux release. Every cell checks the actual OTP patch, Elixir version and compiled OTP major before testing. Missing prerequisites fail the cell. Required Linux checks succeeds only when the core checks and every native cell succeed; no macOS job is required.

Hex is required only for package archive checks. Install it separately from the check loops if it is missing:

$ mix local.hex --force

The core has no third-party runtime dependencies. ExDoc is a development-only dependency; install it before timing documentation checks:

$ mix deps.get

tmux is not needed for pure unit or packed-core checks. The implementation floor is tmux 3.3, and support must be proved against that version rather than inferred from a newer local binary.

Current checks

Check that the active runtime matches the development selectors, minimum versions and compiled OTP major:

$ time elixir scripts/check_runtime.exs tracking

Use reference instead of tracking to require the exact reference pair.

Check formatting after an edit:

$ time mix format --check-formatted

Before handing off a change, validate the Mix project with warnings treated as errors:

$ time mix compile --warnings-as-errors

Check public function specs and type documentation against the compiled API:

$ time mix run scripts/check_public_contracts.exs

Compile the consumer fixtures and check the expected Elixir 1.20 diagnostics:

$ time mix run scripts/check_consumer_types.exs

Typespecs document contracts; the compiler infers types from implementation patterns and guards. These fixtures verify selected valid and invalid uses, not arbitrary criteria or every value-dependent return type. The codec fixture records a case inference does not currently reject; runtime validation remains required. Neither a declaration count nor a silent compiler proves every contract.

With dependencies already installed, render the public reference and guides:

$ time mix docs --warnings-as-errors

Check rendered local files and HTML fragments without network requests:

$ time python3 scripts/check_docs_links.py

The link check reports ExDoc's optional host-provided version catalogue separately. It does not verify external websites or publication.

Set DOCS_SOURCE_REF to the reviewed commit, branch or release tag when building documentation for that revision. ExDoc uses main by default. Rendered copies resolve source-file and artwork-directory links without changing the originals.

With Hex already installed, build the local archive:

$ time mix hex.build

Run critical pure tests in the inner loop, or all unit tests in the mid loop:

$ time mix test

Check generated field, operator and relation documentation after schema changes:

$ time mix run scripts/generate_schema.exs --check

Regenerate it with mix run scripts/generate_schema.exs before the check.

The default suite excludes the integration tag. Linux integration fixtures require Python 3.9+ with pidfd support and an explicit tmux executable or tmux on PATH. Python is a development fixture tool, not a core runtime dependency. The helper owns a foreground tmux server, observes socket readiness through inotify and verifies server/pane exit through process handles. It uses no fixed readiness sleeps and never starts the default server.

Run the real fixture checks in the outer loop with the exact tmux binary being qualified:

$ LIBTMUX_TMUX=/path/to/tmux mix test --include integration

CI runs the complete existing suite with two ExUnit cases at once and two BEAM schedulers to fit the Linux runner. The native tests still exercise their explicit concurrent fault schedules. Source download, prerequisites and tmux compilation run before the timed test step. These cells qualify implemented cases; they do not establish unimplemented API support.

Check packed-core consumption and metadata outside the checkout:

$ time mix run scripts/check_package.exs

Real checks round-trip command and format syntax with hostile bytes. The field encoder protects backslashes and control bytes before tmux prints them; the decoder handles one free-form field per response. It does not assume separator bytes cannot occur in values. The pure control parser enforces byte/event limits, but transport receive bounds and shared lane safety need separate qualification.

The ownership guide describes the one-shot helper, resource ceilings and remaining distribution gates.

These gates prove current foundations and fixture ownership. They do not establish a complete client API, installed adapter graphs or compatibility for unexercised operations. Do not add empty source or tests to make a command appear useful. Complete runnable examples and adapter consumer checks arrive with those components.

Check budgets

Time the entire command, including startup and setup. Record duration and scope in the pull request. Tool installation happens before a timed loop.

LoopBudgetStretchScope
InnerUnder 5 secondsUnder 2 secondsFormatting or critical tests for the edited code
MidUnder 30 secondsUnder 10 secondsUnit suites, lint, and generated-file checks
OuterUnder 5 minutesUnder 60 secondsCompilation, packaging, docs, and integration matrices

Formatting and changed pure tests belong in the inner loop; the complete unit suite belongs in the mid loop. Compilation, packaging and real tmux fixtures and documentation rendering belong in the outer loop. Dependency installation stays outside all check loops. Do not run network operations, installs, builds, browsers, sleeps, or broad corpus scans in the inner or mid loop.

Investigate waits longer than one second; use events and subscriptions for readiness instead of fixed sleeps. Slow tests need an outer-loop tag and a one-line reason. Fix redundant setup, polling, and slow paths before adding tests to an over-budget loop. Benchmarks are separate: each run stays under 10 minutes, and a full sweep stays under one hour.

Package boundaries

mix.exs owns the core package. The workspace loader and MCP server have separate Mix projects that consume the core. Do not add adapter dependencies or adapter configuration to the core. The design note records the planned behavioral boundaries.

Adding implementation

Add tests for critical behavior and regressions, not copies of the implementation. A regression test must fail for the intended reason before its passing result becomes evidence. Prefer pure ExUnit tests for parsing, encoding, and selection; exercise protocol and resource ownership against real tmux as well.

Every tmux fixture uses a unique, owned socket and temporary directory. Clear inherited TMUX and TMUX_PANE. Never connect tests to the default server, and only stop servers or remove files owned by that run. Use bounded, event-based readiness and verify cleanup on success and failure.

Use ExUnit supervision for BEAM children and explicit teardown for owned OS processes. A successful teardown call is not proof that a child exited. Enable asynchronous tests only when sockets, state, and cleanup are isolated. Distinguish protocol acknowledgement from operation completion in assertions.

Each support claim needs its own required CI cell. The tmux floor must run against tmux 3.3 itself; 3.3a is a separate compatibility case. Platform and transport coverage remain unverified until implementation exercises them. Missing prerequisites in a required cell fail that cell; report optional skips explicitly.

Pull requests

Keep changes on a topic branch in a separate worktree. Preserve unrelated edits and keep each PR focused on one reviewable change. Follow the commit format in WRITING.md.

Describe the problem, resulting behavior, and relevant validation. Report passing, failing, skipped, and unverified checks separately. Scope claims to what the checks actually exercise; scaffold validation cannot establish runtime compatibility, performance, or release readiness.

Publication

Pushing a v<version> tag runs the required Linux checks at that revision, then publishes the core package and its documentation to public Hex. The tag must match the root Mix version. The publishing job uses HEX_API_KEY from the GitHub environment named hex, then verifies the public release and an installation outside the checkout. Merges and local archive builds do not publish. Creating a release tag requires separate authorization.

Workspace and MCP have no publication jobs. Their eventual releases must use real dependency versions and pass their own installed-consumer checks.