/// engine_eval.mbt —— 反馈收敛(R111 · Evaluator-Optimizer schema 蒸馏)。
/// 把自由文本反馈归一为四段式 Defects/Evidence/Fix/Acceptance 契约 + 确定性 verdict:
/// 无缺陷且 acceptance 非空 → pass(optimizer 可收敛);否则 fail + 缺段/证据/修复标注。
/// 纯计算只读不写库(决策建议,执行权在调用方;与 plan_revise 反馈修订互补)。
///|
/// 从反馈文本解析某 `## 段名` 下的 `- 列表项`(遇到下一个 `## ` 标题即结束)。
fn parse_section(text : String, header : String) -> Array[String] {
let out : Array[String] = []
let mut in_section = false
for line in text.split("\n") {
let t = line.trim()
if t.starts_with("## ") {
in_section = t == "## " + header
} else if in_section && t.starts_with("- ") {
let s = t.to_owned()
out.push(s.substring(start=2, end=s.length()))
}
}
out
}
///|
/// 反馈文本中是否存在某 `## 段名` 标题(段"在场"判定,与条目数无关)。
fn section_present(text : String, header : String) -> Bool {
for line in text.split("\n") {
if line.trim() == "## " + header {
return true
}
}
false
}
///|
/// 反馈收敛:归一为四段式 schema + verdict(E/O 蒸馏:生成→评估→定向修订→收敛)。
/// 返回 { ok, task_id, schema:{defects,evidence,fix,acceptance}, counts, verdict, flags, note }。
pub fn FistEngine::eval_feedback(
self : FistEngine,
feedback : String,
task_id? : String = "",
) -> Json {
let defects = parse_section(feedback, "Defects")
let evidence = parse_section(feedback, "Evidence")
let fix = parse_section(feedback, "Fix")
let acceptance = parse_section(feedback, "Acceptance")
let d = defects.length()
let e = evidence.length()
let f = fix.length()
let a = acceptance.length()
let flags : Array[String] = []
if d > 0 && e == 0 {
flags.push("evidence_missing")
}
if d > 0 && f == 0 {
flags.push("fix_missing")
}
let missing : Array[String] = []
let has_defects = section_present(feedback, "Defects")
if !has_defects {
missing.push("Defects")
}
let has_evidence = section_present(feedback, "Evidence")
if !has_evidence {
missing.push("Evidence")
}
let has_fix = section_present(feedback, "Fix")
if !has_fix {
missing.push("Fix")
}
let has_acceptance = section_present(feedback, "Acceptance")
if !has_acceptance {
missing.push("Acceptance")
}
if missing.length() > 0 {
flags.push("section_missing:" + missing.join(","))
}
let verdict = if d == 0 && a > 0 { "pass" } else { "fail" }
let (sc_d, sc_e, sc_f, sc_a) = (
d.to_double(),
e.to_double(),
f.to_double(),
a.to_double(),
)
Json::object({
"ok": Json::boolean(true),
"task_id": Json::string(task_id),
"schema": Json::object({
"defects": Json::array(defects.map(Json::string)),
"evidence": Json::array(evidence.map(Json::string)),
"fix": Json::array(fix.map(Json::string)),
"acceptance": Json::array(acceptance.map(Json::string)),
}),
"counts": Json::object({
"defects": Json::number(sc_d),
"evidence": Json::number(sc_e),
"fix": Json::number(sc_f),
"acceptance": Json::number(sc_a),
}),
"verdict": Json::string(verdict),
"flags": Json::array(flags.map(Json::string)),
"note": Json::string(
"反馈收敛(Evaluator-Optimizer schema 蒸馏):feedback 归一为 Defects/Evidence/Fix/Acceptance 四段式——无缺陷且 acceptance 非空 → pass 可收敛;否则 fail 定向回灌(Defects→Fix→再 eval→pass 闭环,硬上限防死循环)。",
),
})
}