package workflow import ( "os" "path/filepath" "testing" "codex-agent-manager/internal/runtime" ) func TestStoreBuildsDynamicEventsWithoutFixedRoles(t *testing.T) { root := t.TempDir() if err := os.WriteFile(filepath.Join(root, "task_plan.md"), []byte("| 3 | in_progress | Runtime model |\n"), 0o644); err != nil { t.Fatal(err) } snapshot := runtime.Snapshot{ Threads: []runtime.Thread{ {ID: "thread-a", Role: "cartographer", Status: "done", CreatedAt: "2026-05-25T01:00:00Z"}, {ID: "thread-b", Role: "navigator", Status: "running", CreatedAt: "2026-05-25T01:02:00Z"}, }, SpawnEdges: []runtime.SpawnEdge{ {FromThreadID: "thread-a", ToThreadID: "thread-b", Reason: "map complete", CreatedAt: "2026-05-25T01:02:00Z"}, }, Goals: []runtime.Goal{ {ThreadID: "thread-b", Goal: "verify route", Status: "blocked", UpdatedAt: "2026-05-25T01:03:00Z"}, }, Source: runtime.SourceEvidence{Kind: "test", Confidence: "high", Path: "memory"}, } view, err := Store{WorkspaceRoot: root, Runtime: StaticRuntime{SnapshotValue: snapshot}}.View() if err != nil { t.Fatalf("View returned error: %v", err) } if len(view.Events) != 5 { t.Fatalf("events = %#v", view.Events) } assertHasEvent(t, view.Events, "thread", "cartographer") assertHasEvent(t, view.Events, "handoff", "map complete") assertHasEvent(t, view.Events, "goal", "blocked") assertHasEvent(t, view.Events, "plan_file", "task_plan.md") if len(view.HandoffEdges) != 1 || view.HandoffEdges[0].FromThreadID != "thread-a" || view.HandoffEdges[0].ToThreadID != "thread-b" { t.Fatalf("unexpected handoff edges: %#v", view.HandoffEdges) } if len(view.Phases) != 1 || view.Phases[0].Name != "3" || view.Phases[0].Status != "in_progress" || view.Phases[0].Source.Confidence != "medium" { t.Fatalf("unexpected phases: %#v", view.Phases) } } func TestStoreNilRuntimeReturnsEmptyLowConfidenceView(t *testing.T) { view, err := Store{WorkspaceRoot: t.TempDir()}.View() if err != nil { t.Fatalf("View returned error: %v", err) } if len(view.Events) != 0 || len(view.HandoffEdges) != 0 || len(view.Phases) != 0 { t.Fatalf("expected empty view, got %#v", view) } if view.Source.Kind != "runtime_missing" || view.Source.Confidence != "low" { t.Fatalf("unexpected source: %#v", view.Source) } } type StaticRuntime struct { SnapshotValue runtime.Snapshot } func (s StaticRuntime) Snapshot() (runtime.Snapshot, error) { return s.SnapshotValue, nil } func assertHasEvent(t *testing.T, events []Event, kind string, contains string) { t.Helper() for _, event := range events { if event.Kind == kind && event.Label == contains { return } } t.Fatalf("missing event kind=%q label=%q in %#v", kind, contains, events) }