Skip to content

C# 更新日志 ​

当前版本 v1.0.30 · NuGet(Mldong.Jeeflow.Core / Mldong.Jeeflow.Repository.MySql / Mldong.Jeeflow.Persist / Mldong.Jeeflow.Facade 四包,独立 1.0.x 版本线)· 仓库 mldong/jeeflow-csharp · NuGet 版本日期以本仓 git tag 为准;跨语言对齐脉络见 更新记录总览。

v1.0.30 — 2026-10-31 ​

「退回修改、重提直返」首轮发版(tag v1.0.30=commit fec4906,守卫补齐 a255a24, 出口契约修复 c8d0653,四包同号)。条文见 规范 04 引擎操作 「退回修改、重提直返」节。

  • 新增:reapplyMode 节点属性与非法值解析期报错、submitType=6 直返建带 _reapplyContext 的申请待办、submitType=5 重提直接回来源节点、_branchCtx 分支归属 与汇合等齐判据、保留键入口剥离与按实例互斥的串行化。实现落点: src/Mldong.Jeeflow.Core/Engine/ReapplySupport.cs + Engine/JeeflowEngine.cs。
  • 变更(补齐带标记申请待办的四入口守卫):此前只在 ExecuteAndJumpTask 的 nodeName 非空那一支挡了(文案也与他栈不同),拒绝/血缘回退/再次退回三档都会被接受; 现守卫上移到入口(两档一并覆盖)+ ExecuteAndJumpToEnd/ExecuteAndJumpToFirstTaskNode 各补,文案统一为 java 串。
  • 修复(ext 回退契约被新保留键打破):ReapplySupport.HasOnlyControlKeys 把两枚 保留键算进控制键;回退从"ext = instanceExt(同一字典直出)"改为副本再合回 _reapplyContext——旧写法一合回就污染同一响应的 instanceExt 出口。本栈实例变量写回 只吃已剥离保留键的 args,结构上不带内部键。

v1.0.29 — 2026-10-17 ​

audit8 R110+委托 update 修复(四包 1.0.29)。

  • 新增(删除定义守卫):processDefine/remove 删除前校验任何实例存在即拒,批量先整批校验;仓储补 HasInstancesByDefineId。
  • 修复(委托 update 缺键清空):surrogate 列 NOT NULL,缺键清空此前落 null 导致更新失败;现落空串,修平 L2-13 门禁。

C# 引擎(jeeflow-csharp)为联邦第八个成员,独立 NuGet 版本线(四包拓扑序 Core → Repository.MySql / Persist → Facade,demo 不发布)。基于 .NET 10 / ASP.NET Core 10,全 async 五方法(start/execute/jump/jumpToEnd/rollbackToOperator),DDD 聚合根充血模型。2026-09-06 首发日连发 1.0.0→1.0.1,2026-09-08 发 1.0.2(三缺陷修复)。发版通道(Trusted Publishing tag 触发)与坑位见 jeeflow-csharp/docs/PUBLISH.md。

v1.0.27 — 2026-10-16 ​

audit8 R77(tag v1.0.27,引擎 commit d8a3187;NuGet 四包 Mldong.Jeeflow.{Core,Facade,Persist,Repository.MySql})。

  • R77 提交后腿通道:SPI/引擎/MySql 模板三处接线,配 160 真库腿(回滚整批丢弃/提交恰好一次), 条文=规范 12 §12.3.1。全量 dotnet test Jeeflow.sln 543/543。
  • 同批只进测试/文档面的两笔:R91 执行档判据补齐(本栈代码零改动)、R71 仓内文档身份证写法更正、 R85 自 v1.0.2 起断更的 25 个版本节补齐(源仓 docs/CHANGELOG.md,本页由 sync:langs 聚合)。

v1.0.26 — 2026-10-15 ​

audit8 R63+R64+R90 三案并批(tag v1.0.26,引擎 commit 6466a93+a5027b1+2768f74)。

  • 行为变更(决策路由,issues/234 丙-9):decision 节点多条出边表达式同时为真时,改首条真边独走 (此前 foreach 无 break=多路并行流转)。对齐 规范 02 §5 与五栈多数派; 升级前自查 decision 节点出边表达式是否可能同时为真。
  • 修复(issues/231①):TaskModelPropertyKeys 黑名单补 width/height/preInterceptors/postInterceptors 四枚——已解析进模型的键不再重复镜像一份进 ext(与 java hasField 沿父类链上溯同案; 规范 02 头注立法)。未知键照常镜像、声明键照不进(回归判据钉住未误伤)。
  • 行为变更(issues/232 R64):autoGenTitle 时间戳钉秒 yyyy-MM-dd HH:mm:ss(原分钟档; 规范 04 拍 A=秒档,标题专用格式化点)。仓内两处既有测试期望随立法同步改判。

