# https://github.com/mentiora-ai/loom 项目说明书

生成时间：2026-06-18 12:17:09 UTC

## 目录

- [Loom 概览、信任区与 Crate 拓扑](#page-overview-architecture)
- [CLI、MCP 工具与多语言 SDK](#page-cli-mcp-sdks)
- [会话生命周期、清单哈希链与回放引擎](#page-session-manifest-replay)
- [安装、Postinstall、Doctor、Vault 与常见故障](#page-ops-security-failures)

<a id='page-overview-architecture'></a>

## Loom 概览、信任区与 Crate 拓扑

### 相关页面

相关主题：[CLI、MCP 工具与多语言 SDK](#page-cli-mcp-sdks), [会话生命周期、清单哈希链与回放引擎](#page-session-manifest-replay), [安装、Postinstall、Doctor、Vault 与常见故障](#page-ops-security-failures)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [loom-core/src/lib.rs](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/lib.rs)
- [loom-core/src/core_api_facade/core_api_facade.rs](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/core_api_facade/core_api_facade.rs)
- [loom-core/src/manifest_writer/manifest_writer.rs](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/manifest_writer/manifest_writer.rs)
- [loom-core/src/vault/impl_local.rs](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/vault/impl_local.rs)
- [loom-core/src/mocks.rs](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/mocks.rs)
- [mocks/README.md](https://github.com/mentiora-ai/loom/blob/main/mocks/README.md)
- [loom-mcp/src/error_mapper/error_mapper.rs](https://github.com/mentiora-ai/loom/blob/main/loom-mcp/src/error_mapper/error_mapper.rs)
- [loom-mcp/src/mcp_dispatcher/mod.rs](https://github.com/mentiora-ai/loom/blob/main/loom-mcp/src/mcp_dispatcher/mod.rs)
- [python-sdk/README.md](https://github.com/mentiora-ai/loom/blob/main/python-sdk/README.md)
- [typescript-sdk/README.md](https://github.com/mentiora-ai/loom/blob/main/typescript-sdk/README.md)
- [typescript-sdk/package.json](https://github.com/mentiora-ai/loom/blob/main/typescript-sdk/package.json)
</details>

# Loom 概览、信任区与 Crate 拓扑

## 项目概览与设计目标

Loom 是一个面向 agent / 自动化测试场景的浏览器录制与确定性回放基础设施，源自 Mentiora code-pipeline 项目，经过 23 轮 GA 驱动硬化后于 v0.9.0（2026-05-04）首次公开发布 资料来源：[v0.9.0 Release Notes](https://github.com/mentiora-ai/loom/releases/tag/v0.9.0)。其核心承诺是：给定相同的动作序列与种子，多次运行可以产出在 manifest 哈希链层面可比较的"变化预言机"（cross-run regression oracle），并支持 JSON 清单、gzip tarball、HAR 1.2 等多种导出形态 资料来源：[loom-core/src/exporters/exporters.rs:1-24]()。

设计上 Loom 把"会话生命周期 / 内容存储 / Manifest 写入 / 凭证保险库 / 回放引擎 / 预算执行器"作为 surface-agnostic 的内层，将所有跨 crate 的对外 API 收敛到单一入口 `CoreApiFacade`，从而避免外部代码绕过内部模块 资料来源：[loom-core/src/core_api_facade/core_api_facade.rs:1-25]()。这与社区中"工具调用 schema 与回放 hash 链必须严格等价"（NFR-DET-01）的诉求一致 资料来源：[v0.10.0 Release Notes](https://github.com/mentiora-ai/loom/releases/tag/v0.10.0)。

## Crate 拓扑与构建层级

Loom 工作区由多个职责单一的 crate 组成。`loom-core` 是 surface-agnostic 的内核，承担会话、内容、Manifest、Vault、回放、预算、Determinism Harness、Observability、Startup Manager 等子系统，并对外只暴露 `core_api_facade` 模块 资料来源：[loom-core/src/lib.rs:1-58](), [loom-core/src/core_api_facade/core_api_facade.rs:11-19]()。`loom-host` 与 `loom-rpc` 仅通过 `CoreApiFacade` 与内核交互，禁止穿透到具体子系统 资料来源：[loom-core/src/core_api_facade/core_api_facade.rs:15-25]()。

```mermaid
graph TD
  CLI["loom-cli / daemon"] --> RPC["loom-rpc (Unix socket / JSON-RPC)"]
  MCP["loom-mcp (stdio, JSON-RPC 2.0)"] --> RPC
  SHIM["loom-shims (CBOR / 0.11 协议)"] --> RPC
  PY["python-sdk (mentiora-loom)"] --> SHIM
  TS["@mentiora-ai/loom-sdk"] --> SHIM
  RPC --> FACADE["CoreApiFacade (loom-core)"]
  FACADE --> SESSION["session_manager"]
  FACADE --> MANIFEST["manifest_writer"]
  FACADE --> REPLAY["replay_engine"]
  FACADE --> BUDGET["budget_enforcer"]
  FACADE --> VAULT["vault"]
  FACADE --> CONTENT["content_store"]
  FACADE --> HARNESS["determinism_harness"]
  FACADE --> STARTUP["startup_manager"]
  CLI -. doctor / postinstall .-> DOCTOR["loom doctor + shim health probe"]
```

`loom-mcp` 通过 `RpcClient` 调用 `loom-rpc`，并把回包按 MCP 工具结果（`text` / `image`）序列化；为兼容 Claude Code/Desktop 的 Zod 校验，结构化 JSON 统一以文本块下发 资料来源：[loom-mcp/src/error_mapper/error_mapper.rs:13-25]()。SDK（Python / TypeScript）面向 Unix socket 与运行中的 `loom-daemon` 通信，并要求先通过 Homebrew / `cargo install` / 安装脚本把 CLI、daemon、Chromium 钉好版本 资料来源：[python-sdk/README.md:1-15](), [typescript-sdk/README.md:1-15]()。

## 信任区与进程边界

Loom 把进程边界当作第一等信任边界来建模，每个进程拥有独立的信任假设：

| 信任区 | 代表进程 | 主要职责 | 关键约束 |
|--------|----------|----------|----------|
| 内核 | `loom-core`（库形态） | 会话/内容/Manifest/Vault/回放/预算 | `pub use core_api_facade::*;` 是唯一对外出口 资料来源：[loom-core/src/lib.rs:23-25]() |
| 守护进程 | `loom-daemon` | 长驻服务、IPC 端点、reaper | 启动前执行 `startup_health_check` 与 `perform_recovery_sweep` 资料来源：[loom-core/src/core_api_facade/core_api_facade.rs:21-26]() |
| 协议适配 | `loom-rpc` / `loom-mcp` / `loom-shims` | JSON-RPC 2.0、stdio 传输、CBOR Shim 协议 | 工具名 `loom.*` 前缀、计数奇偶信封、协议 schema 内嵌（v0.11.1 修复） 资料来源：[loom-mcp/src/mcp_dispatcher/mod.rs:1-50](), [v0.11.1 Release Notes](https://github.com/mentiora-ai/loom/releases/tag/v0.11.1) |
| 客户端 | Python / TypeScript SDK、`loom-cli` | 会话句柄、Admin RPC（`kill_session` / `daemon.health`） | 通过 Unix socket 与 daemon 通信，要求 daemon 已起 资料来源：[python-sdk/README.md:1-15](), [typescript-sdk/README.md:1-15]() |
| 测试替身 | `*/src/mocks.rs` | 不依赖 I/O/时间/随机数的桩实现 | 位于各 crate 内部、`#[cfg(any(test, feature = "mock"))]` 门控 资料来源：[mocks/README.md:1-12](), [loom-core/src/mocks.rs:1-16]() |

凭证侧由 `Vault` 强制执行：调用方必须显式 `threat_model_acknowledged = true` 才能获得授权，且仅接受 `CredentialType::OAuth2`，否则以 `VaultRejection` / `vault_threat_model_missing` / `vault_credential_type_unsupported` 等细分错误码拒绝 资料来源：[loom-core/src/vault/impl_local.rs:1-40]()。该约束与 v0.11.0 "Hardening Sweep" 之后对"凭证/协议/确定性"三方收紧的方向一致 资料来源：[v0.11.0 Release Notes](https://github.com/mentiora-ai/loom/releases/tag/v0.11.0)。

## 关键能力面与社区关注点

围绕社区反复出现的"截图能传到 MCP 客户端吗？""文件上传能做到吗？""跨运行 diff 是否真为 0？""Linux 装完能不能跑？"等问题，Loom 把能力面分成五块：

1. **协议与 Schema**：`loom-mcp` 在 v0.11.0/v0.11.1 之后将 `until` / `timeout_ms` 等参数纳入内嵌 schema，避免 `postinstall` 未生成磁盘 schema 文件时给出错误的 `schema_violation` 资料来源：[v0.11.1 Release Notes](https://github.com/mentiora-ai/loom/releases/tag/v0.11.1), [loom-mcp/src/mcp_dispatcher/mod.rs:1-50]()。
2. **回放与确定性**：`ReplayEngine` 提供 `collect_content_refs` / `non_deterministic_refusal` / `unclean_source_refusal` 等高层判定，v0.10.1 起跨运行 diff `field_diffs=0` 成为正式契约 资料来源：[loom-core/src/replay_engine/mod.rs:1-10](), [v0.10.1 Release Notes](https://github.com/mentiora-ai/loom/releases/tag/v0.10.1)。
3. **捕获语义**：v0.10.0 引入 readiness-gated capture + per-request 网络条目，但仍需保留 NFR-DET-01 哈希链 资料来源：[v0.10.0 Release Notes](https://github.com/mentiora-ai/loom/releases/tag/v0.10.0)。
4. **跨协议内容分发**：v0.9.9 让 `web.screenshot` / `web.navigate` 的 PNG 通过 MCP `image` 内容块真正到达消费方，修正了双重 CBOR 编码的 bug 资料来源：[v0.9.9 Release Notes](https://github.com/mentiora-ai/loom/releases/tag/v0.9.9), [loom-mcp/src/error_mapper/error_mapper.rs:17-25]()。
5. **可观测与自愈**：v0.9.1 增 `daemon.health({deep: true})` Shim 探针；v0.10.1 增 session reaper，用于长驻 daemon 清理僵死会话 资料来源：[v0.9.1 Release Notes](https://github.com/mentiora-ai/loom/releases/tag/v0.9.1), [v0.10.1 Release Notes](https://github.com/mentiora-ai/loom/releases/tag/v0.10.1)。

常见失效模式：Linux 全新安装曾因 `chromium binary not_found` 与 shim IPC 在 fd 3 上与 Tokio I/O 驱动赛跑，导致 `surface_trap` 资料来源：[v0.9.2 Release Notes](https://github.com/mentiora-ai/loom/releases/tag/v0.9.2)；e2e-real-world 计划任务在 `ubuntu-latest` / `macos-latest` 偶发失败，需结合 daemon 日志与 per-site 工件排查 资料来源：[Issue #179](https://github.com/mentiora-ai/loom/issues/179)。

## See Also

- 主页（Loom 项目主页）
- 核心 API 门面（CoreApiFacade 详解）
- Manifest 写入与哈希链（manifest_writer）
- 回放引擎与跨运行确定性（replay_engine）
- MCP 工具分发（mcp_dispatcher）
- Vault 与威胁模型（vault）
- Python SDK（python-sdk）
- TypeScript SDK（typescript-sdk）

---

<a id='page-cli-mcp-sdks'></a>

## CLI、MCP 工具与多语言 SDK

### 相关页面

相关主题：[Loom 概览、信任区与 Crate 拓扑](#page-overview-architecture), [会话生命周期、清单哈希链与回放引擎](#page-session-manifest-replay), [安装、Postinstall、Doctor、Vault 与常见故障](#page-ops-security-failures)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [loom-mcp/src/mcp_dispatcher/mcp_dispatcher.rs](https://github.com/mentiora-ai/loom/blob/main/loom-mcp/src/mcp_dispatcher/mcp_dispatcher.rs)
- [loom-mcp/src/mcp_dispatcher/mod.rs](https://github.com/mentiora-ai/loom/blob/main/loom-mcp/src/mcp_dispatcher/mod.rs)
- [loom-mcp/src/mcp_observability/mod.rs](https://github.com/mentiora-ai/loom/blob/main/loom-mcp/src/mcp_observability/mod.rs)
- [loom-mcp/src/tool_cache/tool_cache.rs](https://github.com/mentiora-ai/loom/blob/main/loom-mcp/src/tool_cache/tool_cache.rs)
- [loom-mcp/src/tool_cache/interface_tests.rs](https://github.com/mentiora-ai/loom/blob/main/loom-mcp/src/tool_cache/interface_tests.rs)
- [loom-mcp/src/error_mapper/error_mapper.rs](https://github.com/mentiora-ai/loom/blob/main/loom-mcp/src/error_mapper/error_mapper.rs)
- [loom-mcp/src/error_mapper/interface_tests.rs](https://github.com/mentiora-ai/loom/blob/main/loom-mcp/src/error_mapper/interface_tests.rs)
- [loom-mcp/src/resource_tracker/resource_tracker.rs](https://github.com/mentiora-ai/loom/blob/main/loom-mcp/src/resource_tracker/resource_tracker.rs)
- [loom-core/src/lib.rs](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/lib.rs)
- [loom-core/src/manifest_writer/manifest_writer.rs](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/manifest_writer/manifest_writer.rs)
- [loom-core/src/exporters/exporters.rs](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/exporters/exporters.rs)
- [loom-core/src/replay_engine/mod.rs](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/replay_engine/mod.rs)
- [loom-core/src/budget_enforcer/mod.rs](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/budget_enforcer/mod.rs)
- [loom-core/src/vault/audit_payloads.rs](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/vault/audit_payloads.rs)
- [typescript-sdk/package.json](https://github.com/mentiora-ai/loom/blob/main/typescript-sdk/package.json)
- [mocks/README.md](https://github.com/mentiora-ai/loom/blob/main/mocks/README.md)
</details>

# CLI、MCP 工具与多语言 SDK

Loom 在核心（`loom-core`）之上暴露了三条并行的对外接口：**`loom` CLI** 用于本地脚本化与运维操作、**MCP 工具集**用于代理/IDE 集成、**多语言 SDK**（目前主要是 `typescript-sdk`）用于嵌入到下游产品（如 agentic-test-studio）。三者都收敛到底层的 `loom-rpc` 方法集合与 `loom-core` 的确定性会话模型，避免出现"行为分叉"。

## 三条接口在栈中的位置

| 接口 | 进程边界 | 调用对象 | 主要职责 |
|------|----------|----------|----------|
| `loom` CLI | 客户端进程直连 daemon（CBOR-over-IPC） | `loom-rpc` 方法 | 一次性录制/回放、导出、Vault 运维 |
| MCP 服务器 | stdio 帧 | `McpDispatcher` → `rpc.schemas` | 将 RPC 方法动态发布为 `tools`/`resources` |
| TypeScript SDK | Node 进程 | 通过 `loom-rpc` 客户端 | 让代理/测试平台以类型化方式调用 |

```mermaid
flowchart LR
    CLI[loom CLI] -->|CBOR/Unix socket| Daemon[loom-daemon]
    SDK[typescript-sdk] -->|CBOR/Unix socket| Daemon
    MCP[loom mcp<br/>stdio] --> Dispatcher[McpDispatcher]
    Dispatcher -->|rpc.schemas| Daemon
    Daemon --> Core[loom-core<br/>session + manifest]
    Core --> Content[ContentStore + Vault]
```

`loom-core` 通过 `pub use core_api_facade::*;` 将模块重新导出，CLI、MCP 与 SDK 都只消费这一层 [`loom-core/src/lib.rs`](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/lib.rs)。

## MCP 工具：动态从 RPC schema 生成

MCP 服务器没有写死工具列表。它在每次 `tools/list` 调用时从 `rpc.schemas` 拉取 `MethodSchema`，再用 `ToolCache::tool_from_method` 转成 MCP `Tool` [`loom-mcp/src/tool_cache/tool_cache.rs`](https://github.com/mentiora-ai/loom/blob/main/loom-mcp/src/tool_cache/tool_cache.rs)：

- **命名空间前缀**：RPC 方法 `action.web.click` 在 MCP 端被转换为 `loom.action.web.click`；反向 `mcp_to_rpc_name` 会剥离 `loom.` 前缀，便于把 `tools/call` 参数路由回 RPC [`loom-mcp/src/tool_cache/interface_tests.rs`](https://github.com/mentiora-ai/loom/blob/main/loom-mcp/src/tool_cache/interface_tests.rs)。
- **字段命名**：`Tool` 结构在序列化时强制使用 `inputSchema`（驼峰）以兼容 MCP wire 格式——这由 `#[serde(rename = "inputSchema")]` 保证，接口测试明确断言序列化结果包含 `"inputSchema"`。
- **协议版本**：MCP 服务器对外公布 `MCP_PROTOCOL_VERSION = "2024-11-05"` [`loom-mcp/src/mcp_dispatcher/mcp_dispatcher.rs`](https://github.com/mentiora-ai/loom/blob/main/loom-mcp/src/mcp_dispatcher/mcp_dispatcher.rs)。

### 隐式会话与生命周期

`McpDispatcher` 不要求 MCP 客户端先调用 `session.create`。它持有一个 `implicit_session: Mutex<ImplicitSessionState>`：首次 `tools/call` 命中时按 `baseline_options` 懒创建，并在会话被 daemon 驱逐后透明重建——重建时复用同一份选项以保持 `seed`/`clock_anchor` 不漂移；`recreated_count` 通过原子计数被 `loom.session.info` 暴露出来，使下游"确定性钉死"客户端能检测到重建而非默默信任 [`loom-mcp/src/mcp_dispatcher/mcp_dispatcher.rs`](https://github.com/mentiora-ai/loom/blob/main/loom-mcp/src/mcp_dispatcher/mcp_dispatcher.rs)。

### 错误与内容类型

`McpContent` 仅暴露标准 MCP `text` 与 `image` 两类内容块：JSON 负载在构造期被 stringify 进 `text` 字段，避免早期 `{"type":"json",...}` 在 Claude Code 等严格 Zod 校验下被拒 [`loom-mcp/src/error_mapper/error_mapper.rs`](https://github.com/mentiora-ai/loom/blob/main/loom-mcp/src/error_mapper/error_mapper.rs)。`ErrorMapper` 是 `LoomError → ToolResult{ isError: true, content }` 的唯一转换点，错误载荷经 `McpContent::from_json` 序列化，接口测试断言其标签为 `"text"` 且内嵌 JSON 被正确转义 [`loom-mcp/src/error_mapper/interface_tests.rs`](https://github.com/mentiora-ai/loom/blob/main/loom-mcp/src/error_mapper/interface_tests.rs)。

### 资源端（resources/*）

`ResourceTracker` 在 `loom://session/<id>/manifest` 与 `loom://blob/<sha256>` 两个 URI 方案下挂载会话清单与内容存储条目，默认 TTL `DEFAULT_TTL = 30s`；`resources/read` 返回形如 `{ contents: [{ uri, mimeType, text|blob }] }` 的 MCP 2024-11-05 兼容结构 [`loom-mcp/src/resource_tracker/resource_tracker.rs`](https://github.com/mentiora-ai/loom/blob/main/loom-mcp/src/resource_tracker/resource_tracker.rs)。

### 安全与可观测性

`McpObservability` 在请求结束写 `mcp_request_end` 结构化日志（包含 `mcp_method` / `tool_name` / `latency_us` / `error_code`），并对凭证类工具做参数级脱敏：cookie 工具的 `value` 字段被路径级剥离但保留名称以维持审计能力 [`loom-mcp/src/mcp_observability/mod.rs`](https://github.com/mentiora-ai/loom/blob/main/loom-mcp/src/mcp_observability/mod.rs)。

## CLI 与 SDK：复用同一条 RPC 路径

CLI 与 TypeScript SDK 都不经过 MCP，而是直接走 `loom-rpc` 的 CBOR-over-Unix-socket。这一设计的好处是 CLI 脚本与生产 SDK 看到的是同一份契约，避免出现"工具里有、CLI 没有"的偏差。`loom-core` 暴露的子系统被这三者共享：

- **Manifest 与哈希链**：`ManifestEntry` 是带标签的枚举（`Header` / `Action` / `Audit` 等），全部用 JCS 序列化以承载 `NFR-DET-01` 哈希链；Header 显式记录 `seed` 以便 replay 时还原 `Math.random/Date.now` [`loom-core/src/manifest_writer/manifest_writer.rs`](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/manifest_writer/manifest_writer.rs)。
- **Replay 引擎**：含 `cookie_replay` 子模块，提供 `collect_content_refs` / `non_deterministic_refusal` / `unclean_source_refusal` 三个对外函数 [`loom-core/src/replay_engine/mod.rs`](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/replay_engine/mod.rs)。
- **预算与导出**：`budget_enforcer` 强制会话级资源上限，`Exporter` 产出 `export_json` / `export_tarball` / `export_har` 三种制品 [`loom-core/src/exporters/exporters.rs](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/exporters/exporters.rs)、[`loom-core/src/budget_enforcer/mod.rs`](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/budget_enforcer/mod.rs)。
- **Vault 审计**：`vault/audit_payloads` 中的 DTO 仅承载字段名与事件元数据，绝不携带原始 cookie 值，从而让审计条目可以安全进入哈希链 [`loom-core/src/vault/audit_payloads.rs](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/vault/audit_payloads.rs)。

## TypeScript SDK

`typescript-sdk/package.json` 描述了一个 Node 测试驱动的 SDK：使用 `tsx` 运行 ESM 测试，`tsc` 负责类型检查与构建，`prepublishOnly`/`prepack` 在发布前强制重新构建；运行时仅依赖 `@types/node`，核心关键字为 `browser` / `automation` / `loom` [`typescript-sdk/package.json`](https://github.com/mentiora-ai/loom/blob/main/typescript-sdk/package.json)。它面向的目标是"agentic-test-studio"——即让测试平台以类型安全方式驱动 daemon，而不是再走一次 MCP。

## 测试与 Mock 约定

每个 crate 的 mock 模块就近放在 `<crate>/src/mocks.rs`，由 `#[cfg(any(test, feature = "mock"))]` 守门；启用 `mock` feature 即可让消费者在测试中替换 ContentStore / Vault / RpcClient 实现，避免去构造一个需要依赖全部 crate 的合成测试 crate [`mocks/README.md`](https://github.com/mentiora-ai/loom/blob/main/mocks/README.md)。

## 常见失败模式

- **MCP 工具参数被误拒（v0.11.0 → v0.11.1）**：daemon 曾经按磁盘上的 per-method schema 文件校验参数，但 `postinstall` 没拷贝这些文件，导致 MCP 调用收到 `schema_violation: field 'params' expected field_unknown got object`。v0.11.1 改为"embedded-first"校验路径修复此回归。
- **截图未达 MCP 客户端（v0.9.9 之前）**：截图字节被双重 `CBOR{data:base64}` 编码且 MCP 没有 image 内容类型，导致渲染图永远到不了消费方；v0.9.9 后 `web.screenshot` / `web.navigate` 通过标准 `image` 内容块返回 base64 PNG。
- **Linux 平台 daemon 启动后 `surface_trap`**：v0.9.2 之前 shim 的 IPC socket 与 Tokio I/O 在 fd 3 上竞争，造成所有 `web.*` 失败；补丁同时修复了 `loom doctor` 报 `chromium binary not found` 的问题（#70、#71）。

## See Also

- [Manifest 写入与哈希链](manifest-writer.md)
- [Replay 引擎与 Cookie 回放](replay-engine.md)
- [Vault 与审计载荷](vault.md)
- [MCP 资源端：Session 与 Blob](mcp-resources.md)

---

<a id='page-session-manifest-replay'></a>

## 会话生命周期、清单哈希链与回放引擎

### 相关页面

相关主题：[Loom 概览、信任区与 Crate 拓扑](#page-overview-architecture), [CLI、MCP 工具与多语言 SDK](#page-cli-mcp-sdks), [安装、Postinstall、Doctor、Vault 与常见故障](#page-ops-security-failures)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [loom-core/src/lib.rs](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/lib.rs)
- [loom-core/src/session_manager/session_manager.rs](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/session_manager/session_manager.rs)
- [loom-core/src/session_manager/mod.rs](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/session_manager/mod.rs)
- [loom-core/src/manifest_writer/mod.rs](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/manifest_writer/mod.rs)
- [loom-core/src/replay_engine/mod.rs](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/replay_engine/mod.rs)
- [loom-core/src/replay_engine/impl_replay.rs](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/replay_engine/impl_replay.rs)
- [loom-core/src/exporters/exporters.rs](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/exporters/exporters.rs)
- [loom-core/src/receipt_builder/interface_tests.rs](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/receipt_builder/interface_tests.rs)
- [loom-mcp/src/mcp_dispatcher/mcp_dispatcher.rs](https://github.com/mentiora-ai/loom/blob/main/loom-mcp/src/mcp_dispatcher/mcp_dispatcher.rs)
</details>

# 会话生命周期、清单哈希链与回放引擎

## 概述

Loom 的核心由三大相互咬合的子系统组成：`session_manager` 负责会话的有限状态机与生命周期治理；`manifest_writer` 将每一次动作回执（ActionReceipt）追加为 JSONL 形式的清单条目，并以此构建出可被跨运行比较的哈希链；`replay_engine` 则在封闭会话之上提供确定性回放能力，并辅以 `exporters` 将已关闭会话导出为 JSON manifest、gzipped tarball 或 HAR 1.2 等标准制品。三个子系统共同实现"录制→清单化→可验证回放→可导出回归"的闭环。

资料来源：[loom-core/src/lib.rs:3-23]()

## 会话生命周期

`SessionManager` 是会话生命周期 FSM 的所有者。每个会话拥有独立的多线程 tokio 任务与独立的 arena，由 `Arc<Notify>` 与 `Arc<AtomicBool>` 协同实现 abort 传播：调用 `abort()` 时翻转布尔位并触发 `notify_one()`，宿主函数入口处会检查该布尔位，`tokio::select!` 则在真实调用与通知之间做竞争。FSM 的状态空间为：

```mermaid
stateDiagram-v2
    [*] --> Created
    Created --> Active: create()
    Active --> Closed: close()
    Active --> Aborted: abort()
    Active --> Killed: budget breach
    Active --> Crashed: panic / fatal
    Closed --> [*]
    Aborted --> [*]
    Killed --> [*]
    Crashed --> [*]
```

`create()` 的同步路径只承担"轻量"职责：ULID 生成、目录创建、WAL 头追加、fsync、任务派发，刻意不触发 WASM、Chromium 或网络动作，从而维持暖创建预算（warm create budget）。同时，`create()` 会向 `BudgetEnforcer` 注册一个 `Arc<dyn Fn(SessionId, KillReason)>` 回调，使预算超支可以从外部中断本会话任务而不引入循环依赖。

在 MCP 层面，每个 MCP 进程会持有一个隐式会话（implicit session），在长期闲置被驱逐后可通过相同的确定性子集参数透明自愈。MCP 通过 `recreated_count` 计数器暴露隐式会话被透明重建的次数，以便确定性感知的客户端"检测"重建而不是"信任"重建——但该计数器从不被纳入清单/哈希链。

资料来源：[loom-core/src/session_manager/session_manager.rs:1-39]()；[loom-mcp/src/mcp_dispatcher/mcp_dispatcher.rs:2-30]()

## 清单哈希链

`manifest_writer` 负责把每一次动作结果追加为 JCS（JSON Canonicalization Scheme）形式的 JSONL 条目（`manifest.wal`）。清单条目（`ManifestEntry`）的字段集由 capture profile 与 surface 共同约束，结构上区分"哈希字段"与"blob 引用字段"两类，以避免在哈希链中重复携带大体数据：例如 `click` 类型的回执只携带 `dom_after_hash` 而不携带 `dom_after_blob_ref`；而 `navigate` 类型的回执反之，携带 blob 引用以支持重放期间再水化。

```rust
// receipt_builder/interface_tests.rs 验证两类回执的字段差异
let r = ReceiptBuilder::build_click_receipt(...);
assert!(r.dom_after_hash.is_some());
assert!(r.dom_after_blob_ref.is_none());
let r = ReceiptBuilder::build_navigate_receipt(...);
assert!(r.dom_after_blob_ref.is_some());
assert!(r.dom_after_hash.is_none());
```

哈希链的角色是"是否发生变化"的真值源：从 0.10.1 起，同一确定页面上同一组动作的两次独立录制，其清单 diff 在 `field_diffs=0` 上达成等值，回放哈希链由此具备跨运行的回归判定能力（cross-run regression oracle）。

资料来源：[loom-core/src/manifest_writer/mod.rs:1-9]()；[loom-core/src/receipt_builder/interface_tests.rs:21-37]()；[loom-core/src/lib.rs:3-9]()

## 回放引擎

`replay_engine` 面向"封闭会话"提供回放：它消费 `manifest.wal` 中的 `ActionReceipt` 序列并按 `collect_content_refs` 汇聚本次回放所需的内容引用（screenshot、DOM 快照等）。其拒绝路径由两个公开函数定义：`non_deterministic_refusal` 在源回执链上检出非确定性字段时拒绝回放；`unclean_source_refusal` 在源会话存在未关闭动作或污染 blob 时拒绝。`cookie_replay` 子模块则专门处理会话 Cookie 的还原策略，避免回放命中陈旧认证态。

回放引擎与清单哈希链形成对偶：清单链是"已发生事实"的不可变账本，回放引擎则是"按账本重建事实"的执行器。NFR-DET-01（跨运行确定性）由两者共同保证——清单保证事实链的等价性，回放保证重建路径的等价性。

资料来源：[loom-core/src/replay_engine/mod.rs:1-12]()；[loom-core/src/replay_engine/impl_replay.rs:1-4]()

## 导出器与跨运行确定性

`Exporter` 是面向"已关闭会话"的离线制品生成器。它通过 `ContentStore::get` 读取受内容完整性检查保护的内容 blob，并按三种形态输出：

| 导出形态 | 文件 | 用途 |
|----------|------|------|
| JSON manifest | `export_json` | 输出 `{"manifest": {...}, "content_blob_index": [...]}` |
| gzipped tarball | `export_tarball` | `manifest.json` + `cas/<sha256>` blob 的归档 |
| HAR 1.2 | `export_har` | 一条 HAR 条目对应一个 `ActionReceipt` |

回放哈希链与 `loom.session.diff`（跨会话 diff 报告：field_diffs / screenshot_diffs / action_count_delta）共同构成跨运行回归判定的两层视图。`SessionManager` 提供的会话再收割器（reaper）则保证长生命周期的守护进程不会因悬挂会话导致并发上限长期饱和。

资料来源：[loom-core/src/exporters/exporters.rs:1-19]()；[loom-mcp/src/mcp_dispatcher/mcp_dispatcher.rs:1-20]()

## 常见失败模式

- **Schema 校验回归**：0.11.0 引入嵌入式优先的 schema 校验时，破坏了 `loom.web.navigate` 对 `until`/`timeout_ms` 的接受路径，使 MCP `tools/call` 误判为 `schema_violation`；0.11.1 修复了该问题。
- **Schema 校验回归的另一面**：同一参数在 `web.wait_for` 上接受、在 `web.navigate` 上拒绝，提示 schema 源在方法间存在不一致。
- **跨运行确定性退化**：若 `manifest.wal` 的哈希链被外部工具改写或会话被异常关闭，跨运行 diff 将失去"真值源"地位，应优先调用 `SessionManager::close()` 正常收尾。
- **预算超支**：当 `BudgetEnforcer` 触发 kill-callback 时，会话进入 `Killed` 状态，回执中 `error.kind="budget_exceeded"`。

资料来源：[loom-mcp/src/mcp_dispatcher/mcp_dispatcher.rs:2-30]()；[loom-core/src/session_manager/session_manager.rs:1-39]()

## See Also

- 错误映射与 `TypedReceipt` 序列化（`loom-mcp/src/error_mapper/error_mapper.rs`）
- 工具缓存与 schema 注册（`loom-mcp/src/tool_cache/interface_tests.rs`）
- 内容存储与 blob 引用生命周期（`loom-core/src/content_store/impl_local.rs`）
- TypeScript SDK（`typescript-sdk/package.json`）

---

<a id='page-ops-security-failures'></a>

## 安装、Postinstall、Doctor、Vault 与常见故障

### 相关页面

相关主题：[Loom 概览、信任区与 Crate 拓扑](#page-overview-architecture), [CLI、MCP 工具与多语言 SDK](#page-cli-mcp-sdks), [会话生命周期、清单哈希链与回放引擎](#page-session-manifest-replay)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [loom-core/src/lib.rs](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/lib.rs)
- [loom-core/src/vault/mod.rs](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/vault/mod.rs)
- [loom-core/src/vault/vault.rs](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/vault/vault.rs)
- [loom-core/src/vault/impl_local.rs](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/vault/impl_local.rs)
- [loom-core/src/vault/audit_payloads.rs](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/vault/audit_payloads.rs)
- [loom-core/src/manifest_writer/manifest_writer.rs](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/manifest_writer/manifest_writer.rs)
- [loom-core/src/manifest_writer/mod.rs](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/manifest_writer/mod.rs)
- [loom-core/src/content_store/impl_local.rs](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/content_store/impl_local.rs)
- [loom-core/src/session_manager/session_manager.rs](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/session_manager/session_manager.rs)
- [loom-core/src/receipt_builder/capture_policy.rs](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/receipt_builder/capture_policy.rs)
- [loom-mcp/src/mcp_dispatcher/mcp_dispatcher.rs](https://github.com/mentiora-ai/loom/blob/main/loom-mcp/src/mcp_dispatcher/mcp_dispatcher.rs)
- [mocks/README.md](https://github.com/mentiora-ai/loom/blob/main/mocks/README.md)
- [release v0.9.2](https://github.com/mentiora-ai/loom/releases/tag/v0.9.2)
- [release v0.11.1](https://github.com/mentiora-ai/loom/releases/tag/v0.11.1)
</details>

# 安装、Postinstall、Doctor、Vault 与常见故障

本页面向刚装好 Loom 或在生产环境中遇到「装上了但跑不起来」类问题的工程师，覆盖 `loom install` / `loom postinstall` 的实际语义、`loom doctor` 的诊断边界、`Vault` 凭据网关以及几条历史上真实踩过的坑（[release v0.9.2](https://github.com/mentiora-ai/loom/releases/tag/v0.9.2)、[release v0.11.1](https://github.com/mentiora-ai/loom/releases/tag/v0.11.1)）。

## 安装与 Postinstall

`loom postinstall` 负责把 daemon、shim、Chromium、per-method schema、macOS 上的 launchd plist 等资源落到正确位置；它是 `loom-core` 之外、由 CLI 侧驱动的预条件动作，与运行时库是解耦的（运行时库对外只暴露领域模块如 `manifest_writer`、`vault`、`replay_engine` 等，见 [loom-core/src/lib.rs:1-25](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/lib.rs#L1-L25)）。

历史上有两个被反复踩过的回归：

- **Chromium 没就位（issue #70）**：0.9.1 之前的 Linux postinstall 表面上 `exit 0`，但实际二进制没解压好，导致后续 `loom doctor` 报 `chromium binary not found`。0.9.2 在 postinstall 内部补齐了下载与权限步骤，并把 doctor 的 chromium 探测当作 sanity check 之一。
- **Schema 落盘回归（v0.11.1）**：0.11.0 把 schema 从「embedded」改为「per-method 文件 + daemon 启动时加载」，但 `loom postinstall` 没有同步把所有 schema 复制到磁盘。结果是 `loom.web.navigate` 带 `until` / `timeout_ms` 时被 daemon 报 `schema_violation: field 'params' expected field_unknown got object`，而 `web.wait_for` 用同样的参数却能通过——根因就是 daemon 找不到对应 schema 文件。v0.11.1 改回 embedded-first 校验，schema 跟随二进制一起编译，不再依赖 postinstall 的写盘动作。

## loom doctor 的诊断能力

`loom doctor` 是一组静态与动态检查的汇总：

| 检查类别 | 含义 |
|---|---|
| 文件存在性 | Chromium、shim、daemon 二进制、launchd plist |
| 进程健康 | daemon 进程是否在跑（0.9.1 起通过 `ShimRequest::Health` CBOR 变体做深探针，返回 `ShimHealthInf…`，由 shim-side handler 填充；见 [release v0.9.1](https://github.com/mentiora-ai/loom/releases/tag/v0.9.1)） |
| Schema 一致性 | embedded schema 与 daemon 期望一致（v0.11.1 后该检查项不再依赖磁盘文件） |
| Vault 依赖 | Keychain 后端是否就绪（详见下节） |

注意：doctor 的「进程在跑」≠「能正常服务请求」。如果 daemon 启动后 IPC socket 与 Tokio I/O driver 在 fd 3 竞态（0.9.2 之前的 issue #71），所有 `web.*` 会以 `surface_trap` 形式被 surface layer 截住——`loom doctor` 不会自动识别这种「半活」状态，必须配合 `daemon.health({deep: true})` 或复现一次 `web.navigate` 才能暴露。

## Vault 与威胁模型

`Vault` 是凭据生命周期的事实源，其 trait 与实现分别在 [loom-core/src/vault/vault.rs](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/vault/vault.rs) 与 [loom-core/src/vault/impl_local.rs](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/vault/impl_local.rs)。`LocalVault::grant` 强制两道门：

1. **凭据类型白名单**：当前仅放行 `CredentialType::OAuth` 与 `CredentialType::Cookie`；`ApiKey` / `Saml` / `Basic` 仍是保留 slot，会以 `vault_credential_type_unsupported` 拒绝（错误上下文里会带 `allowed_types: ["oauth2_authorization_code_pkce","cookie"]`，见 [vault/impl_local.rs:50-80](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/vault/impl_local.rs#L50-L80)）。
2. **威胁模型确认**：调用方必须把 `opts.threat_model_acknowledged` 置为 `true`，否则以 `vault_threat_model_missing` 拒绝（见 [vault/impl_local.rs:90-130](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/vault/impl_local.rs#L90-L130)）。

威胁模型文档本身是受测的：单测会校验仓库内的 `vault_threat_model.md` 至少包含 `# Vault Threat Model` 标题与 `## Attacker Classes` / `## Security Goals` / `## Trust Boundaries` / `## Abuse Cases` 四个固定二级章节，缺一即失败。

```mermaid
flowchart TD
    A[grant call] --> B{credential_type in OAuth/Cookie?}
    B -- no --> X1[vault_credential_type_unsupported]
    B -- yes --> C{threat_model_acknowledged?}
    C -- no --> X2[vault_threat_model_missing]
    C -- yes --> D[secret exists check]
    D --> E[append_audit GrantIssued]
    E --> F[(manifest hash chain)]
```

grant 成功后会通过 `ManifestWriter::append_audit` 把一条 `AuditEntry { audit_kind: GrantIssued, … }` 追加到与 action receipt 同一条 hash chain 上（见 [manifest_writer/manifest_writer.rs:120-160](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/manifest_writer/manifest_writer.rs#L120-L160)），从而把凭据生命周期与 NFR-DET-01 决定的确定性回放哈希绑定在一起——任何 grant 的审计回放都会落进同样的 chain 校验。

## 常见故障速查

| 症状 | 版本 / Issue | 根因 |
|---|---|---|
| Linux 新装后 `loom doctor` 报 `chromium binary not found` | 0.9.2 修复 #70 | postinstall 未把 Chromium 落到正确路径 |
| 所有 `web.*` 返回 `surface_trap` | 0.9.2 修复 #71 | shim IPC socket 与 Tokio I/O driver 在 fd 3 竞态 |
| `loom.web.navigate` 带 `until/timeout_ms` 被 `schema_violation` 拒 | 0.11.1 修复 | 0.11.0 改用磁盘 schema 但 postinstall 未落盘 |
| Vault grant 报 `vault_threat_model_missing` | 行为正确 | 调用方未设 `threat_model_acknowledged=true` |
| GC 误删活跃 blob | 见 [content_store/impl_local.rs:1-40](https://github.com/mentiora-ai/loom/blob/main/loom-core/src/content_store/impl_local.rs#L1-L40) | `collect_referenced_blobs` 必须解码 `receipt_canonical_bytes` 才能找到 CAS 引用，否则会把仍在被 manifest 指向的 DOM/screenshot blob 回收掉 |

## See Also

- [release v0.11.1 Embedded-First Schema Validation](https://github.com/mentiora-ai/loom/releases/tag/v0.11.1)
- [release v0.9.2 Linux-enablement patch](https://github.com/mentiora-ai/loom/releases/tag/v0.9.2)
- [release v0.9.1 daemon-health deep probe](https://github.com/mentiora-ai/loom/releases/tag/v0.9.1)
- [issue #179 e2e-real-world scheduled run failed](https://github.com/mentiora-ai/loom/issues/179)

---

<!-- evidence_pipeline_checked: true -->
<!-- evidence_injected: true -->

---

## Doramagic 踩坑日志

项目：mentiora-ai/loom

摘要：发现 8 个潜在踩坑项，其中 1 个为 high/blocking；最高优先级：运行坑 - 来源证据：e2e-real-world: scheduled run failed。

## 1. 运行坑 · 来源证据：e2e-real-world: scheduled run failed

- 严重度：high
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个运行相关的待验证问题：e2e-real-world: scheduled run failed
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 证据：community_evidence:github | https://github.com/mentiora-ai/loom/issues/179 | 来源讨论提到 macos 相关条件，需在安装/试用前复核。

## 2. 配置坑 · 可能修改宿主 AI 配置

- 严重度：medium
- 证据强度：source_linked
- 发现：项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主，或安装命令涉及用户配置目录。
- 对用户的影响：安装可能改变本机 AI 工具行为，用户需要知道写入位置和回滚方法。
- 证据：capability.host_targets | https://github.com/mentiora-ai/loom | host_targets=mcp_host, claude_code, claude

## 3. 能力坑 · 能力判断依赖假设

- 严重度：medium
- 证据强度：source_linked
- 发现：README/documentation is current enough for a first validation pass.
- 对用户的影响：假设不成立时，用户拿不到承诺的能力。
- 证据：capability.assumptions | https://github.com/mentiora-ai/loom | README/documentation is current enough for a first validation pass.

## 4. 维护坑 · 维护活跃度未知

- 严重度：medium
- 证据强度：source_linked
- 发现：未记录 last_activity_observed。
- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。
- 证据：evidence.maintainer_signals | https://github.com/mentiora-ai/loom | last_activity_observed missing

- 严重度：medium
- 证据强度：source_linked
- 发现：no_demo
- 证据：downstream_validation.risk_items | https://github.com/mentiora-ai/loom | no_demo; severity=medium

## 6. 安全/权限坑 · 存在评分风险

- 严重度：medium
- 证据强度：source_linked
- 发现：no_demo
- 对用户的影响：风险会影响是否适合普通用户安装。
- 证据：risks.scoring_risks | https://github.com/mentiora-ai/loom | no_demo; severity=medium

## 7. 维护坑 · issue/PR 响应质量未知

- 严重度：low
- 证据强度：source_linked
- 发现：issue_or_pr_quality=unknown。
- 对用户的影响：用户无法判断遇到问题后是否有人维护。
- 证据：evidence.maintainer_signals | https://github.com/mentiora-ai/loom | issue_or_pr_quality=unknown

## 8. 维护坑 · 发布节奏不明确

- 严重度：low
- 证据强度：source_linked
- 发现：release_recency=unknown。
- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。
- 证据：evidence.maintainer_signals | https://github.com/mentiora-ai/loom | release_recency=unknown

<!-- canonical_name: mentiora-ai/loom; human_manual_source: deepwiki_human_wiki -->
