Skip to content

Commit 2cf7679

Browse files
KonghaYaodeepseek-v4-pro
andcommitted
chore: archive 16 resolved issues, update domain knowledge and index
- Archive 16 Fixed/Closed/Verify issues to spec/archive-issues/ - Domain updates: agent (+4), system-prompt (+2), compact (+1), tui (+4), mcp (+1) - problems.md: 42 new keyword indexes with dedup logic - CLAUDE.md: update issue links (issue -> domain paths), add 5 new TRAP inline links - SKILL.md: add Verify status support + dedup checks in phases 4/5/6 - Fix: ensure_thinking_blocks always called for DeepSeek compat Co-Authored-By: deepseek-v4-pro <deepseek-ai@claude-code-best.win>
1 parent a74266d commit 2cf7679

26 files changed

Lines changed: 587 additions & 16 deletions

.claude/skills/issue-archive/SKILL.md

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ description: >
2121
| `Fixed`(含 `Fixed + Verify``Fixed(待用户验证)`|| 已修复 |
2222
| `Closed` || 已关闭 |
2323
| `Done` || 已完成 |
24+
| `Verify`(含 `verify`|| 待验证,修复已完成仅需用户确认 |
2425
| `Open``Open (搁置)` || 仍需处理 |
2526
| `Partial``Reopen` || 未完全解决 |
2627

@@ -167,10 +168,11 @@ description: >
167168
168169
对每个领域:
169170
1. Read 对应的 domain 文件(spec/global/domains/<domain>.md)
170-
2. 在文件末尾的「Issue 经验附录」段追加该领域的所有 issue 提炼
171-
3. 如果 domain 文件不存在「Issue 经验附录」段,在「相关 Feature」之前插入该段标题
172-
4. 如果某个 issue 标注"无可提炼认知",跳过
173-
5. 更新文件末尾的「相关 Feature」引用,如有需要
171+
2. **先 Grep 检查是否已存在 `### issue_<filename>` 标题**,存在则跳过(去重)
172+
3. 在文件末尾的「Issue 经验附录」段追加该领域的所有 issue 提炼(仅追加不存在的)
173+
4. 如果 domain 文件不存在「Issue 经验附录」段,在「相关 Feature」之前插入该段标题
174+
5. 如果某个 issue 标注"无可提炼认知",跳过
175+
6. 更新文件末尾的「相关 Feature」引用,如有需要
174176
175177
格式要求:
176178
- 每个 issue 使用三级标题 ### issue_<filename>
@@ -207,6 +209,7 @@ description: >
207209
1. 提取「关键词」字段(逗号分隔)
208210
2. 对每个关键词:
209211
- 在「关键词索引」段查找或创建该关键词的三级标题
212+
- **先 Grep 检查是否已存在对该 issue 的引用(`issue_<filename>`)**,存在则跳过
210213
- 追加条目:`- [<摘要>](domains/<domain>.md#issue_<filename>) — <domain>`
211214
3. 在「更新记录」段追加本次归档记录
212215
```
@@ -238,9 +241,10 @@ description: >
238241
239242
对每个「CLAUDE.md 链接: true」的 issue:
240243
1. Read 当前 CLAUDE.md
241-
2. 在「开发注意事项」段查找相关的 TRAP 或注意事项
242-
3. 在对应条目末尾追加内联链接:`(详见 spec/global/domains/<domain>.md#issue_<filename>)`
243-
4. 如果找不到相关条目,在「开发注意事项」段末尾追加新条目
244+
2. **先 Grep 检查 CLAUDE.md 是否已包含 `#issue_<filename>` 链接**,存在则跳过
245+
3. 在「开发注意事项」段查找相关的 TRAP 或注意事项
246+
4. 在对应条目末尾追加内联链接:`(详见 spec/global/domains/<domain>.md#issue_<filename>)`
247+
5. 如果找不到相关条目,在「开发注意事项」段末尾追加新条目
244248
```
245249

246250
**格式示例**

CLAUDE.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ scripts/start-tui.sh # 启动 TUI(RELAY_PORT=3001)
5656

5757
**[TRAP]** 多工具并发的结果处理循环中,P3/P4 错误路径提前返回会导致后续 tool_result 缺失。必须用 deferred_error 模式——先收集所有错误,循环结束后统一判断。所有 tool_result 必须始终写入 state。(详见 spec/global/domains/agent.md#issue_2026-05-14-orphaned-tool-use-without-tool-result,spec/global/domains/agent.md#issue_2026-05-15-tool-execution-error-stops-agent,spec/global/domains/agent.md#issue_2026-05-18-agent-tool-calls-execute-serially)
5858

59-
**[TRAP]** `prepended_ids` 必须只追踪 `prepend_message` 插入的消息,不能计入 `add_message``before_agent` 中间件有两种注入方式:`prepend_message`(头部 insert System)和 `add_message`(尾部 push Ai/Tool)。cleanup 时只能清理前者。旧逻辑用 `len_after - len_before` 从头部取 N 条 ID,会把 `add_message` 的尾部追加也计入 N,导致从头部误删原始消息,破坏 Ai[ToolUse]/Tool[ToolResult] 配对,产生 Anthropic 400 孤儿 tool_result。正确做法:`take_while(|m| m.is_system())` 只收集头部连续 System 消息。**新增中间件在 `before_agent` 中使用 `add_message` 注入非 System 消息时,不会受 cleanup 影响,但绝不能假设 cleanup 会帮你清理这些消息。**(详见 spec/issues/2026-05-26-skillpreload-anthropic-400-tool-result-orphan.md
59+
**[TRAP]** `prepended_ids` 必须只追踪 `prepend_message` 插入的消息,不能计入 `add_message``before_agent` 中间件有两种注入方式:`prepend_message`(头部 insert System)和 `add_message`(尾部 push Ai/Tool)。cleanup 时只能清理前者。旧逻辑用 `len_after - len_before` 从头部取 N 条 ID,会把 `add_message` 的尾部追加也计入 N,导致从头部误删原始消息,破坏 Ai[ToolUse]/Tool[ToolResult] 配对,产生 Anthropic 400 孤儿 tool_result。正确做法:`take_while(|m| m.is_system())` 只收集头部连续 System 消息。**新增中间件在 `before_agent` 中使用 `add_message` 注入非 System 消息时,不会受 cleanup 影响,但绝不能假设 cleanup 会帮你清理这些消息。**(详见 spec/global/domains/agent.md#issue_2026-05-26-skillpreload-anthropic-400-tool-result-orphan)
6060

6161
**消息类型**`BaseMessage`(Human/Ai/System/Tool),`ContentBlock`(Text/Image/Document/ToolUse/ToolResult/Reasoning/Unknown)。
6262

@@ -70,7 +70,7 @@ scripts/start-tui.sh # 启动 TUI(RELAY_PORT=3001)
7070

7171
**[INFO]** `MessageViewModel` 已不再包含 `message_id` 字段。SubAgentGroup 使用 `instance_id: Option<String>` 标识。新增 VM 变体时注意身份标识字段与显示字段分离。
7272

73-
**[TRAP]** `Interrupted`/`Error` + `Done` 互斥:`Interrupted`/`Error``request_rebuild()` + 添加通知,设 `reconcile_already_done=true`,后续 `Done` 跳过 `request_rebuild()` 防止覆盖通知。(详见 spec/global/domains/agent.md#issue_2026-05-25-interrupt-undo-last-user-message)
73+
**[TRAP]** `Interrupted`/`Error` + `Done` 互斥:`Interrupted`/`Error``request_rebuild()` + 添加通知,设 `reconcile_already_done=true`,后续 `Done` 跳过 `request_rebuild()` 防止覆盖通知。(详见 spec/global/domains/agent.md#issue_2026-05-25-interrupt-undo-last-user-message)**[TRAP]** Cancel 后历史不应无条件截断:ACP server 在 `result.ok==false` 时无条件 truncate history 会丢失 agent 已写入 state 的消息,导致 agent 失忆。应检查 `result.messages.len()` 判断是否有进展,有则保留。(详见 spec/global/domains/agent.md#issue_2026-05-26-ctrl-c-interrupt-causes-agent-amnesia)
7474

7575
**[TRAP]** frozen_subagent_vms:`frozen_subagent_vms: Vec<MessageViewModel>` 按 agent_id + 位置匹配(先 instance_id 精确匹配,失败后按顺序 agent_id 匹配)。轮次作用域状态(frozen_vms、ephemeral_notes)在 `begin_round()` 时显式清空;`done()` 不清空 frozen_subagent_vms(允许 build_tail_vms 在 Done 到下一轮之间消费)。(详见 spec/global/domains/message-pipeline.md#issue_2026-05-16-frozen-subagent-vms-cross-round-accumulation-duplication)
7676

@@ -191,7 +191,7 @@ session/new → chrono::Local::now() → frozen_date
191191
- `DISABLE_COMPACT` / `DISABLE_AUTO_COMPACT` / `COMPACT_THRESHOLD`:每轮读取 env,且被 executor 和 builder **重复读取两次**
192192
- `peri_config`、Provider Snapshot、context_window、context_1m:每轮从 `Arc<RwLock<>>` 克隆快照
193193
- 整个中间件链、AgentState、Cancel Token、Langfuse Tracer:每轮全新构造
194-
- **SubAgent 系统提示词**:调用 `build_system_prompt(None, ...)` 不走 frozen 路径,完全重建
194+
- **SubAgent 系统提示词**:调用 `build_system_prompt(None, ...)` 不走 frozen 路径,完全重建**[TRAP]** 这会导致 SubAgent 使用当前 runtime config 而非 frozen 值(如 language),在同一会话中与 Main Agent 产生漂移。所有 frozen 字段必须通过 `AcpAgentConfig` 传递到 SubAgent builder。(详见 spec/global/domains/system-prompt.md#issue_2026-05-27-language-injection-subagent-drift-cache-isolation)
195195

196196
**核心文件**
197197
| 文件 | 职责 |
@@ -267,7 +267,7 @@ session/new → chrono::Local::now() → frozen_date
267267
| `peri-agent/src/agent/compact/re_inject.rs` | `re_inject()`:重新注入文件/技能上下文 |
268268
| `peri-agent/src/agent/compact/config.rs` | `CompactConfig`:阈值、开关、环境变量覆盖 |
269269
| `peri-agent/src/agent/compact/invariant.rs` | 消息轮次分组(工具调用配对完整性检查) |
270-
| `peri-middlewares/src/compact_middleware.rs` | `CompactMiddleware``before_model` 钩子,在 ReAct 循环内触发 compact |
270+
| `peri-middlewares/src/compact_middleware.rs` | `CompactMiddleware``before_model` 钩子,在 ReAct 循环内触发 compact**[TRAP]** Micro compact 必须加 once-per-prompt 守卫(AtomicBool),否则每轮都重复触发。(详见 spec/global/domains/compact.md#issue_2026-05-23-micro-compact-repeated-triggering) |
271271
| `peri-acp/src/session/executor.rs` | executor 中 compact 触发判断(阈值检查) |
272272
| `peri-tui/src/acp_server/compact.rs` | 手动 compact 入口:`full_compact()` + `re_inject()` |
273273
| `peri-tui/src/command/session/compact.rs` | `/compact` 命令路由 |
@@ -309,7 +309,7 @@ session/new → chrono::Local::now() → frozen_date
309309

310310
`.claude/agents/{agent_id}/agent.md` 定义。`tools` 为空继承父工具(排除 Agent 防递归),有值仅保留允许列表,`disallowedTools` 额外排除。插件 agent 通过 `scan_agents_with_extra_dirs` 追加搜索路径。
311311

312-
**[TRAP]** Background agent 工具完全依赖 `register_tool` 传递,跨 async 边界需确保 Arc 引用生命周期。多语义叠加(fork+background)需明确优先级,跨轮次累积数据(frozen_vms)必须有清理机制。**[TRAP]** Normal/Fork 子 Agent 透传 event_handler 导致事件溢出,StateSnapshot/ContextWarning/LlmRetrying 缺少 in_subagent() 守卫——新增事件类型时必须同步检查所有事件处理路径的守卫。**[TRAP]** 并发 SubAgent 场景:事件路由必须用 `source_agent_id` 精确匹配而非位置堆栈;流式循环必须 `tokio::select!` 竞争取消令牌防止 Ctrl+C 死锁;事件通道容量:主 executor 用 `unbounded_channel()`(无界),`bg_event_tx` 用 `channel(128)`。(详见 spec/global/domains/agent.md#issue_2026-05-12-background-agent-display-and-continuation-bugs,spec/global/domains/agent.md#issue_2026-05-13-sync-subagent-events-leak-to-parent,spec/global/domains/tui.md#issue_2026-05-15-concurrent-subagent-display-delay,spec/global/domains/agent.md#issue_2026-05-16-concurrent-subagent-tool-call-routing-and-background,spec/global/domains/agent.md#issue_2026-05-18-agent-tool-calls-execute-serially,spec/global/domains/agent.md#issue_2026-05-19-concurrent-subagent-duplicate-id,spec/global/domains/agent.md#issue_2026-05-24-concurrent-bg-agent-only-one-completion,spec/global/domains/agent.md#issue_2026-05-26-sync-subagent-cancel-fix-attempts-log)
312+
**[TRAP]** Background agent 工具完全依赖 `register_tool` 传递,跨 async 边界需确保 Arc 引用生命周期。多语义叠加(fork+background)需明确优先级,跨轮次累积数据(frozen_vms)必须有清理机制。**[TRAP]** Normal/Fork 子 Agent 透传 event_handler 导致事件溢出,StateSnapshot/ContextWarning/LlmRetrying 缺少 in_subagent() 守卫——新增事件类型时必须同步检查所有事件处理路径的守卫。**[TRAP]** 并发 SubAgent 场景:事件路由必须用 `source_agent_id` 精确匹配而非位置堆栈;流式循环必须 `tokio::select!` 竞争取消令牌防止 Ctrl+C 死锁;事件通道容量:主 executor 用 `unbounded_channel()`(无界),`bg_event_tx` 用 `channel(128)`。(详见 spec/global/domains/agent.md#issue_2026-05-12-background-agent-display-and-continuation-bugs,spec/global/domains/agent.md#issue_2026-05-13-sync-subagent-events-leak-to-parent,spec/global/domains/tui.md#issue_2026-05-15-concurrent-subagent-display-delay,spec/global/domains/agent.md#issue_2026-05-16-concurrent-subagent-tool-call-routing-and-background,spec/global/domains/agent.md#issue_2026-05-18-agent-tool-calls-execute-serially,spec/global/domains/agent.md#issue_2026-05-19-concurrent-subagent-duplicate-id,spec/global/domains/agent.md#issue_2026-05-24-concurrent-bg-agent-only-one-completion,spec/global/domains/agent.md#issue_2026-05-26-sync-subagent-cancel-fix-attempts-log)**[TRAP]** 同步 SubAgent 取消传播:父 Agent 的 cancel token 必须传播到同步 SubAgent 执行上下文,否则 Ctrl+C 无法中断 SubAgent。(详见 spec/global/domains/agent.md#issue_2026-05-25-ctrl-c-cannot-interrupt-sync-subagent)
313313

314314
## LSP 中间件
315315

@@ -438,3 +438,4 @@ Command trait 的 `description()` 接收 `&LcRegistry` 参数并返回 `String`
438438
- **`app/mod.rs` 模块组织**:使用 `include!` 按功能类别分组声明(`modules_panels.inc`/`modules_agent.inc`/`modules_state.inc`/`modules_system.inc`),每个 `.inc` 文件声明一组相关模块。新增模块按类别加入对应的 `.inc` 文件,避免 `app/mod.rs` 膨胀。
439439
- **`app/edit_utils.rs`**:从 `app/mod.rs` 拆出的文本编辑辅助函数(`build_textarea`/`handle_edit_key`/`ensure_cursor_visible`/`edit_display_parts`),供多面板共用。
440440
- **插件面板拆分**:handler 从 `plugin_panel/handlers.rs` 拆分为 `handlers/plugin_handlers/` 9 个子模块(delete/discover_detail/discover_list/discover_search/install/installed_detail/marketplace/persistence/mod)。渲染从 `panels/plugin.rs` 拆分为 `panels/plugin/mod.rs` + `plugin_render/` 6 个子模块(add_marketplace/detail/discover_detail/discover_list/discover_search/list)。
441+
- **跨平台 spawn [TRAP]**:所有子进程 spawn 必须通过平台感知的统一 wrapper(`shell_command()/spawn_shell()`),Windows 用 `cmd /C`、Unix 用 `bash -c`。三处调用点(MCP transport、Hooks executor、Bash 工具)已统一,新增 spawn 时必须复用。(详见 spec/global/domains/mcp.md#issue_2026-05-27-cross-platform-spawn-wrapper)

0 commit comments

Comments
 (0)