# NullClaw 还是 Infinity：面向本地优先、海量长期会话的二次开发决策

研究日期：2026-10-31。对比对象是通过 Rex 已打开标签页定位的 **NullClaw 与 Hydro Infinity**，不是同名向量数据库、图像模型或其他 Infinity 项目。

## 执行结论

**若核心目标是“本地优先 + 大量长期会话 + 低常驻内存 + 异步任务可恢复”，建议选 Infinity 的 step 内核做二次开发，而不是直接把 Infinity Code daemon 当作成品服务。若首要目标是尽快交付一个多渠道个人/小团队助手，选当前 NullClaw 更合适。两者都不能原样满足前一个目标。**

这不是 Rust 对 Zig 的偏好：关键在于 **能否把一次 Agent 执行拆成可持久化、可重入的事件切片**。Infinity 已把输入、工具结果、子线程报告和订阅事件纳入这一模型；NullClaw 的主路径则是持有 `Agent` 的 session，在一次同步 turn 内循环调用模型与工具。为前者补本地 durable substrate 是基础设施开发；把后者改成同等语义，往往触及执行器、工具接口与恢复协议。[[I01]] [[I02]] [[N01]] [[N06]]

同时，必须否定三个容易导致错误选型的说法：

- **“Infinity 本地模式等工具也完全不驻留”不准确。** 当前 local driver 在 `awaiting_tool_result()` 时走 `AwaitInput`，保留 driver；订阅存续但没有未决工具时才可退出。真正允许工具派发后结束整个执行宿主的是 step embedding。[[I03]] [[I04]]
- **“NullClaw 永不回收 session”不准确。** 它有 idle eviction 和持久化恢复；但 TTL 不是硬字节上限，daemon 的回收又由处理计数触发，不能等同于定时到点释放。[[N02]] [[N03]]
- **“接 SQLite 就能让全部历史不进 RAM”不准确。** NullClaw 恢复仍全量读取历史；Infinity 当前 daemon 的 JSON 持久化也把已加载历史留在内存 store。二者都需要真正有预算的 prompt-context 读取与缓存治理。[[N04]] [[I05]] [[I06]]

**建议决策：Infinity step 为长期运行时主线；NullClaw 保留为近期产品交付或边缘入口的候选，而不是默认同时运行两套 Agent loop。先做两周以内的可证伪 PoC，再决定正式迁移。** 本文后面给出足以推翻这个建议的条件、改动位置和验收方法。

## 目标、假设与边界

“我们的目标”在本次提示里没有重新定义。本报告从 Rex 中同一 Infinity 项目的既有研究稿提取以下工作假设，**它们不是本轮新确认的产品规格**：本地/私有部署优先；长期保留大量会话；内存主要随活跃量而非全部历史量增长；工具可异步等待；重启不丢已接受的工作；模型位置与状态存储位置可以分别选择。该既有报告是上下文线索，不被当成本轮结论的证据。

NullClaw 仓库还存在另一条明确但不同的目标线：Telegram topic 路由、nullboiler 工作流编排、nulltickets 任务流。它出现在 2026-03-13 的集成路线图和分析中，**不能自动替代上述运行时目标，也不能把路线图中的 Planned 当成现成功能**。本报告将其作为“多渠道/业务编排优先”的独立场景。[[N18]]

| 目标维度 | 本报告采用的含义 | 必须另行确认的规格 |
|---|---|---|
| 本地优先 | worker、会话、队列可全部留在本机；不强制 AWS | 是否要求断网推理；模型权重是否计入内存 |
| 海量长期会话 | 已归档会话数 N 很大，活跃切片数 C 可限流 | N、每日事件数、活跃率、历史体积及附件分布 |
| 低内存 | idle 之后不保留无界执行态、热历史和队列 | RSS 上限、采样周期、子进程/cgroup 计量口径 |
| 可靠恢复 | 先 durable accept 再确认；崩溃后重放且可审计 | 进程崩溃还是断电；可接受 RPO/RTO |
| 多 Agent | 父子任务、异步报告、订阅与调度 | 固定 DAG、动态协作还是一次性模型委派 |
| 产品可用 | 可配置渠道、身份与权限、可观测和运维 | 首批必须支持的渠道、租户、UI 与管理员能力 |

如果“< 1 MB 二进制、< 5 MB 整个生产系统 RSS”是不能松动的硬门槛，先暂停选型：本轮没有证明任何一个项目在目标负载下达标。NullClaw 的工程目标不能直接当作所有功能组合的实测承诺。

## 研究方法与证据等级

比较基于**相同研究日期的本地源码快照**，并用 `git ls-remote` 只读核对远端 `HEAD/main`；两者与本地 SHA 相同，没有拉分支、修改上游或把旧版本当最新。

| 项目 | 锁定 commit | 最近提交日期 | 本轮定位 |
|---|---|---|---|
| NullClaw | `5f1cade05c19b6ecdfb9565ae3305e892e484da9` | 2026-10-05 | 当前工作区 |
| Hydro Infinity | `1abc6fcff1f186124f924b56aa92c3a3684c90c5` | 2026-10-28 | Rex 标签页的 Infinity 工作区 |

证据分为四类，阅读时应保持区分：

1. **源码事实**：可沿文中 N/I 编号打开固定 commit 的具体文件与起始行。负面结论限定在被审计的默认路径，而非声称所有部署都没有某能力。
2. **本轮验证**：明确列出命令、环境、通过/失败/跳过项；没有跑过的压测绝不写成实测。
3. **上游样本**：例如 Infinity 内存图表的原始数据，标明机器、负载和采样点，不冒充本机复现。
4. **工程判断/设计提案**：选型、工期、架构与验收目标都属于这一类，不是上游现成保证。

本轮重点读取 session 生命周期、Agent turn、store 契约、local router、step commit/dispatch、持久化实现、入出站队列、父子线程、工具执行、安全边界、模型适配、部署与测试脚本。**这是源码级架构评估，不是完整安全审计、同负载性能竞赛或所有渠道的端到端验收。**

## 产品层级：一个助手产品与一个运行时框架

NullClaw 更靠近“可直接部署的助手”：渠道入口、配对、配置、模型路由、工具、安全策略、记忆检索、cron 与 daemon 都在同一产品边界内。其扩展骨架是 Zig `ptr + vtable` 与 factory；扩展现有渠道、工具、provider 的路径相对清楚。[[N07]] [[N08]] [[N09]]

Infinity 更靠近“可嵌入的 Agent 执行基础”：`ConversationStore`、`StateStore`、`InputSender`、model provider、observer、thread config 等契约与执行器解耦；Infinity Code daemon/Web UI 和 AWS Lambda/CDK 都是 embedding，不是框架必选的宿主。**可本地运行不等于当前本地宿主已适合海量会话。** [[I01]] [[I07]] [[I08]]

| 层级 | NullClaw 默认路径 | Infinity 当前仓库 | 对二次开发的含义 |
|---|---|---|---|
| 用户产品 | 多渠道助手、CLI/daemon、内置工具 | Infinity Code、Web/TUI、Slack 示例 | 前者离通用助手交付近；后者离协作编码体验近 |
| 执行内核 | session-owned Agent；同步 turn loop | local actor router 或外部驱动 step | 后者更容易把等待变成持久化事件边界 |
| 长期状态 | SessionStore 与 Memory 分离 | ConversationStore 与 StateStore 分离 | 两边都要分清 transcript、记忆、执行状态 |
| 平台设施 | 有界 bus、渠道出站 outbox、策略与观测 | RAP、MCP bridge、回调、serverless embedding | 产品适配多不等于 durable scheduling 完成 |
| 宿主选择 | 本地/容器/运行时适配器 | 本地进程或 Lambda 等 | 不能把接口名推断成部署能力与资源保证 |

因此，“功能数更多”“二进制更小”“Rust 更安全”都不是充分的选型理由。要比较的是目标所缺能力会落在**扩展接口外层**还是要求**改动核心时序**。

## NullClaw：一条消息如何完成一轮工作

```text
channel / gateway
  → inbound bus
  → daemon 分片队列 → 固定 worker
  → SessionManager.getOrCreate(session_key)
      → 新 session 时从 SessionStore 恢复历史
      → session 持有 Agent、provider 所有权与 history
  → 同一 session 的 mutex 串行化 turn
  → 模型请求 → 解析 tool calls → 同步逐个 execute → 再请求模型
  → persistTurn：用户/最终助手文本、usage
  → outbound bus → 渠道发送 / 最终消息 outbox
```

