human_brief
问题标题:Workflow 绑定查询把运行时对象形态当成业务事实
问题说明:当前查询 reader 表面上是在读取 workflow binding readmodel,但读取后又继续询问 actor runtime:这个 actor 当前是否存在、是否符合某个具体 GAgent 类型。这会让查询结果依赖当前节点的 runtime 可见性,而不是已经提交并物化的 workflow 事实。
单机环境下它可能表现正常;但在分布式、重启、投影延迟或 runtime 实现替换时,同一个 readmodel 可能因为本地 runtime 形态不同而返回不同结果。开发者需要关注它,因为 workflow run / resume / query 的稳定性会被隐藏地绑定到运行时实现细节上。
示例位置:src/workflow/Aevatar.Workflow.Projection/Orchestration/ProjectionWorkflowActorBindingReader.cs:17-30
public ProjectionWorkflowActorBindingReader(
IProjectionDocumentReader<WorkflowActorBindingDocument, string> documentStore,
IActorRuntime runtime, // problem: 查询 reader 直接依赖 runtime 形态
IAgentTypeVerifier agentTypeVerifier) // problem: 用本地类型探测决定业务绑定类型
{
ArgumentNullException.ThrowIfNull(documentStore);
ArgumentNullException.ThrowIfNull(runtime);
ArgumentNullException.ThrowIfNull(agentTypeVerifier);
_getDocumentAsync = (actorId, ct) => documentStore.GetAsync(actorId, ct);
_queryDocumentsAsync = documentStore.QueryAsync;
_existsAsync = runtime.ExistsAsync; // problem: 查询结果依赖 actor 当前是否被 runtime 看见
_isExpectedAsync = agentTypeVerifier.IsExpectedAsync; // problem: 用实现类型形态判断业务 kind
}
为什么需要设计:修复不是简单删几行,因为当前 reader 同时承担“读已物化 binding”和“兜底判断未绑定 actor 类型”的职责。需要 maintainer 决定:未物化 binding 时是返回 unknown / not found,还是新增 actor-owned binding/status committed fact 来覆盖这个语义。这会影响 workflow run 创建、resume/signal target resolve,以及已有 actor 的兼容查询行为。
Evidence
src/workflow/Aevatar.Workflow.Projection/Orchestration/ProjectionWorkflowActorBindingReader.cs:19 注入 IActorRuntime。
src/workflow/Aevatar.Workflow.Projection/Orchestration/ProjectionWorkflowActorBindingReader.cs:28 保存 runtime.ExistsAsync。
src/workflow/Aevatar.Workflow.Projection/Orchestration/ProjectionWorkflowActorBindingReader.cs:29 保存 type verifier runtime-shape check。
src/workflow/Aevatar.Workflow.Projection/Orchestration/ProjectionWorkflowActorBindingReader.cs:49 在 runtime 表示 actor 不存在时拒绝 query result。
src/workflow/Aevatar.Workflow.Projection/Orchestration/ProjectionWorkflowActorBindingReader.cs:102-103 按 runtime existence/type 过滤已物化 run bindings。
src/workflow/Aevatar.Workflow.Projection/Orchestration/ProjectionWorkflowActorBindingReader.cs:204-207 从 runtime type shape 派生 binding kind。
相关架构约束:
- 运行时形态不是业务事实:不得把本地实例类型、代理类型、对象可见结构当成业务绑定依据。
- 查询始终走 readmodel:对外查询只读 readmodel,不暴露 actor 内部状态、state mirror payload 或 event replay 为查询主路径。
- 禁止侧读冒充 query:跨 actor 读取必须走 actor-owned contract、projection 或 readmodel。
Fix Boundary
- 不新增第二条 query path。
- 不在
ProjectionWorkflowActorBindingReader 中查询 actor runtime。
- 从 committed workflow binding facts 物化 workflow actor kind / existence / binding。
- 如果产品仍需要 unbound actor lookup,定义显式 actor-owned binding/status contract,而不是读取 runtime type。
- 已有 command provisioning 仍可通过 infrastructure port 使用 runtime lifecycle;本 cluster 只约束 query/read path shape。
design_question
当 workflow actor 还没有 binding document 时,查询层应该返回 not found / unsupported,还是要求 actor 在创建或绑定时提交一个明确的 binding/status fact?
⟦AI:AUTO-LOOP⟧
human_brief
问题标题:Workflow 绑定查询把运行时对象形态当成业务事实
问题说明:当前查询 reader 表面上是在读取 workflow binding readmodel,但读取后又继续询问 actor runtime:这个 actor 当前是否存在、是否符合某个具体 GAgent 类型。这会让查询结果依赖当前节点的 runtime 可见性,而不是已经提交并物化的 workflow 事实。
单机环境下它可能表现正常;但在分布式、重启、投影延迟或 runtime 实现替换时,同一个 readmodel 可能因为本地 runtime 形态不同而返回不同结果。开发者需要关注它,因为 workflow run / resume / query 的稳定性会被隐藏地绑定到运行时实现细节上。
示例位置:
src/workflow/Aevatar.Workflow.Projection/Orchestration/ProjectionWorkflowActorBindingReader.cs:17-30为什么需要设计:修复不是简单删几行,因为当前 reader 同时承担“读已物化 binding”和“兜底判断未绑定 actor 类型”的职责。需要 maintainer 决定:未物化 binding 时是返回 unknown / not found,还是新增 actor-owned binding/status committed fact 来覆盖这个语义。这会影响 workflow run 创建、resume/signal target resolve,以及已有 actor 的兼容查询行为。
Evidence
src/workflow/Aevatar.Workflow.Projection/Orchestration/ProjectionWorkflowActorBindingReader.cs:19注入IActorRuntime。src/workflow/Aevatar.Workflow.Projection/Orchestration/ProjectionWorkflowActorBindingReader.cs:28保存runtime.ExistsAsync。src/workflow/Aevatar.Workflow.Projection/Orchestration/ProjectionWorkflowActorBindingReader.cs:29保存 type verifier runtime-shape check。src/workflow/Aevatar.Workflow.Projection/Orchestration/ProjectionWorkflowActorBindingReader.cs:49在 runtime 表示 actor 不存在时拒绝 query result。src/workflow/Aevatar.Workflow.Projection/Orchestration/ProjectionWorkflowActorBindingReader.cs:102-103按 runtime existence/type 过滤已物化 run bindings。src/workflow/Aevatar.Workflow.Projection/Orchestration/ProjectionWorkflowActorBindingReader.cs:204-207从 runtime type shape 派生 binding kind。相关架构约束:
Fix Boundary
ProjectionWorkflowActorBindingReader中查询 actor runtime。design_question
当 workflow actor 还没有 binding document 时,查询层应该返回 not found / unsupported,还是要求 actor 在创建或绑定时提交一个明确的 binding/status fact?
⟦AI:AUTO-LOOP⟧