v1.0.25 — 2026-10-13 ​

issues/193 收口:highLight 补全腿的异常逃逸出 catch(tag v1.0.25,引擎 commit fa31998+e703b84)。 条文见 规范 06 §4.6 义务 2。

  • 修复(机制读错才找到真缺陷):卡面原写「求值器抛异常被静默吞」,现读真根因在语言机制—— C# 异步方法的异常一律收进返回的 Task、不同步上抛,而 CollectPath(...) 调用处不带 await 且丢弃 Task ⇒ 紧随其后的 catch 对这条腿永久失明:求值器抛异常时整条补全腿零日志静默中断, historyNodeNames 少一批可达节点。
  • 修法:补 await +删掉那层透传包装(不新增语义,只让既有的 catch 真能接住)。
  • 同案另一半(PHP)不成立:php 侧已由 issues/156 轮落成带原因日志=与 java 同形,零改动零发版。
  • 判据:两枚(修前红=失败:1 通过:1)+变异 M1/M2 各 1 红;全量 518/518。
  • 传播面:csharp→csharp 壳,1 张镜像(候选 54/0/0→晋升)。

v1.0.24 — 2026-10-13 ​

issues/192 收口:strictColumnMatch 门控不完备(tag v1.0.24,引擎 commit f867629+a9231e2)。 条文见 规范 09 · 持久化 §列匹配。

  • 修复(用户可感知):开关关掉(宽松档)时 FindDataKey 仍恒归一反查数据键——本栈与 java 的 对偶腿门控完备性不同步,坏输入下落库结果与参考实现不一致。
  • 前置立案判据:先读 java——java 对偶腿门控完备 ⇒ 不是「参考实现同形」,本栈独家不完备。
  • 修法:FindDataKey 由静态改实例并读同一枚门控,逐字对齐 java(零自创语义)。
  • 判据:六枚真库判据;修前红以变异取得(M1=3 红 3 绿),全量 510→516; 现生产零行为变化(默认档就是精确)。
  • 同轴遗留:元数据腿不吃这枚开关(moon 恒宽松、java/csharp 恒精确)已另案记档,未随本版动。

v1.0.23 — 2026-10-13 ​

issues/180 收口:abandonTask 不再连带把整单置 99(tag v1.0.23,引擎 commit 7c1fc7a+ea60f55)。

  • 变更:任务级废弃只废任务,删掉实例 state 写点——对齐 spec 与 go/python/node; 五栈同批(java/php/rust/csharp/moon),五栈该方法全部零生产调用者(调用面 grep 仅定义处命中)⇒ 现生产零行为变化,收的是「一旦接上就会顺手废整单」的潜伏形状。
  • 判据:三枚+变异;回归全绿。
  • 传播面:csharp→csharp 壳;本轮 5 引擎→6 壳+moon 插件→6 镜像+moon 通道全晋升。

v1.0.22 — 2026-10-12 ​

issues/179 补修(真机探针定案,同一案的第二腿):processDesign/updateDefine 缺 name 时不再撞 NOT NULL (tag v1.0.22,引擎 commit 3a46ce7+4d4ce09)。条文见 规范 08 场景 44。

  • 修复:name/displayName/type 三处改逐字段判空(缺=保持旧值)。改前缺名 content 无条件写 null ⇒ UPDATE 撞 name NOT NULL(MySQL 1048)⇒ 动作级事务整体回滚、缺名快照存不进, 而 redeploy 随后读到含 name 的旧快照 ⇒ 同一次缺名调用两条腿两个答案(对外静默 code=0)。
  • 为什么守卫必须在真库层证:内存腿 ?? stored.Name 会把 null 遮罩掉,内存测试照不出这一形。
  • 判据:BlankNameCondition179Tests 五枚+真库腿新增 MySqlDesignDraft179Tests (摘守卫真库腿红 Expected 0 Actual 99999999);全量 507/507。
  • 传播面:csharp→csharp 壳;与 java 同轮(v1.8.48),4 壳 4 镜像全晋升。

v1.0.21 — 2026-10-12 ​

issues/179 前半(tag v1.0.21)。空值当没填这条通用放行在定义定位腿上的后果收口。

  • 修复(后果级):getLastByName 缺名/空串/全空白三档此前丢掉 name 条件继续查 ⇒ 返回另一条流程的定义且 code=0;缺 name 时 saveDeployedDefine 的版本号会 +1 到别的流程头上。 本版三档统一报「缺少processDefineName参数」。
  • 拒收边界:deploy/designDeploy/designRedeploy 缺 name ⇒ 报错且不落行。
  • 本卡新发现第三腿:designRedeploy 的缺名替换别流程(与 java 双向核实)。

