Skip to content

Rust 更新日志 ​

当前版本 v1.0.50 · crates.io(jeeflow-core / jeeflow-repository-sqlx / jeeflow-persist / jeeflow-facade 四 crate,独立 1.0.x 版本线)· 仓库 mldong/jeeflow-rust · Releases 版本日期以本仓 git tag 为准;跨语言对齐脉络见 更新记录总览。

1.0.49 — 2026-10-17 ​

audit8 R110+R112(四 crate 1.0.49)。

  • 新增(删除定义守卫):processDefine/remove 删除前校验任何实例存在即拒,批量先整批校验;trait 增 has_instances_by_define_id。
  • 诊断(未知档的边):5 处出边解析落穿统一 target_node_or_warn 带 from/to,行为不变。

Rust 引擎(jeeflow-rust)为联邦第六个成员,独立版本线,API 对齐统一规范。2026-08-25 首发 crates.io v1.0.5(v1.0.0–v1.0.4 为 2026-08-24 联调期 tag,因 crates.io tag 已占而跳过;crate 间依赖 version="1.0.0" caret 兼容,1.0.5 直接可用)。发布通道:四 crate 拓扑序 cargo publish(core → repository-sqlx → persist → facade),CI Release 由 tag push 触发。

v1.0.50 — 2026-10-31 ​

「退回修改、重提直返」首轮发版(tag v1.0.50=commit 60b140c,守卫补齐 adfacd3, 出口契约修复 08a0923,四 crate 同号)。条文见 规范 04 引擎操作 「退回修改、重提直返」节。

  • 新增:reapplyMode 节点属性与非法值解析期报错、submitType=6 直返建带 _reapplyContext 的申请待办、submitType=5 重提直接回来源节点、_branchCtx 分支归属 与汇合等齐判据、保留键入口剥离与实例锁。实现落点:jeeflow-core/src/reapply.rs + jeeflow-core/src/engine.rs。本栈另有两条"变更前先拒"的既有判据一并钉住:来源节点是 申请节点自身、或来源是会签节点 ⇒ 直接报错且不落任何半截事实。
  • 变更(补齐带标记申请待办的四入口守卫):execute_and_jump_sync(命名跳转与血缘回退 两档)、execute_and_jump_to_end_sync(拒绝)、execute_and_jump_to_first_sync(再次退回) 此前三处全裸——对带 _reapplyContext 的申请待办提交 2/3/4/6 都会被接受,其中提交 6 会完成旧申请、建一条无标记新申请 ⇒ 本轮分支等待丢失、另一支汇合提前放行。 上一轮该守卫只传播到 go/python/node/php,本栈是本轮现读出口契约时补上的。
  • 修复(ext 回退契约被新保留键打破):project_task_ext 一枚判据(控制键集合补两枚 保留键),回退取实例变量副本并合回 _reapplyContext;本栈实例变量只在发起腿写 args, 结构上不会把保留键带进实例变量,故不需 go/python/node 那处写回挡键。

v1.0.48 — 2026-10-16 ​

audit8 R91+R77+R78 甲-1+R86(tag v1.0.48,四 crate 拓扑序 core→repository-sqlx→persist→facade; release 提交 f867206)。

  • R91:声明层解析(ProcessModel 两枚根级字段+节点读 properties)+named_interceptors 按名表+ resolve_interceptors 驱动派发;条文=规范 02 §3。
  • R77:run_after_commit 可选通道(三档判据:无通道立即跑/登记到提交后恰好一次/回滚整批丢弃)。
  • R78 甲-1(本栈特有落法):filter_editable 的列匹配一律逐字精确(只折大小写),禁「驼峰↔下划线」 分隔符归一;现读依据=rust 全联邦只有这一处列匹配代码点(DynamicTableWriter 仅测试实现、真库 writer 由集成侧自写), 两轴同源 ⇒ 钉元数据腿必然撤掉本腿宽松档,with_strict_columns 作废为 #[deprecated] no-op, 1.6.4 那把宽松尺子仍以公开件(normalize_column/column_names_equal/find_data_key)留给集成方 writer。 条文=规范 10 §5.1。
  • R86:jump 目标节点不存在 ⇒ 显式报错(此前静默 no-op,对外 code=0 且任务已被办掉=实例原地失联)。

v1.0.47 — 2026-10-16 ​

audit8 R68① 行为变更(tag v1.0.47,引擎 commit 2e52d11;四 crate 同步抬代)。

  • 行为变更(委托 update 缺键档):processSurrogate/update 载荷里缺键的 processName/surrogate/startTime/endTime 四腿,此前 processName 被 ..sg 兜住、其余三条走 .or(原值) ⇒ 保留原值(八栈里唯一的"全保留"形)。现按 规范 06 §4.5 条款 4 改为清空, enabled 缺键走复位 1(java enabledArg == null ⇒ 1 同形);operator 仍是唯一保留腿。
  • 升级影响:只带 id 的 update 语义从"什么都不改"变成"四腿清空+enabled 复位", 与参考实现 java 及 go/python/node/php/csharp/moon 一致;存量若依赖"缺键即不改"需改为显式回传原值。

v1.0.46 — 2026-10-15 ​

issues/216 收口:stats 取钟串解析失败时,回落系统时钟不再无日志静默(tag v1.0.46,引擎 commit f5d5ff6+release 0edbc1f)。

  • 新增(可观测性,行为零变化):解析失败仍回落 chrono::Local、对外仍 code=0(刻意不改语义,避免"改日志顺手改行为"), 但回落前补一条带原因 WARN,文案由新纯函数 stats_clock_fallback_warning 生成(坏钟原串+期望格式两件齐)。
  • 病灶:注入时钟串解析失败 ⇒ 统计窗口/今日新增与数据基准可能错开,且换钟这件事本身不留任何痕迹(C1-L2 T-5,规范 06 §3.3 层位 2)。
  • 判据:自再执行三向——坏钟 WARN 归因齐/好钟零 WARN/回落 Local 真用上。

v1.0.45 — 2026-10-15 ​

issues/212 收口:分页 action 缺省 pageSize 由 20 改为 10(tag v1.0.45,引擎 commit bdb4d71+release a85ede1;四 crate 同步抬代)。

  • 行为变更:六枚分页 action(define/instance/todo/done/design/surrogate)在调用方不传 pageSize 时,缺省档 20 → 10, 对齐 规范 06 §2.2「pageNum 从 1 起;pageSize 默认 10」全局档。
  • 升级影响:依赖"不传就返 20 条"的调用方现看到 10 条;显式传 pageSize 的不受影响。
  • 病灶:验收工装全仓分页调用都显式带 pageSize ⇒ 缺省档在门禁里零取证面,这条 20 一直照不出(新格 L2-57 落格才咬合)。

v1.0.44 — 2026-10-14 ​

issues/201 收口:求值 Err 不再与「判假」同档静默(tag v1.0.44,引擎 commit eeaf4ec+release f629f75)。 条文见 规范 06 · 门面 §4.6「求值失败留痕」(issues/201 立法,2026-10-14 owner 拍 C)。

  • 新增(可观测性,行为零变化):eval_decision_expr 的 matches!(…, Ok(Bool(true))) 拆成 match 三分支, Err 支落新纯函数 eval_failure_warning(stderr,实例号/定义号/nodeId/expr/err 五件齐); Ok(_)(合法判假)与 Ok(Bool(true)) 行为不变、不落日志,对外仍 code=0。