`Session` 直接拥有 `Agent`，不只是一个 ID。`getOrCreate` 在 manager 锁内完成查找、创建和历史恢复；session mutex 防止同一会话并发 turn，不同会话可并行。daemon 默认 4 个分片 worker，每分片入站容量 256；因此慢模型/慢工具会占住对应 worker，同分片其他会话可能遭遇队头阻塞。**这不代表所有 gateway 路径都只有四并发，只描述 daemon channel dispatch 这条路径。** [[N01]] [[N03]]

普通 tool call 在 `agent/root.zig` 的 `for (parsed_calls)` 中直接调用 `executeTool`，`Tool.VTable.execute` 返回最终 `ToolResult`。这给小规模本地助手带来简单、直接、较容易推理的行为；代价是工具等待仍属于当前 turn 的生命周期。[[N06]] [[N09]]

一个值得开发者警惕的细节是 `agent.parallel_tools`：本轮全仓搜索只找到声明、解析、序列化与配置测试，未发现执行循环消费它；主路径依然逐个执行。**不能把配置 round-trip 测试当成并行执行已实现的证据。** 即使未来加上线程并行，也只是单轮工具并行，不会自然得到 durable callback 与进程重启续跑。[[N10]] [[N06]]

## Infinity：必须区分 local 与 step

### local 模式

```text
InputSender 的进程内 channel
  → router 按 thread_id 路由
  → 按需构建 driver / Thread / HistoryManager
  → driver pool：FuturesUnordered
  → 模型完成 → sync history → dispatch tool
  → 无事可做且无未决 tool：退出 driver，移除 worker entry
  → 等未决 tool result：AwaitInput，driver 仍留在 pool
```

router 自己持有 driver futures，而非为每个历史 thread 永久留下 spawned task；已退出 driver 的内存与 worker entry 可以回收。新消息到达时再构建 driver。**但这里的“idle”有精确定义**：`check_before_idle` 若发现 `thread.awaiting_tool_result()`，返回 `AwaitInput`，不是 `Exit`；active subscriptions 本身则不要求 driver 常驻。[[I02]] [[I03]]

这修正了既有 Infinity 研究稿中过于宽泛的叙述：**不能仅凭“工具异步”就断言 local daemon 在每次等工具时都释放执行态。** 当前 local 模式仍可能保留一份 history view；底层内存 store 本身还保存规范历史。

### step 模式

```text
durable inbox → claim 有限批次
  → system.step(inputs, observer, deferral)
  → Thread::load：读取历史、状态、去重与配置
  → 执行一个有边界的模型/同步工具切片
  → sync：提交可持久化历史
  → dispatch 异步工具；后续结果作为新的 InputMessage
  → step 返回；宿主可释放 Thread 或退出整个进程
```

`step` 对输入按 thread 分组，先加载/过滤，再用 `join_all` 并行执行各组。它不是调度器：传入多少组，就可能同时持有多少组上下文；**批次上限、全局并发、租户配额与 queue lease 要由 embedding 负责**。另外，分组使用顺序 `Vec` 查找，大批不同 thread 的批次不宜无节制放大；外层小批处理比急着改内核更优先。[[I04]] [[I09]]

本地化的正确入口是这套 step API，而不是把 daemon JSON store 换成 SQLite 后继续默认常驻 local router，就宣称完成了规模化改造。

## 内存：应该比较什么，而不是比较什么

先定义变量：N 是历史会话总数，H 是历史总字节，C 是同时执行切片数，W 是等待工具的 thread 数，K 是热缓存字节，Q 是排队字节，P 是每个活跃上下文及请求缓冲。

```text
目标模型：RSS ≈ runtime_base + C × P + K_max + Q_ram_max + DB_client_buffers
          持久化历史 H 与 durable backlog 放磁盘，不随 N 全量镜像进 RAM

NullClaw 当前：共享运行时 + 仍驻留的 session/Agent + 活跃 worker 栈与缓冲
              + 恢复历史的瞬时峰值 + 子任务/出站积压

Infinity local + 内存 stores：runtime + H + dedup/metadata/subscriptions
              + C 的执行视图 + 等未决工具的 W 个 driver + 无界 channel 积压

Infinity step + 真正磁盘 store：更接近目标式；但有界读、限并发和 durable queue 必须补齐
```

公式是架构分析，不是经压测拟合的预测模型。`N` 不出现在目标式中也不意味着数据库索引、文件描述符、缓存管理和去重表没有成本；这些成本必须外置或有明确上界。

### NullClaw 已有回收，但不是硬上界

默认 `session_idle_timeout_secs = 1800`。`evictIdle` 扫描 map 并跳过运行中的 turn；daemon 在每 100 次计数触发时调用，不是独立定时器。其他 channel loop 也有调用点，但不改变“TTL ≠ 全局字节预算”的判断。停止流量后不能据此承诺准确 30 分钟内回落；短时间涌入大量不同会话仍可能形成高水位。[[N02]] [[N03]] [[N10]]

此外，恢复是在 manager 锁内调用 `loadMessages`，SQLite 实现是无 `LIMIT` 的 `ORDER BY id ASC`；即使后续 compaction 缩小 history，也已付出了全量读取、分配和锁持有成本。极长历史唤醒可能影响无关 session 的创建延迟。[[N04]]

### Infinity 当前持久化也不是有界缓存

`PersistentConversationStore` 包装核心 `InMemoryConversationStore`，使用 `loaded` 集合追踪已读取 thread；正常读取路径没有按字节/TTL 卸载这些历史。该 wrapper 的 delete/remove 操作与热缓存淘汰不是一回事。store 中的规范历史、driver 中的历史 view 也可能同时占用内存。[[I05]] [[I06]]

`StateStore` 的 processed IDs、metadata、subscriptions 是另一份长期状态；只替换 ConversationStore 而让 StateStore 仍无界，不能做到 RSS 与 lifetime event 数解耦。[[I10]]

## 性能证据：本轮实测与上游样本

### 本轮可以复现的结果

环境：macOS Darwin / arm64；Zig 0.16.0；rustc 1.97.1、cargo 1.97.1。未使用真实 LLM 压测，未启动业务渠道。以下数字不代表同工作负载的横向性能。

| 项目/命令 | 结果 | 能证明什么 | 不能证明什么 |
|---|---|---|---|
| NullClaw `zig build -Doptimize=ReleaseSmall` | 成功；默认构建二进制 4,889,528 B，约 4.66 MiB | 当前宿主/默认功能集可构建 | 不证明全部发布裁剪组合都大于 1 MB |
| NullClaw `--help`，`/usr/bin/time -l` | exit 0；max RSS 2,441,216 B，约 2.33 MiB | 极短 CLI 路径开销 | 不是 daemon、会话并发、工具子进程或模型内存 |
| NullClaw 全套测试，清除进程代理后 | 7,490 通过、9 跳过、0 失败；无泄漏报告 | 当前测试可通过；详见验证章节 | 不是目标负载已达标 |
| Infinity core 单元测试 | 108 通过、0 失败 | 核心状态机与现有回归测试通过 | 不是 daemon、云设施或目标平台全验收 |
| Infinity RAP bridge 单元测试 | 15 通过、0 失败 | 现有 callback 映射/bridge 测试通过 | 不证明公网鉴权与重放防护已产品化 |

NullClaw 主测试进程的构建摘要给出 **MaxRSS 249M**，高于 AGENTS 中“test well under 50 MB”的工程期望。必须分开理解：这不是生产 runtime 的 RSS，也不是可忽略的“已满足协议”——它说明该测试预算在本次环境下没有达成。

### Infinity 上游 80k 样本的准确解读

仓库 `MemoryChart.tsx` 指向 `agent_scale.rs`：AMD EPYC 9R14 单线程；`AGENTS=80000 TURNS=20 WAVE=4000`；内存 stores、进程内 scripted model；每个合成 turn 两轮 completion 加一次异步工具回环；每波完成并 idle 后采样 RSS。[[I11]]

| 累计 Agent | 上游记录 RSS（十进制字节） |
|---:|---:|
| 0 | 5,304,320 |
| 4,000 | 692,879,360 |
| 8,000 | 1,101,406,208 |
| 12,000 | 1,507,291,136 |
| 40,000 | 4,348,772,352 |
| 80,000 | 8,406,446,080 |

全区间平均增量 `(8,406,446,080 − 5,304,320) / 80,000 = 105,014.272 B/agent`，约 **102.55 KiB/agent**。这不是固定常数；前几波并非严格线性。样本说明 idle driver 开销可以回收，**也同时说明内存 store 中的历史仍随会话数增长**。不能用该图证明 80k 个真实活跃 Agent 能在几 MB 内存中运行。

本轮没有把 Linux `/proc` RSS 采样脚本硬套到 macOS，更没有用 NullClaw 的 `--help` 与 Infinity 的 80k 历史样本作速度/内存排行榜。两者的真实胜负要用本文的统一 workload 验证。

## 历史、记忆与恢复：三件不同的事

NullClaw 的 `Memory` 提供语义/关键词记忆操作，`SessionStore` 则提供 transcript 与 usage。向量检索、FTS、衰减、rerank 等很有价值，但不会自动变成可恢复的执行日志。SQLite/Redis/Postgres 等 backend 名称也不保证都支持 session store：registry 用 capability 显式区分。[[N05]] [[N11]]

Infinity 的 `ConversationStore` 保存消息、祖先线程关系与 compaction；`StateStore` 保存 processed IDs、metadata、订阅、待选项等。它更接近执行语义所需的状态分解，但 **trait 被拆开不等于跨 trait 写入天然原子**。[[I01]] [[I10]]

| 语义 | NullClaw | Infinity | 规模化改造要求 |
|---|---|---|---|
| 完整 transcript | 主 turn persistence 保存用户与最终助手文本 | 带类型消息、tool call/result、thread 关系 | 定义规范日志，不能把 UI 渲染文本当执行状态 |
| 在途工具 | 普通同步 turn，spawn 另走进程内任务 | step 历史先 commit 再 dispatch | 还要有持久化 dispatch intent 和恢复扫描 |
| 去重 | 有局部/渠道专用能力，非统一入站 durable inbox | processed IDs；工具结果可对历史 tail 去重 | 稳定 ID、唯一约束、保留窗口与事务 |
| compaction | 活跃 history 压缩与 trim | summary / thread cutoff / ancestor context | 摘要必须持久化、有版本且可重建 |
| 记忆检索 | 内置检索体系更完整 | 本轮未发现同级通用检索产品层 | 单独实现授权过滤、索引一致性和 token 预算 |

NullClaw `persistTurn` 当前逐项写 user/assistant/usage 并 `catch {}`；不会返回“持久化失败”。因此成功生成回复不等于会话已 durable。且这一条主路径没有保存整个逐工具执行日志，重启恢复不等价于从任意 tool 中间点续跑。[[N12]]

Infinity `HistoryManager.sync` 先 append messages，再调用 StateStore 保存需显式去重的 ID；后者结果被忽略。daemon 的 `save_thread*` 则直接 `std::fs::write(...).ok()`。这两个事实都要求正式本地后端重新设计错误传播与事务边界，不能因 Rust 类型系统而跳过。[[I12]] [[I13]]

## Prompt-context：真正的低内存必修课

NullClaw 默认 `max_history_messages = 100`，有 token threshold、compaction、保留最近消息和 hard trimming；Infinity 有 compaction summary、祖先 cutoff 和 fresh-context 子线程。这些是有效的上下文治理机制，但**发生在读取之后的压缩，不保证读取峰值有界**。[[N10]] [[N13]] [[I14]]

Infinity `load_history_up_to(start_from, up_to)` 主要是消息序号范围，不是 byte/token 限制；`load_history_with_ancestors` 返回完整 `Vec`。NullClaw 虽有分页的 `loadMessagesDetailed`，session restore 使用的仍是无界 `loadMessages`。所以两边都不能只靠已有分页 UI API 宣称执行器已 bounded。[[I06]] [[N04]] [[N05]]

建议新增的能力不是泛化的“数据库层”，而是一个有具体调用者的读取契约：

```text
loadPromptContext(thread_id, budget)
  输入：max_bytes、目标 token budget、snapshot/version、tenant
  输出：system/config + durable summary + recent closed messages
       + 必需的未决 tool-call/result 闭合片段 + 受限检索结果
  约束：单消息也有尺寸上限；超长工具输出落 blob；不先全量加载再截断
```

消息条数只是辅助限制，单条工具输出就可能是几十 MB。祖先线程继承还会放大读取；fresh context 能切断继承，但不能代替统一预算。工具调用与结果必须保持协议配对，summary cutoff 必须与快照版本一致。完整审计回放另用分页流式接口，不必塞进模型 prompt。

## 队列、背压与调度公平性

NullClaw bus 是容量 100 的 `BoundedQueue`；daemon 分片队列容量 256、固定 worker 4。这是实在的条目级背压，不应被忽略。但容量按条目而非字节；模型、工具和媒体 payload 仍可能让小数量消息变大。bus 和分片队列在进程内，没有统一 durable inbound accept/claim/ack 语义。[[N14]] [[N03]]

Infinity local 的入口、每线程输入、订阅请求和 lifecycle 通知使用 unbounded channels；router 没有在本轮审计路径中提供全局 semaphore。异步 future 比 OS 线程轻，但**无界生产者仍能把内存填满**。step API 也不是自动限流层。[[I02]] [[I09]]

| 风险 | NullClaw | Infinity | 必须实施的控制 |
|---|---|---|---|
| 突发新会话 | 未淘汰 session 增长 | driver/store/输入 channel 增长 | admission control、磁盘 backlog、字节预算 |
| 同会话顺序 | session mutex / 分片路径 | local router 或外层 queue 保证 | 同 thread 单 lease + fencing，不同 thread 公平调度 |
| 长工具阻塞 | 占住 turn / 分片 worker | local 保留待结果 driver；step 可退出 | durable tool intent、callback 唤醒、超时核对 |
| 过载 | 进程内 bounded 等待/timeout | embedding 自定；local 可无界堆积 | 明确 429/503 或等待策略，不静默丢弃 |
| 大租户挤占 | 本轮未证明完整租户调度 | 本轮未证明完整租户调度 | 每租户并发/字节/模型成本额度 |

更合理的调度单位是“有限成本的切片”，而不是一个直到完成才归还 worker 的整段任务。每 thread 可串行，跨 thread 用轮转/公平队列；不要因为同一个 hash 分片恰好碰到慢工具而阻塞所有邻居。

## 故障模型：可重放不等于 exactly-once

Infinity 的 `step_no_defer` 明确把 history sync 放在工具 dispatch 前，这避免结果比 tool-call 记录更早抵达。但“历史有记录”和“外部工具一定执行”之间仍存在跨进程窗口；它不是分布式事务。[[I04]]

NullClaw 已有渠道最终消息 outbox：enqueue 会持久化，支持 claim、失败退避、最多 5 次尝试与 delivered 记录。它有实际价值，**但它是 outbound delivery，不是任意工具执行的 durable outbox，也没有自动与 turn persistence 共用一次事务**。该实现将 jobs 放在 `ArrayList` 中并重写 JSON，积压很大时仍需磁盘队列化。[[N15]]

| 故障窗口 | 当前实现能依赖的部分 | 仍需补的机制 |
|---|---|---|
| 接到用户输入后、写日志前崩溃 | 都不能仅凭内存入口保证恢复 | inbox 落盘后才返回 accepted；外部平台 ack 时序审查 |
| 历史已 commit、tool 尚未发出 | Infinity 历史保留意图线索 | durable dispatch intent、lease 到期重扫、幂等 call ID |
| tool 已执行、回包前网络断开 | 两边都不能猜测外部副作用是否发生 | 幂等重试或状态查询；无法确定时标 `unknown` |
| callback 已到、ack 前崩溃 | Infinity 有 dedup 契约基础 | callback inbox 原子落盘、稳定 event ID、重复投递测试 |
| 历史写成功、dedup 写失败 | Infinity 两个 trait 写入分开且后者忽略错误 | 同库事务/UoW，或可证明的 replay-safe 提交协议 |
| 回复发送成功、delivered 记账前崩溃 | NullClaw outbox 可重试但可能重复发送 | 下游幂等 key 或明确 at-least-once 用户语义 |
| 磁盘满/权限错误/JSON 半写 | 默认 wrapper 部分错误被吞掉 | 错误向上传播、durable health、原子写/事务与故障注入 |

语义底线应是：**已接受的输入不静默消失；内部可重放；对外副作用幂等或可核对；不确定状态可见。** 不要承诺一个本地 SQLite 事务就能让邮件、支付、shell、第三方 API 全部 exactly-once。

另一个具体细节：Infinity RAP bridge 为 tool result 使用稳定 call ID，但对 subscription event 生成新的 UUID，因为协议事件本身没有逐事件身份。网络重投若携带同一业务事件，不能凭这个新 UUID 自动去重；需要在业务 envelope 中补 stable source-event ID。它不表示相同内容的两次合法事件应该被错误合并。[[I15]]

## 多 Agent：不能只看有没有 spawn

NullClaw 既有 `delegate` 也有 `spawn`，不能把它说成单 Agent 项目。`delegate` 主要对命名 agent/provider 发起模型请求；`spawn` 通过 `SubagentManager` 创建后台任务与 OS 线程、返回 task ID，并把完成结果路由回来源 session/channel。默认子任务并发 4，单任务工具迭代 15。[[N16]] [[N17]]

但 `SubagentManager.tasks` 是进程内 map。本轮在正常完成/通知路径没有发现持久化任务状态或已完成 task 的淘汰；`notified` 标志不会释放结果与线程 handle，最终由 manager deinit 统一回收。这限制长期后台服务；**并发上限限制的是 running 数，不等于 lifetime 完成结果有界**。[[N17]]

Infinity 把 parent-child thread、继承/fresh context、report、订阅和 compaction 纳入核心会话语义。RAP 让工具结果、流事件和订阅回调重新进入输入通道，而不是一定让父 turn 一直等待。step 模式适合低活跃率的大量长期任务；local 模式的等待保留行为仍要单独计量。[[I14]] [[I16]]

| 协作需求 | NullClaw 二次开发 | Infinity 二次开发 |
|---|---|---|
| 换模型做一次子任务 | 已有 delegate，改动少 | 配 thread/model source，也可完成 |
| 少量后台工具 Agent | 已有 spawn，需清理与任务恢复 | 已有线程/报告机制，需宿主配额与持久化 |
| 数万长期等待任务 | 线程/turn/任务 map 语义需要显著改造 | step 生命周期合适；durable scheduler 仍需开发 |
| 固定业务 DAG/人工审批/票据 FSM | nullboiler/nulltickets 是候选集成，不是本仓库证明 | 核心 thread 不是完整业务工作流引擎，仍要独立控制面 |
| 协作编码与分支隔离 | 需要较多产品层补充 | Infinity Code 的 stacked sandboxes/终端/Web 资产更相关 |

多 Agent 工具只是执行原语；预算分配、重试策略、审批、租户隔离和业务结果归档都是产品职责，不会因支持 spawn 自动出现。

## 工具、模型与渠道的复用成本

### 工具协议

NullClaw 的本地 tool vtable 简洁、直接，输入 JSON args、输出 `ToolResult`；安全策略与运行时上下文可在工具层落地。要加一个普通工具通常是实现结构体并 factory 注册；但把工具改成“已受理、未来回调”会影响调用结果、会话状态和调度，不是单个 adapter 即可解决。[[N09]]

Infinity `Tool<M>` 与 `InputSender`、RAP/MCP bridge 的边界更贴合异步执行；需要把本地进程工具变成受控 runner/服务，完成后发事件。MCP 兼容层降低接入成本，但不会把所有同步 MCP 工具自动变成跨重启可续跑服务；持有连接的 bridge/runner 也必须计入资源账本。[[I16]] [[I17]]

### 模型适配

NullClaw 拥有更丰富的 product-level provider factory、API key 解析、兼容 endpoint、fallback/router、不同工具格式与错误处理经验。Infinity 的 `ModelProvider` 协议独立，Bedrock 和 rig bridge 是具体实现，不强制 Bedrock；但已有 NullClaw 特有 provider 行为不能直接按文件拷贝到 Rust。[[N07]] [[I18]]

迁移要验证 streaming delta、tool-call ID/JSON 增量、thinking blocks、取消、context overflow、rate limit、timeout 与 usage。Infinity 文档明确 runtime 不统一设置 provider timeout，provider 应自行实现；这应纳入我们自己的 deadline 契约，不能无限等待。[[I18]]

### 渠道与业务

当前 NullClaw 的 Telegram、Discord、Slack、飞书/企业微信/钉钉等渠道及路由资产，对近期助手落地更有价值；Infinity 仓库中的 Slack embedding 不等于覆盖整套渠道。反过来 Infinity Code 的 Web/终端、diff 与 sandbox 工作区是另一类产品资产，不能因 NullClaw 渠道多就忽略。[[N08]] [[I08]]

渠道迁移最易低估的不是发送 API，而是：thread/topic/account 映射、重试去重、流式草稿转最终回复、附件大小、交互按钮、用户身份/allowlist、主动推送和配对权限。应按真实用户路径验收，而非以“可以发一条消息”作为迁移完成。

## 安全与多租户：两边都需要明确威胁模型

这是高风险设计评估，不是漏洞利用或完整审计。NullClaw 已有 PairingGuard、bearer 校验、公网绑定的鉴权判断、工具策略、路径/命令限制、SSRF 处理、脱敏与多种 sandbox。相对成熟的产品边界有复用价值，但配置、例外与实际调用链仍要验证。[[N19]] [[N20]]

例如 `http_request` 的空 allowed_domains 并非“拒绝全部外网”，而是允许安全检查通过的外部域；显式 allowlist 的域可访问私网，并跳过相应 SSRF/DNS pinning。这是可信操作者配置的能力边界，不能在报告里泛化成“永远禁止私网”或“全系统默认 deny all”。[[N20]]

Infinity daemon 默认 WebSocket 绑定 loopback；本轮审阅的 HTTP upgrade 路径没有看到配套 bearer/Origin 验证，因此不能把 `INFINITY_WS_BIND=0.0.0.0` 当作安全的公网服务开关。RAP 规范将认证交给具体实现，并明确 callback 应认证；loopback callback 也不是多租户授权体系。[[I19]] [[I20]]

Infinity local sandbox 默认启用 macOS sandbox-exec / Linux bwrap，但策略重点限制写入目录；macOS 规则包含 `allow default`，Linux 有 read-only root 等设置。这不是“任何文件都不可读、网络自动全隔离、可运行敌对租户”的证明。工作区隔离和安全沙箱应分别评估。[[I21]]

| 威胁/边界 | 需要的产品控制 | 验收示例 |
|---|---|---|
| 伪造 callback 唤醒 Agent | 短期 scoped token/HMAC 或 mTLS；call 与 tenant 绑定 | 别的租户的 call ID 即使存在也必须拒绝 |
| callback 重放与洪泛 | stable event ID、有效期、大小限制、速率/字节预算 | 重复合法回调不重复执行；过期签名不能注入 |
| prompt injection 导致越权工具 | 工具能力授权独立于模型文本；敏感操作审批 | tool description/结果无法提升权限 |
| 工作区或密钥泄漏 | 最小环境变量、文件/网络隔离、日志脱敏 | 非授权目录读取和跨会话检索必须失败 |
| 多租户资源挤占 | tenant-aware scheduler、DB 查询与 cache key 强制分域 | 恶意大租户不能饿死其他租户 |
| 任意代码执行 | 容器/OS 沙箱、进程树限额、kill deadline | shell 超时后子进程与后代一并回收 |

NullClaw 的内存安全依赖所有权约定与测试；Infinity 的 Rust 能降低悬垂/数据竞争风险，但不能消除业务鉴权、无限队列、落盘失败和外部副作用重复。**语言安全不能代替系统安全。**

## 部署、依赖与工程维护

NullClaw 的 vtable/factory 架构适合保持模块边界，运行产物较集中；当前默认 build 包含 vendored SQLite、外部 Zig websocket/wasm3 依赖，实际 provider/tool 路径还可能调用 curl 或平台命令。因此“零依赖”应解释为具体裁剪配置的运行形态，不是仓库没有构建依赖与外部可选工具。[[N21]]

Infinity core 的 `Cargo.toml` 不要求 AWS SDK，但包含 Tokio、RAP、Rhai 等；完整 workspace 的 Lambda、CDK、Web UI 与 sandbox 工具链更重。**core 可裁剪、daemon 完整产品栈、AWS 示例栈应分开计成本。** `Rc`、`LocalSet`、`spawn_local` 出现在 local embedding；不能把 Tokio 直接理解为所有工作自动分摊多核，多核扩展可以先用多 worker 进程与 thread lease。[[I02]] [[I07]] [[I22]]

| 维度 | NullClaw | Infinity |
|---|---|---|
| 仓库源码统计 | `src/**/*.zig` 293 文件、289,734 行 | `crates/**/*.rs` 168 文件、57,187 行 |
| 测试声明粗计 | `^test "` 7,565 块 | `#[test]` / `#[tokio::test]` 匹配 373 处 |
| 正确解释 | 更大产品表面、更多集成回归负担 | 核心更集中，但另有 TS/Web/CDK 表面 |
| 错误解释 | 不能据行数断言可靠性更高 | 不能据声明数推断缺乏覆盖或更低维护成本 |
| 工具链风险 | 固定 Zig 0.16.0；allocator/vtable 生命周期要严守 | Rust/async trait/LocalSet 学习成本；SDK/前端依赖面 |
| 许可证观察 | MIT | Apache-2.0，含 NOTICE 与 THIRD-PARTY |

统计包含测试且不代表可比“业务逻辑量”；编译条件、宏、文档测试使声明数与实际执行数不同。许可证这里只记录仓库文件，正式分发仍应做依赖和修改通知合规审查，不构成法律意见。[[N22]] [[I23]]

在本轮没有修改任何 Zig/Rust 生产代码、没有版本升级、没有 commit/tag，也没有把已有 Infinity 报告目录作为待覆盖的输出。最终报告是单独的静态站；部署报告本身不意味着两个 Agent runtime 适合跑在 Pages。

## 决策矩阵：先过硬门槛，再谈权重

不提供伪精确的“总分 8.7 对 7.9”。权重未知时，数字只能把假设藏起来。先用场景与硬门槛决策：

| 场景/硬门槛 | 更合适的基础 | 选择理由 | 会推翻结论的条件 |
|---|---|---|---|
| 近期多渠道个人/团队助手，少量后台任务 | **NullClaw** | 渠道、配置、工具、策略与现成产品价值高 | 真正负载以大量长工具等待为主，session/worker 模型成为瓶颈 |
| 大 N、小 C、本地持久化、低 idle RAM | **Infinity step** | 执行切片可退出，输入/状态契约已有 | 有界 store + queue PoC 仍达不到预算，或必需渠道移植成本压倒优势 |
| 海量长工具/订阅、动态子线程协作 | **Infinity step** | 结果重新作为事件，线程语义内生 | 全部工具实际同步且可在短 turn 内完成 |
| 首发强依赖 Telegram topic/nullboiler/nulltickets | **倾向 NullClaw** | 目标与现有产品边界更贴近 | 先核实外部仓库能力；不能仅信旧路线图估工期 |
| 协作编码、Web/终端、sandbox diff | **倾向 Infinity Code** | 仓库已有相关宿主资产 | 我们的场景与其会话/文件/权限模型不匹配 |
| 严格 < 1 MB 默认二进制、全系统 < 5 MB | **当前均未证明** | 本轮默认 NullClaw 产物已超 1 MB；未做极限裁剪对测 | 专项裁剪与目标硬件 workload 证明可达 |
| 零基础设施开发、生产级 durable exactly-once | **当前均不能直接给出** | 两边都有故障/事务窗口 | 缩小语义或引入经过验证的外部执行基础 |

若需要正式加权，由业务先确认优先级，再对“已实现 / 可外层补齐 / 需改核心 / 未验证”打分。核心目标下，**生命周期匹配、持久化边界、上下文有界性**应优先于 provider 数量或宣传基准；短期助手目标则可能反过来。

## 推荐架构：本地 durable substrate + Infinity step

以下全是**建议架构，尚未在本轮实现**。可以不依赖云服务，初期一个本机服务与 SQLite 即可，但接口要按可恢复的执行边界设计。

```text
渠道 / CLI / Web
  │ 鉴权、大小限制、tenant/thread 标识、stable event ID
  ▼
local durable inbox ── lease / fencing / fair scheduling ──┐
  │ 已落盘才确认                                          │ C ≤ 上限
  ▼                                                       ▼
SQLite / PostgreSQL ◄── bounded Conversation/State ── Infinity step workers
  │                    + prompt-context budget            │
  │ messages / summaries / dedup / leases                 │ commit intent
  │                                                       ▼
  ├── tool outbox → 受控 runner / RAP tool → authenticated callback → inbox
  └── delivery outbox → 渠道 sender → 最终回复 / 状态事件

blobs：大工具输出/附件原文；有授权的引用和摘要进入会话
observability：queue bytes、active slices、RSS、lease age、unknown effects
```

三个存储语义不能混用：inbox 表示输入已被接受；tool outbox 表示计划执行的外部动作；delivery outbox 表示发给用户/渠道的输出。可以同库，但必须独立状态机与指标。历史和去重也不应变成所有 thread 常驻内存的 mirror。

SQLite WAL 支持读写并行但同时只有一个 writer；适合单机起步，不承诺无限吞吐/多机多主，也不应把 WAL 当网络共享磁盘上的分布式协调层。若写并发或 HA 超出单机边界，再迁移自管 PostgreSQL/队列，而不是为了 Infinity 被迫上 AWS。[[E01]]

“数据库本地”“worker 本地”“模型本地”是三条独立轴：远程模型 API 不要求会话上云；本地模型的权重/KV cache 也不能藏在 runtime 的几 MB 指标之外。

## 数据模型与事务时序

建议最小持久化实体如下。它们是设计草案，不是新增配置项或承诺的稳定 API：

| 实体 | 关键字段/约束 | 为什么需要 |
|---|---|---|
| `threads` | `(tenant_id, thread_id)`、parent、status、context_version | 权限分域、线程关系、快照一致性 |
| `messages` | thread、sequence、message_id、typed payload/blob ref；唯一约束 | 可重放日志、去重、分页与审计 |
| `summaries` | source cutoff、version、模型/格式、content | 重启后恢复同一上下文，而非丢掉压缩成果 |
| `inbox` | event_id 唯一、payload、status、attempt、available_at | 接收确认、可重试与延迟唤醒 |
| `thread_leases` | owner、lease_until、单调 fencing token | 同 thread 串行；过期 worker 不得覆盖新结果 |
| `tool_calls` / `tool_outbox` | call_id、intent、state、idempotency key、deadline | 重发派发、回调匹配、unknown 状态核对 |
| `delivery_outbox` | output_id、channel/topic/account、attempt、receipt | 用户回复独立重试，不反向重跑整个 Agent |
| `dedup` / retained IDs | source、stable ID、保留窗口/唯一索引 | 重放可吸收，且 lifetime ID 集合不无限进 RAM |

建议切片时序：

1. **接收事务**：鉴权通过，把 event_id 与 payload 写 inbox；commit 后才向入口确认。重复 event 返回原 receipt。
2. **claim 短事务**：选 ready 输入、持有 thread lease/fencing；取有限 batch。不要在模型 HTTP 期间一直持有 SQLite 写锁。
3. **执行切片**：读取有界快照；调用模型/安全的同步工具；构建待提交 typed messages 与 action intent。设置 wall-clock、模型 token、工具输出预算。
4. **提交短事务**：确认 fencing/version 仍有效，写 messages/summary/processed IDs/outbox 并推进 inbox。**跨 store 的 commit unit 是当前 trait 使用方式需要补齐的点。**
5. **异步 dispatch**：从 tool outbox 领取，带稳定 call_id；成功、失败或未知结果分别记账。callback 先落 inbox 再 ack。
6. **终态投递/恢复**：输出进入 delivery outbox；worker 崩溃释放 lease 后重试，超期 action 查询外部状态或标 unknown，不猜成功。

不能只是把三个 trait 分别连到同一个 SQLite connection，就声称具备上面的原子性：当前 `step` 过程中有多次 store 调用与外部派发，必须在 embedding/提交 hook 中显式表达事务单元、错误传播和恢复边界。不要用一个跨 LLM 的大事务掩盖时序问题。

## 改造清单：具体改哪里

### 如果选择 Infinity

| 优先级 | 改动位置 | 最小改动/新增组件 | 不应顺手做的事 |
|---|---|---|---|
| P0 | `traits.rs`、`HistoryManager.sync` | durable 本地 Conversation/State store；明确统一提交单元；dedup 失败显式报错 | 继续复用吞错的 daemon JSON wrapper 作为权威数据源 |
| P0 | `ConversationStore` 读取与 `Thread::load` | 有界 prompt context、summary cutoff、blob refs | 先 SELECT 全量再按 token 截断 |
| P0 | `InputSender` + 新 local scheduler | durable inbox、claim/lease/fencing、限批/限并发 | 将 local unbounded channel 当 durable queue |
| P0 | `step_no_defer` dispatch 边界 | outbox intent、恢复扫描、回调稳定 ID | 把 commit-before-dispatch 误当 exactly-once |
| P0 | callback/runner 边界 | scoped auth、尺寸/速率限制、deadline、租户隔离 | 直接公网暴露 daemon websocket |
| P1 | provider / observer / ThreadConfigSource | 模型期限、成本/租户配额、指标与审计 | 默认引入全部 AWS workspace 与 Code UI |
| P1 | 渠道 adapter / 记忆检索服务 | 首发渠道、回包路由、最小可用记忆检索 | 一口气移植所有 NullClaw provider/channel |
| P2 | 运行宿主 | 视负载加多进程、自管 Postgres、备份与升级工具 | 未证实单机不足就上分布式系统 |

