fix(aibox): Batch N 波次1~2——第八轮审计 T 系列速赢与并发正确性修复

波次1 速赢批(7 项):
- T8 ProcessManager watermark 取号与回显记账原子化(entry.lock 改 RLock)
- T9 LLM 非 200 响应抛出前 close,流式路径清 _current_response
- T13 _sanitize_log_msg 增加裸 sk- key 脱敏,异常构造点统一过脱敏
- T12 流式判定改共享 saw_complete 标志(排空后 empty() 恒 False 死逻辑),
  超长截断前移堵住非流式直发绕过 N8 输出预算
- T16/T17 三处 Popen 显式 encoding=utf-8 + errors=replace
- T18 detach/log_file/force 统一过 _coerce_bool(字符串 "false" 误判)

波次2 并发正确性批(6 项):
- T4 registry 输出队列入口快照,不再向共享工具实例传播(跨会话串扰)
- T5 executor 单槽 _current_process 改令牌多槽注册表,_terminate_tree
  显式传 (proc, pgid),finally 只注销自己槽位(防并发误杀进程组)
- T6 FailoverClient 冷却键改 id(client),与 P6 去重键语义一致
- T7 stream_chat 拆普通方法+内部生成器,消除生成器延迟副作用清除取消标志
- T15 工具结果统一 TOOL_MAX_RESULT_LENGTH 截断(两条分支同口径)
- T24 非流式 execute() timeout 下限夹取 1s(该路径无 3600s 兜底)

测试:532 passed / 4 failed(平台环境项)/ 1 skipped,零回归
审计报告补记 §23 第八轮审计 + §24 Batch N 波次1~2 修复记录
This commit is contained in:
qing committed 2026-08-21 17:33:33 +08:00
1 parent 3e860c16e0
commit 5894e64287
8 files changed
+583 -110

No files matched your search

+8 -5
View File
@@ -76,7 +76,7 @@ class _ProcEntry:
self.max_buffer = max(1024, int(buffer_bytes))
self.next_seq = 1
self.evicted = 0
self.lock = threading.Lock()
self.lock = threading.RLock() # T8:可重入,write_input 持锁期间可调用 _record_line
self.reader_done = threading.Event()
self.reader = None
# 交互写入:单写锁保序(bg_write 串行化,防交错输入)
@@ -178,6 +178,8 @@ class ProcessManager:
text=True,
bufsize=1,
universal_newlines=True,
encoding="utf-8", # T17:显式 UTF-8,避免 Windows cp936 解码 UTF-8 输出致 reader 静默退出
errors="replace",
env=exec_env,
cwd=os.path.expanduser(work_dir),
# 对齐 L9:POSIX 下 shell 成为会话首进程,kill 按进程组
@@ -345,12 +347,13 @@ class ProcessManager:
if entry.status != "running":
return {"ok": False, "error": f"进程已结束({entry.status}),无法写入"}
# watermark:回显行将占用的序号(写入前先记账,响应必然在其后)
# watermark:取号与回显行记账必须在同一临界区,保证 watermark 等于
# 回显行真实序号,bg_output(since=watermark) 正确对齐本条响应(T8)
echo = "[stdin] " + text.replace("\n", "⏎")
with entry.lock:
watermark = entry.next_seq
# 回显行进环形缓冲 + log 镜像(多行输入折叠为单行展示)
echo = "[stdin] " + text.replace("\n", "⏎")
self._record_line(entry, echo)
# 回显行进环形缓冲 + log 镜像(多行输入折叠为单行展示)
self._record_line(entry, echo)
# 写入放 watchdog 线程:进程不读 stdin 且管道缓冲(~64KB)写满时
# write() 会阻塞,不能拖死工具线程;超时后 daemon 线程由系统兜底