v1.0.43 — 2026-10-14 ​

issues/195 收口:元数据注册表 未命中即硬失败 引出的三条真缺陷(tag v1.0.43,引擎 commit 94dfe12+ docs 17ed30b+release bc9fc65)。条文见 规范 10 · 持久化元数据 与 规范 08 场景 45。

  • 架构取向先记档再修:本栈 meta() 未命中直接硬失败,与 spec10「回落探测、零破坏」方向相反。 经裁决架构按现状记档(改契约不改代码),本轮只修三条由它引出的真缺陷: ① 列匹配只精确档(strictColumnMatch 的宽松档在本栈元数据腿结构性不可达); ② persistMode 缺省与未知双档静默不落(既没报错也没落库); ③ persist 时间列绕自家 clock 槽(本栈已支持注入时钟,这两列却取系统墙钟)。
  • 契约腿同批:spec10 两档并陈+spec08 场景 45;docs/persist.md 追加列匹配两档与静默腿日志。
  • 现读关键读数:该硬失败路径全仓零用例,且集成壳的 provider 恒不返回 Ok(None) ⇒ 生产侧零暴露, 属「潜伏面」而非线上故障。
  • 传播面:rust→salvo 壳(ab4ccee),候选 53207ea49565 全案集 54/0/0 → 原样晋升 (生产 ID==候选 ID)。

v1.0.42 — 2026-10-14 ​

issues/196 收口:fire_pre_interceptors 是 Ok(()) 空实现却有 4 个调用点(tag v1.0.42, 引擎 commit e9750b1+release 2d5d8f7)。

  • 修复(能力面补齐):Decision/Fork/Join/End 四处执行体之前都在调这条「前置拦截器」,但函数体是空的 ⇒ 前置语义在本栈结构性不存在:注册进 ctx 的拦截器只在后置位生效,宿主按 spec 配前置件时静默无效果 (后置腿真跑,所以看起来"接上了")。本版补真派发。
  • 八栈现读:其余七家(java/go/python/node/php/csharp/moon)全真派发 ⇒ 本栈独家。 ⚠ moon 的 pre 走独立数组,两栈形状不同,不是同一修法。
  • 判据:三枚+变异 M1/M2 各 2 红;workspace 636/0。同轮把 docs/spi-guide.md 里 「内置基础拦截器」那行假账改成两通道实话。
  • 传播面:rust→salvo 壳(02dba80),候选全案集 54/0/0 → 原样晋升(生产 ID==候选 ID)。

v1.0.41 — 2026-10-13 ​

issues/194 收口:flow.auto/flow.admin 哨兵大小写两派(tag v1.0.41,引擎 commit 4fe612d+fcfe3db)。

  • 修复(用户可感知):两处敏感腿(模型解析与引擎判定)用精确串比对认哨兵 ⇒ 宿主传异写 (Flow.Auto/FLOW_ADMIN)时代执行与管理员语义失效。条文 规范 04 逐字带 「忽略大小写」⇒ 契约已在、改的是行为。
  • 同批:php v1.3.34+moon 0.1.44,2 壳+moon 插件,2 镜像+moon 通道 3/3 全晋升。
  • 判据:两处腿各钉一枚异写档+变异对照。

v1.0.40 — 2026-10-13 ​

issues/184 收口:内置第 8 档 ActionPermissionProvider 的类全名错串(tag v1.0.40, 引擎 commit bd94f0a+release 8f74113)。

  • 修复:className 多了一段 .impl.、displayName 也不是参照串——两字段同改,按 java/csharp 的参照串对齐(元数据注册表按类全名定位,错串=宿主按文档配不上件)。
  • 同案两栈:MoonBit 0.1.43 同批并批发版——本栈头注写「移植 rust」把错串连带搬走,两处同修; 参照串来自 csharp,不是本栈自创。
  • 判据:core 317/317;四处变异各红后字节级还原。
  • 传播面:rust→salvo+moon→插件,1 镜像+moon 通道全晋升(54/0/0/51/0/3)。

v1.0.39 — 2026-10-13 ​

issues/183 收口:入口字段权限过滤写了不接(tag v1.0.39,引擎 commit b1f6e16+f5171cb)。

  • 修复(后果级):filter_fields_by_permission 函数体早在 interceptor 里,但唯一调用点是自家 #[test] ⇒ 生产入口从不按节点字段权限过滤,无权限字段的写入照单全收。本版新增 filter_args_by_node_permission 并在 execute/jump/jump-to-end 三处入口接线;同时把 field_permissions 改读 properties.field (原恒空+死函数)。
  • 判据:core 316/316、workspace 630/0;三档变异各红后还原。
  • 同族分案:与 issues/182(读错键那一行)不并案——「读错键」与「接线缺失」修法不同; moon 的入口过滤同源判例已由 issues/150 修完。
  • 传播面:rust→salvo,候选 54/0/0 → 晋升。

v1.0.38 — 2026-10-13 ​

issues/182 收口:properties.ext 错键族——本栈读 ext 恒 null(tag v1.0.38, 引擎 commit 8f7ae77+d0e5f14)。

  • 修复(一行):lib.rs 那处改读 properties.field。基准就是 properties.field—— 全仓没有任何生产方往 ext 写,persist 字段权限与 taskModel.ext 原料因此恒空。
  • 同案两栈:MoonBit 0.1.42 是同族另一形(读 ext 恒 {});入口过滤缺失另案(v1.0.39)。
  • 判据:3 枚+变异+还原后 md5 全等;候选 54/0/0 → 晋升。

v1.0.37 — 2026-10-13 ​

issues/180 收口:abandonTask 不再连带把整单置 99(tag v1.0.37,引擎 commit 17d58b2+07c9bff)。

  • 变更:任务级废弃只废任务,实例 state 写点删除。五栈同批(java/php/csharp/moon),五栈该方法全部零生产调用者(调用面 grep 仅定义处命中)⇒ 现生产零行为变化,收的是「一旦接上就会顺手废整单」的潜伏形状。
  • 同轮记账:顺补上一轮(v1.0.36)漏带的 Cargo.lock。
  • 传播面:rust→salvo;本轮 5 引擎→6 壳+moon 插件→6 镜像+moon 通道全晋升。

v1.0.36 — 2026-10-12 ​

issues/178 收口:candidatePage 行键 id 三级回落+搜索腿入参透传(tag v1.0.36,引擎 commit 7e6c815)。 条文见 规范 06 · 统一门面。

  • 修复(用户可感知):候选行键按 src.id→src.userId→actorId 字符串化三级回落、realName 回落 id; 此前退回裸 id ⇒ 待办候选人显示成一列数字。
  • 判据:一档 T0 用例+变异红样+字节级还原清洁。
  • 传播面:rust→salvo;同批五引擎(go/py/node/moon)9 张镜像+moon 一键包全晋升。

v1.0.35 — 2026-10-12 ​

issues/177 收口:候选人两键改「顶层优先·properties.field 嵌套兜底」(tag v1.0.35,引擎 commit 1eeb376)。 条文见 规范 08 场景 43「字段权限族」。

  • 修复(用户可感知):parser 只读顶层,设计器写在嵌套形里的候选人被读成空。
  • 判据:一枚新格+变异红样;复跑 workspace 全绿。
  • 传播面:rust→salvo;同批六引擎,9 张镜像+moon 一键包 10/10 晋升。

