test: pin the edit symlink refusal, AppendRegular's clean check and Remove (#188)
CI / Lint / Test / Vet (pull_request) Failing after 1m6s
CI / Mirror to GitHub (pull_request) Skipped

Review round 1 on PR #189 (three tests stayed green with their guard
removed):
- TestEditRefusesANoteBehindASymlinkedDirectory had no .git, so Edit
  refused "not the sync source" before any path check. It now has one,
  plus a positive control.
- AppendRegular's unclean-path case was refused by a final symlink, not
  cleanRel. New test where ".." after a symlinked dir resolves to a real
  file, for AppendRegular and PutRegular.
- brainfs.Remove had no test; new one (refuses behind a symlinked dir,
  removes a final link but never its target, positive control).

Also: promote/reject create with O_EXCL (new brainfs.CreateRegular), so a
note that appears after the collision check is never overwritten;
gofmt fixes in provenance.go and wiki/log.go; dead wingDir and
putBrainFile removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-05 22:57:26 +02:00
co-authored by Claude Opus 5.5
parent 138d6e2545
commit db18785bfc
7 changed files with 80 additions and 13 deletions
+4 -2
View File
@@ -133,7 +133,9 @@ func PromoteNote(brainDir string, opts PromoteOptions) (string, error) {
if err != nil {
return "", err
}
if _, err := putBrainFile(brainDir, dest, []byte(promoted)); err != nil {
// Created with O_EXCL: a note that appeared after the collision check
// above is never overwritten.
if err := createBrainFile(brainDir, dest, []byte(promoted)); err != nil {
return "", fmt.Errorf("write promoted note: %w", err)
}
if err := removeBrainFile(brainDir, src); err != nil {
@@ -196,7 +198,7 @@ func RejectNote(brainDir string, opts RejectOptions) (string, error) {
// Write-then-delete: the source survives any write failure. Both go
// through the brain root (hyperguild#188).
if _, err := putBrainFile(brainDir, dest, []byte(fm.render()+body)); err != nil {
if err := createBrainFile(brainDir, dest, []byte(fm.render()+body)); err != nil {
return "", fmt.Errorf("write rejected note: %w", err)
}
if err := removeBrainFile(brainDir, src); err != nil {
+6 -7
View File
@@ -44,20 +44,19 @@ func StampProvenanceFile(brainDir, relPath, origin, writtenBy string) error {
return nil
}
// putBrainFile creates or replaces the file at abs (inside brainDir) through
// the brain root, never through a symlinked directory or file (#188).
func putBrainFile(brainDir, abs string, data []byte) (string, error) {
// createBrainFile creates the file at abs (inside brainDir) through the
// brain root and fails if anything is already there.
func createBrainFile(brainDir, abs string, data []byte) error {
rel, err := filepath.Rel(brainDir, abs)
if err != nil {
return "", err
return err
}
rel = filepath.ToSlash(rel)
bfs, err := brainfs.Open(brainDir)
if err != nil {
return "", fmt.Errorf("open brain: %w", err)
return fmt.Errorf("open brain: %w", err)
}
defer func() { _ = bfs.Close() }()
return rel, bfs.PutRegular(rel, data)
return bfs.CreateRegular(filepath.ToSlash(rel), data)
}
// removeBrainFile removes the file at abs (inside brainDir) through the