# 2026-05-27 Agent os_release 上报 + 前端系统版本拆分 + 空字段隐藏

## 变更摘要
1. Agent 心跳和 /health 端点新增 `os_release` 字段，读取 `/etc/os-release` 的 PRETTY_NAME（如 "Ubuntu 24.04 LTS"）
2. servers.html 系统信息面板拆分为两卡片：「发行版」显示 os_release，「内核平台」显示 platform
3. servers.html 详情面板描述/目标路径/认证方式空值时隐藏整行，不再显示 `--`

## 动机
1. servers.html 系统版本列显示 `Linux-6.8.0-31-generic-x86_64-with-glibc2.39`（内核字符串），无法直观判断发行版
2. 运维人员需要快速识别服务器是 Ubuntu 24 还是 Debian 12 等
3. 空字段显示 `--` 无意义，应该隐藏整行不占空间

## 涉及文件

### Agent
- `web/agent/agent.py` — 新增 `_os_release()` 函数；health 端点添加 `os_release` 字段；heartbeat payload 添加 `os_release` 字段

### 前端
- `web/app/servers.html` — 系统信息面板拆分为「发行版」(`siOSRelease` / `os_release`) 和「内核平台」(`siPlatform` / `platform`) 两个独立卡片；描述/目标路径/认证方式空值时隐藏行（`style.display`），目标路径用 `<code>` 标签

## 技术细节
- `_os_release()` 读取 `/etc/os-release`，解析 `PRETTY_NAME=` 行，如文件不存在返回空字符串
- health 端点中也有内联的 os_release 检测（与 heartbeat 的 `_os_release()` 逻辑相同）
- 前端拆分为两个独立卡片：发行版 (`os_release`) + 内核平台 (`platform`)，各自独立赋值

## 部署过程问题
- 机器人 (66.154.115.131) Agent 升级后因旧进程占用 8601 端口导致 crash loop
- 原因：旧 Agent 进程未被 kill，新进程无法绑定端口
- 修复：`kill -9 $(lsof -t -i :8601)` 后 `systemctl restart nexus-agent`
- 非代码 bug，是升级流程中端口释放竞争问题

## 需要迁移/重启
- 是：需升级 Agent（curl 新 agent.py + systemctl restart nexus-agent）
- 否：无数据库迁移，Nexus 后端无需重启（心跳 JSON 透传）

## 验证方式
1. API `/api/servers/` 返回 `system_info.os_release = "Ubuntu 24.04 LTS"` ✅
2. 浏览器 servers.html 点击机器人 → 系统信息面板显示 "Ubuntu 24.04 LTS" ✅
3. 冲量银海显示 "Debian GNU/Linux 12 (bookworm)" ✅
4. 机器人 Agent 心跳正常发送 ✅
5. 空字段（描述/目标路径）整行隐藏 ✅
6. 目标路径编辑保存成功后正确显示 ✅
7. 后端 /health 返回 `{"status":"ok"}` ✅

## 审计8步
- H1: `_os_release()` 只读本地文件 — ✅ 无注入风险
- H2: `os_release` / `platform` 字符串用 `textContent` 赋值 — ✅ 无 XSS
- H3: /etc/os-release 为系统只读文件 — ✅ 无安全风险
- H4: 空字段隐藏用 `style.display`，值固定为空或 none — ✅ 无注入
- H5: Agent 端口占用非代码问题 — ✅ 运维处理
- H6: 审计文件 `docs/audit/2026-05-27-servers-info-display.md` — ✅ 0 FINDING
- DoD: 无明文密码/命令注入/SQL注入/静默吞错/硬编码 ✅

## 进度条
☑实现 ☑WSL验证 ☑审计8步 ☑部署 ☑健康检查 ☑浏览器验证 ☑changelog
