fix(core,app-iced): M308 Linux/macOS 的 .tar.gz 真的能自替换 + 重试按 retryable 分流 + 三处文档纠偏
M307 盘查抓到的一条真缺陷 + 两处交互/文档不一致,本条只修它们,不重做通道:
① Linux/macOS 自更新的真缺陷(选 A:真做)
`job::self_replaceable` 只认裸 exe,而发布矩阵里那两平台的启动器是 `.tar.gz`(清单记作
`portable-zip`)⇒ 查得到更新、按钮画得出来、点下去必失败。新增 `core::update::unpack`:
**归档字节过完长度/摘要双检之后**,从归档里取出启动器本体(tar 头 mode 有可执行位 /
`.exe` 名字的唯一普通文件),再交给原有的 `install_staged`(原子替换 + 回滚一字未改)。
零新依赖(flate2/tar 早就是 core 的依赖,`core::game::java` 解 Temurin 用同一套)。
三条具名错误:`LauncherMissing` / `LauncherNotExecutable`(魔数与 target 不符)/
`LauncherSizeMismatch`(0 字节 / 超上限 / 与头声明不符);zip 容器**明确拒绝**(没有可靠的
「哪个条目可执行」判据,不猜)。`target.rs` 的 `PackageFormat` 文档改成与判据逐字一致。
② 重试按钮按 `retryable` 分流
验签类(`is_retryable == false`)不画「重试」,正文换成新 key `UpdateBannerFailedFinal`
(「这次更新已被拒绝(重试没用):{reason}」)。文案抽到 `pages/update/failure.rs`
(`pages/update.rs` 的红线),判据落在**真 Widget 树**上(探针 tag + 递归计数)。
③ 三处文档纠偏 + 同一条谎话的其它落点(都在 scope 内)
`trust.rs`(正式表已有 `ull-release`,commit 68362e5)、`check_signing_ready.py` 自述、
`target.rs`;顺带 `packaging/README.md`、`docs/{signing,signing-runbook}.md`、
`check_test_key_off.py`;新文档 `docs/update-trust-anchor.md` 记「M254 审计的『正式表为空』
已作废」。
判据:core 新增 `unpack_cases`(Linux tar.gz / macOS tar.gz 走完整条链 + 五种拒绝)、
`job_cases` 的形态表改成两种;app-iced 两条真 Widget 树用例(按钮在 / 不在)+ 一条取词入口用例
+ 一条源码守卫。i18n 加一条 key 并**重出金表**(`Key::ALL` 853 行,新行落在 index 834)。
This commit is contained in:
1 parent
db24379e35
commit
af82658d08
24 files changed
+1201
-58
No files matched your search
@@ -1,17 +1,21 @@
|
||||
#!/usr/bin/env python3
|
||||
"""签名就绪度播报(M255):**只读**、零第三方依赖,三行说清「今天能不能签发一份客户端会认的清单」。
|
||||
"""签名就绪度播报(M255,**M308 纠偏**):**只读**、零第三方依赖,三行说清「今天能不能签发一份客户端会认的清单」。
|
||||
|
||||
为什么要它:M254(CLAIMAUDIT)查出 `crates/core/src/update/trust.rs` 的 `PRODUCTION` 表在
|
||||
`PINNED-KEYS` 标记之间是**空的**,而空表一律 `KeyringEmpty` 拒装 —— 于是**今天任何正式二进制都验不过
|
||||
任何清单**(fail-closed 是成立的,但在用户机器上表现为「更新永远失败」)。工具链早就齐了
|
||||
(`sign_manifest.py` 的 `--generate-key` / `--check-pinned-keyring` / `--sign` / `--verify-pinned`),
|
||||
缺的是**操作步骤与可见性**。本脚本只负责「现在差什么」,它不生成钥、不写任何文件、不改 `trust.rs`。
|
||||
为什么要它:M254(CLAIMAUDIT)当时查出 `crates/core/src/update/trust.rs` 的 `PRODUCTION` 表在
|
||||
`PINNED-KEYS` 标记之间是**空的**,而空表一律 `KeyringEmpty` 拒装 —— 那样任何正式二进制都验不过任何
|
||||
清单(fail-closed 成立,但在用户机器上表现为「更新永远失败」)。**那条读数已经过时**:commit
|
||||
`68362e5` 起 `PRODUCTION` 里钉着一条 `ull-release`,今天的正式构建认这把钥签的清单。本脚本照旧
|
||||
只负责「现在差什么」:它不生成钥、不写任何文件、不改 `trust.rs`;① 那一行的判据也从「是不是空的」
|
||||
变成了「标记之间有几条 PinnedKey」,空表那天它照样会喊未就绪。
|
||||
|
||||
工具链早就齐了(`sign_manifest.py` 的 `--generate-key` / `--check-pinned-keyring` / `--sign` /
|
||||
`--verify-pinned`),缺的从来是**操作步骤与可见性**。
|
||||
|
||||
三行就绪度(各一条判据,互不替代):
|
||||
|
||||
| 行 | 判据 | 未就绪意味着 |
|
||||
|---|---|---|
|
||||
| ① | `PRODUCTION` 表非空:解析 `PINNED-KEYS` 标记之间的 `PinnedKey` 条目,0 条即未就绪 | 客户端一把公钥都没有,任何清单都验不过(今天就是这个状态) |
|
||||
| ① | `PRODUCTION` 表非空:解析 `PINNED-KEYS` 标记之间的 `PinnedKey` 条目,0 条即未就绪 | 客户端一把公钥都没有,任何清单都验不过(**不是**今天的状态:表里已有 `ull-release`;哪天有人把标记之间清空,这一行会立刻喊未就绪) |
|
||||
| ② | 环境里有签名钥:`ULL_MANIFEST_SIGNING_KEY`(或 `--key <文件>`)能解出 32 字节种子,**且**它的公钥在 ① 的表里 | 没钥签不了;钥与信任表不是同一把 ⇒ 发布时 `--check-pinned-keyring` 当场红 |
|
||||
| ③ | 最近一次发布的 `manifest.json` / `.sig` 痕迹 | **不参与就绪判定**。取不到证据就写「未知」——「本地没留档」不等于「上次没签」 |
|
||||
|
||||
@@ -78,7 +82,8 @@ def table_state(path: Path) -> tuple[bool, str, list[tuple[str, str]]]:
|
||||
if keys:
|
||||
names = "、".join(f"{kid}({pk[:16]}…)" for kid, pk in keys)
|
||||
return True, f"就绪 —— 标记之间 {len(keys)} 条:{names}({path}:{line_no} 起)", keys
|
||||
# 空表就是今天的状态。顺手查一个真实易错点:有人把条目贴到标记**外面**(`];` 之后)。
|
||||
# 标记之间 0 条 = 未就绪(M254 那天就是这个状态;今天表里有 `ull-release`,这条分支只会在
|
||||
# 有人清空标记之间的内容时亮)。顺手查一个真实易错点:有人把条目贴到标记**外面**(`];` 之后)。
|
||||
# ⚠ 本仓另有一把 `TEST_ONLY` 测试钥**本来就在标记之外**(那是它的正确位置),所以这里只**点名**,
|
||||
# 不替人下结论 —— 上一版写成「贴错位置,等于没钉」,在真实 trust.rs 上是误报(实测抓出来的)。
|
||||
strays = [kid for kid, _ in KID_RE.findall(text[:begin]) + KID_RE.findall(text[end:])]
|
||||
|
||||
Reference in new issue
Block a user