diff --git a/.claude/hooks/guard-wow-install.sh b/.claude/hooks/guard-wow-install.sh deleted file mode 100755 index 2b0e24a0..00000000 --- a/.claude/hooks/guard-wow-install.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env bash -# PreToolUse(Edit|Write|NotebookEdit) guard: refuse to write anything into the 1.12.1 install. -# -# Reads the hook JSON on stdin; exit 2 blocks the call, with stderr as the reason. The protected -# roots are WOW_DATA and the `WoW` link of the primary checkout and of the cwd. -# BENILLA_ALLOW_INSTALL_WRITE=1 lets a write through. -input=$(cat) - -path=$(printf '%s' "$input" | jq -r '.tool_input.file_path // .tool_input.notebook_path // empty' 2>/dev/null) -[ -n "$path" ] || exit 0 - -cwd=$(printf '%s' "$input" | jq -r '.cwd // empty' 2>/dev/null) -cwd="${cwd:-$PWD}" -case "$path" in - /*) ;; - '~'/*) path="${HOME}${path#\~}" ;; - *) path="$cwd/$path" ;; -esac - -[ -n "${BENILLA_ALLOW_INSTALL_WRITE:-}" ] && exit 0 - -# Resolve the target through its nearest existing ancestor: a Write may name new directories too. -dir=$(dirname "$path") -while [ ! -d "$dir" ] && [ "$dir" != "/" ] && [ "$dir" != "." ]; do dir=$(dirname "$dir"); done -[ -d "$dir" ] || exit 0 -real=$(cd -P "$dir" 2>/dev/null && pwd) || exit 0 - -# Compare physical paths (`cd -P`): `WoW` may be a symlink, and a write can name either spelling. -own=$(git -C "$(dirname "$0")" rev-parse --path-format=absolute --git-common-dir 2>/dev/null) -primary=$(cd "${own:-.}/.." 2>/dev/null && pwd) -for root in "${WOW_DATA:-}" "$primary/WoW" "$cwd/WoW"; do - [ -n "$root" ] && [ -d "$root" ] || continue - root=$(cd -P "$root" 2>/dev/null && pwd) || continue - case "$real/" in - "$root"/*) - cat >&2 <`, or a `WoW` link at the repo root, which only a dev build sees: the player build looks for `Data/` or `WoW/Data/` beside the binary. benilla reads the install and never writes into it. `WOW_DATA=` (set, empty) diff --git a/docs/METHOD.md b/docs/METHOD.md index 485739e7..bfaf2a4c 100644 --- a/docs/METHOD.md +++ b/docs/METHOD.md @@ -40,8 +40,7 @@ comment naming the reference fact and why we differ. Anything else is a fork. interface code: FrameXML and GlueXML run off the player's own patch chain, and our own counterparts under `assets/ui` stay until they retire. - **The install is read-only.** benilla never writes into the WoW folder: no screenshot, log, - cache or scratch file. A hook blocks such a write at the tool call, and `scripts/smoke.sh` - fails a run that leaves the install changed. + cache or scratch file. `scripts/smoke.sh` fails a run that leaves the install changed. - **Local state lives in one folder**, `benilla-config/` beside the binary, and every path to it resolves through `crate::local_state`. Player settings are CVars persisted as a diff in `benilla-config/config.toml`. @@ -85,7 +84,6 @@ comment naming the reference fact and why we differ. Anything else is a fork. - **Platform seams**: a `cfg(target_os)`, a `[target.'cfg(…)']` dependency, a `#[link]` or an `extern "system"` is invisible to the gates of the platform you are on. Say in the commit which platforms you built. -- One hook: no writes into the install. Everything else is a gate or discipline. ## The local server