scripts/ensure-tmp-symlink

#!/usr/bin/env bash

ensure-tmp-symlink

#

Sets up the project's two-tier RAM scratch, per the CLAUDE.md convention:

#

tmp/ -> /tmp/neocities-modernization/ (RAM, EXEC allowed)

tmp/shared-memory/ -> /dev/shm/neocities-modernization/ (RAM, noexec)

#

The project's tmp/ points at a per-project dir under /tmp/, which is RAM where

/tmp is a tmpfs and — crucially — allows execution, so compiled binaries and

dlopen'd .so files can live and run there. Nested inside it, tmp/shared-memory/

points at /dev/shm/, which every modern Linux guarantees to be RAM but commonly

mounts noexec: the right home for logs, compiled build artifacts, and other

NON-executable data. Rule of thumb: things you RUN go in tmp/; things you WRITE

(logs, dumps, caches) go in tmp/shared-memory/.

#

Idempotent and self-healing: it creates whatever is missing and repoints a

symlink that aims at the wrong target (a symlink holds no data, so re-aiming it

loses nothing). It refuses loudly only when a real directory or file sits where

a symlink belongs — those bytes might be someone's, and moving them into

volatile RAM would be worse than a loud refusal that asks a human to look.

#

Usage:

scripts/ensure-tmp-symlink # uses hard-coded DIR

scripts/ensure-tmp-symlink /path/to/project/root # overrides DIR

source scripts/ensure-tmp-symlink # bash callers can source

set -eu

{{{ DIR resolution

Hard-coded project root with first-argument override, per the project-wide

convention for scripts.

DIR="${1:-/mnt/mtwo/programming/ai-stuff/neocities-modernization}"

}}}

{{{ TARGET resolution

EXEC_TARGET is the exec-capable RAM tier (under /tmp); SHM_TARGET is the

guaranteed-RAM, noexec tier (under /dev/shm). Names are unique per project so

multiple projects on one host do not collide. The shared-memory symlink lives

INSIDE the exec target, so it is reached from the project as tmp/shared-memory/.

EXEC_TARGET="/tmp/neocities-modernization"
SHM_TARGET="/dev/shm/neocities-modernization"
TMP_LINK="${DIR}/tmp" # -> EXEC_TARGET
SHM_LINK="${EXEC_TARGET}/shared-memory" # -> SHM_TARGET; reached as tmp/shared-memory/

}}}

{{{ ensure_targets_exist()

ensure_targets_exist() {
# Both RAM dirs are cheap and wiped on reboot; create whichever is missing.
[ -d "${EXEC_TARGET}" ] || mkdir -p "${EXEC_TARGET}"
[ -d "${SHM_TARGET}" ] || mkdir -p "${SHM_TARGET}"
}

}}}

{{{ ensure_symlink()

Make ${1} a symlink to ${2}. Shared by both tiers so they obey identical rules:

create when missing, repoint a wrong-target symlink in place, refuse a real

directory/file loudly.

ensure_symlink() {
local link_path="${1}"
local want_target="${2}"

# Case: already a symlink. Repoint only if it aims at the wrong place — a
# symlink holds no data, so removing and recreating it loses nothing. This
# is what self-heals an old target (e.g. a pre-two-tier /dev/shm symlink).
if [ -L "${link_path}" ]; then
if [ "$(readlink "${link_path}")" != "${want_target}" ]; then
echo "ensure-tmp-symlink: repointing ${link_path}: '$(readlink "${link_path}")' -> '${want_target}'" >&2
rm "${link_path}"
ln -s "${want_target}" "${link_path}"
fi
return 0
fi

# Case: a real file/dir sits where the symlink belongs. Refuse loudly rather
# than relocate whatever bytes are there into volatile RAM.
if [ -e "${link_path}" ]; then
echo "ERROR: ${link_path} exists but is not a symbolic link." >&2
echo " Move its contents elsewhere, then remove it, then re-run." >&2
echo " Suggested:" >&2
echo " mv '${link_path}' '${link_path}.preserved'" >&2
echo " scripts/ensure-tmp-symlink" >&2
exit 1
fi

# Case: nothing there yet. Fresh-clone path.
ln -s "${want_target}" "${link_path}"
}

}}}

ensure_targets_exist
ensure_symlink "${TMP_LINK}" "${EXEC_TARGET}"
ensure_symlink "${SHM_LINK}" "${SHM_TARGET}"