# L4 -- 工程实现与部署拓扑层

**文档版本**: 1.0
**适用项目**: sgClaw (业数融合一平台 AI Agent 底座)
**编制日期**: 2026-03-03

**读者**: 开发者、DevOps、测试工程师 -- 需要搭建开发环境、理解构建流程、执行测试、部署发布。

---

## 1. 仓库结构

sgClaw 系统的代码分布在两个仓库中：独立的 sgClaw Rust 仓库和 SuperRPA Chromium 仓库。
前者承载 Agent 核心逻辑，后者承载浏览器侧集成代码和前端 UI。

### 1.1 sgClaw 仓库 (Rust 端)

```
/home/zyl/projects/sgClaw/
├── Cargo.toml                    # 项目配置、依赖声明、编译优化
├── Cargo.lock                    # 依赖版本锁定
├── src/
│   ├── main.rs                   # 入口: pipe I/O 初始化, tokio runtime 启动
│   ├── agent/
│   │   ├── mod.rs                # Agent 模块导出
│   │   ├── runtime.rs            # ZeroClaw ReAct 循环 (think -> act -> observe)
│   │   └── critic.rs             # 输出质量评估 + Circuit Breaker 熔断器
│   ├── pipe/
│   │   ├── mod.rs                # Pipe 模块导出
│   │   ├── protocol.rs           # JSON Line 编解码, 消息类型定义
│   │   ├── handshake.rs          # 版本协商 + HMAC 密钥交换
│   │   └── browser_tool.rs       # BrowserPipeTool: 自定义 Tool trait 实现
│   ├── skill/
│   │   ├── mod.rs                # Skill 模块导出
│   │   ├── loader.rs             # 技能发现 + 签名校验 + 沙箱加载
│   │   └── registry.rs           # 技能注册表 (名称 -> 技能映射)
│   ├── llm/
│   │   ├── mod.rs                # LLM 模块导出
│   │   ├── provider.rs           # Provider trait 定义 (统一接口)
│   │   ├── claude.rs             # Claude API 实现 (streaming)
│   │   ├── openai.rs             # OpenAI/兼容 API 实现
│   │   └── ollama.rs             # 本地 Ollama 实现
│   ├── memory/
│   │   ├── mod.rs                # Memory 模块导出
│   │   ├── short_term.rs         # Ring Buffer 短期对话记忆
│   │   └── long_term.rs          # SQLite + 向量存储 长期知识库
│   ├── security/
│   │   ├── mod.rs                # Security 模块导出
│   │   ├── mac_policy.rs         # 域名 / Action 白名单校验
│   │   └── hmac.rs               # HMAC-SHA256 消息签名与验证
│   └── config/
│       ├── mod.rs                # Config 模块导出
│       └── settings.rs           # 配置文件加载 (TOML / 环境变量)
├── skills/                       # 内置技能目录
│   ├── builtin/                  # 预置业务技能脚本
│   └── registry.json             # 技能清单 + 签名哈希
├── tests/
│   ├── integration/              # 集成测试 (pipe 协议, 端到端)
│   └── fixtures/                 # 测试数据 (mock LLM 响应, JSON 样例)
├── docs/                         # 设计文档 (L0-L4 分层)
├── scripts/
│   ├── build-linux.sh            # Linux musl 静态链接构建脚本
│   ├── build-windows.sh          # Windows MSVC 交叉编译脚本
│   └── install-to-superrpa.sh    # 二进制部署到 SuperRPA 目录
└── .github/
    └── workflows/                # CI/CD 流水线定义
```

### 1.2 SuperRPA 新增文件 (C++ 端)

在已有 SuperRPA 仓库中新增一个 `sgclaw/` 子目录，约 500-600 行 C++ 代码。
所有新增文件位于 `src/chrome/browser/superrpa/sgclaw/` 下，与已有子系统平级。

```
src/chrome/browser/superrpa/
├── BUILD.gn                       # [修改] 新增 :sgclaw source_set 依赖
├── sgclaw/                        # [新增目录]
│   ├── sg_claw_process_host.h     # 进程宿主: 生命周期管理 (Start/Stop/OnCrash)
│   ├── sg_claw_process_host.cc    # ~200-300 行, Singleton, 管道创建与进程启动
│   ├── pipe_listener.h            # 异步读取循环: 解析 JSON Line 消息
│   ├── pipe_listener.cc           # ~150 行, base::FileDescriptorWatcher
│   ├── mac_whitelist_check.h      # Pipe 来源 MAC 校验: action + domain 白名单
│   ├── mac_whitelist_check.cc     # ~100 行, 与已有 rules.json 集成
│   └── BUILD.gn                   # 子模块构建声明
```

已有文件的修改点 (最小侵入):

| 文件 | 修改内容 | 行数变更 |
|------|---------|---------|
| `superrpa/BUILD.gn` | deps 新增 `":sgclaw"` | +1 行 |
| `ui/ui_page_controller.cc` | 新增 Agent 启停的 FunctionsUI handler | +~50 行 |

### 1.3 Side Panel 新增文件 (前端)

前端变更位于 agent-vue 应用中，新增一个 Vue 组件用于 Agent 控制面板。
agent-vue 基于 Vue 2.6 + Element UI，构建产物部署到 Side Panel 的 agent/ 目录。

```
agent-vue/src/
├── components/
│   └── SgClawControl.vue          # [新增] Agent 启停控制 + 状态展示 + 任务输入
```

构建产物部署位置:

```
src/chrome/browser/resources/superrpa/panels/apps/agent/
├── css/
├── js/
├── index.html
└── ...                            # npm run build:production 输出
```

---

## 2. 构建系统

### 2.1 Rust 构建 (sgClaw)

#### 2.1.1 Cargo.toml 核心配置

```toml
[package]
name = "sgclaw"
version = "0.1.0"
edition = "2021"
description = "AI Agent engine for SuperRPA browser"

[dependencies]
zeroclaw = { version = "0.x", features = ["react-loop", "mcp"] }
rmcp = { version = "0.x", features = ["client", "transport-stdio"] }
tokio = { version = "1", features = ["full"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
rusqlite = { version = "0.31", features = ["bundled"] }
hmac = "0.12"
sha2 = "0.10"
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["json"] }
clap = { version = "4", features = ["derive"] }
thiserror = "1"
anyhow = "1"

[profile.release]
opt-level = "z"          # 最小体积优化
lto = true               # Link-Time Optimization
codegen-units = 1         # 单 codegen unit, 更好的优化
strip = true              # 去除符号表
panic = "abort"           # abort 而非 unwind, 减小体积
```

#### 2.1.2 构建命令

