fix(agentcompat): retain transfer sentinel handles

Co-authored-by: naiba/CloudCode <hi+cloudcode@nai.ba>
This commit is contained in:
naiba
2026-07-20 17:05:52 +00:00
co-authored by naiba/CloudCode
parent 393f49aa59
commit 153dfeb569
2 changed files with 23 additions and 12 deletions
@@ -97,6 +97,7 @@ func (Transfer) RunWithEvidence(ctx context.Context, input TransferInput) (resul
result, runErr = transferFinish(assertions, err) result, runErr = transferFinish(assertions, err)
return result, transferEvidence, runErr return result, transferEvidence, runErr
} }
defer sentinels.close()
execution := transferExecution{ execution := transferExecution{
client: dashboardInstance.Clients().MCP, client: dashboardInstance.Clients().MCP,
serverID: serverID, serverID: serverID,
@@ -15,23 +15,31 @@ import (
var transferSentinelContent = []byte("outside-transfer-root-sentinel") var transferSentinelContent = []byte("outside-transfer-root-sentinel")
type transferSentinels struct { type transferSentinels struct {
paths []string root *os.Root
names []string
} }
func newTransferSentinels(root fixture.AgentRoot, workspaceRoot string) (transferSentinels, error) { func newTransferSentinels(root fixture.AgentRoot, workspaceRoot string) (result transferSentinels, err error) {
directPath := filepath.Join(workspaceRoot, "outside-transfer-sentinel") workspace, err := os.OpenRoot(workspaceRoot)
symlinkDirectory := filepath.Join(workspaceRoot, "outside-transfer-directory") if err != nil {
symlinkTarget := filepath.Join(symlinkDirectory, "target-sentinel") return transferSentinels{}, fmt.Errorf("open transfer sentinel root: %w", err)
if err := os.Mkdir(symlinkDirectory, 0o700); err != nil { }
defer func() {
if err != nil {
err = errors.Join(err, workspace.Close())
}
}()
result = transferSentinels{root: workspace, names: []string{"outside-transfer-sentinel", "outside-transfer-directory/target-sentinel"}}
if err := workspace.Mkdir("outside-transfer-directory", 0o700); err != nil {
return transferSentinels{}, fmt.Errorf("create transfer sentinel directory: %w", err) return transferSentinels{}, fmt.Errorf("create transfer sentinel directory: %w", err)
} }
for _, path := range []string{directPath, symlinkTarget} { for _, name := range result.names {
if err := os.WriteFile(path, transferSentinelContent, 0o600); err != nil { if err := workspace.WriteFile(name, transferSentinelContent, 0o600); err != nil {
return transferSentinels{}, fmt.Errorf("write transfer sentinel: %w", err) return transferSentinels{}, fmt.Errorf("write transfer sentinel: %w", err)
} }
} }
symlinkPath := filepath.Join(root.Absolute(), "linked") symlinkPath := filepath.Join(root.Absolute(), "linked")
if err := os.Symlink(symlinkDirectory, symlinkPath); err != nil { if err := os.Symlink(filepath.Join(workspaceRoot, "outside-transfer-directory"), symlinkPath); err != nil {
return transferSentinels{}, fmt.Errorf("create transfer sentinel symlink: %w", err) return transferSentinels{}, fmt.Errorf("create transfer sentinel symlink: %w", err)
} }
if _, err := root.Path("../outside-transfer-sentinel"); err == nil { if _, err := root.Path("../outside-transfer-sentinel"); err == nil {
@@ -40,12 +48,12 @@ func newTransferSentinels(root fixture.AgentRoot, workspaceRoot string) (transfe
if _, err := root.Path("linked/target-sentinel"); err == nil { if _, err := root.Path("linked/target-sentinel"); err == nil {
return transferSentinels{}, errors.New("transfer AgentPath accepted symlink parent") return transferSentinels{}, errors.New("transfer AgentPath accepted symlink parent")
} }
return transferSentinels{paths: []string{directPath, symlinkTarget}}, nil return result, nil
} }
func (sentinels transferSentinels) unchanged() (bool, error) { func (sentinels transferSentinels) unchanged() (bool, error) {
for _, path := range sentinels.paths { for _, name := range sentinels.names {
content, err := os.ReadFile(path) content, err := sentinels.root.ReadFile(name)
if err != nil { if err != nil {
return false, fmt.Errorf("read transfer sentinel: %w", err) return false, fmt.Errorf("read transfer sentinel: %w", err)
} }
@@ -55,3 +63,5 @@ func (sentinels transferSentinels) unchanged() (bool, error) {
} }
return true, nil return true, nil
} }
func (sentinels transferSentinels) close() error { return sentinels.root.Close() }