17 KiB
HEL-895 · 统一发布候选(离线核验过,未执行部署)
HEL-879 发布工具收口(2026-10-27,隔离候选分支
hel-879-assembly):按总管 对 HEL-896 的独立复核完成四项有限收口——①归档一致性:checkpoint 返回值必查、 源/快照行数不一致或 checkpoint busy 一律 CLI 非 0 且不形成可交付包,verify 拒绝 记录了rows_match=False的旧包(§5);②目录内真实 SQLite(history_root 的mem0_public_history.db等)停服口径走 checkpoint+逐表核对,在线模式只允许显式 单库 backup API、含 SQLite 的目录直接拒绝;③提前封账:tools/seal_budget_hel879.py显式封账(真实用量保留、跨重启/归档拒绝,负例 S6);④安装入口唯一化:本文件 §2/§4 为唯一照抄入口(全 offline/no-index;mem0ai 只认固定源码轮),deploy/hel874-release.md§2/§4 已标注被取代。产物清单与精确提交见docs/rework/hel879/sdk-audit/与docs/rework/hel879/release-artifacts.json。不要用旧父提交(04eff61/152479b) 的说明冒充本候选 head:以交付评论与 handoff JSON 记录的精确提交为准。
HEL-896 修订(2026-10-27,正常追加 PR#11):按总管独立复审补齐——①浏览器 「真实服务 7/7」中 B3 原为已证实误报,测试已修为精确交互+严格断言(9 项检查, 含权限 API 调用计数与非回环出站守卫,证据
docs/rework/hel896/browser/); ②A/B/C 预算改为独立团队测试实例 + 全新用户实例的可执行分账 (docs/budget-package-hel895.md§6);③固定 SDK 缺项勘误为 41 项闭包清单 (§4);④归档/回退改为一致性快照口径(§5)。候选 head 与交付物不变,未部署、 未合并、未写权威账。
状态:候选。审核通过与预算/部署授权前不启动面向用户的真实循环、不部署、不合并
PR、不交体验地址。 本文件把已通过独立复审的内核(HEL-894 @ 152479b)与
HEL-881 已审核的主动留言前端(bf234570)装成一个统一候选,给出精确 head、
交付物清单、安装命令、健康矩阵与停用回退。发布卡照抄即可执行;不触 8300–8350
与共享 ASR/TTS/口型,不访问 4080,不导入演示/测试档案为用户伴侣。
0. 精确 head 与整合方式
HEL-879 返修勘误(2026-10-27):本节以下原文记录的是 HEL-895/896 历史 候选(分支
hel-870-assembly,PR #11 未合并),其 299 pytest / 55 vitest 等 验证数字属于那个历史 head,不是当前发布候选。当前统一发布候选是分支hel-879-assembly(在7f0a739之后正常追加返修提交,不强推、不并入 PR #11), 其精确 head、pytest/vitest/build 全量数字与证据以交付评论与docs/requirements/handoff-HEL-879.json记录为准;本文件的安装/检查入口 (§2/§4/§5/§6)继续适用于当前候选,产物清单见docs/rework/hel879/sdk-audit/与docs/rework/hel879/release-artifacts.json(rework_head字段)。历史叙述保留原样,不冒充、不改写。
- 候选 head:见交付评论(分支
hel-870-assembly,PR #11 的正常追加提交, 未强推、未合并)。第一父为 HEL-894 通过复审的152479b3503c3d1ab27681170e6bfd592c54380a, 合并入 HEL-881 已审核的bf234570c0b6595a72f8dbc79e42c63685e08e01(origin/hel-880-inbox-continuation,与 origin/hel-875-proactive-wiring 同点)。 - 整合的机械性:母线
31970c4..152479b从未触碰web/(git diff 31970c4 152479b -- web/为空),合并只带入原作者六个前端文件与handoff-HEL-875/880.json共 9 个文件;src/tests/tools/config相对152479b逐字不变。无重设计、无视觉决定;旧b48d28b测试合并未推送,由本候选取代。 - 合成后验证(全部在本 head 实跑):299 pytest(3.11.16 venv +
requirements.lock 离线)+ ruff 干净;web typecheck 0 错、lint 0 错/1 条既有警告、
vitest 55/55、build 通过且 CSS 仍为
index-DdDYzR5S.css(视觉零改动); 固定 SDK 回归:关闭所有权 16/16、关闭排队 12/12、处理中生命周期 6/6、语义恢复 7/7、真实接线 12/12;发布离线检查 15/15;真实 HTTP 分页合同 7/7 (tools/verify_http_pagination_hel895.py,真实服务 + 327 行播种 + fetchAfter 缺口游标移植对真实后端复验);真实服务浏览器 7/7(web/tests/hel895_real.mjs, Chromium CDP 对真实 API:留言卡、舞台播放、260 行缺口不跳留言、重启 epoch 去重、 零权限申请。HEL-896 勘误:原 7/7 中 B3 为已证实误报——兜底断言+点击 「日子与回忆」导航钮,stage=false仍 PASS;修订版改精确交互+严格断言共 9 项 检查全过,含权限 API 调用计数 0 与非回环出站守卫 0,证据docs/rework/hel896/browser/,原误报证据保留于docs/rework/hel896/browser-before/)。双目标及实际母线需求检查各含/不含 handoff-HEL-895 共 6/6 通过(origin/main、原产品目标 de8874a3803b、实际母线)。
1. 交付物清单
| 交付物 | 位置/来源 | 说明 |
|---|---|---|
| 代码 | 分支 hel-870-assembly,精确 head 见交付评论 |
含本文件、docs/budget-package-hel895.md、tools/verify_http_pagination_hel895.py、web/tests/hel895_real.mjs |
| Python 依赖 | requirements.lock(19 项固定版本,uv 离线可装) |
Python 3.11(发布机 3.11.16 实测) |
| 前端产物 | web/(原作者界面 + HEL-875/880 主动留言) |
npm ci && npm run build;CSS 哈希与已审核版一致 |
| mem0 固定栈 | deploy/mem0-stack.lock(mem0ai 2.2.1 / qdrant-client 1.20.0 / fastembed 0.9.1) |
3.11 缺 41 项闭包,见 §4;缺项不阻塞其余发布 |
| systemd 模板 | deploy/cybergril-hel874-8360.service.example(PYTHONPATH=src 已内置) |
独立单元/端口/数据目录模式 |
| 配置模板 | config/models.yaml(预算全 0)+ config/semantic.example.yaml |
批准值写入位置见 docs/budget-package-hel895.md(A 仅团队实例,§6) |
| 预算执行包 | docs/budget-package-hel895.md(含 §6 HEL-896 分账修订) |
A/B/C 一次批准核定稿,默认 0 |
| HEL-896 工具 | tools/verify_budget_split_hel896.py、tools/audit_sdk_offline_hel896.py、tools/release_snapshot_hel896.py、修订版 web/tests/hel895_real.mjs |
分账切换验证、SDK 余缺只读审计、一致性快照/回退验证、严格浏览器检查 |
2. 安装命令(发布卡执行;本节是唯一照抄入口——HEL-879 收口)
# 全新目录,逐条照抄;任何一步失败即停。全部安装强制 offline/no-index:
# 缓存命中即装,缓存缺失即停并留证;联网补齐只发生在获批的发布窗口内,
# 逐项 sha256 留证(seq48–51 勘误教训:不写 offline 的安装发生过网络获取)。
# 2.1 服务账号与目录(独立可写数据路径,权限边界明确)
useradd --system --home-dir /opt/cybergril-hel874 --shell /usr/sbin/nologin cybergril || true
mkdir -p /opt/cybergril-hel874/data # data 必须为空:新账从零初始化
chown -R cybergril:cybergril /opt/cybergril-hel874
# 2.2 代码 checkout:全新空目录 clone(空目录里没有仓库,不能直接 git fetch)
git clone ssh://git@192.168.200.36:222/leefer/CyberGril.git /opt/cybergril-hel874/current
git -C /opt/cybergril-hel874/current checkout <交付评论/handoff JSON 记录的精确head>
# 2.3 依赖与前端(uv/npm 一律 offline;缓存缺失即停)
cd /opt/cybergril-hel874/current
uv venv --python 3.11 .venv311
uv pip install --python .venv311/bin/python --offline -r requirements.lock
(cd web && npm ci --offline && npm run build)
# 2.4 服务单元(单元内已带 PYTHONPATH=<current>/src:requirements.lock 只装依赖,
# 产品代码经 PYTHONPATH 进程内可 import)
cp deploy/cybergril-hel874-8360.service.example /etc/systemd/system/cybergril-hel874.service
systemctl daemon-reload && systemctl enable --now cybergril-hel874
curl -s http://127.0.0.1:8360/api/health | python3 -m json.tool
发布前必过检查按 §6 与 deploy/hel874-release.md §6 的清单执行(该节仍有效),
另加本卡工具(真实 HTTP 分页合同、真实服务浏览器)在目标机重跑。
3. 健康能力矩阵(/api/health 预期)
与 deploy/hel874-release.md §3 一致:version=R4-assembly;backend
mood/reach_out/semantic 接线;semantic_backend=stub(发布初期,真实 mem0 待 §4
与 B 部分预算);capabilities.proactive=true(生活循环开启时);voice/vision/
weather/materials/backup=false。主动留言前端已并入本候选:生活循环开启且产生
真实 reach-out 后,打开的页面每 20 秒读一次新行、回来立即读,未读有标记;该行为
已在本 head 用真实服务验证(§0)。
4. 固定 SDK(3.11)激活——唯一照抄入口(HEL-879 收口)
本节取代 deploy/hel874-release.md §4(历史文件,已标注被取代,不得再照抄)。
旧 4.1/4.2 按 deploy/mem0-stack.lock 的 mem0ai==2.2.1 向索引拉同名 wheel——
索引同名 wheel 不能证明固定源码身份 2c81af3,这条路已废除。入口只有一条:
固定 tarball 哈希 → 固定源码构建轮 → 目标 cp311 依赖准备 → 仅本地轮安装 → 同进程 co-import。
- 第 0 步 · 产物清单核对:
docs/rework/hel879/sdk-audit/sdk-audit.json(本候选 精确提交上重跑)与docs/rework/hel879/release-artifacts.json记录闭包 55 项、 缺 41 项、缓存可复用 3 项与逐项哈希;发布卡先核对清单与目标提交一致。 事实口径(HEL-896 审计核定,HEL-879 重跑仍成立):三个顶层固定版本 (mem0ai 2.2.1 / qdrant-client 1.20.0 / fastembed 0.9.1)的 wheel 均为py3-none-any纯 Python;闭包按 3.11 Linux markers+extras 共 55 项,产品 3.11 venv 缺 41 项(28 纯 Python + 13 原生:grpcio/numpy/onnxruntime/ tokenizers/sqlalchemy/protobuf 等),这是闭包清单不是已完成的 cp311 下载结果。 seq48–51 pip 事件勘误保留:不写 offline 的安装发生过网络获取(uv 缓存取证), 故本入口全程--offline/--no-index。 - 第 1 步 · 固定 tarball 哈希核对(零下载):
不一致即停;不得改用索引
sha256sum <hel857-data>/mem0-2c81af3.tar.gz # 必须等于 deploy/mem0-stack.lock 记录的 # 9dcef9303ebcec116eec6739f01b8b35bd24459de6a569686b4d19b9412dda23mem0ai==2.2.1wheel 冒充固定源(audit 已证明两者 身份不可互证)。 - 第 2 步 · 固定源码构建轮(HEL-879 返修:已完成可离线构建):此前此处写
「hatchling 当前不在任何本机缓存、待补」——经总管只读核查与本卡复核勘误:
uv wheels-v6/wheels-v7 均有 hatchling 1.32.4 缓存(
release-artifacts.jsonbuild_backend节逐路径留证)。固定源 tarball 已在 3.11.16 +uv build --wheel --offline下离线构建出轮(零下载、零安装、不混 3.10 site-packages):mem0ai-2.2.1-py3-none-any.whl, sha256698284b6083ab8b7761454d65876a6d1bb983d278ad21a7bee38d760cb20e9db。 发布卡在目标机重跑同一命令并核对该哈希:tar xzf <hel857-data>/mem0-2c81af3.tar.gz && cd mem0-2c81af3*/ uv build --wheel --offline --python 3.11 -o wheels/ sha256sum wheels/mem0ai-2.2.1-py3-none-any.whl - 第 3 步 · 目标 cp311 依赖准备:41 项缺项中缓存今天即可复用 3 项
(greenlet 3.5.6 cp311、pillow 12.3.0 cp311、truststore 0.10.5 py3-none-any,
uv wheels-v6/v7 缓存实测,HEL-879 重跑核实仍命中);其余 37 项
由总管获批后发布窗口拉取(
python3 -m pip download --only-binary :all: --implementation cp --python-version 3.11 --platform manylinux2014_x86_64 --abi cp311 -r <缺项清单> -d wheels/),逐项 sha256 留证;本卡零下载、零联网。 某固定版本若无 cp311 wheel,按 lock 注释如实上报缺项,不换版本号、不混 sdist。 - 第 4 步 · 仅本地轮安装(--no-index 全程,目录里只有上两步产物):
uv pip install --python .venv311/bin/python --no-index \ --find-links <本地wheels目录> mem0ai==2.2.1 qdrant-client==1.20.0 fastembed==0.9.1 <41缺项>deploy/mem0-stack.lock的 mem0ai 行只作版本记录;安装来源必须是第 2 步的 固定源码轮(同版本号不同来源不互认)。 - 第 5 步 · 同进程 co-import 与模型落位:
fastembed 模型缓存(hel857-data/fastembed-cache,Qdrant/bge-small-zh-v1.5 + bm25 约 92MB,实测存在)拷入实例数据目录,真实 mem0 模式 cache_dir 指向它。
.venv311/bin/python -c "import cybergril.api, mem0, qdrant_client, fastembed; print('co-import ok')"
产品 venv 目前 import mem0/qdrant_client/fastembed 均缺、产品代码导入不受影响;
在 wheel 落位且 co-import 通过前,不得以 stub/FTS 冒充真实 Mem0 体验就绪。
真缺的下载(37 项运行闭包;hatchling 已勘误为缓存命中并完成离线构建,不在缺单)
仍待主卡授权,本卡不为补命令联网。
5. 停用与保留数据回退
与 deploy/hel874-release.md §5 相同:CYBERGRIL_SEMANTIC=off|stub 停语义层
(表保留、按后端区分续跑);CYBERGRIL_R2_ENABLED=0 停生活/主动联系;整实例
systemctl stop → 数据目录原样保留 → 切回上一 release/上一提交(R4 迁移全部
增量新表,旧代码可安全打开同一数据库);彻底撤销留数据档不删。
HEL-896 归档/回退修订 + HEL-879 收口(2026-10-27,v3 返修):在线库只复制主
.db 会丢 WAL 里已提交的资料(总管复现件连 companion 表都不在)。发布归档一律
二选一:停服务 + PRAGMA wal_checkpoint(TRUNCATE) 后整目录归档(推荐),或
在线用 SQLite backup API 对显式单库做一致性快照。工具已按收口语义强制执行
(v3;v2 的两处已证缺陷由总管独立复核提出并修复):
- checkpoint 返回 busy≠0 或源/快照行数不一致 → CLI 非 0、不产生可交付归档 (「先停服」是前提,不是忽略失败结果的理由);
- 目录内真实 SQLite(history_root 的
mem0_public_history.db、向量目录内库等, 按文件头魔数递归识别)在停服口径一并 checkpoint+逐表核对; - 在线模式只接受显式
--db(backup API);传入含 SQLite 的--file目录直接拒绝; verify要求三个计数直接相等(manifest 源行数 = manifest 快照行数 = 恢复 实测;rows_match只是额外约束——v2 的rows_match is True or …允许记录值 绕过源计数比较,源 2/快照 1 仍 ok,已废除);回退演练按源路径映射实际恢复 到归档旁的持久独立目标树、打开恢复库核对行数与哈希,输出 rollback_plan;- 归档侧目标名无冲突映射:不同目录的同名
ledger.db不再互相覆盖(v2 后写覆盖 前写仍先交成功包);同一源重复传入直接拒绝。
照抄命令:
# 覆盖范围:产品库(CYBERGRIL_DB)、语义向量目录 vector_root、推导史 history_root、
# 权威嵌入账 ledger_path(按部署实例 config/semantic.yaml 实际路径逐项代入)
# 停服口径(推荐;目录内 SQLite 一并一致性处理):
.venv311/bin/python tools/release_snapshot_hel896.py snapshot \
--name <release-或阶段名> --db <产品库> [--db <权威账>] \
--file <vector_root> --file <history_root> --out /opt/<实例>/archives/
# 在线兜底口径:仅显式单库(backup API),不得传含 SQLite 的目录:
.venv311/bin/python tools/release_snapshot_hel896.py snapshot --name <名> \
--db <产品库> --out /opt/<实例>/archives/ --online
.venv311/bin/python tools/release_snapshot_hel896.py verify --archive <产物>.tar.gz
产物含逐文件 SHA256 清单、代码精确提交(快照时刻 git rev-parse HEAD)、
逐表行数核对与回退演练结果;不删档,旧归档永久保留。回退=停服务 → 解包快照到
新数据目录(按 rollback_plan 的源路径映射)→ 指回上一 release/上一提交 → 起
service → verify 通过后交付。本节是发布归档/回退要求,不冒充 R6(CG-009
每日自动备份/手动完整导出)完成。
6. 本候选不做的事
不合并任何 PR(PR #11 保持开放待总管/白栖知决定);不部署、不交体验地址; 零真实 LLM/嵌入/下载;不触 8300–8350、共享语音口型、GPU/4080;不导入演示测试 档案为用户伴侣;不替视觉作者改稿(前端内容以原作者六文件与 CSS 可追溯为准)。 R5(HEL-878/879 语音)、R6(天气/素材/完整备份)、R7(有条件视觉观察)未接入, 界面保持诚实文案,不冒充已运行。