Commit Graph
57 Commits
Author SHA1 Message Date
ChaiHaoandClaude Opus 5 8cb00d1ff6 三面拆分⑫:设计台九区一级目录 —— 一区一内容,测试台收成单例仿真
设计中心从「蓝图 + 四库」摊成九区,顺序即设计的次序:
蓝图 → 触发器 → 流程包 → 活动库 → 工具箱 → 数据域 → 知识库 → 大模型 → 测试台。
触发器与大模型从「并进流程包 / 塞在系统区」里拿出来独立成区 —— 前者与流程包平级
(不入包结构、不随包版本),后者是设计者天天要碰的东西;知识库先立个诚实的空占位。

一区一内容,于是区内页签栏整条删掉(壳层在只剩一格时收起):
  · 流程包:总览的三枚计数并进货架顶端
  · 测试台:入站邮件演练移到触发器区就地验(它验的正是那一区定的规则)
  · 大模型:从系统区拆出,系统区只剩通道实例

测试台一次只跑一条流。起单前先销毁上一单,刷新页面能认回在跑的那一单,
「停止仿真」把工作流连同它派出的任务、工单、实例、留痕一并拔掉 ——
不留半单挂在别人工作台上。实测:起单 → 1 单落到 AI 工作台 → 停止 → 库里零残留。

功能工具补中文名(migration 0018,读回退到逻辑名),治理台一律主显示中文名。
顺带清掉几处说教式文案(「这些是工具,不是模型 —— 模型是它们跑在上面的发动机…」那类)。

五闸:typecheck / lint / depcruise / test 绿;api:check 快照随本提交入库。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-29 04:35:36 +08:00
ChaiHaoandClaude Fable 5 ffb71def4b 修:工作台列表不实时刷新、办完的活不进「已完成」—— 两个 bug 叠在一起
用户实测报的。查下来是两处各自独立、叠在一起才显形的缺陷:

**① SSE 订阅层的 queryKey 与实际键对不上(推送白推)**
TanStack 的失效按**前缀**匹配,而工作台的键都以 `desk` 打头
(`['desk','tasks']` / `['desk','task',id]` / `['desk','messages']`);
订阅层却手写着 `['tasks']` / `['task',id]` / `['messages']` —— 一条也匹配不到。
推送照发、画面纹丝不动。修:订阅层一律取自 `queryKeys`,不写字面量;
`['approvals']` 也收进 queryKeys(app-shell 原来手写)。

**② 推进器推完不广播(压根没推送)**
只有派发器(事件投递)广播;而任务从在办走到终态是**推进器**推的 ——
于是「办完的活不会自己挪到已完成」。修:推进器在 runtime/terminal 真变了时
广播 task + workflow(比对本轮前后,不变不发,免得每两秒给在线浏览器发噪声)。

实测(全程用 AI 测试账号,不碰真人工作台):起单 → 以 AI 身份答验收单 →
浏览器停在工作台,探针记到**任务列表自动重取 1 次**(修复前 0 次),
SSE 三条 touch 齐到(task / task-advanced / workflow)。测完清运行数据。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-29 03:46:37 +08:00
ChaiHaoandClaude Fable 5 48bc664c7e 仿真测试台(界面):装配一次试跑 → 起单 → 全链 TRACE 看穿(frontend-design 专项)
测试台从「只能造一封邮件」升级成仿真试跑台,两种试法同屏切换:

**装配态**:选生效版流程包 → 按 callInterface.input 现生成参数表单(必填标出)→
节点指派表(每个活动点/审批点选账号,留空即轮值)→ 起单试跑;
起不来把后端判词原样上屏(如「must have required property 'rfqRef'」)。

**观测态**:WF 工作流图签 · DSK 任务落到了谁的工作台(明说测试台不代答)·
**TRC 全链 TRACE(签名元素)** · NOD 节点实例。
TRACE 做成一张走查记录纸:左半 span 树(细线方角枝线),右半同轴甘特(方格纸底纹)。
三处判断值得留:
- 轴的右端**只认已知时刻,不认 now** —— 按 now 收口会被不收尾的工作流 span 拉到
  十几秒,真干活的两三毫秒压成发丝;而根 span 常常一辈子不收尾,拉到「此刻」
  等于替它编了个结束时间
- 未收尾的段用剖面线 + 箭头(图纸的「未完待续」画法)
- 包络(流/节点自己不干活)画尺寸线而非实心条 —— 实心会盖过真正干活的那几笔
颜色只花在动作三色(工具石青 / 模型靛 / 人黄铜),结构走灰阶。

顺带修:区头 desc 是纯文本渲染,里面的 markdown `**` 会原样露星号 ——
六处全清;测试台页签名改「联调试跑」(它现在不止入站邮件)。

实测:真起单三次,指派两处都落地(TRACE 的 attributes.assigneeId 与节点实例
受理人一致);浏览器核对装配态与观测态。五闸全过。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-29 02:46:31 +08:00
ChaiHaoandClaude Fable 5 967627d753 三面拆分⑳:属性卡图纸化重排 —— 检验单判据、索引栏拣选、明细表映射(SubAgent 设计)
frontend-design 技能专项重排流程包详情下半区三卡(仅呈现,零逻辑改动):

- 激活双判据卡 → **检验单**:判据一·图编排 / 判据二·活动装载两个检验格,
  各带面头状态字;全清盖检验章(编排闭合 CHK·1 / 装载齐备 CHK·2,反向微旋),
  两面全清出黄铜裁定带「两面都齐 —— vN 可运行」;违规行红左线方角压回
- 节点属性卡 → **索引栏 + 明细区**:节点/边两行分度带(行首 mono 竖签带计数,
  22px 方角芯片,行间虚线),下方唯一滚动层;空态改居中图纸空页
- 节点态两列手排(语义成组):身份与命名+输入+输出口 | 类型与责任+链接活动实现;
  小卡按内容自高(去 250 一刀切),卡头 mono 微签,字段改**底线填写式**
  (mono 大写微签标签、readonly 虚线底、聚焦转钢蓝)
- 边态映射卡加 mono 列头(下游字段/←/来源/口名/路径·值),
  与行共用 6 列 grid,起单载荷/常量的值输入跨列合并 —— BOM 式明细表
- 钩子类名(g-pick/g-ver/g-exfacet/g-props/g-maprow)全保留;
  顺手清一句过时空态文案(「节点填岗位」→ 负责人运营时分配)

三态截图核对(空态检验章/A1 两列/E7 明细表)+ 五闸退出码全过。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 22:22:02 +08:00
ChaiHaoandClaude Fable 5 f145bde875 三面拆分⑲:审批点卸岗位 —— 负责人一律运营时分配,绑员工组,实例记 assignee
模型(用户定):审批点不绑岗位;节点负责人是运营时分配的,绑定到员工组。

