fix(m197): 复审 r1 的 P1 + 三条 P2(描述对齐行为 / 内部编号下屏 / kind 守卫 / gh-proxy 可覆盖)

P1(阻断)`java.auto_install` 的描述与行为不一致——那句会进 AI 工具的 JSON Schema
`description`,等于让助手对用户说一件实现刻意不做的事:
- `crates/core/src/setting/keys.rs`:改成「缺 Java 时在 Java 页标出推荐版本并可一键安装;
  不会自动下载」,去掉 `(D13 基准 JDK17)`。
- `SettingsJavaAutoInstallHint` 中英两侧各补一句显式否定(「不会自己开始下载 —— 点「安装」
  才会下」/ "Nothing is downloaded on its own — you press Install."),标签从「自动准备」改成
  「缺 JDK 时推荐一档」;金表同步。
- 新增守卫 `the_auto_install_description_says_it_never_downloads_by_itself`(描述必须含
  「不会自动下载」、不含旧说法与内部编号)。

P2-1 内部决策编号印在界面上:`SettingsJavaDownloadBaseline` 的 `Baseline (D13)` /
`基准版本(D13)` → `Recommended baseline` / `推荐基准版本`(金表同步)。另加两条目录级守卫
(`no_user_visible_string_mentions_an_internal_decision_id` /
`no_user_visible_string_carries_markdown_backticks`);后者顺带清掉 M168 遗留的
`FontCjkStatusHint` 里的 `ui.font_cdn` 反引号——全仓最后一条。

P2-2 `ProgressEvent::SourceFailed.kind` 没有守卫:`engine_mock_test`
- `reports_progress_events_and_errors_when_all_sources_fail` 的解构补 `kind`,断言
  `ServerError`;
- 新增 `a_404_is_classified_as_not_found_and_never_cools_the_source_down`(404 → `NotFound`,
  与「源坏了」分开)。

P2-3 交付任务书那句「(默认值可改)」:新增 `download.gh_proxy`(空 = 跟随内置默认 /
`off` = 关 / 其它 = 覆盖前缀),`engine_with` 是它的真消费者(改 `RegionProfile`,因为
`gh_proxy_candidates` 读的就是档案里的前缀);Java 页不画 UI(归 M193)。**内置默认值没动**。
schema minor 1.7.0 → 1.8.0(新键必须推 minor),三处硬编码 minor 的用例同步。

另:真下载用例改成 panic 也清理(复审顺带项 7④);`downloads/refusal.rs` 的「四档」改「五档」。
This commit is contained in:
AskaEth committed 2026-11-08 21:35:13 +08:00
1 parent 9a7b138d08
commit a14b00aced
15 files changed
+387 -28

No files matched your search

+2 -2
View File
@@ -131,8 +131,8 @@ fn appearance_keys_are_all_ai_writable_and_registered() {
fn schema_registration_shape_is_right() {
assert_eq!(
launcher_version().minor,
7,
"1.7.0 登记 M168 的 ui.font_cdn(1.6.0 是 M161 的自更新两键)"
8,
"1.8.0 登记 M197 的 download.gh_proxy(1.7.0 是 M168 的 ui.font_cdn)"
);
let schema = launcher_schema();
assert_eq!(
+4 -3
View File
@@ -128,9 +128,10 @@ fn overrides_key_is_an_enum_whitelist() {
#[test]
fn schema_versions_register_the_new_keys_without_migration() {
// 1.7.0 登记 M168 的 `ui.font_cdn`(1.6.0 登记 M161 的自更新两键,1.5.0 = M116 窗口圆角,
// 1.4.0 = M91 外观下层三键,1.3.0 = D17「外观(高级)」,1.2.0 = D23 的 JDK 落点/优先级键)。
assert_eq!(launcher_version(), SchemaVersion::new(1, 7, 0));
// 1.8.0 登记 M197 的 `download.gh_proxy`(1.7.0 = M168 的 `ui.font_cdn`,1.6.0 登记 M161 的
// 自更新两键,1.5.0 = M116 窗口圆角,1.4.0 = M91 外观下层三键,1.3.0 = D17「外观(高级)」,
// 1.2.0 = D23 的 JDK 落点/优先级键)。
assert_eq!(launcher_version(), SchemaVersion::new(1, 8, 0));
assert_eq!(instance_version(), SchemaVersion::new(1, 1, 0));
assert_eq!(launcher_schema().id(), SchemaId::LAUNCHER);
// major 仍是 1:迁移链(按 major 走)不需要新步骤,老文件缺键即默认值。
+32 -4
View File
@@ -66,10 +66,10 @@ fn install_root_accepts_a_path_and_keeps_empty_as_unset() {
#[test]
fn schema_version_bumps_minor_only_so_no_migration_step_is_needed() {
// 1.7.0 = M168 的中文字体下载地址覆盖键(`ui.font_cdn`;此前 1.6.0 是 M161 的自更新两键,
// 1.5.0 是 M116 窗口圆角)。每加一批键推一次 minor 是**纪律**,不是巧合:
// 老版本读新文件会判 `ReadOnlyPreserveSchema`,所以版本号本身就是「新键存在」的对外声明。
assert_eq!(launcher_version(), SchemaVersion::new(1, 7, 0));
// 1.8.0 = M197 的 gh-proxy 覆盖键(`download.gh_proxy`;此前 1.7.0 是 M168 的 `ui.font_cdn`,
// 1.6.0 是 M161 的自更新两键,1.5.0 是 M116 窗口圆角)。每加一批键推一次 minor 是**纪律**,
// 不是巧合:老版本读新文件会判 `ReadOnlyPreserveSchema`,所以版本号本身就是「新键存在」的对外声明。
assert_eq!(launcher_version(), SchemaVersion::new(1, 8, 0));
assert_eq!(
launcher_version().major,
1,
@@ -120,3 +120,31 @@ fn an_old_config_file_without_the_new_keys_still_loads() {
);
let _ = std::fs::remove_dir_all(&dir);
}
/// `java.auto_install` 的 schema 描述必须与实现一致:**不会**自动下载。
///
/// 这句会进 AI 工具的 JSON Schema `description`(`setting/catalog.rs` 把 `spec.doc` 原样塞进去),
/// 所以它不是注释而是**对外文案**:写「缺 Java 时自动下载」等于让启动器自己的助手对用户说
/// 一件实现刻意不做的事(M197 复审 r1 的 P1)。
///
/// 变异证明:把描述改回「缺 Java 时自动下载(D13 基准 JDK17)」⇒ 本用例红(三句断言都会红)。
#[test]
fn the_auto_install_description_says_it_never_downloads_by_itself() {
let schema = launcher_schema();
let doc = schema
.spec("java.auto_install")
.expect("java.auto_install 必须登记")
.doc;
assert!(
doc.contains("不会自动下载"),
"描述必须写明「不会自动下载」(AI 会照这句话告诉用户):{doc}"
);
assert!(
!doc.contains("缺 Java 时自动下载"),
"描述不许再写「缺 Java 时自动下载」:{doc}"
);
assert!(
!doc.contains("D13"),
"描述里不许出现内部决策编号(用户与助手都不知道 D13 是什么):{doc}"
);
}