Files
Elydora-Go-SDK/cmd/elydora/plugins/transaction_atomic_linux.go
T
ZacharyZhang-NY eb41b991bf feat(go): durable transaction engine and Kiro IDE 1.0 adapter
Split the monolithic transaction into focused modules: append-only
crash-recoverable journal under ~/.elydora/transactions with owner
tokens and per-transaction namespaces, staged atomic publication
(stage .pending, fsync, rename, fsync), platform-specific atomic
replacement (MoveFileEx, renameat2, renamex_np), private-directory
hardening per OS, lock-guarded recovery, and workspace cleanup that
removes only transaction-created empty directories.

Add the Kiro IDE 1.0 plugin: strict v1 hook schema with one enabled
PreToolUse guard and PostToolUse audit pair bound to the active
workspace, agent-to-workspace identity binding in runtime config, and
exact migration of the legacy elydora-audit.kiro.hook contract.

Gates: go test ./... and -race pass, go vet clean, govulncheck reports
zero reachable vulnerabilities, git diff --check clean.
2026-07-21 19:02:57 -04:00

61 lines
1.1 KiB
Go

//go:build linux
package plugins
import (
"errors"
"fmt"
"os"
"golang.org/x/sys/unix"
)
func atomicRenameNoReplace(source, destination string) error {
if err := unix.Renameat2(
unix.AT_FDCWD,
source,
unix.AT_FDCWD,
destination,
unix.RENAME_NOREPLACE,
); err != nil {
return err
}
return syncAtomicRenameDirectories(source, destination)
}
func isAtomicDestinationExists(err error) bool {
return errors.Is(err, unix.EEXIST)
}
func atomicReplaceWithBackup(target, replacement, backup string) error {
if replacement != backup {
return fmt.Errorf("Linux atomic exchange requires the replacement to retain the backup")
}
if err := unix.Renameat2(
unix.AT_FDCWD,
target,
unix.AT_FDCWD,
replacement,
unix.RENAME_EXCHANGE,
); err != nil {
return err
}
return syncAtomicRenameDirectories(target, replacement)
}
func atomicReplacementUsesSeparateBackup() bool {
return false
}
func transactionPlatformSupported() error {
return nil
}
func syncTransactionDirectory(path string) error {
directory, err := os.Open(path)
if err != nil {
return err
}
return errors.Join(directory.Sync(), directory.Close())
}