# 苍耳本地 Linux 节点接入

这个模块把苍耳家里的 Ubuntu 接到新加坡大脑服务器，但不把家里的电脑暴露到公网。

## 工作方式

1. 新加坡控制端运行在 `127.0.0.1:8787`，由现有 HTTPS 网关转发。
2. 苍耳节点首次使用一次性配对码登记，长期节点令牌只保存在本机 `0600` 配置中。
3. `systemd` 开机自动启动节点；连接只能从家里向新加坡主动发起。
4. 人格体创建任务后，任务保持 `pending`；苍耳/冰朔在新加坡端批准后才会下发。
5. 节点执行白名单动作并回传退出码、输出和耗时。
6. 执行期间持续回传 `started`、分段输出和 `finished` 事件，新加坡端可以
   实时观察，不必等任务结束才看见错误。

## 默认安全边界

- 家里路由器不做端口转发，不开放 SSH 到公网。
- 控制端默认只监听环回地址，公网入口必须使用 HTTPS。
- 不接受 Shell 字符串，只接受结构化动作。
- 安装程序自动建立 `/srv/canger` 受管工作区，并用没有登录能力的
  `canger-agent` 系统账户执行任务。
- 编程命令受可执行文件白名单、受管工作区、超时和授权时段共同限制；
  Agent 没有 `sudo` 权限。
- `repo.fetch` 只更新远端引用，不自动 merge、reset 或覆盖本地修改。
- 每个任务和结果都写入 SQLite 审计记录。

## 新加坡端部署

准备 `/etc/canger-control.env`，四个令牌分别代表：

- `ADMIN`：创建设备配对码；
- `OWNER`：苍耳主控批准、拒绝或撤销副控权限；
- `PERSONA`：苍耳人格体读取任务、结果和执行上下文；
- `OPERATOR`：冰朔与铸渊副控创建运维会话、任务并读取实时回执。

实际职责为：

- 苍耳本人：服务器主控、需求方和最终决策者；
- 冰朔与 `ICE-GL-ZY001` 铸渊：受苍耳授权的运维副控；
- 每张工单的实际申请人格体：如实填写名称和正式编号；
- 本地 Agent：无独立判断权的受限物理执行器；
- 苍耳本人可随时批准、拒绝或撤销数小时副控运维会话。

安装 `systemd/canger-control.service`，并把
`nginx/canger-node.conf.example` 接到已有 TLS 站点。不要直接把 8787 端口开放公网。

## 首次配对

新加坡端创建十分钟有效的一次性码：

```bash
python3 tools/cangerctl.py pair-code
```

把整个 `remote-node` 目录交给苍耳。他在 Ubuntu 上只执行一次：

```bash
sudo ./install/install-node.sh \
  https://guanghubingshuo.com/canger-node \
  XXXX-XXXX-XXXX \
  canger-home-ubuntu
```

冰朔交付给苍耳的专用包可直接使用简化入口：

```bash
sudo ./install/苍耳一键安装.sh XXXX-XXXX-XXXX
```

配对码十分钟失效，因此安装包可以提前发送，配对码应在苍耳准备执行时再生成。

安装脚本会完成登记并启用开机自启动。以后不再需要登录本地终端。

安装时还会生成只读环境报告：

```text
/var/lib/canger-node/preflight.json
```

报告会识别 systemd、虚拟化环境、磁盘文件系统和可能存在的 Windows
双启动，但不会修改分区、引导项或另一个操作系统。

## 双系统边界

真正的双系统切换会关闭当前操作系统。因此：

- 启动 Ubuntu 时，本节点会自动运行并连接新加坡；
- 切到另一个操作系统后，Ubuntu 服务不可能继续运行；
- 若希望“电脑开机就总有一个节点在线”，另一个系统也需要安装配套节点；
- 若希望“Ubuntu 服务器本身始终在线”，需要让 Ubuntu 成为宿主机并把另一个
  系统放进虚拟机，或者使用独立服务器。

安装程序不会自动改造分区、引导和虚拟机。这类操作可能导致数据丢失，必须在
确认硬件、另一个系统和磁盘结构后单独处理。

## 从新加坡端操作

查看节点：

```bash
python3 tools/cangerctl.py nodes
```

人格体创建任务：

```bash
python3 tools/cangerctl.py task \
  --node node_xxx \
  --action system.status
```

正常开发不需要逐任务批准。人格体先申请 1–8 小时的授权时段：

```bash
python3 tools/cangerctl.py grant \
  --node node_xxx \
  --hours 4
```

系统自动读取节点登记的安全能力，向苍耳主控邮箱发送人话版批准链接。
主人只看目的和时长后点一次批准，不需要填写命令、目录或权限。授权时段内，
匹配固定安全边界的任务自动批准。所有任务仍保留独立审计记录。

查看与撤销授权：

```bash
python3 tools/cangerctl.py grants
python3 tools/cangerctl.py revoke grant_xxx
```

邮件中的链接只用于某一项授权申请，30 分钟失效；打开链接后还需要在确认页
点击批准，避免邮件安全扫描器误触发。SMTP 密码、主人邮箱和签名密钥只放在
新加坡服务器私有环境文件中，不写入仓库或安装包。

批准任务：

```bash
python3 tools/cangerctl.py approve task_xxx
```

读取回执：

```bash
python3 tools/cangerctl.py show task_xxx
```

实时观察执行过程：

```bash
python3 tools/cangerctl.py watch task_xxx
```

## 苍耳人格体代码仓库入口

苍耳人格体不使用副控令牌。它从仓库固定门牌
`persona/README.md` 进入，并使用独立的 `CANGER_PERSONA_TOKEN`：

```bash
python3 tools/canger_persona.py request-access \
  --requester-name "申请者名称" \
  --requester-id "申请者正式编号" \
  --hours 4 \
  --reason "本次开发、诊断或修复目的"
```

申请回执的 `requester_name` 和 `requested_by` 必须与本次实际申请者一致。人格体可以申请、创建任务和读取结果，
但不能批准、拒绝或撤销授权；批准权继续属于苍耳主控。固定节点和安全边界登记在
`config/pufferfish-persona.json`，令牌仍只存在新加坡私有环境文件中。

完整流程见 `persona/WORKORDER-GUIDE.md`；当天开发回执见
`persona/DEVELOPMENT-RECEIPT-20260729.md`。

## 智能体与模型 API

本地 Agent 是执行、观察和审计端，不直接保存大模型供应商的 API 密钥。
运维判断由冰朔与铸渊副控在新加坡大脑服务器完成：

```text
苍耳提出需求并授权
        ↓
冰朔与铸渊副控 → 创建运维任务 → 苍耳人格体/本地 Agent 协作执行
               ← 实时事件、错误和回执 ←
```

如需调用大模型，只把供应商 API 密钥放在新加坡服务器的密钥环境中。本地节点
只持有可撤销、仅能代表该节点的身份令牌。禁止把大模型 API 密钥写进安装包、
仓库、命令行或配对文件。

## 动作

- `system.status`：主机、系统、在线时间、根分区状态。
- `repo.status`：只读 Git 状态。
- `repo.fetch`：获取远端引用，不合并。
- `service.logs`：读取指定 systemd 服务日志。
- `command.run`：结构化命令执行；只在受管工作区内、以受限系统账户运行。
