Never use sibling ~/mine checkout for jerboa-shell-extras; default embed dir to ~/.embed
ober
aca6aa031b30016ee6348fdf8489fa9bae0876e3
--- a/AGENTS.md +++ b/AGENTS.md @@ -348,6 +348,23 @@ Common sibling repos that exist but must NOT be touched without explicit instruc If a user instruction mentions a file path, use EXACTLY that path. Do not substitute a similar-looking path from another repo. +### Never Reference Sibling Checkouts in Build Files + +Build files (Makefile, shell scripts, CI config) must **never** resolve a +dependency via a relative sibling path (`../jerboa-foo`) or an absolute +`~/mine/jerboa-foo` path. That layout is specific to this one machine — +other users and CI do not have it. Always vendor instead: fetch/clone the +dependency into `vendor/` (or this repo's equivalent) at build time, or use +a pinned-release fetch script, so the build is reproducible without +assuming any sibling checkout exists. + +A sibling-path fallback is not just a portability bug: it can silently +substitute a full alternate source tree (build config, embedded data, +secrets) for the vendored one, with no equivalent safety default, changing +what actually gets built without any indication. If you find one +(`grep -rn '\.\./jerboa\|~/mine/jerboa'` over Makefiles/scripts), remove it +and vendor properly instead. + --- ## Build & Verification --- a/Makefile +++ b/Makefile @@ -8,9 +8,9 @@ export JSH_VERSION_SHORT JERBOA_VERSION ?= v0.2.0 JERBOA_TOOL_DIR ?= $(CURDIR)/.jerboa/bin JERBOA_SHELL_EXTRAS_URL ?= https://git.sr.ht/~lisp/jerboa-shell-extras -JERBOA_SHELL_EXTRAS_DIR ?= $(shell if [ -f "$(CURDIR)/../jerboa-shell-extras/Makefile" ]; then printf '%s\n' "$(CURDIR)/../jerboa-shell-extras"; else printf '%s\n' "$(CURDIR)/_vendor/jerboa-shell-extras"; fi) +JERBOA_SHELL_EXTRAS_DIR ?= $(CURDIR)/_vendor/jerboa-shell-extras JSH_EXTRAS_EMBED_CONF ?= $(CURDIR)/.jsh-extras-embed.conf -JSH_EXTRAS_DEFAULT_EMBED ?= $(JERBOA_SHELL_EXTRAS_DIR)/embed +JSH_EXTRAS_DEFAULT_EMBED ?= $(shell if [ -d $(HOME)/.embed ]; then echo $(HOME)/.embed; else echo $(JERBOA_SHELL_EXTRAS_DIR)/embed; fi) JERBUILD ?= $(shell if [ -x ./jerbuild ]; then echo ./jerbuild; \ elif [ -x "$(JERBOA_TOOL_DIR)/jerbuild" ]; then echo "$(JERBOA_TOOL_DIR)/jerbuild"; \ elif command -v jerbuild >/dev/null 2>&1; then command -v jerbuild; \ --- a/docs/extras.md +++ b/docs/extras.md @@ -82,26 +82,30 @@ to `./jsh-extras`. ## Embedded files and encryption -The top-level target deliberately passes this source directory to the extras -build: +`make extras` resolves its embed source directory with +`tools/select-extras-embed.sh`, in this order: -```text -_vendor/jerboa-shell-extras/embed -``` +1. the `JSH_EMBED` environment variable, if set; +2. the path saved from a previous run in `.jsh-extras-embed.conf`; +3. `~/.embed`, if that directory already exists; +4. otherwise `_vendor/jerboa-shell-extras/embed` (created empty when + necessary), so a fresh clone with no `~/.embed` never bakes in or + encrypts anything by accident. -It creates the directory when necessary. Therefore, `make extras` does **not** -read or encrypt `~/.embed`, and an empty default directory does not trigger an -encryption-passphrase prompt. +The `configure`/`features*` steps prompt once for this path (showing the +resolved default in brackets — press Enter to accept it) and persist the +answer in `.jsh-extras-embed.conf`. Override any time with +`JSH_EMBED=/some/dir make extras`; that also updates the saved state. -To build an enhanced shell from `~/.embed`, run the extras target directly -from an interactive terminal and explicitly enable encryption: +The generator (`gen-embed.ss`) auto-enables encryption whenever the resolved +directory is `~/.embed` (override either way with `JSH_EMBED_ENCRYPT=1` or +`=0`). To build directly without going through the top-level selector: ```sh make ensure-shell-extras make -C _vendor/jerboa-shell-extras extras \ JERBOA_SHELL_DIR="$PWD" \ JSH_EMBED="$HOME/.embed" \ - JSH_EMBED_ENCRYPT=1 \ EXTRAS_OUTPUT="$PWD/jsh-extras" ``` @@ -110,10 +114,18 @@ for confirmation. It prompts only when standard input is a terminal. In a noninteractive build it creates or reuses an empty embed table rather than trying to read a passphrase. -An already-generated encrypted embed table is reused without prompting. To -change the embedded files or encryption passphrase, remove the generated -`_vendor/jerboa-shell-extras/src/jsh/embed-data.sls` and rebuild. Do not commit -that generated file or any source secret from `~/.embed` to this repository. +**An already-generated encrypted embed table is reused without prompting —** +`gen-embed` skips regeneration entirely whenever +`_vendor/jerboa-shell-extras/src/jsh/embed-data.sls` already exists and is +marked `embed-encrypted? #t`, no matter what `JSH_EMBED` resolves to this run +or whether `~/.embed`'s contents changed since. This is why a rebuild can +finish with no new passphrase prompt, yet `,unlock` still works: it is +reusing the previous build's encrypted table and passphrase verbatim, not +re-encrypting current `~/.embed` contents. To pick up changed embed files or +set a new passphrase, remove the generated +`_vendor/jerboa-shell-extras/src/jsh/embed-data.sls` and rebuild. Do not +commit that generated file or any source secret from `~/.embed` to this +repository. At runtime, encrypted files remain inaccessible until `,unlock` succeeds: @@ -483,10 +495,14 @@ No feature menu appears: No embed passphrase prompt appears: -- The top-level target uses `_vendor/jerboa-shell-extras/embed`, not - `~/.embed`. +- `JSH_EMBED` did not resolve to `~/.embed` this run (check `make + show-features`, or `.jsh-extras-embed.conf`); encryption only + auto-enables for that path. Pass `JSH_EMBED_ENCRYPT=1` to force it. - The generator prompts only with a TTY. -- An existing encrypted generated table is reused without prompting. +- An existing encrypted generated table is reused without prompting — see + "Embedded files and encryption" above. Remove + `_vendor/jerboa-shell-extras/src/jsh/embed-data.sls` to force a fresh + passphrase prompt. A command reports “not available in this build”: --- a/test/test-make-extras.sh +++ b/test/test-make-extras.sh @@ -33,8 +33,11 @@ print-default-extras-dir: @printf '%s\n' "$(JERBOA_SHELL_EXTRAS_DIR)" EOF )" -if [ -f "$ROOT/../jerboa-shell-extras/Makefile" ] && [ "$default_extras_dir" != "$ROOT/../jerboa-shell-extras" ]; then - fail "default extras checkout should prefer sibling ../jerboa-shell-extras" +[ "$default_extras_dir" = "$ROOT/_vendor/jerboa-shell-extras" ] || + fail "extras checkout must always be the vendored copy, got: $default_extras_dir" + +if grep -Eq '\.\./jerboa-shell-extras|\$\{?HOME\}?/mine' Makefile; then + fail "Makefile must never reference a sibling ../jerboa-shell-extras or ~/mine checkout" fi if grep -Fq 'JSH_EMBED="$(JERBOA_SHELL_EXTRAS_DIR)/embed"' Makefile; then