v1.0.34 — 2026-10-12 ​

issues/176 · 同轮第二次发版:salvo 候选门禁首跑 50/2 红 ⇒ 停晋升、定因后修(tag v1.0.34, 引擎 commit af08926+8bd73b5)。

  • 红①(L2-07,上一版 v1.0.33 带出的回归):fill_system_fields 把哨兵 flow.auto 直写用户列 ⇒ 撞 bigint 报 1366。 修=用户列按既有偏好写 apply_user_id(java/go/node 三参照同判)。
  • 红②(L2-43,既有缺口):复制语义的引擎自动腿 payload 缺 u_*。修=门面并回引擎注入的七键 (u_*/autoGenTitle),对齐内置版「原地注入+复用」形状。
  • 判据:两枚+变异两处逐处红后字节级还原;workspace 616/0/1(含真库腿)。
  • ⚠ 既有测试期望值就地改正:test_persist_sync_task_update_field_permission 的 update_user 旧期望(exec 操作人)与三参照相反,改正依据写进案文。

v1.0.33 — 2026-10-12 ​

issues/176 收口:startAndExecute 自动办理腿 operator 改 flow.auto(tag v1.0.33,引擎 commit 505c628)。

  • 变更(用户可感知):那条任务的办理人记成系统哨兵,真实发起人不再同时出现在「我已办」; 三不变量不动(实例发起人/apply 参与者/u_* 仍记发起人)。八引擎同批。
  • 判据:跨栈门禁 L2-43 同轮落格(--selftest-l2-43 四坏样本敢报红);修前四家族生产镜像同格红。
  • 后续:本栈同轮首候选两红未晋升,见 v1.0.34。

v1.0.32 — 2026-10-12 ​

issues/145 事务七条债 · rust 切片(该案第 5 条收口,tag v1.0.32,引擎 commit 63bae6b); 同批把「引擎 trait 死面」转真。

  • 变更:普查里 persist 业务表写腿不在引擎事务内 那一格的 rust 腿收口。前置记的是「引擎侧没有可注入的 事务抽象」⇒ 本栈**先补可注入抽象层(trait)**再谈与业务写腿同源;抽象层落地后这一格由假账转真账。
  • 判据:真库 tier 档+逐处变异对照。
  • 传播面:rust→salvo,1 张镜像晋升。

v1.0.31 — 2026-10-11 ​

issues/172 收口:updateCCStatus 的 operator 归一缺件(tag v1.0.31,release commit 27cf01b); 同批带上 issues/162 的 rust 腿。

  • 修复(本栈更宽一档):抄送状态更新时 operator 未走归一,且本栈形状更宽——空串直接绑成 actor_id='' 落库。与 node 同案两栈并修(node 只缺归一)。
  • issues/162 rust 腿:降级面保留+带原因日志,不再静默。
  • 门禁同步升级:同轮新增跨栈格 L2-40(operator 归一),selftest 五负控敢报红;真机首跑 48/1 照出夹具注入盲区未晋升,修夹具后 49/0/0 才原样晋升。
  • 传播面:rust→salvo+node→nestjs,2 壳 2 镜像。

v1.0.30 — 2026-10-11 ​

issues/168 收口:会签软拒绝(submitType=20)发码 5 不发码 6(tag v1.0.30)。

  • 修复(读数净错且条文明文禁止):分派表把 20 落进 _ 档 ⇒ 并行会签一票否决时对外发的是 「任务办结」码 5 而不是「会签否决」码 6;规范 08 场景 30/31 逐字禁止该形状。 本版按载荷发码 6。
  • 门禁先行:补牙点 L2-12(原 EXPECTED_EVENT_SEQ 里没有 6、夹具恒 submitType=1)先落, 再跑本栈修复——修前红=现生产镜像跑新腿 47/1,唯一红 codes=[3,5]。
  • 传播面:rust→salvo 壳(4d1b788),候选 48/0/0 → 原样晋升(其余 12 栈不吃这枚引擎,不动)。

v1.0.29 — 2026-10-11 ​

issues/167 A 收口(tag v1.0.29,引擎 commit 4954c14;四 crate publish)。

  • 修复(用户可感知):无 apply 节点流程上,startAndExecute 的首任务自办不再被权限拒—— 共享种子 I13(define=14 assignment-handler,首任务由 FormFieldAssigneeHandler 解析、空表单 ⇒ 零参与者)此前逐字报 权限不足: Operator leader not allowed on task N。根因不是"rust 权限 校验更严",是内存仓读路径漏参与者水合:门面自办腿先 add_task_actor(操作人)(与 java 门面同形、写侧有效),但引擎 is_allowed 读 find_task_by_id 的对象副本,看不到刚写进 参与者表的发起人。现 find_task_by_id/find_doing_tasks/find_done_tasks/ find_history_tasks/page_todo_tasks/count_todo_tasks/get_all_tasks 全部以 task_actors map 为读侧参与者事实源(map 有条目以条目为准,无条目保留对象自带——直存/ 零参与者两档原样),对齐 sqlx 仓 tasks_from_rows/java findTaskById 的 setActorIds。 放行依据是参与者表真实含发起人,不是权限豁免:零参与者 DOING 行照旧谁也办不动 (spec/02 §6.1)。条文见 规范 06 §startAndExecute「无 apply 节点流程的自办腿」。
  • 变更(同根因潜伏面一并收掉):内存仓上「事后加参与者再办理」的路径(surrogate 只加、 transfer 换人后的办理腿)与 remove_task_actor 的删除即刻对引擎权限判定生效——此前 transfer 靠门面把对象副本同步回去绕过。sqlx 仓零改动:生产集成(mldong-salvo)行为 不变,集成壳 pin 无需跟版。
  • demo:jeeflow-demo-salvo 补注册 7 个内置 assignment handler(八家唯一漏注册,对齐 go demo RegisterBuiltinAssignments/node demo registerBuiltinAssignments)——不补则 自办修完后 task2(发起人审批)仍解析零参与者。修后种子 16/16+9/9+8/8、页读 15/10 (八栈基线),I13 与 java/go/node/python 活栈逐键同形(task1 20/leader + task2 10/[leader])。
  • 判据:facade 新格 test_start_and_execute_no_apply_handler_first_task_self_handle (修前红=逐字复现 I13 的 PermissionDenied,修后绿);T0 cargo test --workspace 596/0; T1 SKIP_MYSQL=0 --features mysql-smoke 连 160 真库 68/68。core test_instance_and_tasks 按参与者通道改写(map 真源语义下直存对象 actor_ids 不再可见——sqlx 同输入同答案, issues/117 尺子)。读数=base-verify/reports/2026-10-11-i167-rust-i13-noapply.md。

v1.0.28 — 2026-10-11 ​

