diff --git a/.core/TODO.md b/.core/TODO.md index 91aef5e..e69de29 100644 --- a/.core/TODO.md +++ b/.core/TODO.md @@ -1 +0,0 @@ -- @harden pkg/agentic/sync.go:563 — corrupt report.json is dropped silently when dispatch metadata is malformed. diff --git a/pkg/agentic/sync.go b/pkg/agentic/sync.go index af3e971..5d6e93f 100644 --- a/pkg/agentic/sync.go +++ b/pkg/agentic/sync.go @@ -570,6 +570,11 @@ func readSyncWorkspaceReport(workspaceDir string) map[string]any { var report map[string]any parseResult := core.JSONUnmarshalString(result.Value.(string), &report) if !parseResult.OK { + backupPath := core.Concat(reportPath, ".corrupt-", time.Now().UTC().Format("20060102T150405Z")) + core.Warn("agentic: corrupt dispatch report", "path", reportPath, "backup", backupPath, "reason", parseResult.Value) + if renameResult := fs.Rename(reportPath, backupPath); !renameResult.OK { + core.Warn("agentic: failed to preserve corrupt dispatch report", "path", reportPath, "backup", backupPath, "reason", renameResult.Value) + } return nil } diff --git a/pkg/agentic/sync_test.go b/pkg/agentic/sync_test.go index 976cfda..148dc02 100644 --- a/pkg/agentic/sync_test.go +++ b/pkg/agentic/sync_test.go @@ -367,6 +367,26 @@ func TestSync_HandleSyncPush_Good_ReportMetadata(t *testing.T) { assert.Equal(t, 1, output.Count) } +func TestSync_ReadSyncWorkspaceReport_Ugly_CorruptJSONPreservesArtifact(t *testing.T) { + root := t.TempDir() + setTestWorkspace(t, root) + + workspaceDir := core.JoinPath(root, "workspace", "core", "go-io", "task-5") + metaDir := WorkspaceMetaDir(workspaceDir) + require.True(t, fs.EnsureDir(metaDir).OK) + + reportPath := core.JoinPath(metaDir, "report.json") + require.True(t, fs.Write(reportPath, `{"findings":[{"file":"main.go"}],"changes":`).OK) + + report := readSyncWorkspaceReport(workspaceDir) + require.Nil(t, report) + assert.False(t, fs.Exists(reportPath)) + + entries := listDirNames(fs.List(metaDir)) + require.Len(t, entries, 1) + assert.True(t, core.HasPrefix(entries[0], "report.json.corrupt-")) +} + func TestSync_HandleSyncPull_Good_NestedEnvelope(t *testing.T) { root := t.TempDir() setTestWorkspace(t, root)