- 契约:approval 节点删 approver(功能属性只剩驳回走向/催办/委托消息);
  CLOSURE_VIOLATION_KINDS 删 missing-owner-position(岗位不入编排,无岗可核);
  治理审批列表删 approverPosition 字段
- 运行时统一口径(活动点=审批点):工作流绑了员工组按组轮值(组员并集最闲者先),
  没绑组全员轮值;staffId 稳定排序保证确定性,组员全不在岗退回全员。
  ADR-011「绑定先于策略」随岗位退场 —— 工作组快照的成员集合成为轮值池
- 实例记 assignee(迁移 0014 node_instance.assignee_id):分派结果是流转事实 ——
  审批箱收件(i.assigneeId === me)、裁决权(同一判据)、员工面链条报实际承接人、
  治理台审批列表报人,全部按它认,不再有岗位比对
- closure 卸 positions 入参;desk/desk-approval/governance-ops 三路由改口;
  web 属性卡删「审批岗位」选择与警示、positions 管线拆除;种子 A5 卸 PM;
  导出依赖文件审批段只留编排语义

测试:closure 25、save-package 6、seed 8、graph-to-pkg 5、端到端八例真库全绿;
五闸退出码全过。库:迁移 + v4 就地同步(唯一生效版)。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 21:24:41 +08:00
ChaiHaoandClaude Fable 5 ecfaef1463 三面拆分⑱:属性卡台面化 —— 定高双列,边属性整宽一行排开
- 节点属性卡与激活判据卡**同排定高 560px**:行高由属性卡定,判据卡拉伸补齐;
  内容超高在卡内滚,不把页面撑长 —— 台面件定形,不随内容乱长
- 节点属性两列小卡(等高 250、内部滚):身份与命名 | 类型与责任、输入 | 输出口
- 边属性整宽单列(g-eprops):条件与映射各占满一行;
  映射行 nowrap 一行排开(目标 ← 来源类型 口 路径 删除),输入收缩共分宽度,
  不再有换行错位的怪布局

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 20:19:25 +08:00
ChaiHaoandClaude Fable 5 a10a7b2855 三面拆分⑰:编辑即其身 —— 保存写回本版,新版本只出自「新建」
用户问:为什么编辑一个版本、保存就自动多一个副本?那不是我要的。
旧机制「保存恒新增版本号」改为:

- savePackage:pkg.version 已存在 → **就地写回该版**(号不变、状态不变);
  `asNew: true`(新建按钮)或新流程首版才铸新版本号(服务端算,不生效)
- 底线三道,一道不少:
  ① **在途钉版不可变** —— 该版有未完结工作流(按 (包,版本) 钉定义)→ 409,
    一字不落库;「就地覆盖会改掉在途正在读的编排」由这道闸守,不再靠只插不改一刀切
  ② **生效版必须始终可运行** —— 写回生效版跑闭合闸,不闭合 412 带整份报告;
    未生效版画图不检查、随手存
  ③ **陈旧编辑不复活** —— 流程存在而版本号已被清理 → 409(实测:停在已删旧版上的
    标签页发来保存,把老内容静默复活成了新版本;StaleVersionError 拦死)
- store:新增 updatePackageDefinition(只许命中现存版本)+ countPinnedInFlight
- 前端:保存按钮「保存 v{n}」;新建走 asNew;文案全线「新建才长版本」
- 测试:save-package.test 六例(写回/钉版/热改闭合/asNew/防复活/首版);
  过程中揪出双 API 进程并存(旧进程霸端口跑旧代码)——已重启归一

实测:改名保存 → 版本列表仍唯一 v4 生效中,名字已写回;八例端到端全绿;
五闸退出码全过(api:check 提交后转绿)。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 20:11:41 +08:00
ChaiHaoandClaude Fable 5 2246b26438 三面拆分⑯:手绘图水平居中 —— 画幅下限的余白对称分布
症状(用户报):图保存以后不居中。根因:手绘布局给画幅垫了 1000 的宽度下限,
内容却总从左缘 PAD=20 起 —— 画得比 1000 窄时余白全堆右边,图左贴;
保存时序列化归一化(整体平移到非负)后左贴更明显。

修法:layoutManualFlow 定完画幅宽度后把内容平移到正中,两侧余白对称
(纯呈现层平移,存储坐标不动);纵向保持收顶不居中。

另:用户测试保存产生的 v5 与 v4 几何完全一致,且带着上一轮已拔除的
自动重排 bug 的 id 旋转(保存时浏览器还跑着旧代码)—— 按「图只留 v4」删除。

五闸退出码全过。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 19:44:19 +08:00
ChaiHaoandClaude Fable 5 6988a750ae 三面拆分⑮:图只留 v4 —— 拔自动重排修回节点身份,按钮改边号+标签
用户在编辑器里手调了几何(整体右下移 10px,三条定价来路并入 x170 合流下行道,
议价回边沿左缘绕行),存出 v2–v4;令「图只留 V4 版本」。落库前查出一处大 bug:

**编辑器每次改动都按几何拓扑自动重排活动编号**(renumberAll 挂 commandStack)。
卡点时代回跳不是真边、图无环,重排恰好稳定;上轮回跳成真边后图有环,
破环顺序把在座节点的 id 转圈重派 —— v4 里成本定价 id 变 A6、审批变 A4、议价变 A5
(code 显示无恙,身份已漂)。id 是节点身份:在途按它钉定义、映射按它寻址、
异常按它定位,不许因挪布局而漂移。

处置:
- **拔除自动重排**:编号落子时铸定(mintNodeId 取下一空号),此后恒定;
  orderActivityIds / swapIdTokens 死代码删除
- **修复 v4**:id permute 回对齐编号(A4=定价 A5=审批 A6=议价),语义按种子重建
  (审批 reject 声明与 reopen 标记在漂移中已损,一并复原),几何原样保留用户手调
- **外科手术**:删 v1–v3,v4 成唯一生效版;种子几何回灌 v4 手调版,
  重种实证幂等(「已在库,内容未变 —— 不存新版」)
- **拣选条按钮:边号 + 标签**(E4 直接定价),不再显示边方向;方向在属性卡标题里看

八例端到端真库全绿,五闸退出码全过。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 19:34:22 +08:00
ChaiHaoandClaude Fable 5 7f0d25c337 三面拆分⑭:纯编排第三轮 —— 活动卸岗位、卡点废除全真边、边号 E1–En 图上可选
活动契约不带负责人岗位(用户定):
- 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
2026-07-28 19:02:07 +08:00
ChaiHaoandClaude Fable 5 281f4ef084 三面拆分⑬:流程包纯编排化 —— 编排与传递契约归包,实现方式归库,激活看双判据
模型(用户定):流程包只决定活动编排 + 活动传递的契约,不决定活动的实现方式;
节点只分活动点与审批点;图只定名称与顺序,属性在卡上填,链接好实现即可运行;
激活 = ①Mastra 式图编排闭合完善 + ②活动装载,两面判据。

