- Multi-line copy + paste-IN + Claude Code TUI support. New
bind -n M-MouseDrag1Pane copy-mode -M(Alt-drag, macOS) andbind -n S-MouseDrag1Pane copy-mode -M(Shift-drag, Linux) force tmux selection even when Claude Code / vim / less / htop hold the alt-screen with mouse tracking. New@clip-readuser option +prefix + Ppaste-IN binding pulls the OS clipboard INTO the current pane throughtmux paste-buffer -p(bracketed paste). Seedocs/guides/clipboard.mdfor the operator recipe. - Workable-items SQLite SSoT (
cmd/workable-items/). Project- local Go binary implementing the §11.4.93 SQLite single-source-of- truth for every workable item inIssues.md/Fixed.md. Pure-Go (no CGO) viamodernc.org/sqlite. DB atdocs/workable_items.dbis TRACKED in git per §11.4.95. Seedocs/workable-items/README.mdfor the subcommand reference. - DOCX export on every Markdown sync.
scripts/sync_all_markdown_exports.shnow produces.docxsiblings alongside the existing.html+.pdfexports — verified across 44 candidate documents with pandoc-emitted "Microsoft Word 2007+" output.
A reproducible, hardened build of tmux with built-in jemalloc support, OOM-protection helper, and a comprehensive verification gate. Runs natively on any Linux host (Ubuntu, ALT, Fedora, Arch, openSUSE, Alpine) where podman or docker is available. macOS hosts (Apple Silicon + Intel) are supported via a transparent bridge into the podman machine VM — the operator gets a working tmx command on the macOS shell with no manual SSH-juggling.
The 18 verification tests are why this matters: a typical "build tmux from source" guide assumes the build worked. This project ships a hard wall — bash scripts/setup.sh will refuse to PATH-export the binary unless functional tests pass with positive runtime evidence (cgroup interface readbacks, /proc files, real session output), backed by a §11.4.4 layer-4 paired-mutation harness that proves the gates aren't themselves bluffs. SKIPs document precondition gates (CAP_SYS_RESOURCE, libjemalloc presence, destructive-test opt-in) explicitly. No PASS-bluffs.
Linux host:
git clone --recurse-submodules git@github.com:vasic-digital/tmux.git ~/Projects/tmux
cd ~/Projects/tmux
sudo bash scripts/install_deps.sh # one-time host build deps
bash scripts/setup.sh # build + verify + install (no sudo)macOS host (Apple Silicon or Intel):
brew install podman # one-time: container runtime
podman machine init && podman machine start
git clone --recurse-submodules git@github.com:vasic-digital/tmux.git ~/Projects/tmux
cd ~/Projects/tmux
bash scripts/setup.sh # build + VM-verify + install bridgeAfter setup.sh reports GREEN: open a new shell, or source the rc for your shell (source ~/.bashrc or source ~/.zshrc). Then tmx new|attach|ls|kill invokes the verified vasic-digital build; the system tmux command stays untouched and reachable side-by-side.
┌────────────────────────────────────┐
│ OPERATOR SHELL │
│ $ tmx new -s mywork │
│ $ tmx new -s build ← own scope! │
└──────────────────┬─────────────────┘
│
│ scripts/tmx (host-native, OS-aware dispatch)
▼
┌──────────────────────────┴──────────────────────────┐
│ │
Linux host macOS host (Darwin)
│ │
│ for each `tmx new -s NAME`: │ for each `tmx new -s NAME`:
│ systemd-run --user --scope │ tmux -L tmx-NAME new-session -d -s NAME \
│ --unit=tmx-NAME.scope │ "tmx-rlimit-wrapper.sh \
│ -p MemoryMax=<host-adaptive> │ <mem-kb> <cpu-sec> <nproc> \
│ -p CPUQuota=200% -p TasksMax=4096 │ $SHELL -l"
│ -p Delegate=yes │ set -g default-command "rlimit-wrapper …"
│ tmux -L tmx-NAME new -s NAME -d │
│ │
▼ ▼
┌─────────────────────────────────┐ ┌──────────────────────────────────────────┐
│ cgroup-v2 transient scope │ │ POSIX rlimit wrapper │
│ tmx-NAME.scope │ │ scripts/tmx-rlimit-wrapper.sh │
│ ├ MemoryMax = host-adaptive │ │ ├ ulimit -t ← RLIMIT_CPU (enforced) │
│ ├ CPUQuota = 200% │ │ ├ ulimit -u ← RLIMIT_NPROC (enforced) │
│ ├ TasksMax = 4096 │ │ └ ulimit -v ← RLIMIT_AS NOT enforced │
│ ├ Delegate = yes │ │ by XNU (documented gap) │
│ └ tmux 3.6a (Linux ELF) │ │ tmux 3.6a (Mach-O) │
│ status-bar = DJB2(host) │ │ status-bar = DJB2(host) │
│ oom_score_adj = -500 │ │ (oom_score_adj N/A on Darwin) │
└─────────────────────────────────┘ └──────────────────────────────────────────┘
Shell sees the operator's Shell sees the operator's macOS host:
Linux host: full FS, full PATH, full FS, full PATH (Homebrew, system tools,
all system binaries reachable. all Mach-O binaries), `id` = operator's user.
Native dual-OS per-session isolation (architecture since 2026-05-13). Each tmx new -s NAME invocation creates its own tmux server (socket tmx-NAME) with OS-native isolation:
- Linux — cgroup-v2 transient scope
tmx-NAME.scopeviasystemd-run --user --scope. Kernel enforces MemoryMax, CPUQuota, TasksMax per-group. OOM in one session is contained to that scope — every other session ANDuser.slicesurvive (Constitution §1 invariant). - macOS (Darwin) — POSIX rlimit wrapper sets
RLIMIT_CPU(CPU time) andRLIMIT_NPROC(per-user process count) before exec'ing the operator's$SHELL. The Darwin XNU kernel enforces these per-process. Children inherit.RLIMIT_AS(virtual memory) is NOT enforced by XNU for unprivileged processes — this is a documented gap; full memory containment on macOS requires launchd jobs withHardResourceLimitsplist (root). Seedocs/guide/README.md§5.6 for the strength comparison.
Both OS paths deliver the same operator UX: plain-vanilla tmux behaviour, the operator's shell with full host PATH (Homebrew on macOS, /usr/local/bin on Linux, all system tools), per-session resource ceilings applied transparently. No VM. No bridge. No core@localhost. No bluff.
| Component | Why |
|---|---|
| tmux 3.6a (latest stable) | Pinned to a known-good upstream tag |
| Hardened compile flags | -O2 -DNDEBUG -fstack-protector-strong -D_FORTIFY_SOURCE=2, RELRO + immediate-binding link |
Build-time -ljemalloc |
jemalloc linked at the binary level (more aggressive RAM return than glibc malloc) |
Runtime LD_PRELOAD=libjemalloc.so |
Wrapper preloads jemalloc even on hosts where the linker resolved a different malloc |
| OOM-score protection | Optional setcap-enabled helper (tmx-oom-set) sets oom_score_adj=-500 on the spawned server, making tmux survive most OOM cascades |
Bounded history-limit |
Explicit 2000 (the default — explicit so future bumps are intentional) |
| Per-session cwd memory (v1.0.13+) | tmx-shell-init.sh installs a PROMPT_COMMAND / precmd hook inside every pane; every command's cwd is recorded to ~/.tmx/state.json. Reopen the same session name → wrapper passes -c <last-pwd> to tmux new-session; the pane materialises where you left off. End-to-end guarantee verified by scripts/tests/43_e2e_cwd_persist_real_shell.sh. |
| Hermetic install | Built artifact lives in tmux/build/. PATH export points there; system tmux untouched. Removable via bash scripts/uninstall.sh (or bash scripts/setup.sh --uninstall — both delegate to the same single source of truth). |
SUMMARY: PASS=41 FAIL=0 SKIP=3
GREEN: tmux binary verified — safe to PATH-export.
The 44 numbered tests cover (among others): smoke + binary version, session lifecycle, jemalloc loaded, history-limit honored, clear-history releases memory, 10 concurrent panes, sustained session no-leak, OOM-score wrapper, crash isolation scope (cgroup-v2 transient), hostname-derived status-bar colour (algorithm + integration), memory pressure under cap, TasksMax stress, concurrent OOM independence, per-session cgroup distinctness, window-name .exe strip, scrollback + copy-mode scrolling (operator-path: 3000 lines generated, proven scrolled off-screen, reachable via copy-mode), HelixConstitution inheritance (submodule + every governance doc's pointer), CodeGraph index materialisation, cross-platform parity branches (macOS ↔ Linux), tmx-shell-init non-TTY guard, tmx-state cwd persistence end-to-end across exit + reopen, SSH dispatch to remote nezha, dispatcher session-name validation, setup install/uninstall E2E, and — new in v1.0.14 — clipboard copy-OUT physically proven end-to-end (test 44: marker round-trip through y keystroke → @clip shell-pipe → pbpaste / wl-paste / xclip / termux-clipboard-get returns the marker).
Four honest SKIPs document precondition gates:
03_jemalloc_loadedSKIPs if host doesn't have libjemalloc —sudo bash scripts/install_deps.shprovides it08_oom_score_adjSKIPs unless running as root OR the setcap helper is installed —sudo bash scripts/build_oom_set.sh --installenables it- Tests 12 / 13 / 14 (memory-pressure / TasksMax / concurrent-OOM) require
TMX_TEST_DESTRUCTIVE=1— run only on dedicated test hosts
A layer-4 paired-mutation harness (Constitution §103) lives at scripts/tests/meta_test_false_positive_proof.sh: registered mutations M1–M14 plus CM-CONSTITUTION-INHERITANCE each break a feature, assert the matching test then FAILs, revert, and assert it PASSes again. On macOS the harness reports 18 caught / 0 escaped / 6 skipped (the 6 SKIPs are Linux-only isolation mutations); the remainder run on Linux via META=1 bash scripts/test_vm.sh. The gate is not considered self-validating until every runnable mutation is caught.
See docs/plans/containerization.md for the per-session containerization plan — each tmux session running in its own cgroup-bounded container so that:
- 2 CPU + reasonable RAM cap per session
- Crash isolation: if one session OOMs/crashes, only that session dies; other sessions and their processes survive
- One-command bootstrap:
tmx new <session>transparently creates the container
Every project doc lives under a context-named subdirectory of docs/
per constitution/Constitution.md's file-layout rule. Every Markdown
has a synced HTML + PDF sibling generated by
scripts/export_docs.sh per §11.4.65 universal-Markdown-export.
| Area | Doc |
|---|---|
| Operator guide | docs/guide/README.md — install, OS-by-OS notes, isolation comparison, troubleshooting |
| v1.0.14 / v1.0.15 clipboard | docs/guides/clipboard.md — multi-line copy + paste-IN + Alt/Shift-drag inside Claude Code |
| v1.0.15 workable-items SSoT | docs/workable-items/README.md — cmd/workable-items/ Go binary, subcommand reference, honest gaps |
| v1.0.9 shell-session resume | docs/manual/tmx-shell-integration.md — end-user master manual with copy-paste worked examples |
| v1.0.9 shell integration | docs/guides/tmx-shell-integration.md — operator install/uninstall guide for tmx-shell-init.sh |
| v1.0.9 state daemon | docs/guides/tmx-state.md — operator CLI reference + state-file schema for tmx-state |
| v1.0.9 SSH dispatch | docs/guides/tmx-ssh-dispatch.md — ssh <host>-tmx <session> install, security, troubleshooting |
| Scrolling (Claude Code TUI + mobile) | docs/scrolling/README.md |
| CodeGraph (§11.4.78) | docs/codegraph/README.md — install, per-agent MCP wiring, anti-bluff verification |
| Architecture plans | docs/plans/native-dual-os.md — current native-host design (no VM) |
docs/plans/per-session-isolation.md — per-session OOM containment |
|
docs/plans/containerization.md — original (now superseded) containerization plan |
|
| Cycle plans | docs/plans/v1.0.4.md — this cycle's plan (CodeGraph + covenant propagation + AUDIT fixes) |
| Research notes | docs/research/customization/colors.md — hostname-derived status colour |
| Governance | Constitution.md — Project Articles §101–§109 (extends constitution/); CLAUDE.md, AGENTS.md, QWEN.md — per-agent inheritance pointers + project-specific overlay |
| Universal governance | constitution/ submodule (HelixDevelopment/HelixConstitution, pinned 7f738df) |
| Live state | CONTINUATION.md — read first on a fresh conversation |
| Tracker | Issues.md (open) / Fixed.md (closed with closure SHA + evidence) |
| Changelog | CHANGELOG.md — per-release positive-evidence verification record |
This repo follows the vasic-digital anti-bluff covenant: every
test that PASSes carries positive evidence of the feature working;
every SKIP documents its precondition; every gate has a paired
mutation in meta_test_*.sh proving the gate isn't itself a bluff.
The covenant is restated verbatim in Constitution.md, CLAUDE.md,
AGENTS.md, and QWEN.md (per the 2026-05-21 operator mandate) so
that any tool which doesn't expand @imports still reads it. The
upstream source lives in
constitution/Constitution.md §11.4.
This project is wired with CodeGraph
per constitution/Constitution.md §11.4.78. The MCP server is
configured for Claude Code, OpenCode, Kimi CLI, Crush, and Qwen
Code — see docs/codegraph/README.md for
the install + per-agent wiring contract.
Apache 2.0 — see LICENSE.