Option 1 of #157, slice 2. readExcerpt (brain_context), api.ReadNote
(brain_get / read-after-write) and notes.ReadScoped (brain_read) read
the Syncthing-shared brain by path. Under a symlink swap race each
leaked an outside file hundreds of thousands of times in 1.5s, including
brain_read, whose Lstat check was raced by the reopen-by-name; a FIFO
blocked os.ReadFile.
- All three read through brainfs (os.Root, regular files only,
non-blocking open, type check on the handle).
- brainfs.ReadRegularMax checks a size limit on the opened handle;
notes keeps its ErrTooLarge.
- New internal/brainfs/brainfstest: the shared swap-race harness
(symlink and held-writer FIFO swappers, awaited before TempDir
cleanup; AssertNoLeak / AssertNoHang) for this and later slices.
Tests red first: each reader under a symlink-swap race and a held-writer
FIFO race, plus static checks. Flipped: readExcerpt back to os.ReadFile
is red.
Refs #157
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>