```bash
# --- 开发构建 (快速编译, 含调试信息) ---
cargo build

# --- Release Linux (银河麒麟 V10 目标) ---
# musl 静态链接, 无 glibc 依赖
cargo build --release --target x86_64-unknown-linux-musl
strip target/x86_64-unknown-linux-musl/release/sgclaw

# 验证产物
file target/x86_64-unknown-linux-musl/release/sgclaw
# 预期输出: ELF 64-bit LSB executable, x86-64, statically linked
ls -lh target/x86_64-unknown-linux-musl/release/sgclaw
# 预期大小: ~8.8 MB

# --- Release Windows ---
cargo build --release --target x86_64-pc-windows-msvc

# 验证产物
ls -lh target/x86_64-pc-windows-msvc/release/sgclaw.exe
# 预期大小: ~9.0 MB
```

#### 2.1.3 构建产物位置

```
target/
├── debug/
│   └── sgclaw                         # 开发构建 (~30-50 MB, 含调试符号)
├── x86_64-unknown-linux-musl/
│   └── release/
│       └── sgclaw                     # Linux release (~8.8 MB)
└── x86_64-pc-windows-msvc/
    └── release/
        └── sgclaw.exe                 # Windows release (~9.0 MB)
```

#### 2.1.4 交叉编译配置

在开发机上为 Linux musl 目标编译需要安装 musl 工具链:

```bash
# Ubuntu / 银河麒麟
sudo apt install musl-tools

# 添加 Rust target
rustup target add x86_64-unknown-linux-musl

# 如果需要 Windows 交叉编译 (从 Linux 编译 Windows 产物)
# 需要 cargo-xwin 或在 Windows CI 上构建
cargo install cargo-xwin
cargo xwin build --release --target x86_64-pc-windows-msvc
```

### 2.2 C++ 构建 (SuperRPA 新增部分)

#### 2.2.1 BUILD.gn 配置

新增 `sgclaw/BUILD.gn`:

```gn
# src/chrome/browser/superrpa/sgclaw/BUILD.gn

source_set("sgclaw") {
  sources = [
    "sg_claw_process_host.cc",
    "sg_claw_process_host.h",
    "pipe_listener.cc",
    "pipe_listener.h",
    "mac_whitelist_check.cc",
    "mac_whitelist_check.h",
  ]
  deps = [
    "//base",
    "//content/public/browser",
  ]
}

source_set("sgclaw_unit_tests") {
  testonly = true
  sources = [
    "sg_claw_process_host_unittest.cc",
    "pipe_listener_unittest.cc",
    "mac_whitelist_check_unittest.cc",
  ]
  deps = [
    ":sgclaw",
    "//base",
    "//base/test:test_support",
    "//testing/gtest",
  ]
}
```

在父级 `superrpa/BUILD.gn` 中添加依赖:

```gn
source_set("superrpa") {
  # ... 已有 sources ...
  deps = [
    ":ai",
    ":sgclaw",                    # <-- 新增
    "//base",
    # ... 已有 deps ...
  ]
}
```

#### 2.2.2 构建命令

```bash
# 进入 Chromium 源码目录
cd /home/zyl/projects/superRpa/src

# 生成构建配置 (仅首次或 BUILD.gn 变更时)
gn gen out/Default

# 增量编译 Chrome (24 并发)
autoninja -j 24 -C out/Default chrome

# 单独编译 sgclaw 单元测试
autoninja -j 24 -C out/Default sgclaw_unittests

# 运行 sgclaw 单元测试
./out/Default/sgclaw_unittests
```

### 2.3 前端构建 (agent-vue)

agent-vue 使用 Vue CLI 构建，产物部署到浏览器资源目录。

```bash
# 进入 agent-vue 目录
cd /home/zyl/projects/superRpa/agent-vue

# 安装依赖 (首次)
npm install

# 开发模式
npm run serve

# 生产构建
npm run build:production

# 构建产物位于 dist/ 目录
ls dist/
# css/  js/  index.html  favicon.ico  ...
```

前端技术栈:
- Vue 2.6.14 + Vue Router 3.5 + Vuex 3.6
- Element UI 2.15
- Axios 1.9 (HTTP 请求)
- 无新增依赖，SgClawControl.vue 使用已有框架组件

### 2.4 联合构建流程

完整的从零构建步骤，适用于全新开发环境或 CI 流水线:

```
┌─────────────────────────────────────────────────────────────────┐
│                      联合构建流程                                │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  Step 1: 构建 sgclaw (Rust)                                     │
│  ┌──────────────────────────────────────────────────────────┐   │
│  │ cd /home/zyl/projects/sgClaw                             │   │
│  │ cargo build --release --target x86_64-unknown-linux-musl │   │
│  │ strip target/x86_64-unknown-linux-musl/release/sgclaw    │   │
│  │ cargo test                                               │   │
│  └──────────────────────────────┬───────────────────────────┘   │
│                                 │ sgclaw (~8.8 MB)              │
│                                 ▼                               │
│  Step 2: 复制二进制到 SuperRPA 构建目录                          │
│  ┌──────────────────────────────────────────────────────────┐   │
│  │ cp target/x86_64-unknown-linux-musl/release/sgclaw \     │   │
│  │    /home/zyl/projects/superRpa/repack_work/              │   │
│  │    extract_YYYYMMDD/opt/chromium.org/chromium/sgclaw     │   │
│  └──────────────────────────────┬───────────────────────────┘   │
│                                 │                               │
│                                 ▼                               │
│  Step 3: 构建 SuperRPA (C++)                                    │
│  ┌──────────────────────────────────────────────────────────┐   │
│  │ cd /home/zyl/projects/superRpa/src                       │   │
│  │ gn gen out/Default                                       │   │
│  │ autoninja -j 24 -C out/Default chrome                    │   │
│  └──────────────────────────────┬───────────────────────────┘   │
│                                 │ chrome (Chromium 主程序)      │
│                                 ▼                               │
│  Step 4: 构建 agent-vue (前端)                                  │
│  ┌──────────────────────────────────────────────────────────┐   │
│  │ cd /home/zyl/projects/superRpa/agent-vue                 │   │
│  │ npm install && npm run build:production                  │   │
│  └──────────────────────────────┬───────────────────────────┘   │
│                                 │ dist/ (HTML + CSS + JS)       │
│                                 ▼                               │
│  Step 5: 部署前端到 Side Panel 资源目录                          │
│  ┌──────────────────────────────────────────────────────────┐   │
│  │ cp -r agent-vue/dist/* \                                 │   │
│  │    src/chrome/browser/resources/superrpa/panels/         │   │
│  │    apps/agent/                                           │   │
│  └──────────────────────────────────────────────────────────┘   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘
```

自动化构建脚本 (`scripts/build-linux.sh`):