v1.0.20 — 2026-10-12 ​

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

  • 变更(用户可感知):一键发起并办理的那条任务办理人记成系统哨兵,真实发起人不再同时出现在「我已办」。
  • 判据:跨栈门禁 L2-43 同轮落格。
  • 传播面:csharp→csharp 壳;本轮总传播面 8 引擎→13 壳+moon 插件→14 张镜像全晋升。

v1.0.19 — 2026-10-12 ​

issues/145 · csharp 第二轮(tag v1.0.19,引擎 commit b203fac+e91e1e2)。 首候选门禁首跑 32/18 红 ⇒ 停晋升、按容器日志复现取证后修。

  • 缺陷①(后果级,事务接通才暴露):默认 id 生成器非缓存——IdGenerator ?? new AtomicIdGenerator(...) 每次访问新建一枚,每枚首个 NextId()=(ts<<22)|0|0 ⇒ 同毫秒重复 id。壳侧不设 ctx.IdGenerator, 事务接通后参与者行亚毫秒连续 INSERT 打爆 ⇒ 20 处 Duplicate entry … wf_process_task_actor.PRIMARY。 1.0.17 时代被池连接往返 ≥1ms 的概率遮住("旧形状碰巧不炸"的典型)。
  • 缺陷②:RemoveDesignAsync 裸建命令不绑环境事务 ⇒ MySqlConnector 强制绑定报 not the connection's active transaction(3 处)。
  • 修法:??= 懒建即缓存+两处裸命令改走 NewCmd(全仓 sweep 后裸建只剩两条 NewCmd 定义)。
  • 判据:T0 两枚(固定钟 ⇒ 修前确定性红)+真库 T145_8+变异 M-A/M-B 逐处红后字节级还原; 回归 498→501/501。

v1.0.18 — 2026-10-12 ​

issues/145 事务七条债 · csharp 切片(该案第 4 条收口,tag v1.0.18,引擎 commit 585b9e8+f24fffc)。 条文见 规范 12 · 事务与持久化。

  • 修法:① MySqlTransactionTemplate.ExecuteInTxAsync 加 join 支(AmbientConn 已绑定则并入最外层: 不另开连接、不重复 BEGIN、提交/回滚归最外层);② JeeflowEngine 公开 InTxAsync+ JeeflowFacade.FlowAsync 把整次 dispatch 包进去(信封在事务外生成=先整体回滚再转失败信封); ③ demo mysql 分支注册模板;④ persist 写腿并入动作事务的 csharp 腿:DbDynamicTableWriter 加 AmbientTxProvider (4 处自开连接统一走 LeaseAsync,借 ambient 不释放;未接线时行为与修复前逐字节一致)。
  • 判据:真库 MySqlTxTier145Tests 7/7+变异四处逐处红;回归 498/498。
  • 一条被推翻的直觉:曾评估「门可降级为可选」——双引擎实例真并发跑出 doubleWins=3/3 ⇒ 无门时两条腿都能成功,门是"并发恰一次"的必要守卫,前提不成立、门保留。

v1.0.17 — 2026-10-11 ​

issues/174 收口:redeploy 原地替换保留 version/state(tag v1.0.17,引擎 commit 6b8a952); 同批带上 issues/162 的 csharp 腿。条文见 规范 08 场景 42。

  • 修复(用户可感知):processDesign/redeploy/processDefine/redeploy 此前把 version/state 覆成 1,已办结/已废弃定义重部署后行状态打回。五栈同批(java/go/python/node/csharp)。
  • issues/162 csharp 腿:highLight 降级面保留+带原因日志,不再静默吞。
  • 跨派系单列:本栈走的是与多数派不同的事务/异常机制,故在案文里单列一格逐处核实。
  • 手工 tag 提醒:bump-version.sh 的 commit_and_tag 不含 csharp,本版按 v1.0.16 先例手工 commit+tag。
  • 传播面:csharp→csharp 壳;本轮合计 5 引擎→11 壳→11 张镜像。

v1.0.16 — 2026-10-10 ​

issues/154 ①④(NuGet 四包,引擎 commit 337ea41/tag 04c1b56)。条文见 规范 06 §4.6。

  • 新增:approvalRecord 每行补首列 id(字符串出口)。
  • 变更:行集排序并成 id ASC(OrderBy(TaskId ?? 0L)),与 Java/Go/Python/Node 同一条尺子。

v1.0.15 — 2026-10-08 ​

