A2-A7 全部补齐到验收线;顺手把几处「门拦住却不给路」的坑填了
活动:A2 选型 / A3 寻源 / A4 定价 / A6 议价 / A7 归档五件各补成真活动包 —— 契约宽进(input.required 空,归一在活动内)、台账必填声明(含行级 requiredWhen)、 入场哨兵与 L1/L2 判据一律读基座数、两份件(在办可编辑 + 办结静态快照)、 三案例常备、包内自测。e2e 各三案例 released、行动被拒 0、发口正确、提交闸每单真拦。 基座(共享面,改一处影响所有活动,故每处都带回归): · 重发判断走在站上场之前 —— 人答完那步常已收掉,readyToWork 先抛「不能再往它上面挂活」, 于是「重发已答过的卡 = 无事发生」这条唯一活路在最需要时够不着,A1 基线当场熔断; · 决策卡补幂等兜底(与执行工单同一把尺):头两次无事发生,第三次起才算被拒; · 输出没成形先就地重问一次,原话进工作日志、不再摆上卡面; · 工具调用读数 tool_<名>_calls —— 「机检只读基座数」这条纪律第一次覆盖到工具; · 执行卡 steps/standard 补进出参 schema(从前能到卡面全靠厂商 JSON 模式宽松); · 件的就地更新改逐节点 morph,保存先把新值镜像进只读那份 —— 不闪、不等回声。 A1(基线,全程守住):措辞三档对齐(必填/建议/选填)、禁止拿历史价当客户目标价、 卡骨架从步骤剧本搬进说明书(压成一拍连做时剧本没摊开,会发出没有指导书的裸卡)。 契约两处**新增可选字段**(非破坏):FieldDeclaration.requiredWhen、工单 finalHtml; api-report 同批更新。docs/adr 与 docs/archive 的 13 份文件在工作树里不见了, 本次予以恢复而非提交删除。 门禁:typecheck / lint / depcruise / test(1366)全绿。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+61
-19
@@ -152,8 +152,8 @@ activities/<id>/src/ ──(pnpm activities:build)──> dist/{manifest.json,in
|
||||
|
||||
| 门 | 在哪 | 规则 |
|
||||
|---|---|---|
|
||||
| **起单宽进** | `process.start` | 不按 Schema 拒缺项;缺 required 顶层键 → 发补全卡(不占预算)。「没法填」给理由即带缺口开跑 |
|
||||
| **执行卡提交闸** | 卡面 `gate` + 服务端 | 卡上绑了台账表的执行单,必填缺着按不下提交(`{ready,why,blanks}`,与放行门 L1 **同一个数同一套算法**);**服务端在收下回传之前也把一遍**(前端灰按钮只是给人看的)。算不出来(卡没绑表)不给闸 —— 没有依据的时候不拦人 |
|
||||
| **起单宽进** | `process.start` | 不按 Schema 拒缺项。三活动 `input.required` 一律空(宽进严出),起单补全卡那条老路实际不再触发(彻底移除记 debt) |
|
||||
| **执行卡提交闸** | 卡面 `gate` + 服务端 | 必填缺着按不下提交(`{ready,why,blanks}`,与放行门 L1 **同一个数同一套算法**);**服务端在收下回传之前也把一遍**(前端灰按钮只是给人看的)。看哪几张表:卡上绑了 blocks 看绑的;**没绑(执行卡零输入后是常态)回落到必交付物声明的 `ledgers`/`ledger`**(`gateAddressesOf`,有测钉着)。两边都空才不给闸 —— 没有依据的时候不拦人 |
|
||||
| **提交门**(`submit` 预检) | engines | 机检(L1/L2)**必须为真**;裁量(L3/L4)**裁过即可**(裁成「不满足」照样能提交,裁断连理由随卡交给人 —— 一条只接受「是」的判据是一句教模型说谎的提示);**L4 带谓词时谓词说了算**(谓词真 = 已达标,模型那句相反的理由一并丢掉;谓词假才轮到裁量);必交付物按 ledger 地址数本单草稿行 |
|
||||
| **放行门入场哨兵** | CMMN sentry | **必须有 ifPart,且读基座数、认「办完了没有」** —— 只有 onPart 的哨兵等于「有人写过一笔就开门」,模型写个 `false` 就推开了(实测:跳过三步直达放行门) |
|
||||
| **熔断** | Harness | 连续 5 拍行动被拒 → 停问模型,发熔断卡把拒绝理由摆给人(比对削掉串位前缀、另开 60 条窗) |
|
||||
@@ -165,13 +165,13 @@ activities/<id>/src/ ──(pnpm activities:build)──> dist/{manifest.json,in
|
||||
- 已收掉的项按状态分开说(「挂到当下这一步」+ 列出可为的项),别说「先 start」——
|
||||
start 一个 Completed 项同样被拒,两堵墙对着撞。
|
||||
|
||||
### 3.4 人类工具:五类卡
|
||||
### 3.4 人类工具:四类卡(补全卡已退役)
|
||||
|
||||
| 类 | 行动 | 形态与硬规矩 |
|
||||
|---|---|---|
|
||||
| **执行** | `human` + `workOrder:'execution'` | 卡 = 查看工单钮(四字粗体,与验收卡同形)+ ask + **作业指导书**(`steps`+`standard`,与判据同一套版面、不画对勾)+ 依据 + 表单 + 提交闸。指导书写「哪几格必须有、哪几格值得追」,不写「怎么核表」。**`steps`/`standard` 是纯文本** —— 别写 `**` 这类记号,它们不会变粗体,只会原样摆在人眼前 |
|
||||
| **执行** | `human` + `workOrder:'execution'` | 卡 = 查看工单钮(四字粗体,与验收卡同形)+ ask + **作业指导书**(`steps`+`standard`,与判据同一套版面、不画对勾)+ 依据 + 提交闸。**零输入**(2026-08-02 用户定):卡上没有任何填写 —— 不摆 `fields`、不绑 `blocks`,填报全在工作区的件上(人按「保存」基座直写草稿层,**别再 write 一遍**);空表单是常态,基座照发(从前的「表单不得为空」拒发已删)。指导书写「哪几格必须有、哪几格值得追」,不写「怎么核表」。**`steps`/`standard` 是纯文本** —— 别写 `**` 这类记号,它们不会变粗体,只会原样摆在人眼前 |
|
||||
| **验收** | `submit` | 判据表(读时现算 —— 人在件上补一格判据跟着变;**L5 不上卡**:那张卡本身就是那道关,列进去等于摆一条恒红的项)+ 落地动作 + 可修订值 + 出口(算得出摆 `routedPort` 告知,算不出退 `portChoice` 让人选)。**办结之后换成落地结果**(landing):按交付物点名落了几行、转出哪一口、带过去哪些字段;一个口都没发直说「到此为止」 |
|
||||
| **补全** | `ask` | 对话卡就地填;`fields` 空即拒;能预填的带 `value` 预填 |
|
||||
| ~~补全~~ | ~~`ask`~~ | **已全局退役**(2026-08-02 用户定:「执行卡完全就是包含补全语义的人类工具」)—— 缺信息发**零输入执行工单**:指导书写清缺什么,人在工作区的件上补(保存即落草稿层)。旧输出里的 `ask` 由基座原地转成执行工单(归一不拒);引擎侧直发 `ask` 拒并指路 |
|
||||
| **决策** | `decide` | 选择题(≥2 个选项,少了拒发);人点哪个进轨迹 |
|
||||
| **录入** | `entry` | **人按下确认那一刻基座直接写库,AI 不经手** —— 建档这类主数据用它。可多段(`also`):建客户 = 公司档 + 联系人档,一张卡两段、确认一次落两行(值按 `段号.列名` 隔开)。卡面摆表的**人读名**(不摆 `customer.profile`);`auto` 列不进表单、另摆一句说明 |
|
||||
|
||||
@@ -179,8 +179,9 @@ activities/<id>/src/ ──(pnpm activities:build)──> dist/{manifest.json,in
|
||||
- **一单同一张卡只发一次**。人交回来之后不论还缺什么都不许再发 ——
|
||||
必填有提交闸兜着(卡回来时必填一定齐);**人留空交回来 = 对方给不了,那也是一个答案**:
|
||||
如实记账、缺口照实留着、把这一步收掉往下走。
|
||||
- 发卡即挂起,回传即续跑;在途验收先于一切;人答的值出现在下一拍轨迹里,
|
||||
**看到了要自己 write 落台账**(绑台账的表除外 —— 基座直写)。
|
||||
- 发卡即挂起,回传即续跑;在途验收先于一切。**值怎么落**:件上保存的、录入卡确认的,
|
||||
基座直写;执行卡零输入(空答复 = 人照原样确认,痕上写明);决策卡选项进轨迹 ——
|
||||
该记账的记账,**别当没答过再发一张**。
|
||||
- 调人预算(`humanCallBudget`)环外扣账。
|
||||
|
||||
### 3.5 视图渲染(概要,详见《HTML报告生成规范》)
|
||||
@@ -229,17 +230,17 @@ activities/<id>/src/ ──(pnpm activities:build)──> dist/{manifest.json,in
|
||||
|
||||
| 行动 | 形状 | 语义 |
|
||||
|---|---|---|
|
||||
| `start` | `{itemId}` | 启动标了人工激活的项;**已 Active / 已收掉再按 = 无事发生** |
|
||||
| `start` | `{itemId}` | 显式启动一项(**可省**:2026-08-02 起动它就算启动);已 Active / 已收掉再按 = 无事发生 |
|
||||
| `plan` | `{itemId}` | 裁量项入场 |
|
||||
| `disable` | `{itemId, reason}` | 此单不走这条 |
|
||||
| `judge` | `{criterion, satisfied, rationale}` | 裁语义性前提 / L3-L4 判据;criterion 照判据名**整句原样抄** |
|
||||
| `write` | `{itemId, address, rows:[{key,patch}]}` | 写草稿。授权面是台账声明;`itemId` 只是记账,挂不上照写不拦;patch 只带有值的列;空转写(一行没变)即拒 |
|
||||
| `drop` | `{itemId, address, keys:[{主键}], reason}` | 撤本单草稿层的行;主键与写进去时一字不差 |
|
||||
| `tool` | `{itemId, tool, input}` | 读类即调;写类转意向;未命中转人挂起 |
|
||||
| `ask` | `{itemId, ask, fields:[{key,label,hint?,value?}], basis}` | 补全卡,挂起 |
|
||||
| `ask` | ~~已退役~~ | 基座原地转成零输入执行工单(字段名并进指导书);别再用 |
|
||||
| `entry` | `{itemId, ask, ledger, entryKey, fields, also?}` | 数据录入卡,挂起;确认那一下基座直写 |
|
||||
| `decide` | `{itemId, ask, options(≥2), basis}` | 决策卡,挂起 |
|
||||
| `human` | `{itemId, workOrder, card{title,ask,steps?,standard?,basis,fields?,blocks?}}` | 执行/验收工单,挂起。`blocks` 里绑 `ledger`+`fields` 的表**由基座铺行、由基座写回**,别自己抄行(回复有长度上限,铺长了截断整拍作废) |
|
||||
| `human` | `{itemId, workOrder, card{title,ask,steps?,standard?,basis}}` | 执行/验收工单,挂起。**执行卡零输入**(2026-08-02 用户定):不摆 `fields` 不绑 `blocks`,填写全在工作区的件上(editGate + 孪生件),人按「保存」基座直写草稿层;必填由提交闸看住(闸回落到必交付物的台账声明) |
|
||||
| `listen` | `{itemId, eventType, keyFilter, deadline}` | 立监听,挂起;时限必配 |
|
||||
| `finish` | `{itemId, rationale}` | 宣告一项完成;非人工激活的项就地过 Active 再收 |
|
||||
| `submit` | `{rationale, fields?}` | 提交放行 → 预检 → 发验收卡挂起 |
|
||||
@@ -248,16 +249,20 @@ activities/<id>/src/ ──(pnpm activities:build)──> dist/{manifest.json,in
|
||||
`tool` 之后截断(出参没看见,后面是闭着眼计划的);挂起型收拍;超封顶丢弃留痕。
|
||||
拍级附带 `say{text, tag, view?}`,不占行动位。
|
||||
|
||||
### 4.3 人工激活与 start(话与门同宽)
|
||||
### 4.3 人工激活:动它就算启动(start 墙已拆)
|
||||
|
||||
标了 `manualActivationRule` 的项,**动它之前必须先 `start`** —— 调工具、发卡
|
||||
(ask/human/decide/entry)、宣告完成(finish)都算,一拍里 start 排在那个动作前面即可。
|
||||
只有 `write` 例外(itemId 只是记账)。
|
||||
标了 `manualActivationRule` 的项,**模型显式动它(调工具/发卡/finish)就算启动**,
|
||||
不必单发 `start`(2026-08-02 拆墙)。它的分量在引擎那一侧,原样保留:
|
||||
**引擎不因哨兵满足替它启动**(哨兵只推到 Available/Enabled),
|
||||
**也不给 doneWhen 替人收**(自动收步跳过人工激活项)—— 收它只能是模型的 finish。
|
||||
|
||||
实测账(2026-08-02):这条规矩从前在提示词里写成「先 start **再调工具**」——
|
||||
只说了调工具,而门拦的是一整片;模型那一拍发的是 `human`,照字面读规矩管不着它,
|
||||
于是漏了 start 白烧一拍。**话说的范围必须盖住门拦的范围,话窄一格,模型就正好漏在那一格上。**
|
||||
写全之后三案例复跑全部被拒 0。
|
||||
实测账(两轮,同一堵墙):先是「话与门同宽」—— 提示词写「先 start 再调工具」只说了
|
||||
调工具,而门拦 tool/ask/human/decide/entry/finish 一整片,模型发 `human` 照字面漏了
|
||||
start 白烧一拍;措辞写全之后**仍然熔断**(A1 一单连拒五拍,五次全是「要先 start」,
|
||||
提示词与拒回都写着,它就是学不稳)。这才看清:那道墙保护不了任何东西 ——
|
||||
start 是**模型自己的**动作,同一串连发即过,拦下只是逼它多演一步礼仪,
|
||||
而学不稳的礼仪就是死法。**状态机的礼仪不该长成墙**(与 finish 就地过 Active、
|
||||
start 已收项无事发生同族)。剧本里也别再教 start —— 教它白烧 token。
|
||||
|
||||
### 4.4 自动收步(doneWhen)
|
||||
|
||||
@@ -431,6 +436,33 @@ A1 是 `customerEmail / subject / body / attachments`)。
|
||||
|
||||
---
|
||||
|
||||
## 6.5 设计律(2026-08-02/03 一整轮实测沉淀 —— 每条都付过学费)
|
||||
|
||||
排障表治的是「这一处坏了」;这几条治的是「为什么总在坏」。改 Harness、写活动、
|
||||
做报告之前先过一遍:
|
||||
|
||||
1. **墙要配路**:任何一道门拦住一件事时,必须存在一个模型(或人)做得出的动作
|
||||
把事办对 —— 没有出路的门只是死胡同(drop 之于「多写一行」、撤行之于「替代未果」)。
|
||||
2. **学不稳的礼仪就是死法**:纯礼仪的墙一律拆(start 墙、空表单拒发)。
|
||||
模型十次里学会九次不算学会 —— 第十次熔断的是用户的单。幂等优于拒回:
|
||||
按钮按两下不该报错(start / finish / 重发已答卡,同族三例)。
|
||||
3. **拒回喂对抗,观察喂事实**:拒回的话是模型下一拍的行动指南,指错方向比不给更糟;
|
||||
头几次犯浑先转成 observation 指路(卡已答过→接着办交回后的事),连犯才算撞墙进熔断。
|
||||
4. **「机检只读基座数」管的是一整片**:验收判据、收步判据、放行哨兵、**入场哨兵**、
|
||||
提交闸、红带 —— 任何一处读模型自报的数,那道门就等一个可能永远不来的记账
|
||||
(第四次违反藏在 s_parsed 哨兵里:行落了门却不开,模型被「依赖断点」推去发卡绕路)。
|
||||
5. **提示词分层**:全局提示词只说通用真理,活动级细节归说明书 —— 一句全局禁令
|
||||
(「别再 write 一遍」)能把所有活动的既有约定顶翻,且症状出在别的活动身上,
|
||||
查起来像闹鬼。改全局面 = 改所有活动,回归也要按「所有活动 × 全部常备案例」跑。
|
||||
6. **措辞治不了的要结构治**:模型「不查工具直接编结论」这类顽疾,说明书写死到头
|
||||
仍概率性犯 —— 根治靠机制(规则进判定表由引擎求值 / 工具出参直接带结论只让照抄),
|
||||
措辞只能降频。一条纪律连续两轮被同一形状踩穿,就该停止改话、开始改结构。
|
||||
7. **改共享面必须全量回归**:提示词、turn-runner、解析器、容器 —— 动一处,
|
||||
三活动的全部常备案例都要重跑(A1 新客户路的熔断就是「只回归了老客户路」漏出来的)。
|
||||
「稳定的活动出错」比新功能不 work 伤得多。
|
||||
8. **用户重复提的要求,说明上一轮没打中病根**:往下再挖一层,别在同一层再修一遍
|
||||
(「工作成果 1:1」挖了三层才到「办结那一刻存快照」这个真解)。
|
||||
|
||||
## 7. 排障速查表(症状 → 根因 → 处置;全部实测账)
|
||||
|
||||
| 症状 | 根因 | 处置 |
|
||||
@@ -445,7 +477,15 @@ A1 是 `customerEmail / subject / body / attachments`)。
|
||||
| 同一条理由连拒到熔断而数与行都对 | 拒回把「活没干完」说成「数/行不对」 | 已修:`_rows`=0 直说那一步没办 |
|
||||
| 行数对不上,模型只会改数字 | 拒回没摆主键名单 | 已修:`_keys` 名单;照名单 drop |
|
||||
| 「要先 start」而 start 也被拒 | 拒回没按状态分开说 | 已修;start 已收的项无事发生 |
|
||||
| 模型漏 start 白烧一拍 | 提示词的话比门窄(只说了调工具) | 已修:话与门同宽(§4.3) |
|
||||
| 「要先 start」连拒五拍熔断(措辞已写全) | start 墙本身:学不稳的礼仪就是死法 | 已拆墙(2026-08-02):动它就算启动(§4.3) |
|
||||
| 零输入执行卡被「表单不得为空」拒发到熔断 | 基座旧机检把表单当交付通道 | 已删该拒发:空表单是常态(卡族表「执行」行) |
|
||||
| 整拍六个动作全对却退化成「需要你判断下一步」 | 模型多吐一个闭括号,单数花括号的配平切出半截 | 已修:括号栈 + 丢不配对闭括号(`parseJsonLoose`,有测) |
|
||||
| 「需要你判断下一步」卡面摆着一坨 JSON 原话 | 整拍输出没成形,旧兜底一次就发卡还把原话上卡 | 已修(2026-08-03):就地重问一次、原话归工作日志、卡面只说人话(agent-runner,有测) |
|
||||
| 模型逐字复读一句被明令禁止的话 | **反例把原话引进了提示词**(「别说『…』」)—— 关思考的模型不读否定框,只认框里现成的句子 | 反例只描述、不引原话;要引原话就引**正例**(想听哪句就示范哪句)。A1「照历史价估」逮过(2026-08-03) |
|
||||
| 执行卡上作业指导书整个是空的(basis 里是「当下可为(空)/目标缺口」这类家具) | **卡骨架写在那一步的剧本里**,而模型在「干活+收步+派卡」压成的一拍里发了它 —— 那一拍该步剧本没摊开,模型手上没有骨架,凭记忆拼出裸卡,基座兜底 basis 又摆上局面家具 | **凡要模型照抄的卡骨架,放说明书不放步骤剧本**(说明书每拍都在;A6 决策卡先立此法,A1 审定卡 2026-08-03 同坑)。另:`steps`/`standard` 已补进出参 schema —— 从前能到卡面纯靠厂商 JSON 模式宽松 |
|
||||
| 人答完后同一条拒回重复五遍熔断(「这一步已办完,不能再往它上面挂活」) | **重发判断走在站上场之后** —— 人答完那一步常已收掉,`readyToWork` 先抛,于是「重发已答过的卡 = 无事发生」这条活路在最需要时够不着 | 已修(2026-08-03):**先判重发再站上场**;重发一张已答过的卡本就不需要那一项在场(墙要配路,有测) |
|
||||
| 同一个岔路口连发四张决策卡,调人预算烧光落 `exhausted` | 决策卡没有幂等兜底(执行工单一直有) | 已修:`resendVerdict` 两族共用 —— 头两次无事发生、第三次起算被拒 |
|
||||
| 收上一步时连拒「写了等于没写」 | 值已在台账(件上保存/上一拍写过),模型照抄重写;或提前干了下一步的活(如在 S2 查行情) | 拒回已带指南「该办下一件事」;剧本明写这一拍只有哪几件事 |
|
||||
| 人答了卡,模型又发一张一样的 | 剧本残留「还缺就再发一张卡」死路 | §5.5-5:一单一卡;必填有闸兜着 |
|
||||
| 人在卡上填了值,台账还是空的 | doneWhen 写成「问过就算完」 | 等「答案落了表」的计数(`answered_total`) |
|
||||
| 该经过人的一步整个没发生 | 「经过人」写成了收步条件里的半句 | §5.3-4:独立一项+人工激活 |
|
||||
@@ -466,6 +506,8 @@ A1 是 `customerEmail / subject / body / attachments`)。
|
||||
| 下游网关取不到值 | 出口标量没有台账列承载 | §5.2-② |
|
||||
| 改了包重装没生效 | 同版重装 no-op | 升 packageVersion |
|
||||
| 收口前一两拍预算耗尽 | budget 给太紧 | §5.2-⑦ 留一倍余量 |
|
||||
| 代答脚本交执行卡被拒「必填字段未回填:结果」 | 卡没声明 `fields` 时基座兜底加必填「结果」回执字段 | 交卷 `values.result` 带一句 |
|
||||
| 验收 pass 后落地判「选择组未选出口」 | routedPort 只在前端回传里顶上(已修:服务端发事件前算有效口) | 升级基座;临时:回传自带 `selectedPorts` |
|
||||
|
||||
## 8. 待实现与已知不一致
|
||||
|
||||
|
||||
Reference in New Issue
Block a user