```bash
#!/bin/bash
set -euo pipefail

SGCLAW_DIR="/home/zyl/projects/sgClaw"
SUPERRPA_DIR="/home/zyl/projects/superRpa"
TARGET="x86_64-unknown-linux-musl"

echo "=== [1/4] Building sgclaw (Rust) ==="
cd "$SGCLAW_DIR"
cargo build --release --target "$TARGET"
strip "target/$TARGET/release/sgclaw"
echo "  Binary size: $(du -h target/$TARGET/release/sgclaw | cut -f1)"

echo "=== [2/4] Running sgclaw tests ==="
cargo test --release --target "$TARGET"

echo "=== [3/4] Building SuperRPA (C++) ==="
cd "$SUPERRPA_DIR/src"
autoninja -j 24 -C out/Default chrome

echo "=== [4/4] Building agent-vue ==="
cd "$SUPERRPA_DIR/agent-vue"
npm run build:production

echo "=== Build complete ==="
```

---

## 3. 依赖管理

### 3.1 Rust 依赖 (Cargo.toml)

| 依赖 | 版本 | 用途 | 可选 |
|------|------|------|------|
| `zeroclaw` | latest | Agent Runtime: ReAct 循环, Tool/Provider trait | 否 |
| `rmcp` | latest | MCP Client: 连接外部 MCP Server 获取工具 | features: client, transport-stdio |
| `tokio` | 1.x | 异步运行时: 事件循环, I/O, 定时器 | features: full |
| `serde` | 1.x | 序列化框架: derive 宏 | features: derive |
| `serde_json` | 1.x | JSON 编解码: pipe 协议消息 | 否 |
| `rusqlite` | 0.31+ | SQLite 存储: 长期记忆, Skill 缓存 | features: bundled (内嵌 SQLite) |
| `hmac` | 0.12 | HMAC 消息认证码: pipe 消息签名 | 否 |
| `sha2` | 0.10 | SHA-256 哈希: 配合 hmac 使用 | 否 |
| `tracing` | 0.1 | 结构化日志: span, event, 链路追踪 | 否 |
| `tracing-subscriber` | 0.3 | 日志输出: JSON 格式, 文件/stderr 输出 | features: json |
| `clap` | 4.x | 命令行参数解析: 配置文件路径, 日志级别 | features: derive |
| `thiserror` | 1.x | 错误类型定义: 自定义 Error enum | 否 |
| `anyhow` | 1.x | 错误传播: 顶层错误处理 | 否 |

依赖锁定策略:
- `Cargo.lock` 提交到版本控制，确保可重复构建
- 依赖更新通过 `cargo update` 手动触发，经 CI 验证后合并
- `rusqlite` 使用 `bundled` feature，内嵌 SQLite 源码编译，避免系统库版本差异

### 3.2 C++ 依赖

sgClaw 的 C++ 部分仅使用 Chromium 已有的基础库，无新增第三方依赖:

| 依赖 | GN 路径 | 用途 |
|------|---------|------|
| base | `//base` | 线程 (SequencedTaskRunner), 回调 (OnceCallback), 进程管理 (LaunchProcess), 文件监听 (FileDescriptorWatcher) |
| content | `//content/public/browser` | BrowserContext, WebContents 交互接口 |

无需引入 Mojo IPC -- sgClaw 使用更轻量的 STDIO Pipe 通信。
Side Panel UI 通过已有的 `rpa_page_handler` Mojo 接口发送启停命令，
该接口已在 SuperRPA 中实现，仅需新增 2 个 handler method。

### 3.3 前端依赖

无新增 npm 依赖。SgClawControl.vue 使用 agent-vue 已有的技术栈:

| 依赖 | 版本 | 用途 |
|------|------|------|
| `vue` | 2.6.14 | 组件框架 |
| `element-ui` | 2.15.14 | UI 组件库 (Button, Input, Message) |
| `vuex` | 3.6.2 | 状态管理 (Agent 运行状态) |
| `axios` | 1.9.0 | HTTP 请求 (如需与 local_service 通信) |

---

## 4. 打包与发布

### 4.1 Linux .deb 打包

SuperRPA 以 `.deb` 包形式发布到银河麒麟 V10 SP1。sgClaw 的产物集成到现有打包流程中。

当前 .deb 包结构 (`repack_work/extract_YYYYMMDD/`):

```
DEBIAN/
├── control                  # 包元数据 (版本、大小、描述)
└── postinst                 # 安装后脚本 (chmod +x)
opt/chromium.org/chromium/
├── chrome                   # Chromium 主程序 (~1.6 GB)
├── superrpa-chromium        # 启动脚本 (wrapper)
├── node/                    # Node.js 运行时
├── local_service/           # 本地 HTTP 服务
├── locales/                 # 语言包
├── *.pak                    # 资源文件
├── sgclaw                   # [新增] AI Agent 引擎
└── sgclaw-skills/           # [新增] 技能目录
    ├── builtin/             # 内置技能脚本
    └── registry.json        # 技能清单
usr/bin/
└── superrpa-chromium        # 系统级启动链接
```

#### 4.1.1 修改 repack-with-service.sh

在现有 `scripts/repack-with-service.sh` 中新增 sgclaw 安装步骤:

```bash
# --- 新增: Install sgclaw binary ---
echo "[N/N] Installing sgclaw AI Agent..."
SGCLAW_BIN="/home/zyl/projects/sgClaw/target/x86_64-unknown-linux-musl/release/sgclaw"
SGCLAW_SKILLS="/home/zyl/projects/sgClaw/skills"

if [ -f "$SGCLAW_BIN" ]; then
    cp "$SGCLAW_BIN" "$CHROMIUM_DIR/sgclaw"
    chmod +x "$CHROMIUM_DIR/sgclaw"
    echo "  sgclaw binary: $CHROMIUM_DIR/sgclaw ($(du -h "$SGCLAW_BIN" | cut -f1))"
fi

if [ -d "$SGCLAW_SKILLS" ]; then
    mkdir -p "$CHROMIUM_DIR/sgclaw-skills"
    cp -r "$SGCLAW_SKILLS/"* "$CHROMIUM_DIR/sgclaw-skills/"
    echo "  sgclaw skills: $CHROMIUM_DIR/sgclaw-skills/"
fi
```

#### 4.1.2 postinst 修改

```bash
#!/bin/bash
set -e

CHROMIUM_DIR=/opt/chromium.org/chromium

# 已有权限设置
chmod +x "$CHROMIUM_DIR/node/bin/node" 2>/dev/null || true
chmod +x "$CHROMIUM_DIR/superrpa-chromium" 2>/dev/null || true

# 新增: sgclaw 权限
chmod +x "$CHROMIUM_DIR/sgclaw" 2>/dev/null || true

echo "SuperRPA Chromium with LocalService installed successfully"
```

#### 4.1.3 包大小影响

```
当前 .deb 包大小:           ~447 MB (含 Node.js local_service)
sgclaw 二进制:              + ~8.8 MB
sgclaw-skills/:             + ~0.2 MB (JSON + JS 技能脚本)
────────────────────────────────────────
预计新 .deb 包大小:          ~456 MB (增加约 2%)
```

### 4.2 Windows 安装包

Windows 端的 sgclaw.exe 放置在 SuperRPA 浏览器安装目录下:

```
C:\Program Files\SuperRPA Chromium\
├── chrome.exe
├── sgclaw.exe               # [新增] ~9 MB
├── sgclaw-skills\           # [新增] 技能目录
│   ├── builtin\
│   └── registry.json
└── ...
```

安装程序修改要点:
- 在 NSIS/Inno Setup 脚本中新增 sgclaw.exe 和 sgclaw-skills/ 的文件拷贝项
- 无需注册服务或添加注册表项 -- sgclaw 由 chrome.exe 按需启动
- 卸载时一并删除 sgclaw 相关文件和 SQLite 数据库

### 4.3 升级策略

#### 4.3.1 sgclaw 二进制升级

sgclaw 二进制本身无状态（运行时状态在内存中，持久状态在 SQLite 中），
升级策略为直接覆盖:

```bash
# 停止 Agent (如果正在运行，由 SgClawProcessHost::Stop() 完成)
# 替换二进制
cp sgclaw_new /opt/chromium.org/chromium/sgclaw
chmod +x /opt/chromium.org/chromium/sgclaw
# 下次用户点击 [启动] 时加载新版本
```

#### 4.3.2 Skills 仓库更新

技能文件支持增量更新:

```
更新流程:
  1. 下载新版 registry.json (含每个技能的 SHA-256 哈希)
  2. 对比本地 registry.json, 识别变更的技能文件
  3. 仅下载变更的 .js 文件
  4. 校验每个文件的 SHA-256 签名
  5. 原子替换 (写入临时文件 -> rename)
```

#### 4.3.3 数据库迁移

SQLite 数据库使用 schema 版本管理:

```sql
-- 内置 user_version pragma 记录 schema 版本
PRAGMA user_version;  -- 返回当前版本号

-- sgclaw 启动时检查并执行迁移
-- migration_001.sql: 初始 schema
-- migration_002.sql: 新增索引
-- migration_003.sql: 新增表
```

迁移规则:
- 向前兼容: 新版 sgclaw 可读取旧版数据库
- 自动迁移: 启动时检测 user_version，依次执行未应用的迁移脚本
- 备份优先: 迁移前自动备份 `.db` 文件为 `.db.bak.{timestamp}`

---

## 5. 测试策略

### 5.1 测试金字塔

```
                 ┌───────────────────┐
                 │    E2E 验收测试    │  少量, 模拟完整用户场景
                 │    (mock LLM)     │  确保端到端可用
                 ├───────────────────┤
                 │                   │
                 │   Pipe 协议集成   │  真实 sgclaw 进程
                 │   测试            │  验证 pipe 通信正确性
                 ├───────────────────┤
                 │                   │
                 │   C++ 单元测试    │  SgClawProcessHost
                 │   sgclaw_unittests│  PipeListener / MAC Check
                 ├───────────────────┤
                 │                   │
                 │  Rust 单元测试    │  大量, 覆盖核心逻辑
                 │  cargo test       │  mock LLM + mock pipe
                 │                   │
                 └───────────────────┘
```

测试比例指导:
- Rust 单元测试: ~70% (快速、隔离、可重复)
- C++ 单元测试: ~15% (进程管理、协议解析)
- Pipe 协议集成测试: ~10% (真实进程间通信)
- E2E 验收测试: ~5% (端到端场景，mock LLM 保证可重复)

### 5.2 Rust 单元测试

#### 5.2.1 Agent Runtime 测试

```bash
# 运行全部 Rust 测试
cargo test

# 运行特定模块测试
cargo test agent::runtime
cargo test agent::critic
```

测试内容:
- ReAct 循环: mock LLM 返回固定输出, 验证 think -> act -> observe 流转
- Circuit Breaker: 模拟连续失败, 验证熔断触发与恢复
- 最大步数限制: 验证超出 50 步自动终止

```rust
// 测试示例: Circuit Breaker 在连续 10 次失败后触发
#[tokio::test]
async fn test_circuit_breaker_triggers_after_threshold() {
    let mut breaker = CircuitBreaker::new(10);
    for _ in 0..10 {
        breaker.record_failure();
    }
    assert!(breaker.is_open());
}
```

#### 5.2.2 BrowserPipeTool 测试

测试内容:
- 命令序列化: Rust struct -> JSON Line 格式正确
- 响应反序列化: JSON Line -> Rust struct 解析正确
- 未知 action 拒绝: 非枚举值被正确拒绝
- HMAC 签名: 签名生成与校验一致

```bash
cargo test pipe::protocol
cargo test pipe::browser_tool
```

#### 5.2.3 MAC Policy 测试

测试内容:
- 域名白名单: 允许 / 拒绝 / 通配符匹配
- Action 白名单: 允许的 action 通过, eval/executeJsInPage 被拒绝
- 空白名单: 默认拒绝所有

```bash
cargo test security::mac_policy
```

#### 5.2.4 Memory 测试

测试内容:
- 短期记忆 Ring Buffer: 容量溢出时正确淘汰最旧条目
- 长期记忆 SQLite: CRUD 操作, schema 迁移, 并发读写安全
- 向量搜索: 相似度计算正确性

```bash
cargo test memory::short_term
cargo test memory::long_term
```

### 5.3 C++ 单元测试

新增 `sgclaw_unittests` target, 集成到 SuperRPA 现有测试体系。

```bash
# 构建
autoninja -j 24 -C out/Default sgclaw_unittests

# 运行
./out/Default/sgclaw_unittests
```

#### 5.3.1 SgClawProcessHost 测试

```
测试用例:
├─ Start() 在二进制存在时成功启动子进程
├─ Start() 在二进制不存在时返回错误
├─ Start() 重复调用不创建多个进程 (Singleton 保证)
├─ Stop() 发送 shutdown 命令后等待退出
├─ Stop() 超时后强制 kill
├─ OnProcessCrash() 记录崩溃日志, 不自动重启
└─ 析构函数确保清理子进程
```

#### 5.3.2 PipeListener 测试

```
测试用例:
├─ 正确解析单行 JSON 消息
├─ 正确解析多行连续消息 (JSON Line 流)
├─ 拒绝超过 1 MB 的消息 (防内存 DoS)
├─ 拒绝非 JSON 格式的行
├─ 管道断开时触发 OnPipeDisconnected 回调
└─ sequence_id 乱序时触发告警
```

#### 5.3.3 MAC Whitelist Check 测试

```
测试用例:
├─ 允许列表内的 action (click, type, navigate) 通过
├─ 禁止列表的 action (eval, executeJsInPage) 被拒绝
├─ expected_domain 与当前页面域名匹配时通过
├─ expected_domain 与当前页面域名不匹配时拒绝
├─ 速率限制: 同一域超过 10 次/秒后拒绝
└─ rules.json 加载失败时默认拒绝所有
```

### 5.4 Pipe 协议集成测试

集成测试启动真实的 sgclaw 进程，通过 pipe 发送命令并验证响应。
位于 `tests/integration/` 目录。

```bash
# 运行 Rust 集成测试 (需要先构建 sgclaw)
cargo test --test integration
```

