# pisol
Working-directory Landrun isolation and configuration, with a terminal interface
written in Chez Scheme.
`pisol` combines command isolation with an editor for the local trusted
`.isolate` shell fragment. Outbound TCP is denied by default. The editor manages
extra writable/executable directories and the destination TCP ports commands
may connect to.
## Run
You need Bash, [Landrun](https://github.com/Zouuup/landrun), Chez Scheme 10.4 or
newer, and Ninja. Install `fzf` for fuzzy directory selection. Without it, the
editor uses direct path entry. Install `emacs` to run `ninja fmt`.
```sh
ninja tui
ninja test
```
After installation, open the editor in the working directory:
```sh
pisol
```
Run a command in that directory sandbox:
```sh
pisol -- your-command --with arguments
```
The command receives the caller environment, `PROMPT_ENV_INDICATOR=isolated`,
and `ISOLATE_ENV` set to the canonical working directory. Calling `pisol -- ...`
inside an existing pisol sandbox prints a warning and directly executes the
command rather than creating a nested Landlock domain.
## TUI commands
```text
a fuzzy-find or enter a writable directory path
r choose and remove a writable directory
p PORT allow outbound TCP connections to a destination port
d enter and remove an outbound TCP port
c show global and local configuration file contents
s save
sx save and exit immediately (xs also works)
? help
x exit (discards any unsaved changes)
```
After selecting `a`, enter a base path such as `/home/miro`, or press Enter to
open the picker in your home directory. `fzf` then lists that path and its
immediate child directories only. Press Enter to drill down into a directory,
Alt+Enter or Ctrl-S to select it, or Escape to use the typed path directly.
The baseline writable tree cannot be added redundantly.
Set `NO_COLOR=1` to disable colour. `COLUMNS` and `LINES` are respected by the
terminal environment. Set `ISOLATE_EXTRA_CONFIG` to use a config path other
than `CURRENT_DIRECTORY/.isolate`.
## Configuration and trust
`.isolate` is sourced as trusted Bash by the launcher. A generated file looks
like this:
```bash
args+=(
--rwx '/home/example/shared work'
--connect-tcp 443
)
```
A global init file at `~/.config/pisol/init` is sourced before the local
`.isolate` when it exists. Put shared grants there; the project-specific file
builds on top of it. Override the path with `PISOL_INIT_CONFIG`.
A permissive example init based on the legacy `isolate` script is included at
`config/pisol/init`. Copy it to `~/.config/pisol/init` and edit to taste;
remove `--unrestricted-network` to keep outbound TCP denied by default.
The TUI also evaluates existing custom `.isolate` logic. It extracts the
resulting `--rwx` and `--connect-tcp` entries and preserves other resulting
Landrun arguments. Saving custom logic requires confirmation because the source
is replaced by a canonical argument array; comments and dynamic logic are not
retained. Default grants from the global init are shown but not edited in the
TUI; add or remove project-specific entries instead.
The minimal default policy grants the working tree read/write/execute access,
temporary storage write access, read access to system configuration/data, and
read/execute access to standard runtime and absolute `PATH` directories. It
also grants the standard null, zero, random, and controlling-terminal devices,
but does not grant unrestricted networking. A Wayland socket is added when
`WAYLAND_DISPLAY` and `XDG_RUNTIME_DIR` are set.
## Build and install
```sh
ninja build
ninja test
ninja fmt
ninja install
ninja copy-config
```
`ninja fmt` reindents the Scheme sources in place with `emacs` scheme-mode. Run
it after editing Scheme files; it is a no-op on already-formatted files.
`ninja install` defaults to `/usr/local` and asks for `sudo` only when needed.
Set `PREFIX`, `DESTDIR`, `BINDIR`, `LIBEXECDIR`, `MANDIR`, or `SCHEME` to
override the defaults. See `pisol(1)` after installation.