核心接口已匹配目标，但错误传播、统一事务、有界读取与 scheduler 是实质性开发，不是“加一个 SQLite 文件”两天即可完成。源码导览对应 [[I01]] [[I04]] [[I09]] [[I12]]。

### 如果选择 NullClaw

| 目标层级 | 具体改动 | 是否触及核心 |
|---|---|---|
| 保持当前助手模型、先止内存增长 | session entry/byte 上限、真正定时 eviction；恢复用有界 summary+窗口；缩短 manager 锁内 I/O | 中等：session/restore/daemon |
| 长期运行的 spawn | 任务结果 TTL/字节预算、已完成线程回收；任务与完成通知持久化 | 中高：SubagentManager 与 bus |
| 可靠交付 | persistTurn 错误向上传播；事务化 transcript；durable inbox 与 delivery outbox 对齐 | 高：session/turn/gateway/渠道 ack |
| 同轮工具并行 | 明确消费 parallel_tools；限制并发与输出；可取消 | 中高，但仍不是 durable async |
| 达到 Infinity step 的执行语义 | ToolResult 增加 pending/dispatch 概念；拆 turn 状态机；序列化未决工具、恢复点、父子报告；引入统一事件入口 | **高：跨执行器与 vtable/工具协议，不是普通插件** |

vtable/factory 是 NullClaw 的稳定骨架，应优先沿扩展点做外层增强；但工具等待和 turn 重入语义超出当前简单工具接口。若为了追求目标重写一套 step engine，原先“现成功能多、启动快”的优势会被核心改造成本削弱。[[N01]] [[N06]] [[N09]] [[N17]]

## 混合方案：可行，但不要默认双内核

“NullClaw 接渠道，Infinity 执行长期任务”有现实价值，前提是边界单一：**谁是 conversation/执行状态的唯一权威，谁就拥有 Agent loop**。另一边只做受限 ingress/egress 或独立工具服务。

推荐的最小跨进程 envelope：

```json
{
  "version": 1,
  "event_id": "source-stable-event-id",
  "tenant_id": "tenant_a",
  "thread_id": "thread_a",
  "type": "user.message",
  "payload_ref": "local-blob-reference",
  "reply_target": {"channel": "telegram", "account": "bot_a", "topic": "topic_a"},
  "trace_id": "trace_a"
}
```

这是**提议的 envelope**，不是当前 `/api/send`、`/api/worker`、`/api/callback` 的现成实现。本轮没有在 gateway 找到这三个旧路线图端点；已有 `/a2a`、`/webhook` 等 API 也不能自动提供相同鉴权、租户、持久化确认和回包语义。先写契约测试，再决定复用哪个入口。[[N18]] [[N23]]

本机优先用 Unix socket 或带认证的 loopback RPC，不共享内存指针/vtable，也不在两个进程间各自维护一份可独立修改的 transcript。跨主机通信按仓库要求使用 HTTPS；跨语言 in-process FFI 会增加 allocator、panic/错误、ABI 与线程约束，不建议作为首版捷径。

混合方案增加两套升级、配置、日志、权限与排障面；若首发只需要一个渠道，直接在 Infinity embedding 做 adapter 可能更便宜。只有必需的 NullClaw 产品资产复用收益明显时，才用混合，而不是为了“取两边优点”无条件拼接。

## 工作量、人员与阶段验收

以下是**工程估算，不是上游承诺，也不是固定报价**。假设两名熟悉 Rust/Zig 与数据库的开发者；首发单机、一个主渠道、一类异步工具；不包含完整 UI 重做、多租户商业化、跨机 HA 或移植全部 provider。

| 方案 | 粗略投入区间 | 最大不确定性 |
|---|---|---|
| NullClaw 助手加固，不改执行范式 | 4–7 人周 | 恢复历史、spawn 清理、现有渠道语义与故障行为 |
| Infinity step 本地 durable MVP | 10–16 人周 | 事务边界接入、上下文读取、runner 恢复、首发渠道 |
| NullClaw 改成同等级 durable step 内核 | 14–24 人周 | 工具/turn 协议重构、跨子系统回归面、兼容性 |
| 双运行时混合 | 在选定主线之外额外预算 | RPC/身份/回包映射/双运维，不能假设为零 |

这些区间不能直接除以人数得到日历时间；PoC 的结果可能大幅调整它们。真正的成本判断是“改契约/核心时序还是补适配器”，不是只看语言上手速度。

### 首先做能推翻结论的 PoC

**阶段 A：1–2 周内完成选型验证，而非声称完成生产版。**

- 一个真实磁盘 Conversation/State store，summary+窗口读取有 byte 上限；不使用 full-history mirror。
- 一个 durable inbox、单 thread lease、全局有限 worker；接入 Infinity step；一个可延迟/可重复回调的假工具。
- 相同 fixture 驱动 NullClaw 基线路径；测冷启动、长历史唤醒与 burst 后回收；不调用真实收费模型。
- 做 kill/replay、重复 callback、disk-full 三项故障注入；若关键语义必须大改引擎而超预算，重新评估。

**阶段 B：可靠本地 MVP。** 工具/回复 outbox、错误传播、deadline、备份恢复、指标；首发渠道走完整端到端，保留回滚通道。

**阶段 C：迁移与扩展。** 分批转换 typed transcript/summary，校验条数、顺序、工具配对和租户；小比例新流量 canary，旧运行时只读或停写，避免双主；达到单机瓶颈后再引入多 worker/自管数据库。

停止条件：目标 workload 的 RSS 无法平台化；无法定义可审计的副作用恢复；渠道迁移成本超过预算；或产品优先级已变成“近期助手交付”。出现任一项，应调整方案，而不是维护既定结论。

## 统一压测与故障注入规范

本节是**建议验收方案，尚未执行的数据不得作为达标结果**。先由产品确认数值门槛，再跑同机、同 provider stub、同 fixture、同活跃率、同完整进程树的 A/B。

| 场景 | 建议负载矩阵 | 观察点/通过条件 |
|---|---|---|
| 大 N、小 C | N 取 1k / 10k / 100k；C 固定 8 / 32 | RSS 不随归档 N 线性常驻增长；DB 大小增长可解释 |
| 长历史唤醒 | 每会话 10 / 1k / 100k 条历史 | prompt 读取字节、峰值 RSS 与延迟有界；不先全量读 |
| 长工具等待 | 延迟 1s / 60s / 模拟小时；固定完成流量 | 分开看 local/step 的 driver 数、W 对 RSS 的影响 |
| 突发输入 | 10 倍短时流入，包含新 thread | backlog 到磁盘；有过载信号；队列字节受限 |
| 大输出/附件 | 1 KiB / 64 KiB / 10 MiB 工具结果 | 大对象落 blob；prompt/context 严格限额 |
| 父子与订阅 | 高 fan-out、重复/乱序/迟到事件 | fan-out quota、稳定去重、关闭 thread 后行为可解释 |
| crash/replay | 在 accept/claim/commit/dispatch/ack 每点 kill -9 | 已确认事件可恢复；重复副作用有幂等/核对机制 |
| 磁盘/网络故障 | disk full、权限拒绝、损坏记录、429/断流 | 不静默成功；重试有上限；unknown 状态与告警 |
| 长时运行 | 持续 24–72 小时的创建/完成/淘汰 | task/result/dedup/连接数不过 lifetime 单调增长 |
| 隔离与公平 | 恶意大租户 + 正常租户 | 授权边界、p95 饥饿、缓存/队列/模型成本隔离 |

至少记录：进程及子进程 RSS/PSS、活跃/等待 driver、worker 数、缓存/队列条目与字节、每次历史读取条数/字节、DB/WAL/blob 大小、冷/热 p50/p95/p99、模型 token 与工具成本、retry/lease age/dead-letter、磁盘 fsync 延迟。

把“空闲”“已归档”“等待工具”“有订阅”“正在模型请求”分别计量。RSS 还会受 allocator 保留与 OS 页面回收影响，不能只看对象数；测稳定窗口与峰值，并注明是否 trim allocator。关闭内存 store 的合成基准和真实磁盘方案也不应混作一个系列。

## 本轮验证台账与限制

