@@ -263,19 +263,30 @@ pub fn second_pass_decide(
263263 if session_id <= 0 || draft_id <= 0 {
264264 return Err ( "参数非法" . to_string ( ) ) ;
265265 }
266+ // 属主校验:草稿必须属于该会话(second_pass 与 proofread 两 origin 共用
267+ // 裁决通道——防跨会话 id 误改/越权访问,IPC 校验红线)
268+ let mut drafts = state
269+ . db
270+ . list_refine_drafts ( session_id, ORIGIN_SECOND_PASS , None )
271+ . map_err ( |e| format ! ( "读取草稿失败: {e}" ) ) ?;
272+ drafts. extend (
273+ state
274+ . db
275+ . list_refine_drafts ( session_id, crate :: db_session_refine:: ORIGIN_PROOFREAD , None )
276+ . map_err ( |e| format ! ( "读取草稿失败: {e}" ) ) ?,
277+ ) ;
278+ if !drafts. iter ( ) . any ( |d| d. id == draft_id) {
279+ return Err ( "草稿不存在于该会话(id 越界或已随会话删除)" . to_string ( ) ) ;
280+ }
266281 let status = if adopt { STATUS_ADOPTED } else { STATUS_REJECTED } ;
267282 state
268283 . db
269284 . decide_refine_draft ( draft_id, status)
270285 . map_err ( |e| format ! ( "裁决失败: {e}" ) ) ?;
271- // REQ-269 采集:采纳时把 (旧文→新文)词级差异记入混淆画像(失败仅日志——
272- // 画像为质量增强层 ,不影响裁决主链路)
286+ // REQ-269 采集:采纳第二遍草稿时把 (旧文→新文)词级差异记入混淆画像
287+ // (仅 second_pass origin——校对源不采集;失败仅日志 ,不影响裁决主链路)
273288 if adopt {
274- let drafts = state
275- . db
276- . list_refine_drafts ( session_id, ORIGIN_SECOND_PASS , Some ( STATUS_ADOPTED ) )
277- . map_err ( |e| format ! ( "读取草稿失败: {e}" ) ) ?;
278- if let Some ( d) = drafts. iter ( ) . find ( |x| x. id == draft_id) {
289+ if let Some ( d) = drafts. iter ( ) . find ( |x| x. id == draft_id && x. origin == ORIGIN_SECOND_PASS ) {
279290 if let Ok ( mut store) = state. asr_confusion . lock ( ) {
280291 store. record_adoption ( & d. base_text , & d. refined_text ) ;
281292 if let Err ( e) = store. save ( & state. asr_confusion_path ) {
0 commit comments