Pulse v6 RC3 回归门禁实践:基于 v5.1.29 Delta 的已知 RC 问题闭环核查(known-rc-issue-closure-for-ga)
Pulse v6 RC3 回归门禁实践:基于 v5.1.29 Delta 的已知 RC 问题闭环核查(known-rc-issue-closure-for-ga)
导读
本文基于 Pulse 仓库中一份发布控制记录——known-rc-issue-closure-for-ga-v5-129-delta-2026-05-01.md,完整还原 Pulse v6 RC3 发布候选在 GA 前的"已知 RC 问题闭环(known-rc-issue-closure-for-ga)"门禁核查流程。你将看到:如何逐条比对 v5.1.29 维护分支的修复列表与 v6 候选代码,如何验证安装器/发布序列/安全依赖水位等发布风险点,以及如何用 gh、git 与截图检查把"公开问题不阻塞发布"做成可复现、可审计的工程决策。这套方法适用于任何需要"把上游维护分支的补丁与主线候选逐一对齐"的发布管理场景。
记录背景:一次面向 v5 维护线增量的 RC 清扫
记录元信息与门禁语义
该记录属于 Pulse 仓库 docs/release-control/v6/internal/records/ 目录下的内部发布记录,核心元信息如下:
| 字段 | 值 |
|---|---|
| 日期 | 2026-05-01 |
| 门禁 | known-rc-issue-closure-for-ga |
| 结果 | passed |
在 Pulse 的发布体系中,known-rc-issue-closure-for-ga 是一个面向 GA 候选的已知问题闭环门禁:它要求发布候选在切入下一个 release candidate 之前,把"上游维护分支(release/5.1)最新修复"与"公开 GitHub issue / discussion 队列"全部核对一遍,确认没有任何未处理的 v5→v6 回归被带进候选。该门禁存在一整套关联记录(见 docs/release-control/v6/internal/records/ 下的 known-rc-issue-closure-for-ga-* 系列文件),状态既有 passed 也有 blocked,例如:
- known-rc-issue-closure-for-ga-blocked-2026-05-01.md:同一日期的一次
blocked结果,列出#1441(Proxmox 在线/离线状态不一致)、#1452(图表 tooltip 遮挡)、讨论#1448(PBS 阈值)、#1435(发布序列)四个待处置项; - known-rc-issue-closure-for-ga-rc3-followup-2026-05-01.md:对这四个候选项的逐项修复与回归证明;
- known-rc-issue-closure-for-ga-docker-agent-reconnect-2026-05-01.md:Docker agent 重连身份绑定路径的专项闭环。
本文所讨论的这份记录,是上述清扫链条中针对 v5.1.29 增量 的最后一轮:Docker agent 重连修复落地后,继续以当前开放的 GitHub issue/discussion 队列加上 release/5.1 的 v5.1.29 delta 为对象,确认最新 v5 维护修复与新建公开话题是否仍然暗示 v6 RC3 回归。
本轮核查的范围与纪律
记录明确说明本轮 pass 没有对外发送任何公开评论、不关闭 issue、不改标题、不打标签(No public GitHub comments, issue closes, retitles, or labels were sent during this pass)。这是该门禁的一个关键纪律:发布验证与公开线程卫生(public thread hygiene)分离——验证结论只需要证明"候选代码与文档状态满足门禁",公开队列的维护者跟进是另一项独立工作。
Disposition 逐条分析:v5.1.29 修复在 v6 中的等价落点
记录的核心部分是 5 个 disposition 条目,逐条判断 v5.1.29 delta 中的修复是否已被 v6 候选等价承载。
1. release/5.1 v5.1.29 delta 的整体对齐
记录列出了 v5.1.29 中一批修复,并逐一给出 v6 的等价实现:
- Alert 通知刷屏修复
#1444:已通过提交3d3b1a964以及后续的 RC3 维护移植进入 v6。对应的实现事实是:v6 的 alert cooldown 门禁在 cooldown 设为 disabled 时,仅发送告警首次出现的通知,并在 cooldown 保持 disabled 期间抑制重复通知(见 known-rc-issue-closure-for-ga-blocked-2026-05-01.md 中对#1444的说明)。 - Bootstrap token 显示修复
#1451:v6 通过安装器移植解决了该问题——安装器通过pulse bootstrap-token命令揭示 setup token,而不是打印加密的.bootstrap_tokenJSON 内容。 - SSE EOF 工具调用收尾(tool-call finalization):v6 通过 OpenAI provider 流解析器以及 EOF / 无
[DONE]场景的测试等价承载。 - 一批小项已有 v6 等价实现:更新进度弹窗可关闭、稳定的容器化 agent 身份、guest snapshot 携带延续(carry-forward)、mdstat RAID 操作门控、linked guest filesystems、Ollama
keep_alive=30s。
2. #1435 安装器发布序列问题
#1435 报告的是 LXC 命令安装 v6.0.0-rc.2 的序列问题。本轮核查时:
- 重新检查了 GitHub release 状态,
/releases/latest现在指向v5.1.29而不是v6.0.0-rc.2; - 稳定的
release/5.1安装器会过滤 prerelease,并让 RC 安装保持 opt-in(需要显式选择); - 因此该问题不再是 RC3 代码阻塞项。
3. #1451 附带报告:Proxmox LXC 恢复挂载失败
#1451 的截图中还包含一个 LXC 恢复失败场景。核查结论是:该恢复失败源于恢复后的 LXC 配置中残留的陈旧 /run/pulse-sensor-proxy bind mount。v6 安装器已经携带 cleanup_stale_sensor_proxy_mounts,会在安装前移除陈旧的 pulse-sensor-proxy mp<N> 与 lxc.mount.entry 行。剩余"恢复后容器"的支持性问题属于支持跟进,不构成 v6 RC3 未移植的回归。
4. #1443 v6 界面信息密度反馈
#1443 的截图对比了 v5 表格优先(table-first)的状态展示与 rc.2 的 dashboard/resource-map 图表展示,表达了真实的产品偏好与信息密度担忧。当前 v6 候选已经做了两点调整:
- 认证后的默认落地页移到 Infrastructure(表格优先);
- Workloads 保持表格优先,图表位于显式控件之后(
Charts控制)。
记录对此的判定是:这是有效的产品反馈,但在本轮清扫中不是一个狭窄且未处理的 RC3 缺陷。
5. #1449 与讨论 #1450
#1449是围绕自托管免费层与 SSO 的定价/打包反馈,不是当前候选的运行回归;#1450是项目活跃度/许可证信心的反馈,后续评论者跟进确认活跃度已恢复;- 两者可能都需要维护者侧回复,但都不改变 RC3 代码就绪性决策。
Proof 清单:如何把门禁核查做成可复现审计
记录的 Proof 部分是整份文档最具工程价值的部分,展示了该门禁的完整证据采集命令。这些命令以 gh CLI 与 git 为主:
# 拉取当前开放 issue 队列(前 60 条,含字段信息)
gh issue list --repo rcourtman/Pulse --state open --limit 60 \
--json number,title,author,createdAt,updatedAt,labels,comments,url
# 单条 issue 详情核查
gh issue view 1451 --repo rcourtman/Pulse --json number,title,body,comments,labels,createdAt,updatedAt,url
gh issue view 1444 --repo rcourtman/Pulse --json number,title,body,comments,labels,createdAt,updatedAt,url
gh issue view 1441 --repo rcourtman/Pulse --json number,title,body,comments,labels,createdAt,updatedAt,url
gh issue view 1449 --repo rcourtman/Pulse --json number,title,body,comments,labels,createdAt,updatedAt,url
gh issue view 1443 --repo rcourtman/Pulse --json number,title,body,comments,labels,createdAt,updatedAt,url
# 讨论(discussion)读取
gh api graphql
# release 列表状态核查(draft/prerelease/latest 标记)
gh release list --repo rcourtman/Pulse --limit 20 \
--json tagName,isDraft,isPrerelease,isLatest,createdAt,publishedAt,name
# 稳定安装器落点核查
curl -I -L https://github.com/rcourtman/Pulse/releases/latest/download/install.sh
# 上游维护分支近期提交对比(v5.1.x 工作树)
git -C ../pulse-5.1.x log --oneline --decorate --since='2026-04-20' --no-merges --
# 当前候选分支近期提交对比
git log --oneline --decorate --since='2026-04-20' --no-merges --
# 截图检查(#1451、#1444、#1441、#1443)
这一组命令勾勒出该门禁的三类证据:issue 队列状态(开放/标签/更新时间)、release 发布状态(latest 指向、prerelease 过滤)、提交历史对比(v5 维护分支与 v6 候选自 2026-04-20 以来的变更)。注意 --since='2026-04-20' 的时间窗口与本轮清扫起点(Docker agent 重连修复落地后)呼应。
仓库源码级佐证:四个关键技术点
以下从当前仓库源码出发,进一步验证记录中的关键结论。
Bootstrap token:安装器不再打印加密文件内容
记录称 #1451 通过"安装器揭示 setup token 于 pulse bootstrap-token 而非打印加密 .bootstrap_token JSON"解决。仓库中可确认:
- 安装器 install.sh 在全新安装展示 token 时(第 4771 行附近),仅在
.bootstrap_token文件存在时,优先选择$BINARY_LINK_PATH bootstrap-token,其次$INSTALL_DIR/bin/pulse bootstrap-token,再退到command -v pulse,并以PULSE_DATA_DIR="$TOKEN_DATA_DIR"环境变量驱动命令执行——即走pulse bootstrap-token规范路径,而非直接 cat 文件内容; - 命令实现位于 pkg/pulsecli/bootstrap.go,
ShowBootstrapToken通过config.ResolveRuntimeDataDir("")解析数据目录,再由bootstrapstore.Load(dataPath)读取 token;若 token 不存在(如已完成初始化、已配置认证导致 token 自动删除),会打印带原因列表的引导框并退出。 - 对应测试见 internal/bootstrap/token_store_test.go 与 internal/api/bootstrap_token_test.go。
从源码结构可以推断:pulse bootstrap-token 是 token 展示的 canonical 入口,安装器围绕它做了多级命令解析兜底,这正是记录中"installer reveals the setup token through pulse bootstrap-token"的落点。
陈旧 sensor-proxy 挂载清理:LXC 恢复失败的根本修复
记录将 #1451 附带截图中的恢复失败归因于陈旧 /run/pulse-sensor-proxy bind mount。仓库中 install.sh 确实实现了 cleanup_stale_sensor_proxy_mounts()(第 1046 行起),其注释解释了根因:v4 安装器曾向 LXC 容器配置写入 /run/pulse-sensor-proxy 挂载条目;v5+ 移除了 sensor proxy,但这些条目仍然存在;宿主机重启后 /run(tmpfs)被清空,挂载源消失,导致 Proxmox 拒绝启动容器。
实现细节:
- 检测
pct命令存在与否(不存在则直接返回); pct list枚举所有 CTID;- 对每个
/etc/pve/lxc/${ctid}.conf,先 grep 是否含pulse-sensor-proxy引用,无引用则跳过; - 通过第一个
[snapshot]段行号切出主配置区(避免修改快照区),再清理陈旧mp<N>与lxc.mount.entry行; - 安装流程在第 1137 行调用该函数(见 install.sh)。
关联测试位于 scripts/installtests/uninstall_sensor_proxy_test.go,反方向卸载脚本见 scripts/uninstall-sensor-proxy.sh。
Docker agent 重连:token 绑定身份改为 canonical host 解析
记录开头提到"Docker agent reconnect fix landed"。这条链路在仓库中有完整实现与测试:
- 核心函数
resolveDockerHostIdentifier位于 internal/monitoring/docker_host_identity.go,负责确定 Docker host 的唯一标识; - 上一轮专项记录 known-rc-issue-closure-for-ga-docker-agent-reconnect-2026-05-01.md 指出:
ApplyDockerReport在 canonical Docker host 匹配成功后,token-binding 身份从匹配到的 canonical host 解析,同时把 previous host source ID、previous agent ID、current agent ID、machine ID、hostname 视为同一已匹配 host 的别名;API token 重载后的 token-binding 重建同样复用 canonical identity,而不是重新引入 raw-agent-ID-first 绑定。 - 测试覆盖见 internal/monitoring/docker_host_identity_test.go 与
docker_identity_conflict_test.go中的克隆 machine ID 冲突用例等。
可以推断:ApplyDockerReport 是 monitoring 侧 Docker 报告摄入的统一入口(在 internal/monitoring/docker_detection.go 第 681 行等处被调用),其 canonical-host 优先的 token 绑定逻辑是"容器重建后仍可用同一 token 上报,同时不同 Docker agent 仍保持 one-token-per-host 约束"的实现基础。
Ollama keep_alive:配置归一化与合法取值
记录提到 v5 的 Ollama keep_alive=30s 在 v6 中已有等价实现。仓库中:
- internal/ai/providers/ollama.go 的
NewOllamaClientWithKeepAlive显式接受 keep_alive 值,并通过config.NormalizeOllamaKeepAlive归一化;请求结构体在 internal/ai/providers/ollama.go 以KeepAlive anyjson:"keep_alive,omitempty"` 承载; - internal/config/ai.go 的
NormalizeOllamaKeepAlive定义了合法取值面:空值表示省略 keep_alive 交由 Ollama 服务端默认;数值按秒数解析;也接受30s、5m、24h等 duration;-1表示保持加载,0表示卸载。非法值会返回错误。 - 默认值
DefaultOllamaKeepAlive为空串(internal/config/ai.go),即缺省行为是"省略 keep_alive"。
这印证了记录中"Ollama keep_alive=30s already have v6 equivalents"的表述:v6 通过可配置的归一化通道完整支持该类维护修复。
安全水位:v5 修复基线与 v6 依赖锁定
记录对安全依赖修复给出的结论是"v6 在或高于 v5 底线":
| 依赖项 | v5.1.29 基线(记录口径) | 仓库当前事实 |
|---|---|---|
| Go toolchain | go1.25.9 |
go.mod 当前为 go 1.26.0 / toolchain go1.26.8 |
golang.org/x/net |
v0.52.0 |
见 go.mod 依赖声明 |
dompurify |
锁定到 3.4.1 |
frontend-modern/package.json 当前为 ^3.4.15 |
从当前仓库的 go.mod 与 frontend-modern/package.json 可以确认:v6 线的依赖水位已随时间继续前移,至少不低于记录所述 v5 底线(记录要求 v6 处于"at or above the v5 floor"状态)。这类对比正是该门禁中"security dependency fixes are at or above the v5 floor"判定在仓库中的持续体现。
Outcome 与门禁边界
本轮结论
记录的 Outcome 明确:本轮持续的 RC3 清扫未再发现另一个未处理的 v5→v6 回归,也没有新的 GitHub issue/discussion 项应当阻塞下一个 v6 release candidate。公开线程卫生(public thread hygiene)仍是独立的维护者工作,但对于当前代码与文档状态,known-rc-issue-closure-for-ga 门禁保持满足。
门禁的边界与后续动作
值得强调的是该门禁的验证边界:
- 门禁只证明"候选代码不已知地携带这些 RC 时代缺陷"(no longer knowingly ships those RC-era failures unchanged),不承诺所有公开 issue 已关闭;
#1443、#1449、#1450这类产品/定价/活动度反馈会被判定为"需要维护者回复但不阻塞发布",属于公开队列卫生范畴;- 同期
blocked记录(如 known-rc-issue-closure-for-ga-blocked-2026-05-01.md)证明该门禁在发现真实候选缺陷时会如实置为blocked,直到修复、证明无效或保守地 superseded——#1441、#1452、讨论#1448随后在 known-rc-issue-closure-for-ga-rc3-followup-2026-05-01.md 中被逐项修复并给出回归测试与浏览器证据。
小结:可复用的发布门禁实践
从这份记录可以提炼出一套可复用的"上游维护线对齐 + 已知问题闭环"方法:
- 固定时间窗增量对比:用
git log --since=<窗口>同时对比维护分支与候选分支,避免逐条人工记忆; - 三类证据并采:issue 队列 JSON(
gh issue list/view)、release 状态(gh release list+ 稳定安装器落点curl -I -L)、提交历史——三者互补覆盖"用户报告、发布状态、代码事实"; - 逐项 disposition:每个 issue 明确落点为"已修复/已有等价实现/非代码阻塞/需要维护者回复",不允许模糊地带;
- 验证与公开互动分离:核查过程不对外发评论、不关 issue、不改标签,保持证据纯净;
- 如实记录阻塞:发现真实缺陷时门禁置
blocked,并用后续专项记录(如 docker-agent-reconnect、rc3-followup)追踪到修复与回归测试。
这套实践不仅适用于 Pulse 的 v5→v6 过渡,也是任何多分支发布流中"确认候选没有悄悄丢掉上游修复"的通用审计范式。