Skip to content

Pass every terminal host's env through safehouse, and only what exists - #730

Merged
clkao merged 1 commit into
mainfrom
spacedock-ensign/safehouse-terminal-env-passthrough
Aug 18, 2026
Merged

Pass every terminal host's env through safehouse, and only what exists#730
clkao merged 1 commit into
mainfrom
spacedock-ensign/safehouse-terminal-env-passthrough

Conversation

@clkao

@clkao clkao commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

env | grep TMUX returned nothing inside a safehouse-wrapped session. The frontdoor was not the cause — launchEnv forwards the whole parent environment and only swaps SPACEDOCK_BIN. The loss was at the sandbox boundary.

terminalTargetingEnvArgs gated its entire allowance on one sentinel:

if _, present := os.LookupEnv("ZELLIJ"); !present {
    return nil
}
return []string{"--env-pass=ZELLIJ,ZELLIJ_PANE_ID,ZELLIJ_SESSION_NAME"}

No ZELLIJ meant nothing was passed at all. So a tmux session reached the child with no TMUX and no TMUX_PANE, and five of six terminal hosts lost their identity crossing into the sandbox. When ZELLIJ was present, all three names were emitted whether set or not — and ZELLIJ is not one of the two variables the consumer actually probes.

The visible consequence: inside safehouse, the subspace:r skill resolves Zellij or falls through to none. A captain in tmux, Herdr, CMUX, Ghostty, or Apple Terminal gets the fallback instead of their real pane. That was reproduced live during this work — a review opened toward a detached Terminal tab rather than the caller's tmux split.

What changed

One list of the nine signals subspace:r probes across its six hosts, and one presence filter over it. A name is emitted only when the parent has that variable; an empty parent yields no allowance at all. The lookup is injected, so the composer is testable without touching the process environment.

Four recorded decisions: drop the bare ZELLIJ name, which no live consumer probes; keep TERM_PROGRAM value-agnostic rather than embedding the consumer's resolution semantics; treat presence as LookupEnv, including set-but-empty; duplicate the nine names rather than build a cross-repository mechanism, because drift degrades to today's behavior or to a diagnosable probe stop, never to a wrong pane.

Evidence

The measuring criterion could not be proven from inside the sandbox — no wrapped session can execute safehouse, and validation confirmed that independently rather than substituting unit evidence for it. It was closed by a captain-run comparison outside the sandbox, in a real tmux session: the consumer's own nine-signal probe, run bare and then wrapped.

All nine signals matched. TMUX and TMUX_PANE read present inside, where they read absent before. The other six read absent in both, so nothing is invented.

The composer was also exercised against real compiled production code under a real process environment, and validation judged the test cases against 11 mutations, finding them not padded with one exception it named.

Surface: 4 files, net +135, of which production is +26. That is 3.0x the ideation estimate, disclosed and judged case by case rather than absorbed.


89b

… filter

terminalTargetingEnvArgs gated on bare ZELLIJ and passed a fixed
three-name list regardless of what was actually set, so tmux/Herdr/CMUX/
Ghostty/Apple Terminal parents lost all terminal-host identity crossing
the safehouse boundary, and unset Zellij names could reach the child.
Replace it with terminalEnvPassArgs, a pure presence filter over
subspace's own nine-signal probe set (injectable lookup for
deterministic unit tests), emitted in probe order; a name appears only
when LookupEnv reports it set in the parent.

Reshapes the Wrap allowance test and cli env-pass smoke fixtures to the
tmux pair (bare ZELLIJ is gone from the vocabulary), and widens the
terminal-independent test hygiene (clear-helpers, TestMain baseline) to
all nine names so the suite passes identically under tmux, Zellij, or a
bare terminal.
@clkao
clkao merged commit a108559 into main Aug 18, 2026
5 of 7 checks passed
@clkao
clkao deleted the spacedock-ensign/safehouse-terminal-env-passthrough branch August 18, 2026 18:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant