主机执行限制

有时间和输出上限的工作区命令,在保留沙箱里各自运行在单独的进程组中。它们的 PID 记录里带有 Linux 启动时间;清理时先同时核对 UID 和进程身份,确认无误后才向这个进程组发信号。所以一条命令超时或输出超限,不会波及同一个容器里同时在跑的原生会话和终端。等待容器 init 回收的僵尸进程,不算作还在写入的命令进程。

主机端以 64 KiB 为一块读取 stdout 和 stderr。命令的 stdout 上限在读取过程中就开始生效;stderr 最多保留 256 KiB 的诊断内容。队列最多放四项,满了就让生产方等待,消费方退出时队列随之取消。原生 CLI 的单条记录上限是 8 MiB;sandbox manager 的 NDJSON 帧上限是 32 MiB,因为一帧里要装下规范化后的内容、原始记录和 JSON 转义。原生记录超限时,会走同一条限定范围的清理路径,停掉对应的成员进程。setup 和 runner 的诊断日志尾部同样按字节数设了上限。

每个规范化后的事件,在主机生成时限制在 256 KiB 的 JSON 以内,控制平面收到时还会再限制一次。Postgres 存不了的文本会先被替换掉:NUL(工具输出二进制内容或用 NUL 分隔的内容时会产生)和落单的代理项(CLI 在一个代理对中间截断字符串时会留下)都会变成 U+FFFD。事件会保留下来,而不是被拒绝,因为 runner 一旦记录不了事件,就会结束这一轮。runner 发给控制平面的所有内容都做同样的替换;它在释放一次激活或结束一轮时给出的原因也一样,因为这个原因会引用 CLI 打印的内容,而原因一旦被拒,这一轮就会一直挂在它的租约上。runner 还会把释放原因截到控制平面接受的 1000 个字符以内(ABANDON_DETAIL_MAX_CHARS),就像它截断心跳里的启动错误一样,因为原因再长的话,整个释放请求都会被拒绝。

资源检查点和原生 CLI 事件是分开转发的。所以即使模型或工具调用一直没有输出,最近一次采样的检查点也能在下一条消息出来之前保存下来。收尾时的最终报告仍然是权威的测量结果。

磁盘空间只在准入时检查:可用空间低于存储预留时,runner 不会接需要新建沙箱的轮次。至于运行中的沙箱写了多少,除了可选的单容器磁盘上限,没有任何限制,见沙箱设置。