From dba60717724fb6751748d4b8c423426b028e10f5 Mon Sep 17 00:00:00 2001 From: xcs Date: Sat, 29 Aug 2026 07:24:13 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E7=A1=AE=E5=AE=9A=E6=80=A7=E6=AD=A5?= =?UTF-8?q?=E9=AA=A4=E8=90=BD=E5=9C=B0=20=E2=80=94=E2=80=94=20=E8=A7=84?= =?UTF-8?q?=E8=8C=83=20=C2=A74.6=E3=80=81ADR-014=20=E8=BD=AC=E5=B7=B2?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E3=80=81=E4=B8=A4=E7=AC=94=E6=AC=A0=E8=B4=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ADR-014 §8 的两条禁令(不 submit、不发决策卡)撤掉并写明理由: 那是假设还有 agent 在场时的保守话,全程无 agent 的活动没有别人来干这两件事。 Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01LKMZDwMbyKzjw6Hembwvet --- CLAUDE.md | 11 ++++++- docs/adr/ADR-014-deterministic-steps.md | 26 +++++++++++++-- docs/debt.md | 44 ++++++++++++++++++++----- docs/活动开发规范.md | 44 +++++++++++++++++++++++++ 4 files changed, 112 insertions(+), 13 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index b5843ab..c68bbb3 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1646,6 +1646,15 @@ service 3 + store 1 + 包内 4;真库渲染 `v-ready`、INS-21 / `W05-20260827215148`。欠账见 debt(挑单 / 行级来源 / `vtok` 三份 / `data` 装包静态审)。 +- **确定性步骤已落地**(2026-08-29,ADR-014):`PlanStep.auto` 声明式配方,五个动词 + (`project` / `analyze` / `card` / `submit` / `say`)、四种地址、嵌套两层封顶;引擎在拍首跑, + **发了卡就收拍(零 token)**,有 `guide` 的照常问模型。`analyze` 是**一次结构化 AI 调用** —— + 系统组装入参、声明出参 schema、系统落表,**不给工具不给记忆不多轮**。 + 三条纪律进了规范 §4.6:**行由确定的那一侧决定不由 AI 决定** / 判据不许编数不出来的数 / + 每一笔之前刷读数。静态审在装包时把地址、列名、模型名、视图、submit 的验收清单逐条核死。 + 配套四件:`data-options`(下拉选项从台账现读)· 件上保存后 `wake`(「保存即铺格」)· + 审核卡放宽到单选项 · 卡答复即收步。**E04 / I01 / W05 一个字没改** —— 它们的剧本里没有 `auto`。 + ## 文档权威地图 | 层 | 文件 | 说明 | @@ -1660,7 +1669,7 @@ | | `docs/API文档-鉴权与人员.md` | 鉴权 / 人员 / 角色→端接口的人话版 + 全部路由归属总表;契约不一致时以 `packages/contracts` 为准 | | | `docs/ACT-WORK-05-端到端测试记录.md` | **ACT-WORK-05 差异评估的走查账**:六轮逐轮结论 + A–K 十一条发现总表(现象 / 病根 / 治法 / 层) | | | `docs/数据域字段说明-W05.md` | ACT-WORK-05 的十张台账 / 110 列 / 人填列 27 —— 建活动时照它对字段 | -| | `docs/adr/ADR-014-deterministic-steps.md` | **确定性步骤的设计(提案,未实现)**:W05 九步的确定/判断盘点、`PlanStep.auto` 声明式配方(三动词)、引擎拍内次序、回溯验算、迁移次序、五条待定 | +| | `docs/adr/ADR-014-deterministic-steps.md` | **确定性步骤(已实现,2026-08-29)**:W05 九步的确定/判断盘点、`PlanStep.auto` 声明式配方(五动词:`project`/`analyze`/`card`/`submit`/`say`)、引擎拍内次序、回溯验算、迁移次序、§11 待定前两条已定(决策卡给了 / 工具串接换成 `analyze`) | | | `docs/debt.md` | 欠账台账(只增,销账划线) | | | `docs/adr/` · 各模块 `CONTRACT.md` | 架构决策与模块级不变量 | | 业务样例(活) | `docs/MVP示例工作流.html` | 七节点 SOP + 判定表 + 台账域 —— 开发活动的业务素材 | diff --git a/docs/adr/ADR-014-deterministic-steps.md b/docs/adr/ADR-014-deterministic-steps.md index 66ab53e..1784776 100644 --- a/docs/adr/ADR-014-deterministic-steps.md +++ b/docs/adr/ADR-014-deterministic-steps.md @@ -1,6 +1,6 @@ # ADR-014 确定性步骤:确定的活由引擎按声明做,不问模型 -状态:**提案**(2026-08-28,待用户定) +状态:**已实现**(2026-08-29;设计见 `docs/superpowers/specs/2026-08-29-act-work-05-rewrite-design.md` §5) 背景出处:ACT-WORK-05 差异评估九步流程盘点(§2)、`docs/ACT-WORK-05-端到端测试记录.md` 发现表 A–AE。 关联:ADR-004(活动包 ABI:**系统不执行代码即知包为何物**)、`docs/活动开发规范.md` §4.4(自动收步)、 `PlanStep.humanWrites`(2026-08-28 立的墙)、ADR-005(工具契约与落地预检)。 @@ -135,6 +135,17 @@ - 治理台的活动详情能摆出「这一步系统会做什么」(配方是数据,渲染得出来)—— 这是相对提示词的一大好处; - **自主率的分法要认第三档**:现在两档(AI / 人),配方做的事既不是 AI 判的也不是人办的,是系统做的。 +**改口**(2026-08-29,实现时踩出来的):`docs/superpowers/specs/2026-08-29-act-work-05-rewrite-design.md` +§5.9 写的是「`analyze` 那一笔归 AI 蓝」—— 那句要改口,**它也归系统灰**。理由:那一行记的是 +「系统把 N 条参数交给模型、拿回 M 条结论」,发起与落表都是系统做的,模型只提供内容; +内容本身的归属在它落下的台账行上看得见,不必让日志行冒充成「AI 判的」。 +连带修了一处会让整条留痕**静默消失**的坑:配方留痕最初用的是 `kind: 'result'` —— 那不在工作日志 +的骨架集合里(`result` 是进模型叙事轨迹那一类,不是给人看的那一类);`project` / `analyze` / +「自动收步」那几笔当时又都标了 `internal: true`,会被 `machinery()` 再滤掉一道 —— +**三段各自「正确」,合起来一笔都进不了工作日志**,人打开日志想知道「系统刚做了什么」, +看到的是空的。现在统一改成 `kind: 'observation'` 且不标 `internal`(「已发过卡,不再发第二张」 +这一笔仍保留 `internal` —— 它每拍都打一遍,是排障痕,不是给人看的交代)。 + --- ## 4. 声明形状 @@ -290,13 +301,22 @@ tick 开始 ## 8. 不做什么 -- **不调工具**:工具有副作用面与预算面,先不给(S3 的 `compare → recommend` 串接留作待定) -- **不 `finish`、不 `submit`、不发决策卡**:收步归 `doneWhen`,终局归 submit,岔路口本就是判断 +- **不调工具**:工具有副作用面与预算面,先不给(S3 的 `compare → recommend` 串接留作待定; + 实现时换了个更窄的口子解掉同一个需求,见下方「两处改口」与 §11 待定②的销账) +- ~~**不 `finish`、不 `submit`、不发决策卡**:收步归 `doneWhen`,终局归 submit,岔路口本就是判断~~ + (**`submit` 与发决策卡两条已撤**,见下方「两处改口」;`finish` 这条不变 —— 配方从不 + 显式收步,收步仍旧只有「引擎按 `doneWhen` 自动收」与「半 auto 步问模型、模型 finish」两条路) - **不写正式表**:仍走草稿层 - **不做三层以上的嵌套**:两层(关系 × 参数)是 W05 的上限;超出就别 auto - **不在治理台上编辑配方**:那就成了低代码平台;配方随包走,改配方 = 升版本重装 - **不承诺消灭 agent**:§2 的四类判断照旧归它 +> **两处改口**(2026-08-29,ACT-WORK-05 重写时用户定):`submit` 与**发决策卡**这两条禁令撤掉。 +> 它们原本是**假设还有 agent 在场**时的保守话;而全程无 agent 的活动**没有别人来干这两件事**, +> 不开口最后两步就没人做。护栏没松:`submit` 只许出现在声明了人工验收清单的那一步, +> 提交门(判据全绿)照旧把关 —— **系统提交不比模型提交宽松**;决策卡只在 `variant:'review'` 时 +> 放宽到单选项(它不是岔路口,是一道签字关)。 + --- ## 9. 代价与风险 diff --git a/docs/debt.md b/docs/debt.md index 6209757..0434226 100644 --- a/docs/debt.md +++ b/docs/debt.md @@ -1309,14 +1309,40 @@ pnpm 硬链到全局 store,真实占盘远小于这个数,但 `du` 看着吓人 - **`docs/数据域字段说明-W05.md` §二 / §十二.4 的参数集口径过时**:仍写 `normalized_parameter_set` 是 text 列「不建子表」, 而清单早已拆成子表 `parts.parameter`(库里那一列全 null)。一览表也少 `parts.parameter` 一行。 -- **平台缺「确定性步骤」:确定的流程只能交给模型**(2026-08-28 用户点出:「这个不是一个确定的流程吗? - 根本不需要交给 ai,你直接查库不就知道有没有了吗」)。W05 的「逐个料号查库 → 不在库就铺骨架、发数据工单」 - 是纯规则,却写成了模型的 guide —— 因为一个计划项的做法只有一个落点(模型的 guide):纯工具只读、 - 判定表不写台账也不发卡、`doneWhen` 只收步、哨兵只开门,**没有一个机制能整段承接**「读台账 + 写草稿 + 发人卡」。 - 引擎这三样能力全有(`taskView` / `draftWrite` / `issueExecution`),缺的只是**声明面**。 +- ~~**平台缺「确定性步骤」:确定的流程只能交给模型**~~(2026-08-29 已实现,销账)。 + 2026-08-28 用户点出:「这个不是一个确定的流程吗?根本不需要交给 ai,你直接查库不就知道有没有了吗」。 + W05 的「逐个料号查库 → 不在库就铺骨架、发数据工单」是纯规则,却写成了模型的 guide —— 因为一个计划项的做法 + 只有一个落点(模型的 guide):纯工具只读、判定表不写台账也不发卡、`doneWhen` 只收步、哨兵只开门, + **没有一个机制能整段承接**「读台账 + 写草稿 + 发人卡」。引擎这三样能力全有 + (`taskView` / `draftWrite` / `issueExecution`),缺的只是**声明面**。 代价已经付过两次:08-27 原 PN 不在库却判「在库」(用 `found_pn_ref` 的 refersTo 兜了一半 —— 「说不在库」那一侧至今没有校验);08-28 模型把原 PN 的规格书抄到候选头上(已用 `humanWrites` 立墙)。 - 真治法:剧本加 `auto` 步(声明「这一步引擎按规则做,不问模型」)。**代价**:活动模型往「配置化流程」挪一格, - 与「活动是 Agent 机制」的立场有张力 —— 但这一段本来就没有判断余地。真需要模型的只剩「有 datasheet 附件时从原文抽值预填」。 - **2026-08-28 已出设计:`docs/adr/ADR-014-deterministic-steps.md`**(声明式配方、三动词、迁移次序、回溯验算八条、 - 五条待定)—— 待用户定后实现。 + **`docs/adr/ADR-014-deterministic-steps.md` 已实现**(状态 提案 → 已实现):`PlanStep.auto` 声明式配方, + 五个动词(`project`/`analyze`/`card`/`submit`/`say`,比 2026-08-28 出设计时的「三动词」多了 `analyze` 与 `submit`)。 + §11 待定的前两条随实现落了地:①「决策卡要不要给配方」—— 给了,`card.as: 'decide'`; + ②「工具串接要不要做第四个动词」—— 没照原样给(那会把工具的副作用面与预算面一起引进配方), + 换成了 `analyze`:一次结构化 AI 调用(系统组装入参、声明出参 schema、系统落表,不给工具不给记忆不多轮), + 比工具串接窄但够用。第③④⑤条(`humanWrites` 细到列 / S2 与比对工具的 join 重复 / + `T_release` 第三条裁量该删)是 W05 具体步骤的事,留给下一份计划。规范 §4.6 记了怎么写。 + **机制先在纯函数与假端口上钉死**——这一轮 `git diff --stat b995148...HEAD -- activities/` 为空,九个现有活动包一个字没改 + (它们的剧本里没有 `auto`,新代码在结构上就进不去);机制的第一个真实用户是下一份计划(W05 重写)。 + +- **配方没有 `drop` 动词**(2026-08-29):撤行只能靠 `project` 的 `prune`(「这一笔投影出来的就是全部」)。 + 要撤一行而不重投整张表的场合,现在写不出来。等真出现第二个用例再加。 +- **配方的 `analyze` 不计入 `stalledTurns`,也不进单拍工具缝**(2026-08-29):它烧 token、计预算, + 但不算「被拒」——熔断看不见它。一份写坏的 `instruction` 会每拍烧一次而不触发熔断; + 目前靠「auto 步发了卡就收拍」封住(analyze 那一步不发卡,`doneWhen` 不成立就交人), + 真出现空转再补一道计数。 +- **治理台的活动详情还摆不出「这一步系统会做什么」**(2026-08-29):配方是数据,渲染得出来 —— + 这是相对提示词白赚的一件,但要动前端,不在这一轮(后端已经把 `auto` 随清单存进库了)。 +- **`.stable/**` 进了 `eslint.config.js` 的 `ignores`**(2026-08-29):它是部署快照目录 + (`stable.sh` 放的旧 commit 源码拷贝,已在 `.gitignore` 里),与既有的 `dist` / `.build` / + `api-report` / `.api-tmp` 同类 ——「产物不是源码」,不该被门禁扫。加它是因为本轮门禁曾被 + `.stable/` 下的旧代码拖红(那份代码不受这次改动约束,红也修不掉)。这条动了门禁配置, + 按铁规矩③要在这里留痕;要推翻只需删掉这一条 ignore。 +- **配方留痕的可见性,靠的是「kind 选对 + 不标 internal」,没有机制保证**(2026-08-29, + R10 的教训 —— `result` 不进工作日志骨架、`internal:true` 会被 `machinery()` 再滤一道, + 三段各自「正确」、合起来一笔都看不见,踩了才发现):将来新增一类配方留痕时,若照手感 + 写成 `kind: 'result'` 或顺手加 `internal: true`,它会**静默地**从工作日志上消失 —— + 没有测试会红、装包也不会拒,人只会发现「这一步好像没留痕」。目前靠代码注释提醒 + (`turn-runner.ts` R10 附近),没有静态检查兜底。 diff --git a/docs/活动开发规范.md b/docs/活动开发规范.md index 1751c9a..754f486 100644 --- a/docs/活动开发规范.md +++ b/docs/活动开发规范.md @@ -316,6 +316,50 @@ W05 的两张数据工单(人填的值已入库、必填不缺、逐颗对账) --- +## 4.6 确定性步骤:这一步系统自己做(2026-08-29) + +一步要么确定,要么不是。**不做「一半 auto」** —— 判断点先从那一步里切出去。 + +`PlanStep.auto` 是一份**声明式配方**,五个动词按序执行: + +| 动词 | 做什么 | +|---|---| +| `project` | 从某个来源的每一行投影出台账行,落草稿层。带 `prune` 时,这一笔投影出来的行**就是这张表在本单草稿里的全部** | +| `analyze` | **一次结构化 AI 调用**:系统组装入参、声明出参 schema、系统把结果落表。不给工具、不给记忆、不多轮 | +| `card` | 发一张卡(执行工单 / 数据工单 / 决策卡)。**至多一张**,发过就不再发 | +| `submit` | 提交放行(只许出现在声明了人工验收清单的那一步) | +| `say` | 一句给人看的交代 | + +地址只有四种:`域.对象`(任务视图 = 正式 + 本单草稿叠加,**默认该用的那一种**)· `mine:域.对象` · +`in:入参数组` · `result:xxx`(本拍 analyze 的出参)。 + +**guide 可以留空,但只有声明了 auto 才行**:`planStepSchema` 原来要求 `guide` 非空 +(`.min(1)`)—— 那是防「作者忘了写做法」的老规矩,可它顺手把「这一步一次都不问模型」堵死了。 +现在改成 `superRefine`:没声明 `auto` 的步照旧非空;声明了 `auto` 的步允许 `guide` 写空串 +(`guide.trim() === ''`)——引擎正是按这个空串分「全 auto(一次都不问模型)」与 +「半 auto(确定的先做完,剩下的判断仍问模型)」。**全 auto 的步就把 `guide` 写成空串**, +别为了过 schema 塞一句废话。 + +**半 auto 的步,人答完卡之后那一截判断仍然是模型的活**:配方发过一张卡、`worldTouched` +为真、这一拍没有未答的卡、配方这一拍也没再发新卡 —— 这几个条件都成立时,引擎本可以 +「卡答过了就收步」抄近道直接收掉这一项。但**这条近道只走没有 `guide` 的步**(全 auto); +只要 `guide` 非空(半 auto),就算前面几个条件都成立,也仍然要往下问模型 —— +半 auto 存在的意义就是「确定的先做完,剩下的判断仍问模型」:人答完卡之后那份判断 +(读人写的自由文本、落到具体的行上)恰恰是模型该干的活,收在它前面等于把半 auto 的 +后半截整个删掉。写半 auto 的步时记住这条:`guide` 不空,这一步答完卡不会被引擎抢先收掉。 + +**四条纪律**(每一条都是踩出来的): + +1. **行由确定的那一侧决定,不由 AI 决定。** 明细表要按类型字典 `each` 出来,AI 的出参只是拿主键 + `lookup` 的一张查表 —— 它漏一条,那一格就是空,`required` 立刻变成 `_missing > 0`,闸与放行门当场拦住。 + 写成 `from each(AI 出参)` 的话,它少给两条就少两行,而每一行看着都合规。 +2. **判据不许编一个数不出来的数。** 「本类型有几个字段」不是基座数得出来的数(`_rows` 数的是**本单写下的**行); + 行数对账交给 `prune` 的结构保证,别写进 `doneWhen`。 +3. **每一笔之前刷读数。** 后一笔常要数前一笔刚写下的行。 +4. **出错交人,不重试、不退回模型。** 配方抛错是包的 bug;退回模型就是让它去凑。 + +--- + ## 5. 活动包怎么写 ### 5.1 包结构