@sema-ai/core 1.276.0 → 1.277.1

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.
Files changed (147) hide show
  1. package/README.md +2 -5
  2. package/dist/bench/metrics.js +1 -1
  3. package/dist/bench/metrics.js.map +1 -1
  4. package/dist/core/auto-mode.d.ts.map +1 -1
  5. package/dist/core/auto-mode.js +14 -1
  6. package/dist/core/auto-mode.js.map +1 -1
  7. package/dist/core/cache-break-detector.js +0 -0
  8. package/dist/core/cache-break-detector.js.map +1 -1
  9. package/dist/core/task-registry.d.ts +6 -0
  10. package/dist/core/task-registry.d.ts.map +1 -1
  11. package/dist/core/task-registry.js +30 -0
  12. package/dist/core/task-registry.js.map +1 -1
  13. package/dist/tools/fs/index.d.ts.map +1 -1
  14. package/dist/tools/fs/index.js +5 -2
  15. package/dist/tools/fs/index.js.map +1 -1
  16. package/dist/tools/gitea-issue.d.ts +1 -1
  17. package/dist/tools/gitea-issue.d.ts.map +1 -1
  18. package/dist/tools/scheduler-tools.d.ts.map +1 -1
  19. package/dist/tools/scheduler-tools.js +8 -6
  20. package/dist/tools/scheduler-tools.js.map +1 -1
  21. package/package.json +3 -5
  22. package/CHANGELOG.md +0 -5444
  23. package/docs/A1-ATTRIBUTION-ROUND1-2026-07-09.md +0 -181
  24. package/docs/AB-ORACLE-GATE-VERDICT-2026-07-10.md +0 -100
  25. package/docs/ANCHOR-GAP-INVENTORY-2026-07-09.md +0 -143
  26. package/docs/ARCHITECTURE.md +0 -125
  27. package/docs/BUGHUNT-2026-07-05-NIGHT.md +0 -98
  28. package/docs/BUILD.md +0 -63
  29. package/docs/CANCEL-ASYNC-ATTRIBUTION-2026-07-09.md +0 -98
  30. package/docs/CC-198-VS-201-DRIFT-2026-07-09.md +0 -70
  31. package/docs/CC-BASELINE-FAKE-ZERO-AUDIT-2026-07-09.md +0 -51
  32. package/docs/CC-DRIFT-198-206-AGENT-TYPES-2026-07-10.md +0 -82
  33. package/docs/CC-DRIFT-198-206-CHANGELOG-2026-07-10.md +0 -82
  34. package/docs/CC-DRIFT-198-206-REMINDERS-2026-07-10.md +0 -96
  35. package/docs/CC-DRIFT-198-206-ROADMAP-2026-07-10.md +0 -110
  36. package/docs/CC-DRIFT-198-206-TOOL-INVENTORY-2026-07-10.md +0 -53
  37. package/docs/CC-DRIFT-198-206-USAGE-CONSTANTS-2026-07-10.md +0 -64
  38. package/docs/CC-DRIFT-198-206-WORKFLOW-2026-07-10.md +0 -83
  39. package/docs/CC-PARITY-CHECKLIST.md +0 -220
  40. package/docs/CC-PARITY-DEEP-SWEEP-2026-07-07.md +0 -149
  41. package/docs/CC-SUBAGENT-PROMPT-STUDY-2026-07-09.md +0 -219
  42. package/docs/CC-TASK-REMINDER-CADENCE-STUDY-2026-07-09.md +0 -396
  43. package/docs/CC-TOOL-PARITY-SWEEP-2026-07.md +0 -56
  44. package/docs/CC-TOOL-PROMPT-DEEP-DIFF-2026-07-08.md +0 -274
  45. package/docs/CC-TOOLSURFACE-DEEP-DIVE-2026-07-07.md +0 -197
  46. package/docs/CC206-OBSERVER-ANCHORS-2026-07-11.md +0 -463
  47. package/docs/CC207-CORE-SWEEP-BACKLOG-2026-07-12.md +0 -155
  48. package/docs/CENTER-CONTROL-PLANE-SEAM.md +0 -86
  49. package/docs/CLEANUP-CONTRACT-ANCHOR-2026-07-09.md +0 -83
  50. package/docs/COLD-START-RSI-2026-07-09.md +0 -72
  51. package/docs/COMPACTION-LIVE-AUDIT-2026-07-09.md +0 -114
  52. package/docs/CONTEXT-lifecycle-extension-points-and-stop-attribution.md +0 -71
  53. package/docs/COREWARS-POLYGLOT-TRIAGE-2026-07-09.md +0 -85
  54. package/docs/DEADTARGET-OVERFULL-HBOX-2026-07-10.md +0 -92
  55. package/docs/DEADTARGET-PATH-TRACING-REVERSE-2026-07-10.md +0 -87
  56. package/docs/DEADTARGET-WINNING-AVG-COREWARS-2026-07-10.md +0 -96
  57. package/docs/DEEPSEEK-API-LIMITS-PROBE-2026-07-09.md +0 -118
  58. package/docs/DESIGN-140-MOCK-VERIFY-2026-07-11.md +0 -79
  59. package/docs/DESIGN-140-VERIFICATION-2026-07-11.md +0 -43
  60. package/docs/DESIGN-DRAFT-workflow-collab-2026-07-11.md +0 -56
  61. package/docs/DESIGN-ORACLE-GROUNDING-GATE-2026-07-10.md +0 -167
  62. package/docs/DESIGN-TFRAG-RECONCILE-SCAFFOLD-2026-07-09.md +0 -102
  63. package/docs/EXP-PA2-PE-DESIGN-2026-07-11.md +0 -220
  64. package/docs/EXT-DOGFOOD-2026-07-12.md +0 -50
  65. package/docs/FINAL-VERIFY-SURFACE-AUDIT-2026-07-09.md +0 -44
  66. package/docs/FRAG-RECON-INVESTIGATION-2026-07-09.md +0 -183
  67. package/docs/HANDOFF.md +0 -121
  68. package/docs/KNOWN-ISSUES.md +0 -96
  69. package/docs/LEGW-WINDOW-TAX-2026-07-10.md +0 -82
  70. package/docs/LIVE-PROBE-BATCH-2026-07-11.md +0 -207
  71. package/docs/M2-CERT-ATTRIBUTION-2026-07-10.md +0 -61
  72. package/docs/M25-LEG-VARIANCE-ATTRIBUTION-2026-07-10.md +0 -81
  73. package/docs/MAILMAN-TIMEOUT-ATTRIBUTION-2026-07-10.md +0 -88
  74. package/docs/MEMORY-BACKEND-DIALECT-NOTES.md +0 -69
  75. package/docs/MTEB-ESCAPE-HATCH-ATTRIBUTION-2026-07-09.md +0 -57
  76. package/docs/MTEB-LEADERBOARD-ATTRIBUTION-2026-07-10.md +0 -134
  77. package/docs/ORACLE-GATE-NEGATIVE-SAMPLE-2026-07-11.md +0 -28
  78. package/docs/PARITY-CONTEXT-TRANSACTIONS-2026-07-10.md +0 -67
  79. package/docs/PARITY-PROGRESS-MATRIX-2026-07-10.md +0 -37
  80. package/docs/PARITY-SPOT-AGENT-TYPES-2026-07-10.md +0 -70
  81. package/docs/PARITY-SPOT-REMINDERS-2026-07-10.md +0 -144
  82. package/docs/PARITY-SPOT-TOOL-INVENTORY-2026-07-10.md +0 -61
  83. package/docs/PARITY-SPOT-USAGE-CONSTANTS-2026-07-10.md +0 -95
  84. package/docs/PARITY-SPOT-WORKFLOW-2026-07-10.md +0 -93
  85. package/docs/PASSWORD-RECOVERY-PANEL-VERDICT-2026-07-10.md +0 -62
  86. package/docs/R8-R9-FINALIZE-COORDINATION-2026-07-09.md +0 -124
  87. package/docs/REPL-CODE-MODE-EVALUATION-2026-07-10.md +0 -187
  88. package/docs/REPORT-1249-TARGETED.md +0 -48
  89. package/docs/RESEARCH-3P-MEMORY-SWAP-2026-07-12.md +0 -273
  90. package/docs/ROADMAP.md +0 -111
  91. package/docs/RSI-CLOUD-DEPLOY-2026-07-06.md +0 -289
  92. package/docs/RSI-PROCESS-AI-COLDSTART-2026-07-11.md +0 -68
  93. package/docs/S18-THOROUGHNESS-AUDIT-2026-07-09.md +0 -113
  94. package/docs/SERVICE-INTEGRATION-GUIDE.md +0 -298
  95. package/docs/SUBAGENT-STREAM-RESILIENCE-PARITY-2026-07-10.md +0 -118
  96. package/docs/SWEBENCH-PRO-RECON-2026-07-11.md +0 -31
  97. package/docs/TB-EFFICIENCY-TELEMETRY-2026-07-08.md +0 -114
  98. package/docs/TB-FAILURE-AUTOPSY-2026-07-05-RERUN.md +0 -67
  99. package/docs/TB-FAIRNESS-AUDIT-2026-07-08.md +0 -141
  100. package/docs/TB-FULL-1257-2026-07-08.md +0 -77
  101. package/docs/TB-LEG-GAP-ATTRIBUTION-1261-1263-2026-07-11.md +0 -154
  102. package/docs/TB-REGRESSION-DAEMON-KILL-2026-07-08.md +0 -58
  103. package/docs/TB-RSI-CROSSCHECK-2026-07-06.md +0 -68
  104. package/docs/TB-RSI-LEDGER.md +0 -30
  105. package/docs/TB-STABLE-SET-2026-07-08.md +0 -127
  106. package/docs/TB21-RECON-2026-07-11.md +0 -28
  107. package/docs/TEST-DESIGN-BATCH-1-2-3.md +0 -97
  108. package/docs/THIRD-PARTY-INTEGRATION.md +0 -45
  109. package/docs/TOKEN-ESTIMATE-CALIBRATION-LIVE-2026-07-09.md +0 -102
  110. 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
  111. package/docs/audit-2026-06-10-/350/256/241/347/256/227bug/346/211/253/346/217/217.md +0 -163
  112. 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
  113. 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
  114. 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
  115. package/docs/audit-2026-06-15/ADDENDUM-second-pass.md +0 -88
  116. package/docs/audit-2026-06-15/ARCHITECTURE-AND-ROADMAP.md +0 -187
  117. package/docs/audit-2026-06-15/DOC-CORRECTIONS.md +0 -105
  118. package/docs/audit-2026-06-15/INDEX.md +0 -49
  119. package/docs/audit-2026-06-15/ORCHESTRATION-STATUS.md +0 -98
  120. package/docs/audit-2026-06-15/PRODUCTION-ISSUES.md +0 -189
  121. package/docs/audit-2026-06-15/REFERENCES-literature.md +0 -139
  122. package/docs/audit-2026-06-15/VENDOR-REFACTOR-PLAN.md +0 -96
  123. package/docs/cc-probe-198/README.md +0 -72
  124. package/docs/cc-probe-198/STABILITY-AUDIT.md +0 -118
  125. package/docs/cc-probe-198/live-schema-monitor-worktree-2026-07-09.json +0 -56
  126. package/docs/cc-probe-198/mount-variants.json +0 -536
  127. package/docs/cc-probe-198/plan-mode-run.json +0 -1
  128. package/docs/cc-probe-198/probe-bash-bg.json +0 -224
  129. package/docs/cc-probe-198/probe-edit-mismatch.json +0 -120
  130. package/docs/cc-probe-198/probe-read-missing.json +0 -62
  131. package/docs/cc-probe-198/probe-search-empty.json +0 -127
  132. package/docs/cc-probe-198/probe-task-family.json +0 -227
  133. package/docs/cc-probe-198/probes.status +0 -6
  134. package/docs/cc-probe-198/raw-capture-interactive.json +0 -948
  135. package/docs/cc-probe-198/raw-capture-print.json +0 -787
  136. package/docs/cc-probe-198/raw-capture2-interactive.json +0 -948
  137. package/docs/cc-probe-198/raw-capture2-print.json +0 -787
  138. package/docs/cc-probe-198/system-prompt.txt +0 -135
  139. package/docs/cc-probe-198/tools-array.json +0 -962
  140. package/docs/durability-boundary.md +0 -63
  141. 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
  142. 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
  143. package/docs/parity-sweep/REPORT-DYNAMIC.md +0 -97
  144. package/docs/parity-sweep/REPORT-STATIC-GGB.md +0 -127
  145. package/docs/parity-sweep/REPORT-STATIC-RWE.md +0 -133
  146. package/docs/vendor-history.md +0 -385
  147. package/docs/vendored-upstream-diff-2026-07.md +0 -83
