@sema-ai/core 1.277.0 → 1.278.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +97 -21
- package/NOTICE.md +1 -1
- package/README.md +2 -5
- package/README.new.md +150 -0
- package/README.zh-CN.new.md +145 -0
- package/dist/bench/metrics.js +1 -1
- package/dist/bench/metrics.js.map +1 -1
- package/dist/core/cache-break-detector.js +0 -0
- package/dist/core/cache-break-detector.js.map +1 -1
- package/dist/core/tools.d.ts.map +1 -1
- package/dist/core/tools.js +3 -1
- package/dist/core/tools.js.map +1 -1
- package/dist/engine/execution-env/node-execution-env.d.ts.map +1 -1
- package/dist/engine/execution-env/node-execution-env.js +8 -0
- package/dist/engine/execution-env/node-execution-env.js.map +1 -1
- package/dist/engine/harness/types.d.ts +9 -1
- package/dist/engine/harness/types.d.ts.map +1 -1
- package/dist/engine/harness/types.js.map +1 -1
- package/dist/tools/fs/index.d.ts.map +1 -1
- package/dist/tools/fs/index.js +94 -3
- package/dist/tools/fs/index.js.map +1 -1
- package/dist/tools/gitea-issue.d.ts +1 -1
- package/dist/tools/gitea-issue.d.ts.map +1 -1
- package/package.json +2 -7
- package/CHANGELOG.md +0 -5455
- package/docs/A1-ATTRIBUTION-ROUND1-2026-07-09.md +0 -181
- package/docs/AB-ORACLE-GATE-VERDICT-2026-07-10.md +0 -100
- package/docs/ANCHOR-GAP-INVENTORY-2026-07-09.md +0 -143
- package/docs/ARCHITECTURE.md +0 -125
- package/docs/BUGHUNT-2026-07-05-NIGHT.md +0 -98
- package/docs/BUILD.md +0 -63
- package/docs/CANCEL-ASYNC-ATTRIBUTION-2026-07-09.md +0 -98
- package/docs/CC-198-VS-201-DRIFT-2026-07-09.md +0 -70
- package/docs/CC-BASELINE-FAKE-ZERO-AUDIT-2026-07-09.md +0 -51
- package/docs/CC-DRIFT-198-206-AGENT-TYPES-2026-07-10.md +0 -82
- package/docs/CC-DRIFT-198-206-CHANGELOG-2026-07-10.md +0 -82
- package/docs/CC-DRIFT-198-206-REMINDERS-2026-07-10.md +0 -96
- package/docs/CC-DRIFT-198-206-ROADMAP-2026-07-10.md +0 -110
- package/docs/CC-DRIFT-198-206-TOOL-INVENTORY-2026-07-10.md +0 -53
- package/docs/CC-DRIFT-198-206-USAGE-CONSTANTS-2026-07-10.md +0 -64
- package/docs/CC-DRIFT-198-206-WORKFLOW-2026-07-10.md +0 -83
- package/docs/CC-PARITY-CHECKLIST.md +0 -220
- package/docs/CC-PARITY-DEEP-SWEEP-2026-07-07.md +0 -149
- package/docs/CC-SUBAGENT-PROMPT-STUDY-2026-07-09.md +0 -219
- package/docs/CC-TASK-REMINDER-CADENCE-STUDY-2026-07-09.md +0 -396
- package/docs/CC-TOOL-PARITY-SWEEP-2026-07.md +0 -56
- package/docs/CC-TOOL-PROMPT-DEEP-DIFF-2026-07-08.md +0 -274
- package/docs/CC-TOOLSURFACE-DEEP-DIVE-2026-07-07.md +0 -197
- package/docs/CC206-OBSERVER-ANCHORS-2026-07-11.md +0 -463
- package/docs/CC207-CORE-SWEEP-BACKLOG-2026-07-12.md +0 -155
- package/docs/CENTER-CONTROL-PLANE-SEAM.md +0 -86
- package/docs/CLEANUP-CONTRACT-ANCHOR-2026-07-09.md +0 -83
- package/docs/COLD-START-RSI-2026-07-09.md +0 -72
- package/docs/COMPACTION-LIVE-AUDIT-2026-07-09.md +0 -114
- package/docs/CONTEXT-lifecycle-extension-points-and-stop-attribution.md +0 -71
- package/docs/COREWARS-POLYGLOT-TRIAGE-2026-07-09.md +0 -85
- package/docs/DEADTARGET-OVERFULL-HBOX-2026-07-10.md +0 -92
- package/docs/DEADTARGET-PATH-TRACING-REVERSE-2026-07-10.md +0 -87
- package/docs/DEADTARGET-WINNING-AVG-COREWARS-2026-07-10.md +0 -96
- package/docs/DEEPSEEK-API-LIMITS-PROBE-2026-07-09.md +0 -118
- package/docs/DESIGN-140-MOCK-VERIFY-2026-07-11.md +0 -79
- package/docs/DESIGN-140-VERIFICATION-2026-07-11.md +0 -43
- package/docs/DESIGN-DRAFT-workflow-collab-2026-07-11.md +0 -56
- package/docs/DESIGN-ORACLE-GROUNDING-GATE-2026-07-10.md +0 -167
- package/docs/DESIGN-TFRAG-RECONCILE-SCAFFOLD-2026-07-09.md +0 -102
- package/docs/EXP-PA2-PE-DESIGN-2026-07-11.md +0 -220
- package/docs/EXT-DOGFOOD-2026-07-12.md +0 -50
- package/docs/FINAL-VERIFY-SURFACE-AUDIT-2026-07-09.md +0 -44
- package/docs/FRAG-RECON-INVESTIGATION-2026-07-09.md +0 -183
- package/docs/HANDOFF.md +0 -121
- package/docs/KNOWN-ISSUES.md +0 -96
- package/docs/LEGW-WINDOW-TAX-2026-07-10.md +0 -82
- package/docs/LIVE-PROBE-BATCH-2026-07-11.md +0 -207
- package/docs/M2-CERT-ATTRIBUTION-2026-07-10.md +0 -61
- package/docs/M25-LEG-VARIANCE-ATTRIBUTION-2026-07-10.md +0 -81
- package/docs/MAILMAN-TIMEOUT-ATTRIBUTION-2026-07-10.md +0 -88
- package/docs/MEMORY-BACKEND-DIALECT-NOTES.md +0 -69
- package/docs/MTEB-ESCAPE-HATCH-ATTRIBUTION-2026-07-09.md +0 -57
- package/docs/MTEB-LEADERBOARD-ATTRIBUTION-2026-07-10.md +0 -134
- package/docs/ORACLE-GATE-NEGATIVE-SAMPLE-2026-07-11.md +0 -28
- package/docs/PARITY-CONTEXT-TRANSACTIONS-2026-07-10.md +0 -67
- package/docs/PARITY-PROGRESS-MATRIX-2026-07-10.md +0 -37
- package/docs/PARITY-SPOT-AGENT-TYPES-2026-07-10.md +0 -70
- package/docs/PARITY-SPOT-REMINDERS-2026-07-10.md +0 -144
- package/docs/PARITY-SPOT-TOOL-INVENTORY-2026-07-10.md +0 -61
- package/docs/PARITY-SPOT-USAGE-CONSTANTS-2026-07-10.md +0 -95
- package/docs/PARITY-SPOT-WORKFLOW-2026-07-10.md +0 -93
- package/docs/PASSWORD-RECOVERY-PANEL-VERDICT-2026-07-10.md +0 -62
- package/docs/R8-R9-FINALIZE-COORDINATION-2026-07-09.md +0 -124
- package/docs/REPL-CODE-MODE-EVALUATION-2026-07-10.md +0 -187
- package/docs/REPORT-1249-TARGETED.md +0 -48
- package/docs/RESEARCH-3P-MEMORY-SWAP-2026-07-12.md +0 -273
- package/docs/ROADMAP.md +0 -111
- package/docs/RSI-CLOUD-DEPLOY-2026-07-06.md +0 -289
- package/docs/RSI-PROCESS-AI-COLDSTART-2026-07-11.md +0 -68
- package/docs/S18-THOROUGHNESS-AUDIT-2026-07-09.md +0 -113
- package/docs/SERVICE-INTEGRATION-GUIDE.md +0 -298
- package/docs/SUBAGENT-STREAM-RESILIENCE-PARITY-2026-07-10.md +0 -118
- package/docs/SWEBENCH-PRO-RECON-2026-07-11.md +0 -31
- package/docs/TB-EFFICIENCY-TELEMETRY-2026-07-08.md +0 -114
- package/docs/TB-FAILURE-AUTOPSY-2026-07-05-RERUN.md +0 -67
- package/docs/TB-FAIRNESS-AUDIT-2026-07-08.md +0 -141
- package/docs/TB-FULL-1257-2026-07-08.md +0 -77
- package/docs/TB-LEG-GAP-ATTRIBUTION-1261-1263-2026-07-11.md +0 -154
- package/docs/TB-REGRESSION-DAEMON-KILL-2026-07-08.md +0 -58
- package/docs/TB-RSI-CROSSCHECK-2026-07-06.md +0 -68
- package/docs/TB-RSI-LEDGER.md +0 -30
- package/docs/TB-STABLE-SET-2026-07-08.md +0 -127
- package/docs/TB21-RECON-2026-07-11.md +0 -28
- package/docs/TEST-DESIGN-BATCH-1-2-3.md +0 -97
- package/docs/THIRD-PARTY-INTEGRATION.md +0 -45
- package/docs/TOKEN-ESTIMATE-CALIBRATION-LIVE-2026-07-09.md +0 -102
- package/docs/audit-2026-06-10-/347/254/254/344/272/214/350/275/256-/347/251/272/347/231/275/345/214/272/344/270/216/345/277/230/346/216/245/347/272/277.md +0 -147
- package/docs/audit-2026-06-10-/350/256/241/347/256/227bug/346/211/253/346/217/217.md +0 -163
- package/docs/audit-2026-06-11-/344/277/256/345/244/215/345/244/215/345/256/241/344/270/216/345/233/236/345/275/222/344/270/223/346/211/253.md +0 -95
- package/docs/audit-2026-06-12-design71-P1/346/275/234/344/274/217/351/235/242/350/243/201/345/206/263/344/270/216/345/220/236/351/224/231/345/256/241/350/256/241.md +0 -45
- package/docs/audit-2026-06-12-/345/205/254/345/274/200/346/227/213/351/222/256/346/264/273/346/200/247/344/270/216vendored/346/255/273/350/267/257.md +0 -63
- package/docs/audit-2026-06-15/ADDENDUM-second-pass.md +0 -88
- package/docs/audit-2026-06-15/ARCHITECTURE-AND-ROADMAP.md +0 -187
- package/docs/audit-2026-06-15/DOC-CORRECTIONS.md +0 -105
- package/docs/audit-2026-06-15/INDEX.md +0 -49
- package/docs/audit-2026-06-15/ORCHESTRATION-STATUS.md +0 -98
- package/docs/audit-2026-06-15/PRODUCTION-ISSUES.md +0 -189
- package/docs/audit-2026-06-15/REFERENCES-literature.md +0 -139
- package/docs/audit-2026-06-15/VENDOR-REFACTOR-PLAN.md +0 -96
- package/docs/cc-probe-198/README.md +0 -72
- package/docs/cc-probe-198/STABILITY-AUDIT.md +0 -118
- package/docs/cc-probe-198/live-schema-monitor-worktree-2026-07-09.json +0 -56
- package/docs/cc-probe-198/mount-variants.json +0 -536
- package/docs/cc-probe-198/plan-mode-run.json +0 -1
- package/docs/cc-probe-198/probe-bash-bg.json +0 -224
- package/docs/cc-probe-198/probe-edit-mismatch.json +0 -120
- package/docs/cc-probe-198/probe-read-missing.json +0 -62
- package/docs/cc-probe-198/probe-search-empty.json +0 -127
- package/docs/cc-probe-198/probe-task-family.json +0 -227
- package/docs/cc-probe-198/probes.status +0 -6
- package/docs/cc-probe-198/raw-capture-interactive.json +0 -948
- package/docs/cc-probe-198/raw-capture-print.json +0 -787
- package/docs/cc-probe-198/raw-capture2-interactive.json +0 -948
- package/docs/cc-probe-198/raw-capture2-print.json +0 -787
- package/docs/cc-probe-198/system-prompt.txt +0 -135
- package/docs/cc-probe-198/tools-array.json +0 -962
- package/docs/durability-boundary.md +0 -63
- package/docs/fix-2026-06-10-/350/256/241/347/256/227bug/344/277/256/345/244/215-search/346/211/271.md +0 -75
- package/docs/fix-2026-06-11-/347/254/254/344/272/214/350/275/256-/344/277/256/345/244/215-search/346/211/271.md +0 -62
- package/docs/parity-sweep/REPORT-DYNAMIC.md +0 -97
- package/docs/parity-sweep/REPORT-STATIC-GGB.md +0 -127
- package/docs/parity-sweep/REPORT-STATIC-RWE.md +0 -133
- package/docs/vendor-history.md +0 -385
- package/docs/vendored-upstream-diff-2026-07.md +0 -83
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
# 历史文档/记忆修正项 + 改进原因(事实依据)— 2026-06-15
|
|
2
|
-
|
|
3
|
-
> 每条:**断言(谁说的)→ 真相(代码说的)→ 证据(file:line)→ 修正动作 → 为什么这么改**。
|
|
4
|
-
> 全部经 48-agent 交叉验证(~10 个子系统独立撞到同一版本漂移=强印证),关键项 search AI 亲自复核。
|
|
5
|
-
|
|
6
|
-
## C-1 🔴 版本/CHANGELOG 漂移(最高频,~10 子系统独立报)
|
|
7
|
-
- **断言**:`package.json = 1.99.0` 暗示存在已发布的 1.99.0;memory `project-engine-resilience-fixes` 称"#14 maxTurns 100→10000 / suspends 5→100 在 1.99.0 shipped"。
|
|
8
|
-
- **真相**:`CHANGELOG.md` **无** `## 1.99.0` 头(`grep '1.99' CHANGELOG`=0 命中);最后发布头是 `## 1.98.0`(:30),顶部是 `## Unreleased`(:5)=design/72(repo_map/suspend-loop cap/sensitive-path)。1.99.0 bump(`c4ffa51`)只改 package.json、捆绑了 turn/suspend cap 抬升;`c35a06f` 把默认值 **revert 回** `DEFAULT_MAX_TURNS=100`(runtask.ts:48)/`DEFAULT_MAX_SUSPENDS=5`(prepare-task.ts:90),但**没碰版本号**。design/74(#16)在 VENDOR.md 有记录、CHANGELOG 完全没有。
|
|
9
|
-
- **证据**:package.json:3;CHANGELOG.md:5,30;runtask.ts:42-48(含 revert 注释)、prepare-task.ts:85-90;commits c4ffa51 / c35a06f / 6bb55e8。
|
|
10
|
-
- **修正**:① memory 该条改为"#14 已 **revert**,当前默认 100/5";② 下次发版前补干净 release-cut + CHANGELOG header;③ 已加 CI 版本一致性 pin 测试(P-17)。
|
|
11
|
-
- **为什么**:版本号广告 maxTurns=10000 但代码 ship 100 = 部署方按版本号判断会错配;且 CHANGELOG 是 service AI/集成方读的事实源,不能落后于代码。
|
|
12
|
-
|
|
13
|
-
## C-2 🔴 design/74 文档/注释把"在飞"写成"已 shipped"
|
|
14
|
-
> ⚠️ **二轮更新(本条本身的快照已部分过时)**:第一遍写"suspend-MINT 半边未建 / `requestStopAfterTurn()` 零调用者"是**审计起点(HEAD=`d7724ff`)的真相**;审计中另一谱系提交了 `3e5c52d`(Slice 3c),**suspend 触发器现已接成 + 绿**(prepare-task.ts:1072 调 requestStopAfterTurn)。即:本条揭示的"文档写得像 shipped、其实没接"的**漂移方向是对的**,但**那个 gap 已被 Slice 3c 填上**;现在 still-未建的是 Slice 4 账本机制 + service 半边。详见 `ADDENDUM-second-pass.md` §A。**教训**:design/74 是分钟级移动目标,任何冻结快照都会快速过时——以 git log + memory 为活源。下方原文保留作审计起点记录。
|
|
15
|
-
- **断言**:`checkpoint-store.ts` JSDoc(MAX_SUPPORTED_CHECKPOINT_VERSION=2 等)、`agent-harness.ts:495` 注释("runner's turn_boundary subscriber sets it via requestStopAfterTurn")、VENDOR.md mod #16("Lets the runner's resource-slice suspend stop the loop cleanly")——都读着像在用的能力。
|
|
16
|
-
- **真相**:只有 **resume/READ 半边**接好了(resource_limit gate-match + continuation + applyResumeDecision early-return + 空 suspendedBatch + version 守卫)。**suspend-MINT 半边未建**:`requestStopAfterTurn()` 在 `src/core/` **零调用者**(grep 仅 vendor + VENDOR.md);`serializeCheckpointState` 仅被 human-gate 路径调(prepare-task.ts:1051);`RESOURCE_CHECKPOINT_VERSION(=2)` 在 src 里除自身声明外无引用;`TaskSpec/RunnerDeps` **无** resource-slice 配置字段;`src/core/runner/suspend.ts` 不存在;grep `commitSuspend/mintResourceCheckpoint/overSliceLimit/softDeadline`=零。`agent-harness.ts:495` 描述的 subscriber **不存在**(runtask.ts 的 turn_boundary handler 只做压缩)。
|
|
17
|
-
- **证据**:checkpoint-store.ts:50-233;agent-harness.ts:209-212,495,994-999;VENDOR.md:125-132;runtask.ts:817(onTurnBoundary 只压缩);grep 结果如上。
|
|
18
|
-
- **修正**:本审计已**明确标注**design/74 为 in-flight(另一个 AI),slices 1/2/3a done、trigger+saga+service 半边未建。注释/JSDoc 的"runner uses it"应加 `(design/74 in-flight, not yet wired)` 限定(留给做 design/74 的 AI 在落地时清理,避免撞车)。
|
|
19
|
-
- **为什么**:文档把意图写成现状,会让接手者(或我)误判"资源挂起已能用"而少建 trigger。诚实标注 in-flight 是底线。
|
|
20
|
-
|
|
21
|
-
## C-3 🟠 memory `project-engine-resilience-fixes` 的 teacher.test.ts fail / npm publish 失败已过时
|
|
22
|
-
- **断言**:"#14 core(1.99.0 git 推但 npm publish 失败=teacher.test.ts 1 fail 待坐实)"。
|
|
23
|
-
- **真相**:`npm test` **全绿**(1133 passed / 7 skipped / 91 文件),`teacher.test.ts` 24 测试全过。当时 cap=10000 让 ~23 个 teacher 测试因无界轮次 hang(c35a06f commit body 自陈),revert 后即修复(`3cd5413` 给 teacher 测试设显式 maxTurns + revert)。
|
|
24
|
-
- **证据**:`npx vitest run` 输出;teacher.test.ts 24 tests;commits 3cd5413 / c35a06f。
|
|
25
|
-
- **修正**:memory 改为"已修复(revert + teacher 测试显式 maxTurns)、suite 全绿;待办只剩 release-cut 清账"。
|
|
26
|
-
- **为什么**:陈旧的"待坐实失败"会让接手者重复排查一个已解决的问题。
|
|
27
|
-
|
|
28
|
-
## C-4 🟠 README 第 13 行依赖列表过时(`ignore`/`yaml`)✅亲验
|
|
29
|
-
- **断言**:README:13 "外部依赖:仅 `typebox`、`@modelcontextprotocol/sdk`、`ignore`、`yaml`(后两个仅 vendored 磁盘 skill 用)"。
|
|
30
|
-
- **真相**:design/71 P1 删除了整个磁盘 skill 面,`ignore` + `yaml` 两个 npm 依赖**已被移除**。`package.json` dependencies **只剩** `@modelcontextprotocol/sdk` + `typebox`。
|
|
31
|
-
- **证据**:package.json dependencies(我亲自核);VENDOR.md "ignore + yaml dependencies dropped";CHANGELOG 1.98.0 design/71 P1 条目。
|
|
32
|
-
- **修正**:README 已更新(见交付 #1),依赖描述改为只列 typebox + MCP SDK。
|
|
33
|
-
- **为什么**:README 自陈是"看完即可独立集成、不需读源码"的交接文档,依赖清单错了会误导安装/审计。
|
|
34
|
-
|
|
35
|
-
## C-5 🟠 [R18] 编排器 suspended-guard 行号引用全部陈旧(机制对、坐标漂移)
|
|
36
|
-
- **断言**:Task/memory 的 [R18] guard map 引 `cascade.ts:85, teacher:271-279/441-443, verify.ts:147, team:213` 为 suspended/checkpoint 传播守卫。
|
|
37
|
-
- **真相**:那些行号现在指向**无关代码**(cascade.ts:85=finalRung 的 JSDoc;teacher:271-279=onToolFail 错误签名 helper;verify.ts:147=VerificationOutcome 类型;team:213=runTurn 返回类型)。**真正的守卫在** cascade.ts:191、teacher.ts:482、verify.ts:287/312/342、team.ts:235、subagent.ts:198——**守卫存在且正确**,只是坐标漂了(代码增长所致)。
|
|
38
|
-
- **证据**:上述各 file:line 实读对比。
|
|
39
|
-
- **修正**:更新引用坐标;机制不变(编排器确实把 suspended 映射成 failed+`unexpected.suspended`+checkpointToken)。
|
|
40
|
-
- **为什么**:行号引用是给做 review 的人导航用的,指错地方浪费时间;但要明确**守卫本身没坏**,避免误判为缺失。
|
|
41
|
-
|
|
42
|
-
## C-6 🟠 design/00 称"下一阶段主线=design/69",但 design/69 文件不存在
|
|
43
|
-
- **断言**:design/00 头部(2026-06-11 权威)"当前路线图入口读 67/68/69;design/69=GitHub+CI/CD 接入优化路线图=下一阶段主线"。
|
|
44
|
-
- **真相**:`design/` 下**无 69-*.md 文件**(只有 67-e2e-smoke + 68-llm-planner)。真正的 GitHub/CI 前向 roadmap 在 search AI 的 memory `project-coding-roadmap-next`,不是 committed design 文档。OPT-1(repo_map)是它的第一刀、已 ship;OPT-3(CI async)见 design/72 §3。
|
|
45
|
-
- **证据**:`ls design/` 无 69;design/00:7;memory project-coding-roadmap-next。
|
|
46
|
-
- **修正**:design/00 的悬空引用应改为指向 design/72(下一批 roadmap)+ memory;或补写 design/69。本审计的 ARCHITECTURE-AND-ROADMAP 已把真 roadmap 落成文档。
|
|
47
|
-
- **为什么**:悬空引用让接手者找不到"主线"文档,误以为丢失。且 design/00 自身的"下一阶段主线"判断也被 2026-06-14 大重定向(真 Beatsep 考场)取代——design/00 §1/§4 已自标"冻结在 1.36 era"。
|
|
48
|
-
|
|
49
|
-
## C-7 🟠 OpenAI brain `Usage.cost` 注释暗示反映缓存定价(实际 vestigial)
|
|
50
|
-
- **断言**:openai.ts:281 注释 cacheRead "Surfaced so a caller can see real cache effectiveness"。
|
|
51
|
-
- **真相**:cacheRead **token 计数**正确(openai.ts:289),但 `Usage.cost.cacheRead` **硬编码 0**(:292),totalTokens 不含 cacheRead——与 Anthropic(给 cacheRead 定价、计入 totalTokens)不一致。无害,因 brain 的 `Usage.cost` 非权威:core 用 `computeCostMicroUsd` 从 token 数重新定价,`stats.costUsd` 已 `@deprecated`。但注释读着像有意义。
|
|
52
|
-
- **证据**:openai.ts:281-292 vs anthropic.ts:188-205 vs pricing.ts:45-58。
|
|
53
|
-
- **修正**:注释加"(non-authoritative; core re-prices via computeCostMicroUsd)"。
|
|
54
|
-
- **为什么**:防止有人据 brain 的 `Usage.cost` 做成本决策(应该用 core 的 `computeCostMicroUsd`)。
|
|
55
|
-
|
|
56
|
-
## C-8 🟠 `createFailoverBrain` JSDoc 把 failover 条件描述成"仅传输层失败"
|
|
57
|
-
- **断言**:failover.ts:13-19 "only when it fails before emitting any content (gateway down / connection refused, OR first-token timeout)"——框成传输层 upfront 失败。
|
|
58
|
-
- **真相**:`createFailoverBrain` **不分类 error code**:`cleanUpfrontFailure = stopReason==='error' && !aborted && !sawContent`(:61-62)。一个**无内容的模型输出错误**(如只发了 tool-call delta 就截断 `finish_reason:'length'`——tool delta 不产生流事件)`sawContent=false` 会被 failover,即便它不是传输故障、换网关也无济于事。断路器/降级 brain 都按 error code 分类,failover 是唯一不分类的装饰器。
|
|
59
|
-
- **证据**:failover.ts:13-19,61-62;openai.ts:387-460(tool delta 不 push 事件);circuit-breaker.ts:163-165;degrading.ts:82-87。
|
|
60
|
-
- **修正**:JSDoc 应改为"任何无内容产出的 stopReason:error(含模型输出错误,不限传输)";或让 failover 也按 code 分类(对齐断路器)。
|
|
61
|
-
- **为什么**:文档让集成方以为 failover 只在网关挂时触发,实际会对模型侧截断也切换,可能掩盖真实模型问题。
|
|
62
|
-
|
|
63
|
-
## C-9 🟡 web_fetch 模型可见描述谎称"仅 allowlist"(见 P-6)
|
|
64
|
-
- **断言**:web.ts:103 工具描述"Only allowlisted hosts can be fetched";web.ts:11 header 称 allowlist 是 SSRF/外泄边界。
|
|
65
|
-
- **真相**:无 allowlist 时(68-70)零 host 检查 + `redirect:follow`;即使有 allowlist 也只是 exact-hostname、无 IP/私网拦截。JSDoc(19-21,59-60)是诚实的("Omitted ⇒ no host restriction"),但**模型可见描述**与之矛盾。
|
|
66
|
-
- **修正**:见 P-6,修描述 + 复用 image.ts 的 `isPrivateHost`。
|
|
67
|
-
- **为什么**:模型可见描述影响模型行为(它以为安全),且 header 的安全声明被实际行为打脸。
|
|
68
|
-
|
|
69
|
-
## C-10 🟡 多处"文档写得比代码保证强"(measurement≠invariant)
|
|
70
|
-
- **property-harness.ts:9** "0 false positives (probe-13: 16/16, FP 0/12)":是**探针测量值**,非代码可保证的属性——header 自陈"only FP risk is an unfaithful contract"。0-FP 仅对 faithful contract 成立。
|
|
71
|
-
- **tool-policy.ts:179** `combinePolicies` "check() MUST be idempotent ... accumulate no side effects":是**对调用方 policy 的契约,非系统强制**。combine 会在某 policy ask 后继续调后续 policy 的 check(:194-210 不 break),`createApprovalPolicy.check` 每次调 `opts.approve()` → 非幂等的 approver 会重复弹审批。
|
|
72
|
-
- **trace.ts:8-10** "best-effort, never breaks the task":`emitTrace` 只 try/catch **同步** tracer 调用(:81-85);TracerHook 返回 void,异步抛错(未 await 的 rejected promise / microtask throw)逃逸 try/catch=未处理 rejection。"never breaks"只对同步抛错成立。
|
|
73
|
-
- **修正**:这些是文档措辞,把"保证"改为"在 X 前提下"(faithful contract / caller-idempotent / synchronous)。
|
|
74
|
-
- **为什么**:把测量/前提性保证写成无条件不变量,会让人在不满足前提时过度信任(如装一个非幂等 approver 或异步 tracer)。
|
|
75
|
-
|
|
76
|
-
## C-11 🟡 memory `project-vendored-refactor` "compaction+session 入 src/engine 干净 naturalize"略夸张
|
|
77
|
-
- **真相**:逻辑搬了,但 `src/engine/compaction/compaction.ts` 仍重度依赖 vendored 类型/helper(asAgentMessage/convertToLlm/HarnessMessage/SessionTreeEntry…);`session.ts` 仍 import 整个 SessionTreeEntry union + SessionStorage 接口。"naturalized" 高估了独立性——类型/序列化底座没搬。
|
|
78
|
-
- **证据**:compaction.ts:9-37;session.ts:1-22。
|
|
79
|
-
- **修正**:措辞改为"逻辑 first-party 化,类型底座仍 vendored"。见 vendor 重构计划对此的处理(类型绝缘层 design/33 的后续)。
|
|
80
|
-
|
|
81
|
-
## C-12 🟡 TiDB 适配器 header 数错适配器数 + 缺 CheckpointStore(见 P-3 相关)
|
|
82
|
-
- **断言**:tidb-adapter.ts header(1-8)"TiDB/MySQL reference adapters ... 1. TiDbSessionRepo 2. TiDbBreakerState"——说两个。
|
|
83
|
-
- **真相**:文件实际 ship **三个**:TiDbSessionRepo、TiDbBreakerState、**TiDbToolResultStore**(design/30,:324)。且**无 CheckpointStore**——与 PG(有 PgCheckpointStore + e2e F4 测试)**不对称**:复制 TiDB 文件的 service 没有 durable-checkpoint 参照适配器,TiDB 上的 durable suspend/resume 无示例。
|
|
84
|
-
- **修正**:header 更新为三个;补一个 TiDbCheckpointStore 参照(或在 header 明示"TiDB checkpoint 参照见 PgCheckpointStore 同构实现")。
|
|
85
|
-
- **为什么**:service 主线(leader 编排 + durable suspend)需要 TiDB checkpoint;缺示例是真空白。
|
|
86
|
-
|
|
87
|
-
## C-13 🟡 其余确认的小漂移(完整列表)
|
|
88
|
-
- `RECALL_CAVEAT` 只注入 selective-recall 块(memory-recall.ts:206);默认 inject-all 路径只有 MEMORY_SAFETY 单句(default.ts:79)——eval 验证过的 3/3 强 caveat **只在罕用的 selective 路径**生效。文档没标这点。
|
|
89
|
-
- selector `recentTools` 只填 caller 声明的 `spec.tools`(prepare-task.ts:617),**不含**core 注入的 band(remember/recall/read_file/grep/lsp/skill…)——selector 的工具-gotcha 启发式看不到任务最常用的工具。design 意图比接线宽。
|
|
90
|
-
- `ToolSpec.label` 确认 **INERT**(mapped 但无 reader,事件只带 toolName)——JSDoc 已自标 ⚠️,但首句仍读着像活功能。
|
|
91
|
-
- `TraceEvent.tool.call.effect` 字段**生产者从不设**(runtask.ts:694-702 不带 effect,尽管 toolEffects map 在 scope)——permanently undefined。
|
|
92
|
-
- `mcp.ts` `allowTools` 只过滤 server 的 listTools 工具;合成的 `list_resources`/`read_resource`(server 声明 resources capability 时**无条件**加,:177-217)`allowTools` 压不掉——文档未标此例外。
|
|
93
|
-
- VENDOR.md 编号 mod 停在 #16,但有**第 17 个 vendored 编辑未入编号表**:event-stream.ts:60(design/71 清尾,bare `end()` 无终态事件改 REJECT)带 VENDORED EDIT marker 但只在散文里提;shell-output.ts mod #14 实际有**两块** VENDORED EDIT(同步翻转 + evictedTail 截断标志 follow-up);`src/vendor/agent-core/src/harness/compaction/` 残留**空孤儿目录**(P2 naturalize 后)。
|
|
94
|
-
|
|
95
|
-
---
|
|
96
|
-
|
|
97
|
-
## 给下一个 agent:本次审计校正的"事实地图"
|
|
98
|
-
| 主题 | 旧说法(已废) | 当前真相 |
|
|
99
|
-
|------|---------------|----------|
|
|
100
|
-
| 版本 | 1.99.0 已发、maxTurns=10000 | package.json=1.99.0 但**未发布/未 tag**,默认 100/5(reverted),CHANGELOG 最新=1.98.0+Unreleased(design/72) |
|
|
101
|
-
| 测试 | teacher.test.ts 1 fail / publish 失败 | **全绿 1133/91**,已修 |
|
|
102
|
-
| design/74 | 触顶第三态 spec 未实现 | **slices 1/2/3a 已 commit**(resume/read 半边 + shouldStopAfterTurn 接线),**trigger+saga+service 半边未建**,另一个 AI 在做 |
|
|
103
|
-
| 依赖 | typebox+MCP+ignore+yaml | **只 typebox+MCP SDK**(design/71 删了 ignore/yaml) |
|
|
104
|
-
| [R18] 守卫 | cascade:85/teacher:271… | 真守卫在 cascade:191/teacher:482/verify:287,312,342/team:235/subagent:198(机制对,行号漂) |
|
|
105
|
-
| 主线文档 | design/69 | design/69 **不存在**;真 roadmap 在 design/72 + memory project-coding-roadmap-next |
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
# 2026-06-15 全仓审计 — 证据归档(deep evidence)
|
|
2
|
-
|
|
3
|
-
> 📌 **接手入口已升级为 [`../HANDOFF.md`](../HANDOFF.md)(活文档)。本包 = 2026-06-15 的深度审计证据(冻结、只读)**——"当前状态"以 `docs/` 根的活文档(HANDOFF/ARCHITECTURE/BUILD/ROADMAP/KNOWN-ISSUES/SERVICE-INTEGRATION-GUIDE)为准;本包提供"我们怎么知道的"详证。`SERVICE-INTEGRATION-GUIDE.md` 已升级移到 `../SERVICE-INTEGRATION-GUIDE.md`(活)。本包仍价值高的:**PRODUCTION-ISSUES**(每条 bug 完整 re-derivation)/ **REFERENCES-literature**(~60 文献)/ **DOC-CORRECTIONS**(漂移修正史)/ **VENDOR-REFACTOR** / **ORCHESTRATION-STATUS** / **ADDENDUM-second-pass**。
|
|
4
|
-
|
|
5
|
-
> search AI 受 clay 之命做的全仓核实审计(48-agent 对抗 workflow + 二轮补漏 + search AI 亲自复核关键项)。
|
|
6
|
-
> 方法:对真实代码持**检查+证伪**态度,纠正记忆/文档漂移,交叉验证,清晰证据。本包是当前最新最全的接手信息。
|
|
7
|
-
|
|
8
|
-
## 一句话现状
|
|
9
|
-
引擎成熟(~24.2k LOC first-party + ~6k vendored,**91 测试文件**),四原语 + v1.5 远端 suspend/resume + 编排栈全 shipped。当前主线=**Beatsep Kotlin 迁移真考场**(求最优编码流程 + 鲁棒性)。**另一谱系在飞做 design/74**(资源切片 suspend,长自治跑——审计中从 Slice 2 推进到 **Slice 3c `3e5c52d`:suspend 触发器已建成+绿**;剩 Slice 4 账本 + service 半边)。本审计:**20 confirmed bug(P-1~P-20;首轮 18 findings 含 SSE 重复计=17 unique,+3=20)/ ~40 测试缺口 / ~60 文献 / 12+ 条文档修正 / 1 个未完成发版(1.99.0)**。
|
|
10
|
-
|
|
11
|
-
> ⚠️ **做过两遍**:第一遍(12 子系统 + 18 bug)+ **二轮复查**(补漏 15 个未深读文件 + 反查 8 篇交付的准确性)→ `ADDENDUM-second-pass.md`(+3 新 bug 含 P-20 HIGH、design/74 状态变更、6 处文档不准已就地修、~25 条功能/契约缺口)。**design/74 是分钟级移动目标——以 git log + memory 为活源,别信任何冻结行号。**
|
|
12
|
-
|
|
13
|
-
## 10 项交付(对应 clay 的 10 问)
|
|
14
|
-
| # | 文件 | 内容 |
|
|
15
|
-
|---|------|------|
|
|
16
|
-
| 1 | `../../README.md`(已更新)| 最新 README:修正依赖漂移(删 ignore/yaml)+ 加当前版本状态注记 |
|
|
17
|
-
| 2+3 | `ARCHITECTURE-AND-ROADMAP.md` | 分层架构图 + 数据流 + 设计路线时间线 + 从代码反推的后续 roadmap(带 shipped/in-flight/proposed/deferred 状态)|
|
|
18
|
-
| 4 | `REFERENCES-literature.md` | ~60 篇论文/框架/基准(按主题,标可验证性:多个 2026 arxiv ID 离线不可核)|
|
|
19
|
-
| 5 | `PRODUCTION-ISSUES.md` | 18 confirmed bug(P-1~P-17,亲验 6 条)+ 8 证伪 + 优先级建议 |
|
|
20
|
-
| 6 | `VENDOR-REFACTOR-PLAN.md` | design/71 已完成核实 + 剩余 vendor 面 + 账本缺口 + 前向严密路线 |
|
|
21
|
-
| 7 | `../../test/known-issues-2026-06-15.test.ts` | 11 个 pin 测试(8 bug,全绿、零改既有文件、tripwire 式)|
|
|
22
|
-
| 8 | `SERVICE-INTEGRATION-GUIDE.md` | 给 service AI:实现哪些 seam + 契约 + 直接影响 service 的 gotcha + 重点分析 |
|
|
23
|
-
| 9 | `ORCHESTRATION-STATUS.md` | 8 种编排模式现状/进度/机制/效果(含诚实 caveat)|
|
|
24
|
-
| 10 | `DOC-CORRECTIONS.md` | 12 条记忆/文档漂移修正(断言→真相→证据→动作→为什么)|
|
|
25
|
-
| + | `ADDENDUM-second-pass.md` | **二轮复查**:+3 新 bug(P-18/19/20,P-20 HIGH)+ design/74 状态变更 + 6 处文档不准修正 + ~25 条功能/契约缺口 |
|
|
26
|
-
|
|
27
|
-
## 🔴 接手必知的 6 个事实地图(详见 DOC-CORRECTIONS)
|
|
28
|
-
1. **版本**:`package.json=1.99.0` 但**未发布/未 tag**,默认 100/5(reverted),CHANGELOG 最新=1.98.0 + Unreleased(design/72)。需补 release-cut。
|
|
29
|
-
2. **测试**:审计起点全绿(1133/91);现工作树有另一谱系**未提交的 design/74 Slice 3c 红测试**(`expected 'failed' to be 'suspended'`,触发器没接,非回归)。本审计 11 pin 测试全绿。
|
|
30
|
-
3. **design/74**(⚠️ 二轮更新):审计中从 Slice 2 推进到 **3c `3e5c52d`——suspend 触发器已建成+绿**(`TaskSpec.resourceSuspend` opt-in,turn/budget cap→suspended)。**剩** Slice 4 账本机制 + service 半边 + minors。**别碰** runtask/prepare-task/checkpoint-store/agent-harness/types/remote-suspend-resume.test(另一谱系活跃区)。活真相源=git log + memory。
|
|
31
|
-
4. **依赖**:只 typebox + MCP SDK(design/71 删了 ignore/yaml)。
|
|
32
|
-
5. **[R18] 编排守卫**:机制对、行号漂——真守卫在 cascade:191/teacher:482/verify:287,312,342/team:235/subagent:198。
|
|
33
|
-
6. **design/69**(被 design/00 称"主线")**不存在该文件**;真 roadmap 在 design/72 + memory project-coding-roadmap-next。
|
|
34
|
-
|
|
35
|
-
## 🔴 头号产品命门(非本审计能修,记录)
|
|
36
|
-
- **oracle 失败无自修复**(memory + service ROBUSTNESS-BACKLOG):core 给验证栈,但"对真 oracle 验失败后自动修复"的环要 leader 建。
|
|
37
|
-
- **无路径兼具工具链 + HITL**(单兵实验教训):引擎有 approval-gate 但无 agent 主动 elicitation + leader endpoint 没接审批。
|
|
38
|
-
|
|
39
|
-
## 修 bug 的优先级(给做修复的 AI)
|
|
40
|
-
1. SAFE 文件高杠杆:P-1(MCP isError,1 行 throw)/ P-6(web_fetch SSRF,复用 image.ts isPrivateHost)/ P-3(TiDB delete 序)/ P-4(read_file 假截断)。
|
|
41
|
-
2. 协调 design/74(同文件):P-7/P-8/P-9/P-10/P-11/P-15。
|
|
42
|
-
3. 低危随手:P-12~P-16。
|
|
43
|
-
4. bookkeeping:P-17(release-cut + CHANGELOG + 已加 CI 版本 guard pin)。
|
|
44
|
-
|
|
45
|
-
## 本审计动了什么(全在工作树,未提交,等 clay)
|
|
46
|
-
- **改**:`README.md`(依赖 + 版本注记)。
|
|
47
|
-
- **新增**:`docs/audit-2026-06-15/`(本包 8 文档,含 ADDENDUM)+ `test/known-issues-2026-06-15.test.ts`(11 pin 测试)。
|
|
48
|
-
- **没碰**:任何 design/74 活跃文件、任何既有 src、既有 test(另一谱系 memory 亦确认我没碰它的文件)。`npm test` 全绿(含本审计 +11;另一谱系的 Slice 3c 现已提交转绿)。
|
|
49
|
-
- **新 bug P-18/19/20 未补 pin 测试**(P-20 HIGH 在 SAFE 文件 image.ts,可补)——留给修复者按 ADDENDUM §E + §B 的测试建议补。
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
# 编排支持现状 + 进度 + 效果 — 2026-06-15(代码核实)
|
|
2
|
-
|
|
3
|
-
> 每种编排:**是什么 → 进度(shipped/in-flight/proposed)→ 关键机制(file:line)→ 效果/实测/诚实 caveat**。
|
|
4
|
-
> 全部经子系统验证 + search AI 核对。导出符号见 `src/index.ts:73-105,330-336`。
|
|
5
|
-
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## 总览矩阵
|
|
9
|
-
|
|
10
|
-
| 编排模式 | 入口 | 进度 | core/profile | 效果定性 |
|
|
11
|
-
|---------|------|------|-------------|----------|
|
|
12
|
-
| **单兵(single)** | `Runner.runTask/runTaskStream` | ✅ shipped | core | **主力**;研究共识 single≥multi(等预算);Beatsep campaign 实测 single 主导 |
|
|
13
|
-
| **subagent(委派)** | `createSubagentTool` | ✅ shipped(同步单层) | core | 隔离子上下文;深度+自委派守卫;嵌套成本聚合。push 异步=后续项 |
|
|
14
|
-
| **team(讨论/council)** | `runTeamDiscussion` | ✅ shipped | core | 广度+对抗(council/debate);成员失败显式标记;Tool-MAD |
|
|
15
|
-
| **cascade(质量门级联)** | `runCascade` | ✅ shipped | core | cheap-first+gate 升级;成本天花板;fail-open gate |
|
|
16
|
-
| **teacher(escalation)** | `runWithTeacher` | ✅ shipped | core | 便宜学生+强老师;3 层 stuck 检测;策略仓库 |
|
|
17
|
-
| **verify(L3 去相关判)** | `runWithVerification` | ✅ shipped | core | 实现→验证 fix loop;只读 verifier band;⚠️ 去相关需配 role |
|
|
18
|
-
| **leader 编排 code-agent 团队** | (service profile) | 🔵 proposed(design/68)| **service** | core 依赖全 shipped;planner 本体在 service |
|
|
19
|
-
| **资源切片 suspend(长自治)** | (design/74) | 🟡 in-flight | core+service | resume 半边 done,trigger+saga 未建 |
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
## 1. 单兵(single)✅
|
|
24
|
-
**进度**:完全 shipped,是默认与主力。
|
|
25
|
-
**机制**:eager streaming fire-and-forget(runtask.ts:244-276)——任务在 `runTaskStream` 构造瞬间开跑,`result()` await 共享 `run` promise;两阶段工具门(prepare-task.ts:871-1157,PreToolUse hook→policy→resolveAsk→suspendAsk)单调用栈,"hook 的 allow 不能绕过 policy 的 deny/ask"是结构性而非竞态。
|
|
26
|
-
**效果**:
|
|
27
|
-
- 研究共识(REFERENCES C):等思考预算下 single 一致 ≥ multi(arXiv 2604.02460);SWE-bench Verified 多 agent 全架构 -2~-15%;baseline paradox(2603.22651)模型越强多 agent 增益越小。
|
|
28
|
-
- **Beatsep campaign 实测**(memory project-single-agent-experiment + service 通道):单兵 DeepSeek 自治建 DoneTone **3 次全败 0 提交**(run 019ec5d1);hybrid(A 面)5 特性 + 157MB APK 绿。**纠错**:失败真因**不是**"core 无 elicitation"——引擎**有** approval-gate(ToolPolicy 三态 + durable suspend),真缺口是**无 agent 主动 elicitation + leader endpoint 没接审批 = 纯自治**(无路径兼具工具链 + HITL)。
|
|
29
|
-
- task#2a-2d(service)单兵+评分流水线**全 PASS**($0.044-0.07/run,cache 94.7%)→ **明确分解的小任务上单兵稳且便宜**。
|
|
30
|
-
|
|
31
|
-
## 2. subagent(委派,单向)✅
|
|
32
|
-
**进度**:shipped,**同步单层**(父等子);push-based 异步 + 中途进度回流=README §14/design/00 A3 的后续项。
|
|
33
|
-
**机制**:
|
|
34
|
-
- 递归双重有界(subagent.ts:164 `depth+1<maxDepth` + :108,163 自委派排除集)→ 模型不能 X→X→X 死循环。
|
|
35
|
-
- 嵌套成本 disjoint own-vs-nested(subagent.ts:185-191 冒泡全子树);消费方真总额 = `stats.X + stats.nested.X`。
|
|
36
|
-
- 子结果经 `delimitUntrusted` opaque-delimit(subagent.ts:230);`SUBAGENT_SYSTEM_NOTE` framing 子报告为"证据待核验"(gap E:报告指示父核验、不能覆盖系统/用户策略)。
|
|
37
|
-
- 子默认 `enableBlockedReport:true`(子也能上报受阻);suspended 子 → failed-like 报告带 checkpointToken、不 release(⚠️ 二轮修正:subagent **不** import `mapNestedSuspend`,而是**内联**等价逻辑于 `subagent.ts:198-206`)。
|
|
38
|
-
**效果**:隔离干净上下文做长检索/计算;委派 1B(`defineAgent`/`AgentDefinition`)shipped。SOTA 对照:OpenHands DelegateTool(max 5)+ RemoteWorkspace **从不组合**=我们差异化(委派×远端容器);CAID worker 峰值 4(8 退化)。
|
|
39
|
-
|
|
40
|
-
## 3. team(多 agent 讨论/council)✅
|
|
41
|
-
**进度**:shipped。N 个角色化成员多轮讨论 → synthesizer 合成。
|
|
42
|
-
**机制**:每轮每成员收"`<team-discussion>` + 此前所有发言(`<statement>` 数据块引用)";成员每轮无状态(共享 transcript 提供连续性);成员一轮失败**自动重试一次**,仍失败标 `[unavailable: <status>]` 计入 `failures`(不静默污染);transcript 压缩;Tool-MAD(工具增强辩论);全 untrusted 内容 `sanitizeUntrustedText`(team.ts:14 tag denylist)+ suspended 成员标 `[unavailable]` 不 release(team.ts:235-238)。
|
|
43
|
-
**效果**:广度 + 对抗(council/debate)正交于 teacher 的深度升级。**适用**:开放式"完整性/质量"判断(找全 bug、创意质量)——没 oracle 知道"该有几个",靠广度+对抗而非深度升级。DeepSeek council(deep+debate,6 lens)是本项目设计/代码评审的实际对抗工具。
|
|
44
|
-
|
|
45
|
-
## 4. cascade(质量门级联)✅
|
|
46
|
-
**进度**:shipped。`runCascade`:rung 0 失败→rung 1…,gate 判 escalate。
|
|
47
|
-
**机制**:默认 gate=`status===completed`;rung0 fail→rung1 pass(escalated,finalRung 1,成本=两次之和);全 fail→`cascadeOutcome:"exhausted"`返回最后 rung 不强制 failed;**throwing gate 是 fail-open**(escalate,记 gateError);`maxEscalations` 上限;`costCeilingMicroUsd` 在下个 rung 前止损(cascade.ts:159-162);成本 own-vs-nested disjoint(cascade.ts:130-149,171-185);suspended rung → push attempt + `mapNestedSuspend` 不 release 不 escalate(cascade.ts:191-201)。
|
|
48
|
-
**效果**:cheap-first+gate 比预测路由稳(FrugalGPT/Dynamic Routing Survey 2026 验证);production-proven 成本省。
|
|
49
|
-
|
|
50
|
-
## 5. teacher(老师模式 escalation)✅
|
|
51
|
-
**进度**:shipped(design/12-15,含策略仓库二期)。便宜学生干主活,卡住/答错请教强老师。
|
|
52
|
-
**机制(3 层 stuck 阶梯)**:
|
|
53
|
-
- **Tier-0**:同工具+**同错误** streak(tool-wrapper,teacher.ts:277-300,任何 success 重置)→ 提前止损 abort;
|
|
54
|
-
- **cheap stuck-monitor LLM** 二次确认(teacher.ts:399-407,"progressing" 后 2 轮 grace)+ `stuckHardOverride`(:397 无视 monitor/grace);
|
|
55
|
-
- **Tier-1 语义 rubric 质检**(便宜模型)抓"通过但语义错"+ `blocked`/`failed` 终态。
|
|
56
|
-
- 老师=隔离 advisor 角色子运行,只回 JSON `{strategy,correction,nextStep,takeover,confidence}`,**对话丢弃、只把结构化建议注回同一学生 session**(护前缀缓存),要求学生先用工具核验再照做;纠正多次→老师接管。
|
|
57
|
-
- 硬护栏:`maxEscalations`、`teacherSpendRatioCap`(老师 token ≤ 学生×比例,分母含 studentNestedTokens 防过早止损,teacher.ts:528)、老师每次 ≤4 turn;suspended 学生→`finalize(mapNestedSuspend)`(teacher.ts:482)。
|
|
58
|
-
- 学生流一检测到 stuck 立即 abort + 10s `abortFallback` race 促止损(teacher.ts:419-436)——⚠️ 该 fallback 定时器泄漏=P-12(低危)。
|
|
59
|
-
**效果 + 诚实 caveat**:
|
|
60
|
-
- **适用前提**:任务要有"可判定的 verify 信号"(Tier-0 同工具同错卡住 / Tier-1 rubric / 终态)。
|
|
61
|
-
- **不适用**开放式"完整性/质量"判断(code-review 找全 bug、创意)——没 oracle 知道"该有几个、漏了哪个",学生找到一个明显问题就过 verifier、静默漏其余,触发机制空转(verifier 纯增本)→ 这类靠 **team council/debate** 非深度升级。
|
|
62
|
-
- 提醒:小而明确任务上"强模型"未必更贵(强模型简洁、弱模型啰嗦),"便宜学生省钱"前提被削弱(service 实测,design/12 §六)。
|
|
63
|
-
- 策略仓库:奏效策略存下,相似问题注入学生 objective(前缀缓存安全),`scope` 强制隔离;检索高精度低召回 + "过去不同任务、可能不适用、请核验"否定前言。SOTA=Inter-Cascade(2509.22984)/ERL(2603.24639)。
|
|
64
|
-
|
|
65
|
-
## 6. verify(L3 去相关验证门 / dev 模式)✅
|
|
66
|
-
**进度**:shipped。`runWithVerification`:实现→验证,FAIL→fix→PASS loop(同 session 续),持久 FAIL 到 `maxRounds` 停(无死循环)。
|
|
67
|
-
**机制**:
|
|
68
|
-
- 自动选 prompt:有 diff 证据且无 override → `STATIC_VERIFICATION_PROMPT`(只读 judge),否则 `VERIFICATION_PROMPT`(verifier 自跑检查)——避免只读沙箱挡 runtime 时"全 PARTIAL"(verify.ts:225,service[36]/search[48] dogfood)。
|
|
69
|
-
- **只读 verifier band 双机制**(因 design/44 hand band 绕过 caller-tools effect filter):(a) caller 工具过滤到 `effect:"read"`(verify.ts:222),(b) `handsReadOnly:true` 让 Runner 只挂只读 hand 子集(verify.ts:237);+ verifier 不给 durableApproval/checkpointStore,policy "ask" 无头自动 deny 而非 suspend(verify.ts:238-240,DESIGN#5)。
|
|
70
|
-
- 成本/轮次天花板(verify.ts:277-278);suspended → unverified/failed-with-token(verify.ts:287,312,342)。
|
|
71
|
-
- 全 untrusted objective `delimitUntrusted`(verify.ts:181-194)。
|
|
72
|
-
- subagent 自报核验(gap E):报告 framing 为证据,端到端 verifying parent 能 surface mismatch 而非声称成功。
|
|
73
|
-
**效果 + 🔴 重要诚实 caveat**:
|
|
74
|
-
- **去相关 judge 是文档契约,非此处强制**(verify.ts:96-104 明示):role→model 解析在 Runner,**默认 verifier role 回退到 default=implementer**——**这会击穿去相关**!要真去相关,**必须**在 deps.roles 配一个不同的 verifier 模型。这是关键接入点(否则 self-preference bias,arXiv 2410.21819,judge 偏好自分布)。
|
|
75
|
-
- judge 本身不稳(REFERENCES D:SE judge audit 同案自相矛盾、扰动翻 verdict;JudgeBiasBench >50% 错误率)→ verify 是**纵深**非唯一保证;objective-oracle(exec-gate 机械门)才是确定性可靠那层。
|
|
76
|
-
|
|
77
|
-
## 7. leader 编排 code-agent 团队(v2 主场景)🔵 proposed
|
|
78
|
-
**进度**:design/68 spec **定稿**(deep council + 两次 core 实现者复核)。**设计为 all-profile / zero-new-core**——Router(难度路由,默认 single,fail-closed)+ 有界 Decomposer(2-4 不相交文件子任务,parsePlan 不变量)+ 反应式 replan-lite(确定性反应表,≤1 LLM re-decompose)**都在 service leader profile**,不在 core。
|
|
79
|
-
**core 依赖项全 shipped**:`runTaskStream` fan-out + suspended-cancel(1.71)、`verifyCompleted`+L2 exec-gate、property-harness、checkpoint、steering、cost stats。core src 里 planner/fanout/parsePlan/Decomposer **只出现在注释**——planner 本体 by-design **不在本仓**。
|
|
80
|
-
**效果(SOTA 对照)**:Cursor FastRender(Planner/Worker/Judge,平权 agent+锁失败、层级胜)、Agyn(72.2% vs single 65%)、ManagerWorker("direction>review" +11pp vs +2pp)、ComposioHQ(确定性状态机编排,无 LLM)、LangGraph(Send API fan-out + checkpoint 按 task_id 键=独立验证我们 Set<toolCallId> 完成键)。**价值判决 FIRM**:default-single,fan-out 仅为 speed/cost,adaptive-DAG 不建。
|
|
81
|
-
|
|
82
|
-
## 8. 资源切片 suspend/resume(长自治跑)🟡 in-flight
|
|
83
|
-
见 ARCHITECTURE §6.2 + SERVICE-GUIDE §4 + `ADDENDUM-second-pass.md` §A。⚠️ **二轮修正**:**core 侧 suspend 触发器现已建成并提交**(`3e5c52d` Slice 3c,turn/budget cap→suspended,测试绿);**剩** Slice 4 账本机制 + service 半边 + minors。快速移动——活真相源=git log + memory。
|
|
84
|
-
|
|
85
|
-
---
|
|
86
|
-
|
|
87
|
-
## 9. 横切安全/正确性不变量(所有编排共享)
|
|
88
|
-
- **`mapNestedSuspend`(suspend-guard.ts:25)= 载重安全不变量**(⚠️ 二轮修正:**四**编排 import 它=cascade/team/teacher/verify;**subagent 内联**等价于 subagent.ts:198-206):suspended→failed + `unexpected.suspended`,checkpointToken/gate 经 spread 透传,**call site 故意不 release session**(release 会孤立 pinned checkpoint 使 resume 永远重建不了);每编排配"不 escalate/不 re-run"停止避免重放写副作用。**注意 team 例外**:`TeamResult`(team.ts:123-127)**无 checkpoint 字段**→suspended 成员的 checkpointToken 被丢、永不可经 team API resume(by-design v1,但调用方须让 team 成员跑非-durable policy 避免孤儿 checkpoint,详见 ADDENDUM §D)。
|
|
89
|
-
- **untrusted 内容一致 opaque-delimit / sanitize**(design/53 §2.A):teacher trace/monitor/verifier、verify objective、team 成员/summary、subagent 子结果全过 `delimitUntrusted`/`sanitizeUntrustedText`;**可信 caller objective/spec 保持 plain**——一致纪律。
|
|
90
|
-
- **成本 disjoint own-vs-nested**(A-7/R-5/B-5 修):真总额=`stats.X + stats.nested.X`,防过早止损。
|
|
91
|
-
|
|
92
|
-
---
|
|
93
|
-
|
|
94
|
-
## 10. 效果数据现状(诚实)
|
|
95
|
-
- **机械确定性可靠**(唯一站得住):exec-gate 退出码 / property-harness 结构不变量(probe-13:结构-契约 catch 16/16,FP 0/12)。
|
|
96
|
-
- **cheap-judge / 跨模块降级 = 待 service 真环境严验的方向性假设**(shadow-lab 的 design/56 被对抗 council 降级为"未验证假设":confound/确认偏误/无对抗/成本零计/n 小)。
|
|
97
|
-
- **真考场数据**:Beatsep campaign task#2a-2d 全 PASS(单兵+评分流水线,$0.044-0.07/run);单兵自治建复杂特性 3/3 失败(无 HITL 路径)。ledger 起账中、样本量在攒(outcome ledger 自动 fire 仍 TODO,service[107] 自陈)。
|
|
98
|
-
- **结论**:编排原语都 shipped 且机制正确;**"哪种编排在哪种任务最优"的定量效果数据仍在 Beatsep campaign 积累中**,这正是当前主线。
|
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
# 生产遗留重大问题清单 — 2026-06-15 审计
|
|
2
|
-
|
|
3
|
-
> **方法**:48-agent 对抗审计(12 子系统验证 + 8 bug 类猎杀 + 每条独立 re-derivation 证伪)。
|
|
4
|
-
> 26 候选 → **18 confirmed / 8 refuted**。其中 **6 条由 search AI 亲自读源码复核**(逐行核对,见✅亲验标记)。
|
|
5
|
-
> 全部带 `file:line` 证据。每条已核对**不是** design/74 在飞代码(另一个 AI 正在做的资源挂起)。
|
|
6
|
-
> 测试基线:审计起点(HEAD=`d7724ff`)`npm test` = **1133 passed / 7 skipped / 91 文件全绿**(本清单的 bug 均**不**导致测试失败——它们是 happy-path 之外的边界/错误路径/契约缺口,现有测试没覆盖)。
|
|
7
|
-
> **⚠️ 审计期间 design/74 被另一谱系快速推进**:审计起点 HEAD=`d7724ff`(Slice 2);审计结束已到 `3e5c52d`(Slice 3a/3b/3c 全提交)。Slice 3c "resource-slice suspend trigger" 一度是工作树红测试(`expected 'failed' to be 'suspended'`),**现已提交并转绿(31 passed)**——即第一遍"suspend-MINT 半边未建"的结论**已被 3e5c52d 推翻**(见 `ADDENDUM-second-pass.md` §A;另一谱系 memory 亦确认)。**design/74 活真相源 = git log + memory `project-engine-resilience-fixes`**,非本文冻结表述。本审计新增的 `test/known-issues-2026-06-15.test.ts`(11 pin 测试)**全绿**且零改既有文件。
|
|
8
|
-
|
|
9
|
-
## 严重度总览
|
|
10
|
-
|
|
11
|
-
| # | 严重度 | 标题 | 文件 | 亲验 |
|
|
12
|
-
|---|--------|------|------|------|
|
|
13
|
-
| P-1 | 🔴 HIGH | MCP 工具丢弃 `isError` 标志——失败的 MCP 调用被当成功 | `src/core/mcp.ts:161-169` | ✅ |
|
|
14
|
-
| P-2 | 🔴 HIGH | SSE `/task/stream` 客户端断连不取消 eager run——任务烧到底+持有 env/MCP+无界缓冲 | `src/server/http.ts:127-131` | ✅ |
|
|
15
|
-
| P-3 | 🔴 HIGH→服务 | `TiDbSessionRepo.delete()` 先删 entries 后删 session row——静默空历史窗口(Pg 修复的镜像反例) | `src/examples/adapters/tidb-adapter.ts:207-210` | ✅ |
|
|
16
|
-
| P-4 | 🟠 MED | `read_file` 对以 `\n` 结尾的文件多算 1 行(幻影空行 + 假截断标志) | `src/tools/fs/index.ts:121-148` | ✅ |
|
|
17
|
-
| P-5 | 🟠 MED | 悬空符号链接:`env.readLink` 未实现时 sensitive-path guard 被绕过 | `src/tools/fs/safety.ts:199-200` | ✅ |
|
|
18
|
-
| P-6 | 🟠 MED | `web_fetch` SSRF:无 allowlist 分支零防护 + 即使有 allowlist 也无 IP/私网/metadata 拦截 + 模型描述谎称"仅 allowlist" | `src/tools/web.ts:68-103` | ✅ |
|
|
19
|
-
| P-7 | 🟠 MED | resume 烧掉 HITL checkpoint 后静默丢弃缺失工具,run 报 completed + 假"已执行"续写 | `src/core/runner/runtask.ts:1266-1343,1428-1442` | |
|
|
20
|
-
| P-8 | 🟠 MED | `prepareTask` MCP materialize 后抛错泄漏 MCP 传输(stdio 子进程/HTTP) | `src/core/runner/prepare-task.ts` catch(MCP 不 dispose) | |
|
|
21
|
-
| P-9 | 🟠 MED | `PgCheckpointStore` 缺 `reopen()`——durable 部署上 post-CAS env-restore 失败=静默丢挂起工作 | `src/stores/pg.ts:348-408` | |
|
|
22
|
-
| P-10 | 🟡 LOW | `InMemoryCheckpointStore.reap()` 过期不 unpin + 无 runner auto-reaper——内存 store 上 pin 泄漏到进程退出 | `src/core/checkpoint-store.ts:417-426` | |
|
|
23
|
-
| P-11 | 🟡 LOW | resume prepare 抛错(reserved-tool-name)泄漏原 suspend 的 session pin | `src/core/runner/runtask.ts:278-303` | |
|
|
24
|
-
| P-12 | 🟡 LOW | teacher `abortFallback()` 每次 stuck-abort 竞速泄漏未清/未 unref 的 10s 定时器 | `src/agents/teacher.ts:435-436` | |
|
|
25
|
-
| P-13 | 🟡 LOW | §25.2 anti-thrash 地板把 chars/4 的 freedTokens 从 usage 锚定的 triggerTokens 里减——code-dense 真模型上虚高地板可能压死任务内压缩 | `src/core/auto-compaction.ts:167,267-288` | |
|
|
26
|
-
| P-14 | 🟡 LOW | `jsGrep` multiline content 模式超过 head_limit + `[capped at N]` 标记少报真实行数 | `src/tools/fs/search.ts:286-292` | ✅ |
|
|
27
|
-
| P-15 | 🟡 LOW | `TaskStream.interrupt()/destroy()/steer()` 在 `prepareTask` 永不 settle 时永久挂起(env factory/MCP connect 无超时/abort) | `src/core/runner/runtask.ts:369,396,407,463` | |
|
|
28
|
-
| P-16 | 🟡 LOW | `RoleSpec.systemPrompt` 在显式设了 `TaskSpec.model` 时被静默丢弃 | `src/core/roles.ts:159-161` | |
|
|
29
|
-
| P-17 | 🟡 LOW | 版本/CHANGELOG 漂移:`package.json=1.99.0` 无 CHANGELOG 条目,1.99.0 标志性改动已 revert | `package.json` vs `CHANGELOG.md:5,30` | ✅ |
|
|
30
|
-
| **P-18** | 🟡 LOW | `reservedFor()` 用 `api==="anthropic"` 但真值是 `"anthropic-messages"`→design/40 碰撞警告对 Anthropic 部署用错 reserved 集 | `src/brain/request-params.ts:47-48` | |
|
|
31
|
-
| **P-19** | 🟡 LOW | `formatZodValidationError` 对嵌套属性失败命名父参数 + 错 expected 类型,且永不产出 docstring 承诺的 path | `src/core/tool-errors.ts:89-93` | |
|
|
32
|
-
| **P-20** | 🔴 HIGH | `isPrivateHost` SSRF guard 被 IPv4-mapped/NAT64/site-local IPv6 字面量绕过(`[::ffff:169.254.169.254]`)——**且推翻 P-6"复用 isPrivateHost"的建议** | `src/core/runner/image.ts:5-11` | ✅ |
|
|
33
|
-
|
|
34
|
-
> **P-18/P-19/P-20 详情见 `ADDENDUM-second-pass.md` §B**(二轮复查新增)。**P-20 是 HIGH**:它意味着我在 P-6/SERVICE-GUIDE 推荐"web_fetch 复用 image.ts `isPrivateHost`"的那道防线**本身有绕过**——修法=先用 `net.isIP()` 硬化 `isPrivateHost`(IPv4-mapped 抽内嵌 v4 重检 + 拦 NAT64/site-local/ULA),image+web_fetch 共用硬化版。
|
|
35
|
-
|
|
36
|
-
> design/74-adjacent 但**确为既有 bug**(非在飞):P-7/P-8/P-9/P-10/P-11/P-15。对抗验证逐条确认它们位于 design/45 既有 resume/checkpoint/leak 路径,design/74 的资源臂 early-return 不触碰它们。但**这些文件正被另一个 AI 编辑**(runtask/prepare-task/checkpoint-store)→ 按 PS2 指示**只记录,附 ready-to-add 测试,不在这些文件加可执行测试**(避免 git 撞车);其余在 SAFE 文件的 bug 已补 pin 测试(见 `test/known-issues-2026-06-15.test.ts`)。
|
|
37
|
-
|
|
38
|
-
---
|
|
39
|
-
|
|
40
|
-
## 🔴 HIGH
|
|
41
|
-
|
|
42
|
-
### P-1 · MCP 工具丢弃 `isError` —— 失败的 MCP 调用被当成功 ✅亲验
|
|
43
|
-
**文件**:`src/core/mcp.ts:161-169`(`connectServer` 里的 execute 闭包)+ `mapContent:70-87`
|
|
44
|
-
|
|
45
|
-
execute 闭包调 `client.callTool(...)`,把 `res.content` 经 `mapContent` 转换,返回 `{ content, details: res, terminate: false }`——**从不读 `res.isError`、从不抛错**。`mapContent` 只按 `item.type`(text/image/fallback)分支,也不看 `isError`。SDK 的 `callTool` 对一个普通 `{content, isError:true}` 文本结果**正常 resolve**(只在声明了 `outputSchema` 却无 `structuredContent` 时才抛)。
|
|
46
|
-
|
|
47
|
-
**亲验**:我读了 mcp.ts:161-169(返回 `{content, details, terminate:false}`)+ mapContent:70-87(只 switch `item.type`)——确认 `res.isError` 永不被消费。
|
|
48
|
-
|
|
49
|
-
**影响**:MCP server 返回 `{content:[{type:'text',text:'tool failed: ...'}], isError:true}` 被全链路当**成功**:agent-loop 的 `tool_execution_end` 携 `isError:false`(vendor `agent-loop.ts:829` 对任何不抛错的 execute 无条件 `isError:false`)→ `tool_end`(runtask.ts:707)→ trace `ok:true`(runtask.ts:700)→ consecutive-error 断路器/`outputErrorStreak` 永不跳闸 → `onError` 监控永不告警。模型虽然在 content 文本里看得到错误,但**引擎层的失败信号、可观测、断路全失效**。
|
|
50
|
-
|
|
51
|
-
**类对比**:本仓在别处正是**靠 throw** 修这一类——`tools.ts:74` 重抛"so the loop still marks the result isError";`ask-question.ts:163-167` 重抛 config 错"becomes a real tool error (isError, visible to onError)"。MCP 工具直接 wrap 成 `AgentTool`、绕过 `tools.ts` wrapper,所以这条纪律从没施加到它身上。
|
|
52
|
-
|
|
53
|
-
**测试缺口**:`test/mcp.test.ts` 零 `isError` 断言;MCP execute runtime 路径(callTool/mapContent/isError/resources fencing)整体**无任何单测**。
|
|
54
|
-
**建议修复**:execute 闭包在 `res.isError === true` 时 throw(或设可读错误信号),对齐 `tools.ts:74`。
|
|
55
|
-
|
|
56
|
-
---
|
|
57
|
-
|
|
58
|
-
### P-2 · SSE 断连不取消 eager run ✅亲验
|
|
59
|
-
**文件**:`src/server/http.ts:127-131`
|
|
60
|
-
|
|
61
|
-
```ts
|
|
62
|
-
const stream = opts.runner.runTaskStream(spec);
|
|
63
|
-
for await (const ev of stream) { res.write(`data: ${JSON.stringify(ev)}\n\n`); }
|
|
64
|
-
res.end();
|
|
65
|
-
```
|
|
66
|
-
**亲验**:我读了 http.ts:121-131——确认**无** `req.on('close')`、无 `stream.destroy()/interrupt()`、不检查 `res.write()` 背压返回值。
|
|
67
|
-
|
|
68
|
-
**影响**:`runTaskStream` 是 **eager**(`const run = (async()=>{...})()` 立即自执行,runtask.ts:244,文档自陈 :218-222)——任务在 stream 构造时就开跑,与是否有人 pull 解耦。客户端断连后:① 即使后续 `res.write` 抛 `ERR_STREAM_DESTROYED` 让 `for await` 退出,底层 `run` IIFE **不被 abort**,继续烧到 maxTurns/预算上限,持有 factory 铸的 ExecutionEnv + MCP 连接到自然 finish;② `PushQueue` 无界缓冲 + 循环忽略 `res.write` 背压 → 慢/死消费者下内存无界增长。`createTaskServer` 是**导出的公开 API**(index.ts:346)、README §4.10 推荐的前端 SSE 路径,非示例。
|
|
69
|
-
|
|
70
|
-
**正确原语已存在却没接**:`TaskStream.destroy()`(runtask.ts:402-419,abort+harness.abort+reap env)/ `interrupt()`(393-398)。
|
|
71
|
-
**建议修复**:SSE 分支加 `req.on('close', () => void stream.destroy())`;`res.write` 返回 false 时 `await once(res, 'drain')`。
|
|
72
|
-
|
|
73
|
-
---
|
|
74
|
-
|
|
75
|
-
### P-3 · TiDbSessionRepo.delete() 删除顺序 → 静默空历史 ✅亲验(影响服务)
|
|
76
|
-
**文件**:`src/examples/adapters/tidb-adapter.ts:207-210`(delete)+ open guard `:194`
|
|
77
|
-
|
|
78
|
-
```ts
|
|
79
|
-
async delete(metadata) {
|
|
80
|
-
await this.sql.execute(SQL.deleteEntries, [metadata.id]); // 先删 entries
|
|
81
|
-
await this.sql.execute(SQL.deleteSession, [metadata.id]); // 后删 session row
|
|
82
|
-
}
|
|
83
|
-
async open(metadata) {
|
|
84
|
-
...
|
|
85
|
-
if (sessionRows.length === 0 && entryRows.length === 0) throw not_found; // 两者皆空才 not_found
|
|
86
|
-
const entries = entryRows.map(...);
|
|
87
|
-
return new Session(new TiDbSessionStorage(..., entries)); // 中间态 entries=[] → 空 Session
|
|
88
|
-
}
|
|
89
|
-
```
|
|
90
|
-
**亲验**:我读了 tidb-adapter.ts:185-210——确认 delete 无事务、两次独立 await;open 用 `&&`(两者皆空才 throw)。
|
|
91
|
-
|
|
92
|
-
**影响**:无事务包裹,中间态 `{session row 在、entries 没了}` 在崩溃或另一副本并发 `open()` 时**持久可见**。此时 open 的 `&&` 条件为假 → 不抛 → 返回一个 **0 entry 的合法 Session**(`BaseSessionStorage` 容忍空 entries,`resolveLeafId([])`=null 不抛)→ wake/resume 拿到**空白对话历史**。这正是 `PgSessionRepo` 的 **BUG-2 修复的镜像反例**:Pg 先删 session row、且 open 只按 session row 判 not_found(pg.ts:285-289,303-304);TiDB 反着来。该文件 header 明示"copy verbatim into service"→ 缺陷**会传播进 service 的 durable 会话中心**。
|
|
93
|
-
|
|
94
|
-
**建议修复**:对齐 Pg——先删 session row,或把 open 的 not_found 判据改成"session row 不在"单条件。
|
|
95
|
-
|
|
96
|
-
---
|
|
97
|
-
|
|
98
|
-
## 🟠 MEDIUM
|
|
99
|
-
|
|
100
|
-
### P-4 · read_file 多算 1 行 + 假截断标志 ✅亲验
|
|
101
|
-
**文件**:`src/tools/fs/index.ts:121-122,127,146,148`
|
|
102
|
-
|
|
103
|
-
`const lines = content.split("\n"); const total = content.length===0 ? 0 : lines.length;`。`"a\nb\n".split("\n")` = `["a","b",""]`(len 3)→ `total=3`(应为 2)。body(:129)会输出幻影 `3\t` 空行。**更要命**:恰好 2000 真行 + 尾 `\n` 的文件 → total=2001,默认 limit=2000 → end=2000 → `truncated = end<total = true`(:127),header 谎称"of 2001 — use offset to see more"(:148),且 `truncated` 落进 `ReadFileState`(:146)→ `edit_file`(:192)的 `checkEditMatch` 在 not-found/ambiguous 时追加误导性"the read was truncated"提示(safety.ts:289/294)。
|
|
104
|
-
|
|
105
|
-
**亲验 + 张力解决**:对抗验证里有一条 `lineCount() +1` 被**正确证伪**(因 read/edit/write 都用同一公式 → 自洽,不互相矛盾);但 read_file 这条是**另一回事**——幻影行 + **假截断标志**是真缺陷。二者不冲突:行计数对 totalLines 是自洽的,但 truncated 标志依赖 `end<total` 的比较,被尾换行污染。
|
|
106
|
-
**建议修复**:像 vendored `truncate.ts:53-62 splitLinesForCounting()` 那样,尾随 `\n` 时 `lines.pop()`。
|
|
107
|
-
|
|
108
|
-
### P-5 · 悬空符号链接 sensitive-path guard 绕过 ✅亲验
|
|
109
|
-
**文件**:`src/tools/fs/safety.ts:199-200`
|
|
110
|
-
|
|
111
|
-
```ts
|
|
112
|
-
const info = await env.fileInfo(abs, signal);
|
|
113
|
-
if (!(info.ok && info.value.kind === "symlink") || !env.readLink) return { ok: true, key: abs };
|
|
114
|
-
```
|
|
115
|
-
**亲验**:我读了 safety.ts:183-210——`ExecutionEnv.readLink` 是**可选**方法(types.ts:330 `readLink?`);当 `env.readLink` 为 undefined 时直接返回**未解析的 innocent `abs`**,符号链接 target 永不被读。`createSensitivePathPolicy` 用该 `key` 匹配(sensitive-path-policy.ts:98)→ innocent 名不命中任何敏感段 → 放行。
|
|
116
|
-
|
|
117
|
-
**影响**:`write_file innocent.txt`(其中 `innocent.txt -> .git/hooks/payload`、target 尚不存在=悬空叶链接)在**不实现 readLink 的 env** 上绕过 sensitive-path guard。当前仅 `NodeExecutionEnv` 实现 readLink;`StubExecutionEnv` + 远端/E2B env 若省略它 → guard 的标志性保护**静默失效**。`test/sensitive-path-policy.test.ts` 6 个测试全用 NodeExecutionEnv,从不走 `!env.readLink` 分支。
|
|
118
|
-
**建议修复**:检测到悬空符号链接但 readLink 不可用时 **fail-closed**(视为不可解析→guard 不应静默放行)。
|
|
119
|
-
|
|
120
|
-
### P-6 · web_fetch SSRF ✅亲验
|
|
121
|
-
**文件**:`src/tools/web.ts:68-70`(无 allowlist 分支)+ `:76`(allowlist exact-hostname)+ `:103`(模型描述)
|
|
122
|
-
|
|
123
|
-
**亲验**:我读了 web.ts:55-110——确认:
|
|
124
|
-
- **有 allowlist 时**:逐跳 `redirect:"manual"` + 每跳重校验 host/scheme(72-91)——这部分**是好的**(design/64 §13.2 重定向绕过修复)。
|
|
125
|
-
- **无 allowlist 时**(68-70):`return doFetch(start, { redirect:"follow" })`——**零 host 检查、零私网/loopback/link-local(169.254.169.254 metadata)/RFC1918 拦截**,平台跟随所有 3xx。
|
|
126
|
-
- **即使有 allowlist**:`allowHosts.includes(current.hostname)` 是**纯 hostname 字符串匹配**,无 IP-literal/私网范围检查 → allowlist 里放个 IP 字面量、或 allowlisted host DNS-rebind 到私网,都不被范围校验。
|
|
127
|
-
- 模型可见描述(:103)"Only allowlisted hosts can be fetched"——无 allowlist 时**是假的**。出口走 `globalThis.fetch`(:97),不受注入的 ExecutionEnv 沙箱约束。
|
|
128
|
-
|
|
129
|
-
**类对比**:本仓 `image.ts` 有 `isPrivateHost()` 拦 metadata/loopback/RFC1918 + `redirect:"manual"`,**web_fetch 没复用**。`web_fetch` 是 `effect:"read"`(非 egress-marked)→ design/70 egress gate 不覆盖它。
|
|
130
|
-
**建议修复**:复用 `image.ts` 的 `isPrivateHost`,对每跳(含无 allowlist 分支)做 IP-class 拦截;修正模型描述措辞。
|
|
131
|
-
|
|
132
|
-
### P-7 · resume 丢弃缺失工具 + 假"已执行"续写(无 readLink 不可达;此为另一路径)
|
|
133
|
-
**文件**:`src/core/runner/runtask.ts:1266-1343`(resumeStream pre-CAS guards)+ `:1428-1442`(resolvePendingCall tool-not-found)
|
|
134
|
-
|
|
135
|
-
resumeStream 的 pre-CAS 守卫只查:gate-match、deny-reason 标签、checkpoint version、remote workspaceHandle——**不查 `taskConfig.tools` 是否含 `cp.pendingAction.toolName`**。CAS 在 :1326 无条件 resolve(烧掉 checkpoint,pending→resolved,不可逆)。之后 `resolvePendingCall` 在 :1428 `prepared.tools.find(t=>t.name===pendingAction.toolName)`;找不到(:1429)就发 `tool_end(isError)` + 追加"approved tool ... no longer available ... was not executed" toolResult 然后 `return`——**不抛、无 errorCode、不 suspend**。续写 `harness.prompt(resumeContinuation)` 对 allow 情形**硬编码**"was APPROVED and **has now been executed**"(:163-166,与"was not executed"自相矛盾),`assembleResult` 落到终态 `else` → **status `completed`**。净:resume caller 重传的 taskConfig 漏了已批准(常含副作用)的工具 → 静默丢工作 + 误导模型 + run 报 completed + 不可重试(checkpoint 已消费,二次 resume 命中 `already_resolved`)。
|
|
136
|
-
|
|
137
|
-
**与 env_failed 的不对称**:`resume.env_failed` 有 reopen 补偿(:285),这条没有。
|
|
138
|
-
**建议修复**:pre-CAS 加 satisfiability 检查(taskConfig.tools 必须含 pendingAction.toolName,否则拒绝、checkpoint 留 pending 可重试);或 tool-not-found 时不报 completed。
|
|
139
|
-
|
|
140
|
-
### P-8 · prepareTask MCP 泄漏(抛错时不 dispose)
|
|
141
|
-
**文件**:`src/core/runner/prepare-task.ts`(catch 块只 `ownedEnv.destroy()` + `forgetOnThrow()`,不碰 mcp)
|
|
142
|
-
|
|
143
|
-
MCP 在 try 块内 materialize(:552);try 内 552 之后有同步抛错点(skills reserved-name :663、tool_search reserved-name :782、harness 构造 :832)。catch 只 destroy ownedEnv + forget session,**从不引用 mcp**。`prepared.mcp.dispose()` 仅在 `finish()`(runtask.ts:1514,需返回 `Prepared`)调一次;prepare 抛错 → 永不返回 → 已连的 stdio 子进程 + HTTP socket 存活到 worker 进程退出。触发:`spec.mcp` 非空 + 一个 reserved-name 碰撞(caller 配置错,但确定性)。长寿 worker 反复失败任务 → fd/僵尸进程耗尽。
|
|
144
|
-
**建议修复**:prepare catch 加 best-effort `await mcp?.dispose()`。
|
|
145
|
-
|
|
146
|
-
### P-9 · PgCheckpointStore 缺 reopen() → durable 部署丢挂起工作
|
|
147
|
-
**文件**:`src/stores/pg.ts:348-408` vs 接口 `src/core/checkpoint-store.ts:303-315` + 消费 `runtask.ts:1338-1342`
|
|
148
|
-
|
|
149
|
-
只有 `InMemoryCheckpointStore` 实现 `reopen`(可选接口方法);`PgCheckpointStore` 的方法集只有 put/get/resolve/expire/reap。消费侧 `onEnvRestoreFailed = store.reopen ? ... : undefined`——Pg 上 `store.reopen` 为 undefined → 补偿不触发 → CAS 已 resolve 的 checkpoint 留 `resolved`、pending action 永不跑 = **工作丢失**。`resume.env_failed`(resumeVM 失败、CAS 已消费 checkpoint)是真实可达路径。**讽刺**:`d1c2750`("no more lost suspended work")加的保护**在最不需要的地方有**(InMemory,进程死本就全丢)、**在最需要的地方无**(durable Pg,长自治任务正是 design/74 的目标场景)。
|
|
150
|
-
**建议修复**:`PgCheckpointStore` 加 `reopen`(UPDATE status='pending' WHERE status='resolved',镜像现有 resolve/expire 的 UPDATE,schema 已有 status 列,trivially 可实现)。
|
|
151
|
-
|
|
152
|
-
---
|
|
153
|
-
|
|
154
|
-
## 🟡 LOW(真缺陷,严重度受限,但应记录/补测)
|
|
155
|
-
|
|
156
|
-
- **P-10 · checkpoint reap 不 unpin**(`checkpoint-store.ts:417-426`):`reap()` 只翻 pending→expired,`InMemoryCheckpointStore` 无 session-store 引用故无法 unpin;无 runner auto-reaper(无 `.reap(` 调用者);唯一 unpin 在 `runtask.ts:1111`(需 resume 到达非 suspended 终态)。net:内存 store 上一个 deadline 过期但从未 resume 的 checkpoint → session 永远 pinned、`sweep()` 永久跳过它到进程退出。durable store 上 pin/unpin 是 no-op 故生产无害,仅限内存默认。**cancellation 路径 `reapSuspended`(runtask.ts:314-352)也不 unpin**——缺口比 reap 更广。
|
|
157
|
-
- **P-11 · resume prepare 抛错泄漏 pin**(`runtask.ts:278-303`):resume 时 prepareTask 抛非-env_failed 错(如 reserved-tool-name)→ `run.catch` 只处理 env_failed + assemble failed,**从不 unpin** → 原 suspend 的 session pin 永久残留(仅内存 store)。
|
|
158
|
-
- **P-12 · teacher abortFallback 定时器泄漏**(`teacher.ts:435-436`):`new Promise(res=>setTimeout(()=>res(...),10_000))` 句柄不捕获、不 clear、不 unref;`settled` 赢 race 时 10s 定时器继续跑、持有闭包到触发。本仓其余定时器全 unref/clear(runtask:1162/1560、tool-policy:78、session-store:74…),唯它例外。仅 stuck 路径、bounded 10s,但延迟干净退出 + 并发 stuck 时定时器堆积。
|
|
159
|
-
- **P-13 · anti-thrash 地板坐标混用**(`auto-compaction.ts:167,267-288` 消费于 `runtask.ts:857-859`):`floor = (triggerTokens - freedTokens)*1.5`,但 `triggerTokens` 是 **usage 锚定的绝对值**(real provider tokens),`freedTokens` 是 **chars/4 启发式 delta**——两个坐标系相减。code-dense 真模型(R≈2)+ 大 free 时 floor 可超窗口 → `tokens < minTokens` 永真 → 任务内压缩对该 run 关停。1133 测试测不到:scripted brain 的 usage = chars/4(R=1),坐标恰好重合掩盖了它。请求级 `trimToBudget` 仍兜底防硬截断,故只是"压缩抑制"非数据丢失。
|
|
160
|
-
- **P-14 · jsGrep multiline 超 cap** ✅亲验(`search.ts:286-292`):cap 检查在 per-span context 内循环**之后**,单个跨多行 span 无条件 push 整段 → `out` 超 cap 达 `span_lines+2*ctx-1`,且从不 slice 就 join;`[capped at N]` 用 cap 值而非真实计数。非 multiline 分支(295-307)有 ctx 时同样先 push 整 2*ctx+1 窗口才查——两分支都超。仅影响 grep 输出量/诚实度。
|
|
161
|
-
- **P-15 · prepareTask 永挂 → stream 不可取消**(`runtask.ts:369,396,407,463`):`interrupt/destroy/steer` 都先 `await ready`,`ready` 仅由 `runLocked`(prepareTask 返回后)或 `run` 的 finally resolve。`executionEnvFactory`(prepare-task.ts:444,无 AbortSignal 参数、无 race/timeout)或 MCP connect 永不 settle 时 → `ready` 永不 resolve → 三个取消方法永久挂起。是 run 循环里**唯一无 signal/timeout 兜底的长 await 窗口**(resumeVM 有 `AbortSignal.any`,policy gate 有 raceAbort)。需 factory/transport 永不 resolve 且永不 reject(纪律好的 adapter 自带 timeout 可避)。
|
|
162
|
-
- **P-16 · RoleSpec.systemPrompt 被显式 model 吞掉**(`roles.ts:159-161`):`spec.model` 设了时 `resolveTaskModel` 返回 `{model, thinking}` **无 systemPrompt 字段**;只有 fallback-chain 路径(166-171)才带 preset。→ 在 `default` 角色 pin 了 `CODE_AGENT_PROMPT` 的部署,任何显式 model 的任务静默跑中性 prompt(安静质量回退)。RoleSpec.systemPrompt 的 JSDoc 只说"TaskSpec.systemPrompt 未给时用",没警告显式 model 也抑制它。`RoleSpec.thinking` 同样对称丢失。
|
|
163
|
-
- **P-17 · 版本/CHANGELOG 漂移** ✅亲验:`package.json=1.99.0` 但 `CHANGELOG.md` 无 `## 1.99.0` 头(最后发布头=1.98.0,顶部 `## Unreleased`=design/72)。1.99.0 bump(`c4ffa51`)只改 package.json、捆绑了已 revert 的 turn/suspend cap;`c35a06f` 把默认值 revert 回 100/5 但**没动版本号**。即:1.99.0 字符串既无 changelog、又不反映 shipped 行为(广告 maxTurns=10000 实际 100)。design/74 在 VENDOR.md(#16)有记录但 CHANGELOG 完全没有。**修复=补一次干净的 release-cut + CHANGELOG header**(并加 CI guard 测试,见 P-17 测试)。
|
|
164
|
-
|
|
165
|
-
---
|
|
166
|
-
|
|
167
|
-
## 8 条被对抗验证证伪(记录以免重复 raise)
|
|
168
|
-
|
|
169
|
-
| 候选 | 证伪理由 |
|
|
170
|
-
|------|----------|
|
|
171
|
-
| `lineCount() +1` 使 edit/write totals 不一致 | read_file 用**同一公式**算 total → 持久值与后续 read 完全一致;尾换行 +1 是全 fs band 统一自洽的约定,非缺陷(但 P-4 的"假截断标志"是真的,二者不同) |
|
|
172
|
-
| `TtlSessionStore.forget()` 竞争 in-flight `acquire()` | 真事件循环机制但**无可达触发**:所有 forget 调用者在 Runner per-sessionId 锁下、acquire 已 resolve 后才同步调;接口契约也不承诺该原子性 |
|
|
173
|
-
| SQL allowlist 剥 schema 限定符 → 跨 schema 读 | 行为真,但 `allowTables` 契约**明示**"Best-effort, NOT a hard isolation boundary";真边界是只读 DB 凭据;无 caller 按 schema 隔离并过信 allowlist |
|
|
174
|
-
| SQL validator 不拒 MySQL `#` 行注释 | 注释被**扫描非剥离** → `#` 注释藏不了语句/禁用关键字/INTO/禁表;validator 明示是只读凭据后的纵深防御;最多方言不一致/文档 polish |
|
|
175
|
-
| design/74 resource-slice suspend 的 producer 未落地 | **in-flight design/74**(另一个 AI),非 bug |
|
|
176
|
-
| v2 resource_limit checkpoint 过 resume 守卫但无 slice-budget read-path | **in-flight design/74** |
|
|
177
|
-
| onTurnBoundary 压缩守卫不 key design/74 soft-stop 标志 | **in-flight design/74** |
|
|
178
|
-
| `void harness.abort()` 拒绝未处理 | 触发**不可达**:唯一 `"*"` 订阅者是同步 switch、abort/queue_update 上 no-op 不抛;async hooks 在不同 channel;`AgentHarness.subscribe()` 未导出故无外部抛错订阅者。纯 latent(需未来代码加抛错订阅者) |
|
|
179
|
-
|
|
180
|
-
> **证伪本身的价值**:验证器正确区分了"自洽的行计数"vs"假截断标志",正确把 3 条 design/74 半成品判为非 bug,正确把"已文档化为 best-effort 的 SQL allowlist"判为非缺陷,把"不可达的 latent landmine"降级。这是审计可信度的标志(不是 18 条全 confirm)。
|
|
181
|
-
|
|
182
|
-
---
|
|
183
|
-
|
|
184
|
-
## 优先级建议(给 search AI / 另一个 AI)
|
|
185
|
-
|
|
186
|
-
1. **先修(SAFE 文件,高杠杆)**:P-1(MCP isError,真静默失败一类,1 行 throw)、P-6(web_fetch SSRF,复用 image.ts isPrivateHost)、P-3(TiDB delete 序,改 service 参照适配器避免传播)、P-4(read_file 假截断,误导 edit)。
|
|
187
|
-
2. **协调另一个 AI**(design/74 文件):P-7(resume satisfiability)、P-8(MCP leak)、P-9(Pg reopen)——这些与 design/74 正交但同文件,等其资源挂起切片落地后一起 review。
|
|
188
|
-
3. **低危补测即可**:P-10~P-16 已有 ready 测试代码/pin,随手修。
|
|
189
|
-
4. **立即 bookkeeping**:P-17——补 release-cut + CHANGELOG + CI 版本一致性 guard(已加 pin 测试)。
|