os.Root follows an intermediate directory symlink that stays inside the
brain. A dir symlink inside wiki/ pointing elsewhere in the brain let
brain_update and brain_tunnel rewrite an existing .md there (e.g. under
raw/), and session_log followed a symlinked sessions dir.
- WriteRegular, ReadRegular and ReadRegularMax require every directory
above the file to be a real directory (realDir). Reads too: brain_tunnel
read the redirected target, then rewrote the source before the target's
write was refused; and brain_read/brain_get could read another part of
the brain through such a path.
- session.Append refuses a sessions dir that is not a real directory.
- A directory swapped in after the check remains the #167 residual.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
brain_tunnel accepts only clean wiki/.../*.md paths and reads/rewrites both notes through brainfs; new brainfs.WriteRegular never creates, never writes through a final symlink (Lstat + O_NOFOLLOW|O_NONBLOCK + os.SameFile on the handle, since os.Root follows in-root final symlinks even with O_NOFOLLOW). brain_update resolves like brain_edit (knowledge/ and wiki/ notes only) and reads/rewrites through brainfs. session_log requires a plain-name session id and opens with O_NOFOLLOW|O_NONBLOCK.
Fixes#169. Adversarial review: BLOCKED, BLOCKED, PASS (round 3 by the estate session's reviewer). Follow-ups: #173, #174.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Mathias <mthbqv@gmail.com>