文件
hyb-oa/.trellis/tasks/08-23-arm-public-health-monitor-controlled-rollout/prd.md
T

10 KiB
原始文件 Blame 文件历史

ARM 公网健康监控受控部署

Goal

把提交 a0f0483 中已通过本地合同的公网健康诊断与防抖增强,安全升级到现有 ARM 异机监控;保留已有脱敏状态和备份 dead-man 能力,先安装为 disabled 并完成只读核验,再受控启用 5 分钟 timer。部署后只以真实公网 /ready 的自然结果运行,不制造故障、不发送专门测试消息。

Background and Confirmed Facts

  • 08-23-wecom-public-health-alert-diagnostics-and-debounce 已完成本地实现:DNS/TCP 分类分离、连续 2 次健康恢复、60 分钟同类复发抖动提醒、连续健康 30 分钟静默退出,以及“OA 公网健康”专用标题。
  • 本地应用健康合同 36 项、自动备份共享合同 74 项均通过;候选工作提交为 a0f0483,归档提交为 42bbbda。
  • 腾讯云服务器是 OA 真实生产主机,运行 OA 应用、数据库及公网入口;ARM 是独立异机备份与外部健康探测节点,不运行 OA 服务。应用健康探测器部署在 ARM,并从外部访问腾讯云 OA 的公网 /ready。
  • 2026-07-27 已在 ARM 安装并启用旧版监控,现有应用健康探测器、两个 systemd units、独立状态目录及共用企微 helper 均可能存在;本次是原位升级,不适用首次安装时的“必须不存在”前提。
  • 现有安装器 install 会先停用应用健康 timer,再覆盖固定的探测器、helper 和 units,并保留状态目录;enable 会重新安装后启用 timer。
  • 用户已同意为本次 ARM 监控节点 rollout 建立 Trellis task,并允许按“默认禁用安装 → 只读检查 → 受控启用”规划;该授权不包含腾讯云 OA 应用部署或配置变更。

Requirements

R1 — 本地与来源门禁

  • 部署源必须来自已提交的 a0f0483,且探测器、helper、安装器相对该提交无漂移。
  • 远端写入前复跑应用健康合同和自动备份共享合同;任一失败即停止。
  • 不使用工作区中未提交的报销任务文件,不把当前 Trellis 文档作为远端部署源。

R2 — ARM 只读预检

  • 写入前通过既有受控 SSH 入口核对身份、sudo -n、Python、systemd、当前应用健康 timer/service、备份 dead-man 基线和公网 /ready。
  • 只在 ARM 内解析并验证现有 root-owned 0600 webhook 文件路径;不得读取、传输或回显正文。
  • 记录现有探测器/helper/unit 的哈希匹配结果、允许的状态 schema/phase、timer enabled/active 和 dead-man 基线;证据只包含布尔值、稳定 token、短提交号和哈希是否匹配。
  • sudo -n 需要密码、现有对象为符号链接/权限异常、状态无法解析、真实 /ready 不健康或备份 dead-man 基线异常时,停止在写入前并报告。

R3 — Disabled 原位升级

  • 只上传已提交的探测器、共用 helper 和安装器到本次唯一临时目录,并核对源/上传件 SHA-256。
  • 运行安装器 install,只覆盖固定的应用健康探测器、共用 helper 和两个应用健康 units;保留现有应用健康状态、alert state、webhook、备份 receiver/dead-man、归档和其他 systemd 对象。
  • 安装后 timer 必须为 disabled/inactive;探测器/helper 为 root:root 0755,units 为 0644,状态目录为 root:root 0700,已有状态文件为 0600。
  • 已安装探测器/helper 必须与 a0f0483 的候选哈希一致,unit 仍固定正式 HTTPS /ready、失败阈值 2、5 分钟周期和安全目标路径。

R4 — Disabled 状态核验

  • 在 timer disabled 时只运行正式 systemd oneshot 对真实公网 /ready 做一次健康检查,不改 URL、DNS,也不人工编辑状态内容。
  • oneshot 必须成功,状态 schema 必须为 v2 且只包含允许字段;健康基线不得产生故障或恢复消息。
  • 如旧状态迁移后自然形成一个通知候选,立即停止启用并报告,不以删除或伪造状态来压制消息。

R5 — 受控启用与观察

  • R1–R4 全部通过后,才运行安装器 enable;不执行不可达端口、停服务、改 DNS 等故障注入。
  • timer 最终必须 enabled/active,调度周期仍为 5 分钟,最近一次 service 成功,下一次计划时间符合 timer 合同。
  • 启用后至少观察两个连续调度窗口,并核对状态 schema/phase、service 结果和消息去重状态;允许真实健康异常自然触发生产运维消息,但不发送专门测试消息。
  • 备份 dead-man 的 unit/timer 状态和共用标题合同必须保持不变。

R6 — 停止与回滚

  • 任一步出现身份、权限、哈希、unit、状态、真实健康或备份基线不一致时,停止扩大变更并保留脱敏证据。
  • disabled 安装后、enable 前失败:恢复升级前探测器/helper/units 的同机备份,保留状态目录,再核对 timer 回到升级前状态;不得删除共用 webhook、备份组件或归档。
  • enable 后失败:先 disable/stop 应用健康 timer,恢复升级前文件和 units,执行 daemon-reload,并按升级前 enabled/active 基线恢复 timer;只有确认真实 /ready 健康和旧版可读取状态后才重新启用。
  • 若新版已写入旧版不能读取的 schema v2,回滚时先保留精确状态文件副本,再将精确状态文件移出活动目录,让旧版建立新健康基线;不得伪造恢复状态。
  • 若正式健康告警已经自然发出但无法闭环恢复,保持 timer 停用并明确报告“告警未闭环”,不发送人工伪造的恢复消息。

