package api import ( "fmt" "path/filepath" "github.com/mathiasbq/hyperguild/ingestion/internal/brainfs" "github.com/mathiasbq/hyperguild/ingestion/internal/provenance" ) // StampProvenance applies server-owned provenance (hyperguild#145) to note // content. See package provenance for the rule; an error means the stamped // note would not read back as stamped, and the write must be refused. func StampProvenance(content, origin, writtenBy string) (string, error) { return provenance.Apply(content, provenance.Stamp{Origin: origin, WrittenBy: writtenBy}) } // StampProvenanceFile applies StampProvenance to a brain-relative note path, // read and rewritten through the brain root (hyperguild#158). func StampProvenanceFile(brainDir, relPath, origin, writtenBy string) error { rel, _, err := resolveWithin(brainDir, relPath) if err != nil { return err } bfs, err := brainfs.Open(brainDir) if err != nil { return fmt.Errorf("open brain: %w", err) } defer func() { _ = bfs.Close() }() b, err := bfs.ReadRegular(rel) if err != nil { return fmt.Errorf("read for provenance: %w", err) } out, err := provenance.Apply(string(b), provenance.Stamp{Origin: origin, WrittenBy: writtenBy}) if err != nil { return err } if out == string(b) { return nil } if err := bfs.WriteRegular(rel, []byte(out)); err != nil { return fmt.Errorf("write provenance: %w", err) } return nil } // 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 } bfs, err := brainfs.Open(brainDir) if err != nil { return fmt.Errorf("open brain: %w", err) } defer func() { _ = bfs.Close() }() return bfs.CreateRegular(filepath.ToSlash(rel), data) } // removeBrainFile removes the file at abs (inside brainDir) through the // brain root. func removeBrainFile(brainDir, abs string) error { rel, err := filepath.Rel(brainDir, abs) if err != nil { return err } bfs, err := brainfs.Open(brainDir) if err != nil { return fmt.Errorf("open brain: %w", err) } defer func() { _ = bfs.Close() }() return bfs.Remove(filepath.ToSlash(rel)) }