schema(库经外科手术清空,无历史包袱,网关彻底出局):
- contracts:删 gateway 节点变体 / GATEWAY_KINDS / GATEWAY_KIND_LABEL /
  'gateway-deprecated' 违规项 —— 节点四种:start/end(结构件)+ activity/approval
- routing:joinReady 整个删除(多入边即异或汇合,没有「等回齐」;AND 待并行组);
  selectEdges 精简;closure 删 checkGateway;process-service 删汇合等待与网关直传,
  节点一律只收装配后载荷(verdict/outcome 判据由系统注入,不走映射)

编排面(画布 = 名称 + 顺序,其余在属性卡):
- 元素盘五件:活动点(单一,不再分标准/案例 —— 那是实现方式)/审批点/起止/卡点
- 属性卡:节点类型二分(活动点/审批点);新增「链接活动实现」选择器(装载面,
  FlowNode.act 经 merge 成为语义 activityId);范式/版本降为只读装载信息
- 边属性可填:条件(S-FEEL)+ 映射(上游输出口/起单载荷/常量三种来源;
  workflow-var/expression 归系统隐性,不进设计者面)—— FlowEdge.condition/mapping
  工作副本,pkg-to-graph 回填、graph-to-pkg 合并,清空条件即变默认兜底边
- 异常看板 → 激活双判据看板:图编排(结构+属性+契约)与活动装载(unknown-activity)
  分面亮灯,两面清零激活才亮
- pkg-to-graph 去 paradigms 绿化与网关分支;图例/文案全线「活动点/审批点」

测试:closure 27(joinReady 两组 describe 随机制摘除)、advance-order 按真图形状重写
(去 as never 捏造的网关节点)、graph-to-pkg 9(新增 act 合并 + 边契约合并/清空用例)、
seed 8、端到端八例真库全绿;五闸退出码验过(api:check 提交后转绿)。

库:purge 后重种,唯一 unified-quote@v1 生效(10 节点 14 边,双面判据齐)。
债:M5-5 清账(兼容路径连 schema 一起摘);M5-4(并行组)仍挂。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 18:29:32 +08:00
ChaiHaoandClaude Fable 5 6854524784 三面拆分⑫:网关去节点化 —— 分支即条件出边,汇合即多入边异或
模型(与 Mastra .branch 同构,条件挂在步与步之间):
- routing.selectEdges:多出边一律异或,不分节点种类 —— 条件命中优先(按声明序),
  无条件边作默认兜底,恰取一条;单出边直通保留(历史并行网关的遗留通道)
- closure:含网关即 gateway-deprecated(历史版本仅可读、不可激活);
  「隐式合并」禁令删除(多入边=异或汇合,上游互斥无歧义);
  新规:多出边节点的无条件边至多一条,超出报 multi-default-edge
- contracts:CLOSURE_VIOLATION_KINDS 去 gateway-unbalanced/join-ambiguous-source,
  进 multi-default-edge/gateway-deprecated(下游零引用,api-report 随行)

种子(按用户要求:只留一条流一个版本,图/节点/边全部对账):
- MVP_PACKAGE 重写:10 节点 14 边零网关 —— G1/G2 展开为 A1 的三条出边
  (选型/直接寻源/默认直接定价)+ A2 的两条,G2J/G3 整颗删除,
  A5 审批点的两个去向就是自己的两条 verdict 条件出边(驳回边与 reject 声明字字对齐)
- 手绘图:顶车道 y30 补画 A1→A3「直接寻源」—— 画布保存只认画出来的边,
  不画这条语义边会在首次存盘被静默丢掉(新增图边对账测试卡死这类漏画);
  「供应商底价表」标注钉进 y190 车道空档,不再被卡点压住
- 开发库外科手术:清运行数据 + 删 v1–v4,重种为唯一生效版 v1(闭合过闸)

UI 与文案同步:
- 元素盘/追加盘不再有网关件(画布仍认得历史图);图例删「判断/并行网关」「菱形=网关」
- 新建流程补激活一跳(保存不生效模型下,不激活「建出来就能起单」就是谎言)
- 总览四种编排要素、「画图不检查,激活才查完整」贯穿 blueprint/memory/process 文案

测试:closure 43 通过(gateway-deprecated + multi-default-edge 两用例),
seed-mvp-flow 8 通过(含图边对账),端到端八例真库全绿(网关从不建实例,断言原样存活);
五闸 typecheck/lint/depcruise/api:check/test 全过(退出码验)。

债:M5-4 AND 并行待「并行组」声明(Mastra .parallel);M5-5 网关运行时兼容三处,
含网关在途流清零后随 schema 一并摘除。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 17:56:20 +08:00
ChaiHaoandClaude Opus 5 7a065a50e0 删编排工作区标语 —— 版本号在版本卡上、保存钮上自己会说,不用题头再念一遍
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 16:58:41 +08:00
ChaiHaoandClaude Opus 5 448285776c 删掉流程详情的「契约细节」段 —— 页面到节点属性为止
它的三块都已有更好的去处或本就冗余:边映射的问题由异常看板逐条点名(还能点击定位),
调用接口在画布「开始」节点的属性里,触发器有自己的页签。
连带清掉因此变成死代码的整页 EdgesPage(路由类型 / 壳分发 / 出口 / 死 import 一并删,
不留只进不出的入口)。

详情页现在就四件:版本卡 · 流程图 · 异常看板 · 节点属性。

typecheck ✓ lint ✓ depcruise ✓ 506 测试 ✓

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 16:54:51 +08:00
ChaiHaoandClaude Opus 5 545103af1b A6 三个去向改选择组,「恰选一口」全链打通 —— 整条流第一次真正跑完
G4 是整条流最后的断点:三个去向写成了必交口里的 outcome 字段 + selective: [],
而引擎只在选择组恰发一口时才注入 outcome —— 结构上永远没有判据。

## 四层贯通

① 契约:验收工单加 `portChoice`(组名 + 可选出口)。draft 是 Omit 透传,human-tool 零改动。
② A6 声明:outcome 移出必交口,三个去向成选择组(won/revise/lost 各一口带人读说明)。
   契约 0.2.0、包版 0.7.0。G4 三条边一行没改 —— outcome 由放行选口注入落地事实。
③ 引擎:验收发卡时从活动契约现读选择组上卡(组是契约的事实,不在步的卡面里声明)。
④ 前端 AcceptForm:选择组渲染为必选单选,不选「通过」不亮;选中的口随放行回传。

## 「恰选一口」拦在收单,不拦在落地 —— 拦错位置实测翻过车

