[Init] Initial commit - NetMesh terminal manager
Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled

This commit is contained in:
2026-09-13 18:24:01 +08:00
commit 3c72efcb7f
3255 changed files with 907009 additions and 0 deletions

View File

@@ -0,0 +1,211 @@
# Grok Build 终端上下文工程研究:给 Catty 的对照结论
## 研究范围与结论口径
- Grok Build 本地源码:`/Users/chenqi/.codex/external-sources/grok-build`
- 仓库当前提交:`8adf9013a0929e5c7f1d4e849492d2387837a28d`
- 仓库内 `SOURCE_REV``2ec0f0c8488842da03a71eeee3c61154957ca919`
- Catty 源码:本报告所在 Netcatty 工作树
- **已验证**:可直接由源码或本地只读实跑证明。
- **推断**:由多处实现拼合出的行为判断,尚未做完整产品级端到端复现。
一句话结论:**Grok 最值得 Catty 学的不是“多截一点输出”而是把终端分成三层原始输出单独保存、给模型的内容严格限额、持续日志进入对话前先做限流和抑制。Catty 的增量轮询和远程编码处理其实更好,但当前有两个入口能绕过限额,另有一个入口会稳定累积重复输出;这三个确定性问题都足以直接塞满上下文,必须先修。**
## 一、Grok 的终端输出怎样流动
```text
命令进程
├─ 原始 stdout/stderr ──> session/terminal/<tool_call_id>.log
│ ├─ 运行期最多 5 GiB超过则杀进程
│ └─ 退出后只留文件前 64 MiB
├─ 模型结果内存 ────────> 默认约 20k 字符:前半冻结 + 后半滚动
│ └─ 去 ANSI、超长行每 2000 字符软换行
└─ 后台读取 ────────────> get_task_output
└─ 超限时只回前 2k 预览 + 文件路径
交互 PTY 是另一条通道256 KiB 环形缓冲 + offset + base64 推送,
不会自动把整个终端画面塞进模型对话。
```
### 1. 原始输出与模型输出分开
- **已验证**:每次 Bash 调用都会把输出写入会话目录下的 `terminal/<tool_call_id>.log`,而不是只留在对话消息里。[bash/mod.rs:1915](/Users/chenqi/.codex/external-sources/grok-build/crates/codegen/xai-grok-tools/src/implementations/grok_build/bash/mod.rs:1915)
- **已验证**:模型侧默认终端预算为 20,000 字符;超出后冻结前半、滚动保留后半,再插入截断提示。[bash/mod.rs:156](/Users/chenqi/.codex/external-sources/grok-build/crates/codegen/xai-grok-tools/src/implementations/grok_build/bash/mod.rs:156) [terminal.rs:346](/Users/chenqi/.codex/external-sources/grok-build/crates/codegen/xai-grok-tools/src/computer/local/terminal.rs:346)
- **已验证**:原始字节转模型文本时用 UTF-8 容错解码;非法字节会被替换,因此二进制输出和错误编码并不是无损的。[terminal.rs:308](/Users/chenqi/.codex/external-sources/grok-build/crates/codegen/xai-grok-tools/src/computer/local/terminal.rs:308)
- **已验证**:模型看到的文本会去掉 ANSI 控制码,超长单行按 2,000 字符软换行;磁盘文件仍保存原始字节。[bash/mod.rs:406](/Users/chenqi/.codex/external-sources/grok-build/crates/codegen/xai-grok-tools/src/implementations/grok_build/bash/mod.rs:406) [output.rs:413](/Users/chenqi/.codex/external-sources/grok-build/crates/codegen/xai-grok-tools/src/types/output.rs:413)
- **已验证**stdout 与 stderr 被收进同一个输出流和文件;每次轮询先读完当前 stdout再读 stderr所以二者的相对时间顺序并不精确。[terminal.rs:1528](/Users/chenqi/.codex/external-sources/grok-build/crates/codegen/xai-grok-tools/src/computer/local/terminal.rs:1528)
这套设计最重要的价值是:**模型消息只是有界索引,原始输出是独立资产。** Catty 目前成功命令也有类似“预览 + handle”但全文仍在渲染进程内存中没有磁盘配额、TTL 或范围读取。
### 2. 长任务和失控输出有多层保险
- **已验证**:前台可自动转后台的命令默认最多阻塞当前轮 15 秒;后台任务最长运行 10 小时。[terminal.rs:47](/Users/chenqi/.codex/external-sources/grok-build/crates/codegen/xai-grok-tools/src/computer/local/terminal.rs:47)
- **已验证**:运行中输出文件默认最多 5 GiB超出会终止进程进程结束后文件被 `set_len(64 MiB)`。[terminal.rs:65](/Users/chenqi/.codex/external-sources/grok-build/crates/codegen/xai-grok-tools/src/computer/local/terminal.rs:65) [terminal.rs:382](/Users/chenqi/.codex/external-sources/grok-build/crates/codegen/xai-grok-tools/src/computer/local/terminal.rs:382) [terminal.rs:1236](/Users/chenqi/.codex/external-sources/grok-build/crates/codegen/xai-grok-tools/src/computer/local/terminal.rs:1236)
- **已验证**:退出后仍会最多等待 2 秒排空管道,避免子进程继承管道导致永久卡住。[terminal.rs:77](/Users/chenqi/.codex/external-sources/grok-build/crates/codegen/xai-grok-tools/src/computer/local/terminal.rs:77)
- **已验证**:完成的后台任务在内存中保留 5 分钟,之后只保留最多 100 条轻量元数据;输出仍指向磁盘文件。[terminal.rs:42](/Users/chenqi/.codex/external-sources/grok-build/crates/codegen/xai-grok-tools/src/computer/local/terminal.rs:42) [terminal.rs:1432](/Users/chenqi/.codex/external-sources/grok-build/crates/codegen/xai-grok-tools/src/computer/local/terminal.rs:1432)
- **已验证**:会话文件默认 30 天后清理,可配置;当前会话目录会跳过。[persistence.rs:2600](/Users/chenqi/.codex/external-sources/grok-build/crates/codegen/xai-grok-shell/src/session/persistence.rs:2600)
需要注意两个不能照搬的点:
1. 5 GiB 对桌面应用太大Catty 应采用更小的默认值和全局总配额。
2. Grok 提示模型“完整输出在文件”,但退出后只保留**文件开头** 64 MiB因此对更大输出这句话不准确末尾错误甚至可能丢失。
### 3. 后台读取并不是真正的增量读取
- **已验证**`get_task_output` 每次读取当前完整快照;若超过预算,只回前 2,000 字符预览并给出文件路径。[task_output/tool.rs:11](/Users/chenqi/.codex/external-sources/grok-build/crates/codegen/xai-grok-tools/src/implementations/task_output/tool.rs:11)
- **已验证**:多任务读取允许最多 20 个任务,各自独立套用默认约 40 KiB 上限,没有统一总预算。[task.rs:318](/Users/chenqi/.codex/external-sources/grok-build/crates/common/xai-tool-types/src/task.rs:318) [task_output/mod.rs:205](/Users/chenqi/.codex/external-sources/grok-build/crates/codegen/xai-grok-tools/src/implementations/grok_build/task_output/mod.rs:205)
- **推断**:一次多任务调用最坏仍可能向上下文注入约 800 KiB而且重复轮询会把相同预览反复写进历史。Grok 的模型读取没有 Catty 的 `nextOffset` 语义。
因此,**Catty 的 `terminal_start` / `terminal_poll` 设计更好**:它有 256 KiB 滚动尾窗、`outputBaseOffset``totalOutputChars``outputTruncated``nextOffset`,并按聊天会话隔离任务。[aiExec.cjs:16](/Users/chenqi/.codex/worktrees/de5f/netcatty/electron/terminalWorker/aiExec.cjs:16) [aiExec.cjs:165](/Users/chenqi/.codex/worktrees/de5f/netcatty/electron/terminalWorker/aiExec.cjs:165) [aiExec.cjs:196](/Users/chenqi/.codex/worktrees/de5f/netcatty/electron/terminalWorker/aiExec.cjs:196)
Catty 当前的问题不是底层没有增量,而是上层没有利用好它:相同 offset 的重复 poll 不会被历史裁剪SessionState 也不记录 jobId、nextOffset 和已读位置。由于该问题已实测可在一次短循环内稳定累积近 50k 字符,本文将它列为 P0而不是一般优化。
### 4. 持续日志先限流,再进入对话
Grok 为 monitor 单独做了一条“事件入口”,这是最值得 Catty 借鉴的部分:
- **已验证**:单行最多 500 字符,一个事件批次最多 3,000 字符,原始行缓冲最多 1 MiB200ms 合批。[monitor/types.rs:1](/Users/chenqi/.codex/external-sources/grok-build/crates/codegen/xai-grok-tools/src/implementations/grok_build/monitor/types.rs:1)
- **已验证**:令牌桶初始允许 10 个事件,之后每 2 秒补 1 个;被抑制的事件只累计数量,恢复时发一条摘要。[rate_limiter.rs:5](/Users/chenqi/.codex/external-sources/grok-build/crates/codegen/xai-grok-tools/src/implementations/grok_build/monitor/rate_limiter.rs:5)
- **已验证**:持续 30 秒过载后停止向对话发送该监控流,并提示改写为更精确的 grep/awk 过滤。[rate_limiter.rs:121](/Users/chenqi/.codex/external-sources/grok-build/crates/codegen/xai-grok-tools/src/implementations/grok_build/monitor/rate_limiter.rs:121)
- **推断**:该“自动停止”只中断事件管线,没有在同一路径调用终端 kill底层命令可能继续运行到超时或会话清理。因此 Catty 借鉴时应同时停止进程或明确标为“仅静音”。[monitor/tool.rs:321](/Users/chenqi/.codex/external-sources/grok-build/crates/codegen/xai-grok-tools/src/implementations/grok_build/monitor/tool.rs:321) [monitor/tool.rs:360](/Users/chenqi/.codex/external-sources/grok-build/crates/codegen/xai-grok-tools/src/implementations/grok_build/monitor/tool.rs:360)
对于 Catty正确做法不是让每个终端刷新都成为一条消息而是把它们变成`时间窗口内合批 -> 单行/单批上限 -> 总速率限制 -> 被抑制数量摘要 -> 必要时停流/停进程`
### 5. 交互终端和模型上下文彻底分开
- **已验证**Grok 的交互 PTY 是独立客户端通道,使用 256 KiB 环形缓冲、单调 offset、16ms 合批,并以 base64 传输原始字节。[pty_session.rs:1](/Users/chenqi/.codex/external-sources/grok-build/crates/codegen/xai-grok-shell/src/terminal/pty_session.rs:1) [pty_session.rs:186](/Users/chenqi/.codex/external-sources/grok-build/crates/codegen/xai-grok-shell/src/terminal/pty_session.rs:186) [pty_session.rs:366](/Users/chenqi/.codex/external-sources/grok-build/crates/codegen/xai-grok-shell/src/terminal/pty_session.rs:366)
- **已验证**:重连时只回放这 256 KiB 环形缓冲,重建客户端终端画面;这不是模型工具结果。[pty_session.rs:530](/Users/chenqi/.codex/external-sources/grok-build/crates/codegen/xai-grok-shell/src/terminal/pty_session.rs:530)
这一边界对 Catty 尤其重要:**用户看到的终端画面可以高频、完整;模型读取必须显式、有界、可增量、可审计。** 不应把终端 UI 的 scrollback 直接当模型记忆。
## 二、上下文裁剪、压缩与恢复
### 1. 普通旧工具结果先做便宜裁剪
- **已验证**Grok 在上下文使用超过 50% 后,构造请求时裁剪旧工具结果;最近 3 轮不动,超过 4,000 字符的旧结果保留 1,500 头 + 1,500 尾10 轮前直接替换为占位。[request_builder.rs:155](/Users/chenqi/.codex/external-sources/grok-build/crates/codegen/xai-chat-state/src/actor/request_builder.rs:155) [types.rs:67](/Users/chenqi/.codex/external-sources/grok-build/crates/codegen/xai-chat-state/src/types.rs:67)
- **已验证**:这一步发生在请求副本上,不会先破坏完整会话记录;更深层的 compaction 另有归档与重建流程。[request_builder.rs:20](/Users/chenqi/.codex/external-sources/grok-build/crates/codegen/xai-chat-state/src/actor/request_builder.rs:20) [compaction.rs:219](/Users/chenqi/.codex/external-sources/grok-build/crates/codegen/xai-grok-shell/src/session/compaction.rs:219)
Catty 已经会在预算压力下按终端 session 只保留最近两次成功的 `terminal_execute`,方向正确。[staleContextPruner.ts:184](/Users/chenqi/.codex/worktrees/de5f/netcatty/infrastructure/ai/harness/staleContextPruner.ts:184) 但它没有覆盖 `terminal_poll``terminal_read_context`,所以 6 次相同 offset 的本地实跑仍累计约 49.6k 字符且未触发调整。
### 2. 压缩后要恢复“可继续工作”的状态,而不是恢复大段日志
- **已验证**Grok compaction 后会重新注入正在运行的终端任务、子代理、已编辑文件、待办和工具状态,而不是重新塞入任务输出。[compaction.rs:1205](/Users/chenqi/.codex/external-sources/grok-build/crates/codegen/xai-grok-shell/src/session/compaction.rs:1205)
- **推断**:它注入运行任务 ID/命令/状态,但没有“模型上次读到哪个 offset”加上 `get_task_output` 是全快照,压缩后仍可能重复读取。
- **推断**:终端任务表是进程内 Map新建 actor 时为空,未发现从磁盘恢复活进程的路径。重启后旧日志文件可能还在,但旧 taskId 不能继续作为真实运行任务读取。[terminal.rs:543](/Users/chenqi/.codex/external-sources/grok-build/crates/codegen/xai-grok-tools/src/computer/local/terminal.rs:543)
Catty 应保存的是结构化任务续读状态:`jobId + sessionId + command + status + nextOffset + outputBaseOffset + handleId + sideEffectClass`。恢复时先向后端核实任务是否仍存在,再注入“仍运行 / 已完成 / 已失联”,不能假装恢复,也不能建议盲目重跑。
## 三、Catty 当前最危险的三个确定性漏洞
### P0-1失败或超时输出绕过终端压缩
- **已验证**:工具执行器把失败命令的完整 stdout/stderr 拼进 error。[toolExecutors.ts:96](/Users/chenqi/.codex/worktrees/de5f/netcatty/infrastructure/ai/shared/toolExecutors.ts:96)
- **已验证**`capabilityTools` 对失败结果直接返回,只有成功结果进入 `fitTerminalExecuteResultForModel`。[capabilityTools.ts:328](/Users/chenqi/.codex/worktrees/de5f/netcatty/infrastructure/ai/harness/capabilityTools.ts:328)
- **已验证**:前台 PTY 默认 `maxBufferedChars=0`,而 helper 将 0 解释为不限长度。[ptyExec.cjs:27](/Users/chenqi/.codex/worktrees/de5f/netcatty/electron/bridges/ai/ptyExec.cjs:27) [ptyExecHelpers.cjs:277](/Users/chenqi/.codex/worktrees/de5f/netcatty/electron/bridges/ai/ptyExecHelpers.cjs:277)
- **实跑已验证**:构造约 200k 字符后超时,进入模型的 error 长度为 200,035handle 数为 0同等大小的成功输出会被截断并生成 handle。
这意味着最容易产生巨量日志的“失败、超时、构建报错”恰好绕过保护。修复标准必须是:**无论成功、失败、超时、取消、桥接异常,所有 stdout/stderr 都先经过同一个终端输出封装器,模型只拿有界预览。**
### P0-2`tool_output_read` 可以把全文重新灌回上下文
- **已验证**handle 默认读 12k但调用方可传任意 `maxChars``full` 模式只是从头截到调用值,没有硬上限。[toolOutputStore.ts:67](/Users/chenqi/.codex/worktrees/de5f/netcatty/infrastructure/ai/harness/toolOutputStore.ts:67) [toolInputs.cjs:345](/Users/chenqi/.codex/worktrees/de5f/netcatty/electron/capabilities/schemas/toolInputs.cjs:345)
- **已验证**`tool_output_read` 被明确排除在二次 fitting 之外,因此模型可以用一个巨大 `maxChars` 将原文一次性拉回。[capabilityTools.ts:126](/Users/chenqi/.codex/worktrees/de5f/netcatty/infrastructure/ai/harness/capabilityTools.ts:126)
修复标准:服务端写死单次硬上限,支持 `offset/range/search/head/tail`,返回 `nextOffset/hasMore/totalChars`;每一轮所有 handle 读取还要共享总预算,不能只限制单次调用。
### P0-3重复 poll/read_context 不参与终端历史去重
- **已验证**:跨轮历史省略只识别 `terminal_execute` 的几个别名,不覆盖 `terminal_poll``terminal_read_context`。[cattyHistoryReplay.ts:112](/Users/chenqi/.codex/worktrees/de5f/netcatty/components/ai/cattyHistoryReplay.ts:112)
- **已验证**:预算压力下的终端特化裁剪同样只识别 `terminal_execute`。[staleContextPruner.ts:98](/Users/chenqi/.codex/worktrees/de5f/netcatty/infrastructure/ai/harness/staleContextPruner.ts:98)
- **实跑已验证**:连续 6 次使用相同 offset 读取约 8k 内容,预算压力下 `didAdjust=false`,约 49.6k 重复文本全部保留。
修复标准:把每次读取标识为 `chatSessionId + sessionId/jobId + requestedOffset + nextOffset + snapshotVersion`;完全相同的读取只保留一次,后续增量可合并为一个范围。`terminal_read_context` 当前的行号会随 scrollback 淘汰或 reflow 漂移,不能假装成可靠日志 cursor需要单独的输出版本或快照 ID。
## 四、逐项对比
| 维度 | Grok Build | Catty 现状 | 判断 |
|---|---|---|---|
| 成功命令预览 | 默认约 20k头尾 | stdout 24k / stderr 12k重复行压缩、头尾 + handle | Catty 不弱 |
| 失败/超时输出 | 同一终端结果路径,仍受预算约束 | **绕过 fit可无上限** | Catty P0 |
| 原文保存 | 会话磁盘文件,有运行/完成/TTL上限 | JS 内存全文,无总量/TTL/LRU | Grok 更完整 |
| 后台读取 | 全快照,超限前 2k + 文件;无 offset | `nextOffset` 增量 + 256 KiB 尾窗 | Catty 更好 |
| 重复读取去重 | 无真正 cursor可能重复 | 底层有 cursor上下文层不按 job+offset 去重 | Catty 应补上层 |
| handle 读取 | 通过有界工具读文件 | head/tail/full`maxChars` 无硬上限 | Catty P0 |
| ANSI/进度条 | 模型预览去 ANSImonitor 合批限流 | PTY normalize 去 ANSI/CR但各工具路径不统一 | Grok 更一致 |
| UTF-8/远程编码 | UTF-8 lossy | Stateful decoder支持 GBK/GB18030 分块 | Catty 更强 |
| 持续日志 | monitor 专用入口:批次、速率、抑制 | 主要依赖模型谨慎 poll | Grok 值得学 |
| 交互 PTY | 与模型工具分离256 KiB 环形缓冲 | UI 终端与 AI 能力分层,但 read_context 仍是屏幕行语义 | 原则一致 |
| 历史裁剪 | 通用旧 tool result 分层裁剪 | terminal_execute 特化poll/read_context 未覆盖 | Grok 更完整 |
| 压缩后任务状态 | 注入运行任务,但无已读 offset | SessionState 只记 lastCommand | 两边都有缺口 |
| 敏感信息 | 未发现通用终端 secret redaction | 未发现catalog 还标为 `sensitiveRead:false` | 两边都缺 |
| 会话/跨聊天隔离 | 任务有 owner session | 后台 job 按 chatSessionId 校验 | 两边都有基础 |
## 五、建议实施顺序
### P0先堵住能直接撑爆上下文或泄密的入口
1. **统一终端输出封装**:成功、失败、超时、取消、异常全部走同一预算器;先保存原文,再只回结构化预览。
2. **锁死 `tool_output_read`**:单次和单轮双重硬上限;增加 offset/range/search禁止调用参数放大服务端上限。
3. **让 poll/read_context 真正去重**:相同范围不得重复进入历史;只保存已读区间、摘要和下次 offset。
4. **终端敏感信息处理**:在进入模型前识别并遮罩常见 token、私钥、密码、连接串原文只留本地受控存储并明确生命周期。
5. **写命令 413 只执行一次**压缩或重试只能重放已记录结果不能重新执行有副作用的命令。历史提示也不应默认写“Re-run terminal_execute”。[cattyHistoryReplay.ts:112](/Users/chenqi/.codex/worktrees/de5f/netcatty/components/ai/cattyHistoryReplay.ts:112)
### P1把现有增量能力变成真正的上下文能力
1. SessionState 保存运行任务和最后已读 offsetcompaction 后先核实真实状态,再恢复续读位置。
2. ToolOutputStore 增加每 handle、每 chat、全局总字节数、条数、TTL、LRU关闭终端和删除聊天时精确清理。
3. 大输出从 JS heap 移到 Netcatty 专用临时目录;以不可猜 handle 访问,使用受限权限,支持字节范围读取和搜索。
4. 统一 ANSI、CR 进度、超长单行、重复行、binary/base64/高熵文本处理;保留 `encoding` 与是否 lossy 的元数据。
5. 为 follow/watch/log tail 增加 Grok monitor 式入口200ms 合批、单行/单批预算、速率限制、抑制计数和明确的停流/停进程行为。
### P2长期上下文质量
1. 通用工具历史裁剪覆盖 terminal_execute、terminal_poll、terminal_read_context 和 tool_output_read而不是按工具名漏补。
2. 结构化保存命令 outcome命令、退出码、时间、是否有副作用、摘要、handle、任务状态旧历史删原文但保留事实。
3. 建立离线终端上下文基准,记录峰值上下文占比、重复率、错误定位率、秘密暴露数和写命令执行次数。
## 六、交付前硬门槛与 13 个压测场景
以下门槛建议作为合并前必须通过的条件:
- 写命令遇到 413`WriteCount = 1`
- 并发任务串线、跨聊天读取:`crossTalk = 0``crossChatRead = 0`
- 模型可见内容里的测试密钥:`SecretExposure = 0`
- UTF-8 分块边界不损坏Catty 原有 GBK/GB18030 能力不退化。[ptyExecHelpers.cjs:8](/Users/chenqi/.codex/worktrees/de5f/netcatty/electron/bridges/ai/ptyExecHelpers.cjs:8)
- 任一场景不得把上下文推到窗口的 90% 以上。
建议自动化 13 场景:
1. 持续高速日志;
2. 超长单行;
3. 关键错误位于输出中段;
4. ANSI 颜色与 `\r` 进度刷新;
5. UTF-8 多字节字符跨 chunk
6. 二进制与高熵 base64
7. 四个并发终端;
8. 后台任务多次轮询;
9. 相同 offset 重复读取;
10. 有副作用命令执行后触发 413
11. 应用重启 / session resume
12. 输出包含 token、密码、私钥片段
13. handle 过期、淘汰和跨聊天访问。
每个场景至少采集进入模型字符数、原始输出字符数、压缩比、重复字符比例、峰值上下文占比、handle 数和内存/磁盘占用;涉及命令的再采集执行次数、任务归属和最终状态。
## 七、不建议照搬 Grok 的地方
1. 不照搬 5 GiB 运行文件默认上限;桌面产品应更保守并有全局配额。
2. 不照搬“完成后截文件开头 64 MiB”应保留头尾或分块索引否则真正错误常在末尾。
3. 不照搬 `get_task_output` 全快照Catty 已有 offset应把它贯彻到上下文历史。
4. 不照搬多任务各自限额却没有聚合限额。
5. 不照搬 monitor “显示已停止但未确认进程已杀”的含糊语义。
6. 不照搬仅 UTF-8 lossyCatty 的 stateful decoder 和远程编码支持必须保留。
7. 不把“文件路径”直接当安全 handle路径泄露、权限和生命周期都需要单独设计。
## 最终判断
Catty 不需要复制 Grok 的终端系统。Catty 已经有更适合真实终端代理的底座:远程会话、增量 offset、尾窗、跨聊天隔离和多编码解码。真正需要补的是模型入口治理
> 任何终端字节进入模型前都必须经过同一个有界入口;任何大输出只能通过有额度、有游标、可过期的句柄读取;任何持续日志都先限流再入对话;任何压缩与恢复都保存任务事实和已读位置,而不是保存或重放大段日志。
先修三个 P0再补句柄生命周期和 monitor 式限流Catty 在“会真正操控终端”的场景里会比 Grok 当前实现更稳,也更不容易因一次失败命令把整个上下文窗口打满。