优化: 弱模型治理收尾(AC-2探索预算:单轮上限+目录去重+禁绕行 + AC-5失败画像:合法目标回灌+相近锚点提示)

This commit is contained in:
lxy
2026-08-08 19:38:53 +08:00
parent 02c8d8e5ea
commit fe780c0084
8 changed files with 648 additions and 12 deletions
+47
View File
@@ -112,6 +112,20 @@ pub fn can_transition(from: &str, to: &str) -> bool {
table.get(&(from, to)).copied().unwrap_or(false)
}
/// 返回从 `from` 出发的所有合法目标状态列表。
///
/// 供 advance_task 错误提示复用:状态机拒绝非法转换时,把「当前状态 + 合法目标」附进
/// 错误信息,让 LLM 下次直接选对目标态,避免靠猜反复触发状态机拒绝。
/// 遍历 ALL_STATES 过滤 can_transition,与状态机矩阵单一真相源对齐(矩阵改动自动同步)。
/// 终态(done/cancelled)无合法后继 → 返回空列表,调用方据此提示「终态无后继」。
pub fn legal_targets(from: &str) -> Vec<&'static str> {
ALL_STATES
.iter()
.copied()
.filter(|to| can_transition(from, to))
.collect()
}
/// 判定一次转换是否为「退回」(review_rounds 应 +1)。
///
/// 退回语义:任务从前向推进阶段回退到更早的推进阶段,意味着上一轮产出未过闸门、
@@ -229,6 +243,39 @@ mod tests {
assert!(!can_transition(BLOCKED, DONE));
}
// ---------- legal_targets(错误提示用合法目标列表) ----------
#[test]
fn legal_targets_matches_transition_matrix() {
// 逐态锁定合法目标列表(顺序 = ALL_STATES 遍历序),与 can_transition 矩阵一一对应
assert_eq!(legal_targets(TODO), vec![IN_PROGRESS, CANCELLED]);
assert_eq!(legal_targets(IN_PROGRESS), vec![IN_REVIEW, BLOCKED, CANCELLED]);
assert_eq!(legal_targets(IN_REVIEW), vec![IN_PROGRESS, TESTING, BLOCKED, CANCELLED]);
assert_eq!(legal_targets(TESTING), vec![IN_REVIEW, DONE, BLOCKED, CANCELLED]);
assert_eq!(legal_targets(BLOCKED), vec![IN_PROGRESS, CANCELLED]);
// 终态无合法后继
assert!(legal_targets(DONE).is_empty());
assert!(legal_targets(CANCELLED).is_empty());
}
#[test]
fn legal_targets_all_returned_values_are_valid_and_allowed() {
// 性质断言:任何合法目标都必须是合法状态值且 can_transition 放行(防列表与矩阵漂移)
for from in ALL_STATES {
for to in legal_targets(from) {
assert!(is_valid_state(to), "legal_targets({from}) 返回 {to:?} 不是合法状态值");
assert!(can_transition(from, to), "legal_targets({from}) 含 {to:?} 但 can_transition 拒绝");
}
}
}
#[test]
fn legal_targets_unknown_state_empty() {
// 未知态防御性 → 空列表(不 panic,调用方提示无合法后继)
assert!(legal_targets("merged").is_empty());
assert!(legal_targets("").is_empty());
}
// ---------- 未知状态 ----------
#[test]