R7 — 隐私、清理与报告

  • 不在聊天、Trellis、日志摘要或提交中保存主机地址、用户名、完整远端路径、webhook、Secret、原始响应、journal 或企微 payload。
  • 删除本次精确临时上传目录和临时权限入口;若使用临时 sudoers,必须在同一受控 root 流程中校验后删除,并证明原非交互权限已恢复到基线。
  • 未完成远端检查前不得报告“已部署”;未观察两个调度窗口前不得报告“运行稳定”。

Acceptance Criteria

  • AC1 / R1:候选来源固定为 a0f0483,本地 36 项应用健康合同和 74 项自动备份合同再次通过,部署源无漂移。
  • AC2 / R2:ARM 写入前预检通过,且证据不含凭证、地址、完整路径、原始响应或 payload。
  • AC3 / R2:记录升级前应用健康与备份 dead-man 的脱敏基线;现有状态可严格解析,回滚材料已在 ARM 同机受控保存。
  • AC4 / R3:disabled 安装后 timer 明确 disabled/inactive,受管文件、units、权限、固定目标和 SHA-256 全部符合合同。
  • AC5 / R4:timer disabled 时正式 oneshot 对公网 /ready 成功,状态安全迁移至 schema v2,未产生测试或恢复噪声。
  • AC6 / R5:受控启用后 timer enabled/active,连续两个调度窗口成功且状态/消息去重无异常。
  • AC7 / R5:备份 receiver/dead-man、归档和共享非应用健康标题均未改变。
  • AC8 / R6:每个阶段都有可执行停止/回滚点;本轮未触发回滚,最终 timer 状态、真实健康和备份基线均完成复核。
  • AC9 / R7:临时上传与临时权限已精确清理,最终证据仅包含允许的脱敏字段。

Scope

  • 从提交 a0f0483 取得并复核探测器、企微 helper 与既有安装器。
  • 对现有 ARM 应用健康监控执行只读预检、同机回滚准备、disabled 原位升级和正式 /ready oneshot。
  • 前置门禁全部通过后启用 5 分钟 timer,并观察两个连续调度窗口。
  • 核对应用健康独立状态、共享 helper 兼容和备份 dead-man 基线,完成临时材料清理及脱敏记录。

Out of Scope

  • 修改 DNS、resolver、Caddy、TLS 证书、OA 应用、数据库、Compose 或业务数据。
  • 故意制造失败、停止真实服务、使用不可达端口或发送企微测试消息。
  • 修改机器人配置、webhook 内容、备份 receiver/dead-man 配置、归档或保留策略。
  • 清理历史状态、历史告警、旧候选文件或其他并行任务改动。
  • 宣称 ARM 监控具备第三方 dead-man 能力。

Test Plan

  • 本地:应用健康合同、自动备份合同、安装器 Shell 语法、process baseline、Trellis governance、task validate、敏感扫描和 git diff --check。
  • ARM 写前:连接/权限、当前版本/哈希、应用健康和 dead-man timer/service、状态 schema、webhook 文件属性、公网 /ready 的脱敏布尔检查。
  • ARM 写后 disabled:哈希、owner/mode、unit 固定合同、timer disabled/inactive、正式 oneshot 和 schema v2。
  • ARM enable 后:enabled/active、两个连续调度窗口、最近 service 成功、状态/去重 token、dead-man 基线不变、临时材料清理。

Execution Evidence

  • 2026-08-23:候选提交门禁、安装器 Shell 语法、应用健康合同 36 项、自动备份共享合同 74 项和 process baseline 均通过;测试 capture 未访问真实企微。
  • 2026-08-23:既有 ARM SSH alias 可非交互连接,但首个写前门禁 sudo -n true 返回需要密码;流程在任何 root 检查、上传或远端写入前停止。
  • 2026-08-23:用户在 ARM 侧建立临时非交互 sudo 运维入口后,完整只读预检通过:旧应用健康 timer 和备份 dead-man 均 enabled/active,probe state 为有效 v1,webhook 文件合同与腾讯云 OA 公网 /ready 均通过。
  • 2026-08-23:候选上传哈希、同机回滚副本、disabled 原位安装、受管文件权限和固定 unit 合同均通过;正式 oneshot 成功把 probe state 从 v1 保守迁移为 v2/healthy,alert state 未变化,未产生恢复噪声。
  • 2026-08-23:timer 受控启用后连续两个自然调度窗口成功,probe 保持 v2/healthy,未出现非预期企微消息,备份 dead-man 基线未变化。腾讯云 OA 应用、数据库、DNS 和业务数据均未修改。
  • 2026-08-23:三个临时上传文件和空目录已精确删除;临时 sudoers 已删除、sudoers 全量语法通过,sudo -n 恢复为不可用。ARM 同机回滚副本按计划保留,后续清理需另行授权。
  • 2026-08-23:收尾 task validate、Trellis governance、process baseline、敏感扫描和 git diff --check 均通过;文档审计 errors=0,仅保留既有未登记文件 warning。