#### 5.4.1 测试场景

```
┌─────────────────────────────────────────────────────────┐
│              Pipe 协议集成测试架构                        │
│                                                         │
│  Test Harness (Rust)                                    │
│  ┌───────────────────────────────────────────────┐      │
│  │                                               │      │
│  │  1. 创建 pipe pair                            │      │
│  │  2. spawn sgclaw 子进程                       │      │
│  │  3. 发送 handshake init 消息                  │      │
│  │  4. 验证 init_ack 响应                        │      │
│  │  5. 发送 command 消息                         │      │
│  │  6. 验证 response 格式和内容                  │      │
│  │  7. 发送 shutdown                             │      │
│  │  8. 验证进程正常退出                           │      │
│  │                                               │      │
│  │  sgclaw 使用 mock LLM (--llm-mock 标志)      │      │
│  │  mock LLM 返回固定 action 序列               │      │
│  │                                               │      │
│  └───────────────────────────────────────────────┘      │
└─────────────────────────────────────────────────────────┘
```

测试用例:
- Handshake 成功: init -> init_ack, 版本匹配
- Handshake 版本不匹配: sgclaw 返回错误并退出
- 命令执行: command -> response, 验证 seq 匹配
- 错误处理: 发送格式错误的 JSON, 验证 error response
- 管道断开: 关闭写端, 验证 sgclaw 退出码 0
- 大消息拒绝: 发送 > 1 MB 的消息, 验证被丢弃

### 5.5 E2E 验收测试

E2E 测试覆盖完整的用户场景: 从浏览器启动 Agent 到任务执行完成。
使用 mock LLM 确保测试可重复、无外部依赖。

#### 5.5.1 测试环境

```
┌─────────────────────────────────────────────────────────┐
│                 E2E 测试环境                              │
│                                                         │
│  SuperRPA Chrome (headless 模式)                        │
│  ├─ SgClawProcessHost 启动 sgclaw                      │
│  ├─ sgclaw 使用 mock LLM (固定输出)                     │
│  └─ 目标页面: 本地 test HTTP server (固定 HTML)         │
│                                                         │
│  验证链:                                                │
│  用户输入 -> Agent 理解 -> 生成 action -> Pipe 传输     │
│  -> MAC 校验 -> CommandRouter 执行 -> 页面 DOM 变更     │
│  -> 响应返回 -> Agent observe -> 任务完成               │
└─────────────────────────────────────────────────────────┘
```

#### 5.5.2 验收场景

| 场景 | 用户输入 | 预期行为 | 验收标准 |
|------|---------|---------|---------|
| 基本点击 | "点击提交按钮" | Agent 生成 click action | 按钮状态变为 disabled |
| 表单填写 | "在用户名框输入 admin" | Agent 生成 type action | input.value === "admin" |
| 页面导航 | "打开审批列表页面" | Agent 生成 navigate action | URL 变更为目标地址 |
| 域名拦截 | "访问 evil.com" | MAC 拒绝, Agent 报告失败 | 未发生导航 |
| 熔断触发 | 连续 10 次无效 action | Circuit Breaker 打开 | Agent 自动停止 |

### 5.6 测试运行汇总

```bash
# === Rust 全量测试 ===
cd /home/zyl/projects/sgClaw
cargo test                              # 单元测试 + 集成测试
cargo test --release                    # Release 模式测试 (更贴近生产)

# === C++ 全量测试 ===
cd /home/zyl/projects/superRpa/src
autoninja -j 24 -C out/Default sgclaw_unittests
./out/Default/sgclaw_unittests

# === 已有 SuperRPA 测试 (回归验证) ===
autoninja -j 24 -C out/Default superrpa_unittests
./out/Default/superrpa_unittests        # 14 test files

autoninja -j 24 -C out/Default superrpa_ai_unittests
./out/Default/superrpa_ai_unittests     # 3 test files

# === 代码质量检查 ===
cargo clippy -- -D warnings            # Rust lint
cargo fmt -- --check                    # Rust 格式化检查
cd /home/zyl/projects/superRpa/src && git cl format  # C++ 格式化
```

---

## 6. 开发环境搭建

### 6.1 Rust 开发环境

#### 6.1.1 基础安装

```bash
# 安装 Rust 工具链 (stable channel)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env

# 验证安装
rustc --version       # 预期: rustc 1.7x.x (stable)
cargo --version       # 预期: cargo 1.7x.x

# 安装编译目标
rustup target add x86_64-unknown-linux-musl    # Linux 静态链接
rustup target add x86_64-pc-windows-msvc       # Windows 交叉编译 (可选)

# 安装 musl 工具链 (Linux 静态链接依赖)
sudo apt update && sudo apt install -y musl-tools

# 安装开发工具
rustup component add clippy       # Lint 工具
rustup component add rustfmt      # 格式化工具
```

#### 6.1.2 项目克隆与首次构建

```bash
# 克隆项目
git clone <repo-url> /home/zyl/projects/sgClaw
cd /home/zyl/projects/sgClaw

# 开发构建 (首次编译需下载依赖，约 2-5 分钟)
cargo build

# 运行测试
cargo test

# 运行代码检查
cargo clippy -- -D warnings

# 格式化代码
cargo fmt
```

#### 6.1.3 开发模式运行

sgclaw 通过 STDIO 与浏览器通信，开发时可直接在终端模拟 pipe 输入:

```bash
# 方式一: 直接运行，手动输入 JSON Line
cargo run

# 在终端中输入 (模拟 Browser 发来的 init 消息):
{"type":"init","version":"1.0","hmac_key":"dev-test-key"}

# 方式二: 使用文件作为输入
cargo run < tests/fixtures/sample_session.jsonl

# 方式三: 使用 echo + pipe
echo '{"type":"init","version":"1.0"}' | cargo run
```

### 6.2 C++ 开发环境

C++ 开发依赖已有的 SuperRPA 开发环境。以下假设 depot_tools 和 Chromium 源码已就绪。

```bash
# 确认 depot_tools 在 PATH 中
which gn          # /path/to/depot_tools/gn
which autoninja   # /path/to/depot_tools/autoninja

# Chromium 源码目录
ls /home/zyl/projects/superRpa/src/chrome/browser/superrpa/
# 预期看到: BUILD.gn, ai/, cdp/, router/, session/, zombie/, ...

# 新增 sgclaw 文件后，重新生成构建配置
cd /home/zyl/projects/superRpa/src
gn gen out/Default

# 增量编译 (仅编译变更的文件)
autoninja -j 24 -C out/Default chrome

# 编译并运行 sgclaw 单元测试
autoninja -j 24 -C out/Default sgclaw_unittests
./out/Default/sgclaw_unittests
```

### 6.3 联合调试

#### 6.3.1 sgclaw 独立调试 (Rust 侧)