issues/152 委托三件收口(NuGet(四包),引擎 commit f2ef84b)。规范条文见 规范 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.14 — 2026-10-02 ​

NuGet 四包同代发(Mldong.Jeeflow.Core / Persist / Repository.MySql / Facade,net8.0;net10.0 双目标)。

  • 新增(issues/115 §3-8):门面第 47 个 action processTask/removeTaskActor; §3-8/6.A 的 action 清单与条数门禁前进到 47 ⇒ 第 47 个 action 从此在两栈门禁(csharp + rust)覆盖内。
  • 修复(issues/137 A §3-4):补上本栈自己的断链——ModelParser 没把根上 expireTime 搬进 ProcessModel(与 Java 基准同一处漏,同批修掉)。
  • 修复(issues/137 §3-1/§3-6):门面固定文案+判别式五条,底层原文进 InnerException/stderr; 删除腿「原值 ∪ trim 值」两形并集(Core + Repository.MySql)。
  • 修复(issues/137 D):相对档前缀判非负——四档各加 >= 0,不换成正则禁符号;E 档只加测试。
  • 修复(issues/137-G/139):JSON 主腿与 bizData 出口只给固定文案。
  • 测试:dotnet test ⇒ 通过 481 / 失败 0 / 跳过 0(1m37s;Category=mysql-smoke 那批未被 filter, 故 T0 与真库腿同跑)。安装侧核验见总览页脚注(nuget.org 下载腿 200 + 1.0.99 负向对照 404)。

