Commit Diff


commit - 77abbd7c60f1b86567878155667ad2806ff24d1c
commit + ecbc43f0d9708d2ddb4708e27b3f24cdb3902da7
blob - e5bb910dee32022ed917f75383a5771c5e2704ec
blob + 68a69f134860e2eb21be7320c03677c6055f71b9
--- Makefile
+++ Makefile
@@ -1,80 +1,54 @@
-LIBDIR = src
+PREFIX ?= /usr/local
+BINDIR ?= $(PREFIX)/bin
+LIBEXECDIR ?= $(PREFIX)/libexec/pisol
+MANDIR ?= $(PREFIX)/share/man
+DESTDIR ?=
+
+INSTALL ?= install
+RM ?= rm -f
 SCHEME ?= scheme
-
-.PHONY: build tui test copy-config clean run fmt install uninstall help
-
+.PHONY: build tui test copy-config clean run install uninstall help
 default: help
-
 build: build/runtime/pisol.so
-
 build/runtime/pisol.so: bin/pisol.ss src/pisol/core.sls src/pisol/tui.sls tools/build.ss
 	@mkdir -p build/runtime/lib/pisol
-	$(SCHEME) --libdirs $(LIBDIR) --compile-imported-libraries --program tools/build.ss
+	$(SCHEME) --libdirs src --compile-imported-libraries --program tools/build.ss
 	cp src/pisol/core.so src/pisol/tui.so build/runtime/lib/pisol/
-
 tui: build
-	$(SCHEME) --libdirs $(LIBDIR) --program bin/pisol.ss
-
+	$(SCHEME) --libdirs src --program bin/pisol.ss
 test: build
-	shellcheck bin/pisol test/integration.sh tools/fmt.sh
-	$(SCHEME) --libdirs $(LIBDIR) --program test/test.ss
+	shellcheck bin/pisol test/integration.sh
+	$(SCHEME) --libdirs src --program test/test.ss
 	sh test/integration.sh
-
 copy-config:
-	@config_home="$${XDG_CONFIG_HOME:-$$HOME/.config}"; \
-	target="$$config_home/pisol/init"; \
-	s=; if [ -e "$$config_home" ] && [ ! -w "$$config_home" ]; then s=sudo; fi; \
-	if [ -f "$$target" ]; then \
-		printf 'pisol: %s already exists\n' "$$target" >&2; \
-		exit 1; \
-	fi; \
-	$$s install -d "$$config_home/pisol" && \
-	$$s install -m 644 config/pisol/init "$$target"
-
+	@target="$${XDG_CONFIG_HOME:-$$HOME/.config}/pisol/init"; \
+	[ ! -e "$$target" ] || { printf 'pisol: %s already exists\n' "$$target" >&2; exit 1; }; \
+	$(INSTALL) -d "$${target%/*}" && $(INSTALL) -m 644 config/pisol/init "$$target"
 clean:
 	rm -rf build src/pisol/core.so src/pisol/tui.so
-
 run: install
-	bash /usr/local/bin/pisol
-
-fmt:
-	sh tools/fmt.sh src/pisol/core.sls src/pisol/tui.sls bin/pisol.ss test/test.ss tools/build.ss
-
+	$(DESTDIR)$(BINDIR)/pisol
 install: build
-	@prefix="$${PREFIX:-/usr/local}"; \
-	bindir="$${BINDIR:-$$prefix/bin}"; \
-	libexecdir="$${LIBEXECDIR:-$$prefix/libexec/pisol}"; \
-	mandir="$${MANDIR:-$$prefix/share/man}"; \
-	destdir="$${DESTDIR:-}"; \
-	can_create() { d="$$1"; while [ -n "$$d" ] && [ ! -e "$$d" ]; do d=$$(dirname "$$d"); done; [ -d "$$d" ] && [ -w "$$d" ]; }; \
-	s=; if ! can_create "$$destdir$$bindir"; then s=sudo; fi; \
-	$$s install -d "$$destdir$$bindir" "$$destdir$$libexecdir/lib/pisol" "$$destdir$$mandir/man1" && \
-	$$s install -m 755 bin/pisol "$$destdir$$bindir/pisol" && \
-	$$s install -m 755 build/runtime/pisol.so "$$destdir$$libexecdir/pisol.so" && \
-	$$s install -m 644 build/runtime/lib/pisol/core.so build/runtime/lib/pisol/tui.so "$$destdir$$libexecdir/lib/pisol/" && \
-	$$s install -m 644 doc/pisol.1 "$$destdir$$mandir/man1/pisol.1"
-
+	$(INSTALL) -d $(DESTDIR)$(BINDIR) $(DESTDIR)$(LIBEXECDIR)/lib/pisol $(DESTDIR)$(MANDIR)/man1
+	$(INSTALL) -m 755 bin/pisol $(DESTDIR)$(BINDIR)/pisol
+	$(INSTALL) -m 755 build/runtime/pisol.so $(DESTDIR)$(LIBEXECDIR)/pisol.so
+	$(INSTALL) -m 644 build/runtime/lib/pisol/core.so build/runtime/lib/pisol/tui.so $(DESTDIR)$(LIBEXECDIR)/lib/pisol/
+	$(INSTALL) -m 644 doc/pisol.1 $(DESTDIR)$(MANDIR)/man1/pisol.1
 uninstall:
-	@prefix="$${PREFIX:-/usr/local}"; \
-	bindir="$${BINDIR:-$$prefix/bin}"; \
-	libexecdir="$${LIBEXECDIR:-$$prefix/libexec/pisol}"; \
-	mandir="$${MANDIR:-$$prefix/share/man}"; \
-	destdir="$${DESTDIR:-}"; \
-	can_create() { d="$$1"; while [ -n "$$d" ] && [ ! -e "$$d" ]; do d=$$(dirname "$$d"); done; [ -d "$$d" ] && [ -w "$$d" ]; }; \
-	s=; if ! can_create "$$destdir$$bindir"; then s=sudo; fi; \
-	$$s rm -f "$$destdir$$bindir/pisol" "$$destdir$$libexecdir/pisol.so" "$$destdir$$libexecdir/lib/pisol/core.so" "$$destdir$$libexecdir/lib/pisol/tui.so" "$$destdir$$mandir/man1/pisol.1"
-
+	$(RM) $(DESTDIR)$(BINDIR)/pisol $(DESTDIR)$(LIBEXECDIR)/pisol.so
+	$(RM) $(DESTDIR)$(LIBEXECDIR)/lib/pisol/core.so $(DESTDIR)$(LIBEXECDIR)/lib/pisol/tui.so
+	$(RM) $(DESTDIR)$(MANDIR)/man1/pisol.1
 help:
 	@printf '%s\n' \
-		'make build       Compile the Chez Scheme program' \
-		'make tui         Run the configuration TUI' \
-		'make test        Run specification, static, Chez, shell, and TUI tests' \
-		'make run         Install and run pisol' \
-		'make fmt         Format Scheme sources with emacs scheme-mode' \
+		'make build       Compile pisol' \
+		'make tui         Run pisol program' \
+		'make test        Run pisol tests' \
 		'make copy-config Copy the default global init to ~/.config/pisol/init' \
 		'make clean       Remove generated artifacts' \
 		'make install     Install pisol and its manual' \
 		'make uninstall   Remove installed pisol files' \
 		'make help        Show this help message' \
 		'' \
-		'Variables: SCHEME=scheme'
+		'Variables: PREFIX=/usr/local DESTDIR= BINDIR=PREFIX/bin' \
+		'           LIBEXECDIR=PREFIX/libexec/pisol MANDIR=PREFIX/share/man' \
+		'           SCHEME=scheme INSTALL=install'
blob - ea1eb8902b18e4e1e8e1880e09dcef553b61fd1e
blob + e9e5036cf087d5343b0cbd5a121280f5c1b858f3
--- README.md
+++ README.md
@@ -1,19 +1,20 @@
 # pisol
 
-Working-directory Landrun isolation and configuration, with a terminal interface
-written in Chez Scheme.
+Run commands in a Landrun sandbox and manage each project's isolation settings.
+The terminal interface is 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.
+`pisol` uses a trusted local `.isolate` Bash file. It denies outbound TCP by
+default. Use the editor to add writable and executable directories, and allow
+connections to specific TCP ports.
 
 ## Run
 