issues/164 A+166 A(种子)收口(tag v1.0.28,引擎 commit eeed1ec;四 crate 拓扑序 publish)。

  • 变更(用户可感知):决策节点零命中显式报错——遍历完全部出边仍无命中(带 expr 的边全判 false/ 判定变量缺失/零出边/自定义决策处理器未命中)时抛 decision节点无法确定下一步执行路线 (逐字=java WfErrEnum.NOT_FOUND_NEXT_NODE,门面出口 99999999+该 msg)。改前本栈该档 静默停住(令牌不前进也不报错):办理人看到 code=0"成功"、实例挂在 state=10 且没有任何人的 待办。条文见 规范 06 §4.6「零命中档」。
  • 种子:demo FINISHED 三行(F5/F8/F9)补 finalAmount=8000(issues/166——define 映射漂移, flows 目录加入 06-…-expire.json 后 define=12 已是 10-mixed-mode;补键走 e8→boss→end 与旧蒙臂 同形,demo 重置读数回 15/10)。
  • 判据:engine.rs tests 3 格(内联夹具——共享夹具 03 的 >1000/<=1000 恒有一条真照不到) +变异对照(删 else 臂即红)。rust demo 读数 15/10;无 apply 流程首任务自办权限分叉另立 issues/167。

v1.0.27 — 2026-10-10 ​

