forked from ChaiHao/BPOS-MVP
手改是**兜 AI 的错**的那一手 —— 这一轮把它从「摆在那儿但落不了地」做成真的: 件上就地改 · 保存**按地址收**,不看当下那张卡:载荷从前借道工单的 `blocks[i]` 取列名, 于是熔断卡(没有 blocks)在屏上时,人补的那一格一个字都送不出去 —— 而他要补的恰恰是把这一单卡住的那个必填格。授权面改由活动清单的台账声明把关。 · **能增删行**:错不止「这一格填错了」,还有「这一行不该在」与「漏了一行」。 删挂记号不当场抹掉(看得见、可后悔),且**删要说出来**(`drops`)—— 「没回传就是删了」会把一次不完整的回传变成一次删表。 · **必填没填按不下提交**:与放行门 L1 同一个数同一套算法;闸上摆出差在哪一行哪一格。 · 只写真改了的那几行 —— 改一格却留「修订 4 行」的痕,那句话是假的。 判据与门 · 裁量判据带谓词时**谓词说了算**:「选填缺口已补齐」基座数得出来, 人填好的目标价它照样判「客户未提供」的毛病由此消掉。 · 验收卡判据**读时现算** —— 人在成果件上补一格,判据跟着变。 · 放行门认「**办完了没有**」不认「有人写过」:从前写个 `false` 就把门推开, 于是一单没打标就进了放行门。三个数全由基座现数。 · 拒回把「活没干完」说成「数或行对不上」的毛病:判据点名的表一行都没写时直说那一步没办。 **指向两扇打不开的门,比不指还糟。** 界面不撒谎 · 日志只有三色:负责人绿 · 智能体蓝 · 系统灰(归侧五种是度量的分法,不是给人看的)。 · 验收收口答两件事:落了什么(按**交付物**点名,一份成果的几张表并成一行)、 往哪儿去(转出哪一口、带过去哪些字段);一个口都没发就直说到此为止。 · 签完到收尾之间那一段有自己的话「字已签下,正在落地」—— 中间态本来就该说出来,只是要说对。 · 消息不再被内部事件刷屏:只有从通道进来的件才谈得上「无人认领」。 · 建客户公司与联系人**一次确认落两行**;联系人编码自增不问人;卡面摆表的人读名。 A1 三案例端到端全 released:全 A 类直通 12 拍 / 客户点名跳一条 10 拍 / 新客户缺必填 14 拍。 五道门禁全绿(971 passed)。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JsTDjoHovERXyy6Wmw1ALp
43 KiB
43 KiB
JCAI-WOS —— 企业级 AI Native 任务操作系统
一句话:组织的工作定义为可编排的工作流,工作流由活动编排而成;活动是完成一项任务的 Agent 机制,系统外开发、安装即用。人只在责任点与放行点出现 —— 确定交系统,临场交 AI,落地交人。
现状快照(2026-07-30)
- 三面一体:设计中心
/design(九区:蓝图/触发器/流程包/活动库/工具箱/数据域/知识库/ 大模型/测试台:三格 —— 流程(投一封信)/ 活动(按契约填入参)/ 日志(历次试跑存档))· 运营中心/ops(六区:驾驶舱/工作流/任务/员工/台账/系统)· 工作台/。/gov302 →/ops。 - 编排层与流程引擎已跑通并测死:起单宽进(门口不拒缺项)、数据按字段名流动(无强制 类型)、边只表达顺序与条件(对齐 Mastra)、闭合校验只查结构闭合 + 活动装载、一条流恰一个 生效版本、在途按启动版本跑完、版本号与名归设计人员自己定。
- 活动一律案例模型(2026-07-29 范式退役):flow-engine 已删,业务模型只有
CMMN + 说明书 + DMN 一形;
defineActivity已去paradigm,run改为可选 —— 行为全在清单里。turn-runner每拍要agent.decide—— 环境无模型密钥时 案例活动一步走不动,三套端到端(unified-quote-flow / new-package-flow / testbed-trace) 整套跳过,恢复条件写在各文件头。 - A1 客户RFQ受理已是真活动包(2026-07-30):
activities/quote-intake@2.0.0经安装通道 读文件装入(seed-activities.ts读dist/{manifest.json,index.js},不经 import —— 与 activities 之间只有安装通道)。五对象台账(record / type_table / verdict / alt_request / rfq_request)、两张判定表(F-01 完整度 · P-03 三分类)、三条技能、四张 HTML 报告模版; 案例模型照 SOP 图一步一项(S1…S6 + 放行,7 项,扁平无阶段)—— v2.0.0 重写: 上一版 12 项(擅自加阶段/里程碑/裁量项)让 Agent 全程跟 harness 较劲,实测无限死循环; 流程包 A1 节点已指向它。其余五槽位照旧占位。 - 模型实例:只留
deepseek-v4-flash/deepseek-v4-pro两条;种子读不到JCAI_DEEPSEEK_API_KEY就不绑密钥(卡上如实显示不可用),去治理台大模型区补。 - A1 已真跑通(2026-07-30):起单 → Loop 逐拍 → 写台账草稿 → 提交放行 → 人签 →
releaseWrite 合并进正式版 → 发射 intake 口 →
released。三分类与双去向旗业务正确 (A 直通 / B 寻源 / C 选型)。为跑通它补了 Loop 的七个洞:write行动 ·finish宣告完成 · 进行中的项进局面 · 工具清单进单拍提示词 · 里程碑自达成 · 在途验收不被兜底 save 擦掉 · 必交付物只数本单草稿。A1 的槽位rfq-intake已退役卸载(库里两个同名活动会骗人)。 - A1 两条路径都跑通并零卡壳(2026-07-30):常路五步与最长路径(含 S2 补全卡来回)
各跑一遍
released,行动被拒 0 次。补全卡走对话卡族(ask行动); 连续 5 拍被拒即熔断交人(stalledTurns)。 - 一拍一串行动(2026-07-30,
AgentTurn.actions,封顶 6):从前一拍只许一个行动, 每个 write/finish/start 都单烧一遍完整上下文 —— A1 六步恰花 21 拍(19 拍是该约束下的 最短路径)。收成串后 7 拍 released、56k token(自 21 拍 173k);纪律引擎强制: 被拒停在谁那儿(前缀生效)、tool 后截断、挂起型收拍。浏览器 UI 点「确认通过」→ released 全链亦验证过。 - 写的授权面是台账声明,不是计划项(2026-07-30 修死锁):
write的 itemId 降为记账, 挂不上(项已完成/人工激活未 start/阶段/不存在)照写不拦、留痕注明。此前绑死在项生命周期上, 实测死锁:S5 收完才发现打标没写全,能挂的项全 Completed,每拍补写被「要先 start T_release」 拒回,连拒五拍熔断 —— 而数据本身合规。台账声明与空转检查仍是硬门。 同批修:finish对非人工激活的项就地过 Active 再收(白按一下省一拍); 事件到达痕只记 task 层一条(此前 task 与 loop 各记一条,同一次回传日志三行像结巴)。 最长路径(含补全卡人环)复测:8 拍 released、64k token、行动被拒 0 次。 - 每拍时延 20-56s → 1.5-4.9s(2026-07-30):trace 拆出 tokIn/tokOut/reasonChars 实证 ——
慢全在隐藏推理解码(最慢拍可见 1538 字、推理 9808 字)。
ModelCall.reasoning: 'off'经 provider-profile 的reasoningControl译成 DeepSeekthinking:{type:'disabled'}(探针核过;low在该厂无效)。配套:write patch 只带有值列、scope 摊平字段前置整表殿后 (rest 3000→1800)、轨迹剔除装配技能戳、旧出参截 120 字、技能戳版本不变不重写、温度 0.2。 off 档一次误判(缺目标价当关键字段)以说明书写死规则治(「关键字段只有 PN/EAU/交期」), 不给思考额度 —— 判断归判定表与说明书,模型只做编排。复测:7 拍 49k token released、零被拒。 - 工作台交互按 PRD 补全(2026-07-30):①对话区点卡 → 视图区 locate 跳转(待办跳页位、 办结跳成果详情);②工作成果页签真实现(一行一份 → 定稿报告[印章+verdict+嵌 HTML 汇报] → 返回列表);③执行工单挂作业指导书卡组二;④工单办结回执以人事件进对话流,引擎内部观察 (internal 标)与裸「事件到达(human)」不再污染对话区;⑤空待处理四态分明(推进中动画 / 等外部回音 / 都办完了 / 已收尾)。
- AI 工作中动画(2026-07-30):对话区办事条(均衡条,语义「在办事」不是「在打字」;
三点气泡仍留给回话中)+ 头像呼吸环;空工作区推进场景(涟漪 + 微光工作线)。
纯 CSS、只动 transform/opacity、prefers-reduced-motion 全静止;
状态源自任务投影
runtime === 'running',等人/等外部/已收尾不亮 —— 界面不撒谎。 - 活动开发规范已重写为开发手册(2026-07-30 第二版):销账史砍掉(在 git),
精华收进建模八纪律与排障速查表;余账在 §15(④受理分支误吞验收裁决 ·
⑤治理台白名单授权口 · ⑦dist 真编译 · ⑧单拍工具缝 · ⑨⑩死代码 · ⑪评价卡暂不做)。
语义源两卷(操作系统/活动模型)已归档
docs/archive/。 - 实时同步补齐五处(2026-07-30 第二轮,测试台为引子):①订阅层不失效
['gov','testbed',*]—— 测试台全靠 2s 轮询而轮询到终态即停,一单跑完那屏就此定格; ②testCurrentRoute把已终结的试跑单当成「在跑」,旋钮永久锁死(现返回live分开 「摆出来」与「占着仪器」);③试跑起单/销毁不广播 —— 销毁掉的真任务还挂在别人工作台上; ④**kind:'system'声明了却全仓从未发布** —— 治理台所有配置面(活动/工具/模型/流程包/ 数据域/驾驶舱)永不实时刷新;现由/api/gov/*写路由中间件统一发(一处拦住,新路由自动生效), 任务走到终态也补发一次(台账与指标不以任务为轴);⑤本地 id 活过服务端事实 —— 别处销毁后面板还钉着旧号,显示「取数失败」的鬼卡片(渲染期对齐,服务端说没了就松手)。 订阅映射已抽成纯函数invalidateFor并按「哪一屏靠什么刷新」逐屏断言(8 条)。 - MVP 工作流第一轮跨节点跑通 A1→A2(2026-07-31),并挖出七个编排缺陷(全已修):
①六节点绑的是退役槽位 id ②流程包入参还是
customerCode+rfqRef③触发器装配映射是空的 —— 事件触发的 scope 不打底(只有 registration 才铺 scope), 「同名会自动带过去」是错觉,subject/body同名照样缺 ④E5 读needSourcing而 A2 出口不发 ⑤E10/E11/E12 读outcome而 A6 三口载荷是空对象 ⑥A2 要originalPn而 A1 发的是altRequests(上游发一批、下游要一个) ⑦自动收步与行动串并行 —— 引擎在拍首收了 T_select,而模型这一拍原本就打算 write 完再 finish,Completed → Active当场抛非法迁移,连拒五拍熔断;现与start同款:收过了就当已完成。 ④⑤⑥ 同一类:边读什么 / 下游要什么,上游就得发什么 —— 光测单活动测不出来,只有真跑跨节点才现形。 - 六个活动全部转正为真活动包(2026-07-31):
REAL_PACKAGES六件齐,经安装通道读dist/装入 —— 治理台里不再有viewTemplates: []的占位槽。六份案例模型统一到 A1 的 状态机模式(剧本steps:intent / guide / writes / tools / doneWhen): A2/A3 各只有「派一张执行单 + 放行」两项(专家判断,建细了只是跟 harness 较劲); A4 定价三项(算价归判定表 · 超限才叫人的决策卡 · 放行); A6 议价三项(落单 · 发出去人工激活 + 立监听等回音 · 放行); A7 归档两项(一步落三张表 —— 它们互不依赖,分开只多两次 finish)。 凡触达世界的项一律不给doneWhen(给了等于给引擎一把替人签字的钥匙)。 - A2/A3 的简化口径(同日):案例模型从九个 humanTask 砍成两项 ——
T_select/T_source(派一张执行单,卡面两张可编辑表)+T_release(人工激活)。 上一版把「FAE/采购脑子里怎么想」当成了「系统要管几步」;而那一整段在业务上是一件事。 剧本与 A1 同一套(doneWhen真了引擎自己收步)。REAL_PACKAGES已含这两个, 不再是治理台里viewTemplates: []的占位槽。 - 判据三态 + 表格默认锁着(2026-08-01,
quote-intake@20.0.0,用户两问): ①「这条未达标为啥还在」——acceptanceCriterionCheckSchema只有{label,level,pass}, 裁断与理由传不到卡面,于是「裁了但裁成不满足」与「压根没裁」都是一个红叉。 补settled+rationale,卡面变三态:达标(绿)/ AI 判为不满足 · 交你定 (琥珀 + 左侧色条 + 理由)/ 未达标(红)。更早的注释写着「理由随卡交给人」—— 那句话描述的行为从来没实现过,因为契约里没有那两个字段。 ②表格默认锁着:每张可改的表各带一道闸([data-edit-for]),锁着只出「编辑」, 开了换「取消 / 保存」;取消还原成按下那一刻的值,保存才交给外层缓冲。 看与改是两件事 —— 从前一进屏 54 个输入框一起亮着。 途中踩了跨 realm 陷阱:event.target instanceof Element在 iframe 元素上恒为 false (Element是父文档的构造器),症状是点「编辑」毫无反应而 class/CSS/选择器逐个查都对。 认能力不认血统;监听挂载也改成幂等的(srcdoc 换文档时机抓不准,每次有机会就挂一遍)。 验收:6/6 released;浏览器里走完「编辑→改→取消还原→再改→保存→提交」,落草稿层。 - A1 连跑 10/10 全 released、行动被拒 0 次(2026-08-01,
quote-intake@19.0.0, 10-11 拍 / 99-112k token)。基线是 5 轮熔断 1(其中一轮 13 次拒回、23 拍、234k token)—— 五处 harness 改动逐轮逼出来的(见下两条与docs/debt.md)。 - 最后一条自报的机检判据也交给基座数(2026-08-01):台账字段声明加
required(可选, 不建 NOT NULL —— 草稿层的本分就是过程中允许缺),基座据此出域_对象_missing与_missing_keys(缺在哪几行、缺哪一列)。A1 的「必填齐(PN/年用量)」原读活动自写的missing_key_total—— 人在卡上补了年用量、基座已写回草稿层,而那个数要模型自己重算, 漏算一次这道门就再也开不了:十轮里三轮死在这。这是「机检只许读基座数得出来的数」 这条纪律第二次被违反,第一次是 missing_minor_total 被改小那次。 - Harness 三条死胡同已通(2026-08-01,连跑 A1 摸底逼出来的:5 轮熔断 1、再 6 轮熔断 2)。
三条全是同一个病 —— 判据正确地拦住一件办错的事,而模型没有一个动作能把它办对:
①写错一行没有退路 → 加
drop行动(ledger.draftDrop→DraftStore.drop): 只撤本单草稿层那一笔,正式版一个字都动不了、不抛事件,不是第四种写。 起因:客户明说本轮跳过的那颗料被写进有效清单,数全对(9 有效/1 跳过)而表里 10 行,record_rows = line_total拦住 —— 模型唯一能改的是那个数(改了 skipped_total 又不对), 13 次拒回、23 拍、234k token; ②拒回只给数字 → 读数连主键名单一起摆(域_对象_keys,封顶 12 行): 两份名单一比,多的那个 PN 就在里面对着,一句话能办的事; ③拒回把模型指上死路 —— 「要先 start,当下是 Completed」,而 start 一个 Completed 项同样被拒,两堵墙对着撞;现按状态分开说,且 start 已收的项改为无事发生。 拒回的话是模型下一拍的行动指南,指错方向比不给指引更糟 —— 同一条也改了提交门的 结尾建议:先分清差的是数还是行,行不对就 drop,别去改数。 顺带:收步判据与验收判据同源(S2/S5/S6 都改读基座的_rows)—— 松出来的那一截就是返工;S2 那条把「多写一行」的发现点从第 10 拍提前到第 2 拍。 还删了孤儿模版intake-gaps(7 处view:无一指向它)。 - 对话区一轮一句(不是一拍一句)(2026-08-01,用户:「太密集了」):形状是
设定目标 →(分析现状 → 规划 → 执行)× N 轮 → 一个气泡,气泡可以是仅结论,
也可以是结论 + 功能卡两部分。三处:①
turn-runner的handsOff—— 只有交出控制权那一拍(ask/human/decide/listen/submit)的交代进对话区, 别的拍留进工作日志(internal);②提示词与 say 字段说明明写这条规矩, 否则模型照旧每拍写播报、只是被默默丢掉(白烧 token 还写不好总结); ③chat-projection把交代与卡并成一个气泡,并把收尾三条引擎回声 (裁决 / 发口 / 终态)收成一条。并卡的判断按来路认(只有 terminal 不认领卡)—— 一度写成tag !== 'conclusion',而交代本身常是结论口吻,于是第一轮并对、第二轮没并。 账:同一条 11 拍的 A1,对话区 9 条 → 5 条;压下的 8 条交代一条不少留在工作日志。 - 放行卡不摆 L5、去向不再有 L4 裁量(2026-08-01,用户当场指出): L5「BD 放行」是责任关,而那张卡本身就是这道关 —— 列进判据表等于摆一条恒为 「未达标」的项,「n/m 达标」永远差一条;声明留着、呈现去掉(滤在基座组卡处,六活动通用)。 L4「去向判断合乎业务常理」删掉 —— 去向已由出口谓词算出,再让模型裁一次是给自己 没做的决定盖章:裁「满足」是废话,裁「不满足」也改不动什么(能改的是三类条数, 那已由 route-alt / route-rfq 两条机检看着)。判据得能指向一个可做的动作。
- 三个区各归各位:件归工作区,判据与指导书归对话区(2026-08-01,
quote-intake@14.0.0, 用户指出「你用你自己的报告格式嵌套了一层我要的报告格式」):工单报告组件自带一整套外壳 (题头/编号带/依据带/判据表/章节头),又把活动推的那一屏包在里面 —— 两套版面语言叠着。 现在 待处理与工作成果只放那份 HTML 模版;作业指导书 · 依据 · 判据 · 填报表单 · 提交与裁决全在对话区的卡上。待处理是可编辑态:可改的格子在模版里挂data-col、 行容器挂data-edit="域.对象",渲染时每格多渲一个<input class="jc-cell">孪生件, 只读那份与输入那份由样式表按根节点的editing二选一 —— 同一份 HTML 两处用,不存两份。 收值在外层(allow-same-origin读得到 DOM),iframe 里仍然一行脚本都没有; 收上来按台账地址对上工单blocks[i]的ledger/fields,仍走老的table:N回传。 同批修两个只在真人点的那条路上现形的洞:①监听挂在 about:blank 上 ——srcDoc异步换文档,渲染那刻挂的监听随旧文档作废,人改了两格提交时载荷一个字都没有; ②算出来的去向没交回去 ——routedPort那一路selectedPorts恒空,按「确认通过」 当场判「选择组未选出口」,台账都合并进正式表了单子却死在最后一步(blocked)。 验收:浏览器里走完两道人环 —— 件上改两格 → 提交 → 落草稿层 → 放行 → released, 九行数据(含人补的 eau/brand)落进正式表;工作成果那一屏零输入框、零外壳。 - 阶段2 补回成一项:受理需求交人审定(2026-08-01,
quote-intake@13.0.0,用户指出 「我都没确认需求 它就让我验收了」):「经过人」从前不是一项,而是归一那步收步条件里的半句missing_minor_total = 0 or answered_total > 0—— 只在缺东西的时候才叫人。 一封字段齐全的询价进来,这半句在拆完那一刻就为真,引擎自己把那步收了, 人一眼没看过受理需求,下一次被叫到已是终局验收。现在S3_confirm是独立一项: 人工激活 + 不给 doneWhen(与放行同款),view: intake-overview,一单必发一张; S4 的入场前提改读confirmed_total(只有人回卡才产生的数)。 规范 §7.1 立纪律 3.5:判据是「这件事办完了没有」,不是「要不要办」。 连带修掉一个零条死锁:没写过 ≠ 写了 0 行 —— 全 A 类那条路上替代请求表一行没写,quote_intake_alt_request_rows整个键不存在,而判据= type_c_total(0=0)本该成立, 未绑定的名字比较为假 → 永远过不去、连撞五拍熔断;现按declarations.ledger先铺 0。 验收:常路 11 拍 released、被拒 0;全齐无 C 类那条 10 拍 released、去向to-sourcing。 - A1 两份报告改为从 PRD 目标件整份搬过来(2026-08-01,
quote-intake@12.0.0):views/prd-style.ts是机械抽取的整段样式表 + 图标精灵(PRD_CSS/PRD_SPRITE,数值未改),views/report.ts逐块搬标记、只把写死的数据换成绑定 —— 不再用@sdk拼装件复述 (那套外壳有自己的版面语言,「照着做」出来的是第二种版面;前三轮报「25 块到位」都是 结构断言,对版面零约束)。规范 §10.3.1 立此法:视觉目标件只能看,不能用 DOM 断言验收。 连带三件:①**data-class-of不再以data-slot为前提** —— 纯色块(格里不写字、只按值上色) 从前整条静默失色,屏上一排灰格子看着像「还没算出来」(补 4 条用例); ②去向进视图:case:routeKey/routePort/routeTo/routeWhy由基座按出口谓词求值后注入, 与放行发口是同一次判定,报告只摆不算(分布条按条数分宽也走同一招:条数投影成 class + 宽度梯子); ③contact_name落进verdict—— 老客户不重写主数据,联系人卡从前会显示公司名。 端到端复跑:10 拍 released、96k token、行动被拒 0 次,去向to-alternative(type_c_total > 0)。 - A1 五轮端到端全部 released(2026-07-31):行动被拒 0 次,判据 7/8(只剩 L5 人放行)。
跑测逼出并修掉两个「人答了什么 Agent 看不见」:①可编辑表的修改只活在组件局部 state,
回传载荷一个格子都没有(加
onTableChange链,键table:N、首行列名); ②决策卡选了哪个不进轨迹(payloadOf只认 values/output/error,补detail.value)。 两者都会让 Agent 重发同一张卡 —— 人以为自己白填/白点了一次。 - 工作台空占位统一(2026-07-31):任务那一栏的空态从裸
execution-panel改挂jc-panel-card(其余四模块一直有,只它是画布上飘着的一段文字);.jc-empty由固定内边距改margin:auto+justify-content:center,在栏内真居中。 - 活动状态机:每步一条剧本,成果已在就自己收(2026-07-31,治 A1 空转)。
LoopModel.steps一个计划项一条:intent/guide/writes/tools/doneWhen。 引擎每拍开头先对任务视图求doneWhen,真了就自己 finish 那一项,不问模型 (人工激活的项不自动收 —— T_release 触达世界,不给它 doneWhen); 上下文按状态组织:只摊开当前这一步的做法与它该用的东西,其余步骤各留一行。 起因是实测死循环:S1 一次写齐八字段后 S3「补齐八字段」已无活可干,而每拍喂整本说明书, 模型只能把同样三行再写一遍 → 「写了等于没写」被拒 → 下一拍再来一遍,连拒到熔断。doneWhen的坑:S-FEEL 里未绑定的名字!= null求值为 true,写它等于那一步开局即收; 布尔列也不能当判据(分不清「没写」与「写了 false」)—— 一律取同步写下的计数列(测里拦下过)。 实测三连:A1 三次端到端全部released,行动被拒 0 次,S3 每次自动收步; 8 拍 / 58k token(状态机之前是 11 拍 / 82-90k)。 - 决策卡 Agent 侧接通(2026-07-31):新增
decide行动(contract / port / turn-runner / engines / 提示词 / 解析)。此前决策卡只有 UI 没有 Agent 侧,岔路口只能写成补全卡 —— 人拿到一张要敲字的表单而不是两个可点的选项。少于两个选项拒发。 - 真实文件进得了活动(2026-07-31):
sys.upload(迁移 0024)存原字节 + 读出来的文本;POST /api/gov/upload(base64,8MB 封顶)/GET /api/gov/upload/:id; xlsx 不引依赖自己读(ZIP 中央目录 +inflateRawSync+ XML,13 条测试); 契约字段标format:'file'→ 测试台出文件选择器。读不出文本的类型如实说读不出。 - 沟通记录接通(2026-07-31):
sys.task_comm(迁移 0025);活动清单声明contract.input.inboundComm(哪几个入参字段合起来是那封来件),基座起单那一刻归档 —— 人一点开这单,沟通记录里就已经躺着那封信,不必等模型跑几拍。附件那一行照抄基座的读取说明。 - 测试台改三格 + 试跑日志(2026-07-30):两档旋钮长在内容里(别处跳不进来、刷新记不住
试的是哪一台,第三样东西也塞不进二档),提到页签 —— 流程 / 活动 / 日志;单在另一台上
不抢页签,只挂一句「它在那边」。日志是拔之前先存一份:停止仿真照旧连根拔掉,拔前
archiveRun存一条(逐拍轨迹 + 台账草稿 + 发出去的人卡 + 读数),一次试跑一条 (流程包把名下节点任务合成一条,痕带节点名前缀、按时刻排);可单删可清空,reset-runs一并清。 库表sys.testbed_run(迁移 0023),路由四条挂/api/gov/testbed/logs(写路由中间件自动广播)。 顺手修:单活动那一台的负责人下拉掉进.tb-asn-r的 40px 那一格(它比流程那台少一列), 现给.solo四列版 + 插座列加宽到 184–238px。 - 台账列归型前移到写入那一刻(2026-07-30):模型用
""表示「原文没给」,草稿层照收, 到releaseWrite才被 PG 掀桌(invalid input syntax for type double precision: "")—— 而那是人签完字之后,整单落blocked。现在draftWrite按声明列型归:空值=不写这一列、 数值/布尔字符串转真类型、归不了当场拒(理由喂回下一拍)。台账字典也带上列型给 Agent 看。 - 前端实时刷新已通(2026-07-30):前端那一侧一直是好的(单条 SSE + 按前缀失效缓存),
三处后端没广播:①
task-advancer只在 runtime/terminal 换名字时广播,而案例活动 连跑十几拍全程running(改为progressed即广播);②interaction的推送一个订阅者都没有 (加onPush系统级转接);③发消息不经事件投递,收件人的消息气泡不动(outbox 处补广播)。 - 四类人类工具:前三类已通(2026-07-30):执行(工单 · 报告页填报提交)、
补全(对话卡 ·
ask行动,两条路必走其一)、验收(工单 · 判据表 + AI 已填好可编辑 + 裁决在对话区)。决策卡(第四类)UI 已在、Agent 侧未接。 验收修订链原来断在五处「声明了没接线」——契约revisableAtRelease定死哪几个值可改、 改完落哪儿;拟值放行前从台账现读,不让模型重述。 - A1 的两份执行页照 PRD 目标件重做并跑实(2026-07-31,
quote-intake@9.5.0):~/coding/JCAI_PRD/docs/活动执行页/的两份 HTML 是「办完该长什么样」的答案 —— 询价受理需求(来件原文 → 受理要素四卡 → 指标带 → PN 清单 → 本轮不报)与 统一受理记录(要素 → 逐条记录带标 → 分级依据 → 分流去向 → 两类请求 → 结论 → 这一签下去会发生什么)。@sdk补letter/factCards/actionList与列样式req/opt/num/pill;data-blank让空值真的留空,必填/选填胶囊与缺项标底 由模版自己的 CSS 出 —— 模版仍不许算(分布条宽度、命中高亮这类算出来的画面一律不做假)。 顺手删掉@sdk里五个零调用方的拼装件(kvCard/tableCard/noteCard/stagesCard/critList)。 - A1 六轮端到端,末轮九行数据全对(2026-07-31):每轮
released、行动被拒 0 次, 9-10 拍 / 76-89k token。逐轮逼出并修掉五个洞: ①机检判据两边都由活动自报 —— 条数报 9 而表里 10 行、三类条数报 7A/2B 而判定器给 5A/3B,派单数同源同错于是「2 = 2」顺利过关;现加基座读数域_对象_rows(本单写下几行), 判据必有一边不是自报,classify出参也带counts供照抄; ②问过 ≠ 答过 —— 收步判据写asked_total(卡一发就为真),人填完提交这一步当场被收, 答案没轮到写回台账;改等answered_total; ③归档件被冲掉 —— 收口后引擎再跑一拍,推固定的case-overview退到「声明的第一张」, 把人刚签过的放行页冲成阶段二的执行件;现按剧本view推、活步收完不推; ④说明书与剧本各写一份六步,分叉出三个案例模型里不存在的计划项名(S1_register 等), 模型照它报 itemId 一报一个被拒;说明书现在只讲整单的事,逐步做法归剧本(有测试钉死); ⑤三类数据失真(PN 抄漏后缀→同一料两行、数值缺失写成 0、制表符 BOM 拆错列)—— 逐条在说明书里写死实测账。 - Harness 可靠性:三处「门本身教模型撒谎」已修(2026-08-01,两条样例路径连跑逼出来的):
①机检判据读活动自报的数 —— 一颗料只缺目标价,模型如实记 1、被连拒四次,
第五拍把那个数改回 0 就绿了(台账从此写着「缺选填 0 条」);
机检只许读基座数得出来的数,数不出来的别假装机器判得了 —— 该条已降 L4 交人;
②裁量判据也被要求「为真」 —— 它如实裁「未满足」并写了理由,提交照样被拒,
判-提-拒十二轮 21 拍 187k token,最后把裁断翻成「满足」才过去;
提交门已改:机检必须为真、裁量裁过即可,裁断连理由随卡交给签字的人;
③熔断数不出「同一堵墙」 —— 拒回标题带着串位(「第 2 个」),整条一比成了 N 堵墙,
叙事窗 20 条也装不下几次撞墙;一单被同一条判据拒回 33 次、40 万 token 烧到
exhausted。已修:削掉串位前缀比对 + 熔断另开 60 条窗。 顺带:计划项号认唯一前缀简写(S4→S4_history)。 验收:Itelma 与新客户两条路径各三轮全部released—— 10 拍 / 88-90k / 被拒 0 与 9-11 拍 / 71-88k / 被拒 0-1,数据逐轮对得上。 - 执行页补到「能做的极限」(2026-08-01):新增
data-class-of(把值消毒成 class 后缀, 仍只是取值,判断留在样式表)—— 于是类标 A/B/C 三色、两枚旗的是/否、一条料一格的刻度条 都真做得出来;要素卡补方/圆标(方=组织、圆=人,里面放图标不放算出来的首字母)与大号计数; G2 那段改成三条规则连着本单计数的规则表 —— 命中由编排层求值,这份件不画对勾替它宣布。 仍不做的只剩两类:按条数分宽的分布条(宽度得算)、编辑态(沙箱无脚本,改数走执行卡)。 - 试跑日志吞主键已修(2026-08-01):存档那一屏只渲染
patch,key整个不显示 —— 三行受理记录屏上只剩「eau / lead_time」,看的人据此判「PN 没提取到」,而 PN 一条不少。 两处观测面已合并到gov-testbed/internal/drafts.tsx一份实现。 - 就地改的三处不老实已修(2026-08-02,同一单实测逼出来的):
①保存按地址走,不看当下那张卡 —— 载荷从前是
{workOrderId, values:{'table:0':…}}, 列名由那张工单的blocks[0]给出,于是「这份件能不能改」被绑在了「此刻开着的那张卡 长什么样」上。一单在放行门连拒五拍熔断,引擎发的是没有 blocks 的熔断卡,而屏上摆着的 正是受理记录那份件 —— 闸在、编辑进得去、保存按得下,前端找不到匹配的块,一格都没往下送; 人要补的恰恰是把这一单卡在那儿的那个必填格。现在收件自己说的话(data-edit地址 +data-col列名),授权面改由活动清单的台账声明把关。 ②必填还空着就按不下提交(ExecutionWorkOrder.gate,基座按声明现算, 与放行门 L1域_对象_missing = 0同一个数同一套算法);闸上摆出差在哪一行哪一格, 人在件上补齐、保存,闸自己开。算不出来(卡上没绑表)就不给闸 —— 没有依据的时候不拦人。 ③只写真改了的那几行:件上按一次保存整张表都回传,照单全写会留「就地修订成果:4 行」 的痕而人只改了一格。 端到端:12/12 判据、released、被拒 0(另一轮 3 次、亦 released)。 - 日志只有三色(2026-08-02 用户定):负责人绿 · 智能体蓝 · 系统灰(
LogLine.who)。 从前按归侧上五色 —— 那是度量的分法(自主率要把「等外面」与「机器干的」分开), 对读日志的人不构成区别。连带两件:放行那一刻四条痕说的是同一件事(合并 / 发口 / 流转 / 终态), 日志只留说得出实情的那一条(带「几行没进正式表」);台账写入认by定主语 —— 放行合并归系统,人工修订归人。 - 件上的表能增删行(2026-08-02 用户:「编辑列表应该还能增删行」):手改本来就是
兜 AI 的错那一手,而错不止「这一格填错了」——「这一行根本不该在」(客户点名跳过的料
被写进了有效清单)与「漏了一行」是同一类错,只给改格子就没有出口。
序号那一格编辑态换成 ×(一列两用),表尾一条「加一行」;删是挂记号不当场抹掉
(看得见、可后悔),「取消」把加的撤掉、把记号摘掉、把值放回去,三样一起才叫还原。
删要说出来(载荷
drops),不靠「没回传就是删了」—— 那种口径会把一次不完整的回传 变成一次删表。撤的只是本单草稿层那一笔(draftDrop),正式版一个字不动。 痕里点名撤了哪几行并写「别再写回去、条目数跟着改对」—— 那条痕是下一拍模型的行动指南, 不说清它会照「条目数 9 而表里 8 行」判成少写了一行,把人刚删的写回去。 实测:删一行 + 加一行 + 补必填 → released、11 拍、被拒 0。 - 裁量判据带谓词时谓词说了算(2026-08-02 用户:「这个价格是我填写的,但是它判错了」):
「选填缺口:已补齐,或由你放行时确认可以先受理」是复合命题 —— 前半句基座数得出来
(
域_对象_gaps),后半句才需要人。从前整条只读裁断,于是模型凭记忆写理由, 人填好的目标价它照样判「客户未提供」(复现的那单更离谱:两行年用量都填着, 它写「共 4 处选填缺口」,而 EAU 压根是必填)。现在谓词为真即达标、那句相反的话一并丢掉; 谓词为假才轮到裁量。同批:验收卡的判据改为读时现算(container.checks.of, 与提交门同一段criterionCheck)—— 人在成果件上补一格,判据跟着变;remark不再算选填缺口(它是我方写的注,不是客户该给而没给的)。 - 作业指导书与验收判据同一套版面(2026-08-02 用户定):从前指导书是一串松散的圆点、
判据是一摞带章的行,同一张卡上两套版面语言。差别只留一处:指导书不画对勾 ——
它是要办的事,系统并不知道人做没做。执行卡那一钮也改称「查看工单」。
连带挖出:引擎压根不往下传
steps/standard—— 活动照骨架写了,发卡时一个字 都没到卡面,人拿到的只有一句「请核对确认」。空着不是简洁,是把交代省掉了。 - 建客户要公司与联系人都经人确认(2026-08-02 用户定):录入卡加
also段 —— 一张卡两段(公司档 + 联系人档),确认一次落两行,值按段号.列名隔开 (两张表都有name,平铺会互相盖掉而没人看得出来)。从前联系人由 AI 自己写, 而contact_code恰是它编出来的那一个。 - 该问人的问人,人答不上来的别摆到他面前(2026-08-02 用户两条):
①卡面摆的是台账登记的表人读名(「客户档案」),不是
customer.profile; 主键行只摆表单里没有的那几格、用中文列名 —— 从前一句「主键 customer_code=待定」 既是英文列名,又在替一件他马上就要做的事做旁白。 ②自增列不问人:声明加FieldDeclaration.auto,标了的列压根不进表单, 写入那一刻由基座按「同组其余主键值-两位序号」生成(CU-9001-01,序号数正式版 + 本单草稿, 同一单连加两位也不撞);卡上另摆一句「由系统按顺序生成,不用你填」—— 不能一声不吭地拿掉,那样人会以为这张档少了一格。 - 放行卡砍掉四条判据,办结后换成落地结果(2026-08-02 用户定):
downgrade-safe·route-alt·route-rfq·typed-on-record四条都是内部一致性 (打标依据对不对、几类料开了几张单、两张表行数齐不齐)—— 该由引擎自己看住, 而放行卡是给签字的人看的:一屏九条,真正要他过目的那几条反而淹了。 落地那一侧不因此变松:同一批基座读数仍在 S5/S6 的收步判据里。 办结之后那一屏换成「这一签下去发生了什么」:进了哪几张表各几行(摆表的人读名)、 转去哪儿了(摆出口的 description)、试跑挡下几行 —— 判据说的是签之前要核什么, 签完再回看,那一摞对勾答不了这个问题。事实取自放行那一刻的结构化留痕 (ledger-write/release-verdict的 detail),不解析日志句子。 - 判据措辞写全,两张卡的按钮统一(2026-08-02 用户定): 「客户已确认(认出或已建档)」→「客户已确认:发件邮箱认出为老客户,或已为新客户建好档」, 五条同批改写;执行卡与验收卡那一钮改成同一形状 —— 图标一格、四字粗体 (执行工单 / 验收工单)、小字说明、右侧箭头,且四字在上小字在下(从前是反的)。
- 执行工单说的是「哪几格必须有、哪几格值得追」(2026-08-02 用户定): A1 的作业指导书从「怎么核表」改成逐项建议 —— PN/年用量必须有(缺一条走不到放行)、 目标价尽量试探出来、客户料号对齐回价单、品类与制造商能填就填; 收口标准写明「问不到的留空并在备注里写明,放行时由你决定先受理还是退回」。
- A1 不再开请求单(2026-08-02 用户当场定):
alt_request/rfq_request两张表 连同 S6 的开单动作、两个派单计数列、报告里那两张明细表一并退休。原话: 「这两项数据不在这里产出;随令牌流向下一个节点的只有工作成果验收内的内容; 进入选型替代后,活动会自己归一需要的数据」。从前 A1 逐条开单交给 A2/A3 —— 那是替下游把它的输入先摆好,而下游本来就要照自己口径归一一遍: 同一份事实两处各存一份,改一处就分叉而没人看得出以哪份为准。 S6 的收步判据改读route_decided_total(旗是布尔,分不清「没写」与「写了 false」)。 报告同批瘦身三处:两张请求单表 + 那条对账说明、「受理结论」四格表、 「本轮不报 0 行」横幅 —— 后两者要么与别处重复,要么九成时候在说「没有」。 - 消息不再被内部事件刷屏(2026-08-02 用户:「消息怎么总莫名其妙的出内容」):
「无主入站待认领」从前只看「有没有主 + 有没有人接住」,于是台账写一行发的
data事件也进兜底 —— 装一次活动包就往三个人收件箱塞十几条 「无主入站待认领:(无主题) … 原件:无」。判据加一刀认来源不认类型: 同样是data,从通道进来的是件、台账写出来的是事实;只有source.kind === 'channel'才谈得上「无人认领」。顺带:顺利收尾那条终态:released不再进对话区 (落地结果那一屏已经说全了,且它摆的是英文状态名);没顺利收尾的仍出声,措辞取TERMINAL_STATE_LABEL。 - 一道只认「有人写过」的门等于没有门(2026-08-02,用户送来一单熔断的实测):
那一单跳过 S4/S5/S6 直接提交放行 —— 受理记录三行一个标没打、分类表一行没写,
却进得了放行门。查出来三个洞:
①放行门的入场哨兵
s_routed只有 onPart 没有 ifPart —— 「往 need_sourcing 写过一笔 就开门」,模型顺手写了个false就把门推开了。现在认办完了没有, 且三个数全由基座现数(打了标的条数 = 记录行数、去向定过了)。 ②「每条都已打标」这条 L2 读的还是活动自报的untyped_total—— 「机检只许读基座数得出来的数」第三次被违反(前两次:missing_key_total / missing_minor_total)。改读_type_tag_a + _b + _c = _rows,两边都是基座出的数。 ③拒回把「活没干完」说成了「数或行对不上」 —— 那一单数是对的(诚实报了 3 条没打标)、 行也是对的,而话术只给「改数 / 改行」两条路,还明写「别为了过判据去改那个数」, 正好堵死它唯一想走的门,于是原样重提五拍熔断。现在判据点名的表若这一单一行都没写 (基座_rows= 0),就直说「那一步还没办,回去办了再来」。 指向两扇打不开的门,比不指还糟。 - 验收那一屏是活动的收口,答两件事(2026-08-02 用户定):①落了什么 —— 按交付物点名
(
RequiredDeliverable.ledgers说清一份成果由哪几张表承载:A1 的受理记录 / 分类表 / 结论 是同一份询价受理记录的内部结构,从前各占一条,人在成果面上看到三样东西); ②往哪儿去 —— 转出哪一口、带过去哪些字段(载荷即已落地的事实,摆列名不摆值), 一个口都没发就直说「到此为止」。同批:统一受理记录全仓改称询价受理记录; 成果列表执行蓝 / 验收绿两色;办结卡那一钮改称「打开报告」。 - 签完到收尾之间有自己的话(2026-08-02 用户:「点完验收按钮后会闪一下中间态」): 那不是渲染毛病,是真的中间态(合并 / 发口 / 落终态还在跑)。从前它落在通用四态里 —— 待办清零先闪一句「都办完了」再跳「已收尾」;那句话在那一刻是对的,可它说的是另一件事。 现在这一段说「字已签下,正在落地」。中间态本来就该说出来,只是要说对。
- 后端 19 模块 + 6 活动包 + 前端 features;五道门禁全绿(2026-08-02)。
- 别用
db:seed当装活动的手段:它会重写整套治理台配置。装活动用pnpm activities:install。
文档权威地图
| 层 | 文件 | 说明 |
|---|---|---|
| 活文档(冲突时以代码现状为准) | docs/编码规范.md |
工程结构权威:模块层级 L1-L8、依赖门禁、AI 协作协议 §12 |
docs/产品设计.md |
三面一体的产品形态与决策记录 | |
docs/活动开发规范.md |
开发活动照这份(2026-07-30 重写为开发手册):世界观/四铁律/开发流程/清单六区/案例建模八纪律/判定表/工具/人类工具/运行时参考/自测/排障速查表;§15 = 待实现 | |
docs/debt.md |
欠账台账(只增,销账划线) | |
docs/adr/ · 各模块 CONTRACT.md |
架构决策与模块级不变量 | |
| 业务样例(活) | docs/MVP示例工作流.html |
七节点 SOP + 判定表 + 台账域 —— 开发活动的业务素材 |
| 前端语义权威 | ~/coding/JCAI_PRD/workbench ~/coding/JCAI_PRD/governance |
原型 1:1 平移(只平移不 import);工作台视图逻辑以 workbench/.../\_data/model.ts 统一建模为准 |
| 归档 | docs/archive/ |
已完成使命的文档(操作系统/活动模型两卷语义源、旧 README 规格包、PROGRESS、旧计划),只读;代码注释里的 OS x.x / AM x.x 编号指向归档卷章节 |
铁规矩(违者返工)
- 五道门禁以退出码验,不许以 echo 验:
pnpm -s typecheck && pnpm -s lint && pnpm -s depcruise && pnpm -s api:check && pnpm -s test(或pnpm gates)。 - 契约变更四步(§12.4):depcruise 反查下游 → 同步 CONTRACT.md →
pnpm api:check --update && git add api-report→ 破坏性走三步弃用。 - §12.5 禁止清单:no
any/as unknown as/@ts-ignore;domain 零 IO; 不删测试;不动门禁配置;不绕写三分/两缝。 - mock 只许出现在外界(邮件通道、外部系统的录制回放替身);系统内部机制不得 mock。
- 密钥只从环境读:
JCAI_DEEPSEEK_API_KEY(模型)、JCAI_SEED_PASSWORD(种子口令)、JCAI_SECRET_KEY(凭证密封);不入源码、不入包、不入留痕;E2E 永不回退开发库。 - 试跑一律用 AI 账号(密码
jcai-dev-2026),绝不派到用户工作台;测完pnpm --filter @app/api reset-runs清运行数据(清跑出来的,留配置好的)。 - 安装恒新增:活动/工具改了内容必须升版本号,同版重装是 no-op(静默丢失,踩过)。
- 界面不撒谎:状态如实(未绑就写未绑)、错误带厂商原话、不可用不摆假数字。
常用命令
pnpm gates # 五道门禁(gen:tiers → typecheck → lint → depcruise → api:check → test)
pnpm db:up # docker compose 起 PG16
pnpm db:migrate # 应用迁移(新迁移写 db/migrations/ 并登记 meta/_journal.json)
pnpm db:seed # 播种(五员工 + AI 账号;登录者 = 冯兵)
pnpm dev:api # :8787 pnpm dev:web # :5173(/api 反代)
pnpm --filter @app/api reset-runs # 清运行数据,留配置
pnpm activities:install # 只装活动包(不碰治理台配置)—— 开发活动时用这个,别用 db:seed
结构速查
apps/api/src/modules/<m>/{index,contract,port,CONTRACT.md,internal/{domain,usecase,adapter}}
apps/api/src/app/ # 唯一组装层:container / wiring/engines / routes / workers / seed
apps/web/src/features/ # desk-*(工作台)· gov-*(设计+运营)· auth
packages/{contracts,activity-sdk,sfeel,ui-kit,testing}
activities/<id>/src/{index,manifest,case-model,skills,views/} # 活动包(只准 import @sdk/@contracts)