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.
This commit is contained in:
1 parent
dd72793cdb
commit
eb41b991bf
70 files changed
+8182
-358
No files matched your search
@@ -0,0 +1,57 @@
|
||||
package plugins
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
type durableTransactionLock struct {
|
||||
file *os.File
|
||||
path string
|
||||
}
|
||||
|
||||
func acquireDurableTransactionLock(root string) (*durableTransactionLock, error) {
|
||||
path := root + string(os.PathSeparator) + "lock"
|
||||
file, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR, 0600)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("open transaction lock at %s: %w", path, err)
|
||||
}
|
||||
fail := func(cause error) (*durableTransactionLock, error) {
|
||||
return nil, errors.Join(cause, file.Close())
|
||||
}
|
||||
opened, err := file.Stat()
|
||||
if err != nil {
|
||||
return fail(fmt.Errorf("inspect open transaction lock at %s: %w", path, err))
|
||||
}
|
||||
current, err := os.Lstat(path)
|
||||
if err != nil {
|
||||
return fail(fmt.Errorf("inspect transaction lock at %s: %w", path, err))
|
||||
}
|
||||
if current.Mode()&os.ModeSymlink != 0 || !current.Mode().IsRegular() ||
|
||||
!os.SameFile(opened, current) {
|
||||
return fail(fmt.Errorf("transaction lock is not a stable physical file: %s", path))
|
||||
}
|
||||
if err := lockTransactionFile(file); err != nil {
|
||||
return fail(fmt.Errorf("lock transactions at %s: %w", path, err))
|
||||
}
|
||||
current, err = os.Lstat(path)
|
||||
if err != nil || current.Mode()&os.ModeSymlink != 0 ||
|
||||
!current.Mode().IsRegular() || !os.SameFile(opened, current) {
|
||||
return fail(errors.Join(
|
||||
fmt.Errorf("transaction lock changed while acquiring: %s", path),
|
||||
err,
|
||||
unlockTransactionFile(file),
|
||||
))
|
||||
}
|
||||
return &durableTransactionLock{file: file, path: path}, nil
|
||||
}
|
||||
|
||||
func (lock *durableTransactionLock) close() error {
|
||||
if lock == nil || lock.file == nil {
|
||||
return nil
|
||||
}
|
||||
file := lock.file
|
||||
lock.file = nil
|
||||
return errors.Join(unlockTransactionFile(file), file.Close())
|
||||
}
|
||||
Reference in new issue
Block a user