| 验证 | 命令/处置 | 结果 |
|---|---|---|
| 项目定位 | Rex `window ls` / `block ls` / 只读 `pwd` | 找到已打开 Infinity 项目；未向其他运行中终端发送输入 |
| 版本核对 | 两仓 `git rev-parse HEAD` 与 `git ls-remote ... HEAD refs/heads/main` | 本地与远端 SHA 一致；未 fetch/改分支 |
| NullClaw 初次测试 | `zig build test --summary all` | 最初依赖 git 传输失败；从同 commit 官方归档填充 Zig cache 后恢复，不改 manifest |
| NullClaw 代理环境测试 | 同上，原有代理环境 | 7,489 通过、9 跳过、1 失败；本地 curl resolve fixture 走代理导致 GET exit 22 |
| NullClaw 隔离代理重跑 | `env -u http_proxy -u https_proxy -u HTTP_PROXY -u HTTPS_PROXY -u ALL_PROXY -u all_proxy zig build test --summary all` | **7,490 通过、9 跳过、0 失败；无泄漏报告**；没有修改失败测试或产品代码 |
| NullClaw release | `zig build -Doptimize=ReleaseSmall --summary all` | **成功**；产物大小与 `--help` RSS 见性能章节 |
| Infinity 离线尝试 | `cargo test -p infinity-agent-core --lib --offline` | 缓存缺 strkind，未进入测试；不把它写成代码失败 |
| Infinity core | `cargo test -p infinity-agent-core --lib --locked` | **108 通过、0 失败**；测试执行约 5.06s，不含编译时间 |
| Infinity RAP | `cargo test -p rap-protocol -p infinity-rap-bridge --lib --locked` | bridge **15 通过**；rap-protocol 此命令下 **0 项**，不可加成覆盖数 |
| Infinity 全量脚本 | `./check.bash` | prerequisite 阶段缺 `jj`，未跑完整脚本；未宣称 workspace/daemon/e2e 全通过 |
| 官方规则 | Cloudflare Pages limits/pricing、SQLite WAL 官方文档 | 2026-10-31 抓取核对；仅作为部署/存储规则来源 |

未做：真实渠道发送、真实 LLM 负载、跨进程生产恢复演练、Infinity daemon/Web e2e、全 workspace/云环境测试、同负载 A/B RSS、目标硬件极限裁剪、安全渗透与依赖供应链全审计。上游 80k 数据没有在本机重跑。

测试输出中的故障注入 warning 不是实际生产故障；统计以最终 summary 为准。仓库说明中的源文件/测试数量快照已过时，本文用当前源码统计和实际测试结果，不沿用“245 文件 / 5,640+ tests”当作当前精确规模。

## 报告交付、免费部署与隐私

本报告作为纯静态文件部署到 **Cloudflare Pages**：HTML、CSS、浏览器原生 JS、Markdown 下载和机器可读证据清单；不启用 Functions、D1、R2、Worker 或收费模型服务。Cloudflare 官方说明静态资源请求免费且不限次数；Free plan 当前文件数上限 20,000，单文件 25 MiB。本产物远低于限制。免费描述仅针对该报告站点，不包含未来 Agent 系统、模型调用或云存储成本。[[E02]] [[E03]]

部署使用已登录的 **cf CLI** 创建独立 Pages 项目、取得短期 upload token、提交 production manifest；当前 CLI 目录参数本身不会自动上传文件，因此上传资源步骤由脚本调用同一官方 Pages Direct Upload API。**不使用 Wrangler，不读取/打印长期 OAuth token，不更改已有报告站点，不开通付费资源。** upload token 仅在进程内使用，不进入站点或 git。

公开内容只包含开源源码、固定 commit 引用、环境类型、验证汇总与设计建议；没有 Rex session/block ID、用户名、机器名、本机绝对路径、终端原文、账号标识、密钥或私有项目列表。Pages 是公开发布，若未来加入业务目标细节或私有测试样本，应先重新审查发布边界。

## 最终建议与下一步

**本地优先的长期 Agent 平台：选 Infinity step，但把 durable store、队列、上下文预算和安全控制作为首发必做项。短期多渠道助手：选 NullClaw，先补 session/任务清理与持久化错误，不贸然重构内核。**

对开发团队而言，最重要的不是“采用哪个项目”这一句话，而是下面五件可检查的事：

1. **锁定目标**：首发到底是海量长期 runtime，还是 Telegram/多渠道助手；把 N、C、RSS、历史和恢复口径写成验收规格。
2. **锁定宿主**：Infinity 选择 step embedding，不把 local daemon 的宣传能力当 step 的生命周期保证。
3. **锁定权威状态**：所有 accept/commit/dispatch/ack 的故障窗口可审计；不做两个 Agent loop 的双主会话。
4. **锁定资源预算**：不仅控制 worker 数，还限制 history、tool output、cache、queue、dedup 和完成任务结果的字节。
5. **用 PoC 决定而非维护偏好**：两周内证明有界 RSS、冷恢复、重复/崩溃语义；不通过就调整主线。

**报告结论的置信度：执行模型/默认源码路径为高；目标产品适配为中，依赖目标假设；真实吞吐/长期 RSS/总体迁移工期为待验证。** 这是一个可被测试推翻的工程决策，不是项目宣传。

## 固定版本证据索引

以下引用由构建脚本从 `evidence.json` 生成；N 是 NullClaw，I 是 Infinity，E 是官方外部规则。所有 GitHub 代码引用固定到本报告的 commit，不随 main 分支漂移。