第一版把 validateSelection 放进 release.land:回传是**同步收单**(200 = 收到裁决),
落地在推进器里**异步**跑 —— 拦晚了就是「工单已答完、任务卡死、推进器循环报错」(实测)。
改到 checkWorkOrderReply(与「驳回必附意见」同族的收单规矩):工单投影自带 portChoice,
放行回传缺口/口不在组内 → 400 同步拒收,工单还活着,人补选就是。
land 里的 validateSelection 留作兜底 —— 这条从 contracts 导出以来从未被执行的不变量,
现在两个岗位都有了。

## 实测四连

  不选口通过 → 400「放行前先选『议价结果』」,工单未被吃掉
  选 won    → end_won released,流 completed —— **整条流第一次真正跑完**
  选 revise → A4#2 重开新实例(A4#1 留痕不动)
  选 lost   → A7 情报归档 → end_arch released,流 completed
  全程 route-dead-end 事件 0 条

typecheck ✓ lint ✓ depcruise ✓ 498 测试 ✓

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 16:37:59 +08:00
ChaiHaoandClaude Opus 5 894769e2ca 流程包详情整页 UI 梳理:一套图纸语言,贴边清零
量了一遍页面,问题四处,全修:

① **属性卡是混进来的第二种风格**(治理台圆角卡),同格栅其它三块都是图纸风。
   改为图纸卡:外壳同纸同影同角,题头入族 ——
   「流程包 · 版本」「流程图 · 顺序」「异常 · 看板」「节点 · 属性」四张两字·两字对仗;
   题头右侧 = 状态字 + 保存芯片(与「新建」「编辑」同款);
   内部小卡与节点条也入图纸语言(方角细线、mono 小字距题头),等高 250、超高内滚。

② **属性卡内部三处贴死**(题头↕0节点条↕0属性格↕0按钮):
   内容区统一 12px 呼吸;保存从底部挪进题头,不用滚到底找按钮。

③ **异常板被 stretch 拉到 916px**,三条异常配一片空白:改为高度随内容
   (实测 916 → 150),行顶仍与属性卡对齐。

④ 2px 的 margin hack 删了,row2 两卡顶严格同线(840 = 840)。

typecheck ✓ lint ✓ depcruise ✓ api:check ✓ 498 测试 ✓

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 16:10:57 +08:00
ChaiHaoandClaude Opus 5 ba5f65e685 画图不检查,激活才查完整 —— 保存 bug 的根治 + 异常看板
你存不了图的根因:保存跑闭合校验,而画图必然经过不完整的中间态
(节点没接完边、活动没安装)—— 画到一半就 412 卡死。实测同一份图:
改前 412 拒存;改后存为未生效的新版,报告随行。

## 模型改成三段

  画图 = 只创建节点和边,图上真正生效可编辑的只有**名字**(双击不再出岗位一栏;
        边上的字是辅助阅读的注记;岗位/判据/映射这些**闭环要素在节点属性里决定**;
        分配到人是运营的事,设计侧不碰)
  保存 = 不检查、不生效:恒存为新版本号,谁也伤不着 —— 因此不设确认卡,直接存;
        任何版本都可编辑(在旧版上改 = 以旧版为底另起一版)
  激活 = 完整性闸:不闭合 412 拦下并点名缺什么;过了即独占生效

## 异常看板(左,与版本卡同列同风)

画图不拦,看板替你盯着:逐条列这一版缺什么,**点一条定位到那个节点的属性**;
零异常时给空占位说「可以激活」。版本行的「激活」按钮按闭合灰显 ——
不闭合点不了,亮了才能上线。实测:v4 两条异常全列出、激活灰;闭合的 v2/v1 亮。

## 顺手修一个画布盲区

packageToGraph 以手绘存证为呈现真相,**语义里有、存证里没有的节点画布看不见**:
异常看板指着一个图上不存在的节点,点了也定位不到(实测:API 直存的包新增节点后
picker 里根本没有它)。补画:缺席节点按 60px 一档排在图纸下缘 —— 位置丑没关系,
看得见才能修。实测点异常 → 选中 A8 → 五张属性小卡弹出。

## 布局照你定的

row2 = 异常看板(1/3,与版本卡对齐)+ 节点属性卡(2/3,与流程图同宽);
属性卡内部小卡**等高 250px**,输入/输出超高的内容自己滚(实测五张全 250)。

种子改为保存后显式激活;NotClosedError 文案「不得保存」→「不得激活」。

typecheck ✓ lint ✓ depcruise ✓ 498 测试 ✓

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 15:52:45 +08:00
ChaiHaoandClaude Opus 5 2a89e9feda 版本卡题头与图题**同一组几何数** —— 标题、按钮、底线三线全平
上一版只对了底线,标题被顶在高盒子的上沿,与右图题差 16px(用户点破);
「3 版」计数也多余,去掉。

改法不是再补一个差值,是**逐段照抄右边的几何**:图题距纸顶 30 / 题行高 19 /
题底到 hero 框顶 16(实测),左题头同为 30+19+16 —— 于是三样对齐都不是碰巧:
  标题行  y 286 = 286
  按钮    y 286 = 286
  底边界线 322 ≈ 321(1px 边框宽)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 15:19:02 +08:00
ChaiHaoandClaude Opus 5 1bb74a9a2d 版本卡三处对细节:题头成对 · 按钮同款 · 底线与图框平齐
① 题头成对:左卡「流程包 · 版本」对右图「流程图 · 顺序」—— 同字型同字距,
   左右两卡说同一句话的两半。
② 「新建」按钮换成图上「编辑」芯片(dc2-addbtn)完全同款 —— 计算样式逐项比对
   (背景/边框/颜色/字号/圆角/内距)全同:一对动作一种长相。
③ 题头栏的底边界线与右图 hero 框的上边对齐:补 23px 对齐量,
   实测两线同落 y=321,差 0 —— 两卡横线一条平线。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 15:16:38 +08:00