```bash
# 使用 RUST_LOG 控制日志级别
RUST_LOG=debug cargo run 2>sgclaw-debug.log

# 使用 lldb 或 gdb 调试
cargo build
lldb target/debug/sgclaw

# VS Code 调试 (需要 CodeLLDB 扩展)
# launch.json 配置见 6.4 节
```

#### 6.3.2 附加到浏览器进程调试 (C++ 侧)

```bash
# 启动 SuperRPA 浏览器
cd /home/zyl/projects/superRpa/src
./out/Default/chrome --no-sandbox

# 在另一终端查找 sgclaw 子进程 PID
pgrep -a sgclaw

# 使用 gdb 附加
gdb -p <sgclaw_pid>

# 或使用 gdb 附加到 chrome 主进程，在 sgclaw 相关代码设断点
gdb -p <chrome_pid>
(gdb) break SgClawProcessHost::Start
(gdb) continue
```

#### 6.3.3 日志查看

```bash
# sgclaw Rust 日志 (输出到 stderr, 不干扰 pipe 通信)
# 日志格式: JSON (tracing-subscriber json feature)
RUST_LOG=sgclaw=debug ./sgclaw 2>agent.log

# 实时查看日志
tail -f agent.log | python3 -m json.tool

# Chrome 日志 (含 SgClawProcessHost 日志)
./out/Default/chrome --no-sandbox --enable-logging --v=1 2>&1 | grep -i sgclaw
```

### 6.4 IDE 配置

#### 6.4.1 VS Code + rust-analyzer (推荐)

`.vscode/settings.json`:

```json
{
  "rust-analyzer.cargo.target": "x86_64-unknown-linux-musl",
  "rust-analyzer.check.command": "clippy",
  "rust-analyzer.check.extraArgs": ["--", "-D", "warnings"],
  "rust-analyzer.inlayHints.typeHints.enable": true,
  "rust-analyzer.inlayHints.parameterHints.enable": true,
  "[rust]": {
    "editor.formatOnSave": true,
    "editor.defaultFormatter": "rust-lang.rust-analyzer"
  }
}
```

`.vscode/launch.json` (调试配置):

```json
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "lldb",
      "request": "launch",
      "name": "Debug sgclaw",
      "cargo": {
        "args": ["build", "--bin=sgclaw"]
      },
      "args": [],
      "env": {
        "RUST_LOG": "debug"
      },
      "stdio": [null, null, null]
    },
    {
      "type": "lldb",
      "request": "launch",
      "name": "Debug unit tests",
      "cargo": {
        "args": ["test", "--no-run"]
      }
    }
  ]
}
```

推荐扩展:
- `rust-lang.rust-analyzer` -- Rust 语言支持
- `vadimcn.vscode-lldb` -- LLDB 调试器
- `tamasfe.even-better-toml` -- TOML 语法高亮
- `serayuzgur.crates` -- Cargo.toml 依赖版本提示

#### 6.4.2 CLion + Rust 插件

CLion 原生支持 Rust (通过内置插件)。打开 `Cargo.toml` 即可识别项目。

关键配置:
- File -> Settings -> Languages -> Rust -> Cargo target: `x86_64-unknown-linux-musl`
- Run Configuration -> Cargo Command: 选择 `run` 或 `test`
- External Tool: 可配置 `cargo clippy` 为保存时自动运行

---

## 7. 代码规范

### 7.1 Rust 规范

#### 7.1.1 格式化

使用 `rustfmt` 统一代码格式。配置文件 `rustfmt.toml`:

```toml
edition = "2021"
max_width = 100
tab_spaces = 4
use_field_init_shorthand = true
use_try_shorthand = true
```

执行命令:

```bash
# 格式化所有代码
cargo fmt

# 检查格式 (CI 中使用)
cargo fmt -- --check
```

#### 7.1.2 Lint

使用 `clippy` 进行静态分析，CI 中以 `-D warnings` 模式运行 (warnings 即 error):

```bash
cargo clippy -- -D warnings
```

#### 7.1.3 命名约定

| 元素 | 风格 | 示例 |
|------|------|------|
| 变量 / 函数 | snake_case | `process_message`, `pipe_reader` |
| 类型 / Trait | CamelCase | `BrowserPipeTool`, `MacPolicy` |
| 常量 | SCREAMING_SNAKE_CASE | `MAX_MESSAGE_SIZE`, `DEFAULT_TIMEOUT` |
| 模块 | snake_case | `browser_tool`, `mac_policy` |
| 文件名 | snake_case | `browser_tool.rs`, `mac_policy.rs` |

#### 7.1.4 错误处理

- 库级别错误: 使用 `thiserror` 定义具体的 Error enum
- 应用级别传播: 使用 `anyhow::Result` 简化错误链
- 禁止 `unwrap()` / `expect()` 出现在非测试代码中 (clippy 规则)

```rust
// 正确: 定义具体错误类型
#[derive(thiserror::Error, Debug)]
pub enum PipeError {
    #[error("message too large: {size} bytes (max {max})")]
    MessageTooLarge { size: usize, max: usize },

    #[error("invalid JSON: {0}")]
    InvalidJson(#[from] serde_json::Error),

    #[error("pipe disconnected")]
    Disconnected,
}

// 正确: 使用 ? 传播
fn read_message(reader: &mut BufReader<Stdin>) -> anyhow::Result<PipeMessage> {
    let line = reader.read_line()?;
    let msg: PipeMessage = serde_json::from_str(&line)?;
    Ok(msg)
}
```

#### 7.1.5 日志

使用 `tracing` 框架，提供结构化日志和链路追踪:

```rust
use tracing::{info, warn, error, debug, instrument};

#[instrument(skip(self), fields(seq = msg.seq))]
async fn handle_message(&self, msg: PipeMessage) -> Result<Response> {
    info!(action = %msg.action, "processing command");
    // ...
    if let Err(e) = result {
        error!(error = %e, "command failed");
    }
}
```

### 7.2 C++ 规范 (延续 SuperRPA)

延续 Chromium / SuperRPA 现有编码风格:

| 规则 | 说明 |
|------|------|
| 缩进 | 2 空格 |
| 命名 | CamelCase (类型), lower_case (变量), kCamelCase (常量) |
| 头文件 | `#ifndef` 守卫，使用 `#pragma once` 亦可 |
| 智能指针 | `std::unique_ptr` 优先，`scoped_refptr` 用于引用计数对象 |
| 线程安全 | `base::SequencedTaskRunner` 绑定，避免直接使用锁 |
| 格式化 | `git cl format` (调用 clang-format) |

```bash
# 格式化 C++ 代码
cd /home/zyl/projects/superRpa/src
git cl format
```

### 7.3 Git 规范

#### 7.3.1 分支策略

```
main (保护分支, 始终可部署)
  │
  ├── feature/sgclaw-pipe-protocol     # 功能分支
  ├── feature/sgclaw-mac-check         # 功能分支
  ├── fix/sgclaw-crash-on-large-msg    # 修复分支
  └── release/v1.0.0                   # 发布分支
```