- **[N01](https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/session.zig#L204)** — Session 直接持有 Agent；getOrCreate、mutex 与恢复路径；`src/session.zig:204`
- **[N02](https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/session.zig#L2243)** — evictIdle 扫描、跳过 active turn 与销毁 session；`src/session.zig:2243`
- **[N03](https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/daemon.zig#L1193)** — 分片队列容量、worker 数、每 100 次处理触发回收；`src/daemon.zig:1193`
- **[N04](https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/memory/engines/sqlite.zig#L835)** — loadMessages 无界历史读取；session.zig:1488 为调用点；`src/memory/engines/sqlite.zig:835`
- **[N05](https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/memory/root.zig#L208)** — SessionStore 与分页详细消息契约；Memory 另有独立 vtable；`src/memory/root.zig:208`
- **[N06](https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/agent/root.zig#L2708)** — 主 turn 的逐工具同步执行循环；`src/agent/root.zig:2708`
- **[N07](https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/providers/root.zig#L1)** — Provider 契约、factory 与配置/兼容层导出；`src/providers/root.zig:1`
- **[N08](https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/channels/root.zig#L1)** — Channel 契约与渠道产品边界；`src/channels/root.zig:1`
- **[N09](https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/tools/root.zig#L182)** — Tool.VTable.execute 同步返回 ToolResult；`src/tools/root.zig:182`
- **[N10](https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/config_types.zig#L406)** — Agent 配置默认值、parallel_tools 与 session TTL；`src/config_types.zig:406`
- **[N11](https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/memory/engines/registry.zig#L23)** — 后端 capability：session store、事务、outbox 支持独立；`src/memory/engines/registry.zig:23`
- **[N12](https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/agent/turn_persistence.zig#L18)** — persistTurn 保存 user/assistant/usage；错误被忽略；`src/agent/turn_persistence.zig:18`
- **[N13](https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/agent/compaction.zig#L78)** — 按消息数/token 触发的上下文压缩；`src/agent/compaction.zig:78`
- **[N14](https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/bus.zig#L409)** — BoundedQueue.publish 与容量 100 的 bus；`src/bus.zig:409`
- **[N15](https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/channels/outbox.zig#L164)** — 最终消息出站 outbox、claim、持久化与重试；`src/channels/outbox.zig:164`
- **[N16](https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/tools/delegate.zig#L33)** — 命名 provider/model 子任务委派与 completeAgentPrompt；`src/tools/delegate.zig:33`
- **[N17](https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/subagent.zig#L99)** — 后台 task map、OS 线程、结果通知与 deinit 回收；`src/subagent.zig:99`
- **[N18](https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/docs/integration-roadmap.md#L1)** — 2026-03-13 业务集成目标与 Planned 端点，非现成能力证明；`docs/integration-roadmap.md:1`
- **[N19](https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/gateway.zig#L719)** — Webhook/public-bind bearer 鉴权与配对边界；`src/gateway.zig:719`
- **[N20](https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/tools/http_request.zig#L14)** — HTTP 工具 allowed_domains 与 SSRF/DNS pinning 例外；`src/tools/http_request.zig:14`
- **[N21](https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/build.zig.zon#L1)** — Zig 版本及 SQLite/websocket/wasm3 构建依赖；`build.zig.zon:1`
- **[N22](https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/LICENSE#L1)** — NullClaw MIT 许可证；`LICENSE:1`
- **[N23](https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/docs/en/gateway-api.md#L24)** — 已有 webhook/A2A API 与鉴权；不等于路线图端点；`docs/en/gateway-api.md:24`
- **[I01](https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-agent-core/src/traits.rs#L27)** — ConversationStore、StateStore、InputSender 的平台契约；`crates/infinity-agent-core/src/traits.rs:27`
- **[I02](https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-agent-core/src/system/local/router.rs#L241)** — FuturesUnordered、worker 移除、unbounded channels 与 spawn_local；`crates/infinity-agent-core/src/system/local/router.rs:241`
- **[I03](https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-agent-core/src/system/local/driver.rs#L331)** — check_before_idle：未决工具 AwaitInput，订阅本身不保活；`crates/infinity-agent-core/src/system/local/driver.rs:331`
- **[I04](https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-agent-core/src/system/thread.rs#L414)** — step_no_defer、sync-before-dispatch 与可退出切片；`crates/infinity-agent-core/src/system/thread.rs:414`
- **[I05](https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-daemon/src/memory_store.rs#L46)** — daemon 持久化 wrapper、core 内存 store 与 loaded 集合；`crates/infinity-daemon/src/memory_store.rs:46`
- **[I06](https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-agent-core/src/traits.rs#L49)** — history/ancestor API 返回完整 Vec，范围不等于字节预算；`crates/infinity-agent-core/src/traits.rs:49`
- **[I07](https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-agent-core/Cargo.toml#L1)** — core 包依赖，不要求完整 AWS embedding；`crates/infinity-agent-core/Cargo.toml:1`
- **[I08](https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/README.md#L1)** — Runtime、RAP、Infinity Code 的产品定位；`README.md:1`
- **[I09](https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-agent-core/src/system/builder.rs#L452)** — step 的 Vec 分组、load、join_all；外层需限批；`crates/infinity-agent-core/src/system/builder.rs:452`
- **[I10](https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-agent-core/src/stores.rs#L409)** — StateStore processed IDs/subscriptions/metadata 的长期内存状态；`crates/infinity-agent-core/src/stores.rs:409`
- **[I11](https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/docs/src/components/MemoryChart.tsx#L3)** — 80k 上游内存样本的负载、环境与原始 RSS 数据；`docs/src/components/MemoryChart.tsx:3`
- **[I12](https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-agent-core/src/event_processor.rs#L627)** — HistoryManager.sync 先 append；processed ID 写入结果被忽略；`crates/infinity-agent-core/src/event_processor.rs:627`
- **[I13](https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-daemon/src/memory_store.rs#L350)** — JSON save_thread / save_thread_metadata 忽略文件写失败；`crates/infinity-daemon/src/memory_store.rs:350`
- **[I14](https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-agent-core/src/tools/thread.rs#L14)** — spawn_thread、fresh_context、父子报告与线程工具；`crates/infinity-agent-core/src/tools/thread.rs:14`
- **[I15](https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-rap-bridge/src/lib.rs#L41)** — callback dedup ID：tool result 稳定，subscription event 新 UUID；`crates/infinity-rap-bridge/src/lib.rs:41`
- **[I16](https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-agent-core/src/tools/rap_tool.rs#L1)** — RAP tool 适配与回调执行原语；`crates/infinity-agent-core/src/tools/rap_tool.rs:1`
- **[I17](https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-mcp-bridge/src/lib.rs#L1)** — MCP bridge：协议接入不等于工具重启续跑；`crates/infinity-mcp-bridge/src/lib.rs:1`
- **[I18](https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/docs/docs/infinity-runtime/model-providers.md#L8)** — ModelProvider、rig/Bedrock、provider 自有 timeout 与错误分类；`docs/docs/infinity-runtime/model-providers.md:8`
- **[I19](https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-daemon/src/ws_handler.rs#L41)** — daemon HTTP/WebSocket upgrade 路径；需额外公网授权审查；`crates/infinity-daemon/src/ws_handler.rs:41`
- **[I20](https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/docs/docs/rap/spec/overview.md#L88)** — RAP 安全：认证由 embedding 实现，callback 应认证；`docs/docs/rap/spec/overview.md:88`
- **[I21](https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/sandbox-local/src/backend.rs#L277)** — macOS/Linux sandbox 命令及具体写限制策略；`crates/sandbox-local/src/backend.rs:277`
- **[I22](https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/Cargo.toml#L1)** — workspace 核心、daemon、provider、sandbox、AWS 的独立包边界；`Cargo.toml:1`
- **[I23](https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/LICENSE.txt#L1)** — Infinity Apache-2.0；分发另查 NOTICE 与 THIRD-PARTY；`LICENSE.txt:1`
- **[I24](https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/check.bash#L13)** — 全量验证前置条件、clippy、tests、doctests、Web e2e；`check.bash:13`
- **[I25](https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-agent-core/examples/agent_scale.rs#L1)** — 内存基准驱动、合成工具与 idle 后采样；`crates/infinity-agent-core/examples/agent_scale.rs:1`
- **[E01](https://sqlite.org/wal.html)** — SQLite 官方 WAL：单 writer 与同机共享内存边界
- **[E02](https://developers.cloudflare.com/pages/functions/pricing/)** — Cloudflare Pages 官方静态资源请求定价
- **[E03](https://developers.cloudflare.com/pages/platform/limits/)** — Cloudflare Pages 官方 Free plan 文件数/大小限制
- **[E04](https://developers.cloudflare.com/pages/get-started/direct-upload/)** — Cloudflare Pages 官方 Direct Upload 部署方式


[N01]: https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/session.zig#L204
[N02]: https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/session.zig#L2243
[N03]: https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/daemon.zig#L1193
[N04]: https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/memory/engines/sqlite.zig#L835
[N05]: https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/memory/root.zig#L208
[N06]: https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/agent/root.zig#L2708
[N07]: https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/providers/root.zig#L1
[N08]: https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/channels/root.zig#L1
[N09]: https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/tools/root.zig#L182
[N10]: https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/config_types.zig#L406
[N11]: https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/memory/engines/registry.zig#L23
[N12]: https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/agent/turn_persistence.zig#L18
[N13]: https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/agent/compaction.zig#L78
[N14]: https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/bus.zig#L409
[N15]: https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/channels/outbox.zig#L164
[N16]: https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/tools/delegate.zig#L33
[N17]: https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/subagent.zig#L99
[N18]: https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/docs/integration-roadmap.md#L1
[N19]: https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/gateway.zig#L719
[N20]: https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/src/tools/http_request.zig#L14
[N21]: https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/build.zig.zon#L1
[N22]: https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/LICENSE#L1
[N23]: https://github.com/nullclaw/nullclaw/blob/5f1cade05c19b6ecdfb9565ae3305e892e484da9/docs/en/gateway-api.md#L24
[I01]: https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-agent-core/src/traits.rs#L27
[I02]: https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-agent-core/src/system/local/router.rs#L241
[I03]: https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-agent-core/src/system/local/driver.rs#L331
[I04]: https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-agent-core/src/system/thread.rs#L414
[I05]: https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-daemon/src/memory_store.rs#L46
[I06]: https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-agent-core/src/traits.rs#L49
[I07]: https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-agent-core/Cargo.toml#L1
[I08]: https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/README.md#L1
[I09]: https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-agent-core/src/system/builder.rs#L452
[I10]: https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-agent-core/src/stores.rs#L409
[I11]: https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/docs/src/components/MemoryChart.tsx#L3
[I12]: https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-agent-core/src/event_processor.rs#L627
[I13]: https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-daemon/src/memory_store.rs#L350
[I14]: https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-agent-core/src/tools/thread.rs#L14
[I15]: https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-rap-bridge/src/lib.rs#L41
[I16]: https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-agent-core/src/tools/rap_tool.rs#L1
[I17]: https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-mcp-bridge/src/lib.rs#L1
[I18]: https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/docs/docs/infinity-runtime/model-providers.md#L8
[I19]: https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-daemon/src/ws_handler.rs#L41
[I20]: https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/docs/docs/rap/spec/overview.md#L88
[I21]: https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/sandbox-local/src/backend.rs#L277
[I22]: https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/Cargo.toml#L1
[I23]: https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/LICENSE.txt#L1
[I24]: https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/check.bash#L13
[I25]: https://github.com/hydro-project/infinity/blob/1abc6fcff1f186124f924b56aa92c3a3684c90c5/crates/infinity-agent-core/examples/agent_scale.rs#L1
[E01]: https://sqlite.org/wal.html
[E02]: https://developers.cloudflare.com/pages/functions/pricing/
[E03]: https://developers.cloudflare.com/pages/platform/limits/
[E04]: https://developers.cloudflare.com/pages/get-started/direct-upload/
