EF UserTasks History scope omits CompletedBy (InMemory/VNext OR events)
Problem
UserTaskQueryScopeKind.History visibility diverges across providers. InMemory and VNext treat a terminal task as History-visible when the subject is CompletedBy OR appears as an event actor. EF only correlates UserTaskEvents actor columns and never consults CompletedBy / CompletionActorJson.
That breaks parity with the access policy’s completer rule (DefaultUserTaskAccessPolicy authorizes ReadSummary via isCompleter || acted) and can hide a completer’s terminal task from History on EF hosts when CompletedBy is set but no matching event actor row exists (incomplete event write, import/recon path, or actor-null system events).
Evidence
- InMemory:
src/modules/Elsa.UserTasks/Repositories/InMemoryUserTaskRepository.cs—IsVisibleHistory branch:CompletedBy?.Matches(subject) || Events.Any(actor.Matches) - VNext:
src/modules/Elsa.UserTasks.Persistence.VNext/Repositories/VNextUserTaskRepository.cs— same OR - EF:
src/modules/Elsa.UserTasks.Persistence.EFCore/Repositories/EFCoreUserTaskRepository.cs—BuildQueryHistory branch filters terminal status +UserTaskEventsActorProvider/Type/Id only - EF stores completer as
UserTaskRecord.CompletionActorJson(PersistenceModels.cs) and maps it toUserTask.CompletedByon load, but History never predicates on it - Manager Complete/Cancel normally write both
CompletedByand an actor event (DefaultUserTaskManager), so the gap is often masked — still a store-contract divergence - Conformance (
UserTaskRepositoryConformanceTests) has no History / CompletedBy visibility case
Proposal
- Align EF History with InMemory/VNext: terminal + (
CompletedBymatches subject OR event actor matches). Prefer denormalized completer provider/type/id columns (mirror Assignee*) if JSON predicates are undesirable; smallest correct query wins. - Add conformance: project a terminal task with
CompletedBy = aliceand no matching event actor; History for alice returns the task on InMemory, Sqlite EF, and VNext. Optionally assert event-actor-only path still works.
Notes for triage
Milestone left unset for Elsa 3 Issue Triage / Elsa 3 Crew Lead. Soft proposal: 3.9 Backlog — Triage/Crew Lead decide (UserTasks query parity leftover after #8109/#8110/#8111).
Source: elsa-workflows/elsa-core