Never use sibling ~/mine checkout for jerboa-shell-extras; default embed dir to ~/.embed

ober

aca6aa031b30016ee6348fdf8489fa9bae0876e3

diff --git a/AGENTS.md b/AGENTS.md
index 4789b6b..d56d2e6 100644
--- 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
diff --git a/Makefile b/Makefile
index 8f37bdc..bd72c66 100644
--- 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; \
diff --git a/docs/extras.md b/docs/extras.md
index 34e4818..307be97 100644
--- 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”:
 
diff --git a/test/test-make-extras.sh b/test/test-make-extras.sh
index b69783c..2bc17a2 100755
--- 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