package projectlog import ( "context" "errors" "path/filepath" "strings" "testing" "time" "iop/packages/go/agentstate" "iop/packages/go/agenttask" ) type sinkTestHarness struct { manager *agentstate.Store store *Store sink *Sink project agenttask.ProjectRecord } type replayFailingEvidenceResolver struct { evidence EventEvidence calls int } func (r *replayFailingEvidenceResolver) ResolveEventEvidence( _ context.Context, _ agenttask.Event, ) (EventEvidence, error) { r.calls++ if r.calls > 1 { return EventEvidence{}, errors.New("resolver must not be called for stable replay") } return r.evidence, nil } func newSinkTestHarness( t *testing.T, projectID agenttask.ProjectID, workspaceID agenttask.WorkspaceID, ) *sinkTestHarness { t.Helper() root := t.TempDir() manager, err := agentstate.NewStore(filepath.Join(root, "manager-state.json")) if err != nil { t.Fatalf("agentstate.NewStore manager: %v", err) } journalState, err := agentstate.NewStore(filepath.Join(root, "projectlog-state.json")) if err != nil { t.Fatalf("agentstate.NewStore projectlog: %v", err) } store, err := NewStore(journalState, filepath.Join(root, "archives"), projectID, workspaceID) if err != nil { t.Fatalf("NewStore: %v", err) } resolver, err := NewStateStoreEvidenceResolver(manager) if err != nil { t.Fatalf("NewStateStoreEvidenceResolver: %v", err) } sink, err := NewSink(store, resolver) if err != nil { t.Fatalf("NewSink: %v", err) } return &sinkTestHarness{ manager: manager, store: store, sink: sink, project: agenttask.ProjectRecord{ ProjectID: projectID, WorkspaceID: workspaceID, Status: agenttask.ProjectStatusRunning, Intent: &agenttask.StartIntent{ CommandID: "cmd-001", ProjectID: projectID, WorkspaceID: workspaceID, MilestoneID: "milestone-001", WorkflowRevision: "workflow-rev-1", ConfigRevision: "config-rev-1", GrantRevision: "grant-rev-1", StartedAt: time.Date(2026, 7, 30, 9, 0, 0, 0, time.UTC), }, Works: make(map[agenttask.WorkUnitID]agenttask.WorkRecord), }, } } func (h *sinkTestHarness) putWork(t *testing.T, work agenttask.WorkRecord) agenttask.StateRevision { t.Helper() h.project.Works[work.Unit.ID] = work state, revision, err := h.manager.Load(context.Background()) if err != nil { t.Fatalf("manager Load: %v", err) } if state.Projects == nil { state.Projects = make(map[agenttask.ProjectID]agenttask.ProjectRecord) } state.Projects[h.project.ProjectID] = h.project next, err := h.manager.CompareAndSwap(context.Background(), revision, state) if err != nil { t.Fatalf("manager CompareAndSwap: %v", err) } return next } func sinkTestWork( projectID agenttask.ProjectID, workspaceID agenttask.WorkspaceID, workUnitID agenttask.WorkUnitID, attempt uint32, state agenttask.WorkState, ) agenttask.WorkRecord { attemptID := agenttask.AttemptID("attempt-" + string(rune('0'+attempt))) return agenttask.WorkRecord{ Unit: agenttask.WorkUnit{ ID: workUnitID, MilestoneID: "milestone-001", WriteSetKind: agenttask.WriteSetDisjoint, IsolationMode: "overlay", }, State: state, Attempt: attempt, AttemptID: attemptID, DispatchOrdinal: 17, Target: &agenttask.ExecutionTarget{ ProviderID: "provider-exact", ModelID: "model-exact", ProfileID: "profile-exact", ProfileRevision: "profile-rev-exact", ConfigRevision: "config-rev-exact", Capacity: 2, }, Locators: map[agenttask.LocatorKind]agenttask.LocatorRecord{ agenttask.LocatorSession: { Kind: agenttask.LocatorSession, Opaque: "session-exact", Revision: "session-rev-exact", ProjectID: projectID, WorkspaceID: workspaceID, WorkUnitID: workUnitID, AttemptID: attemptID, }, agenttask.LocatorProcess: { Kind: agenttask.LocatorProcess, Opaque: "process-exact", Revision: "process-rev-exact", ProjectID: projectID, WorkspaceID: workspaceID, WorkUnitID: workUnitID, AttemptID: attemptID, }, }, } } func TestSinkMapsEveryEventType(t *testing.T) { ctx := context.Background() harness := newSinkTestHarness(t, "proj-sink-1", "ws-sink-1") work := sinkTestWork( harness.project.ProjectID, harness.project.WorkspaceID, "work-001", 1, agenttask.WorkStateReviewing, ) harness.putWork(t, work) eventTypes := []agenttask.EventType{ agenttask.EventObserved, agenttask.EventManualStart, agenttask.EventAutoResume, agenttask.EventStopped, agenttask.EventDependencyReady, agenttask.EventDispatchStarted, agenttask.EventSubmissionAccepted, agenttask.EventReviewResult, agenttask.EventFollowup, agenttask.EventIntegrationResult, agenttask.EventBlocked, agenttask.EventCompleted, } now := time.Date(2026, 7, 30, 10, 0, 0, 0, time.UTC) for index, eventType := range eventTypes { event := agenttask.Event{ EventID: "event-" + string(rune('a'+index)), Type: eventType, ProjectID: harness.project.ProjectID, WorkspaceID: harness.project.WorkspaceID, WorkUnitID: work.Unit.ID, CommandID: harness.project.Intent.CommandID, Timestamp: now.Add(time.Duration(index) * time.Minute), } if err := harness.sink.Emit(ctx, event); err != nil { t.Fatalf("Emit %s: %v", eventType, err) } } scoped, err := harness.store.ForWorkUnit(work.Unit.ID) if err != nil { t.Fatalf("ForWorkUnit: %v", err) } records, err := scoped.ReplayRecords(ctx) if err != nil { t.Fatalf("ReplayRecords: %v", err) } if len(records) != len(eventTypes) { t.Fatalf("record count = %d, want %d", len(records), len(eventTypes)) } for index, record := range records { if record.EventType != eventTypes[index] { t.Fatalf("record %d type = %s, want %s", index, record.EventType, eventTypes[index]) } if record.State != agenttask.WorkStateReviewing { t.Fatalf("record %d inferred state %q", index, record.State) } if record.DispatchOrdinal != work.DispatchOrdinal || record.LoopOrdinal != uint64(work.Attempt) { t.Fatalf("record %d lost exact ordinal evidence: %+v", index, record) } } } func TestSinkResolvesExactDurableEvidence(t *testing.T) { ctx := context.Background() harness := newSinkTestHarness(t, "proj-exact", "ws-exact") work := sinkTestWork( harness.project.ProjectID, harness.project.WorkspaceID, "work-exact", 3, agenttask.WorkStateTerminalDeferred, ) work.ChangeSet = &agenttask.ChangeSetIdentity{ ID: "change-exact", Revision: "change-rev-exact", ArtifactID: "artifact-exact", } work.IntegrationAttempt = 4 work.Integration = &agenttask.IntegrationResult{ ProjectID: harness.project.ProjectID, WorkUnitID: work.Unit.ID, ChangeSet: *work.ChangeSet, Ordinal: work.DispatchOrdinal, Attempt: 4, Outcome: agenttask.IntegrationOutcomeTerminalDeferred, Retained: true, BeforeRevision: "base-before", Blocker: &agenttask.Blocker{ Code: agenttask.BlockerIntegrationFailed, Message: "safe integration failure", }, } work.Blocker = work.Integration.Blocker wantRevision := harness.putWork(t, work) event := agenttask.Event{ EventID: "manager-event-exact", Type: agenttask.EventIntegrationResult, ProjectID: harness.project.ProjectID, WorkspaceID: harness.project.WorkspaceID, WorkUnitID: work.Unit.ID, AttemptID: work.AttemptID, Ordinal: work.DispatchOrdinal, ChangeSetID: work.ChangeSet.ID, ChangeSetRevision: work.ChangeSet.Revision, IntegrationAttempt: work.IntegrationAttempt, State: work.State, ProviderID: work.Target.ProviderID, ProfileID: work.Target.ProfileID, Detail: "terminal integration evidence", Timestamp: time.Date(2026, 7, 30, 11, 0, 0, 0, time.UTC), } if err := harness.sink.Emit(ctx, event); err != nil { t.Fatalf("Emit: %v", err) } scoped, _ := harness.store.ForWorkUnit(work.Unit.ID) records, err := scoped.ReplayRecords(ctx) if err != nil || len(records) != 1 { t.Fatalf("ReplayRecords = %d, %v", len(records), err) } record := records[0] if record.StateRevision != wantRevision || record.LoopOrdinal != uint64(work.Attempt) || record.AttemptID != work.AttemptID || record.DispatchOrdinal != work.DispatchOrdinal { t.Fatalf("exact state/attempt evidence lost: %+v", record) } if record.RouteStatus == nil || record.RouteStatus.ProviderID != work.Target.ProviderID || record.RouteStatus.ModelID != work.Target.ModelID || record.RouteStatus.SelectionRevision != "" || record.RouteStatus.ReasonCode != "" { t.Fatalf("route evidence was fabricated or lost: %+v", record.RouteStatus) } if record.ChangeSetID != work.ChangeSet.ID || record.ChangeSetRevision != work.ChangeSet.Revision || record.IntegrationAttempt != work.IntegrationAttempt || record.IntegrationOutcome != work.Integration.Outcome || record.BlockerCode != work.Blocker.Code { t.Fatalf("change-set/integration evidence lost: %+v", record) } if len(record.Locators) != 2 || record.Locators[0].Kind != agenttask.LocatorProcess || record.Locators[1].Kind != agenttask.LocatorSession { t.Fatalf("locators are not exact and sorted: %+v", record.Locators) } } func TestSinkAllowsProjectEventWithoutWorkEvidence(t *testing.T) { ctx := context.Background() harness := newSinkTestHarness(t, "proj-project-event", "ws-project-event") state, revision, err := harness.manager.Load(ctx) if err != nil { t.Fatalf("manager Load: %v", err) } state.Projects = map[agenttask.ProjectID]agenttask.ProjectRecord{ harness.project.ProjectID: harness.project, } if _, err := harness.manager.CompareAndSwap(ctx, revision, state); err != nil { t.Fatalf("manager CompareAndSwap: %v", err) } event := agenttask.Event{ EventID: "project-event-manual-start", Type: agenttask.EventManualStart, ProjectID: harness.project.ProjectID, CommandID: harness.project.Intent.CommandID, Detail: "manual project start", Timestamp: time.Date(2026, 7, 30, 11, 30, 0, 0, time.UTC), } if err := harness.sink.Emit(ctx, event); err != nil { t.Fatalf("Emit project event: %v", err) } records, err := harness.store.ReplayRecords(ctx) if err != nil || len(records) != 1 { t.Fatalf("ReplayRecords = %d, %v", len(records), err) } record := records[0] if record.WorkUnitID != "" || record.AttemptID != "" || record.State != "" || record.StateRevision != "" || record.RouteStatus != nil { t.Fatalf("project event fabricated work evidence: %+v", record) } } func TestSinkRejectsEvidenceIdentityDrift(t *testing.T) { harness := newSinkTestHarness(t, "proj-drift", "ws-drift") work := sinkTestWork( harness.project.ProjectID, harness.project.WorkspaceID, "work-drift", 2, agenttask.WorkStateDispatching, ) work.ChangeSet = &agenttask.ChangeSetIdentity{ID: "change-1", Revision: "change-rev-1"} harness.putWork(t, work) base := agenttask.Event{ EventID: "event-drift", Type: agenttask.EventDispatchStarted, ProjectID: harness.project.ProjectID, WorkspaceID: harness.project.WorkspaceID, WorkUnitID: work.Unit.ID, AttemptID: work.AttemptID, Ordinal: work.DispatchOrdinal, State: work.State, ProviderID: work.Target.ProviderID, ProfileID: work.Target.ProfileID, Timestamp: time.Date(2026, 7, 30, 12, 0, 0, 0, time.UTC), } tests := []struct { name string mutate func(*agenttask.Event) }{ {"workspace", func(event *agenttask.Event) { event.WorkspaceID = "ws-other" }}, {"attempt", func(event *agenttask.Event) { event.AttemptID = "attempt-other" }}, {"dispatch", func(event *agenttask.Event) { event.Ordinal++ }}, {"state", func(event *agenttask.Event) { event.State = agenttask.WorkStateReviewing }}, {"provider", func(event *agenttask.Event) { event.ProviderID = "provider-other" }}, {"change set", func(event *agenttask.Event) { event.ChangeSetID = "change-other" event.ChangeSetRevision = "change-rev-other" }}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { event := base test.mutate(&event) err := harness.sink.Emit(context.Background(), event) if !errors.Is(err, ErrEvidenceIdentityDrift) { t.Fatalf("Emit error = %v, want ErrEvidenceIdentityDrift", err) } }) } } func TestSinkPendingDeliveryUsesExactCommittedEvidence(t *testing.T) { ctx := context.Background() harness := newSinkTestHarness(t, "proj-pending", "ws-pending") pendingWork := sinkTestWork( harness.project.ProjectID, harness.project.WorkspaceID, "work-pending", 1, agenttask.WorkStateReviewing, ) pendingWork.Review = &agenttask.ReviewResult{ ProjectID: harness.project.ProjectID, WorkUnitID: pendingWork.Unit.ID, AttemptID: pendingWork.AttemptID, ArtifactID: "artifact-pending", Verdict: agenttask.ReviewVerdictFail, Message: "committed review", Rework: true, } pendingProject := harness.project pendingProject.Works = map[agenttask.WorkUnitID]agenttask.WorkRecord{ pendingWork.Unit.ID: pendingWork, } event := agenttask.Event{ EventID: "event-pending-review", Type: agenttask.EventReviewResult, ProjectID: pendingProject.ProjectID, WorkspaceID: pendingProject.WorkspaceID, WorkUnitID: pendingWork.Unit.ID, CommandID: pendingProject.Intent.CommandID, AttemptID: pendingWork.AttemptID, Ordinal: pendingWork.DispatchOrdinal, Detail: string(agenttask.ReviewVerdictFail), Timestamp: time.Date(2026, 7, 30, 12, 30, 0, 0, time.UTC), } currentWork := sinkTestWork( harness.project.ProjectID, harness.project.WorkspaceID, pendingWork.Unit.ID, 2, agenttask.WorkStateReady, ) currentProject := harness.project currentProject.Works = map[agenttask.WorkUnitID]agenttask.WorkRecord{ currentWork.Unit.ID: currentWork, } state, revision, err := harness.manager.Load(ctx) if err != nil { t.Fatalf("manager Load: %v", err) } state.Projects = map[agenttask.ProjectID]agenttask.ProjectRecord{ currentProject.ProjectID: currentProject, } state.PendingEvents = map[string]agenttask.EventDelivery{ event.EventID: { Event: event, EvidenceRevision: "pending-state-revision-17", Project: &pendingProject, Work: &pendingWork, }, } if _, err := harness.manager.CompareAndSwap(ctx, revision, state); err != nil { t.Fatalf("manager CompareAndSwap: %v", err) } if err := harness.sink.Emit(ctx, event); err != nil { t.Fatalf("Emit pending event: %v", err) } scoped, err := harness.store.ForWorkUnit(pendingWork.Unit.ID) if err != nil { t.Fatalf("ForWorkUnit: %v", err) } records, err := scoped.ReplayRecords(ctx) if err != nil || len(records) != 1 { t.Fatalf("ReplayRecords = %d, %v", len(records), err) } record := records[0] if record.StateRevision != "pending-state-revision-17" || record.LoopOrdinal != 1 || record.AttemptID != pendingWork.AttemptID || record.State != agenttask.WorkStateReviewing || record.Result != string(agenttask.ReviewVerdictFail) { t.Fatalf("record did not use pending delivery evidence: %+v", record) } if len(record.Locators) != len(pendingWork.Locators) || record.Locators[0].AttemptID != pendingWork.AttemptID { t.Fatalf("record locators came from advanced work: %+v", record.Locators) } } func TestSinkReplayShortCircuitsEvidenceAfterClockAndStateAdvance(t *testing.T) { ctx := context.Background() root := t.TempDir() journalState, err := agentstate.NewStore(filepath.Join(root, "projectlog-state.json")) if err != nil { t.Fatalf("agentstate.NewStore: %v", err) } store, err := NewStore( journalState, filepath.Join(root, "archives"), "proj-replay", "ws-replay", ) if err != nil { t.Fatalf("NewStore: %v", err) } work := sinkTestWork("proj-replay", "ws-replay", "work-replay", 1, agenttask.WorkStateDispatching) project := agenttask.ProjectRecord{ ProjectID: "proj-replay", WorkspaceID: "ws-replay", Status: agenttask.ProjectStatusRunning, Intent: &agenttask.StartIntent{ CommandID: "cmd-replay", ProjectID: "proj-replay", WorkspaceID: "ws-replay", MilestoneID: "milestone-replay", WorkflowRevision: "workflow-replay", ConfigRevision: "config-replay", GrantRevision: "grant-replay", }, Works: map[agenttask.WorkUnitID]agenttask.WorkRecord{ work.Unit.ID: work, }, } resolver := &replayFailingEvidenceResolver{ evidence: EventEvidence{ StateRevision: "state-revision-1", Project: project, Work: &work, }, } sink, err := NewSink(store, resolver) if err != nil { t.Fatalf("NewSink: %v", err) } event := agenttask.Event{ EventID: "stable-replay-event", Type: agenttask.EventDispatchStarted, ProjectID: project.ProjectID, WorkspaceID: project.WorkspaceID, WorkUnitID: work.Unit.ID, CommandID: project.Intent.CommandID, AttemptID: work.AttemptID, Ordinal: work.DispatchOrdinal, State: work.State, ProviderID: work.Target.ProviderID, ProfileID: work.Target.ProfileID, Detail: "stable logical event", Timestamp: time.Date(2026, 7, 30, 13, 0, 0, 0, time.UTC), } if err := sink.Emit(ctx, event); err != nil { t.Fatalf("first Emit: %v", err) } event.Timestamp = event.Timestamp.Add(6 * time.Hour) resolver.evidence.StateRevision = "state-revision-999" if err := sink.Emit(ctx, event); err != nil { t.Fatalf("stable replay Emit: %v", err) } if resolver.calls != 1 { t.Fatalf("evidence resolver calls = %d, want 1", resolver.calls) } scoped, _ := store.ForWorkUnit(work.Unit.ID) records, err := scoped.ReplayRecords(ctx) if err != nil || len(records) != 1 { t.Fatalf("ReplayRecords = %d, %v", len(records), err) } } func TestSinkRejectsLogicalEventIDReuseAcrossScopesBeforeEvidenceResolution(t *testing.T) { ctx := context.Background() root := t.TempDir() journalState, err := agentstate.NewStore(filepath.Join(root, "projectlog-state.json")) if err != nil { t.Fatalf("agentstate.NewStore: %v", err) } store, err := NewStore( journalState, filepath.Join(root, "archives"), "proj-cross-scope", "ws-cross-scope", ) if err != nil { t.Fatalf("NewStore: %v", err) } work := sinkTestWork( "proj-cross-scope", "ws-cross-scope", "work-A", 1, agenttask.WorkStateDispatching, ) project := agenttask.ProjectRecord{ ProjectID: "proj-cross-scope", WorkspaceID: "ws-cross-scope", Status: agenttask.ProjectStatusRunning, Intent: &agenttask.StartIntent{ CommandID: "cmd-cross-scope", ProjectID: "proj-cross-scope", WorkspaceID: "ws-cross-scope", MilestoneID: "milestone-cross-scope", WorkflowRevision: "workflow-cross-scope", ConfigRevision: "config-cross-scope", GrantRevision: "grant-cross-scope", }, Works: map[agenttask.WorkUnitID]agenttask.WorkRecord{ work.Unit.ID: work, }, } resolver := &replayFailingEvidenceResolver{ evidence: EventEvidence{ StateRevision: "state-revision-cross-scope", Project: project, Work: &work, }, } sink, err := NewSink(store, resolver) if err != nil { t.Fatalf("NewSink: %v", err) } event := agenttask.Event{ EventID: "event-cross-scope-conflict", Type: agenttask.EventDispatchStarted, ProjectID: project.ProjectID, WorkspaceID: project.WorkspaceID, WorkUnitID: work.Unit.ID, CommandID: project.Intent.CommandID, AttemptID: work.AttemptID, Ordinal: work.DispatchOrdinal, State: work.State, ProviderID: work.Target.ProviderID, ProfileID: work.Target.ProfileID, Detail: "original work A event", Timestamp: time.Date(2026, 7, 30, 13, 30, 0, 0, time.UTC), } if err := sink.Emit(ctx, event); err != nil { t.Fatalf("first Emit: %v", err) } conflicting := event conflicting.WorkUnitID = "work-B" conflicting.AttemptID = "attempt-B" conflicting.Detail = "changed work B event" if err := sink.Emit(ctx, conflicting); !errors.Is(err, ErrRecordReplayConflict) { t.Fatalf("cross-scope Emit error = %v", err) } if resolver.calls != 1 { t.Fatalf("evidence resolver calls = %d, want 1", resolver.calls) } workA, _ := store.ForWorkUnit("work-A") workB, _ := store.ForWorkUnit("work-B") recordsA, err := workA.ReplayRecords(ctx) if err != nil || len(recordsA) != 1 { t.Fatalf("work A records = %d, %v", len(recordsA), err) } recordsB, err := workB.ReplayRecords(ctx) if err != nil || len(recordsB) != 0 { t.Fatalf("work B records = %d, %v", len(recordsB), err) } } func TestSinkUsesOpaqueStableRecordID(t *testing.T) { ctx := context.Background() harness := newSinkTestHarness(t, "proj-opaque", "ws-opaque") work := sinkTestWork( harness.project.ProjectID, harness.project.WorkspaceID, "work-opaque", 1, agenttask.WorkStateDispatching, ) harness.putWork(t, work) event := agenttask.Event{ EventID: "raw-manager-event-with-secret-detail", Type: agenttask.EventDispatchStarted, ProjectID: harness.project.ProjectID, WorkspaceID: harness.project.WorkspaceID, WorkUnitID: work.Unit.ID, AttemptID: work.AttemptID, Ordinal: work.DispatchOrdinal, Detail: "Authorization: Bearer secret-value", Timestamp: time.Date(2026, 7, 30, 13, 0, 0, 0, time.UTC), } if err := harness.sink.Emit(ctx, event); err != nil { t.Fatalf("first Emit: %v", err) } if err := harness.sink.Emit(ctx, event); err != nil { t.Fatalf("replayed Emit: %v", err) } scoped, _ := harness.store.ForWorkUnit(work.Unit.ID) records, err := scoped.ReplayRecords(ctx) if err != nil || len(records) != 1 { t.Fatalf("ReplayRecords = %d, %v", len(records), err) } record := records[0] if !strings.HasPrefix(record.RecordID, "evt-sha256-") || len(record.RecordID) != len("evt-sha256-")+64 { t.Fatalf("RecordID is not a bounded SHA-256 identity: %q", record.RecordID) } if strings.Contains(record.RecordID, event.EventID) || strings.Contains(record.RecordID, "secret") || record.Message != "[REDACTED]" { t.Fatalf("raw event evidence leaked: %+v", record) } } func TestSinkRejectsMissingEventID(t *testing.T) { harness := newSinkTestHarness(t, "proj-missing", "ws-missing") work := sinkTestWork( harness.project.ProjectID, harness.project.WorkspaceID, "work-missing", 1, agenttask.WorkStateDispatching, ) harness.putWork(t, work) err := harness.sink.Emit(context.Background(), agenttask.Event{ Type: agenttask.EventDispatchStarted, ProjectID: harness.project.ProjectID, WorkspaceID: harness.project.WorkspaceID, WorkUnitID: work.Unit.ID, Timestamp: time.Date(2026, 7, 30, 14, 0, 0, 0, time.UTC), }) if !errors.Is(err, ErrMissingEventID) { t.Fatalf("Emit error = %v, want ErrMissingEventID", err) } } func TestTimelineProjectionIsStableAndRedacted(t *testing.T) { ctx := context.Background() harness := newSinkTestHarness(t, "proj-timeline", "ws-timeline") work := sinkTestWork( harness.project.ProjectID, harness.project.WorkspaceID, "work-timeline", 1, agenttask.WorkStateDispatching, ) harness.putWork(t, work) now := time.Date(2026, 7, 30, 15, 0, 0, 0, time.UTC) sensitive := agenttask.Event{ EventID: "timeline-sensitive", Type: agenttask.EventDispatchStarted, ProjectID: harness.project.ProjectID, WorkspaceID: harness.project.WorkspaceID, WorkUnitID: work.Unit.ID, AttemptID: work.AttemptID, Ordinal: work.DispatchOrdinal, Detail: "Dispatching with token sk-secret12345678", Timestamp: now, } if err := harness.sink.Emit(ctx, sensitive); err != nil { t.Fatalf("Emit sensitive event: %v", err) } work.State = agenttask.WorkStateCompleted work.Integration = &agenttask.IntegrationResult{ ProjectID: harness.project.ProjectID, WorkUnitID: work.Unit.ID, ChangeSet: agenttask.ChangeSetIdentity{ ID: "change-timeline", Revision: "change-timeline-rev", }, Ordinal: work.DispatchOrdinal, Attempt: 1, Outcome: agenttask.IntegrationOutcomeIntegrated, } work.ChangeSet = &work.Integration.ChangeSet work.IntegrationAttempt = 1 harness.putWork(t, work) completed := agenttask.Event{ EventID: "timeline-completed", Type: agenttask.EventCompleted, ProjectID: harness.project.ProjectID, WorkspaceID: harness.project.WorkspaceID, WorkUnitID: work.Unit.ID, AttemptID: work.AttemptID, Ordinal: work.DispatchOrdinal, State: work.State, Detail: "Task completed successfully", Timestamp: now.Add(time.Minute), } if err := harness.sink.Emit(ctx, completed); err != nil { t.Fatalf("Emit completed event: %v", err) } scoped, _ := harness.store.ForWorkUnit(work.Unit.ID) records, err := scoped.ReplayRecords(ctx) if err != nil { t.Fatalf("ReplayRecords: %v", err) } projection := ProjectWorkLog(records) if len(projection.Entries) != 2 { t.Fatalf("projection entry count = %d, want 2", len(projection.Entries)) } if projection.Entries[0].Message != "[REDACTED]" || projection.Entries[0].RoleStage != "dispatch" || len(projection.Entries[0].Locators) != 2 { t.Fatalf("first projection entry = %+v", projection.Entries[0]) } if projection.Entries[1].Message != "Task completed successfully" || !projection.Entries[1].Terminal || projection.Entries[1].Result != string(agenttask.IntegrationOutcomeIntegrated) { t.Fatalf("terminal projection entry = %+v", projection.Entries[1]) } }