Files
JX-BPOS/CLAUDE.md
ChaiHaoandClaude Opus 5 70e83d0b09 工作日志:一行摆首句,展开就把话说完
从前一条只有一行标题,而人真想回看的东西全躺在留痕里没露过面 ——
凭什么算这一步办完了、那一笔落下哪几行、被拒到底拒在哪儿、发的是哪种卡送到哪儿。
现在每条可展开,细节由 detailOf 摘成**一句句人话**(不摆 execution 这类内部名);
摘不出就是空数组,前端据此不给展开钮 —— 点开是空抽屉比不给还糟。

不摆二级条目(用户定):细节不是「键:值」两栏 —— 那是把留痕的字段名搬到人面前,
人还得自己在脑子里连成句子。每句自带主语与语境,单拎出来也读得通。

连带修一处文档与实现不符:「一轮一句」的口径说埋头办事那几拍的交代「留进工作日志」,
而实现把 internal 整类滤掉了,那几句哪儿都看不到。现在带交代的放行,
章写「交代进展」、记在 AI 名下;排障用的内部痕照旧不摆。
两种交代统一「首句上行、全文进抽屉」,一句话说完的不重复摆;截了才加省略号。

契约:任务详情的日志行新增可选 detail(字符串数组),api-report 同批更新。
门禁:typecheck / lint / depcruise / test(1378)全绿;浏览器实测折叠行高 34-36px 齐平、
展开无键值两栏残留。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-03 13:10:46 +08:00

