forked from ChaiHao/BPOS-MVP
活动契约不带负责人岗位(用户定): - schema:活动节点删 owner(审批点的 approver 是「卡到人的工位」的功能语义,保留) - 运行时:活动任务默认**全员轮值**(在岗候选并集、最闲者先、staffId 稳定排序, owner-resolved 事件岗位记「(全员轮值)」);运营分派机制落地后让位 —— 债已记 - closure:活动点不核岗位,missing-owner-position 只出自审批点 - 员工面链条:活动点报**实际承接人**(实例→任务→人),没起的如实报「轮值待派」; NodeInstance 公开 taskId/approvalId(店面读回,与端口型合流) - 画布/导出依赖文件/属性卡全线摘岗位;属性卡活动点明说「分派归运营」 卡点画法废除,顺序流一律真边(用户定): - 种子图重画:四条回跳/直达(E4 直接定价、E6 选型后定价、E10 不通过、E12 有异议) 全部画成折线真边,车道分层零交叉(顶 y30 / y190 / y230 / 缝隙对开 / 底 y380); 卡点节点删净,图=恰 10 语义节点 + 14 真边一一对应(测试守着) - graph-to-pkg 卡点认亲机制删除;pkg-to-graph 直接按 from→to 认亲 - 元素盘删卡点件;图例、属性卡卡点分支、kindLabel/kindTone 随删 边号 E1、E2…(用户定): - 语义边 id 即边号:种子 E1–E14;合并器铸号(旧边保号、新边取下一空号,回归测试守着) - 画布线标带号(`E3 直接寻源`,无注记的边也标 `E1`);拣选条以边号立牌, **条件不再上按钮** —— 条件/映射只住属性面 - 边在图上可选中:FlowDiagram 连线加宽透明命中垫(边可点时注解层提到形状层上), 点线即切属性卡到该边(实测 E4 命中) 测试:closure 28、advance-order 6、graph-to-pkg 5(新增铸号例)、seed 8、 端到端八例真库全绿(全员轮值下照跑);五闸退出码验过。 库:purge 后重种,唯一 unified-quote@v1 生效(双面判据齐)。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
6.9 KiB
6.9 KiB
module: process
职责: 流程层:流程包定义与版本、边映射闭合校验(连线即映射 · 画图不检查 · 不闭合不得激活)、 负责人四策略的确定性解析、工作流状态的聚合投影、失败走向的消化判定、节点实例重开 不负责: 活动的执行(见 task 与范式引擎)、触发器(与流程包平级,见 trigger)、 画布的绘制(见 apps/web 的 gov-process)
公开出口: index.ts
- 类型:
ProcessServiceStartWorkflowInputWorkflowRecordClosureReportClosureViolationActivityContractFaceCandidateResolutionNodeInstanceWorkflowStateDispatch - 错误:
NotClosedErrorPositionVacantError - 端口类型:
ProcessStoreActivityDirectoryOrgDirectoryTaskGatewayApprovalGatewaySfeelFlowEventPublisherReceiptNotifier - 用例工厂:
createProcessService(deps): ProcessService(含setPackageState版本启停) - 纯函数:
checkClosureclosedresolveOwneraggregateWorkflowState(resolveOwner的bound入参 = 已校验的工作组绑定,ADR-011)isDigestednextInstanceNumberselectEdgesassemblerejectRouteOfdispatchOfstartNodeOfadvanceOrder(advanceOrder= 推进次序,按边拓扑排、排除回边、并行支按编号定序; 呈现用,不参与流转判断 —— 图纸坐标不配决定次序) - adapter:
createProcessStore;Drizzle 表:processPackageTableworkflowTablenodeInstanceTable
层级: L7(编码规范 §4) 依赖: @contracts;task(L6)、@sfeel 被依赖: trigger, app(治理台 · 工作流管理)
不变量(OS 03 / 3.2):
- 画图不检查,激活才查完整(产品决策 2026-07-28):
savePackage不跑闭合校验, 随手画的半成品也存得进来(存出来即retired,不生效);setPackageState激活时 跑checkClosure,不闭合抛NotClosedError(HTTP 412 带整份报告)。 违规项:未完成边、必填未映射、类型冲突、孤立节点、多默认出边、 活动未装载、审批岗位不存在、容忍分支被下游必填依赖 —— 任一即closed = false,激活被拒。 (活动点不核岗位 —— 契约不带负责人,missing-owner-position只出自审批点。) - 纯编排模型(产品决策 2026-07-28 二、三轮):流程包只决定活动编排与
活动传递的契约,不决定活动的实现方式(范式/版本住活动库,节点仅以
activityId链接),也不带负责人岗位(分派归运营;运营分派机制未建前, 活动任务运行时默认全员轮值 —— 在岗候选并集、最闲者先、staffId 稳定排序。 审批点例外:「卡到人的工位」是它的功能语义,approver留在声明里, 工作组绑定 ADR-011 也只对它生效)。节点只分活动点与审批点 (起点/终点是结构件);kind: 'gateway'已从 schema 摘除。 分支 = 源节点的多条条件出边(恰取一条,无条件边作默认兜底、至多一条), 汇合 = 多入边异或(上游互斥,只会来一条 ——joinReady已删,没有「等回齐」)。 AND 并行暂无声明机制,将来以「并行组」加回(对应 Mastra.parallel,见 debt.md)。 - 边有编号身份:语义边 id 即边号(E1、E2…,服务端/合并器铸号,旧边保号、 新边取下一个空号);画布线标带号、边在图上可选中,条件与映射住属性面。 顺序流一律画成真边(卡点画法已废除)—— 画布保存由画出来的边反推语义边, 图上没画的语义边会在存盘时丢失,种子与测试按「一一对应」守着。
- 激活双判据:①图编排闭合完善(结构 + 属性 + 传递契约,
checkClosure的 非 unknown-activity 项)②活动装载(节点链接的实现已安装,unknown-activity项)。 两面都清零才可激活;图照画照存,未装载不拦保存。 系统隐性上下文(审批verdict、放行选口outcome的判据注入、起单载荷穿透) 由引擎决定,不进设计者的编排面。 - 一条流恰一个生效版本(产品决策 2026-07-28):
setPackageState激活即独占 (同流其余版本一并停用);停用生效版 = 整条流下线,新起单被拒。 起单取生效版;在途工作流按启动时钉住的版本号读定义 —— 启停对它们零影响。 - 保存恒新增版本号(服务端算,不采信入参):工作流按 (包id, 版本) 读定义, 就地覆盖会改掉在途任务正在读的编排。store 层因此只插不改,撞键宁可报错也不静默覆盖。
- 求值语义前后端同源:画布的即时校验与后端裁决共用
checkClosure - 负责人解析确定性:轮值并列时按 staffId 稳定排序;同输入必同结果,结果与依据留痕
- 工作流状态是聚合投影:流程层不另设状态机;计量对象是节点实例, 重开产生新实例、旧实例不再入算;XOR 未选分支从未激活、不入集合
- 「完成」凭到过终点节点,不凭「没有在跑的了」:收敛但未到终点 = 卡住 =
abnormal。aggregateWorkflowState收第三个入参(包的终点 id 集);不传则退回旧口径,新代码一律传 - 失败走向的消化:改道 / 容忍 / 升审批一经生效即消化;终止流待人工处置中算异常
- 流级重做一律重开新实例 —— 同节点、新任务 ID、留痕关联,不复活旧任务
其它不变量:
- 流转零 LLM:选边与条件求值全部经
@sfeel;判定依据入事件记录 - 多出边一律异或,不分节点种类:条件命中优先(按声明序),无条件的边作默认兜底;
一条都没中而该节点确有出边 = 死路,发
route-dead-end事件 (哪个节点、各出边的条件、判据里当时有哪些键 —— 只记键名不记值)。 审批点的裁决(verdict)由引擎注入判据,两个去向就是它自己的两条条件出边 - 异或汇合不等:互斥分支结构上只会来一条,等齐 = 等一个不可能到来的分支, 流会无声卡死 —— 汇合等待机制已随网关整体摘除,容忍分支消化后直接推进
- 流程层不自动重试活动(过程内重试归 Harness); 流级重做一律人裁决后重开新任务实例
- 驳回走向声明式:审批点的驳回按
reject声明回指定节点重开新实例,不由临场决定 - 凡单必有来源:
source必填;终点按输出声明交付、按来源回执
M5 待补(docs/PROGRESS.md · docs/debt.md M5-1)
internal/adapter/workflow-compiler.ts —— 编码规范 §6.1 规定流程包动态编译为 Mastra
createWorkflow/createStep(XOR → .branch(),AND → .parallel(),节点 suspend()/resume())。
当前流转由本模块自持的确定性状态机 + sys.node_instance 持久承担,语义等价且已可测;
Mastra 编译器作为可替换的 adapter 后补,替换时 usecase 不动。