@@ -1,396 +0,0 @@
1
- # CC 2.1.198 任务清单 system-reminder 周期性注入机制 — 源码考据档
2
-
3
- > **腿性质**:CC 考据腿(证据收集,不落码)。本档 = 二手证据。
4
- > **落码前须过锚核腿(独立核 198 源)+ 落码后对 CC 本体探针对比**([[feedback-cc-anchor-cross-verify-probe-constitution]])。
5
- > **前科警示**:directive-prefix 案曾因转录错标签导致落码错 → 本档转录务求逐字忠实,宁多贴原文。
6
-
7
- ---
8
-
9
- ## §0 锚源口径与结论一句话
10
-
11
- **唯一一手锚源**:`/Users/clay/开发/gittea/claude-198/cc-2.1.198/package/claude-cli-2.1.198.pretty.js`(26.4MB)。下述行号全部指向此文件。
12
-
13
- **结论一句话**:CC 198 的「任务清单 nudge」是一条 **turn-boundary attachment**,判定式 =「距上次 TaskCreate/TaskUpdate(或 TodoWrite)≥10 个 assistant 轮 **且** 距上次同类 reminder ≥10 轮」(两个门都是 10,常量 `RXt={TURNS_SINCE_WRITE:10,TURNS_BETWEEN_REMINDERS:10}`,pretty.js:480563);它以 `role:"user"` 的 **isMeta 消息**注入,内容被 `<system-reminder>\n…\n</system-reminder>` 包裹;**默认走 task_reminder 分支(TaskCreate/TaskUpdate),仅在 `CLAUDE_CODE_ENABLE_TASKS` 显式关掉时才退回 todo_reminder(TodoWrite)分支**;有全局 kill-switch(`CLAUDE_CODE_TODO_REMINDER_MODE` / `tengu_soft_slate_nudge` gate,值 `off` → 完全不发)。**sema 已实现该机制且文案逐字对齐**,主要差:sema 无「off 模式 kill-switch」、无跨 reminder 同轮去重、无 stale-list 专门变体(CC 也没有 stale 专门变体——见 §1 澄清)。
14
-
15
- **重要澄清(纠正任务背景的一处措辞)**:CC 198 里**没有**独立的「stale 清单」文案变体。「stale」只是**基础文案里的一句话**(「Also consider cleaning up the task list if it has become stale」),不是一个条件分支。真正的条件分支只有两个维度:①**任务系统模式**(task_reminder vs todo_reminder,由 `iv()` 决定)②**清单是否为空**(空 → 只发 base 文案;非空 → base 文案 + 动态渲染的当前清单)。
16
-
17
- ---
18
-
19
- ## §1 文案逐字锚(行号)
20
-
21
- reminder 文案在**渲染分发函数**里生成(attachment.type → 文案),锚在 pretty.js:598962–598986(`case "todo_reminder"` / `case "task_reminder"`)。
22
-
23
- ### 1a. todo_reminder(TodoWrite 分支)—— pretty.js:598962–598973
24
-
25
- ```js
26
- case "todo_reminder": {
27
- let n = e.content.map((o, s) => `${s + 1}. [${o.status}] ${o.content}`).join(`
28
- `),
29
- r = `The TodoWrite tool hasn't been used recently. If you're working on tasks that would benefit from tracking progress, consider using the TodoWrite tool to track progress. Also consider cleaning up the todo list if has become stale and no longer matches what you are working on. Only use it if it's relevant to the current work. This is just a gentle reminder - ignore if not applicable.
30
- `;
31
- if (n.length > 0)
32
- r += `
33
-
34
- Here are the existing contents of your todo list:
35
-
36
- [${n}]`;
37
- return Cp([In({ content: r, isMeta: !0 })]);
38
- }
39
- ```
40
-
41
- - **base 文案逐字**(注意原文 "if has become stale" 缺 "it",CC 原样如此,勿修):
42
- > `The TodoWrite tool hasn't been used recently. If you're working on tasks that would benefit from tracking progress, consider using the TodoWrite tool to track progress. Also consider cleaning up the todo list if has become stale and no longer matches what you are working on. Only use it if it's relevant to the current work. This is just a gentle reminder - ignore if not applicable.\n`
43
- - **非空清单追加段**:`\n\nHere are the existing contents of your todo list:\n\n[${n}]`(整个清单被方括号 `[ ]` 包裹)。
44
- - **清单单项形状**:`${i+1}. [${status}] ${content}`(1-based 序号)。
45
-
46
- ### 1b. task_reminder(TaskCreate/TaskUpdate 分支,**默认分支**)—— pretty.js:598975–598986
47
-
48
- ```js
49
- case "task_reminder": {
50
- if (!iv()) return [];
51
- let n = e.content.map((o) => `#${o.id}. [${o.status}] ${o.subject}`).join(`
52
- `),
53
- r = `The task tools haven't been used recently. If you're working on tasks that would benefit from tracking progress, consider using ${bD} to add new tasks and ${hF} to update task status (set to in_progress when starting, completed when done). Also consider cleaning up the task list if it has become stale. Only use these if relevant to the current work. This is just a gentle reminder - ignore if not applicable.
54
- `;
55
- if (n.length > 0)
56
- r += `
57
-
58
- Here are the existing tasks:
59
-
60
- ${n}`;
61
- return Cp([In({ content: r, isMeta: !0 })]);
62
- }
63
- ```
64
-
65
- - **模板占位符**:`${bD}` = `"TaskCreate"`(pretty.js:224235),`${hF}` = `"TaskUpdate"`(pretty.js:224237)。解析后 base 文案逐字:
66
- > `The task tools haven't been used recently. If you're working on tasks that would benefit from tracking progress, consider using TaskCreate to add new tasks and TaskUpdate to update task status (set to in_progress when starting, completed when done). Also consider cleaning up the task list if it has become stale. Only use these if relevant to the current work. This is just a gentle reminder - ignore if not applicable.\n`
67
- - **非空清单追加段**:`\n\nHere are the existing tasks:\n\n${n}`(**无**方括号包裹,与 todo 分支不同)。
68
- - **单项形状**:`#${id}. [${status}] ${subject}`(`#` 前缀 + 任务 id;字段名是 `subject` 不是 `content`)。
69
- - **二次 `iv()` 门**:渲染函数开头 `if (!iv()) return []` —— 即使 attachment 排到了,若 task 模式未启用仍返回空(双重保险)。
70
-
71
- ### 1c. `<system-reminder>` 外壳(注入形状)
72
-
73
- - 渲染出的原始文本 `r` 经 `Cp([In({content:r,isMeta:!0})])` 包装。
74
- - `In(...)`(pretty.js:597139)构造 `{type:"user", message:{role:"user", content:r}, isMeta:true, …}` —— **是一条 role=user 的 isMeta 消息**,不是独立 system 消息。
75
- - `Cp(...)`(pretty.js:598726)对每条消息 content 跑 `_v()`。
76
- - `_v(e)`(pretty.js:598654)= **就是 `<system-reminder>` 外壳**:
77
- ```js
78
- function _v(e) {
79
- return `<system-reminder>
80
- ${e}
81
- </system-reminder>`;
82
- }
83
- ```
84
- 即最终注入形状 = `<system-reminder>\n{文案}\n</system-reminder>`,作为 user turn 的文本内容。
85
-
86
- ---
87
-
88
- ## §2 触发 / 周期 / 位置机制(行号 + 代码摘录)
89
-
90
- ### 2a. 阈值常量 —— pretty.js:480563
91
-
92
- ```js
93
- (RXt = { TURNS_SINCE_WRITE: 10, TURNS_BETWEEN_REMINDERS: 10 });
94
- ```
95
- 导出名 `TODO_REMINDER_CONFIG`(pretty.js:334131 `TODO_REMINDER_CONFIG: () => RXt`)。两个门都是 **10 个 assistant 轮**。
96
-
97
- ### 2b. 计数器(倒扫 transcript)—— todo 版 `BFm` pretty.js:480205 / task 版 `qFm` pretty.js:480241
98
-
99
- 两函数结构相同,从消息尾向前扫:
100
- - `turnsSinceLastTodoWrite`/`turnsSinceLastTaskManagement`(变量 `r`):数**多少个 assistant 轮**里没出现过对应工具的 `tool_use`(`_or(i)` 跳过某类 assistant 消息不计)。
101
- - `turnsSinceLastReminder`(变量 `o`):数距上次**已注入的同类 reminder attachment** 有多少 assistant 轮(靠 `i.attachment.type === "todo_reminder"` / `"task_reminder"` 识别)。
102
-
103
- task 版判据(pretty.js:480253–480257):
104
- ```js
105
- i.message.content.some((a) => a.type === "tool_use" && (a.name === bD || a.name === hF))
106
- ```
107
- 即 **TaskCreate 或 TaskUpdate 任一 tool_use** 都算「用过任务工具」→ 复位计数。(注:sema 侧口径更宽,把 TaskGet/TaskList 读也算 engagement——见 §4。CC 这里只认 create/update。)
108
-
109
- todo 版判据(pretty.js:480215):`a.name === "TodoWrite"`。
110
-
111
- ### 2c. 注入判定 —— task 版 `jFm` pretty.js:480264 / todo 版 `$Fm` pretty.js:480226
112
-
113
- **task_reminder 生产者 `jFm`(默认路径):**
114
- ```js
115
- async function jFm(e, t) {
116
- if (!iv()) return [];
117
- if (uor && t.options.tools.some((o) => Tl(o, uor))) return []; // BRIEF_TOOL_NAME 挂载时让路(子代精简模式)
118
- if (!t.options.tools.some((o) => Tl(o, hF))) return []; // TaskUpdate(hF)未挂载 ⇒ 不发
119
- if (!e || e.length === 0) return [];
120
- if (r2o() === "off") return []; // kill-switch
121
- let { turnsSinceLastTaskManagement: n, turnsSinceLastReminder: r } = qFm(e);
122
- if (n >= RXt.TURNS_SINCE_WRITE && r >= RXt.TURNS_BETWEEN_REMINDERS) {
123
- let o = await S4(W2()); // 拉当前任务清单(动态渲染内容)
124
- return [{ type: "task_reminder", content: o, itemCount: o.length }];
125
- }
126
- return [];
127
- }
128
- ```
129
- 门全部满足才产出 `{type:"task_reminder", content:<当前任务列表>}`。**注意 content 是当前实时任务清单**(`await S4(W2())`)—— reminder **动态渲染当前列表内容**,非静态文案。
130
-
131
- **todo_reminder 生产者 `$Fm`(pretty.js:480226):**
132
- ```js
133
- if (!t.options.tools.some((o) => Tl(o, yO))) return []; // yO="TodoWrite" 未挂载 ⇒ 不发
134
- if (uor && t.options.tools.some((o) => Tl(o, uor))) return [];
135
- if (!e || e.length === 0) return [];
136
- if (r2o() === "off") return [];
137
- let { turnsSinceLastTodoWrite: n, turnsSinceLastReminder: r } = BFm(e);
138
- if (n >= RXt.TURNS_SINCE_WRITE && r >= RXt.TURNS_BETWEEN_REMINDERS) {
139
- let o = t.agentId ?? Ht(),
140
- i = t.getAppState().todos[o] ?? []; // 按 agentId 取该 agent 的 todo
141
- return [{ type: "todo_reminder", content: i, itemCount: i.length }];
142
- }
143
- return [];
144
- ```
145
-
146
- ### 2d. 分发(task vs todo 二选一)—— pretty.js:479190
147
-
148
- 在 attachment 收集主循环 `GFl`(pretty.js:479172)内:
149
- ```js
150
- f = (() => {
151
- let T;
152
- return () => (T ??= iv() ? jFm(o, t) : $Fm(o, t));
153
- })(),
154
- ```
155
- `iv()` 为真(默认)→ 走 **task**;为假 → 走 **todo**。二者**互斥,一个 boundary 最多一条**。随后 pretty.js:479218 `ng("todo_reminders", f)` 把该生产者挂进 attachment 流水线(与 `changed_files`/`plan_mode`/`deferred_tools_delta` 等并列)。
156
-
157
- ### 2e. `iv()` 语义(默认 task 分支)—— pretty.js:334131
158
-
159
- ```js
160
- function iv() {
161
- if (Hl(process.env.CLAUDE_CODE_ENABLE_TASKS)) return !1;
162
- return !0;
163
- }
164
- ```
165
- `Hl(e)`(pretty.js:1935):`e===void 0 → false`;值为 `"0"/"false"/"no"/"off"` 之一 → `true`,否则 `false`。
166
- **推论**:`CLAUDE_CODE_ENABLE_TASKS` **未设 或 设为任意真值** → `Hl` 返回 false → `iv()` 返回 **true**(task 模式)。仅当把它显式设成 `0/false/no/off` → `iv()` 返回 false(退回 todo 模式)。**默认 = task 模式**。(变量名有反直觉的反转语义,勿望文生义。)
167
-
168
- ### 2f. kill-switch `r2o()` —— pretty.js:479167
169
-
170
- ```js
171
- function r2o() {
172
- let e = Oe.CLAUDE_CODE_TODO_REMINDER_MODE;
173
- if (e !== void 0) return e;
174
- return nt("tengu_soft_slate_nudge", "baseline") === "off" ? "off" : "baseline";
175
- }
176
- ```
177
- env `CLAUDE_CODE_TODO_REMINDER_MODE` 优先;否则看 gate `tengu_soft_slate_nudge`。返回 `"off"` → §2c 两个生产者都直接 `return []`(整个 nudge 关闭)。
178
-
179
- ### 2g. 跨 reminder 同轮去重 —— pretty.js:480326
180
-
181
- tool_search reminder 生产者 `lUl`(pretty.js:480300)在快产出前调 `c = await n()`(n = §2d 那个 memoized 的 task/todo 生产者),若本轮已有 task/todo reminder 待发,则 `if (c) return i("task_reminder_same_turn")` —— **同一 boundary 不同时发 tool-search 与 task reminder**(让 task reminder 优先)。这是 CC 的跨 reminder 节流,sema 目前无对应(sema 各 attachment 独立收集,§4)。
182
-
183
- ### 2h. 位置 / 节流小结
184
-
185
- - **位置**:注入到 message 流末尾附近,作为 **`role:"user"` 的 isMeta 消息**,文本被 `<system-reminder>` 包裹(§1c)。attachment 由 `GFl` 在 turn boundary 统一生成。
186
- - **周期**:满足「≥10 轮没用任务工具 且 ≥10 轮没发过同类 reminder」时发一次;发后 `turnsSinceLastReminder` 归零,故最快 **每 10 轮一次**,一旦用了任务工具则 `turnsSinceLastWrite` 归零、停发直到再攒够 10 轮闲置。
187
- - **去重**:①同类 reminder 靠 `turnsSinceLastReminder≥10` 自节流;②跨 reminder 靠 §2g 同轮互斥;③task/todo 二选一(§2d)。
188
-
189
- ---
190
-
191
- ## §3 与任务工具的耦合
192
-
193
- | 概念 | CC 198 符号 | 行号 |
194
- |---|---|---|
195
- | Todo 工具名 | `yO = "TodoWrite"` | 224181 |
196
- | Task 创建工具名 | `bD = "TaskCreate"` | 224235 |
197
- | Task 更新工具名 | `hF = "TaskUpdate"` | 224237 |
198
- | 子代精简工具名(让路条件) | `uor = BRIEF_TOOL_NAME` | 480562 |
199
-
200
- 耦合点:
201
- 1. **挂载门**:todo 分支需 `TodoWrite` 挂载(`$Fm`);task 分支需 `TaskUpdate` 挂载(`jFm`)。工具没挂 ⇒ 永不发该分支。
202
- 2. **engagement 复位**:任一 `TaskCreate`/`TaskUpdate` 的 tool_use(task 分支)或 `TodoWrite`(todo 分支)会复位「距上次写」计数(§2b)。CC 这里**不**把 TaskGet/TaskList 读算作 engagement(只认 create/update)。
203
- 3. **动态渲染当前列表**:reminder content 是**实时任务/todo 清单**(task:`await S4(W2())`;todo:`getAppState().todos[agentId]`),空则只发 base 文案,非空则追加渲染(§1)。
204
- 4. **分支选择**:`iv()`(默认 task)决定 task vs todo(§2d/§2e)。CC 198 生产环境默认发的是 **task_reminder**(TaskCreate/TaskUpdate 措辞)。
205
- 5. **工具描述里的强关联文案**:TodoWrite 描述(pretty.js:458960 起)、TaskCreate/TaskUpdate 描述(460763 起)、plan-approval 后的「Start with updating your todo list」(405475)—— 这些是同族 prompt,但与 cadence 判定无耦合(仅语料层)。
206
-
207
- ---
208
-
209
- ## §4 sema 现状对照三档表
210
-
211
- sema 对应实现:`/Users/clay/开发/gittea/ai-agent-core/src/core/runner/turn-attachments.ts`(纯生产层,design/133 §R3),接线在 `src/core/runner/runtask.ts:2415`、bin `src/bin/sema-tb.ts:440`。
212
-
213
- | 维度 | CC 198(锚) | sema 现状 | 档 |
214
- |---|---|---|---|
215
- | 阈值常量 10/10 | `RXt={10,10}`(:480563) | `TODO_REMINDER_CONFIG={TURNS_SINCE_WRITE:10,TURNS_BETWEEN_REMINDERS:10}`(turn-attachments.ts:17) | **有(逐字对齐)** |
216
- | task base 文案 | :598979 | `TASK_REMINDER_BASE`(turn-attachments.ts:391),TaskCreate/TaskUpdate 已内联解析,含 stale 句 | **有(逐字对齐)** |
217
- | todo base 文案 | :598965 | `TODO_REMINDER_BASE`(turn-attachments.ts:387),含 CC 原文 "if has become stale" 缺 it | **有(逐字对齐,连 CC typo 都保留)** |
218
- | task 非空清单段 `Here are the existing tasks:` + `#id. [status] subject` | :598984 | turn-attachments.ts:414–415,同形状(`#${id}. [${status}] ${content}`) | **有** |
219
- | todo 非空清单段 `[...]` 方括号 + `i+1. [status] content` | :598970 | turn-attachments.ts:399–400,同形状含方括号 | **有** |
220
- | `<system-reminder>` 外壳单点包裹 | `_v`(:598654) | 生产层只出 body,steerer 单点加壳(F3,文件头注释 line 11) | **有(等价)** |
221
- | task/todo 二选一(both mounted → task 赢) | `iv()` 分发(:479190) | turn-attachments.ts:283–302,`taskListMounted` 优先(注释「CC isTodoV2 branch」) | **有(等价)** |
222
- | 双门判定(sinceWrite & betweenReminders) | :480234/:480271 | turn-attachments.ts:286–288 / 296–298,双门 | **有** |
223
- | 动态渲染当前清单 | :480272 `await S4(W2())` | ListProjection/taskItems 快照(H4 thin projection,turn-attachments.ts:76–99) | **有(投影而非实时拉取,等价)** |
224
- | engagement 复位口径 | 仅 TaskCreate/TaskUpdate(:480253) | **更宽**:任一 task-family 工具用(含 TaskGet/TaskList 读)都算 engagement(turn-attachments.ts:97–99 注释明说) | **口径差**(sema 更宽松,更少发 reminder) |
225
- | kill-switch off 模式 | `r2o()==="off"`(:479167,env `CLAUDE_CODE_TODO_REMINDER_MODE` / gate `tengu_soft_slate_nudge`) | **无 off-mode 常量**;仅靠 `config.todoReminder` 布尔开关 + env `TB_TODOREMIND=0`(sema-tb.ts:440)整体关 | **口径差 / 缺**(功能上 config=off 可关,但无 CC 那种 mode 值语义) |
226
- | 跨 reminder 同轮去重(task 抢占 tool-search)| :480326 `task_reminder_same_turn` | **无**(sema 各 attachment 独立收集,collectDueAttachments 逐条 push) | **没有**(sema 有 8KB cap 排序但无同轮互斥) |
227
- | `iv()`/`CLAUDE_CODE_ENABLE_TASKS` 反转门 | :334131 | 无该 env;由 `taskListMounted` 布尔直接决定分支 | **口径差**(sema 用挂载态,不读 CC env;行为默认等价=task 优先) |
228
- | stale-list 专门变体 | **无**(stale 仅是 base 文案一句) | 无 | **一致(都没有)** |
229
-
230
- **三档汇总**:
231
- - **有(对齐)**:阈值、双文案逐字、非空清单渲染、外壳、二选一分发、双门、动态清单——**核心机制 sema 已完整实现且逐字对齐**。
232
- - **口径差**:①engagement 复位口径 sema 更宽(TaskGet/TaskList 读也复位,CC 只认 create/update)②无 CC 的 mode 值语义 kill-switch(有等价 config 开关)③分支选择用挂载态而非 `CLAUDE_CODE_ENABLE_TASKS` env。
233
- - **没有**:跨 reminder 同轮去重(§2g `task_reminder_same_turn`)——sema 缺这条互斥。
234
-
235
- ---
236
-
237
- ## §5 落码建议
238
-
239
- > **本档 = 二手证据。以下建议为候选,落码前须过锚核腿(独立核 198 源坐实每条锚)+ 落码后对 CC 本体活体探针对比。**([[feedback-cc-anchor-cross-verify-probe-constitution]])
240
-
241
- 结论:**sema 的核心 nudge 机制已到位且高保真**,本考据未发现「漏了整个机制」——任务背景里说的「注入时机/周期漏掉」实际已在 `turn-attachments.ts` 落地。真正剩下的是三个小口径缺口,按投产影响排序:
242
-
243
- 1. **[评估] engagement 复位口径**(turn-attachments.ts:97–99):sema 把 TaskGet/TaskList 读也算「用过任务工具」→ 复位计数 → 比 CC **更少**发 reminder。CC 只认 TaskCreate/TaskUpdate(:480253)。若目标是「行为 parity」,应收窄成只认 create/update;若目标是「更克制的 nudge」,现状是有意 deviation(注释已记档,勿盲改)。**须探针对比 CC 在「只读了 TaskList 但没 update」场景下是否仍发 reminder**(锚预测:CC 会发,sema 不发)。
244
-
245
- 2. **[评估] 跨 reminder 同轮去重**(缺 §2g `task_reminder_same_turn`):sema 若同时挂了 tool-search reminder 与 task reminder,可能同轮双发。CC 让 task reminder 抢占。落码点在 collectDueAttachments 收集顺序处加同轮互斥(task/todo 在场时抑制 tool-search reminder)。影响面取决于 sema 是否已实现 tool-search reminder——**须先确认 sema 有无 tool_search_usage_reminder,无则本条为 no-op**。
246
-
247
- 3. **[可选] off-mode kill-switch 语义**:CC 有 `CLAUDE_CODE_TODO_REMINDER_MODE` 三态(env / gate `tengu_soft_slate_nudge`)。sema 用 config 布尔 + `TB_TODOREMIND=0` 已能整体关,功能等价,**除非要跨仓配置面 parity 否则可不补**。
248
-
249
- **探针清单(落码后必跑)**:
250
- - P1:构造「≥10 轮无 TaskCreate/TaskUpdate」的对话喂 CC 本体,抓 `<system-reminder>` 出现的确切轮次 + 逐字文案,与 sema 输出 diff。
251
- - P2:让清单非空,验证 CC 的 `Here are the existing tasks:\n\n#id. [status] subject` 渲染逐字(尤其 `#`/无方括号/subject 字段名)与 sema 一致。
252
- - P3:只读 TaskList 不 update,看 CC 是否仍在第 10 轮发 reminder(定 §5.1 口径)。
253
- - P4:验 CC 默认(不设 `CLAUDE_CODE_ENABLE_TASKS`)发的是 task 还是 todo 措辞(锚预测:task)。
254
-
255
- ---
256
-
257
- ## 附:关键行号索引
258
-
259
- | 内容 | pretty.js 行号 |
260
- |---|---|
261
- | todo base 文案 | 598965 |
262
- | task base 文案 | 598979 |
263
- | `Here are the existing tasks:` | 598984 |
264
- | todo 渲染 case | 598962 |
265
- | task 渲染 case | 598975 |
266
- | `_v` system-reminder 外壳 | 598654 |
267
- | `Cp` 外壳应用 | 598726 |
268
- | `In` isMeta user 消息构造 | 597139 |
269
- | 阈值常量 `RXt` 10/10 | 480563 |
270
- | todo 计数器 `BFm` | 480205 |
271
- | task 计数器 `qFm` | 480241 |
272
- | todo 生产者 `$Fm` | 480226 |
273
- | task 生产者 `jFm` | 480264 |
274
- | 分发 task/todo 二选一 | 479190 |
275
- | attachment 主循环 `GFl` + 挂载 | 479172 / 479218 |
276
- | `iv()` 门 | 334131 |
277
- | `Hl()` env 解析 | 1935 |
278
- | `r2o()` kill-switch | 479167 |
279
- | 跨 reminder 同轮去重 | 480326 |
280
- | `TodoWrite` 名 | 224181 |
281
- | `TaskCreate` 名 | 224235 |
282
- | `TaskUpdate` 名 | 224237 |
283
- | `TODO_REMINDER_CONFIG` 导出 | 334131 |
284
-
285
- ---
286
-
287
- ## §6 锚核腿判决(2026-07-10)
288
-
289
- > **腿性质**:宪法锚核腿(独立核转录忠实性,落码前强制闸)。方法 = 当本档不存在,自己从 198 源 + sema src 独立取证,再对比本档转录。全部行号在本次核验中**逐条打开原文核对**(非仅信本档给的坐标)。
290
-
291
- ### 6.1 逐条判决表
292
-
293
- | # | 本档声明 | 独立核实结果 | 判决 |
294
- |---|---|---|---|
295
- | A | 阈值常量 `RXt={TURNS_SINCE_WRITE:10,TURNS_BETWEEN_REMINDERS:10}` @:480563 | :480563 逐字命中;双门在 :480234(todo)/:480271(task) | **PASS** |
296
- | B | todo base 文案(含 "if has become stale" 缺 it 的 CC typo)@:598965 | :598965 逐字命中,typo 属实,CC 原样 | **PASS** |
297
- | C | task base 文案(含 "if it has become stale" 正确)@:598979 + `${bD}=TaskCreate`/`${hF}=TaskUpdate` | :598979 逐字命中;bD=:224235 / hF=:224237 / yO(TodoWrite)=:224181 全命中 | **PASS** |
298
- | D | todo 非空段 `[${n}]` 方括号 + `${i+1}. [status] ${content}` @:598962–598973 | :598962–598973 逐字命中,方括号包裹属实 | **PASS** |
299
- | E | task 非空段 `Here are the existing tasks:` **无**方括号 + `#${id}. [status] ${subject}` @:598975–598986 | :598975–598986 逐字命中,无方括号 + subject 字段名属实 | **PASS** |
300
- | F | `_v` = `<system-reminder>\n{e}\n</system-reminder>` 外壳 @:598654 | :598654–598658 逐字命中 | **PASS** |
301
- | G | `In(...)` = role=user isMeta 消息 @:597139;`Cp` @:598726 | :597139 / :598726 命中(In 是解构签名,isMeta 参数在列) | **PASS** |
302
- | H | 计数器 `BFm`(todo)@:480205 / `qFm`(task)@:480241,倒扫 transcript,双变量 sinceWrite/sinceReminder | :480205–480226 / :480241–480262 结构逐字命中 | **PASS** |
303
- | I | task engagement 复位判据 = `a.name === bD \|\| a.name === hF`(仅 create/update)@:480253 | :480254 逐字命中,**只认 TaskCreate/TaskUpdate**,不认 read | **PASS** |
304
- | J | 生产者 `jFm`(task)@:480264 / `$Fm`(todo)@:480226,含 kill-switch + 挂载门 + 双门 | :480264–480276 / :480228–480240 逐字命中,门序一致 | **PASS** |
305
- | K | 分发 `iv() ? jFm : $Fm` 二选一 @:479190;挂进 `ng("todo_reminders",f)` @:479218 | :479190 / :479218 逐字命中 | **PASS** |
306
- | L | `iv()` @:334131,`Hl()` @:1935,默认=task 模式,反转语义 | :334131–334134 / :1935–1939 逐字命中,反转语义属实 | **PASS** |
307
- | M | kill-switch `r2o()` @:479167,env `CLAUDE_CODE_TODO_REMINDER_MODE` 优先 → gate `tengu_soft_slate_nudge` | :479167–479171 逐字命中,env=:41663/:479168,gate=:479170 | **PASS** |
308
- | N | 跨 reminder 同轮去重 `task_reminder_same_turn` @:480326(tool-search 让位 task)| :480326 命中;wire 在 :479219(`(await f()).length>0` 传入 lUl) | **PASS** |
309
- | O | sema base 文案「逐字对齐」(turn-attachments.ts:386/391) | 独立 diff:sema TODO/TASK_REMINDER_BASE 与 CC **逐字节相同**,连 typo 都保留 | **PASS** |
310
- | P | sema 阈值/双门/二选一/渲染形状对齐(turn-attachments.ts:283–303,394–418)| 独立核:10/10 常量、task 优先分发、`[...]`/`#id` 渲染形状全一致 | **PASS** |
311
- | Q | 口径差①:sema engagement 复位更宽(TaskList 读也复位)| **坐实**:`reduceToolEnd` 在 `d.type==="task-list"`(读)时 set `taskLastWriteTurn`(ts:205),CC `qFm` 只认 create/update(:480254)→ sema 更少发 | **PASS(口径差真实)** |
312
- | R | 口径差②:sema 无 CC mode 值 kill-switch,仅 config 布尔 + `TB_TODOREMIND=0` | **坐实**:sema src 无 `CLAUDE_CODE_TODO_REMINDER_MODE`/`tengu_soft_slate_nudge`;仅 `config.todoReminder` + env(sema-tb.ts:443/447)| **PASS(口径差真实)** |
313
- | S | 口径差③:sema 无跨 reminder 同轮去重(`task_reminder_same_turn`)| **坐实**:sema src `grep tool_search_usage_reminder / task_reminder_same_turn` = **零命中**,sema 根本无 tool-search reminder → 本条对 sema 是 no-op(本档 §5.2 已正确加此 caveat)| **PASS(口径差真实,且 no-op 判断正确)** |
314
-
315
- ### 6.2 FAIL 条目
316
-
317
- **无转录偏差(FAIL)**。文案、行号坐标、机制逻辑全部经独立核实忠实。所有引用的关键行(常量/文案/生产者/分发/门/外壳)均逐字命中,无一处标签错位或原文篡改。前科(directive-prefix 错标签)未重演。
318
-
319
- ### 6.3 MISSING 条目(本档未覆盖的 CC 口径 —— 锚核腿最有价值产出)
320
-
321
- **MISSING-1(实质口径,建议记档,可能影响 reasoning 模型 cadence):CC 的 turn 计数排除「纯思考轮」,sema 计数不排除。**
322
- - **CC 真值**:`BFm`/`qFm` 倒扫 transcript 时对每个 assistant 消息跑 `_or(i)`(:599513–599517):**若该 assistant 轮的 content 全是 `thinking`/`redacted_thinking`(纯思考、无文本无 tool_use)则 `continue` 跳过,不计入 sinceWrite/sinceReminder 计数**。即 CC 的「轮」= 有实质产出的 assistant 轮,纯思考轮不占额度。
323
- - **sema 现状**:sema 用**单调计数器**模型 —— `onTurnEnd`(runtask.ts:1771)对每个 assistant turn boundary **无条件** `stats.turns += 1`,`inp.turn` 直接取 `stats.turns`。**不区分纯思考轮**。
324
- - **后果**:对会产出纯思考轮的推理模型(sema 主打面),sema 计数器比 CC 推进快 → sema 可能**比 CC 更早**触发 reminder(同样 10 轮,但 sema 的 10 轮里可能含若干 CC 会跳过的纯思考轮)。这是与本档三口径**正交**的第四个 cadence 偏差,本档 §2b 仅一句「`_or(i)` 跳过某类 assistant 消息不计」带过,**未点明是纯思考轮、未对照 sema 是否复刻、未评估对推理模型的 cadence 影响**。
325
- - **修法建议**:若要 parity,sema 需在计数侧排除纯思考轮(判据:该轮无 text/tool_use content),或在 attachment 计数上引入等价 `_or` 过滤。**须探针**:构造含多个纯思考轮的对话喂 CC 本体,数它到第几个「物理轮」才发 reminder,与 sema 同输入 diff。
326
-
327
- ### 6.4 三口径修法与 198 真值一致性核对
328
-
329
- | 口径 | 本档 §5 修法描述 | 与 198 真值一致? |
330
- |---|---|---|
331
- | ①engagement 复位收窄 | 「收窄成只认 create/update」(对齐 :480254)| **一致**。CC :480254 判据确为 `bD\|\|hF`,收窄方向正确。锚预测「CC 只读 TaskList 仍发 reminder / sema 不发」与代码一致(CC 读不复位,sema 读复位)。 |
332
- | ②跨 reminder 同轮去重 | 「collectDueAttachments 收集顺序处加同轮互斥,task 抢占 tool-search」+ caveat「sema 无 tool-search reminder 则 no-op」 | **一致**。CC :480326 确为 tool-search 让位 task;caveat 正确(sema 无 tool-search reminder,本次核实零命中)。落码时机 = 待 sema 建 tool-search reminder 后。 |
333
- | ③off-mode kill-switch | 「CC 三态 mode(env/gate),sema config 布尔功能等价,除非跨仓配置面 parity 否则可不补」| **一致**。CC :479167 确为 env→gate 两级返回 mode 字符串;sema config 布尔功能上能整体关,语义档次差但功能等价判断成立。 |
334
-
335
- ### 6.5 总判决
336
-
337
- **✅ 可落码(附一处 MISSING 需补记)。**
338
-
339
- - 本档转录**零 FAIL**:文案逐字、行号坐标、机制逻辑全部经独立 198 核验忠实,前科未重演。
340
- - 三小口径缺口(engagement 收窄 / 同轮去重 / off-mode)描述与 198 真值**逐条一致**,修法方向正确,§5.2/§5.3 的 caveat 均准确。
341
- - **唯一需补**:MISSING-1(纯思考轮计数差)—— 这是本档漏掉的**第四个 cadence 口径**,对推理模型有实质影响,建议在落码前一并评估(至少记档为 known deviation)。它不推翻本档任何结论,但补齐了「已逐字对齐」的完整边界:**文案与判定式对齐,但「轮」的定义 sema≠CC(sema 含纯思考轮,CC 不含)**。
342
- - 一处**微瑕(非 FAIL,不影响落码)**:附录/§2a/§2e 把 `TODO_REMINDER_CONFIG` 导出行标为 334131,实际导出在 **:479163**(`TODO_REMINDER_CONFIG: () => RXt`);334131 是 `iv()` 的行(被混标)。常量值 10/10 的真源 :480563 无误,不影响任何判定。建议顺手订正坐标。
343
-
344
- — 锚核腿 agent,2026-07-10
345
-
346
- ---
347
-
348
- ## §7 计数单位口径修正:轮 → content block(2026-07-10 对抗复审逮到,二次锚核坐实)
349
-
350
- > **性质**:task#51 落码批(commit 3f4a314)的对抗复审(find→verify,16 agent)确认了一个本档 §2/§6 全程漏掉的**第五口径**:cadence 的计数单位。本节由落码 agent 二次独立锚核后追加;原 §6 锚核腿 19/19 PASS 的判决**漏了此项**(它核的是转录忠实性——转录本身没错,错在「轮」这个词的所指从未被核过)。
351
-
352
- ### 7.1 CC 真值:计数单位 = 逐非思考 content block 的 assistant transcript 条目
353
-
354
- 二次锚核证据链(全部行号逐条打开原文核对):
355
-
356
- 1. **流式铸条**:`content_block_stop`(:593011–593038)对**每个 content block** 单独构造一条 `{type:"assistant", message:{...Xr, content: pnn([Pr],…)}}`(单块数组)并 `rn.push(Fs)`——一个 `[thinking, text, tool_use]` 响应在 transcript 里是 **3 条** assistant 条目。
357
- 2. **归一化拆条**:`tgf`(:597284)对任何多块 assistant 消息 `content.map((r,o)=>…content:[r]…)` 拆成逐块条目——非流式路径同样保证逐块形态。
358
- 3. **扫描输入**:attachments 收集输入 = `[...de, ...pe, ...Ae]`(:474057 → `k7e` → `GFl` → `BFm`/`qFm`),即上述逐块条目原样。
359
- 4. **逐条计数**:`BFm`(:480210–480226)/`qFm`(:480246–480262)倒扫,对每条 `type==="assistant"` 且非 `_or` 的条目 `r++`/`o++`;写锚条目先置 `t=s` 再判 `if(t===-1) r++`——**锚块本身不计入 since-write 距离**,锚之后的非思考条目才计。
360
- 5. **`_or` 的真实作用面**(:599513–599517):在单块条目上退化为「该块是否 thinking/redacted_thinking」——**「纯思考整轮」在 API 层几乎不存在**,若按整轮解读,`_or` 近似死码;逐块解读下它是「思考块不占额度」。
361
- 6. **活体证据**:`bench/probes/task51-cadence-live/`(真 CC 2.1.198 二进制 + stub API,wire.jsonl 全请求体):场景 D(`[text, tool_use]×14`)CC 在请求 **#7** 首注 task_reminder + **#12** re-fire——与 block 级模型精确吻合(2 格/轮),轮级模型预测 #11–12;场景 B(`[thinking, tool_use]×10`)两侧 #12 同(思考块零耗的活体证据)。
362
-
363
- **后果量化**:真实会话多块轮为主(text 前导 + 工具调用是常态,并行工具批更甚),10/10 窗口按 block 消耗 ⇒ CC 约 3–5 个物理轮即触发;3f4a314 的轮级时钟让 sema reminder 系统性**晚发/少发 2–3 倍**。两者仅在「每轮恰 1 个非思考 block」的退化转写上等价——恰好是原探针测试全部用例的形态,所以 16 用例全绿仍拦不住。
364
-
365
- ### 7.2 MISSING-1 重新表述
366
-
367
- 原 §6.3 MISSING-1(「CC 的轮计数排除纯思考轮」)的方向正确但单位错了,重新表述为:
368
-
369
- > **CC 的 cadence 计数单位是逐非思考 content block 的 assistant transcript 条目;「纯思考轮不计」只是它在单块退化形态下的投影。** `_or` 是逐条目(=逐块)谓词,不是整轮谓词;`TURNS_SINCE_WRITE`/`TURNS_BETWEEN_REMINDERS` 里的 "TURNS" 是 CC 源码变量命名的历史残留,所指是 transcript 条目数。
370
-
371
- 原 §6.3 的修法建议(「计数侧排除纯思考轮」)与 3f4a314 的落码(轮级布尔 `cadenceTurnHadSubstance`)均建立在轮级单位上,已被本节取代。
372
-
373
- ### 7.3 sema 修正(task#51 复审修批)
374
-
375
- - **F1 时钟**:`cadenceTurns` 改为块级——`advanceCadenceClock`(turn-attachments.ts)在每条 assistant `message_end` 对每个非思考 block +1(非数组 content = `_or` false ⇒ +1;空数组 vacuous 全思考 ⇒ +0),`onTurnEnd` 不再推进时钟,`cadenceTurnHadSubstance` 机构移除。
376
- - **写坐标**:锚 = 写型 tool_use block 的**含块**时钟值(同消息前导 text 已计入时钟、位于锚前不占 since-write 距离;同消息后随兄弟块计入距离;后一个写块赢 = qFm 倒扫取尾),与 :480246–480262 的锚块不计语义精确对齐。
377
- - **F3 发起锚**:窗口复位改在 message 走块时 stamp(`stampWriteAnchor`)——CC 锚 = tool_use 块在 transcript 里**存在**,无执行结果检查 ⇒ 失败/被拦/挂起的写同样复位;投影摄入(`reduceToolEnd`)保持成功-only(失败写无可信 details;CC 的 reminder 正文本来就从权威 store 渲染、不消费工具结果)。
378
- - **F2 别名**:窗口判定先经 alias→canonical 解析(挂载 roster 的 `name`+`aliases` 建表 + `canonicalToolName` 兜底)——CC 无别名层(qFm 裸比较块名),默认部署字节等价,但 sema 的 `findToolByName` 派发面让别名调用的写不复位窗口 = 误发,已闭合。
379
- - **F4 压缩**:两个压缩落地点(置 `postCompactPending` 的同两点)`rebaseCadenceWindows` 把 4 个窗口字段 rebase 到当前时钟——CC 倒扫在压缩后锚全失 = 双窗事实重置。caveat:若未来实现 messagesToKeep 式保留段,近期锚在 CC 会存活,届时需按保留段是否含锚细化。
380
- - **探针**:`test/task-reminder-cadence-probe.test.ts` 真值表按 block 单位全部重推(SimTurn 带 block 结构),新增多块轮判别用例(与轮级时钟互斥的期望值)+ 失败写锚用例 + 压缩交叉用例;全链腿新增 text+tool 双块轮(call 5 vs 轮级 call 10)、别名写、失败写三条判别。活体第二闸 = `bench/probes/task51-cadence-live`(修后 sema 场景 D 应与 CC 逐请求同为 #7/#12)。
381
-
382
- ### 7.4 resume 窗口清零 = known deviation(记档 + backlog)
383
-
384
- **CC 真值**:BFm/qFm 每请求对**全 transcript** 倒扫现算 + reminder 正文从活体 store 渲染(`$Fm` 读 `getAppState().todos`、`jFm` 读 `S4(W2())`,:480234–:480275)⇒ 跨进程重启天然保 cadence 与列表内容。
385
-
386
- **sema 现状**:`AttachmentState` 是 run-local(每腿 `createAttachmentState()` 清零)。durable resume 后:
387
- - **已修(点修,本批 F5)**:resume 批准执行的 TaskCreate/TaskUpdate/TodoWrite 走 `resolvePendingCall` 直接 `tool.execute`,绕过 onToolEnd ⇒ 修前既不 stamp 窗口也不进投影(恢复腿首个 task_reminder 的列表里恰恰没有人刚批准的任务)。现经 `onResolvedToolSuccess` 回调把 `res.details` 喂进新腿 attachState(投影)+ 按腿内时钟 stamp 窗口(resume 时钟 = 0,窗口从该写起算,CC-faithful)。
388
- - **未修(known deviation + backlog)**:pre-suspend 的写与已发 reminder 在恢复腿被遗忘——窗口从 0 重跑(挂起前 1 轮刚写过也要再攒 10 有效格;前腿已 due 的 reminder 推迟满 10 格)+ 投影内容不重建(下一次 reminder 列表从空/resume 写起步)。**修法(backlog)**:CC-faithful 的 transcript 重播种——resume 时倒扫 `prepared.session.getBranch()` 找最后一条携带写型 toolCall block 的 assistant 消息与最后一条 reminder 正文(header 匹配,同 agentListing MED-3② 种子技法),按腿内 block 坐标播种 `taskLastWriteTurn`/`lastReminderTurn`,投影从最后一张 task/task-list toolResult details 重建。本批判定为大修不做(方向 = sema 少发一条 + 列表短暂失忆,有界;与 agentListing 的保守种子同类权衡),记档待批。
389
-
390
- ### 7.5 顺手勘误(复审 LOW 尾单)
391
-
392
- - 本档 §2c/附录若干处引 r2o 第二消费点 `:480268`,实际 `if (r2o() === "off") return []` 在 **:480269**(:480268 是 jFm 的挂载门行)——纯行号勘误,不影响任何判定。
393
- - 附录「`TODO_REMINDER_CONFIG` 导出 = 334131」系 §6.5 已指出的混标(实际 :479163),此处再次确认待订正。
394
- - 复审另确认两条先于 3f4a314 的 parity 缝,不属本批修面、记档待批:①task lane 挂载门 sema 用 TaskCreate(runtask),CC jFm 用 `hF`=TaskUpdate(:480269)——部分族挂载(tool-filter 只放行其一)时行为分叉;②resume 重放路径 tool_start/tool_end 事件携带 `pendingAction.toolName` 原文(可能是 pre-rename 旧名,F5 回调已 canonical 化,事件面未动)。
395
-
396
- — 落码 agent(fable),2026-07-10,task#51 复审修批
@@ -1,56 +0,0 @@
1
- # CC 工具面系统 diff 横扫(2026-07-07,clay 拍:对新版 CC、不拍脑袋)
2
-
3
- 起因:TOC 现场 UTF-16 案(clay 朋友,CC 能"强行"读/改 UTF-16 而我们拒读)。三路并行取证,原始报告在 `docs/parity-sweep/`:
4
-
5
- - **动态腿(主 ground truth)**:本机 CC **2.1.187** headless `--output-format stream-json` 采**原始 tool_use/tool_result 帧**(不信模型转述)vs sema **1.246.0** 工具直调;8 文件套件(UTF-16LE±BOM/UTF-16BE/UTF-8+BOM/CRLF/latin-1/伪装 PNG/空),每写场景前后 hexdump 落盘字节。→ `REPORT-DYNAMIC.md`
6
- - **静态腿 A**(Read/Edit/Write 机制):CC 88 可读源逐行 + 2.1.201 `sdk-tools.d.ts` schema 佐证。→ `REPORT-STATIC-RWE.md`
7
- - **静态腿 B**(Grep/Glob/Bash/NotebookEdit):同素材。→ `REPORT-STATIC-GGB.md`
8
-
9
- ⚠️ **方法论情报(记档)**:CC 自 2.x 起发行物是 **Bun 编译原生二进制**(2.1.201 = 216MB Mach-O),无 minified cli.js 可读。今后 CC 行为对照:88 可读源=机制定位,`sdk-tools.d.ts`=参数面,**动态实测=唯一的新版行为 ground truth**。
10
-
11
- ## 一、UTF-16 案定谳(动态铁证,修正初判)
12
-
13
- | 面 | CC 2.1.187 实测 | sema 1.246.0 实测 |
14
- |---|---|---|
15
- | Read UTF-16/latin-1/二进制 | **无任何防线**:乱码/NUL/U+FFFD 直接进模型上下文,`is_error` 恒空 | 内容嗅探全部显式拒读 |
16
- | Edit UTF-16LE **带 BOM** | **编码感知无损往返**(BOM 检测→utf16le 解码→匹配→原编码+BOM 回写,hexdump 铁证)——Read 与 Edit 不同层! | Read 拒 → inv1 挡,改不了 |
17
- | Edit UTF-16 **无 BOM** | not-found 失败(检测只认 BOM),零损坏 | 同样改不了(结果一致) |
18
- | Write 覆盖 UTF-16LE+BOM | 半保真:**保编码、丢 BOM** | **死锁**:read-first 永不满足 → 永不能覆盖 |
19
- | Read UTF-8+BOM / CRLF | 剥 BOM、归一 `\n`(呈现层) | 原样呈现(U+FEFF/`\r` 直出) |
20
- | Edit CRLF 单行 | 保 CRLF 落盘 | **字节级一致**(E3 两侧 hexdump 相同) |
21
-
22
- **判决**:
23
- 1. 上下文卫生我们严格更优(CC 的乱码硬读是真风险,不学)。
24
- 2. **CC 的编码感知 Edit/Write(BOM 档)是真 parity 缺口**——我们抄 88 时只挖到 `isBinaryContent` 函数,没挖到 `fileRead.ts` 编码层,且把 sniff 接在了 Read 上(CC 本尊没接)= "抄了函数、漏了接线语境"类暗漂移。
25
- 3. **我们独有的 Write 死锁面**是本轮唯一指向我们的功能性 bug 类:Read 永拒 ⇒ 模型无法用 Write 修复坏编码文件(只剩 bash)。
26
- 4. CRLF:单行 Edit 已等价;**多行 old_string 在 CRLF 仓上我们必 not-found**(CC 匹配前归一 `\r\n→\n`、回写保留原行尾;我们零 `\r` 处理)——静态腿 A 判定的最高频真缺口,动态 E3 单行案例测不到它。
27
-
28
- ## 二、分级清单
29
-
30
- ### P0 → 编码 parity 批(1.247.0,立即做)
31
- 1. **BOM 检测**(`FF FE`→utf16le;`EF BB BF`→utf8)+ **Edit/Write 原编码回写**——带 BOM UTF-16LE 无损往返(CC 同款);我们**保 BOM**(CC 丢 BOM 是它的 bug 面,有意优于并记档)。
32
- 2. **Read 呈现归一**:剥 BOM(U+FEFF)+ CRLF 归一 `\n`(与 CC 一致;也是 3 的前提——模型从 Read 输出复制的 old_string 才能匹配)。
33
- 3. **Edit CRLF 归一匹配 + 回写保留原行尾**(检测 endings)——CRLF 仓多行编辑的必挂根治。
34
- 4. **sniff 收窄**:BOM 检出的合法编码不再触发 NUL 拒;无 BOM UTF-16/latin-1/真二进制**保持拒读**(比 CC 严是有意的:动态腿证明 CC 那档是乱码进上下文),错误文案升级(报「可能是 UTF-16 无 BOM/latin-1,用 `iconv` 转换或 bash 处理」)。
35
- 5. **Write 死锁面**:编码批后 BOM 档可读(死锁面缩小);剩余拒读类文件的 Write 拒绝文案加逃生说明(bash rm/iconv),不开盲覆盖(保守)。
36
- 6. Grep 文档 bug:描述 "default 200" → 实际 250(一行)。
37
-
38
- ### P1 → 下一 parity 小件批(横扫 backlog,可与其他批拼车)
39
- - ENOENT 纠错建议(CC "Did you mean Y?" 高频自愈路径)· Edit-as-create(`old_string:""` 建文件)· 删行连尾 `\n` · curly-quote 归一匹配(静态 A)
40
- - Grep `-o`(2.1.201 新参)· Grep glob 逗号拆分 · rg 路径 `--max-columns 500` · Glob 绝对路径 pattern 拆解 · Bash exit code 语义注记(grep 1=无匹配)· Bash 图片输出 ·(Bash sleep 阻断=绑定 Monitor 缺席,搁)(静态 B)
41
- - 2.1.201 行为线索(需后续动态验证):Read 超 token 闸**自动分页**(`truncatedByTokenCap`,88/我们=硬错)· `file_unchanged.source:"seeded"`
42
-
43
- ### P2 → 动态重议(拿数据再拍)
44
- - Grep/Glob **literal-vs-regex 默认**(design/115 KEEP-OWN 的最大静默行为差;建议量「CC-trained 模型发 regex 语法 pattern 的频率」)
45
- - Grep files 模式 / Glob 的 **mtime 排序**(活跃文件优先对 agent 有真实信息量)
46
-
47
- ### 有意分歧(维持,记档)
48
- - isBinaryContent 接 Read(上下文卫生)· Grep 默认 literal + output_mode=content · Glob 过滤哲学(gitignore vs CC 全搜+100 上限)· Bash 截断(头尾 20k vs CC 头 30k+persisted-output)· stdout/stderr 分流+恒显 exit code · staleness 用全文 hash(**强于** CC mtime+LRU content)· Read 部分读 2000 行真闸(CC 88 文案实化——其代码无默认限,只有 256KB+25K token 闸)· 非原子直写(CC temp+rename;可后议)
49
-
50
- ### 翻案/销案(核实后撤回的传闻)
51
- - ~~CC 单行 2000-char 截断~~(88 全源 0 hit,销案)
52
- - ~~CC Read 有 2000 行默认限~~(只在 prompt 文案,代码 limit=undefined)
53
- - ~~CC Read 有编码检测~~(88→187 实测都没有,detectEncoding 只接 Edit/Write)
54
-
55
- ## 三、质量门(clay 拍)
56
- 编码批交付按:**多角度 codex 复审 + 真实测试**(动态腿脚本复用——同一 8 文件套件对新实现重跑,hexdump 验往返字节;CC 侧数据已归档可比)。