issues/158:highLight 的决策边求值与引擎运行时改用同一条通道(crates.io 四 crate,引擎 commit 2c18460,tag v1.0.27)。条文见 规范 06 §4.6 义务 2。

  • 修复(用户可感知):宿主没注册 IExpressionEvaluator 时,流程图上通向当前待办的那根决策分支线不再亮 (实例确实走了那一支:同一读数里活跃节点、决策节点都在,唯独那条边缺)。 根因是本栈两条腿各用一个答案——运行时一直有内置求值腿,门面却在 SPI 为 None 时整档判 false。 现新增 jeeflow-core::default_evaluator(内置默认求值器,SPI 形状)+ ServiceContext::expression_evaluator_or_default() 单一出口,运行时与门面共用; "未注册 ⇒ 判 false"这条降级档在本栈结构性不可达(与 C# 的 ExpressionEvaluatorOrDefault 同形)。 ⇒ 集成壳零改动:不注册 SPI 的宿主(如 mldong-salvo)升级引擎即生效。
  • 变更(内置求值器本身):裸变量名现在代入再比较,关系运算(> >= < <=)要求两侧都是数字。 旧内置只代入 ${var}/#var,amount > 1000 是拿 "amount" 与 "1000" 比字典序蒙对方向的, 同一条比较对 amount <= 1000 也为 true——两支一起"为真"只是被"先撞上第一条 true 边"掩盖。 升级后可感知差异:两条分支都带 expr 的流程,未走的那条不再被误判为"也走了"。 语义基准=C# DefaultExpressionEvaluator(其自身以 PHP WfExpressionEvaluator 为最小基准不超集), 不含 && / ||(旧内置也没有,不扩集)。
  • 判据:门面仍只认 Ok(JsonValue::Bool(true)) 为 true(与 Java Boolean.TRUE.equals/Go 类型断言同档)。
  • 会签门控:内置腿把 gate_vars 并进求值原料,#nrOfCompletedInstances == 2 一类条件照旧生效 (缺省回落 0,与 PHP 同形)。

issues/153 ②③ + issues/154 ①②③④ 六条分叉收口(crates.io 四 crate,引擎 commit 138a231)。条文见 规范 06 §4.6。

  • 变更:决策节点的带表达式出边先求值再过滤——false 分支的边名与目标节点都不再收进来 (此前本栈整条丢弃带 expr 的边,未走的分支与走过的高亮一起消失)。
  • 修复:nodeProgress 成员的 name 不再硬编码空串,改走 ctx.user_provider 取 real_name (只有 SPI 未注册/查无此人/real_name 空/provider 报错四档才留空串)。
  • 新增:approvalRecord 首列 id(Json::String(task_id) 显式串化,不押门面 stringify_ids 兜底)。
  • 变更:实例不存在改出空数组(删掉 InstanceNotFound 那条 ok_or);ext 空档改出 {}, 删掉回落实例变量那一条(并把那句自称"对齐 Go taskRowToMap"的注释改成实话——Go 直取任务变量、无回退)。
  • 变更:ccList 默认 pageSize 由 20 并成 10(与其余七栈同档)。
  • 判据:true 只认 Ok(JsonValue::Bool(true)),与 Java Boolean.TRUE.equals/Go 的类型断言同档; 表达式求值复用引擎那一只口,不另立第二套。

v1.0.25 — 2026-10-08 ​

issues/152 委托三件收口(crates.io(四 crate),引擎 commit 3c5c52d)。规范条文见 规范 06 §2.5 口径表 与 §4.5「processSurrogate/page 归属不变式」, 判据基线=规范 08 用例 38–41。升级前两处用户可感知的行为变更必读(见下)。

  • 新增:processSurrogate/page 的归属不变式落到引擎自己身上——门面按 §2.5 把归一后的 operator (缺键/空串/全空白 ⇒ demo 缺省 user1)作为 t.operator EQ 下发,形状与本栈 instancePage 一致; 仓储侧补第二层(SQL 侧 AND 1=0、内存侧判不命中),内存仓与 SQL 仓同答案。 此前这条语义全靠集成壳注入 operator(换宿主/直调 SPI 即退化成全库台账,vben5 前端本就不传)。
  • 变更:归属条件的缺失档与空值档同判——绕过门面直调 pageSurrogates 时,t.operator 那条 EQ 值为空或整条没给都返回空页,不再"这条条件不加"放出全库;只收归属列, m_LIKE_* 那套"空值当没填"的可选过滤放行原样不动(与 §2.5 抄送侧同一条尺子)。
  • 修复:写侧授权人三档归一。processSurrogate/save 收到空串/全空白 operator 时不再落进 operator (那种行是死行:getSurrogate 的 WHERE operator = ? 永不命中,台账看得见、待办永不并人); save 缺省档落归一值,update 缺省档保留原授权人不变。
  • 不变:委托查询的作用域优先级(精确优先)与择优顺序(先按 id 取最新一条再交判据裁决) 维持 v1.8.2x 起的既有立法(issues/123 收口形状),与内置 mldong-wf 版方向相反—— 差异与迁移动作已写进 §4.5「与内置版(mldong-wf)的三条方向差异」。
  • ⚠️ 行为变更(用户可感知):① 集成方若曾依赖"processSurrogate/page 不带 operator 返回全库", 升级后该档只返回归一缺省 user1 名下的行;② 直调仓储的调用方若不给归属条件,将拿到空页。 jeeflow-ui 与 vben5 两条前端腿都经门面且各栈已实测零回归。
  • 测试:仓内 T0 五档判据(作用域优先级/停用不自愈/自委托/写侧三档/分页归属两层), 每档配真值档阳性对照;摘掉兜底判据必红。

v1.0.24 — 2026-10-02 ​

四 crate(jeeflow-core → jeeflow-repository-sqlx → jeeflow-persist → jeeflow-facade)按拓扑序同代发。

  • 新增(issues/115 §3-8):门面第 47 个 action processTask/removeTaskActor; §3-8/6.A 的条数门禁前进到 47,并给这格补上真正的牙(此前它只数清单长度,摘掉一个 action 也不会红)。
  • 修复(issues/137 §3-1):门面出口固定文案「流程处理失败」+判别式;内部异常原文只进日志。
  • 修复(issues/137 §3-6):删除腿「原值 ∪ trim 值」两形并集(core + repository-sqlx 两腿)。
  • 修复(issues/137 A §3-4):实例级 expire_time 按定义级表达式求值(注入钟 current_time_str() 那条腿不变)。
  • 修复(issues/137 D):相对档前缀判非负——n < 0 走既有 ? 落穿,不新造返回路径; E 档只加测试(产品代码零改动)。
  • 文档(§3-11):过期注释随批+更正一处实测版本号——落穿是八栈一致,不是"与 Java 的故意差异"。
  • 测试:cargo test --workspace -- --test-threads=1(连 160 真库;并行会间歇假红) ⇒ 578 passed / 0 failed,其中 jeeflow-repository-sqlx 66/0(23.8s,含 MySQL 腿)。

v1.0.23 — 2026-09-30 ​

  • 新增(issues/142 A 批):记录类(snaker:custom)执行形状拆分——parser 旧 _ => NodeType::Custom 兜底臂拆成「custom 显式一档」+新增 NodeType::Unknown(未知串 查表前剥 snaker: 前缀;未知档留在模型里+落一条带 nodeId 与实得类型串的 WARNING; ⚠️ subProcess/wfSubProcess 别名有意分叉挂账,与子流程真实现同批收); 任务类零参与者照常建 DOING 行。ServiceContext 新增 custom_handlers/ register_custom_handler/find_custom_handler,spi 新增 CustomNodeHandler trait 与 CUSTOM_RETURN_VAL。
  • 修复:save_task 的 INSERT 语句补 finish_time 列——留痕行此前只在聚合里、落库缺列 (内存绿 ≠ 落库,真库那一路才照出来)。
  • 变更(issues/142 B 批 · spec 06 §2.11):model::normalize_actors 升格通用入口 (旧名 normalize_cc_actors 保留为转发,已发布 crate 的 API 面不破坏);门面四条任务写点接 同一枚(arg_actor_ids 两腿只拆形、判据收单点;transfer 的 operator/fromActor/toActor 走 require_normalized_actor,必填信封逐字不动);主键档 require_task_id(缺失/0/负数响亮报错); 发起腿 f_nextNodeOperator 原样透传(旧 get_str 把数组形态整条静默丢弃);两仓 remove_task_actor 删除位 trim。注释更正:spec 02 §6.2 第 1bis 条"一列不写"指 expire_time。
  • 测试:cargo test --workspace 全绿(core 258 / facade 128 / persist 33 / sqlx 54,含真库)。

v1.0.22 — 2026-09-29 ​

  • 修复(issues/138 · 内存仓储 ccList 行形状):page_cc_instances 在内存仓里把 cc 行原样投了出去 ——operator 取的是被抄送人(=查询者本人,恒等)、主键给的是 cc.id、state 是 cc 已读位、 create_* 是 cc 行的创建人。改法=抽出实例行唯一投影出口 instance_row_of(),cc 只当归属谓词 (cc.actor_id)用,命中后输出实例行:id←instance_id、operator←inst.operator(流程发起人)、 state/business_no/variable/create_* 全取实例列,并按实例 id 去重(对齐 sqlx 侧 COUNT(DISTINCT pi.id))。jeeflow-repository-sqlx 侧本就合规 ⇒ 零改动,两仓形状首次一致。
  • 孤儿 cc 的处置(实例不存在的 cc 行):内存腿出降级行(id←cc.process_instance_id、 operator 留空串)而不是冒充发起人 ⇒ 门禁判据必判红,归属档计数语义不变;真库走 INNER JOIN 天然不出行。
  • 测试:cargo test --workspace EXIT=0,404 passed / 0 failed(基线 395 + 9: core 新增 7 格 + 门面 integration 测试 2 格,判据与集成层 judge_cc_row_shape 逐字同判, 并用 runner.py --selftest-l2-31 交叉核对)。变异:operator 退回 cc.actor_id ⇒ core+facade 两层各红;主键投 cc.id ⇒ 红样点名「行主键 id 不是实例 id ⇒ 行来自 cc 表而不是实例表」。
  • 传播面:salvo 壳 pin 仍 1.0.21(本轮镜像已按 1.0.21 晋升);本代只改内存仓 ⇒ salvo 生产路径 (sqlx)行为不变,壳 pin 与镜像随下一批带上。

v1.0.21 — 2026-09-29 ​

  • 新增(issues/127 + 132):A 套码表补 TaskComplete(5) / TaskReject(6) / TaskTransfer(7) / TaskWithdraw(8) / InstanceTerminated(9);办理抄送腿进引擎(只 execute_task 一条腿,jump 族不建 cc); 撤回只 fire 8 不补 2;直传载荷键(instanceId / taskId / operator / submitType / ccActorId)按 §11.3 补齐。 本栈成员名本就是规范名 ⇒ §11.6 别名义务不适用。
  • 修复(发版前拦下):新测 test_i127_cc_create_on_execute_leg 挂死 >60s 致 cargo test --workspace 中断——根因不是实现死锁而是测试自死锁:Mutex guard 被持有期间 seq() 从同线程再入(非重入)。修法=取快照即放 guard。旧形状在副本里注回可稳定复现 has been running for over 60 seconds,机理闭环。
  • 新增判据:§11.7 边界 2 的窄口径负向格(jump4/rollback3/rollback6/end2 四档带 tf_ccActors ⇒ 不建 cc 行、不发 4)——此前本栈没有任何一格守着这条边界。
  • 测试:cargo test --workspace EXIT=0,四 crate 合计 395 passed / 0 failed (core 193 + facade 128 + persist 33 + repository-sqlx 41),其中 16 支 test_mysql_* 真连 160 MySQL(非静默跳过)。变异:摘 cc 钩子 ⇒ 正向格红;把钩子塞进 jump ⇒ 负向格红。
  • 已知形状:本栈不做完整子流程展开 ⇒ java 的「父实例待播上收」结构性不适用; 真库口令硬编码在 Cargo.toml / repository-sqlx(非本轮引入,未动)。

v1.0.20 — 2026-09-29 ​

  • 修复(issues/134 · 撤回不校验实例状态):对已办结/非进行中的实例调撤回,改前会被静默改写—— 实例 state 被写成 30 且返回 code=0(症状现场:boot2 生产镜像 code=0 msg='成功',state 20→30)。 聚合根 withdraw 入口加实例态守卫:state != 10(进行中) 一律拒,内部码 20010009,被拒时 实例与任务行零改写、不落库;出口按 issues/121 口径透出 code=99999999 + 逐字文案 「流程实例非进行中,无法撤回」(内部码不进 msg)。任务行层面的既有保护(spec 06 的"20/40 任务行 不改写")原样保留,实例级守卫排在它之前。落点:model.rs::withdraw 返回类型改 JeeflowResult<()> + lib.rs 把 withdraw()? 上提到回写与两次落库前。workspace 四 crate 全绿(core 179 / facade 122 / persist 33 / sqlx 41 连 160)。 rust 栈 130 侧无需改动(静态类型存不进字符串)。

v1.0.19 — 2026-09-28 ​

  • 修复(issues/126 案 A):本栈无求值器 ⇒ 新增 jeeflow-core/src/expire_time.rs(零依赖): process_time 三档逐字(变量档终局 None/类型不认识落穿/Ns·Nm·Nh·Nd 相对档,d 走历日分解/绝对档严格 19 位), 取时只走本栈时钟单源 clock::current_time_str()(issues/120 路 1 的成果,没有引入 SystemTime); 毫秒档由「引擎钟串 − UTC 串」推宿主偏移。五处写点接 stamp_expire(返回份与聚合尾部都写)。 实例级 expire_time 仍搬定义级原串——那是另一件事,本轮按口径只报不改。
  • 测试 cargo test --workspace ⇒ jeeflow_core 175 passed / 0 failed(基线 156+19 新格)、facade 118、persist 33; T1 cargo test -p jeeflow-repository-sqlx 41 passed / 0 failed(真连 MySQL)。 ⚠️ 复跑核验时别把 doc-test 那行 0 passed 当成 T1 读数——真读数在它上面一行。
  • 变异对照两层:求值换 now ⇒ 8 红("普通建单 expire − create = 0s");摘掉第五处 ⇒ 1 红且可归因(首成员格仍绿)。 四档 sha256 还原核对,grep MUTATION-126 零残留。
  • 本轮的跨栈分叉是本栈执行者报出来的:它顺手比对隔壁栈代码,发现 go/python 把回退那处的表达式取成了 prev。 ⇒ 判据随后统一改成双节点不同偏移夹具(详见各栈页)。
  • 跨栈一致性(同批八栈一起发,基准=boot2 内置版 ProcessTaskServiceImpl:213/386/524 三处写):普查发现写点其实是五处,第五处=串行会签推进出的下一位成员(boot2 的推进回调 createCountersignTask(:485,内含 :524 到期写)),各栈这一支普遍绕过本栈建单 helper 直建行,只看建单/回退两支会漏。另一处分叉在落地中被抓出来:回退新建的表达式该取 boot2 的 current=被回退掉的那个节点(:363 current = model.getNode(currentTask.getTaskName()) → :385 ((TaskModel)current).getExpireTime()),而不是落地行所属的 prev;java/php/csharp/rust/node/moon 取 current,go 与 python 头一轮取成了 prev,两栈当时的夹具只给一个节点配表达式 ⇒ 取错也全绿,是比对隔壁栈代码才发现。修完的判据改成双节点不同偏移(落地 1d ∧ 当前 3h ⇒ 断 ≈3h)+反向钉一档「当前未配 ⇒ 必须空」。

v1.0.18 — 2026-09-28 ​

  • 变更(issues/131 案 A · 串行会签簿记从实例变量搬到任务变量,对齐 Java 参考实现):三键 operatorList_{node}(数组,不再是逗号串)/ loopCounter_{node} / nrOfInstances_{node} 原写在 instance.variables 上且带 csv_ 前缀(csv_{node}_operatorList),现全部改写到任务变量: 建单侧 seed_countersign_bookkeeping 写进首个成员任务,推进侧 countersign_roster(task.variables, …) 从完成节点那条任务读回名单、并把三键抄给新建的下一成员任务(写在先,next_task 拿到 prev_id); 门面 lib.rs 的进度/高亮还原按数组取。旧读法退回逗号串 ⇒ 名单只剩 1 人 ⇒ 串行推进直接断链。
  • 为什么 Java 那一半是对的:键名带 _{node} 后缀,落实例上攒的是"走过的那几个会签节点各一条链", 走完三个会签节点后实例里同时留着 operatorList_a/b/c;clear_count_bookkeeping 只按传入 nodeId 清 (清不掉历史),读回写时又整图重扫、把 countersign_type != "parallel" 的排他会签也拉进来—— 三个病叠在一个键上,而串行"一个实例一条链"正是排他会签的互斥前提。搬到任务上以后三个病一起消失。
  • 判据不是"实例上没出现过这个键":断言形状是"实例通道这三个键一个都没有 ∧ 任务通道三个都在且 值等于当前节点那条链",绕开通用 insert 直接 variables[key]=… 写回实例仍会报红。既有"实例带 csv_* 簿记" 的断言按 A 案改写到任务侧——这条改写的依据是 Java 参考实现与既有六栈同形,不是本栈实现。
  • 测试 cargo test --workspace 全绿:core 156 / facade 118 / persist 33 / repository-sqlx 41 (0 failed;台账留痕 .scratch/rust-131-t0b.log,落账时二次复跑读数一致)。 变异对照 .scratch/mutate-rust-131.py:单独回退建单侧 / 推进读侧 / 名册值形状 ⇒ 对应格各自报红, 按 sha256 还原后全绿。
  • 镜像层验收(本栈唯一的集成壳 salvo):落点=taskExt 键=operatorList_approve 成员数=3 且 inst_ext_roster=[](实例侧零残留),与 java/php/csharp 三栈逐字段同形; 生产镜像晋升后补跑 wf 门禁 35 格 PASS=35 FAIL=0 SKIP=0。
  • 发版核验 tag v1.0.18(ae07285,与 HEAD 同值)触发三条 workflow 全绿:Release(单步 "Publish in dependency order" success ⇒ 四 crate 按依赖序 cargo publish)、Demo Deploy、sync-cn; 下游 salvo 壳 cargo check 实拉通过(Cargo.lock 四件均 1.0.18=安装侧证据)。

v1.0.17 — 2026-09-27 ​

  • 修复(issues/129 · 本案 rust 半,案 A 立法前的实弹依据):空串 operator 不再折叠成"读全库"。两层同 java 后来的形状——门面归一化 + 仓储归属判据。本栈原形状独有一套:SQL 文本里写 ? IS NULL OR ... 的归属谓词,空串进去命中 IS NULL 分支 ⇒ 条件失效返回全量;现删除该折叠,归属值为空即空页。
  • 线上复验(tag v1.0.17 的 demo 部署绿后重打三路探针):四出口空串档 = 4 / 5 / 1 / 2,与 user1 档逐出口相同、__nobody__ 全 0;修前不传/空串读到 25 条。
  • 发版核验:crates.io 四 crate 拓扑序发布(core → repository-sqlx → persist → facade),CI Release + 安装侧回拉绿。⚠️ 四 crate 必须拓扑序,^1.0.0 互依赖会让错序发布"打包成功却锁到旧 core"。
  • 同批跨栈:本条是八栈空串档收口的第一发实证;其余七栈(Java/Go/Python/Node/PHP/C#/MoonBit 1.8.32 / 1.8.32 / 1.8.32 / 1.8.32 / 1.3.15 / 1.0.9 / 0.1.15)于 2026-09-28 按同一判据逐栈落地,规范条文见 规范 06 · 统一门面 §2.5。

v1.0.16 — 2026-09-27 ​

  • 修复(issues/125 · SQL 侧数据库时钟的写路径,本栈是四栈里唯一中招在写侧的):jeeflow-repository-sqlx 的 update_instance / update_task 两条 UPDATE 原写 update_time=NOW() ⇒ 同一行的 create_time 由引擎钟写、update_time 由数据库会话钟写,两列两个基准,宿主注入东八而库会话 UTC(或反过来)时"更新时间"比"创建时间"凭空差 8 小时,也把 1.0.12–1.0.13(issues/120 路 1)辛苦收敛的"壳注入后全栈同基准"在这两列上作废。现在两条都绑 jeeflow_core::clock::current_time_str()——与 save_* 写 create_time 用的是同一个时钟出口,每条语句只取一次。
  • 实测补一条(比立案时的判断更严重):sqlx 会把 MySQL 会话时区钉在 UTC。开发服务器墙钟 +08(11:30)时,同一条 SELECT DATE_FORMAT(NOW(), …) 在 sqlx 连接上返回 03:30:14,而 mysql CLI / go-sql-driver / MySqlConnector 的连接都是 +08:00 ⇒ 本栈这两处的发作不需要换 RDS、不需要容器改时区,只要走 sqlx 就必然与库的 global time_zone 分家。
  • 判据(新增 M5 test_mysql_m5_update_time_follows_engine_clock,160 真库;夹具只用 900501–900599 段并测后自删):用 ClockScope::injected 注入固定钟(时钟是进程级 static,跨 spawn_blocking 线程同样可见),断 create_time == update_time == 注入串——即"一行只有一把钟";并先断 NOW() != 注入串 自证这条等值不是两把钟恰好同读数的假绿;finish_time 同批断言。另加 test_update_sql_has_no_db_clock(不连库、恒跑):两个函数体剥掉整行注释后不许出现 NOW(),必须是 update_time=? + current_time_str() 形状。
  • 测试 cargo test --workspace ⇒ core 156 / facade 116 / persist 33 / repository-sqlx 40 全绿;门面 NOW() 入参哨兵那条(facade_now_follows_engine_clock,与本缺陷无关)保持绿。变异对照:两处换回 NOW() 并删绑参 ⇒ M5 红在 update_time 实得库钟 2026-09-27 03:30:14、形状门禁同时红,还原后绿。
  • 发版核验 crates.io 四 crate 1.0.16 拓扑序发布(core → persist → repository-sqlx → facade,CI Release 按依赖序),/api/v1/crates/<crate>/1.0.16 四件全 200 且 max_version=1.0.16;下游 salvo 壳 cargo check 实拉通过(Cargo.lock 四件均 1.0.16)。

v1.0.15 — 2026-09-24 ​

  • 变更(issues/124 变量出口立法,对齐 Java v1.8.30 基准):processInstance/detail 出口改 "ext": flow_data_to_object(&inst.variables)(键形态与列表行一致),行 / 任务出口的 variable 原串摘除;唯一出口 = ext(实例侧)+ instanceExt(任务行侧),空变量出 {};持久层 variable 列不动。
  • 附注 camelCase 强制层的 opaque-key 白名单本就含 ext——详情键从 variables 换成 ext 后,下划线键在详情 / 列表两侧的驼峰分叉随之消失(issues/124 顺带收口)。
  • 测试 187 例全绿;crates.io 四 crate 拓扑序发布、1.0.15 回拉 200。

v1.0.14 — 2026-09-23 ​

  • 修复(委托判据取行顺序,对齐 Java 参考实现):surrogate.rs 拆出三件套——surrogate_effective(四判据本体:enabled 严格 1 / 被委托人非空且非本人 / 窗口覆盖判定时刻,起止 NULL = 该侧不限)、surrogate_in_scope(作用域腿)、newest_in_scope(不带判据按主键取最新);pick_surrogate 按「精确腿最新一条 → 判否再看全流程腿最新一条」的次序裁决。sqlx 仓 query_newest_surrogate 同形(撤掉 enabled / 窗口 / 自委托谓词),内存仓与 sqlx 仓共用同一份判据 ⇒ 双仓同答案。旧形状「先滤生效再取最新」等于任一条历史窗内委托永久生效,用户后续停用 / 挪窗外 / 改自委托都判不动它。
  • 修复(出口文案统一):退回上一步两格对外 msg 删 20010007: / 20010008: 码前缀(jeeflow-core/src/engine.rs 两处),改 Java 逐字中文文案;两码只留引擎内部,对外恒 code=99999999。测试断言由 contains(文案) 加反闸 !msg.contains("2001000")——旧形状带前缀同样命中子串,无反闸即恒绿。
  • 测试 cargo test -p jeeflow-core ⇒ 148 passed; 0 failed;cargo test --workspace exit 0 全绿(core / repository-sqlx / persist / facade / demo)。形状经代码与文档两轮独立核验。
  • 发版 四 crate 按拓扑序 cargo publish(core → repository-sqlx → persist → facade),crates.io 四件 1.0.14 元数据逐一 200 回拉核验通过;Release 由 tag v1.0.14 触发。
  • 跨栈验证 13 个集成栈候选镜像门禁对拍:委托判据格 L2-17 全绿(13/13,salvo 栈同判),13 栈逐格 0 分叉;L2-18 13 栈同形同错=门禁夹具支间未清场,非引擎缺陷。

v1.0.13 — 2026-09-22 ​

09-22 夜发版轮(issues/120 进程级 clock 槽 + issues/121 P1/P2 血缘回退)Rust 侧代次;tag v1.0.13(19:23),bump commit 8d2fd53。

  • 新增(120 时钟基座):jeeflow-core 落进程级 clock 槽——ServiceContext 注入走不通 (17 个取时点里 8 个在 sqlx、4 个在聚合根),故时钟槽放 core 进程级;统计口径的"当日/最近 30 天"锚点 接回与时间串同一出口(07f472d 补漏)。
  • 新增(121 P1):建单写 parent_task_id 与行级 isFirstTaskNode,门面读时行上值优先(bfc9076); 引擎控制键不算「任务变量非空」,P1 不打断 ext 回退实例变量(c652aa2)。
  • 变更(121 P2):退回上一步改血缘版并拆开 3/6 共用分支(4487c2d)。
  • 修复(T0 核账抓到的真缺陷):复活行的老行血缘 NULL 必须落 0、不得留 None(b4a3353)—— 建单不变量靠 persist 收口保证时,绕过收口的那条路径就静默错血缘(二元环)。 无血缘用例补到三种形状,"parent 指不到真实行"那格才杀得住静默不建单(7cb5b9c)。
  • 发版核验:四 crate 拓扑序发布(core → repository-sqlx → persist → facade,互依赖 ^1.0.0 错序会 打包成功却锁到旧 core);crates.io 回拉核到。⚠️ 壳侧(salvo)在 1.0.13 发布前编译不过属正常—— 它依赖 crates.io 上的正式版本,本地源码不算数。

v1.0.12 — 2026-09-10 ​

  • 修复 salvo S15「指定下一节点处理人」双缺口:① facade collect_static_candidate_actors 静态候选误收节点 assignee——assignee 是默认处理人(运行时落 task.actor_id)非候选池成员,Java/Python/Go 参考实现均只取 candidateUsers+candidateGroups;误收致 candidatePage 短路 user_search 全量搜索,弹窗只剩默认处理人。删 assignee 收集分支。② core resolve_assignee 优先级1 只取字符串形态,前端 UserSelect multiple 提交 JSON 数组取不到 → 落 assignee 字面量、指定不生效;对齐 Python _resolve_actors 双形态(数组逐项 + 字符串逗号分隔)。
  • 测试 双回归单测负向红/修复绿;workspace 全绿 core 129 / facade 96 / persist 33 / sqlx 28(Cargo.lock 顺带从过期 1.0.8 修正)。
  • 集成栈 mldong-salvo-jeeflow pin 1.0.11 → 1.0.12(真拉 crates.io,31 单测绿);干净重建候选 c5871ce6 全 gate(baseL2 11/11 + gate26 26/26 + wf-L3 18 passed/1 skipped 含 S15 绿 + base-L3 零新增)后原样晋升生产,生产冒烟 wf-L3 全绿,公网 demo 抽查健康。坑:crates.io api 端点对默认 curl UA 返回 403(Fastly 拦截),回拉验证需带自定义 UA 或直拉 static.crates.io。

v1.0.11 — 2026-09-09 ​

  • 修复 五语言 SQL 仓聚合水合:find_instance_by_id(jeeflow-repository-sqlx)此前硬编码 tasks: vec![],门面 processInstance/detail 的 tasks/activeTaskList 恒空(gate26 L2-12 门禁真根因,非会签语义)。二次查 wf_process_task(内联查询 + 自由异步 fn tasks_from_rows:批查 actor、保行序;不套 block_on 避免嵌套 block_in_place)水合任务副本,语义对齐 Java findTasksByInstanceId / PHP PdoProcessRepository / C# FindTasksInternalAsync(聚合水合口径)。update_instance 本就不级联任务(仅实例行),withdraw 逐任务 update_task 路径不变。memory 仓本就水合(基线正确,未动);引擎核心会签语义未动。
  • 测试 T0 新增 test_mysql_i110_find_instance_by_id_hydrates_tasks(真实 MySQL,独立 9008xx id 段——C8 占 9004xx,cargo test 并行线程共用 160 DB 会撞主键);workspace 全绿:core 129 / facade 94 / persist 33 / sqlx 28。
  • 集成栈 mldong-salvo-jeeflow pin 1.0.10 → 1.0.11 随 P3 收口(base+1,进行中)。

v1.0.10 — 2026-09-06 ​

  • 修复 分页双重分页:facade 6 个分页 action(processDefine/page、processInstance/page、ccList、todoList、doneList、processDesign/page)的 m_ 过滤 + 分页切片下推仓储(memory/sqlx 消费 PageQuery.filters,core 新增 filter_sql 构造器 + 列白名单,对齐 java pushdown 与仓内 processSurrogate/page 正确形态)。两大主症状消除:recordCount = 总记录数(此前虚低为本页行数)、pageNum≥2 不再恒空;m_ 过滤下 total/rows 口径自洽。
  • 测试 新增多页/翻页/m_ 过滤跨页单测;T0 cargo test --workspace(core 129 / facade 94 / persist 33 / sqlx 27)+ T1 mysql-smoke(连 160)全绿;公网八语言 processDefine/page pageNum=2&pageSize=3 同参抽检全部 15/5/3(修复前 rust 3/1/0)。
  • 集成栈 mldong-salvo pin 1.0.9 → 1.0.10 随本批收口(集成仓按 base+1 模式 squash 回薄壳单 commit 10c8248,cargo build+28 单测绿后 push feature/jeeflow)。

v1.0.9 — 2026-09-05(crates.io 拓扑序发布于 09-05,tag 09-04) ​

  • 修复.3 兑现:execute_and_jump_to_end_async(submitType=2 驳回路径)在 update + abandon 后直接返回 Ok(Vec::new()),未 fire 任何事件——违反 spec 合并派「办结+拒绝都 fire ProcessInstanceEnd(2)」。补 fire ProcessInstanceEnd(对齐内联办结路径),salvo 集成层监听器 ProcessInstanceEnd → 发起人 NOTICE「流程已办结」由此恢复;新增回归测试(红证 + cargo test --workspace 绿)。

v1.0.8 — 2026-09-04 ​

  • 新增 stats 契约对齐 A–E(wire 裸数组 / stateIn 生效 / trend 缺参报错 / define avg 口径 / define group 4 列映射,与 Java 参考实现逐字段一致)。
  • 新增 CC_CREATE 事件补齐 = CcCreate(4)(P0 抄送知会事件,六语言枚举对齐)。
  • 修复 publisher 单监听器异常兜底(P2,一个监听器 panic 不打断其余监听器,六语言同语义)。

v1.0.7 — 2026-09-01(crates.io 发布成功,tag 09-02) ​

  • 修复「wf 流程消息写路径缺失 / messagePage 恒空」的 salvo 栈引擎侧根因:ProcessTaskStart 事件在 create_task/create_node_tasks 的 3 处落库前 fire(此时 task_id=0),监听器 find_task(0) 落空 → 静默丢,新待办 TODO 从不发出。统一改为在 persist_tasks 落库(save_task + add_task_actor 之后)fire 一次(每任务每操作一次)。与 Java CreateTaskHandler 1.8.20 / go/python/node 1.8.23「落库后 fire」同一 批次对齐。
  • 测试 新增回归 test_task_start_event_fires_after_persist:红证 + 绿证(cargo test --workspace 253 tests 0 fail)。
  • 集成栈 mldong-salvo pin 1.0.6 → 1.0.7 随本批收口(Cargo.toml+Cargo.lock 重锁,cargo check 全绿)。

v1.0.6 — 2026-08-30 ​

  • 修复 processSurrogate/remove 兼容 {ids} 批量:此前只读单数 id → 报「缺少id参数」,「我的委托」页删除不可用。改用本仓现成助手 arg_ids()(数组优先 / 单 id 兼容 / 含 null 报非法)。
  • 测试 A 档 2 例 + 6 类负向载荷;T0 cargo test --workspace core 116 / facade 71 / persist 33 / sqlx 27 全绿;T1 SKIP_MYSQL=0(连 160)真库绿 + 假主机反证(管道有效)。
  • ⚠️ 负向文案仍为 Rust 既有的「缺少id参数」,与其余五语言「id 缺失或非法」存在 drift(已记)。

v1.0.5 — 2026-08-25(crates.io 首发) ​

首个 crates.io 正式版本。

  • 发布 四 crate 拓扑序发布,T0 cargo test --workspace 245 全绿 + T1 mysql-smoke 27 全绿(真库 M1–M4)。
  • 五语言对齐缺口闭环(bootX / salvo 集成反馈):
    • resume mergeVars:execute_task / jump / jump_to_end 三路径以实例 variables 为底、本次提交覆盖(对齐 Go),发起时 f_* 表单字段 resume 可达。
    • 组织取人 7 个 AssignmentHandler 实装:Applicant / Dept(×main)Leader / TaskRoleAssignee 等,注册时捕获 User/OrgUserProvider,空结果跳过节点(对齐 Java)。
    • FormFieldAssignee 查找序:f_ 前缀优先 → 裸名回落 → _NN 后缀去后缀(对齐 Go/Java)。
    • 发起抄送 f_ccActors 数组/字符串双形态解析(对齐 Go)。
    • facade args_to_flow_data 数组/对象原样透传(旧兜底 to_string() 把多选 ApiSelect 的 JSON 数组字符串化——L3 S6 根因)。
    • 雪花 EPOCH 对齐 1288834974657(2010-11-04,同 Go/Java/Python/Node 联邦 ID 空间)。
    • persist 语义对齐 Java/Go:状态字段探测错误传播、information_schema CAST、create_time 落库(8 处 INSERT 补审计列)。
  • SPEC 语言指南 languages/rust/(快速开始 / 引擎 API / 流程定义 / SPI / persist / salvo 集成 / demo)随本版本入库文档站。
  • 集成验收:mldong-salvo(Salvo 0.76 + SeaORM 1.1)薄集成栈一键部署 L0–L2 19/19 + L3 14 过 / 1 固定 skip(S12)/ 0 失败。

v1.0.0–v1.0.4 — 2026-08-24 ​

  • 联调期内部 tag(UI 契约对齐、种子联调、startAndExecute/submitType 分发),未发布 crates.io,被 v1.0.5 取代。

jeeflow · 轻量级多语言工作流引擎