1111
1212use serde:: { Deserialize , Serialize } ;
1313
14- /// 十二类档案标识(全栈统一业务术语)。
14+ /// 十二类档案标识(全栈统一业务术语;v0.7.1 起含 Unknown 共十三值 )。
1515#[ derive( Debug , Clone , Copy , PartialEq , Eq , Serialize , Deserialize ) ]
1616#[ serde( rename_all = "kebab-case" ) ]
1717pub enum ProfileKind {
@@ -39,6 +39,9 @@ pub enum ProfileKind {
3939 FollowAlong ,
4040 /// v0.7.0 REQ-121(T3):编程实战——OCR+ASR 双通道(示例代码提取)
4141 Coding ,
42+ /// v0.7.1 用户需求:未知——自动检测无法识别时如实标注(不假装猜中);
43+ /// 无内置档案配置,管线参数回退默认(Lecture)档(零回归),产物模板同网课讲义。
44+ Unknown ,
4245}
4346
4447impl ProfileKind {
@@ -58,12 +61,14 @@ impl ProfileKind {
5861 ProfileKind :: Exercise => "题目讲解" ,
5962 ProfileKind :: FollowAlong => "跟练" ,
6063 ProfileKind :: Coding => "编程实战" ,
64+ ProfileKind :: Unknown => "未知" ,
6165 }
6266 }
6367
6468 /// 解析前端传入的档案标识(kebab-case);非法值回退 Lecture(默认档案不阻断)。
6569 pub fn parse ( s : & str ) -> ProfileKind {
6670 match s {
71+ "unknown" => ProfileKind :: Unknown ,
6772 "hands-on" => ProfileKind :: HandsOn ,
6873 "talking-head" => ProfileKind :: TalkingHead ,
6974 "interview" => ProfileKind :: Interview ,
@@ -94,6 +99,7 @@ impl ProfileKind {
9499 ProfileKind :: Exercise => "exercise" ,
95100 ProfileKind :: FollowAlong => "follow-along" ,
96101 ProfileKind :: Coding => "coding" ,
102+ ProfileKind :: Unknown => "unknown" ,
97103 }
98104 }
99105}
@@ -213,7 +219,7 @@ pub struct VideoProfile {
213219/// 五档案内置常量(默认值;JSON 导出后可人工校准覆盖)。
214220pub use crate :: video_profile_data:: builtin_profiles;
215221
216- /// 按档案标识查内置档案(未知标识回退 Lecture——默认档案不阻断)。
222+ /// 按档案标识查内置档案(Unknown/ 未知标识回退 Lecture——默认档案不阻断)。
217223pub fn profile_by_kind ( kind : ProfileKind ) -> VideoProfile {
218224 let mut profiles = builtin_profiles ( ) ;
219225 let idx = profiles. iter ( ) . position ( |p| p. kind == kind) . unwrap_or ( 0 ) ;
@@ -246,7 +252,7 @@ pub struct ProfileCandidate {
246252/// 检测结果。
247253#[ derive( Debug , Clone , PartialEq , Serialize , Deserialize ) ]
248254pub struct DetectResult {
249- /// 候选档案(降序;全部 0 分时为默认 Lecture 单候选)
255+ /// 候选档案(降序;全部 0 分时为 Unknown 单候选——诚实未知,不猜默认 )
250256 pub candidates : Vec < ProfileCandidate > ,
251257 /// 是否需用户确认(信号冲突/得分不足——置信度低才问,高则静默生效可改)
252258 pub needs_confirmation : bool ,
@@ -273,9 +279,10 @@ pub fn vote_detect(signals: &ObservedSignals) -> DetectResult {
273279 . collect ( ) ;
274280 let max = scored. iter ( ) . map ( |( _, s) | * s) . fold ( 0.0f32 , f32:: max) ;
275281 if max <= 0.0 {
276- // 无任何信号命中:默认 Lecture 且需确认(不静默假设)
282+ // 无任何信号命中:Unknown 单候选 + 需确认(诚实未知,不假装猜中网课;
283+ // v0.7.1 用户需求:无法自动识别时选中"未知")
277284 return DetectResult {
278- candidates : vec ! [ ProfileCandidate { kind: ProfileKind :: Lecture , score: 1.0 } ] ,
285+ candidates : vec ! [ ProfileCandidate { kind: ProfileKind :: Unknown , score: 1.0 } ] ,
279286 needs_confirmation : true ,
280287 memory_hit : None ,
281288 } ;
0 commit comments