ChaiHaoandClaude Opus 5 fd5ff1606f 拆掉画布的灰壳 —— 白图纸自己就是那张卡,一行一层
用户点破:右侧流程图看着是「两个层叠风格」—— 因为 .g-canvas 自己是一张灰卡
(#e9edf2 底 + 边框 + 14px 圆角),里面再垫白图纸;而左侧版本卡是单层白纸。
同一行两种叠法,像两套风格摞着。

拆掉灰壳:.g-canvas 只做布局(透明、无框),白图纸(process-doc)flex 撑满列高,
自己就是那张卡 —— 与版本卡同纸同影同角。实测:壳背景 transparent、边框 none,
白纸与版本卡顶对齐(256=256)、等高(572=572)。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 15:11:44 +08:00
ChaiHaoandClaude Opus 5 28adab83b0 版本卡改图纸风 —— 与右侧流程图同一套视觉语言
版本卡原是治理台的圆角卡,跟旁边的图(flow-canvas 的图纸风)是两套语言。
改成同一张图纸的构件:

  · 白纸同影同角(10px 圆角、同一串投影,与 g-canvas 里的 process-doc 逐项相同)
  · 题头 mono 小字距大写:「VER — 版本记录」对图的「FIG — xx流程」
  · 行是细线方框(方角,同图例 legend 的画法),左侧 3px 色条:
    钢青 = 普通版,黄铜 + 米色底 = 生效版 —— 一眼可辨
  · 「新建版本 / 激活 / 停用」按钮同为细线方框小件,黄铜色标激活类动作
  · 卡尾说明也落 mono 小字,像图纸的备注栏

实测(计算样式逐项比对):背景 #fff=#fff、圆角 10px=10px、投影同串、
题头字体/字号/字距(SF Mono / 9.5px / 1.33px)全同,与图等高不变。

typecheck ✓ lint ✓ 498 测试 ✓

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 15:00:24 +08:00
ChaiHaoandClaude Opus 5 8fe9ef8ecb Web 开发服务器改双栈全绑 —— 单栈回环怎么绑都有一族是死的
这坑栽了两次:不给 host 只绑 [::1],127.0.0.1 连不上;上次改绑 127.0.0.1,
[::1] 又连不上。浏览器把 localhost 解析到哪族全看系统心情,表现就是「时好时坏」。
回环双栈没有单 socket 的绑法,只能 any(host: true)。

代价写在配置里:会暴露到局域网 —— 但 API 从来就是 `*:8787`(Node 默认双栈 any),
Web 跟它对齐没有扩大暴露面;有登录门,且这是开发机。要收回环改回 '127.0.0.1' 即可。

实测:127.0.0.1 / [::1] / localhost 三种写法全 200,/api 代理 200。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 14:55:23 +08:00
ChaiHaoandClaude Opus 5 ff114a2246 流程详情:版本卡与图平齐 + 显式「新建版本」+ 节点属性成卡
三处走查反馈:

① 版本列改成**固定高度卡片,与右侧的图等高**(grid stretch):
   头部 = 标题 + 版本数 + 「新建版本」;中段版本行,多了在卡内滚,不把页面撑长;
   卡尾一句常驻说明(恰一个生效;在途按启动版本跑完)。实测两侧 591px 对 591px,顶对齐。

② 版本从此有**显式的新建入口** —— 之前只能靠改图保存来隐式长版本。
   「新建版本」= 以当前看的版本为底克隆一版(服务端定版号并即刻生效)。
   与「激活」分工明确:激活只是切生效指针,不长版本;新建才长 ——
   把旧版本的画法复活成最新版、或在现状上另起一版接着画,都走这儿。
   画布有未保存改动时确认卡会明说「克隆不带未保存的改动」。
   实测:以 v3 为底建 v4 → v4 生效、v3 自动停用、列表实时刷新。

③ 节点属性从裸块改成**卡片**(与页面其它卡同一形制),标题右侧带状态
   (只读 / 有改动待保存 / 点节点就地填写)。

typecheck ✓ lint ✓ depcruise ✓ api:check ✓ 498 测试 ✓

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 14:50:08 +08:00
ChaiHaoandClaude Opus 5 710946e729 流程包台面重做:版本收进包内部,启停是运行时开关
按你定的六条做:

## ① 台面三页签:总览 · 流程包 · 触发器
「调起规则」改名触发器(键不动,深链不断)。

## ② 版本收在流程内部,不平铺台面
货架一流程一卡:名字 + 标识 + 「生效 vN / 已下线」+ 版本数。
从前一版本一张卡,三个版本占三格 —— 版本是流程的内部事,不该摊在台面上。

## ③ 详情页布局照你说的排
左 1/3 版本列表(恰一个生效,点谁看谁的图),右 2/3 流程图;
图下是节点属性(点画布或点节点条,就地填);再往下才是声明式契约细节
(边映射校验 · 调用接口 · 触发器)。属性区从右侧窄栏挪到图下整行。

## ④ 新建流程
「新建流程」→ 填名称与标识 → 建出一张「开始 → 结束」的最小图,v1 即刻生效,直接进详情。
最小图天然过闭合校验 —— 不闭合存不进来这条闸对新建同样成立。
标识收紧为小写字母开头、只许小写/数字/连字符(它进 URL 和触发器规则)。

## ⑤ 历史包袱文案清掉
「工作流不设负责人,责任只落在节点上:此处不声明岗位,起单时就解析不出任务负责人」
→「这个节点还没指定岗位 —— 不指定,起单时就不知道任务该派给谁」。
同类:「未声明 · 发布前须补齐」→「未指定 —— 保存前选一个岗位」;
「发布前须先安装并过跨包契约相容核对」→「先去活动库安装;保存时会核对契约相容」;
边映射页的「边不闭合不得发布」→「不得保存」。

## ⑥ 版本可激活/停用,一次只能激活一个,切换不动在途
运行时模型从「最新版生效」改为**显式生效指针**:
  · `setPackageState` 激活即独占(同流其余版本一并停用)
  · 停用生效版 = 整条流下线,新起单被拒(报「无生效版本 —— 去流程包里激活一个」)
  · 起单取生效版;在途工作流按启动时钉住的版本号读定义,启停对它们零影响
  · 保存新版仍即刻生效(旧生效版自动停用)—— 回退就是把生效切回旧版,不用改图
store 的 setPackageState 把列上与 definition(jsonb)里的两份 state 一起改(教训同 0012);
迁移 0013 把存量多版同 active 归一为「每条流只留最高版生效」。

实测:激活 v1 → v3 自动停用,新起单钉 v1;停用 v1(零生效)→ 起单 500 且明说原因;
在途 v1 工作流照跑;恢复激活 v3。UI:切版看图、只读提示、启停确认卡、新建一条龙全通。

typecheck ✓ lint ✓ depcruise 376 模块 ✓ 498 测试 ✓

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 14:35:54 +08:00
ChaiHaoandClaude Opus 5 2b1d983678 Web 开发服务器显式绑 IPv4 回环 —— 127.0.0.1 从前直接连不上
不给 `server.host` 时 vite 走 Node 默认解析,在本机上**只绑到 `[::1]`**:
`http://127.0.0.1:5273` 连不上,而 `localhost` 通不通取决于浏览器/系统把它解析成哪个栈。
同一台机器上表现为「有时打得开有时打不开」,查起来极费劲。

绑 `127.0.0.1` 之后两种写法都通,且不暴露到局域网(要给别的设备访问再显式 `--host`,
那是另一个决定)。代理目标也一并从 `localhost:8787` 换成 `127.0.0.1:8787`,
免得同一处歧义在代理侧再来一遍。

实测:改前 `127.0.0.1:5273` → 连不上、`[::1]:5273` → 200;
改后 `127.0.0.1` 与 `localhost` 都 200,且只靠配置生效、不必带命令行参数。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 14:07:00 +08:00
ChaiHaoandClaude Opus 5 a9e9c7babd 设计中心加联调测试台:造入站邮件(带附件)投通道,看真结果
你要的「模拟输入邮件+附件触发起单」。后端**本来就齐了** ——
`ingestMailRoute` 契约里早有 attachments,出参也早就回归属解析与三级消费结果。
所以这是纯前端加一个区:设计中心新增 `testbed`,一个页签「入站邮件」。

走的是与真通道**同一条**入站链路(通道归一 → 归属解析 → 统一事件流 → 三级消费)。
邮件通道是外界,模拟通道是 README 明许的;系统内部机制这里一行都不 mock ——
命中判定、起单、消息兜底全是真的。

## 这一屏回答三个问题

投出去之后就摆三样:归属判到谁(哪一级命中 / 无主的原因 / 默认认领岗位)、
谁接了(任务监听 vs 触发器各命中几个)、没人接落哪儿(消息兜底)。

还有一格**起单前置自检**:投之前就告诉你会不会命中,不用投完了猜。
判据与真实配置同源 —— 通道 id、主题关键词、两个归属键正则,四条逐条给绿灯或说差什么。
预填的样例是一键能起单的那一封;把它改坏,自检立刻指出差哪条。

附件如实说明「只走**登记**」:名字/类型/大小/存证指针进事件信封,内容不解析 ——
解析 Excel/PDF 是活动的事,活动还没实现。不含糊过去。

## 顺手修一个会静默分裂数据的 bug

通道的归属键正则 `RFQ-[A-Z0-9]+` 不含连字符,`RFQ-2607-501` 只抽到 `RFQ-2607` 就停。
而这个键会成为「受理结论」那一行的**主键** —— 截断了,同一单的数据就静默分裂成两行,
网关读到哪一行全看运气。改成分段续接 `RFQ-[A-Z0-9]+(?:-[A-Z0-9]+)*`,
实测 `RFQ-2607-501` / `RFQ-ABC123` 都整个吃下。

## 我自己踩的两个

① 出参类型手搓,`level`/`kind`/`position`/`rationale` **四个字段名全是编的** ——
页面上就摆出两个永远显示「—」的格子。改为直接用契约类型:归属解析真实是按 `outcome`
判别的联合(owned 给 rule+taskId,unowned 给 reason+可选 fallbackPosition)。
为此给契约补了 `IngestMailOutput` 导出(加法)。
② JSX 正文里写 markdown 的 `**` 会显示成字面星号,换 `<b>`。这坑本轮踩过第二次。
另补两个缺失图标(flask-conical / split),不补就是空 SVG。

## 实测

界面上点「投递这封信」→ 归属判**无主 · 三级都没对上 · 默认认领岗位 运营**
(对新询价完全正确:没有在途任务可归)→ 触发器命中 1 个 → 起单。
起单入参 `customerCode: C014` / `rfqRef: RFQ-2607-501` 都抽对了。

一个值得记的观察:事件起单**没有「来源人」**,所以不装载工作组,A1 的 BD 岗位解析到
真正的 BD(冯兵),任务落他工位而不是我的 —— 这是对的,不是 bug。
要在自己工位上看,用「人工登记起单」那条路(登记人即来源)。

typecheck ✓ lint ✓ depcruise 376 模块 ✓ 498 测试 ✓

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 14:02:00 +08:00
ChaiHaoandClaude Opus 5 b2f5f69d6a 流程包去掉发布机制 —— 严格检查 + 保存即生效,生效由运行时决定
用户要的是运行时机制:新建 + 编辑,存下去就生效,旧任务走完旧版本,
新任务调用时才加载新编排。所以「草稿 → 发布」两态整套去掉。

## 闸从「发布」挪到「保存」

`savePackage` 现在先跑闭合校验,不闭合抛 `NotClosedError`(路由 412 带报告)——
**一个字节都不落库**。存进来的每一版都能起单,所以不需要「已发布」这个标记。
`publish` 用例、路由、`publishPackage` 存储方法一并删掉。

实测:把进 A6 的边映射清空后保存 → 412,逐条点名「边 e-g3-a6 未完成载荷映射;
节点「报价议价」的必填字段未映射:rows」。

## 保存恒新增版本号,服务端说了算

这不是可选项,是「旧任务走完旧版本」的前提:工作流按 (包id, 版本) 去读定义,
就地覆盖 v1 就等于改掉所有在途 v1 任务正在读的编排 —— 它们会中途换了规则却毫不知情。

版本号由用例层算(当前最大 + 1),**不采信入参**。实测:入参故意填 version: 999,
落的是 v2。store 层因此改成**只插不改**:撞键宁可让唯一约束报错,也不静默覆盖。

起单取版从「最新已发布」改为「最新一版」(retired 除外);触发器的 requiredInputs 同口径。
实测:改完描述存成 v2 后,新起的单用 v2,早先那单仍挂 v1。

## 迁移:旧状态值不归一就是一读就炸

状态枚举从 draft/published/retired 收成 active/retired。列上和 definition 这个 jsonb 里
各存着一份 state,两处都要改 —— 不改,`processPackageSchema.parse` 读一行就抛。
这不是开发期小麻烦,任何已部署实例都会中招。加了迁移 0012。

## 界面:恒为 0 的假指标撤掉,不换个说法留着

- 编排面板:「已发布/草稿」芯片 → 「生效中/历史版本」(真正的区别是哪一版会被新起单取到);
  发布按钮撤掉,保存按钮改成「保存并生效(存为 vN)」并在确认卡里说清影响面
- 历史版本只读,但就地指路:「去 v(N-1) 改(生效中)」,不让人自己找
- 蓝图面:「草稿 N · 未闭合 M」两个计数在新机制下**结构上恒为 0**(不闭合存不进来),
  换成「共 N 个版本,保存即生效」
- 驾驶舱:「未闭合草稿」卡整张撤掉 —— 同理恒为 0。天然的第三张是「死路」
  (route-dead-end 事件),但那需要一条按事件类型聚合的路由,没有之前不摆(同死信卡的规矩)

## 顺手修:种子的幂等判断本来是坏的

比对用 `JSON.stringify` 认键序,而 jsonb 从 PG 读回来键是重排过的 —— 永远判不等,
每播一次种就多存一版一模一样的定义(实测一口气堆到 v3)。改成递归按键名排序后比对。
连播三次,只第一次存。

## 契约变更(破坏性,一步到位)

`publish` 删除、`NotPublishableError` → `NotClosedError`、`publishable` → `closed`、
状态枚举收窄。按规矩破坏性变更该走三步弃用 —— 这里一步改完,因为:
① depcruise 反查下游全在仓内(374 模块无违规),同批改完;
② 要弃用的是一个**产品决定不再存在**的机制,留弃用窗口没有意义。
CONTRACT.md 已同步,快照单独说明。

typecheck ✓ lint ✓ depcruise 374 模块 ✓ 495 测试 ✓

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 12:49:24 +08:00
ChaiHaoandClaude Opus 5 9802550ae8 审批 / 消息 / 纪要 / 汇报补上助理栏 —— 那不是空态,是整栏没渲染
`.workspace` 是**三列**网格(侧栏 · 工作区 · 助理栏 440px)。这四个模块只渲染了
两栏,右边就空出一条 **234px 的白带** —— 里面什么都没有,不是「空态没写好」,
是这一栏根本没画。实测四面皆然。

那一栏该摆什么,按 OS 4.1 定:「对话流 / 视图区」是**工作台-任务**的交互结构、
是回环输入的唯一入口。这四个要素各有自己的形态 —— 审批是通过/驳回附依据、
消息是就地答(MessageDesk 自己那条 NoteBand 早写着「不开放任务对话流」)、
纪要靠人记、汇报是确认即提交 —— 都不经对话流。

所以**不摆能打字的输入框**:那是在许诺聊得起来。只如实说这一栏是什么、
这一面该怎么用、想说话该去哪儿。共用件 `AssistantAside`,色调 `muted`
(通路不在这儿,灰着就不许诺),章也不打彩色渐变 —— 亮着像在待命。
四句文案各说各的事,不是同一句复制四遍:

  审批 拍板不用先商量 —— 看依据就够了,想先问一句就去那一单的任务里说
  消息 这儿不用聊     —— 就地答完即可,作答只及卡面,不用跑进别人的任务
  纪要 会得你自己开   —— 你写下来最准,写完登记起单责任才落到人
  汇报 不用你写一个字 —— 按任务日志自动聚合,要数字好看得回任务里干活

顺带治了题头被截:一行摆四件(章 · 任务助理 · Agent · 说明句),对话区压到
212px 时说明句只剩 29px,被省略号截成「汇…」,一个字都读不出来。改为按**本栏宽度**
容器查询,挤了就让说明句换到第二行拿整行说完。任务面的「盯着这单推进 · 有事随时说」
以前也是截的,这下一并读全了。容器上下文落在 `.jc-tch` 不是 `.session-chat` ——
后者带拖拽调宽的负偏移柄,不给它加 containment。

补 3 个缺失图标(gavel / pencil-line / chart-column)—— 不补就是空 SVG,这坑踩过。

typecheck ✓ lint ✓ depcruise 374 模块 ✓ api:check ✓ 490 测试 ✓

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 11:27:52 +08:00
ChaiHaoandClaude Opus 5 f7b6a3a107 空态分出第三种空 —— 「没接通」不许诺,别让人白等
上一版补占位时漏了一件:占位分**两种**空,我只做了一种。

「沟通记录」的注释写着「明说没接,不伪装成暂无数据」,正文却写「与客户、供应商的
邮件和消息都会归到这里」—— 注释和文案自相矛盾。按单归档的投影根本没做,`outbound_mail`
至今只有 channel 建表和 reset-runs 碰过,**任何界面都读不到**。所以在那一屏等下去
永远不会有内容,而文案在请人等。

改成如实说:「往来记录还没接通」。并给 EmptyState 加第三色调,让三种空长得不一样:

  ok     办完了、清空了 —— 这是好事(待批清空、无未读)
  brand  还没发生,但通路是通的 —— 等着就会有(还没有任务、还没有成果)
  muted  通路还没接 —— 等下去也不会有。灰环灰图标,视觉上就不许诺

`muted` 是新加的真色调(不是我编的类名 —— union 与 CSS 一并落地)。
文案也不把人指去「消息」面:那里同样读不到外部邮件,指过去是第二个谎。

顺手把十处空态过了一遍:其余 brand 都名副其实(起单、聚合、纪要、成果的装配都通),
只有沟通记录这一处在许诺。债务簿该条对账。

tsc ✓ eslint ✓ depcruise ✓ 481 测试 ✓

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 10:32:23 +08:00
ChaiHaoandClaude Opus 5 c59e73754b 工作台空占位补齐 —— 有内容渲染内容,没内容才落空态
任务面原来缺两处占位:中栏是一行裸文字,对话区在没选中任务时**整栏不渲染**。
补齐后三栏恒在:中栏落设计空态「手上没有任务」,对话区给全壳(题头 +
空态 + 禁用输入条),空着也看得出这是干什么的地方。

但真起一单之后暴露了更重的问题:占位在**说谎**。待处理角标写着 1,正文却
说「手上没有待办」—— 因为 ChatStream(643 行)与 WorkOrderReport(449 行)
早就写好、也从 @features/desk-task 导出了,却没有一处在用。占位不是缺内容,
是内容没接上。三处接回真渲染:

  待处理  → WorkOrderReport(工单正文、编号、派发时间、数据与分析)
  工作日志 → .jc-log 行,按归侧四类各一色(机器/人类/裁决/等世界)
  工作成果 → .jc-file 行,点开进 FileViewer;打开时右槽换「返回」
  对话区  → ChatStream,三个回传(说一句 / 答卡 / 答工单)在这里收口

顺带治了窄对话区的抗压:工作区优先保「五按钮 + 翻页」,对话区在 1280 下被
压到 212px,卡头标题 `flex:1` 没设 `min-width:0`,一挤就逐字折断成竖排单字。
降级顺序改成「状态芯片换行下沉、标题始终整词可读」—— 截断能让布局不崩,
但读的人不知道这是什么卡。不改任何一栏尺寸。

五闸:tsc ✓ eslint ✓ depcruise 373 模块 ✓ api:check 公开契约无变化 ✓ 481 测试 ✓
走查后清了运行数据(仓库自带 reset-runs,配置原样留着),换业务化主题重起一单。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 10:25:19 +08:00
ChaiHaoandClaude Fable 5 5619d86ce4 编排层③:活动装入/换版入口 —— 开发完能装进来,不必跑种子
此前活动只能靠 seed 装入,治理台没有任何入口 —— 这是「逐个开发活动」的拦路石。
补 POST /api/gov/activities(无代码通道:交清单 + .js 产物,都是数据),
两审在服务端跑;不过审按发布门同样的式样回 412 + ApiError.detail 带审计结论
(直接回业务体的话类型化客户端拿不到详情)。活动库给「装入 / 换版」卡:选文件或粘贴两份。
实测:0.1.0 → 0.2.0 版本并存;声明未注册的工具即 412 并点名到工具。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 10:01:25 +08:00
ChaiHaoandClaude Fable 5 9de641459e 编排层①:改图入口下沉画布 + 活动契约面全链打通
① 已发布包就地给「起草新版本并去编辑」,不用去页头找;
② 修一个我自己引入的 bug:卡点还原把审批点的「退回调整」牌子当成边,凭空造出 e-A5-A4 ——
   卡点只认亲、不新建(旧包有这条边才认);实测编辑器往返 16 边 14 节点无损;
③ 活动契约面接进治理台:列表出参带必填入参/输出口/声明依赖,活动详情摆成一屏,
   导出依赖文件一并带上 —— 开发一个活动要照着的东西,现在有一处能看全。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 03:02:44 +08:00
ChaiHaoandClaude Fable 5 af789f546c UI④:元素盘点击落子真能落 —— 原型里这条路是坏的
事件流实测:click → drag.init → create.start → create.move → **create.rejected**。
create.move 要有 hover 目标才算 canExecute,而 click 到达时鼠标早已抬起,
拖拽在同一个调用栈里就被拒 —— 工具提示写着「点击后点画布落子」,一颗子也落不下。
点击这条路改为直接 modeling.createShape 到空位(撞车往下让、一列满换列);
拖拽那条路不动。实测:落子 32→33、追加自动连线 33→34、撤销回退干净。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 02:49:50 +08:00
ChaiHaoandClaude Fable 5 5a8589046b UI③:LLM 工具改为大模型驱动的系统内通用工具 —— 不是模型实例
五件真实存在的:案例决断(loop-turn)/ 步内生成(flow-step)/ 叙述性小结 /
蒸馏归纳 / 连通探针,各标算谁的账。模型实例退成尾注:模型是发动机,这些是装在上面的件。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 02:36:57 +08:00
ChaiHaoandClaude Fable 5 ec0b78c550 UI②:数据对象全用中文名 —— label 随物化落 PG 注释,全链读回
此前 label 在建表那一步就丢了,治理台只剩 project__intake_record 这种键给人看。
用表/列注释而非另建元数据表:名字与表同生共死,不会对不上。
设计台/运营台/对象详情/触发器下拉一律中文名在前、键在后。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 02:33:09 +08:00
ChaiHaoandClaude Fable 5 188637cf26 UI①:修卡片被压扁剪裁 —— 工作面是滚动 flex 列,子块一律不压缩
内部是 grid 的块(.g-entries)会被按很小的 min-content 算,整张卡压扁,
内容再被 .g-card 的 overflow:hidden 剪掉 —— 卡里只剩个头。两台全页审计已清零。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 02:27:43 +08:00
ChaiHaoandClaude Fable 5 10990a1efa MVP底座⑧:数据域四域大卡 —— 项目/客户/情报/供应商
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 02:05:28 +08:00
ChaiHaoandClaude Fable 5 21b66567bd MVP底座⑦:活动库卡片化 —— 六槽位卡
卡上只报查得到的事实(范式/分类/包版本/资产生效版/上架):
清单里没有「实现到没到位」的可靠依据,不在卡上编一个章 —— 槽位状态记在 debt.md。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 02:04:11 +08:00
ChaiHaoandClaude Fable 5 06b9cbde04 MVP底座⑥:工具箱四段卡片 —— 功能/LLM/人类/接入
三类工具并列不是编排,是「一件事能交给谁办」的全集:交给系统、交给模型、交给人。
导入表单走两审同门(端点真调);MCP 如实标未连接,不摆点不动的按钮。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 02:02:00 +08:00
ChaiHaoandClaude Fable 5 0fe5222f79 MVP底座④:统一报价 1:1 流程包单实例 —— 四域物化,种子整体切换
14 语义节点/16 边:A5 是内置审批点(驳回走 reject 声明 reopen A4),
G2 的两条互斥分支显式汇合于 G2J —— 隐式合并过不了闭合校验(实测)。
顺手修 graph-to-pkg:卡点带 to 时还原成语义边,否则回边画成卡点一存盘就没了。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 01:49:49 +08:00
ChaiHaoandClaude Fable 5 3edd133230 MVP底座①:数据四域命名 —— 项目/客户/情报/供应商
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-27 22:39:49 +08:00
ChaiHaoandClaude Fable 5 34e207c3e8 三面拆分⑫:UI 打磨 —— 补 10 枚缺失图标,蓝图改因果链,台账收成一个模块
图标注册表缺 arrow-left-right/columns/table/tag 等 10 名,用到即渲染成空 SVG —— 补齐;
蓝图四库改真箭头相连的因果链节点卡(卡即入口,删重复的入库段);
驾驶舱终态分布改五色堆叠条;运营数据收成左轨一枚「台账」,域下沉为 2-3 字短名页签
(受理→寻源→定价→议价→替代→共享,按流程序),进模块自动落首域。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-27 22:02:49 +08:00
ChaiHaoandClaude Fable 5 4a19690389 三面拆分⑪:收口 —— 走查通过,删掉与蓝图重复的需处置页签,文档对账
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-27 21:32:38 +08:00
ChaiHaoandClaude Fable 5 6f36f8340a 三面拆分⑩:工作组管理落员工区 —— ADR-011 欠账清账
建组/改组:逐岗位选人,留空即回落四策略。绑定先于策略,起单时快照进工作流;
实测改绑定后新起单的 work_group 快照即含新成员表,在途不受影响。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-27 21:28:30 +08:00
ChaiHaoandClaude Fable 5 a93f03f464 三面拆分⑨:台账动态位入运营,数据域瘦身为纯定义面
设计侧只见结构(列/主键),运营侧按域列行数与行浏览 —— 改 schema 与查行数据
是两种心智,摞一屏行数会把结构挤到看不见。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-27 21:22:12 +08:00
ChaiHaoandClaude Fable 5 6bb4675893 三面拆分⑦⑧:触发器一分为二 —— 规则定义入设计·流程包,起单开关入运营·任务
定义面可改名/改目标包/改三类规则/改起单装配;编辑期的装配行走本地状态,
存盘才解析 —— 派生自已解析 mapping 的话,刚添加的空行会被当场滤掉,人打不出第一个字。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-27 21:19:42 +08:00
ChaiHaoandClaude Fable 5 19108af6fa 三面拆分⑤:企业蓝图首页 —— 四库因果链与待补清单(闭合/缺活动/无调起)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-27 21:11:09 +08:00
ChaiHaoandClaude Fable 5 9fce0fdaa0 三面拆分④:驾驶舱首页 —— 度量改接 report 真八指标,纠正率/DMN 不再恒为 0
治理台原先调 memory 的五指标版,还把 submissions/corrections/judgements
硬塞 0 —— 仪表在说谎。八指标本就在 report 里算好,这里接上,与工作台汇报同源同口径。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-27 21:08:42 +08:00
ChaiHaoandClaude Fable 5 bb6760d7a4 三面拆分③:壳参数化两台,台账随域动态生成,顶栏互跳按权亮灯
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-27 21:00:25 +08:00
ChaiHaoandClaude Fable 5 cbae9b1284 三面拆分②:三章标签与入口路由,/gov 深链整链改写
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-27 20:53:43 +08:00