838 lines
83 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# JCAI-WOS —— 企业级 AI Native 任务操作系统
> 一句话:组织的工作定义为可编排的工作流,工作流由**活动**编排而成;活动是完成一项任务的
> Agent 机制,系统外开发、安装即用。人只在责任点与放行点出现 —— 确定交系统,临场交 AI,落地交人。
## 现状快照(2026-08-02)
- **三面一体**:设计中心 `/design`(九区:蓝图/触发器/流程包/活动库/工具箱/数据域/知识库/
大模型/**测试台:三格 —— 流程(投一封信)/ 活动(按契约填入参)/ 日志(历次试跑存档)**)· 运营中心 `/ops`(六区:驾驶舱/工作流/任务/员工/台账/系统)· 工作台 `/`。
`/gov` 302 → `/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` 译成 DeepSeek `thinking:{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 用户:「点完验收按钮后会闪一下中间态」):
那不是渲染毛病,是**真的中间态**(合并 / 发口 / 落终态还在跑)。从前它落在通用四态里 ——
待办清零先闪一句「都办完了」再跳「已收尾」;那句话在那一刻是对的,可它说的是另一件事。
现在这一段说「字已签下,正在落地」。**中间态本来就该说出来,只是要说对。**
- **进度条漏了一格,和一条已经不存在的路**(2026-08-02 用户送来一条实测日志):
①`INTAKE_PHASES` 漏了 `S3_confirm`(它是 08-01 才补回成一项的)—— 计划项六个、名单里五个,
于是 S2 一收进度条当场跳到「判定去向」,而人这会儿正对着受理需求审定那张卡:
**他手上办的那件事在条上没有格子**,条却已经走过去了。补成四格
(定位客户 / 归一受理 / 交你审定 / 判定去向 + 基座统一加的放行收口),
包内自测钉死「除放行外每一项恰好属于一个阶段」。
②说明书里还留着「人交回来还缺必填,就再发一张卡」—— **提交闸上线后那条路已经不存在**
(缺必填按不下提交),模型照它办,每次都撞在「这件事刚问过,人也答过了」上,连烧四拍。
改成「这张卡一单只发一次」;同时把提交闸补到**服务端**(收下回传之前把住)——
说明书向模型承诺「卡回来时必填一定是齐的」,那句承诺只有服务端拦得住才算数。
- **话说的范围要盖住门拦的范围**(2026-08-02 用户问「为什么会少了 start」查出来的):
提示词那条规矩写的是「标了『须你启动』的项要先 start **再调工具**」——只说了调工具;
而拦截那一侧(`readyToWork`)管的是 tool / ask / human / decide / entry / finish 一整片。
模型那一拍要发的是 `human`(派工单),照字面读这条规矩管不着它,于是漏了 start,
撞上「S3_confirm 标了人工激活,要先 start 再干活」白烧一拍。**话窄一格,模型就正好漏在那一格上。**
写全之后三案例复跑 **全部被拒 0**(案例三从 14 拍 126k / 被拒 2 → 11 拍 97k / 被拒 0)。
同批两处呈现:目标价改左对齐(右对齐是给要竖着相加的数用的,这张表一行一个料、彼此不相加);
待处理那一屏表上方加**缺项红带**,点名还差几格、差在哪一行哪一列 —— 两个数由基座现算
(`_missing` / `_missing_keys`,与提交闸、放行门 L1 同源),「一格不缺就别出这条带」
交给样式表(`data-class-of` → `v-0` 那档 display:none),模版仍不算也不判。
- **A1 三案例常备**(2026-08-02):全 A 类直通 / 客户点名跳一条 / 新客户中文正文列料缺必填 ——
三条来件形状真不同(俄文 BOM 附件、正文点名跳料、中文正文列料无附件),
末次复跑 **3/3 released、全部被拒 0**(11 / 10 / 11 拍)。
- **A2/A3 按复杂活动 MVP 简化形完整重写**(2026-08-02 用户改盘:「MVP 期间只做精美验收报告 +
一张执行单,提交就是输出」):`quote-alternative@3.0.0` / `quote-sourcing@3.0.0`,各四项扁平
(归一 → 一张执行单交人 → AI 判稳/齐检 → 放行)。**A2**:挑 C 类组单交 FAE 系统外选型填回,
替代料查库行情**判稳定标**(≤90 天且稳转 A,否则转 B;尺与 P-03 的 A/B 行同一把),
询价受理记录就此转成**询价受理清单**;出口 `alt-route` 两口带 when(还有 B → to-sourcing,
全 A → to-pricing),verdict 落 `need_sourcing` —— **E5 自此第一次真正成立**(从前 A2 台账
没有承载列,那条边恒假)。**A3**:归一**目标报价清单**、A 类行按库内历史价预填
(`price_basis` tally HIST/SOURCED)、PRM 执行单补货源价 —— `base_price` 标 `required`,
件上红带 / 执行卡提交闸 / 放行门 L1 三处同源,实测闸真拦(单飞两颗料只填一颗,
交卷被点名「缺底价」)。判据全读基座读数(旧版两活动各两条 L2 读自报数,全部置换);
GRADE_DMN / STRATEGY_DMN 两张零求值器判定表、shortlist/benchmark/supplier_quote/compare_table
四张不再产出的表、两个死 `run()` 全部退役留墓志铭。报告各一张件贯穿在办与归档
(`alt-roster` / `sourcing-roster`,PRD 版面语言拷自 A1;A2/A3 无 PRD 目标件,用户定沿用自造)。
**验收:A2 3/3、A3 3/3 全部 `released`、行动被拒 0**(6-7 拍 / 38-47k token),
三案例形状真不同(流内混行载荷 / 免寻源转 A / 单飞宽进自造案号)。
`contract.input.required` 一律空(用户定:宽进严出,输入契约在活动内归一+补全)。
同批:A1@43 出口撤空壳 `altRequests`/`rfqRequests`(表已退休,数组通配让它装的与 records
完全相同);e2e 脚本落成 `tools/e2e-a2.mjs`(登录 AI → testbed 起单 → 件上按地址保存 →
答卡 → 断言 released/被拒 0/发口)。
- **「算出来的口」改为服务端算数**(2026-08-02,A2 e2e 逼出来的 harness 修死):放行卡的
`routedPort` 从前只在**前端回传**时顶上 `selectedPorts`(chat-bubbles 里那段),而放行落地
读的是**人事件载荷**(原始 reply)—— 换个客户端(脚本/API)就死在「选择组未选出口」,
台账已合并、单落 `blocked`。现 `human-tool-service.replyWorkOrder` 在发事件前算好**有效口**
(routedPort 优先,算不出才认人选),事件与返回值同一份 —— 服务端说了算的事,
不靠每个客户端自觉。顺带:执行卡 `fields` 缺席时基座兜底加必填「结果」回执字段,
代答脚本交卷要带 `values.result`。
- **A2 浏览器真人路走查通过并逮住一个洞**(2026-08-02):锁定 → 编辑 → 填错取消(还原)→
重填 → 保存(痕「改了 1 行」不撒谎)→ 交执行卡 → AI 判稳(原标 C 现标 B,依据逐行留痕)→
验收签字 → **released、7 拍/51k、被拒 0**;归档件零输入框、闸与红带都收、去向命中留在定稿。
逮住的洞:**模版主键格没挂 `data-col`,人保存的行没有钥匙**,服务端按「全表一致列」补键,
两行对到同一行上、后者盖前者(BBPY 的 C 标被隔壁行的 A 盖掉)—— e2e 走 API 自带主键测不出,
只有件上真按保存才现形。修:主键列必挂 `data-col`(它不是编辑面,是行的钥匙;A1 从头就带),
两包自测钉死,`quote-alternative@3.1.0` / `quote-sourcing@3.2.0`。
A3 另修一处时序:第一拍禁写 verdict(凭据列提前落会让引擎提前收步,预填从此不发生 ——
实测嘴上说预填了、台账里没有)。
- **A2 执行件重做成替代选型工作单**(2026-08-02 用户:「执行工单的 HTML 怎么是按验收单做的?
替代选型要为选型高度定制一个模版」):`quote-alternative@3.4.0` 两个局面各一张 ——
`alt-worksheet` 选型工作单(S1/S2 摆):逐颗料一张**选型档案卡**(题面:要素/为什么要替代/
客户约束与预授权;定案回显带待填胶囊;A/B 行收成「原样承继」一行)+ **替代等级判据表**
(P2P 直换 / FUNC 功能兼容 / OTHER 须验证,附 pin-to-pin 五项核对与「同封装不等于同引脚」警示)+
三层筛指引(参数硬指标 → 认证合规 → 供应价格)+ 填回工作表;`alt-roster` 清单(S3/放行/归档)。
台账补齐**对标维度**:`alt_grade`(tally P2P/FUNC/OTHER)/`alt_diff`/`alt_risk`/`alt_verify` +
承继 `remark`(预授权/约束);执行卡指导书按等级写死核对深度。复跑 3/3 released、被拒 0。
连带逮住一个渲染器约束并记进陷阱表:**行展开按第一个同名闭合标签截行内容** ——
`<div data-rows>` 的行模版里嵌 `<div>` 会把行截成套娃(第二张卡长进第一张的表头里),
行容器要用行内不会再出现的标签(`<section>`/`<tbody>`)。
- **A2 选型工作单精专一颗 + 逐颗按序派单**(2026-08-02 用户两条:「选型 HTML 里为啥出现
ABC 类描述的表?这个报告就精专一个芯片的选型」「多个芯片按顺序派选型单」):
`quote-alternative@3.8.0`。台账加**排程列 `sel_stage`(tally NOW/WAIT/DONE)**:
S1 给每颗待选型料标 WAIT;S2 只 start 一次、一串卡都发在它名下 —— 每轮把一颗置 NOW、
发**这一颗**的选型单(标题带 PN 与第 k/n 颗,互不撞「一单一卡」闸;卡=七格表单,
选填显式 `required:false` 留「替代未果」通道),人交回 → 定案照抄落行、置 DONE → 下一颗;
全部 DONE 记 filled_total 才 finish。工作单随排程列演**当前这一颗**:顶部选型队列丸
(当前蓝/办结绿/排队灰,非选型行一枚不出)、替代关系图(芯片→芯片内联 SVG,未定案「待选定」红)、
题面/定案两栏档案、等级判据三档配示意图(P2P 引脚一一对应/FUNC 芯片+外围件/OTHER 打样烧瓶)、
pin-to-pin 五项核对图标带(封装尺寸/引脚/电气/温度/认证)、三层筛漏斗;填回表只显当前行;
已定案收一行摘要 —— **ABC 分类语言全部归收口清单**(自测钉死工作单正文不含原标/分布条/判稳)。
验收:3/3 released、被拒 0(双卡案例 8 拍/69k,第 1/2 → 第 2/2 依序)。
路上逼掉三类抢跑(guide 写死):S2/S3 收步后「这一拍到此为止」、第一轮 start 提成显式第一步、
被拒重试不重写已生效的值(空转写也是拒)。
- **A3 执行件同款重做成寻源询价工作单**(2026-08-02 用户定,素材取 MVP 示例工作流 §1.7
**只作文字参考、不作实现逻辑参照**):`quote-sourcing@3.4.0` 两个局面各一张 ——
`sourcing-worksheet`(S1/S2 摆):逐颗待询料一张**询价档案卡**(题面含**取价对象**
「替代料有值取替代料」/客户约束;A 类收成「已按历史价预填 · 可校可改」一行)+
**按场景圈渠道**规则(BOM早期可放宽 / 后期主→备选→贸易商圈两三家贸易商尽量不用 /
现货只认库存实拍无库存转单商不可选 / 样品量小求快)+ **价格验证的尺**(早期首报即用 /
后期按历史最低降两成两轮核 / 现货多重校验 / 样品低于线上即用)+ 发询纪律与时限带 +
填回工作表(缺价红带与提交闸同源);`sourcing-roster`(S3/放行/归档)。
`quote_list` 补承继列 `remark`(认证/预授权/急料)。复跑 3/3 released、被拒 0。
同批堵一条自造案号的口子(A2@3.5.0 同款):单飞造号**只从本单来件取材,
不许从台账里已有的别单单号里挑** —— 实测一轮借走了正式表里的 MD14.1。
- **执行卡零输入**(2026-08-02 用户定:「执行卡片不要有任何填写的了,填写全去工作区,
包括A1的补全信息,那个『结果』输入框没任何作用」):基座兜底的必填「结果」textarea 删掉
(`fields = declaredFields ?? []`);三活动卡骨架撤 `blocks`/`fields` —— 填报全在
工作区的件上(editGate + 孪生件,保存即落草稿层,模型**不许再 write 一遍**)。
**提交闸回落**:卡不绑表时改看必交付物声明的 `ledgers`/`ledger`(纯函数
`gateAddressesOf`,有测),与放行门 L1 仍同一个数;服务端收回传前同一段把关。
连带删「执行工单 = 指导书 + 空表单,表单不得为空」的拒发 —— 通道换到件上之后,
那道机检让活动照新规矩发卡、基座按旧规矩连拒到熔断(实测 A1 五拍)。
- **A2 选型件升格「一页汇报」**(2026-08-02 用户:「还是不够华丽,要设计成强交互的
汇报形式,直接拿去当一页 PPT 的程度」):深空电路底 hero(队列信标呼吸 /
原厂芯片 → 流光走线 → 替代定案 / 四格账)+ 编号 slide 小节推进(题面七格 ·
等级三卡悬停展开口径 · 五项核对徽章 · 三层筛 · 填回表 · 已定案摘要,空节 `:has` 自折)。
「强交互」全是纯 CSS(hover 浮起 / focus 展开 / reduced-motion 全静),沙箱仍零脚本、
模版仍不算不判。规范新增 §8.5 立此语言;踩了「媒体查询写在基础规则之前被盖掉」
的层叠坑(竖排下走线该藏未藏,排障入册)。
- **start 墙拆除 + JSON 括号栈 + 空转拒回带指南**(2026-08-02,零输入改造连跑逼出):
①**人工激活「先 start」不再是墙**(`readyToWork`):措辞写全(话与门同宽)之后 A1
仍连拒五拍熔断,五次全是「要先 start」—— 那墙保护不了任何东西(start 是模型自己的
动作,同一串连发即过),学不稳的礼仪就是死法;现在**动它就算启动**,人工激活真正
要保的两条(引擎不因哨兵替启、不给 doneWhen 替收)原样有测。三活动剧本的 start
礼仪同批删除。②关思考的模型偶发多吐一个 `}`,单数花括号的配平切出半截非法片段,
整拍六个动作全对却退化成「需要你判断下一步」兜底卡;`parseJsonLoose` 改**括号栈**、
不配对的闭括号当噪声丢(7 测)。③「写了等于没写」拒回补行动指南(值已在台账 →
该办下一件事),治 A2 收步时连拒四拍的重写循环;A2 判稳同批堵死「拿上游原 PN 的
9999 顶替、不亲查 alt_pn」的近路(实测走岔过一单去向)。
**e2e 三套七案例 7/7 released、全部被拒 0**(6-11 拍):a1 闸拦空手交卷→件补年用量;
a2 to-sourcing / to-pricing / to-sourcing;a3 quotation×3(案例 3 闸拦真拦)。
浏览器全链走查:hero 呈现、编辑→保存→落草稿→队列推进(办结绿/当前信标)→
零输入卡提交→released。A1@45.0.0 / A2@4.5.0 / A3@3.6.0。
- **一天里连挨三炸后的返工账**(2026-08-02 下午,全部用户实测逼出):
①**工作区滚轴拉不到填写区** —— ViewContainer 量高在 `editable` class 落下**之前**
(闸/红带现身把内容撑高 122px 没人再量),且 ResizeObserver 挂在 srcdoc 之前那份
空白文档的 body 上(盯着一具尸体);修:先 bind 再量 + observer 每次有机会重挂真 body。
②**「稳定的活动又开始出错」** —— 零输入改造时我往**全局提示词**塞了一句
「执行工单…别再 write 一遍」,把 A1 说明书「人交回确认卡后写 confirmed_total 记账」
顶翻:模型收到答复不记账不收步、把确认卡当没答成,重发同一张卡连拒五拍熔断。
改回通用真理(「人答回的东西在轨迹里,照说明书处理,别当没答过再发一张」);
**全局提示词只说通用真理,活动级细节归说明书** —— 此为铁训。
同批把「重发已答过的卡」从拒改为**头两次无事发生 + 观察指路**(第三次起才算被拒,
熔断兜底仍在),空答复落痕带「人已办完并交回」一句(空 values 在模型眼里像没答)。
③**「啥都没干就能提交」** —— A2 定案列当时全标选填(想保「未果留空」通道),
闸回落后成了没牙的闸。新增**行级必填 `requiredWhen`**(`{column:'sel_stage',
value:'NOW'}`:该轮到的那一行才算必填,排队的颗不拦当前的卡 —— 表级 required
在逐颗派单下会被第二颗的空格拦死成死锁);未果通道改「备注写缘由 + 行首 × 撤行」。
`_missing`/红带/提交闸/放行门同源生效,e2e 三案例空手交卷全部 400 真拦。
④**「输入区和汇报内容为啥分开?一屏都看不完算什么一页 PPT」** —— A2 工作单改
**看与改同一块**:01 区平时是汇报稿(题面七格+定案摘要+档案行),按「编辑」同一块
换成表单(`:has` 切换),保存/取消回稿;方法论(等级三卡/五项核对/三层筛)收进
原生 `<details>` 折叠条(零脚本);页高 2528 → 1285。A2@4.7.0。
⑤**遗留(记 debt):A2 单飞判稳连续两轮「不查工具直接编」**转 A 走岔去向 ——
说明书措辞已到头,结构性根治 = 判稳 decisionTask 化 / 工具出参带标(见 debt.md);
现状兜底:验收页 type_tag 可改、去向跟着变。
⑥契约变更:`FieldDeclaration.requiredWhen`(api-report 已刷新,随本轮一并提交后
api:check 门才绿 —— 它拦的就是「契约变了没入库」)。
- **A1「又出补全卡」的病根:入场哨兵读自报列**(2026-08-02 用户送来 exhausted 单):
`s_parsed` 读模型自报的 `line_total`,模型把 record 三行在 S1 拍写完、没记这个数,
S2 空手收步 —— 门永不开,引擎报「依赖断点」,提示词「断点请调人」把模型推去发
补全卡绕路(两张标题只差尾巴的卡把 humanCalls 4/4 烧光)。
**「机检只读基座数」第四次违反现形,这次是哨兵**。修:s_parsed 改读
`quote_intake_record_rows > 0`(行落了门就开,不等模型记账);`sameQuestion`
补前缀比对(≥6 字前缀 = 同一问)。复跑新客户空手确认路:**released、被拒 0、
断点 0、补全卡 0**(11 拍,回稳定基线)。A2/A3 哨兵同缝记 debt。
- **补全卡(ask)全局退役**(2026-08-02 用户定:「彻底全局退役补全卡,执行卡完全
就是包含补全语义的人类工具」):缺信息 = 发**零输入执行工单**(指导书写清缺什么,
人在工作区的件上补)。归一层把旧输出的 `ask` **原地转成执行工单**(字段名并进
指导书;拒回只会让模型换花样再发,归一才是铺路);引擎侧直发 `ask` 如实拒并指路;
提示词④段改写、handsOff 去 ask;A2/A3 剧本里「未果问人」改用决策卡(二选本就是
处置);规范 §3.4 五类卡 → 四类。历史卡回放兼容件(契约类型/前端渲染/起单老路)
留着,清理记 debt。A1@47.0.0 / A2@4.8.0 / A3@3.7.0。
- **A2 工作单第三版:对决卡 + 一张贯穿 + 占位三级**(2026-08-02 用户四条连发):
①「01 重构成渲染态就是结构,编辑就是写组件内的值;顶栏与 01 合并:左静态原厂
SVG 卡、右替换卡、等级直接选择(正确性全由人控)」→ **对决区**:深空 hero 里
左卡(原厂题面规格)→ 流光走线 → 右卡(替代定案就地编辑);**等级 = 三枚自绘
radio**(不写 checked,当前值 data-class-of 投影描虚线;基座 collect 对未选中
radio 整列不交 ——「没点」是「不改」;快照/取消按 checked 存取)。
收值铁律:**一张卡里所有输入格的祖父必须同一元素**(collect 按祖父归行)。
②02 指引铺开、不写类型(口径贴在三枚选择钮上);③**空占位三级全局统一**:
必填红 / 建议填橘 / 选填灰 = required / expect / 其余(A2 已上,A1/A3 记 debt);
④**一张模版贯穿到底**:「待处理的 HTML 报告完成后直接转变为静态的工作成果」——
alt-roster 退役,收口内容(清单总览三态丸、去向判定)长在同一张尾部有值才现身;
规范 §1 硬规矩收紧,A1/A3 旧制记 debt。基座陪三小刀:`setOpen` 对非表格容器把
`.on` 落在 `data-edit` 元素自身;collect/快照/取消的 radio 特判。
验收:e2e 3/3 released 被拒 0(闸拦三案例全 400);浏览器实证 radio 选 P2P →
保存落草稿 → 徽变绿 → 取消还原(含 radio uncheck)。A2@4.9.0。
- **A2 工作单定稿为 One Pager + 单卡多页 + 成果 1:1 快照**(2026-08-02/03 用户连定):
①「这份报告就是一颗芯片的替代选型」—— 队列丸/清单总览/去向段全撤(收口整合的
东西不在这份),版面 = 深空 hero 对决卡(左原厂静态 SVG 卡 · 流光 · 右替换卡)+
选型指引(不分段);「待选定」与必填同风格红胶囊左对齐;编辑钮做进替换卡右上角
(cardbtn 三件套仍是 data-edit-open/cancel/save);等级口径贴在三枚选择钮上。
②「一个执行单可以派多个 HTML 待执行报告,合理利用右上角的翻页」——
**逐颗派单退役**:一张执行单,件里一颗待选型芯片一页(行挂 `data-page`,
orig_type=C 成页),右上角箭头翻页;`sel_stage` 排程列整个退休;
requiredWhen 改钉 `orig_type=C`;双 C 案例 7 拍(比逐颗省)。
基座配套:渲染器**行内表单组名唯一化**(radio 组按行号缀名,页间不互斥);
ViewContainer 通用分页(`[data-page]` 可见段,`page`/`onPages`,不传 page 不分页)。
③「工作成果要 HTML/UI/数据/内容/布局 1:1 从待处理转成静态报告」(反复强调)——
病根:执行单定稿走 WorkOrderReport 卡壳、验收单渲「当下」视图,都不是办结时那份。
修:**回执收下那一刻把渲好的件存进工单**(`WorkOrder.finalHtml`),成果页
1:1 静态渲快照(零编辑钮、数据定格);旧单无快照退最近视图再退卡壳(历史兼容)。
e2e 3/3 released 被拒 0;浏览器实证:1/2↔2/2 翻页、两页一次保存全落库、
成果点开即对决卡静态版。A2@4.10.0。
- **A2 逻辑收口:两件各归各位**(2026-08-03 用户:「验收工单怎么又变成选型了?」):
「一张贯穿」被我执行过头 —— 验收阶段摆的还是选型 One Pager。校准后的口径
(规范 §1 已改):**「1:1」的落点是每份件与它的办结快照**(在办可编辑 ↔ finalHtml
静态归档),**不同工作各有各的件** —— 选型 One Pager 归执行单(S1/S2),
**收口整合清单归验收**(S3/放行/归档,`alt-roster` 恢复:整份清单
原标/替代/等级/现标/依据 + 按分类算出的去向判定,只读 —— 就地改走验收卡的
editableAtRelease 表)。浏览器全链实证:验收阶段工作区 = 收口清单(判稳这轮
也真查了工具:43 天·稳 → 转 A);成果两份定稿各是各的快照(执行单=One Pager
静态、验收单=清单静态)。e2e released 被拒 0。A2@4.11.0。
同批沉淀:活动开发规范新增 **§6.5 设计律八条**(墙要配路 / 学不稳的礼仪就是死法 /
拒回喂对抗观察喂事实 / 机检只读基座数管一整片 / 提示词分层 / 措辞治不了的结构治 /
改共享面全量回归 / 用户重复提的要求说明没打中病根);HTML 规范补「概念图形是
第一语言」与「收值三铁律」。
- **A2 两张报告第四版(用户 /brand 推倒重设计)**(2026-08-03):
①**选型执行工单**重单颗芯片:白纸文件基底 + 身份条(眉头式,客户在条内不占右上角),
深空只留「对决 Stage」(原厂芯片 →流光→ 替代芯片,PN 大字,**编辑钮组在 Stage 右上**);
定案面板白纸双栏(左题面灰底/右定案,输入全在右栏);指引脚注化(五徽一行+三层筛横条)。
②**选型验收报告**重列表与落边:汇总带(条数/A/B/C)→ 受理记录大表 →
**落边图**(SVG 流程:清单 → 菱形「还有 B 类?」→ A3 寻源/A4 定价,命中边实线亮+流光、
未命中灰虚,`case:routeKey` 投影 —— 不冒充判过)。
③占位三种定稿:**必填(红)/选填(灰)/建议(橘)**(`ph-req/ph-opt/ph-sug`);
**等级空位归「必填」**(不再写「待选定」),打开编辑即三枚选择。
e2e released 被拒 0;浏览器实证:Stage 空位红胶囊呼吸、落边图 v-r1 命中亮线带真实计数。
A2@4.12.0。
- **兜底卡不再摆模型原话:输出不成形先就地重问**(2026-08-03,用户送来一单:
「正常派工单为啥不是作业指导书,卡片里又是乱七八糟的东西」):关思考的模型偶发把
整拍输出写坏(一串行动一个都不认识 —— 多闭括号那形已由括号栈自修,这次是另一形),
从前一次没认出就发「需要你判断下一步」兜底卡,还把 JSON 原话整段摆卡面。
现在 `normalizeTurn` 标 `unrecognized` → decide **就地重问一次**(原文经 `note`
存工作日志内部痕,附「只输出 JSON」硬提示);第二次仍不成形才交人,卡面只说人话
(原话在日志,不上卡)。假网关三测钉死:重问只一次、原文进痕、好拍不白重问。
复测 e2e a1:released、被拒 0(11 拍/102k)。
- **提交钮靠右 + A1 占位补齐三级**(2026-08-03 用户两条):①执行工单的提交钮从卡脚
左侧移到右侧(`jc-fc-ft` 加 flex-end;验收卡「重做|通过」有 `jc-fc-sp` 撑着不受影响;
旧版报告页脚 space-between 同批)。②A1 报告里品类/制造商/目标价三列的空占位从灰
「选填」改橘「**建议**」(用户点的是目标价)—— 档位跟台账声明走:required→必填红、
expect→建议橘、其余→选填灰,颜色与 A2 同套;备注仍选填;「分级依据」那段话同步改口。
跟着一条(用户:「没有和数字对齐」):裸 inline-flex 胶囊按 baseline 挂,盒子比字的
基线深几像素,整枚往下坠、行高忽高忽低 —— 空格子(`:empty`)转 flex 居中 +
`min-height` 撑住文字那份盒高,胶囊中线对数字中线(陷阱表入册)。
再跟一条(用户:「编辑态太拥挤」):那条 flex 规则比「编辑态藏只读份」的 display:none
**更特异**,编辑态里胶囊盖过隐藏冒了出来,54 个输入框旁边各站一枚 —— 圈上
`:not(.on)`:胶囊只属于看的那份,编辑态里该不该填由闸与红带说。
quote-intake@48.2.0 已装,62 测绿。A3 的占位三级仍欠着(debt)。
- **保存不再闪:就地换内容的第二层是逐节点 morph**(2026-08-03 用户:「保存的时候
HTML 会闪一下,之前都修过怎么又来了」):08-02 那刀把 srcDoc 重载换成
`body.innerHTML`,文档不再重载 —— 可整树仍是**推倒重建**:47KB 样式表在 body
再解析一遍(head 那份还在,从此一文档两份同文样式,实测拿探针在真单上量出来的)、
二十来个 SVG 全部重建、CSS 动画回第 0 帧重起跳 —— 同一个症状,病根在下一层。
现 `ViewContainer.replaceInPlace`:顶层样式归位 head 去重(注意 `:scope > style`
在 DocumentFragment 上**实测不命中**,要用 children 过滤 —— 不然新旧顶层错一位
全树失配,浏览器独立三轮验证逮出来的)+ `morphNode` 新旧逐节点对齐,一样的不碰,
输入件活值只在拟值真变时跟上(人敲了一半的字不因无关重推被擦);任何一步栽了
退回整树重建(闪但不错)。验证:浏览器独立三轮(改值保identity/加行保敲字/
遗留双样式自愈)全过;1103 测、typecheck/lint 绿。真单上的探针账:save 后
probe alive、loads 0、无 remount —— 闪的确不是重载,是重建。
- **「保存后旧值还持续一会儿」才是人看见的那件事**(2026-08-03 用户第三次指出同一处):
上面两刀治的都是**重绘**,而人说的是**内容**:保存要跑个来回(POST 落草稿 → 失效缓存 →
重取详情 → 新件推回),闸却在按下那一刻就关了 —— 这几百毫秒里屏上摆的是只读那份的
**旧值**,人刚敲完的数当场消失,看着像这一下没生效(会再改一遍、再按一次)。
值本来就在手上,不必等服务端告诉我们:按下保存**先把新值写进只读孪生件**再关闸
(`mirrorTwins`),回声到达时 morph 一比已经一样,一次重绘都没有。
只镜像格子自己的值 —— 红带缺几格 / 分布条 / 去向是**基座算的数**,一律等回声(界面不撒谎)。
途中逮住一条会让这一段静默失效的事实:**渲染那一遍把 `data-slot` 连同槽位一起消费掉**,
活 DOM 里只读那份与 input 都没有这个属性;认孪生件要**按位置**(`previousElementSibling`)。
第一版按 `data-slot` 找,在我自己搭的合成 fixture 上全绿、在真单上一格都不动 ——
**验证要在真单的 DOM 上做**。实测:显示 1ms(点击同步内完成)、20 秒 663 帧零抖动、
值真落库(服务端详情里就是新值)。
- **A4 成本定价补齐到验收线**(2026-08-03,`quote-pricing@3.5.0`):契约宽进(input.required 清空,
原本 required `customerCode`+`records` 而上游 A3 发的是 `rows` —— 这条边真跑会断)、
`draft` 口载荷对齐 A6、哨兵与判据全改基座读数(`draft_total` 自报数是第 5 类同款违反)、
两份件(pricing-worksheet / pricing-roster)、78 条包内自测、e2e 加 `a4` 套件
(含**决策卡代答** answerDecisions / expectDecision)。**e2e a4 3/3 released、被拒 0**
(7-9 拍 / 54-74k),闸每单真拦,超限那单真发决策卡。三处踩坑各留一条账:
①**只有一列价时 AI 会编价**(库里查不到的料它照样填一个,交代还说「价空着等你定」)——
结构治:拆 `suggested_price`(AI 算)/ `quoted_price`(人填,`required`),
闸从此每单有牙,不靠模型分辨「这行算得出没有」;②门禁三列没人写、放行门只说
「数不对/行不对」→ 底价自检独立成项 `S3_gate`,`doneWhen` = 三档守恒(与验收 L2 同源);
③人点完决策卡后那一步被重念、guide 头一段写着「发一张决策卡」→ 连发四张烧光调人预算,
改成**先分岔(轨迹里人选了没有)再谈动作**。
- **决策卡也有了幂等兜底**(2026-08-03,A4 逼出):`resendVerdict` 抽成纯函数,
执行工单与决策卡**同一把尺** —— 人已答过的同一问,头两次「无事发生」(卡不真发、
humanCalls 不烧,只把事实摆回轨迹),第三次起才算被拒(熔断仍看得见)。
从前只有执行工单那一路有,决策卡一道都没有:同一个岔路口连发四张,四次调人预算
烧光落 `exhausted`。**按钮按两下不该变成墙,也不该变成四张卡**;6 测钉死三档。
- **重发判断要走在站上场之前**(2026-08-03,**A1 基线当场熔断**逼出来的顺序):
人答完之后那一步常常已经收掉,而 `readyToWork` 走在前面 —— 对 Completed 项直接抛
「这一步已经办完,不能再往它上面挂活」,于是「重发已答过的卡 = 无事发生」这条**唯一的活路
在最需要它的时候够不着**:同一条拒回重复五遍熔断(实测 13 拍 124k、发口一个都没有,
而数据本身合规)。重发一张已答过的卡本就不需要那一项在场 —— 它什么也不做。
两族(human / decide)同批换序,无事发生那一路**原样交回局面**(不顺手把项推上场)。
这是设计律第一条「墙要配路」的第三次现形。复跑 A1 四轮:三轮 released 被拒 0、
一轮 released 被拒 4,**熔断不再出现**。
同批修 e2e 脚本一处误判:**「已回传」不是「闸拦着」** —— 两种 400 长得一样而处置正相反,
当成闸拦着就原样再交一遍、三次判失败,把一单 released 的 A1 记成了失败。
- **A6 报价议价补齐到验收线**(2026-08-03,`quote-negotiate@3.5.0`):五项
(排版报价函 → 交人发出并落客户回音 → 逐条定案 → **还价才叫人拍板** → 放行),
四道哨兵全读基座读数,两张判定表(N-01 议价结果 / N-02 让步梯度),三口带 `when`
(won / revise / lost),两份件(negotiate-worksheet 可编辑 + negotiate-roster 收口含落边图),
90 条包内自测,e2e 加 `a6` 套件。**连跑两轮 3/3 released、被拒 0**(6-8 拍 / 44-65k),
三口各覆盖一条,闸每单真拦,还价那单真发决策卡。三个结构账各修死并有测:
①**同一张决策卡连发六次** —— `revise` 那条路原写「定案不动」,人点完哨兵照旧成立;
改:`deal_status` 加第四档 `REVISE`,拍板三条路都必须动它,「办完了」在数上看得见。
②**模型自己写 REVISE 绕过拍板**(一轮 released 而决策卡 0 张,让步梯度成摆设)——
病根:哨兵读模型判出来的 `deal_status`;改读**客户自己填的那一格**(`_reply_type_counter`,
基座现数)。**「该不该叫人」不能由被叫的那一方说了算**。
③断点那几拍模型自编决策卡(拿计划项中文名当 itemId / 换问法发出两张)——
itemId / ask / 选项值写进**说明书**(说明书每拍都在提示词里,而 step guide 在断点时没摊开)。
**等外部回音落在执行工单上**(人收到信把回音填进件里),不用 `listen` ——
引擎的 `listen` 恒挂起而 desk 侧没有投递 data 事件的入口(记 debt)。
- **五套十三案例一次全绿**(2026-08-03,第三阶段主体达成):A1 1 + A2 3 + A3 3 + A4 3 + A6 3
= **13/13 released、行动被拒 0、发口全对、提交闸每单真拦**(6-11 拍 / 45-108k token;
两张决策卡分别落在 A4 超限拍板与 A6 让幅超授权)。门禁 1278 测、typecheck / lint 全绿。
这一轮同时是**共享面改动的回归证据**(agent-runner 重问 / turn-runner 重发换序 +
决策卡幂等 / ViewContainer morph 与保存镜像)。A7 归档同法补齐中。
- **「机检只读基座数」第一次覆盖到工具**(2026-08-03,治 A2 判稳偶发走岔):
新读数 `tool_<工具名去符号>_calls`(`toolCallReadings` 按留痕数**成功返回**的次数,
声明过的工具一律先铺 0;调失败不算查过 —— 调不通等于没拿到行情)。
病根:判稳的行情只有 `crm.history-price-read` 一条来路,而模型偶发压根没调工具
就把料判成「稳」转 A,**自报的依据列写得漂漂亮亮**,去向从寻源走成定价(约十次一次)。
说明书已写到头,**措辞治不了的结构治**(设计律第六条)。A2@4.14.0 立 L2:
`quote_alternative_list_type_tag_a = 0 or tool_crm_history_price_read_calls > 0`
—— **写成析取**:一颗都没转 A 就无需查行情(全 B 那条路合法),有 A 才必须亲查过。
静态审(`static-audit.boundNames`)与包内自测的「谓词绑得上」名单同批扩到这一类
(`declarations.tools` 在审计入参里做可选 —— 老调用方只传 ledger,别掀翻整份审计)。
判据锚在 `orig_type_c`(原标)而非现标 `type_tag_a`:清单里的 A 多半是**上游原样承继**的,
拿现标当锚会把「全是承继的 A、一颗 C 都没有」这条合法路径也拦下。
- **「闸没拦」与「压根没东西可拦」是两件事**(2026-08-03,一次假失败逼出来的):
`expectGateBlock` 从前写成「空手交卷必须吃 400」,于是模型碰巧把该填的格子全填上的那些轮
(A1 补齐了缺的年用量、A2 客户点名的替代料型号本来就在来件里)一律被判成「提交闸失效」。
**而闸好端端的** —— 拿一单直接空手交卷实测吃的就是 400,还点名了缺哪一行哪一格。
现在断言分三档:blocked / nothing-missing(该填的全填上了,闸无需出手)/ leaked(缺着还放过去,真失效),
用**与 buildEdits 同一份草稿、同一个列名**去数。断言报的失败是假的,真失效那天反而没人信它。
- **A7 情报归档补齐到验收线**(2026-08-03,`quote-archive@3.0.0`):归一情报卡 →
一张零输入执行单(逐条落**输赢归因** + 竞对价)→ 按败价幅度算档 → **入库口径决策卡**
拍板(全量/脱敏/仅内部)→ 放行,一口 `archived`。哨兵读**人填的那一格**、
6 条 L1/L2 全读基座数、`competitor_price` 用 `requiredWhen{cause_tag:PRICE}`
(交期/认证败的行不被拦成死锁)、82 条包内自测。**e2e a7 3/3 released、被拒 0**(各 7 拍/54k)。
同批退役三张共享域表并留墓志铭(单案例算不出月度落地率、客户档案 A1 已持有、
行情历史与情报卡是同一份事实)。
- **A2 常路会跳过派给 FAE 那一步**(2026-08-03 发现,**未修**,已写 debt):
案例①连续三轮 6 拍收口、一张执行工单都没发 —— 模型自己把替代料填了,
而 S2 的 `doneWhen` 认的正是那几格填没填,于是收步条件当场成立、**人环整个消失**。
这是「触达世界的项不给 doneWhen」的反面教材:「把清单交给 FAE 选型」触达的是人,
完成与否不该由数据形状推出来。治法与 T_release 同款(人工激活 + 不给 doneWhen)。
**排除项**:撤掉当日新加的工具留痕判据(@4.15.0)后原样复现 —— 不是它引起的。
- **A1 的话与工单说的不是一回事**(2026-08-03 用户四连指出:「这个工单是让员工填必填,
建议追问目标价,其他选填,你这条日志的表述就完全变了」):件与卡早已是**三档**
(必填红 / 建议橘 / 选填灰),而 A1 的说明书还在教**两档** —— 目标价被明写成「选填」,
于是交代里说成「缺的选填项你看着补」;更糟的是同一句里「NE555P 我先照历史价估」:
**它把 S4 查来的历史价当成了客户的目标价填进去** —— 那是替客户表了态,
下游定价议价全建在这个假数上。三处同批改齐(`quote-intake@49.2.0`):
①说明书「两种分量」改「三种分量」,逐列点名哪几格是建议档,并写死
**目标价客户没给就留空、不许用历史价或经验价估**;②say 口径写明「用件上那三个词、
只说事实」;③S3 卡骨架的 steps/standard/basis 与验收判据 label 一并换成「建议追问」
(judge 按整句对名,说明书那一处同字改)。实测交代已改成
「DAG… 缺年用量(必填),UMW… 缺制造商、NE555P 客户没给目标价(这两条建议追问,不拦单)」。
- **反例引了原话,模型照抄反例**(2026-08-03 用户送来 10:40 的单:「还是老样子啊,
派工单的时候为什么会查历史价?」):上一轮治措辞时,我把那句错话**原文**引进说明书
当反例(「别说『我先照历史价估』」)—— 关思考的模型不读「别说」的否定框,
只认框里现成的句子,又原样说了一遍。台账数据其实全对(信里给了 8.0/22,NE555P 留空,
一个假数没写),错的只有这句被我喂进去的叙事 —— 且它谈的历史价那一拍**根本还没查**
(S4 未跑,轨迹里零工具调用):纯编造。治法(`quote-intake@49.3.0`):
①**反例一律不引原话**(描述失败,不给可照抄的句子),A1 三处清扫,其余五包 grep 无同类;
②**要引原话就引正例** —— S3 派卡拍给了一句完整交代模版(三档词 + 只说事实);
③叙事纪律:历史价/分类/去向是审定之后那几步的事,派卡拍一个字不提。
验证:同一封信两轮 —— 一轮平实无编造、一轮逐字命中正例模版,台账两轮全对。
**提示词里唯一该出现的原话,是你想听到的那句。**
连带一笔:复现时我起的试跑单把用户 10:40 那单顶掉了(试跑台一次只挂一单,已有 debt)——
**用户正在测试台上测的时候,别起自己的试跑单**。
- **执行卡的指导书空了:卡骨架住错了地方**(2026-08-03 用户:「作业指导书展示不对了」):
受理需求审定卡的骨架(steps/standard/basis)写在 S3 那一步的**剧本**里,而模型把
「建档→落表→收步→派卡」压成一拍连做(被鼓励的省拍打法)—— 那一拍摊开的是 S1 的剧本,
S3 的骨架看不见,模型凭记忆拼出一张裸卡,基座兜底 basis 又摆上「当下可为(空)/目标缺口」
这类内部家具。**卡内容不该取决于它在哪一拍被发出**。两处修:
①骨架搬进**说明书**(每拍都在;A6 决策卡先立此法 —— 断点拍自编决策卡同一个坑),
剧本留一句指路;第一版误插进 S1 剧本(录入卡骨架就住在那儿,被我当成了说明书),
测试逮住后挪进 NARRATIVE 本体。②`steps`/`standard` **补进出参 schema** ——
它们从前不在 schema 里,能到卡面纯靠厂商 JSON 模式宽松放行,而本仓早有纪律
「结构化出参只吐 schema 里声明过的键」(ai/ledger 当年就是这么丢的)。
`quote-intake@49.5.0` 已装;1366 测、typecheck/lint/depcruise 绿。
用户在途那单已见到全指导书;e2e 复跑等测试台空出来再补(他的单还开着,不顶)。
- **工作日志:一行摆首句,展开才看细节**(2026-08-03 用户:「细节展开不够好」):
从前一条只有一行标题,而留痕里那些人真想回看的东西 —— 凭什么算这一步办完了
(`rationale`)、那一笔写了哪几行(主键名单)、被拒到底拒在哪儿(`reason`+`hint`)、
发的是哪种卡送到哪儿 —— **一个字都没露过面**。现在 `detailOf` 把它们摘成
**人读键值对**(与 title 同一条纪律:不摆内部英文名、认不出的不摆),
折叠不占地方、展开才现身;**摘不出就是空数组,前端据此不给展开钮** ——
点开是空的抽屉比不给还糟。
连带修一处**文档与实现不符**:「一轮一句」口径说埋头办事那几拍的交代
「留进工作日志」,而实现把 `internal` 整类滤掉了 —— 那几句**哪儿都看不到**。
现在带 `say` 的放行(它是人话),章写「交代进展」、记在 AI 名下;
排障用的内部痕(重问原文)照旧不摆。
两种交代统一「首句上行、全文进抽屉」(一句话说完的不重复摆,免得点开发现一模一样);
截了才加省略号 —— 加了等于说「后面还有」。
实测:一单 8 行、6 行有抽屉、行高 34-36px 齐平,展开那两行 141/103px。
14 条新测(detailOf 五类 + 压下交代放行 + 首句去重)。
## 文档权威地图
| 层 | 文件 | 说明 |
|---|---|---|
| **活文档**(冲突时以代码现状为准) | `docs/编码规范.md` | 工程结构权威:模块层级 L1-L8、依赖门禁、AI 协作协议 §12 |
| | `docs/产品设计.md` | 三面一体的产品形态与决策记录 |
| | `docs/活动开发规范.md` | **开发活动照这份**(2026-08-02 第三版,按四轴重组:解耦机制/Harness 契约/Loop/活动怎么写):基座读数与机检纪律、门与闸、五类卡、剧本 steps、建模十纪律、三常备案例与验收口径(released+被拒0)、**排障速查表**;§8 = 待实现 |
| | `docs/HTML报告生成规范.md` | **报告模版照这份**(2026-08-02 从开发规范拆出):一份 HTML 三个身份(件/表单/归档件)、**报告与卡的关系与同源纪律**、绑定语言全表、编辑态(闸/孪生件/增删行/红带)、PRD 平移法、陷阱表 |
| | `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 编号指向归档卷章节 |
## 铁规矩(违者返工)
1. **五道门禁以退出码验**,不许以 echo 验:`pnpm -s typecheck && pnpm -s lint &&
pnpm -s depcruise && pnpm -s api:check && pnpm -s test`(或 `pnpm gates`)。
2. **契约变更四步**(§12.4):depcruise 反查下游 → 同步 CONTRACT.md →
`pnpm api:check --update && git add api-report` → 破坏性走三步弃用。
3. **§12.5 禁止清单**:no `any` / `as unknown as` / `@ts-ignore`;domain 零 IO;
不删测试;不动门禁配置;不绕写三分/两缝。
4. **mock 只许出现在外界**(邮件通道、外部系统的录制回放替身);系统内部机制不得 mock。
5. **密钥只从环境读**:`JCAI_DEEPSEEK_API_KEY`(模型)、`JCAI_SEED_PASSWORD`(种子口令)、
`JCAI_SECRET_KEY`(凭证密封);不入源码、不入包、不入留痕;E2E 永不回退开发库。
6. **试跑一律用 AI 账号**(密码 `jcai-dev-2026`),绝不派到用户工作台;测完
`pnpm --filter @app/api reset-runs` 清运行数据(清跑出来的,留配置好的)。
7. **安装恒新增**:活动/工具改了内容必须升版本号,同版重装是 no-op(静默丢失,踩过)。
8. **界面不撒谎**:状态如实(未绑就写未绑)、错误带厂商原话、不可用不摆假数字。
## 常用命令
```bash
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)
```