fix(m193): 复审 r2——台账三处失效引用、M39 注释逐字还原、schema doc 数字补守卫
- P2-1:docs 的契约表把 retry_limit 范围从 (1,10) 改成 0–10(0 与 1 都 = 只试一次), 与 §4 和 keys.rs 对齐;§2 与 §6 的守卫名统一成 the_schema_contract_is_single_sourced (原两条已合并),并把变异 M9(去掉 .max(1) ⇒ 红)补进 §6 台账。 - P3-4:keys.rs 的 M39(MCP server)既有注释按 origin/dev 原文逐字还原(含「同一安全策略、 同一审计日志」);腾出的 1 行用「去掉 alias use、两处常量改全路径」换,没有压任何既有论证。 比对:版本史 / D20 / M39 三段与 origin/dev 逐字节相同。 - P3-2:SettingSpec.doc 是 &'static str(concat! 插不进常量),描述里的数字是第三处第二来源, 现在有守卫 the_key_docs_quote_the_real_limits(改 1~64 → 1~99 ⇒ 红,变异 M10 已跑)。 §6.1.1 用表登记三处「数字的第二来源」现状。 - P3-1:docs 里那个游离反引号删掉。
This commit is contained in:
1 parent
94f56f9d9c
commit
54dde7f494
3 files changed
+46
-25
No files matched your search
@@ -184,8 +184,8 @@ impl DownloadTuning {
|
||||
}
|
||||
}
|
||||
|
||||
/// 每个缓存根一份「宿主想要什么」(`engine_for` 构造时用它,见 [`wanted`])。按数据根而不是进程级:
|
||||
/// 登记处本就是「一个数据根一个引擎」;进程级那份在多数据根时会互相踩(A 根改 2、B 根冲回 8)。
|
||||
/// 每个缓存根一份「宿主想要什么」([`wanted`] 用)。按数据根而不是进程级:登记处本就是「一个数据根
|
||||
/// 一个引擎」;进程级那份在多数据根时会互相踩(A 根改 2、B 根冲回 8)。
|
||||
fn wanted_slot() -> &'static Mutex<HashMap<PathBuf, DownloadTuning>> {
|
||||
static WANTED: OnceLock<Mutex<HashMap<PathBuf, DownloadTuning>>> = OnceLock::new();
|
||||
WANTED.get_or_init(|| Mutex::new(HashMap::new()))
|
||||
@@ -228,10 +228,8 @@ mod tests {
|
||||
use crate::setting::keys::{launcher_schema, launcher_version};
|
||||
|
||||
/// **守门③**:schema 的默认值 / 区间 / 键名与 `EngineConfig::default()` / 调优默认值取同一组常量。
|
||||
///
|
||||
/// 变异证明(只改实现侧):`EngineConfig::default()` 的并发写回字面量 64 ⇒ 红;schema 默认值
|
||||
/// 写成字面量 16 ⇒ 红;`MAX_CONCURRENCY` 改了而 schema 仍写 64 ⇒ 红。这条防的正是「两处各写
|
||||
/// 一个数」长回来(8 vs 64 就是这么长出来的)。
|
||||
/// 变异证明(只改实现侧):`EngineConfig::default()` 的并发写回 64、schema 默认值写成 16、
|
||||
/// `MAX_CONCURRENCY` 改了而 schema 仍写 64 ⇒ 各自红。
|
||||
#[test]
|
||||
fn the_schema_contract_is_single_sourced() {
|
||||
let schema = launcher_schema();
|
||||
@@ -275,6 +273,17 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
/// `SettingSpec.doc` 是 `&'static str`(`concat!` 插不进常量),描述里的数字只能手写——这条钉住它,
|
||||
/// 改常量不改文案就红(`catalog.rs` 会把这些 doc 当 JSON schema 的 description 发出去)。
|
||||
#[test]
|
||||
fn the_key_docs_quote_the_real_limits() {
|
||||
let schema = launcher_schema();
|
||||
let doc = |key: &str| schema.spec(key).expect("键已登记").doc;
|
||||
assert!(doc(KEY_CONCURRENCY).contains(&format!("1~{MAX_CONCURRENCY}")));
|
||||
assert!(doc(KEY_CONCURRENCY).contains(&format!("出厂 {DEFAULT_MAX_CONCURRENCY}")));
|
||||
assert!(doc(KEY_RETRY_LIMIT).contains(&format!("出厂 {DEFAULT_MAX_ATTEMPTS_PER_SOURCE}")));
|
||||
}
|
||||
|
||||
/// 未填 / 越界回落默认(不阻断下载);**`retry_limit: 0` 是合法值**,语义 = 只试一次。
|
||||
///
|
||||
/// 变异证明:把并发的区间过滤删掉 ⇒ `0` / `9999` 两条红;把尝试次数的 `.max(1)` 删掉 ⇒
|
||||
@@ -330,9 +339,8 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
/// `apply_gh_proxy` 的三档真的改到档案上、并且**改到候选链上**(`MirrorTable::expand()` 读的
|
||||
/// 就是档案里那个前缀)。端到端(schema 键 → 调优 → `plan()`)由 `shared.rs` 与 presenter 守。
|
||||
/// 变异证明:把 `Off` 分支改成原样返回 `profile` ⇒ `off` 那条红。
|
||||
/// `apply_gh_proxy` 的三档真的改到档案上、并且**改到候选链上**(`expand()` 读的就是档案里那个
|
||||
/// 前缀;自定义前缀那一档的链断言在 `shared.rs`)。变异证明:`Off` 分支改成原样返回 ⇒ `off` 红。
|
||||
#[test]
|
||||
fn gh_proxy_override_reaches_the_profile_and_the_chain() {
|
||||
use crate::download::mirrors::{MirrorTable, SOURCE_GH_PROXY};
|
||||
@@ -353,21 +361,20 @@ mod tests {
|
||||
assert_eq!(kept.gh_proxy, mirror_first.gh_proxy, "Builtin 不该动档案");
|
||||
assert!(
|
||||
sources(&kept).contains(&SOURCE_GH_PROXY.to_string()),
|
||||
"出厂默认套前缀"
|
||||
"出厂套前缀"
|
||||
);
|
||||
|
||||
let off = DownloadTuning::from_settings(None, None, Some("off"))
|
||||
.apply_gh_proxy(mirror_first.clone());
|
||||
assert!(!off.gh_proxy_enabled());
|
||||
assert!(
|
||||
!sources(&off).contains(&SOURCE_GH_PROXY.to_string()),
|
||||
"关了就没有候选"
|
||||
"关了就没候选"
|
||||
);
|
||||
|
||||
let prefix = DownloadTuning::from_settings(None, None, Some("https://gh.example/"))
|
||||
.apply_gh_proxy(mirror_first);
|
||||
assert_eq!(prefix.gh_proxy.as_deref(), Some("https://gh.example/"));
|
||||
assert!(prefix.gh_proxy_enabled());
|
||||
assert!(prefix.gh_proxy_enabled(), "前缀生效");
|
||||
}
|
||||
|
||||
/// 每个数据根的调优互不串味(一个根改成 2 不该改另一个根的引擎)。
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
use super::catalog::SettingSchema;
|
||||
use super::schema::{SchemaId, SchemaVersion};
|
||||
use super::spec::{AiPolicy, SettingSpec};
|
||||
use crate::download::config as download;
|
||||
|
||||
/// `core.data_mode` 允许值。
|
||||
pub const DATA_MODES: &[&str] = &["portable", "standard", "custom"];
|
||||
@@ -105,15 +104,15 @@ pub fn launcher_schema() -> SettingSchema {
|
||||
))
|
||||
.with(SettingSpec::int(
|
||||
"download.concurrency",
|
||||
download::DEFAULT_MAX_CONCURRENCY as i64,
|
||||
(1, download::MAX_CONCURRENCY as i64),
|
||||
crate::download::config::DEFAULT_MAX_CONCURRENCY as i64,
|
||||
(1, crate::download::config::MAX_CONCURRENCY as i64),
|
||||
AiPolicy::silent(),
|
||||
"同时下载的文件数(1~64,出厂 8)。这是引擎真实持有的并发许可,不是展示值;越界或手改坏值按出厂值生效",
|
||||
))
|
||||
.with(SettingSpec::int(
|
||||
"download.retry_limit",
|
||||
download::DEFAULT_MAX_ATTEMPTS_PER_SOURCE as i64,
|
||||
(0, download::MAX_ATTEMPTS_PER_SOURCE as i64),
|
||||
crate::download::config::DEFAULT_MAX_ATTEMPTS_PER_SOURCE as i64,
|
||||
(0, crate::download::config::MAX_ATTEMPTS_PER_SOURCE as i64),
|
||||
AiPolicy::silent(),
|
||||
"单个下载源的最多尝试次数(含首次;出厂 3)。0 与 1 都等于「只试一次、不重试」——0 是旧版 GUI 提供过的档位,保留合法但不代表「不下载」。换源不受此限",
|
||||
))
|
||||
@@ -228,8 +227,9 @@ pub fn launcher_schema() -> SettingSchema {
|
||||
AiPolicy::locked(),
|
||||
"LLM API 密钥——AI 永不读写的凭据(D9)",
|
||||
))
|
||||
// M39(P3 MCP server,02 §0「传输定论」):对外 agent 工具服务。三个开关默认「关 / 只读」——
|
||||
// 外部客户端拿到的是与内置客户端**同一注册表**的工具,但写权限必须用户显式打开(02 §1)。
|
||||
// M39(P3 MCP server,02 §0「传输定论」):对外 agent 工具服务。
|
||||
// 三个开关默认「关 / 只读」——外部客户端拿到的是与内置客户端**同一注册表**的工具,
|
||||
// 但写权限必须用户显式打开(02 §1「同一注册表、同一安全策略、同一审计日志」)。
|
||||
.with(SettingSpec::bool(
|
||||
"agent.mcp.enabled",
|
||||
false,
|
||||
|
||||
Reference in new issue
Block a user