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:
ZacharyZhang-NY committed 2026-07-21 19:02:57 -04:00
1 parent dd72793cdb
commit eb41b991bf
70 files changed
+8182 -358

No files matched your search

@@ -0,0 +1,122 @@
package plugins
import (
"errors"
"fmt"
"os"
"path/filepath"
)
func recoverInitializingDurableTransaction(journal *durableJournal) error {
if journal.Phase != durablePhaseInitializing {
return nil
}
verifiedWorkspaces := make(map[string]bool, len(journal.Workspaces))
for index := range journal.Workspaces {
workspace := &journal.Workspaces[index]
if workspace.DirectoryID == "" {
if err := cleanupUnpersistedDurableWorkspace(workspace.Path); err != nil {
return err
}
continue
}
if err := verifyPersistedDurableWorkspace(journal, workspace); err != nil {
return err
}
if err := cleanupInterruptedCapabilityProbe(workspace.Path); err != nil {
return fmt.Errorf("clean interrupted transaction capability probe: %w", err)
}
verifiedWorkspaces[durablePathKey(workspace.Path)] = true
}
for index := range journal.Entries {
entry := &journal.Entries[index]
if entry.NextPath == "" || entry.Next.Identity != "" {
continue
}
current, err := readDurableArtifact(entry.NextPath, "unpersisted staged "+entry.Label)
if err != nil || current == nil {
if err != nil {
return err
}
continue
}
if !verifiedWorkspaces[durablePathKey(entry.Workspace)] {
return fmt.Errorf(
"unpersisted staged transaction artifact preserved at %s",
entry.NextPath,
)
}
if err := removePhysicalOwnedFile(entry.NextPath, current.identity); err != nil {
return err
}
if err := syncTransactionDirectory(entry.Workspace); err != nil {
return err
}
}
return nil
}
func cleanupUnpersistedDurableWorkspace(path string) error {
info, err := os.Lstat(path)
if errors.Is(err, os.ErrNotExist) {
return nil
}
if err != nil || info.Mode()&os.ModeSymlink != 0 || !info.IsDir() {
return errors.Join(fmt.Errorf("unpersisted transaction workspace changed: %s", path), err)
}
if err := verifyPrivateTransactionDirectory(path); err != nil {
return err
}
directoryID, err := transactionDirectoryIdentity(path)
if err != nil {
return err
}
entries, err := os.ReadDir(path)
if err != nil {
return err
}
if len(entries) > 1 || len(entries) == 1 && entries[0].Name() != "owner" {
return fmt.Errorf("unexpected object in unpersisted transaction workspace: %s", path)
}
if len(entries) == 1 {
ownerPath := filepath.Join(path, "owner")
owner, err := readManagedFile(ownerPath, "unpersisted workspace owner", maxDurableJournalBytes)
if err != nil || owner == nil {
return errors.Join(fmt.Errorf("unpersisted workspace owner changed: %s", ownerPath), err)
}
if err := removePhysicalOwnedFile(ownerPath, owner.identity); err != nil {
return err
}
}
latestID, err := transactionDirectoryIdentity(path)
if err != nil || latestID != directoryID {
return errors.Join(fmt.Errorf("unpersisted transaction workspace changed: %s", path), err)
}
if err := os.Remove(path); err != nil {
return fmt.Errorf("remove unpersisted transaction workspace %s: %w", path, err)
}
return syncTransactionDirectory(filepath.Dir(path))
}
func verifyPersistedDurableWorkspace(
journal *durableJournal,
workspace *durableWorkspace,
) error {
if err := verifyPrivateTransactionDirectory(workspace.Path); err != nil {
return err
}
directoryID, err := transactionDirectoryIdentity(workspace.Path)
if err != nil || directoryID != workspace.DirectoryID {
return errors.Join(fmt.Errorf("transaction workspace identity changed: %s", workspace.Path), err)
}
marker, err := readManagedFile(
workspace.MarkerPath,
"transaction workspace owner",
maxDurableJournalBytes,
)
wantMarker := journal.ID + ":" + workspace.OwnerToken + "\n"
if err != nil || marker == nil || string(marker.contents) != wantMarker {
return errors.Join(fmt.Errorf("transaction workspace owner changed: %s", workspace.Path), err)
}
return nil
}