规则:
- `main` 分支受保护，仅通过 PR 合并
- 功能分支从 `main` 创建，完成后合并回 `main`
- 命名格式: `{type}/{scope}-{brief-description}`
- type: feature, fix, refactor, test, docs

#### 7.3.2 Commit Message 格式

采用 Conventional Commits 规范:

```
<type>(<scope>): <subject>

<body>

<footer>
```

类型:
- `feat`: 新功能
- `fix`: Bug 修复
- `refactor`: 重构 (不改变行为)
- `test`: 测试
- `docs`: 文档
- `chore`: 构建/工具

示例:

```
feat(pipe): implement JSON Line protocol encoder/decoder

Add PipeMessage struct with serde serialization.
Support command, response, event message types.
Maximum message size: 1 MB.

Refs: #42
```

#### 7.3.3 Code Review 流程

```
开发者                      审查者
  │                           │
  ├─ 创建 feature 分支        │
  ├─ 编写代码 + 测试          │
  ├─ cargo test 通过          │
  ├─ cargo clippy 通过        │
  ├─ cargo fmt --check 通过   │
  ├─ 创建 PR ───────────────→ │
  │                           ├─ 代码审查
  │                           ├─ 运行 CI
  │  ◄──────── 审查意见 ──────│
  ├─ 修改代码                 │
  ├─ 推送更新 ──────────────→ │
  │                           ├─ Approve
  ├─ Squash & Merge ─────────→│
  │                           │
```

### 7.4 文档规范

#### 7.4.1 代码文档

```rust
//! 模块级文档: 描述模块的职责、设计决策和使用方式。
//!
//! # 示例
//!
//! ```rust
//! let tool = BrowserPipeTool::new(writer);
//! tool.execute(Action::Click { selector: "#btn".into() }).await?;
//! ```

/// 公开 API 文档: 描述函数的作用、参数、返回值和错误情况。
///
/// # Arguments
///
/// * `msg` - 待发送的 pipe 消息
///
/// # Errors
///
/// 返回 `PipeError::Disconnected` 当管道已断开。
pub async fn send(&mut self, msg: &PipeMessage) -> Result<(), PipeError> {
    // ...
}
```

规则:
- 所有 `pub` item 必须有 `///` 文档注释
- 每个模块的 `mod.rs` 必须有 `//!` 模块级文档
- 复杂逻辑在代码中使用 `//` 行内注释说明 "为什么"，而非 "做什么"

#### 7.4.2 CHANGELOG 维护

```markdown
# Changelog

## [Unreleased]

### Added
- Pipe protocol JSON Line encoder/decoder
- BrowserPipeTool with click, type, navigate actions

### Fixed
- Circuit Breaker not resetting after cooldown period

## [0.1.0] - 2026-03-03

### Added
- Initial project structure
- Agent Runtime based on ZeroClaw
```

---

## 8. 部署拓扑

### 8.1 目标环境

| 环境 | 用途 | 操作系统 | 硬件配置 |
|------|------|---------|---------|
| 开发环境 | 日常开发调试 | Ubuntu 22.04 / 银河麒麟 V10 | 16 GB RAM, SSD |
| 测试环境 | CI + 集成测试 | 银河麒麟 V10 SP1 | 8 GB RAM |
| 生产环境 | 最终部署 | 银河麒麟 V10 SP1 (x86_64) | 8 GB RAM |
| Windows 环境 | 开发 + 部分客户 | Windows 10 / 11 | 8 GB RAM |

### 8.2 生产部署目录结构

```
/opt/chromium.org/chromium/              # SuperRPA 安装根目录
├── chrome                               # Chromium 主程序 (~1.6 GB)
├── superrpa-chromium                    # 启动脚本 (包含 watchdog)
├── sgclaw                               # [新增] AI Agent 引擎 (~8.8 MB)
├── sgclaw-skills/                       # [新增] 技能目录
│   ├── builtin/                         # 内置业务技能
│   │   ├── oa-approval.js              # OA 审批流程
│   │   └── finance-report.js           # 财务报表导出
│   └── registry.json                    # 技能清单 + SHA-256 签名
├── node/                                # Node.js 运行时
│   └── bin/node
├── local_service/                       # 本地 HTTP 服务
│   ├── bin/www
│   └── routes/
├── locales/                             # 国际化语言包
├── resources.pak                        # Chromium 资源
├── *.pak                                # 其他资源文件
└── *.so                                 # 共享库
```

### 8.3 运行时进程拓扑

```
superrpa-chromium (wrapper script, PID 1)
  │
  ├── watchdog (background, PID 2)
  │   └── node local_service (PID 3)
  │       └── 监听 127.0.0.1:9527
  │
  └── chrome --no-sandbox (foreground, PID 4)
       │
       ├── GPU Process (PID 5)
       ├── Network Service (PID 6)
       ├── Renderer: 前台标签页 (PID 7, 8, ...)
       ├── Renderer: Side Panel (PID 9)
       ├── Renderer: Zombie Pages (PID 10, 11, ...)
       │
       └── sgclaw (PID 12, 按需启动)            # [新增]
            │
            ├── stdin  <── chrome pipe 写端
            ├── stdout ──> chrome pipe 读端
            ├── stderr ──> 日志文件 / 丢弃
            │
            ├── tokio runtime (async)
            │   ├── pipe reader task
            │   ├── pipe writer task
            │   ├── agent runtime task
            │   └── LLM HTTP client task
            │
            └── SQLite (文件 I/O)
                └── ~/.sgclaw/memory.db
```

### 8.4 网络拓扑

```
┌──────────────────────────────────────────────────────────────────────┐
│                          用户工作站                                   │
│                    (银河麒麟 V10 SP1, 8 GB)                          │
│                                                                      │
│  ┌──────────────────────┐    STDIO     ┌──────────────────────┐     │
│  │ chrome (Browser)     │◄───Pipe────►│ sgclaw (Agent)       │     │
│  │                      │  进程私有     │                      │     │
│  │  port 9527 (loopback)│             │  HTTPS out ──────────┼──┐  │
│  │  ←→ local_service    │             │  (LLM API 调用)      │  │  │
│  └──────────┬───────────┘             └──────────────────────┘  │  │
│             │                                                    │  │
│             │ HTTPS                                              │  │
│             ▼                                                    │  │
│  ┌──────────────────────┐                                       │  │
│  │ 业务系统 Web 页面     │                                       │  │
│  │ (ERP, OA, HR...)    │                                       │  │
│  └──────────────────────┘                                       │  │
│                                                                  │  │
└──────────────────────────────────────────────────────────────────┼──┘
                                                                   │
                                    ┌──────────────────────────────┘
                                    │
                                    ▼
                         ┌─────────────────────┐
                         │   LLM API 服务       │
                         │                     │
                         │  ├─ Claude API      │
                         │  ├─ OpenAI API      │
                         │  └─ 本地 Ollama     │
                         │    (127.0.0.1:11434)│
                         └─────────────────────┘
```