v1.0.13 — 2026-09-30 ​

  • 新增(issues/142 A 批):记录类历史行真落库——落库通道选在引擎漏斗 PersistTasksAsync(本仓约定:模型/处理器层从不碰 IProcessRepository),新增 Execution.HistoryTasks 独立队列,DOING 循环后另起一段;留痕行补写 ActorId 与 FinishTime(第 1bis 条;ExpireTime 留 null);顺带把参与者集合形状收干净—— op 为 null 时旧写法往 actor_id 灌一条空串("空归属值读全库"的进水口),改空集合不插行。 任务类零参与者照常建单。
  • 变更(issues/142 B 批 · spec 06 §2.11):PageQuery.NormalizeActors 升格通用入口, 补 NormalizeActors(object) 两形入口(逗号串/数组/标量/嵌套集合同一枚;数字按 InvariantCulture 收敛;字典与类型名形状整体丢弃)与 NormalizeActorValue 单人档; NormalizeCcActors 保留为转发(NuGet 已发布不删)。四条任务写点接同一枚—— 破坏面:transfer 的 fromActor/toActor/operator 数组不再被串成 .NET 类型名; startAndExecute 的 f_nextNodeOperator 数组不再串成 List\1[System.Object]; CreateTaskHandler消费腿的数组[""]不再被当"已指派"(下一节点零参与者死锁黑洞); 主键档taskId<=0响亮报错;两仓removeTaskActor` 删除位 trim。
  • 修复(issues/143 + G4 义务 2/3 补票):本栈是"无声停住"那一派,两件都没兑现—— ① ParseNode 认不出类型时补一条带 nodeId +实得类型串(含 snaker: 前缀原样)的 WARNING; ② 悬边(Target==null)ExecuteAsync 补落穿 WARNING + 令牌停住,不再无声 no-op; ③ 类型表补小写 subprocess 档(G4 义务 3 的旧写法别名)。

v1.0.12 — 2026-09-29 ​

  • 新增(issues/127 + 132):A 套码表补 TaskComplete(5) … InstanceTerminated(9); 办理抄送腿进引擎(只 ExecuteProcessTaskInTxAsync 一条腿);撤回只 fire 8; EventCodes132Tests 钉住码表与序列。成员名本就是规范名 ⇒ §11.6 别名义务不适用。
  • 修复(R2-1,照 java 移植三段式):EndProcessHandlers 就地 fire 改为 登记 → 上收 → 两处 flush(PersistTasksAsync 的 UpdateInstanceAsync 之后 + 发起路径)。 同轮抓出父实例终态不落库这一同族缺陷:级联里只把父实例的新任务上收、父行没人写 ⇒ 永远停在 10;flush 内补写后由「父子两支各只播一次且回调时行已是 20」钉住。
  • 探针形状:本栈 MemoryRepository.FindInstanceByIdAsync 已是 clone 快照语义 (与 java 的活引用相反),故探针仓只需补「写库次数」这一维——只比 state 照不出「一次没写就播」。
  • 测试:dotnet test 245/245,确定性子集(Category!=mysql-smoke)221/221。 变异:删两处 flush ⇒ 时机断言红 (Expected:["TaskComplete","ProcessInstanceEnd"] Actual:["TaskComplete"]); 把 flush 挪到写库前 ⇒ 5/5 红(Expected: 20 Actual: 10)且幽灵事件格同红。
  • 已知:真库套件 MySqlBehaviorSuite 用固定号段 910101+ 顺序发号, 多会话并发必互踩(红数在 0/4/12/15 间漂移、单跑全绿)——跨栈夹具设计问题,本轮未改。

v1.0.11 — 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 任务行 不改写")原样保留,实例级守卫排在它之前。落点:Error/JeeflowException.cs 加 WfErr.WithdrawInstanceNotDoing=20010009 + 聚合根守卫 (取时仍走 clock ?? SystemClock.Instance,不退化成裸 DateTime.Now)。dotnet test 228/228(基线 220)。 csharp 栈 130 侧无需改动(静态类型存不进字符串)。

v1.0.10 — 2026-09-28 ​

  • 修复(issues/126 案 A):本栈是八栈里唯一已有求值器的(FlowUtil.ProcessTime(expire, args, clock),带 IClock), 但只有回退那支在调 ⇒ 补齐四支:普通建单 / 串行会签首位 / 并行全员 / 串行推进出的下一位成员 (Handlers.cs:410,绕过建单 helper 的直建路径),回退那支并入同一 helper(变量源与钟取法逐字不变)。 全程 clock ?? SystemClock.Instance,没有一处退化成裸 DateTime.Now——它是域层唯一带钟注入的栈(issues/120 落点)。
  • 测试 新增 ExpireTime126Tests.cs 六格;dotnet test 失败 0 / 通过 220(基线 214), 单复跑 Category=mysql-smoke 24/24(该档要 JEFFLOW_DB_PWD,取不到 env 时恒红属环境红不是行为红)。 变异对照两层:求值换 now ⇒ 4 红;摘掉第五处 ⇒ 全量正好红 1 格(断在「第二成员必须带到期」)。
  • 它报出的缺口反过来补了参考实现:「并行会签全员」这一支 java 自己也没测 ⇒ java 侧补正/负两格(167842e), 摘掉并行那处会红在「成员 [u1] 的行必须带到期时间」。csharp 侧该格仍缺,已记进台账。
  • 跨栈一致性(同批八栈一起发,基准=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.9 — 2026-09-28 ​

  • 修复(issues/129 案 A,与 Java 1.8.32 同题):门面 ToStr(args.GetObj("operator"), "user1") 只在 null 时兜缺省 ⇒ 新增 OperatorArg()(Trim 判空回落 user1)替换 ActionsMain 9 处 + ActionsExt 3 处;第二层有两条仓储路(MySqlRepository.BuildWhere 与 MemoryRepository.ApplyConditions),只修 MySQL 那条会 T0 绿而生产红 ⇒ 两处同形改判"归属列空值 ⇒ 空页",归属列清单收在 PageQuery.OwnershipColumns 一处定义、两仓共用。只收 EQ 归属列,m_LIKE_* 通用放行不动(三格哨兵钉住)。issues/114 的 withdraw 硬必填未动。
  • 测试:全套 214/214(改前基线 211 + 新 3 件:门面三档并排、内存仓储直喂空值、MySQL BuildWhere 拼串探针 WhereProbe 不连库);带 JEFFLOW_DB_* 指向 160 的一次含 T1。
  • 变异对照三发各自隔离转红:只回退 OperatorArg ⇒ 门面件红;只摘内存守卫 ⇒ 内存件红;只摘 BuildWhere 守卫 ⇒ 拼串件红;三文件按 sha256 还原。
  • 线上复验:160 demo 部署 v1.0.9 后四出口空串档 = 4 / 5 / 1 / 2(修前 25 / 46 / 24 / 15)。
  • 发版核验:清掉 NuGet http-cache 后集成壳 dotnet restore 解析到四包 1.0.9 并 dotnet build 0 错误(本机 api.nuget.org 被透明改写到 nuget.azure.cn ⇒ 安装侧为凭,curl 状态码不算证据)。

v1.0.8 — 2026-09-28 ​

  • 修复(issues/128 · ext.isFirstTaskNode 出口覆写):processInstance/detail.tasks[] 与 processTask/detail 两处出口把行上值无条件盖掉(现算值覆盖持久化的 isFirstTaskNode),与规范「行上值优先、缺键才现算」不符——建单侧本就合规(既有测试钉着),违约只在出口,所以正格用例在带病实现下同样能过 ⇒ 那正是本缺陷逃过 207 条既有测试的原因。
  • 判据(新增 FirstTaskNodeExitTests 三格):只有"行 false / 行上脏值"两格有鉴别力,正格作为回归保留;行上值先取一次再写两处出口(否则第二处会读到第一处刚写的值——写这段时自caught的坑)。
  • 测试:dotnet test 211 件全绿(当时基线);变异对照:还原无条件现算 ⇒ 两格红。NuGet 安装侧回拉 1.0.8。

v1.0.7 — 2026-09-27 ​

  • 修复(issues/125 · SQL 侧数据库时钟,与 Java 1.8.31 / Go 1.8.31 / Rust 1.0.16 同题):MySqlRepository.StatsPendingAndOverdueCountAsync 的逾期判据原写 expire_time < NOW()——MySQL 的 NOW() 取 @@session.time_zone 的墙钟,而 expire_time 是引擎钟写进去的裸墙钟 ⇒ 一个 SET time_zone(或换一台默认 UTC 的托管库)就让待办逾期计数差一个时区偏移,并且与内存仓 MemoryRepository 不同数(它早就用 Clock.Now)。本栈其实早就有时钟出口,只有 SQL 仓绕过了它:现在改绑 Clock.Now(= 本类写 create_time / update_time 的同一把,来自 ServiceContext.ClockOrDefault),SQL 变 expire_time < ?,方法内只取一次、pending / overdue 两半共用。注入能力零成本继承(FixedClock 直接可用)。
  • 判据(新增 tests/Mldong.Jeeflow.Tests/StatsClockTests.cs,160 真库;夹具 931000–931099,并额外挂一条真实 wf_process_instance 行——本仓的孤儿自愈会把"实例不存在的任务"当垃圾扫走,不挂实例的夹具会被自己人清掉;断言用"其余行 + 夹具"的差量 ⇒ 抗并发插入):注入即变(有牙)——FixedClock 前移 2 小时 ⇒ 逾期 1→2,旧实现写死 NOW() 时钟挪不动即红;边界——expire_time IS NULL 的行钟拨到 +30 天仍不计入(只有三条带到期时间的行);回归——pending 半边不受钟影响,同注入值重复调用读数稳定;危害见证——同批夹具按旧写法 expire_time < NOW() 直查,会话 +08:00 与 +00:00 下读数必须不同,且回读 @@session.time_zone 自证 SET 真落到这条连接,相同就判失败(不给恒绿死格留活路);形状门禁——方法体剥掉整行注释后不许出现 NOW(),必须是 expire_time < ? + Clock.Now。
  • 口径说明:本栈不做"仓储读数跨会话时区等值"的实弹——MySqlConnector 的连接池不让外部把仓储钉在指定时区的物理连接上。该等值判据由 Go 栈的 stats_clock_test.go 承担(四栈里只有它做得到),本栈用"注入即变 + 旧写法跨时区必不相同"两条覆盖同一病灶。
  • 测试 dotnet build(多目标 net8.0/net10.0)0 错误 + dotnet test 207/207 全通过(0 失败 0 跳过)——本组用例不吃 SKIP_MYSQL,SKIP_MYSQL=1 会让整组抛异常(那条开关会把未执行的用例计成通过,2026-09 已废弃)。变异对照:实现换回 NOW() 并删绑参 ⇒ 注入判据与形状门禁同时红,还原后绿。
  • 发版核验 NuGet 四包 Mldong.Jeeflow.{Core,Repository.MySql,Persist,Facade} 1.0.7 由 tag 触发 CI(Pack → OIDC 临时 key → Push)发布,清空本机 flatcontainer 缓存后四包 .nupkg 回拉全命中;下游 mldong-csharp-jeeflow 壳 dotnet restore 后 project.assets.json 实测解析到 Mldong.Jeeflow.*/1.0.7。

v1.0.6 — 2026-09-24 ​

  • 变更(issues/124 变量出口立法,对齐 Java v1.8.30 基准):ActionsMain 的 processInstance/detail 出口 variables 更名为 ext(inst.Variables ?? new FlowData()),JeeflowFacade 任务行的 variable / instanceVariable 原串摘除;唯一出口 = ext(实例侧)+ instanceExt(任务行侧),空变量出 {};docs/action-manifest.json 响应字段说明同步;持久层 variable 列不动。
  • 测试 dotnet test 全绿(含空变量负向:detail ext 出空对象);NuGet 四包拓扑序发布、1.0.6 回拉 302。

v1.0.5 — 2026-09-23 ​

  • 修复(issues/123 判据④「enabled 脏值不算生效」):根因不在判据代码而在驱动——wf_process_surrogate.enabled 建表是 tinyint(1),而 MySqlConnectionFactory.ConnectionString 没关 TreatTinyAsBoolean,MySqlConnector 默认把 tinyint(1) 当 bool:库里存的脏值 2 读回来是 true,GetInt 折成 1,v1.0.4 那道「只认整数 1」被驱动静默改写。只有 ④ 红是因为 0/1 经 bool 往返不变、唯独 2 会被折成 1(同时违反条款 6「双仓同答案」)。
  • 修法 落在唯一的 DSN 出口:连接串追加 TreatTinyAsBoolean=False;新增 MySqlConnectionFactoryTests 断言该开关在连接串里,并带反向自证(不关时该键不存在)。
  • 发版 tag v1.0.5 → CI 四包拓扑序四个 Successfully created package + PUT …/api/v2/package/;回拉核验两处 flatcontainer index.json(nuget.azure.cn 镜像与 api.nuget.org)均列到 1.0.5。⚠️ 途中一次假阻塞:dotnet add package 连撞 10+ 次 NU1102,不是没发出去,而是 dotnet http 缓存里的 index.json 还是旧的 ⇒ dotnet nuget locals http-cache --clear 后立即解析成功。判发布要看索引真值,别被本机缓存骗。
  • 跨栈验证 csharp 壳 pin 四包 → 1.0.5(restore 通过、base+1、强推 SYNC 2726f706)→ 候选镜像(第一次构建因 scp/tar 截断失败,重试即过)→ 门禁 PASS=31 FAIL=1(唯一红 L2-18=门禁支间未清场,非引擎缺陷)。委托五排法复跑转绿:D 排 4/4、E 排 4/4(修前 3/4,红固定在最末那格)。

v1.0.4 — 2026-09-23 ​

  • 修复(委托判据取行顺序,对齐 Java 参考实现):ProcessTask.cs 新增单条裁决 IsEffective(Enabled 严格 1 / 被委托人非空白且非本人 / 窗口覆盖判定时刻,起止 null = 该侧不限),内存仓与 MySQL 仓共用;NewestInScope / QueryNewestSurrogateAsync 只按 operator + 作用域取 id 最大,SQL 撤掉 AND enabled = 1 AND surrogate <> ? 与窗口谓词(旧形状=先滤后取 ⇒ 历史窗内记录永久生效)。精确作用域判否(含池空)后仍看全流程作用域的最新一条,不判否即止;窗口比较走 ClockOrDefault.Now(引擎钟),无 DateTime.UtcNow 混基准。
  • 修复(出口文案统一):退回上一步两格对外 msg 删 20010007: / 20010008: 码前缀(Mldong.Jeeflow.Core/ProcessInstance.cs 两处),改 Java 逐字中文文案;对外恒 code=99999999,异常断言补 Assert.DoesNotContain("2001000", msg) 反闸。
  • 测试 SurrogateAutoApplyTests 补三格(五种不生效形状各压过旧的窗内有效行 + 正向对照),MySqlBehaviorSuite 补真表侧同形状用例;dotnet test ⇒ 182 通过 / 21 失败——21 条全是 Access denied for user 'root'@'…' (using password: NO),属缺库凭据未测(未把凭据写进任何文件),非行为红;内存侧 --filter ~Surrogate 31 通过。
  • 变异对照 会话内副本把三个 src 还原到旧形状 ⇒ 失败 1 / 通过 202,红的正是新增的「最新一条裁决」用例(10 条形状级失配);改回新形状 ⇒ 203 全通过。
  • 发版 tag v1.0.4 → CI 四包拓扑序(Core → Repository.MySql / Persist → Facade)推送成功(日志四次 Successfully created package)。本机 flat-container 探针当时仍 404 = 镜像通道滞后(见 v1.0.2 的 ~25min 注意项),以 CI 推送成功为凭。
  • 跨栈验证 13 个集成栈候选镜像门禁对拍:委托判据格 L2-17 全绿(13/13,csharp 栈同判),13 栈逐格 0 分叉;L2-18 13 栈同形同错=门禁夹具支间未清场,非引擎缺陷。

v1.0.3 — 2026-09-22 ​

09-22 夜发版轮(issues/120 时钟基座 + issues/121 P1/P2 血缘回退)C# 侧代次;tag v1.0.3(19:26),bump commit 896d81d。

  • 新增(121 P1):建单写 ParentTaskId 与行级 isFirstTaskNode(0ff5ac4); 引擎控制键不算「任务变量非空」,P1 不打断 ext 回退实例变量(ffaccca)。
  • 变更(121 P2):退回上一步改血缘版(a52010c),action-manifest 里 submitType=3 的 「沿首入边回退」旧口径删掉(81fbaf0),过时的"拓扑版/待对齐"说明一并清(2f65247)。
  • 修复(T0 核账抓到的真缺陷):CreateHistoryTask 此前写死 null/false, 改为按 Java 参考实现传 parent 与首节点标记(b1f16f3);引擎侧补「无血缘三种形状」用例, NULL 老行与悬空 parent 各走独立判定(9871372)。
  • 发版核验:NuGet 四包(Trusted Publishing,tag 触发);判发布看 CI 日志里的 PUT … 201 Created 或 壳侧 dotnet build 实际解析到的版本——本机 flatcontainer 探针走 nuget.azure.cn 镜像会滞后。

v1.0.2 — 2026-09-08 ​

  • 修复 三缺陷(tag v1.0.2,Release run 34163519251 全绿,commit aba6480): ① MySqlRepository.GetStr 列型容错——宿主审计列 create_user/update_user 可为 BIGINT,GetString 直接 InvalidCastException,改 GetValue + invariant 转字符串; ② BindSurrogate insert 补 update_time 参数(11 占位符只绑 10); ③ MetaTableReader 补 : IBizDataReader 接口声明——Facade 的 bizData 按接口取 reader,类漏声明致按提示装配也失效。
  • 集成联动 mldong-csharp-jeeflow 同批补 persist PrimaryKeyGenerator(ctx 雪花)+ BizDataReader=MetaTableReader+noop(对齐 gin 集成口径),集成 gate24 24/24(候选栈 csharpj-cand,T011 补完收口报告)。
  • 验证 引擎 153 单测全绿(T1 160 真库 15 项);生产镜像 3d8f24e1… 已晋升。
  • 注意 发版后 nuget.org flat-container / 检索索引有 ~25min 延迟(flatcontainer 404→200),CI 成功 ≠ 立即可 restore。

v1.0.1 — 2026-09-06 ​

  • 变更(包元数据完善)四包内嵌 README(nuget.org 包页直接展示,消除 "missing a README" 警告)+ PackageLicenseExpression MIT → Apache-2.0(对齐联邦七兄弟仓 LICENSE;1.0.0 已发 MIT 属首发笔误,新装请用 1.0.1)。
  • 变更 仓库 README 全面扩写:架构图 / 包矩阵 / 快速开始(内存与 MySQL 双装配)/ 契约速览 / 测试矩阵 / 文档索引 / 发版通道;补 LICENSE 文件(Apache-2.0,与 java/php/rust/moon 同文本)。
  • 发版通道修复留档 NuGet/login@v1 输出名为大写 NUGET_API_KEY(小写引用取空 → push 401,1.0.0 首发时实证,已固化在 release.yml)。

v1.0.0 — 2026-09-06(首发) ​

  • C# 首发版本(第 8 语言)。引擎全量移植:start/execute/jump/jumpToEnd/rollbackToOperator 全 async 五方法;聚合根充血模型(实例 10/20/30/40/45/50/99 + 任务 10/20/30/40/50/99)。
  • 会签:串行逐个推进(任务变量 operatorList_{node} / loopCounter_{node} / nrOfInstances_{node})、并行全量/表达式门控(#nrOfCompletedInstances 等)、ONE_VOTE_VETO 一票否决、软拒绝 flag、残留废弃。
  • 事件:INSTANCE_START / END(终态两路)/ TASK_START(落库后 fire)/ CC_CREATE(逐抄送人直传),逐监听器隔离。
  • 45 action 统一门面 + 契约出口层(id 全字符串化递归含复数、时间 yyyy-MM-dd HH:mm:ss、恒五键、stats int 出参);契约基线与 java JeeflowFacade 实查双向无差集(docs/action-manifest.json 固化)。
  • MySQL 仓储全量(分页五键 / m_ 解析 / NULL 安全 / 级联更新 / 参与者全量覆盖+去重追加 / 纯列 stats);persist ARCHIVE/SYNC 双模式、字段权限双格式键、状态字段列探测、元数据子表递归。
  • 验证:T0 153 用例(memory)+ T1 全绿(160 真库)+ T2 冒烟 20/20(demo/smoke_test.sh)+ stats 一致性 15/15 逐字段一致(快照 consistency/csharp.json,与 moon.json 全等)。
  • 发布通道:Trusted Publishing tag v1.0.0 → GitHub Actions OIDC 换临时 key 拓扑序 push(run 34004792139 全绿);回拉验证通过(临时工程 dotnet add package 四程序集加载运行全通)。
  • 前端:jeeflow-ui /csharp-api 代理 + ?lang=csharp 分段已接(jeeflow-ui f1d889b);demo 内存/MySQL 双存储(:8093)。

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