-You need Bash, [Landrun](https://github.com/Zouuup/landrun), Chez Scheme 10.4 or
-newer, and Make. Install `fzf` for fuzzy directory selection. Without it, the
-editor uses direct path entry. Install `emacs` to run `make fmt`.
+You need Bash, [Landrun](https://github.com/Zouuup/landrun), Chez Scheme 10.4
+or later, and Make.
 
+Install `fzf` to search for directories. Without it, enter a path directly.
+Install `emacs` to run `make fmt`.
+
 ```sh
 make tui
 make test
@@ -31,14 +32,14 @@ Run a command in that directory sandbox:
 pisol your-command --with arguments
 ```
 
-Use `pisol -- COMMAND` when a command name conflicts with a pisol option. The
-command receives the caller environment, `PROMPT_ENV_INDICATOR=isolated`, and
-`ISOLATE_ENV` set to the canonical working directory. Calling `pisol COMMAND`
-inside an existing pisol sandbox prints a warning and directly executes the
-command rather than creating a nested Landlock domain.
+Use `pisol -- COMMAND` when a command name conflicts with a pisol option.
 
-## TUI commands
+The command receives your environment, `PROMPT_ENV_INDICATOR=isolated` and
+`ISOLATE_ENV`, set to the resolved working directory. If you run `pisol COMMAND`
+inside an existing pisol sandbox, it warns you and runs the command directly.
 
+## Terminal interface commands
+
 ```text
 a          fuzzy-find or enter a writable directory path
 r          choose and remove a writable directory
@@ -51,20 +52,21 @@ sx         save and exit immediately (xs also works)
 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.
+After you select `a`, enter a base path such as `/home/miro`. Press Enter to
+start in your home directory. `fzf` shows the path and its immediate child
+directories. Press Enter to open a directory. Press Alt+Enter or Ctrl-S to
+select it. Press Escape to use the path you entered.
 
+You cannot add the baseline writable tree again.
+
 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:
+`.isolate` is trusted Bash code. The launcher sources it. A generated file
+looks like this:
 
 ```bash
 args+=(
@@ -73,26 +75,29 @@ args+=(
 )
 ```
 
-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 global init file at `~/.config/pisol/init` runs before the local `.isolate`
+file. Put shared grants there. Project settings build on those grants. Set
+`PISOL_INIT_CONFIG` to use a different global init file.
 
-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 source tree includes a permissive example init at `config/pisol/init`.
+Copy it to `~/.config/pisol/init` and change it for your needs. Remove
+`--unrestricted-network` to deny outbound TCP 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 editor evaluates existing custom `.isolate` code. It manages the resulting
+`--rwx` and `--connect-tcp` values and keeps the other Landrun arguments.
 
-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
+Saving custom code needs confirmation. It replaces the code with a static
+argument array, so it removes comments and dynamic logic. The editor shows
+global grants but does not let you change them. Add or remove project grants
+instead.
+
+The default policy gives the working tree read, write and execute access. It
+also gives write access to temporary storage. System configuration and shared
+data are read-only. Standard runtime and absolute `PATH` directories are
+readable and executable.
+
+The policy allows the standard null, zero, random and terminal devices. It does
+not allow unrestricted networking. It adds a Wayland socket when
 `WAYLAND_DISPLAY` and `XDG_RUNTIME_DIR` are set.
 
 ## Build and install
@@ -105,9 +110,10 @@ make install
 make copy-config
 ```
 
-`make 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.
+`make fmt` formats Scheme files in place with `emacs` scheme mode. Run it after
+you edit Scheme files. It does not change files that are already formatted.
 
-`make install` defaults to `/usr/local` and asks for `sudo` only when needed.
+`make install` defaults to `/usr/local`; use `sudo make install` only when your
+chosen destination requires it.
 Set `PREFIX`, `DESTDIR`, `BINDIR`, `LIBEXECDIR`, `MANDIR`, or `SCHEME` to
 override the defaults. See `pisol(1)` after installation.
blob - 02b2e3b98611be14fa0f53f80d5647f81aa32e41
blob + 1c6a2cb10b3921fbcddd56b0df72f9f5daa4cf4d
--- config/pisol/init
+++ config/pisol/init
@@ -1,7 +1,6 @@
 #!/usr/bin/env bash
-# Default global init for pisol.
-# Sourced before the project-specific .isolate file. Put shared grants here
-# and keep per-project additions in `.isolate`.
+# Default global init for pisol that is sourced before
+# the project-specific .isolate file.
 
 args+=(--unrestricted-network)
 
blob - 89789314f9085e56e28497232eb4c24a28d07602
blob + ce3f2aec5603520c0caa998b0008cc9b32a17d3d
--- doc/pisol.1
+++ doc/pisol.1
@@ -13,60 +13,60 @@ pisol \- configure and run working-directory Landrun i
 .RI [ ARG ...]
 .SH DESCRIPTION
 .B pisol
-opens a Chez Scheme terminal editor for the current directory isolation
-configuration.  With a command, it replaces itself with
+opens a Chez Scheme terminal editor for the current directory's isolation
+settings.  With a command, it replaces itself with
 .BR landrun (1)
-and executes the command in a working-directory sandbox.  Use
+and runs the command in a sandbox for the current directory.  Use
 .B --
 before a command whose name conflicts with a pisol option.
 .PP
-The canonical current directory defines the writable tree.  The configuration
+The resolved current directory defines the writable tree.  The configuration
 path is
 .I CURRENT_DIRECTORY/.isolate
 unless
 .B ISOLATE_EXTRA_CONFIG
 is set.
 .SH ISOLATION POLICY
-The working tree is readable, writable, and executable.  Temporary storage is
+The working tree is readable, writable and executable.  Temporary storage is
 writable.  Standard runtime and absolute PATH directories are readable and
-executable, while system configuration and shared data are read-only.  The
-standard null, zero, random, and controlling-terminal devices are writable.
+executable.  System configuration and shared data are read-only.  The standard
+null, zero, random and controlling-terminal devices are writable.
 .PP
 Outbound TCP is denied by default.  Only destination ports configured with
 .B --connect-tcp
 are granted.  Scoped IPC restrictions are relaxed, and the current Wayland
 socket is granted when its environment variables are available.
 .PP
-The caller environment is forwarded.  The command additionally receives
+The command receives the caller environment.  It also receives
 .B PROMPT_ENV_INDICATOR=isolated
 and
 .B ISOLATE_ENV
-set to the canonical working directory.  If
+set to the resolved working directory.  If
 .B ISOLATE_ENV
-is already non-empty, pisol warns and directly executes the command without
-starting a nested Landlock domain.
-.SH TUI COMMANDS
+is already non-empty, pisol warns and runs the command directly.  It does not
+start a nested Landlock domain.
+.SH TERMINAL INTERFACE COMMANDS
 .TP
 .B a
-Prompt for a base directory path and add it as an additional
-read/write/execute grant.  With no input, the picker opens in the user's home
-directory.  When
+Prompt for a base directory path and add a read/write/execute grant.  With no
+input, the picker opens in the user's home directory.  When
 .BR fzf (1)
-is available, the picker lists only the typed path and its immediate child
-directories.  Press Enter to drill down into a directory, Alt+Enter or
-Ctrl-S to select it, or Escape to use the typed path directly.
+is available, the picker lists the typed path and its immediate child
+directories.  Press Enter to open a directory.  Press Alt+Enter or Ctrl-S to
+select it.  Press Escape to use the typed path directly.
 .TP
 .B r
 Prompt for the number of a writable directory and remove it.
 .TP
 .BI p " PORT"
-Allow outbound TCP connections to PORT.  Valid ports are 1 through 65535.
+Allow outbound TCP connections to PORT.  Valid ports are 1 to 65535.
 .TP
 .B d
 Prompt for a configured outbound TCP port and remove it.
 .TP
 .B c
-Show the resolved global init file and the local configuration file, including their raw contents.  A missing file is labelled absent.
+Show the global init file and local configuration file, including their raw
+contents.  A missing file is labelled absent.
 .TP
 .B s
 Save atomically with mode 0600.  The combined commands
@@ -79,7 +79,7 @@ save and then exit immediately.
 Show help or exit.  Exit discards any unsaved changes.
 .SH CONFIGURATION
 .I .isolate
-is trusted Bash code sourced by the launcher.  It modifies the Bash array
+is trusted Bash code.  The launcher sources it.  It changes the Bash array
 .IR args ,
 normally with an
 .B args+=(...)
@@ -87,10 +87,10 @@ fragment.
 .PP
 If
 .I ~/.config/pisol/init
-exists, it is sourced before the local
+exists, the launcher sources it before the local
 .I .isolate .
-Put shared grants in the global init file; per-project configuration builds on
-top of it.  The path can be overridden with
+Put shared grants in the global init file.  Per-project configuration builds on
+it.  Set
 .BR PISOL_INIT_CONFIG .
 .PP
 A permissive example global init based on the legacy
@@ -99,18 +99,18 @@ script is included in the source tree at
 .IR config/pisol/init .
 Copy it to
 .I ~/.config/pisol/init
-and edit to customize.  Remove
+and change it for your needs.  Remove
 .B --unrestricted-network
 from the copy to deny outbound TCP by default.
 .PP
-The editor evaluates an existing file, manages resulting
+The editor evaluates an existing file.  It manages the resulting
 .B --rwx
 and
 .B --connect-tcp
-pairs, and preserves other resulting arguments.  Saving custom shell logic
-requires confirmation and replaces it with a canonical static array; source
-comments and dynamic logic are not preserved.  Default grants from the global
-init file are shown but not editable in the TUI.
+pairs and keeps other resulting arguments.  Saving custom shell code requires
+confirmation.  It replaces the code with a static array, so it removes source
+comments and dynamic logic.  The terminal interface shows global init grants.
+It does not let you change them.
 .SH ENVIRONMENT
 .TP
 .B ISOLATE_EXTRA_CONFIG
@@ -132,7 +132,7 @@ Supply runtime paths and grants.
 .BR WAYLAND_DISPLAY , " XDG_RUNTIME_DIR"
 Identify an optional Wayland Unix socket grant.
 .SH EXIT STATUS
-The TUI returns zero on normal exit and non-zero on load or save errors.  In
+The terminal interface returns zero on normal exit and non-zero on load or save errors.  In
 command mode, pisol propagates the executed command status.  Usage errors
 return 2 and a missing Landrun executable returns 127.
 .SH SEE ALSO