网络访问说明:
- sgclaw 仅需出站 HTTPS 连接 (LLM API)
- sgclaw 不监听任何端口 (零网络攻击面)
- local_service 仅监听 127.0.0.1:9527 (loopback, 不对外暴露)
- chrome 与 sgclaw 之间通过 STDIO Pipe 通信 (不经过网络)
- 本地 Ollama 部署时，LLM 调用也走 loopback，无外网依赖

### 8.5 数据目录

sgclaw 的持久化数据存放在用户主目录下:

```
~/.sgclaw/                               # sgclaw 数据根目录
├── memory.db                            # SQLite 长期记忆数据库
├── memory.db.bak.{timestamp}            # 迁移前自动备份
├── config.toml                          # 用户级配置 (可选)
└── logs/                                # 日志目录 (可选)
    └── sgclaw-YYYY-MM-DD.log
```

数据目录在首次运行时自动创建，权限设置为 `0700` (仅用户可访问)。

---

## 9. CI/CD 流水线

### 9.1 Rust CI (sgClaw 仓库)

```
┌────────────────────────────────────────────────────────┐
│                  sgClaw CI Pipeline                     │
│                                                        │
│  触发条件: push to main / PR 创建                       │
│                                                        │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐             │
│  │  Check   │  │  Test    │  │  Build   │             │
│  │          │  │          │  │          │             │
│  │ clippy   │  │ cargo    │  │ release  │             │
│  │ fmt      │  │ test     │  │ linux    │             │
│  │ audit    │  │ (all)    │  │ musl     │             │
│  └────┬─────┘  └────┬─────┘  └────┬─────┘             │
│       │             │             │                    │
│       └──────┬──────┘             │                    │
│              │ 全部通过            │                    │
│              ▼                    ▼                    │
│       ┌────────────┐      ┌────────────┐              │
│       │  PR 可合并  │      │  Artifact  │              │
│       │            │      │  上传       │              │
│       └────────────┘      └────────────┘              │
└────────────────────────────────────────────────────────┘
```

GitHub Actions 配置要点:

```yaml
# .github/workflows/ci.yml
name: CI

on:
  push:
    branches: [main]
  pull_request:

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
        with:
          targets: x86_64-unknown-linux-musl
          components: clippy, rustfmt
      - run: cargo fmt -- --check
      - run: cargo clippy -- -D warnings

  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - run: cargo test

  build:
    runs-on: ubuntu-latest
    needs: [check, test]
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
        with:
          targets: x86_64-unknown-linux-musl
      - run: sudo apt install -y musl-tools
      - run: cargo build --release --target x86_64-unknown-linux-musl
      - run: strip target/x86_64-unknown-linux-musl/release/sgclaw
      - uses: actions/upload-artifact@v4
        with:
          name: sgclaw-linux
          path: target/x86_64-unknown-linux-musl/release/sgclaw
```

### 9.2 C++ CI (SuperRPA 仓库)

C++ CI 依赖 Chromium 构建环境，通常在专用构建服务器上执行:

```bash
# CI 脚本 (在构建服务器上运行)
cd /home/zyl/projects/superRpa/src

# 增量编译
autoninja -j 24 -C out/Default chrome

# 运行所有 SuperRPA 测试 (含新增的 sgclaw 测试)
./out/Default/superrpa_unittests
./out/Default/superrpa_ai_unittests
./out/Default/sgclaw_unittests

# 格式化检查
git cl format --diff
```

### 9.3 发布流程

```
版本发布流程:

1. 版本号更新
   ├─ sgClaw: Cargo.toml version
   ├─ CHANGELOG.md: 新版本记录
   └─ 创建 Git tag: v0.1.0

2. 构建产物
   ├─ Linux: cargo build --release --target x86_64-unknown-linux-musl
   ├─ Windows: cargo build --release --target x86_64-pc-windows-msvc
   └─ 验证: file, size, strip

3. 集成到 SuperRPA
   ├─ 复制 sgclaw 到 repack_work/extract_YYYYMMDD/opt/chromium.org/chromium/
   ├─ 复制 sgclaw-skills/ 到同目录
   ├─ 运行 repack-with-service.sh
   └─ 生成 .deb: superrpa-chromium-1.0.0-kylin-v10-YYYYMMDD-with-service.deb

4. 验证
   ├─ 在银河麒麟 V10 虚拟机安装 .deb
   ├─ 启动浏览器, 打开 Side Panel
   ├─ 点击 [启动 Agent], 验证进程启动
   ├─ 执行简单指令, 验证 pipe 通信
   └─ 验证 .deb 包大小在预期范围内

5. 发布
   ├─ 上传 .deb 到内部分发平台
   └─ 通知测试团队
```

---

## 10. 常见问题与故障排查

### 10.1 构建问题

| 问题 | 原因 | 解决方案 |
|------|------|---------|
| `linker 'musl-gcc' not found` | 未安装 musl 工具链 | `sudo apt install musl-tools` |
| `cargo build` 依赖下载超时 | 网络问题或 crates.io 镜像 | 配置 `~/.cargo/config.toml` 使用镜像源 |
| rusqlite 编译失败 | SQLite C 代码编译问题 | 确保使用 `features = ["bundled"]` |
| `gn gen` 报错 `sgclaw not found` | BUILD.gn 路径错误 | 检查 `sgclaw/BUILD.gn` 文件是否存在 |
| strip 后二进制过大 (>15 MB) | LTO 或 opt-level 配置问题 | 检查 `[profile.release]` 配置 |

### 10.2 运行时问题

| 问题 | 排查方式 | 解决方案 |
|------|---------|---------|
| sgclaw 启动后立即退出 | 查看 stderr 输出或日志 | 检查 handshake 超时、配置文件路径 |
| pipe 消息无响应 | `RUST_LOG=debug` 查看日志 | 检查 JSON 格式、sequence_id 是否连续 |
| MAC 拒绝合法操作 | 查看 C++ 侧日志 | 检查 rules.json 域名白名单配置 |
| LLM 调用失败 | 检查网络连接和 API key | 确认 LLM API endpoint 可达 |
| Circuit Breaker 触发 | 查看 Agent 日志 | 分析连续失败原因，可能是目标页面变更 |
| SQLite 数据库锁定 | 检查是否有多个 sgclaw 实例 | 确保 Singleton 机制生效 |

### 10.3 Cargo 镜像配置 (国内网络)

```toml
# ~/.cargo/config.toml
[source.crates-io]
replace-with = "ustc"

[source.ustc]
registry = "sparse+https://mirrors.ustc.edu.cn/crates.io-index/"
```

---

*文档结束。本文档为 sgClaw L4 层工程实现参考，覆盖仓库结构、构建系统、依赖管理、
打包发布、测试策略、开发环境、代码规范、部署拓扑与 CI/CD 流程。
如有疑问请联系 sgClaw 开发团队。*
