HEL-864: full-grammar whole-answer parsing for S6 affirmative verification - per manager independent review of 7aa9280: (1) affirms_promise_claim/affirms_promise_state rewritten as bounded-grammar full-parse (parse_supported_answer): the entire answer must be declarative (no question marks, no sentence-final 吗/呢/吧/嘛/呗) and EVERY clause must be fully consumed (fullmatch) as exactly one of P promise clause (subject? -> promise verb -> aspect 过/了? -> 周五(晚)? -> tell action -> receiver pronoun? -> correct object 面试结果, nothing further) / C closed-state clause / O open-state clause; whole answer needs >=1 P clause, state affirmation needs >=1 clause of required polarity and 0 of the opposite; (2) manager seven wrong-answer groups all now judged fail through the same real s6_result: foreign object without 结果 suffix (体检报告现在已经告诉我了), post-state object (现在已经告诉我了体检情况), bare-noun clause in earlier position (体检结果,现在已经告诉我了), whole-answer conflicting tail (但面试结果仍待告知), question mood (……吗?), conditional (如果你答应……), suffix denial (已经告诉我了是假的) - plus the same seven mirrored on the unresolved side; (3) EN equally verified with the same clause structure (old code failed even the EN positive with 'the interview result'; now 3 EN positives pass, 6 EN negatives fail); substring-assembly judges (clause_affirms_promise/clause_affirms_state/clause_foreign_object/_prefix_negated) removed - no per-sentence blacklists, no 报告/吗/假 forbidden words, no new model, no generic semantic engine
Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
co-authored by
multica-agent
parent
7aa928025b
commit
c65de003a1
+146
-165
@@ -51,9 +51,26 @@ HEL-863 动作极性与状态对象绑定(总管对 6859696 独立复核三组
|
||||
更远处出现不再凑数;
|
||||
- 状态绑定回同一目标声明:状态短语所在小句若提及正确对象之外的结果对象
|
||||
("体检结果现在已经告诉我了"),该状态断言属于别的对象,不能证明面试
|
||||
承诺已结/未结;裸回指"结果已收到"与"面试结果已经告诉我了"仍可证明;
|
||||
- 同样限定受支持表达的完整语法,不靠整句黑名单或逐句禁词;不能按该语法
|
||||
解析的额外对象/谓语/否定一律保守判失败。
|
||||
承诺已结/未结;裸回指"结果已收到"与"面试结果已经告诉我了"仍可证明。
|
||||
|
||||
HEL-864 完整受支持语法全量解析(总管对 7aa9280 独立复核七组反例+未结侧镜像):
|
||||
- 不再按"任一小句发现承诺词、另一小句发现状态词、再用'结果'字样排除
|
||||
异物"拼装肯定验证;affirms_promise_claim/affirms_promise_state 改为
|
||||
对整个回答做有界语法全量匹配(parse_supported_answer);
|
||||
- 预声明受支持结构与语气(固定合成语料领域,中英文同等结构):
|
||||
语气——全篇陈述语气(?/? 或句末 吗/呢/吧/嘛/呗 一律非陈述,保守失败);
|
||||
小句——每个小句必须被且仅被三类之一完整消费(fullmatch,条件前缀、
|
||||
额外对象、状态后置对象、尾随否认/残料均无法完整匹配 → 保守失败):
|
||||
P 承诺小句(主语?→承诺动词→体标记?→周五(晚)?→告知动作→接收者?→
|
||||
正确对象,到此为止)、C 已结状态小句、O 未结状态小句(词表见
|
||||
PROMISE_*/TELL_ACTION_* 预声明闭类);
|
||||
- 整篇 ≥1 个 P 小句才存在被肯定的承诺断言;状态肯定另要求 ≥1 个对应
|
||||
极性 C/O 小句且 0 个反向极性小句;跨小句只出现对象词、裸名词小句
|
||||
("体检结果")、全段冲突尾句("但面试结果仍待告知")、条件句
|
||||
("如果你答应……")、疑问("……吗?")、状态短语后否认("已经告诉
|
||||
我了是假的")均判失败;对侧状态短语与不确定表述整篇排除不变;
|
||||
- 不加七句黑名单、不补"报告/吗/假"禁词、不新增模型、不做通用语义
|
||||
引擎;只约束本实验判据,不限制产品表达。
|
||||
|
||||
对照设计(批准范围第5条):
|
||||
现状路径 = docs/reuse-hel847/probe_recall.py 的生产语义重放(总管已核对的 v2 基线,
|
||||
@@ -668,8 +685,9 @@ def has_any(text: str, terms_zh: list[str], terms_en: list[str]) -> bool:
|
||||
# 独立成函数以便离线负例直接代入错误模型答案验证判据本身。
|
||||
# S6 承诺状态判据词集(HEL-860:固定合成语料的预声明等价集,不冒充通用语义
|
||||
# 理解;离线先行证明,不靠真实请求调判据)。HEL-861 原混合词表(任一承诺词+
|
||||
# 状态词即过)拆分;HEL-862 起这些词表只作小句内状态短语词表,极性由
|
||||
# clause_affirms_state 按小句前缀否定结构判定。
|
||||
# 状态词即过)拆分;HEL-862/863 曾作小句内状态短语词表+前缀否定极性;HEL-864
|
||||
# 起肯定验证改为有界语法全量匹配(parse_supported_answer),这些词表继续用作
|
||||
# 对侧短语与不确定表述的整篇排除集(s6_result/未结块自洽)。
|
||||
PROMISE_CLOSED_ZH = ["已经告诉我", "已告诉我", "已经告知", "已告知", "已经说了",
|
||||
"结果已收到", "已收到", "收到了", "已经拿到", "拿到了",
|
||||
"已兑现", "已解决"]
|
||||
@@ -690,16 +708,14 @@ PROMISE_VERB_EN = ["promis", "pledge", "commit"]
|
||||
TELL_ACTION_ZH = ["告诉", "告知"]
|
||||
TELL_ACTION_EN = ["tell", "inform", "notify"]
|
||||
# HEL-863 告知动作后的接收者代词(封闭类):对象必须紧随告知动作(至多隔一个
|
||||
# 接收者代词),"告诉我面试结果"成立、"告诉我体检结果而面试结果是另一件事"
|
||||
# 的承诺对象错挂不成立。
|
||||
# 接收者代词),"告诉我面试结果"成立、"告诉我体检结果而面试结果是另一件事"
|
||||
# 的承诺对象错挂不成立。HEL-864 起该封闭类并入受支持语法的接收者槽。
|
||||
PROMISE_RECEIVER_ZH = ["我", "你", "他", "她", "它", "咱们", "我们", "你们",
|
||||
"他们", "她们", "它们"]
|
||||
PROMISE_RECEIVER_EN = ["me", "you", "us", "him", "her", "them"]
|
||||
# 否定语素(封闭语法类,非逐句黑名单):出现在承诺动词/状态短语之前的同小句
|
||||
# 前缀内,即该断言未被肯定——"未曾答应/从未答应/并未答应/并非已经告诉我"
|
||||
# 由结构拒绝,不靠不断枚举整句禁词。
|
||||
NEGATION_MORPHS_ZH = ["不", "没", "未", "非", "无", "别", "莫", "勿"]
|
||||
NEGATION_MORPHS_EN = ["not", "n't", "never", "no "]
|
||||
# HEL-864:否定语素不再作前缀扫描(原 _prefix_negated 随小句拼装判据一并移除)
|
||||
# ——有界语法 fullmatch 天然不含否定槽位,"未曾答应/答应不告诉/并非已经告诉
|
||||
# 我/还没有告诉我是假的"等否定形态因结构无法完整消费而保守失败。
|
||||
# 不确定/存疑模式(对承诺或状态的不知情、疑问、存疑)。
|
||||
PROMISE_UNCERTAIN_ZH = ["不知道", "不确定", "是否", "说不清", "记不清", "可能"]
|
||||
PROMISE_UNCERTAIN_EN = ["don't know", "do not know", "not sure", "unclear",
|
||||
@@ -731,151 +747,120 @@ def iter_clauses(text: str) -> list[str]:
|
||||
return clauses
|
||||
|
||||
|
||||
def _prefix_negated(clause: str, idx: int) -> bool:
|
||||
"""小句内位置 idx 之前的前缀是否含否定语素(未肯定极性,保守判定)。"""
|
||||
if idx < 0:
|
||||
return False
|
||||
prefix = clause[:idx]
|
||||
low = prefix.lower()
|
||||
return any(m in prefix for m in NEGATION_MORPHS_ZH) or any(
|
||||
m in low for m in NEGATION_MORPHS_EN)
|
||||
# ---------------------------------------------------------------------------
|
||||
# HEL-864 完整受支持语法(预声明,固定合成语料领域内的有界语法全量匹配)。
|
||||
# 肯定验证=全量解析:整个回答的每个小句必须被且仅被 P/C/O 三类结构完整消费
|
||||
# (fullmatch);语气必须为陈述;任何无法消费的额外小句、对象、谓语、条件、
|
||||
# 疑问、否认或冲突一律保守判失败(fail-closed)。词表均取上方预声明闭类。
|
||||
_ZH_PRONOUN_ALT = "|".join(PROMISE_RECEIVER_ZH)
|
||||
# P 承诺小句:主语?→承诺动词→体标记?→时间(周五晚/周五)?→告知动作→
|
||||
# 接收者代词?→正确对象(面试结果),小句到此为止(尾随残料即失败——
|
||||
# "告诉我体检结果""答应不告诉""如果/未曾答应"等均无法完整匹配)。
|
||||
_PROMISE_CLAUSE_ZH = re.compile(
|
||||
r"(?:你|我)?(?:答应|承诺|许诺)(?:过|了)?(?:周五晚|周五)?"
|
||||
rf"(?:告诉|告知)(?:{_ZH_PRONOUN_ALT})?面试结果")
|
||||
# C 已结状态小句:正确对象/裸回指?→现在?→已经/已?→告知动作→接收者?→了;
|
||||
# 或 正确对象/裸回指?→现在?→已经/已?→收到/拿到/兑现/解决→了?。
|
||||
# 主语槽只认 面试结果/裸"结果"——"体检报告现在已经告诉我了"(外来对象无
|
||||
# "结果"后缀)与"现在已经告诉我了体检情况"(状态后置对象)均无法匹配。
|
||||
_CLOSED_STATE_ZH = tuple(re.compile(p) for p in (
|
||||
rf"(?:面试结果|结果)?(?:现在)?(?:已经|已)?(?:告诉|告知)(?:我|你)?了",
|
||||
rf"(?:面试结果|结果)?(?:现在)?(?:已经|已)?(?:收到|拿到|兑现|解决)(?:了)?"))
|
||||
# O 未结状态小句:正确对象/裸回指?→现在?→主语我?→还没有/还没/尚未→
|
||||
# 告知/收到/拿到/兑现/说→接收者?。
|
||||
_OPEN_STATE_ZH = re.compile(
|
||||
rf"(?:面试结果|结果)?(?:现在)?(?:我)?(?:还没有|还没|尚未)"
|
||||
rf"(?:告诉|告知|收到|拿到|兑现|说)(?:我|你)?呢?")
|
||||
# EN 同等结构(大小写不敏感;句末允许 .!?;条件 if/unless 前缀与疑问天然
|
||||
# 无法完整匹配,另由语气检查整篇排除 ?/?)。
|
||||
_PROMISE_CLAUSE_EN = re.compile(
|
||||
r"(?:you|i|we)?\s*(?:promised|pledged|have promised|has promised|"
|
||||
r"committed to)\s*(?:to\s+)?(?:tell|inform|notify)\s*"
|
||||
r"(?:me|you|us|him|her|them)?\s*(?:about\s+)?(?:the\s+)?"
|
||||
r"(?:interview result|interview results|interview)"
|
||||
r"(?:\s*[.!?])?", re.IGNORECASE)
|
||||
_CLOSED_STATE_EN = tuple(re.compile(
|
||||
p + r"(?:\s*[.!?])?", re.IGNORECASE) for p in (
|
||||
r"(?:the interview result|the result|i|we|you)?\s*(?:have|has)?\s*"
|
||||
r"(?:already\s+)?(?:told|informed|notified)\s*(?:me|you|us|them)?\s*"
|
||||
r"(?:about\s+it|it|the interview result|interview result)?",
|
||||
r"(?:the interview result|the result|i|we)?\s*(?:have|has)?\s*"
|
||||
r"(?:already\s+)?(?:received|got)\s*"
|
||||
r"(?:the interview result|the result|it|the notification)?"))
|
||||
_OPEN_STATE_EN = re.compile(
|
||||
r"(?:you|i|we)?\s*(?:haven't|have not|hasn't|has not)\s*(?:yet\s*)?"
|
||||
r"(?:told|informed|notified|received|got)\s*"
|
||||
r"(?:me|you|us|them)?\s*"
|
||||
r"(?:it|the result|the interview result|the notification)?\s*(?:yet)?"
|
||||
r"(?:\s*[.!?])?", re.IGNORECASE)
|
||||
# 语气(封闭类,非逐句黑名单):问号或句末疑问/祈使语气词 → 非陈述语气。
|
||||
_QUESTION_MARK_CHARS = ("?", "?")
|
||||
_ZH_MOOD_PARTICLES = "吗呢吧嘛呗"
|
||||
|
||||
|
||||
# HEL-863 对象一致性(结构类,非逐句黑名单):正确对象是"面试结果";同一小句
|
||||
# 内出现其他"…结果"对象提及(如体检结果),该小句的断言(承诺或状态)就绑定
|
||||
# 在别的对象上,不能用来证明面试承诺的任何一部分。裸"结果"(回指,无修饰前
|
||||
# 缀)与"面试结果"本身不算外来对象。
|
||||
_FOREIGN_OBJECT_ZH = "结果"
|
||||
_FOREIGN_OBJECT_EN = "result"
|
||||
_CORRECT_OBJECT_ZH = PROMISE_OBJECT_ZH[0] # 面试结果
|
||||
_CORRECT_OBJECT_EN = "interview result"
|
||||
def _clause_kind(clause: str) -> str | None:
|
||||
"""小句被哪类受支持结构完整消费:'promise'/'closed'/'open',否则 None。"""
|
||||
if _PROMISE_CLAUSE_ZH.fullmatch(clause) or _PROMISE_CLAUSE_EN.fullmatch(clause):
|
||||
return "promise"
|
||||
if any(r.fullmatch(clause) for r in _CLOSED_STATE_ZH) or any(
|
||||
r.fullmatch(clause) for r in _CLOSED_STATE_EN):
|
||||
return "closed"
|
||||
if _OPEN_STATE_ZH.fullmatch(clause) or _OPEN_STATE_EN.fullmatch(clause):
|
||||
return "open"
|
||||
return None
|
||||
|
||||
|
||||
def clause_foreign_object(clause: str) -> bool:
|
||||
"""小句是否提及正确对象之外的结果对象(体检结果等"…结果"形态提及)。"""
|
||||
for m in re.finditer(_FOREIGN_OBJECT_ZH, clause):
|
||||
k = m.start()
|
||||
if k >= len(_CORRECT_OBJECT_ZH) - len(_FOREIGN_OBJECT_ZH) and (
|
||||
clause[k - (len(_CORRECT_OBJECT_ZH) - len(_FOREIGN_OBJECT_ZH)):
|
||||
k + len(_FOREIGN_OBJECT_ZH)] == _CORRECT_OBJECT_ZH):
|
||||
continue
|
||||
if k == 0: # 裸回指"结果"(句首、无修饰前缀)
|
||||
continue
|
||||
return True
|
||||
low = clause.lower()
|
||||
_off_en = len(_CORRECT_OBJECT_EN) - len(_FOREIGN_OBJECT_EN)
|
||||
for m in re.finditer(_FOREIGN_OBJECT_EN, low):
|
||||
k = m.start()
|
||||
if k >= _off_en and low[k - _off_en:
|
||||
k + len(_FOREIGN_OBJECT_EN)] == _CORRECT_OBJECT_EN:
|
||||
continue
|
||||
if k == 0:
|
||||
continue
|
||||
return True
|
||||
return False
|
||||
def parse_supported_answer(text: str) -> dict:
|
||||
"""HEL-864 全量解析:整个回答按预声明受支持结构与语气逐小句绑定。
|
||||
|
||||
|
||||
def clause_affirms_promise(clause: str) -> bool:
|
||||
"""单小句内肯定承诺断言(HEL-863 完整受支持语法,一次核对对象与两种动作
|
||||
极性):
|
||||
|
||||
承诺动词(前缀无否定语素)→ 告知动作(承诺动词至告知动作的间隔内无否定
|
||||
语素,即告知动作同样被肯定)→ 可选接收者代词 → 正确对象(面试结果)紧随
|
||||
其后;且该小句不提及其他"…结果"对象。"答应周五晚不告诉我面试结果"是否定
|
||||
告知(另一种承诺,非承诺告知),"告诉我体检结果而面试结果是另一件事"承诺
|
||||
对象错挂,均不能证明"承诺告知面试结果"这一项声明。
|
||||
返回 clauses/declarative/all_consumed/has_promise/closed_clauses/
|
||||
open_clauses/unparsed——肯定验证(affirms_*)与审计复现共用同一解析,
|
||||
不再按子串存在+否定词排除拼装。
|
||||
"""
|
||||
if clause_foreign_object(clause):
|
||||
return False
|
||||
for verb in PROMISE_VERB_ZH:
|
||||
start = 0
|
||||
while (i := clause.find(verb, start)) >= 0:
|
||||
if not _prefix_negated(clause, i):
|
||||
after_verb = clause[i + len(verb):]
|
||||
for tell in TELL_ACTION_ZH:
|
||||
t = 0
|
||||
while (j := after_verb.find(tell, t)) >= 0:
|
||||
if not _prefix_negated(after_verb, j):
|
||||
after_tell = after_verb[j + len(tell):].lstrip()
|
||||
for recv in PROMISE_RECEIVER_ZH:
|
||||
if after_tell.startswith(recv):
|
||||
after_tell = after_tell[len(recv):].lstrip()
|
||||
break
|
||||
if any(after_tell.startswith(obj)
|
||||
for obj in PROMISE_OBJECT_ZH):
|
||||
return True
|
||||
t = j + 1
|
||||
start = i + 1
|
||||
low = clause.lower()
|
||||
for verb in PROMISE_VERB_EN:
|
||||
start = 0
|
||||
while (i := low.find(verb, start)) >= 0:
|
||||
if not _prefix_negated(low, i):
|
||||
after_verb = low[i + len(verb):]
|
||||
for tell in TELL_ACTION_EN:
|
||||
t = 0
|
||||
while (j := after_verb.find(tell + " ", t)) >= 0:
|
||||
if not _prefix_negated(after_verb, j):
|
||||
after_tell = after_verb[j + len(tell):].lstrip()
|
||||
for recv in PROMISE_RECEIVER_EN:
|
||||
if after_tell.startswith(recv):
|
||||
after_tell = after_tell[len(recv):].lstrip()
|
||||
break
|
||||
for obj in PROMISE_OBJECT_EN:
|
||||
if after_tell.startswith(obj):
|
||||
return True
|
||||
t = j + 1
|
||||
start = i + 1
|
||||
return False
|
||||
|
||||
|
||||
def clause_affirms_state(clause: str, closed: bool) -> bool:
|
||||
"""单小句内肯定已结/未结状态且绑定回正确对象(HEL-863):
|
||||
|
||||
状态短语(预声明等价集)前缀无否定语素;且该小句不提及其他"…结果"对象
|
||||
——"体检结果现在已经告诉我了"的状态断言属于体检结果,不能证明面试承诺
|
||||
已结;裸回指"结果已收到"与"面试结果已经告诉我了"绑定正确对象可证明。
|
||||
"但并非已经告诉我"含已结短语但前缀被否定 → 未肯定;"还没有告诉我"/
|
||||
"尚未收到"是未结短语的肯定形态(短语本身表达未结,非否定已结)。
|
||||
"""
|
||||
if clause_foreign_object(clause):
|
||||
return False
|
||||
terms_zh = PROMISE_CLOSED_ZH if closed else PROMISE_OPEN_ZH
|
||||
terms_en = PROMISE_CLOSED_EN if closed else PROMISE_OPEN_EN
|
||||
low = clause.lower()
|
||||
for t in terms_zh:
|
||||
start = 0
|
||||
while (i := clause.find(t, start)) >= 0:
|
||||
if not _prefix_negated(clause, i):
|
||||
return True
|
||||
start = i + 1
|
||||
for t in terms_en:
|
||||
start = 0
|
||||
while (i := low.find(t, start)) >= 0:
|
||||
if not _prefix_negated(clause, i):
|
||||
return True
|
||||
start = i + 1
|
||||
return False
|
||||
raw = text or ""
|
||||
clauses = iter_clauses(raw)
|
||||
kinds = [(c, _clause_kind(c)) for c in clauses]
|
||||
unparsed = [c for c, k in kinds if k is None]
|
||||
declarative = (
|
||||
not any(ch in raw for ch in _QUESTION_MARK_CHARS)
|
||||
and not any(c and c[-1] in _ZH_MOOD_PARTICLES for c in clauses))
|
||||
return {
|
||||
"clauses": [{"text": c, "kind": k} for c, k in kinds],
|
||||
"declarative": declarative,
|
||||
"all_consumed": bool(clauses) and not unparsed,
|
||||
"has_promise": any(k == "promise" for _, k in kinds),
|
||||
"closed_clauses": [c for c, k in kinds if k == "closed"],
|
||||
"open_clauses": [c for c, k in kinds if k == "open"],
|
||||
"unparsed": unparsed,
|
||||
}
|
||||
|
||||
|
||||
def affirms_promise_state(text: str, *, closed: bool) -> bool:
|
||||
"""肯定陈述已结/未结状态:任一小句内状态短语被肯定(前缀无否定)。"""
|
||||
return any(clause_affirms_state(c, closed) for c in iter_clauses(text))
|
||||
"""肯定陈述已结/未结状态并绑回同一项承诺声明(HEL-864 全量解析):
|
||||
全篇陈述语气 AND 每个小句都被受支持结构完整消费 AND ≥1 承诺小句 AND
|
||||
≥1 对应极性状态小句 AND 0 个反向极性小句 AND 无不确定表述。状态短语
|
||||
属于别的对象(体检报告/体检情况)、裸名词小句、全段冲突尾句、条件句、
|
||||
疑问语气、状态后否认均无法消费 → 保守判失败。
|
||||
"""
|
||||
p = parse_supported_answer(text)
|
||||
wanted = p["closed_clauses"] if closed else p["open_clauses"]
|
||||
opposite = p["open_clauses"] if closed else p["closed_clauses"]
|
||||
return bool(p["declarative"] and p["all_consumed"] and p["has_promise"]
|
||||
and wanted and not opposite
|
||||
and not has_any(text, PROMISE_UNCERTAIN_ZH, PROMISE_UNCERTAIN_EN))
|
||||
|
||||
|
||||
def affirms_promise_claim(text: str) -> bool:
|
||||
"""肯定陈述固定语料中的承诺(HEL-862/863 小句结构化判据):
|
||||
|
||||
存在单一小句按"承诺动词(前缀无否定语素)→ 告知动作(间隔内无否定语素,
|
||||
告知动作同样被肯定)→ 可选接收者代词 → 正确对象(面试结果)紧随其后"
|
||||
绑定,小句内无其他"…结果"对象提及,且全文无不确定表述。对象词与动作词
|
||||
分处不同小句各出现一次不再凑数;承诺动词被否定(未曾答应/没有答应过)、
|
||||
告知动作被否定(答应不告诉)、对象错挂(告诉我体检结果而面试结果是另一
|
||||
件事)、仅陈述告知结果而无承诺断言(面试结果已经告诉我了)、答错对象
|
||||
(体检结果)均判 False;无法按受支持表达证明即保守判失败,不靠枚举整句
|
||||
禁词冒充肯定验证。
|
||||
"""肯定陈述固定语料中的承诺(HEL-864 全量解析):
|
||||
全篇陈述语气 AND 每个小句都被受支持结构完整消费 AND ≥1 承诺小句 AND
|
||||
无不确定表述。承诺动词被否定(未曾答应)、告知动作被否定(答应不告诉)、
|
||||
对象错挂(体检结果/状态后置对象)、条件句(如果你答应)、跨小句各出现
|
||||
一个词凑数、仅陈述告知结果而无承诺断言(面试结果已经告诉我了)均判
|
||||
False;无法按受支持表达完整解析即保守判失败,不靠枚举整句禁词或
|
||||
七句黑名单冒充肯定验证。
|
||||
"""
|
||||
return bool(any(clause_affirms_promise(c) for c in iter_clauses(text))
|
||||
p = parse_supported_answer(text)
|
||||
return bool(p["declarative"] and p["all_consumed"] and p["has_promise"]
|
||||
and not has_any(text, PROMISE_UNCERTAIN_ZH, PROMISE_UNCERTAIN_EN))
|
||||
# 未结对照块自洽:与"未结"状态矛盾的结果类条目(已通过/已收到通知)须剔除
|
||||
RESULT_RECEIVED_ZH = ["面试过了", "通过了", "拿到通知", "拿到了通知", "已收到",
|
||||
@@ -977,18 +962,15 @@ def s3_result(*, b_hits3: list, b_hits3b: list, m_hits3: list, m_hits3b: list,
|
||||
|
||||
|
||||
def s6_result(orch: dict, a_resolved: dict, a_unresolved: dict) -> dict:
|
||||
"""S6 判据(HEL-863:小句结构化绑定承诺对象/两种动作极性/状态与目标声明):
|
||||
"""S6 判据(HEL-864:有界语法全量解析绑定承诺对象/动作极性/状态/语气):
|
||||
编排层(已知id置 resolved 留痕 + 未结对照块自洽)+ 状态进上下文层(正确对象
|
||||
的 resolved 状态实际写入带门装配块)+ 模型使用层(两侧请求成功;已结侧必须
|
||||
在单一小句内按"承诺动词(前缀无否定)→告知动作(间隔内无否定)→(可选
|
||||
接收者)→面试结果紧随其后"肯定陈述同一项承诺,小句内无其他"…结果"对象,
|
||||
且状态短语(已经告诉我等)所在小句前缀无否定语素、同样不提及其他"…结果"
|
||||
对象并肯定为已告知;未结侧同一绑定且肯定为尚未告知——对象与动作分处不同
|
||||
小句各出现一次(体检承诺+面试另一件事)、告知动作被否定(答应不告诉)、
|
||||
状态属于别的对象(体检结果已经告诉我了)、承诺被否定(未曾答应)、状态被
|
||||
否定(并非已经告诉我)、仅陈述告知而无承诺断言(面试结果已经告诉我了)、
|
||||
"不知道是否"、两侧同答不区分状态、已结侧答未结、未结侧同义宣称已收到均判
|
||||
失败,不以字面提到'告诉/答应'冒充状态正确;无法按受支持表达证明即保守判
|
||||
的 resolved 状态实际写入带门装配块)+ 模型使用层(两侧请求成功;两侧回答
|
||||
均须全篇陈述语气且每个小句被受支持结构完整消费——承诺小句"主语?→承诺动词
|
||||
(未被否定)→告知动作(未被否定)→(可选接收者)→面试结果到此为止"+
|
||||
对应极性状态小句(已结/未结);外来对象(含无"结果"后缀)、状态后置对象、
|
||||
裸名词小句、全段冲突尾句、条件句、疑问语气、状态短语后否认、对象与动作
|
||||
串错、仅陈述告知而无承诺断言、不确定表述、两侧同答不区分状态均判失败,
|
||||
不以字面提到'告诉/答应'冒充状态正确;无法按受支持表达完整解析即保守判
|
||||
失败)。"""
|
||||
ans_r = (a_resolved or {}).get("answer") or ""
|
||||
ans_u = (a_unresolved or {}).get("answer") or ""
|
||||
@@ -1028,16 +1010,15 @@ def s6_result(orch: dict, a_resolved: dict, a_unresolved: dict) -> dict:
|
||||
and model_use["unresolved_no_false_resolution"])
|
||||
return {"layers": layers, "pass": ok,
|
||||
"expect": "已知id编排置 resolved 留痕且未结对照块剔除矛盾条目后自洽;"
|
||||
"正确对象的状态实际写入带门装配块;模型沿状态区分且必须"
|
||||
"肯定验证同一项声明:已结侧单一小句内'承诺动词(未被否定)→"
|
||||
"告知动作(间隔内无否定、同样被肯定)→(可选接收者)→面试"
|
||||
"结果紧随其后'绑定成立,小句内无其他'…结果'对象,已结状态"
|
||||
"短语所在小句前缀无否定、不提及其他'…结果'对象并肯定为已"
|
||||
"告知;未结侧同一绑定且肯定为尚未告知;对象与动作串错/答应"
|
||||
"不告诉/状态属于体检结果等其他对象/未曾答应/并非已经告诉我/"
|
||||
"仅陈述告知无承诺/不知道/是否/两侧同答/已结侧答未结/未结侧"
|
||||
"宣称已收到均判失败(无法按受支持表达证明即保守判失败,不以"
|
||||
"字面提到'告诉/答应'冒充)"}
|
||||
"正确对象的状态实际写入带门装配块;模型沿状态区分且两侧"
|
||||
"回答均须按预声明受支持语法全量解析:全篇陈述语气(无问号"
|
||||
"/句末吗呢吧嘛呗)、每个小句被承诺小句(主语?→承诺动词→"
|
||||
"告知动作→(可选接收者)→面试结果到此为止)或对应极性状态"
|
||||
"小句完整消费、整篇含承诺断言——外来对象(含无'结果'后缀)、"
|
||||
"状态后置对象、裸名词小句、全段冲突尾句、条件句、疑问、状态"
|
||||
"短语后否认、对象与动作串错、仅陈述告知无承诺、不确定表述、"
|
||||
"两侧同答、已结侧答未结、未结侧宣称已收到均判失败(无法完整"
|
||||
"解析即保守判失败,不以字面提到'告诉/答应'冒充)"}
|
||||
|
||||
|
||||
# HEL-860:无门 assemble_block 出口已删除——全部问答最终装配一律经
|
||||
|
||||
@@ -0,0 +1,359 @@
|
||||
#!/usr/bin/env python3
|
||||
"""HEL-864 负例复现脚本:总管独立复核《HEL-863-独立复核.md》七组反例+未结侧镜像。
|
||||
|
||||
零真实模型、零网络(socket 硬拒绝 + HF 离线)、零本地嵌入:S6 判据为纯函数
|
||||
代入(真实 s6_result 构造器同一入口);既有判据不回归部分直接复用 audit861
|
||||
的两组纯函数节(S6 全套正负例 + S2/S3 总判据)、audit862 的四组复核用例与
|
||||
audit863 的三组复核用例(后两组在起点 7aa9280 已判失败,预期极性固定为不
|
||||
回归)。同一脚本在修复前(7aa9280)与修复后代码上均可运行:
|
||||
|
||||
修复前(--phase prefix,在 7aa9280 工作树上运行)→ 七组反例与七组未结侧
|
||||
镜像全部 pass=true(复现),其余用例维持既有预期极性;英文为本轮新声明
|
||||
支持,prefix 期仅记录实际值、不参与退出码
|
||||
修复后(默认 postfix)→ 同一真实 s6_result 七组+镜像全部判失败;正确
|
||||
正例(含 audit860/rework 形态)、HEL-862 四组、HEL-863 三组、audit861
|
||||
既有正负例与 S2/S3 总判据维持预期;英文同等验证(正例过、反例败)
|
||||
|
||||
补正口径(固定合成语料领域内的有界语法全量匹配,预声明受支持结构与语气):
|
||||
整个回答必须为陈述语气且每个小句被且仅被三类结构完整消费——P 承诺小句
|
||||
(主语?→承诺动词→体标记?→周五(晚)?→告知动作→接收者?→正确对象,到此为止)、
|
||||
C 已结状态小句、O 未结状态小句;整篇 ≥1 个 P;状态肯定另要求 ≥1 对应极性
|
||||
C/O 且 0 个反向极性小句。外来对象(含无"结果"后缀,如体检报告/体检情况)、
|
||||
状态后置对象、裸名词小句(体检结果)、全段冲突尾句(但面试结果仍待告知)、
|
||||
条件句(如果你答应)、疑问语气(……吗?)、状态短语后否认(已经告诉我了是
|
||||
假的)一律保守判失败;已结侧与未结侧镜像输入同判。不加七句黑名单、不补
|
||||
"报告/吗/假"禁词、不新增模型、不做通用语义引擎;中英文同等结构验证。
|
||||
|
||||
退出码真实依赖正负例:除全部用例满足预期外,还对每个用例做翻转自检
|
||||
(flip 任一用例的实际结果,用例总判必翻转);任一翻转不改变结论则退出 1。
|
||||
|
||||
用法:python -m spike.hel857.audit864 [--phase prefix|postfix] [输出json路径]
|
||||
退出码:prefix=0 当且仅当七组反例与七组镜像全部复现(pass=true)且其余用例
|
||||
维持预期;postfix=0 当且仅当七组+镜像全部判失败、正例保留、英文同等验证、
|
||||
既有判据不回归、权威账与既有证据只读未动、翻转自检全部通过。权威嵌入账
|
||||
只读快照核对(不补种不回退不双扣)。
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import socket
|
||||
import sqlite3
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
REPO = Path(__file__).resolve().parents[2]
|
||||
LEDGER = Path("/home/xiaomo/multica_workspaces/hello-af23464d222e/"
|
||||
"hel-859-1f079e50f551/workdir/audit-data/embed_ledger.sqlite3")
|
||||
os.environ["HEL857_EMBED_LEDGER"] = str(LEDGER)
|
||||
os.environ.setdefault("HF_HUB_OFFLINE", "1")
|
||||
os.environ.setdefault("TRANSFORMERS_OFFLINE", "1")
|
||||
|
||||
|
||||
def deny_network(*a, **k):
|
||||
raise RuntimeError("audit864 blocks network")
|
||||
|
||||
|
||||
socket.socket.connect = deny_network
|
||||
socket.socket.connect_ex = deny_network
|
||||
|
||||
from . import ab_scenarios as A
|
||||
from .audit861 import section_s2_s3_no_regression, section_s6_affirmative
|
||||
from .audit862 import (HELD_S2S3_EXPECT, HELD_S6_EXPECT, ORCH6,
|
||||
REVIEW_CASES, REVIEW_NEGATIVE_NAMES)
|
||||
from .audit863 import ADDITIONAL_CASES
|
||||
|
||||
OUT = {"real_network_allowed": False, "real_model_requests": 0,
|
||||
"local_embeddings": 0}
|
||||
PHASE = "postfix"
|
||||
|
||||
|
||||
def ledger_snapshot():
|
||||
with sqlite3.connect(f"file:{LEDGER}?mode=ro", uri=True) as c:
|
||||
return {"counts": dict(c.execute("select kind,sum(items) from embed_ops "
|
||||
"group by kind")),
|
||||
"rows": c.execute("select count(*) from embed_ops").fetchone()[0]}
|
||||
|
||||
|
||||
PRESERVED_EVIDENCE = [
|
||||
"ab_scenarios_run1.json", "ab_scenarios.json", "rework858_offline.json",
|
||||
"rework859_offline.json", "rework860_offline.json", "audit859_prefix.json",
|
||||
"audit859_postfix.json", "audit859_reuse860.json", "audit860_prefix.json",
|
||||
"audit860_postfix.json", "audit861_prefix.json", "audit861_postfix.json",
|
||||
"audit861_reuse862.json", "audit862_prefix.json", "audit862_postfix.json",
|
||||
"audit861_reuse863.json", "audit863_prefix.json", "audit863_postfix.json"]
|
||||
|
||||
|
||||
def evidence_hashes():
|
||||
res = {}
|
||||
for name in PRESERVED_EVIDENCE:
|
||||
p = REPO / "spike/hel857/results" / name
|
||||
res[name] = (hashlib.sha256(p.read_bytes()).hexdigest()
|
||||
if p.exists() else "missing")
|
||||
return res
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 总管《HEL-863-独立复核.md》七组反例(已结侧原文逐字)+ 未结侧镜像(同一缺口
|
||||
# 在 unresolved 侧的形态)。两侧均经同一真实 s6_result 入口,对侧用正确答案。
|
||||
def s6_answer(s):
|
||||
return {"answer": s, "ok": True}
|
||||
|
||||
|
||||
GOOD_CLOSED = "你答应周五晚告诉我面试结果,现在已经告诉我了。"
|
||||
GOOD_OPEN = "你答应周五晚告诉我面试结果,还没有告诉我。"
|
||||
P = "你答应周五晚告诉我面试结果,"
|
||||
SEVEN_CLOSED = {
|
||||
"foreign_object_without_result_suffix":
|
||||
P + "体检报告现在已经告诉我了。",
|
||||
"foreign_object_after_state":
|
||||
P + "现在已经告诉我了体检情况。",
|
||||
"foreign_object_in_previous_clause":
|
||||
P + "体检结果,现在已经告诉我了。",
|
||||
"conflicting_target_state":
|
||||
P + "现在已经告诉我了,但面试结果仍待告知。",
|
||||
"question_not_assertion":
|
||||
P + "现在已经告诉我了吗?",
|
||||
"conditional_not_promise":
|
||||
"如果你答应周五晚告诉我面试结果,现在已经告诉我了。",
|
||||
"suffix_denies_state":
|
||||
P + "已经告诉我了是假的。",
|
||||
}
|
||||
SEVEN_OPEN_MIRROR = {
|
||||
"open_foreign_object_without_result_suffix":
|
||||
P + "体检报告还没有告诉我。",
|
||||
"open_foreign_object_after_state":
|
||||
P + "还没有告诉我体检情况。",
|
||||
"open_foreign_object_in_previous_clause":
|
||||
P + "体检结果,还没有告诉我。",
|
||||
"open_conflicting_target_state":
|
||||
P + "还没有告诉我,但面试结果仍待告知。",
|
||||
"open_question_not_assertion":
|
||||
P + "还没有告诉我吗?",
|
||||
"open_conditional_not_promise":
|
||||
"如果你答应周五晚告诉我面试结果,还没有告诉我。",
|
||||
"open_suffix_denies_state":
|
||||
P + "还没有告诉我是假的。",
|
||||
}
|
||||
SEVEN_NAMES = tuple(SEVEN_CLOSED.keys())
|
||||
MIRROR_NAMES = tuple(SEVEN_OPEN_MIRROR.keys())
|
||||
|
||||
# 英文同等验证(本轮声明支持即同等结构核验:正例必须过、反例必须败)。
|
||||
# 值为 (已结侧回答, 未结侧回答)。
|
||||
EN_POSITIVE = {
|
||||
"en_positive_resolved": (
|
||||
"You promised to tell me the interview result, "
|
||||
"and you have already told me.", GOOD_OPEN),
|
||||
"en_positive_open": (
|
||||
GOOD_CLOSED, "You promised to tell me the interview result, "
|
||||
"but you haven't told me yet."),
|
||||
"en_positive_open_not_received": (
|
||||
GOOD_CLOSED, "You promised to tell me the interview result, "
|
||||
"you haven't received it yet."),
|
||||
}
|
||||
EN_NEGATIVE = {
|
||||
"en_conditional_not_promise": (
|
||||
"If you promised to tell me the interview result, "
|
||||
"you have already told me.", GOOD_OPEN),
|
||||
"en_question_not_assertion": (
|
||||
"You promised to tell me the interview result, "
|
||||
"have you already told me?", GOOD_OPEN),
|
||||
"en_foreign_object_suffix": (
|
||||
"You promised to tell me the interview result, and you have "
|
||||
"already told me the medical check result.", GOOD_OPEN),
|
||||
"en_negated_promise": (
|
||||
"You never promised to tell me the interview result, "
|
||||
"and you have already told me.", GOOD_OPEN),
|
||||
"en_open_mirror_question": (
|
||||
GOOD_CLOSED, "You promised to tell me the interview result, "
|
||||
"haven't you told me yet?"),
|
||||
"en_open_mirror_conditional": (
|
||||
GOOD_CLOSED, "If you promised to tell me the interview result, "
|
||||
"you haven't told me yet."),
|
||||
}
|
||||
|
||||
|
||||
def _record(name: str, resolved: str, unresolved: str, expected: bool) -> dict:
|
||||
result = A.s6_result(ORCH6, s6_answer(resolved), s6_answer(unresolved))
|
||||
mu = result["layers"]["model_use"]
|
||||
return {
|
||||
"resolved_input": resolved, "unresolved_input": unresolved,
|
||||
"expected_pass": expected, "actual_pass": result["pass"],
|
||||
"layers": {
|
||||
"resolved_states_promise": mu["resolved_states_promise"],
|
||||
"resolved_affirms_closed": mu["resolved_affirms_closed"],
|
||||
"unresolved_states_promise": mu["unresolved_states_promise"],
|
||||
"unresolved_affirms_open": mu["unresolved_affirms_open"]},
|
||||
"result": result,
|
||||
}
|
||||
|
||||
|
||||
def section_seven_and_mirror() -> dict:
|
||||
"""七组反例+未结侧镜像:prefix 期预期 pass=true(复现),postfix 判失败。"""
|
||||
out = {}
|
||||
for name, closed in SEVEN_CLOSED.items():
|
||||
out[name] = _record(name, closed, GOOD_OPEN, PHASE == "prefix")
|
||||
for name, opened in SEVEN_OPEN_MIRROR.items():
|
||||
out[name] = _record(name, GOOD_CLOSED, opened, PHASE == "prefix")
|
||||
return out
|
||||
|
||||
|
||||
def section_held_previous() -> dict:
|
||||
"""HEL-862 四组与 HEL-863 三组:起点 7aa9280 已按预期判失败,极性固定。"""
|
||||
out = {}
|
||||
for name, (closed, opened) in REVIEW_CASES.items():
|
||||
out[f"review.{name}"] = _record(
|
||||
name, closed, opened, name not in REVIEW_NEGATIVE_NAMES)
|
||||
for name, closed in ADDITIONAL_CASES.items():
|
||||
out[f"additional.{name}"] = _record(name, closed,
|
||||
"你答应周五晚告诉我面试结果,还没有告诉我。", False)
|
||||
return out
|
||||
|
||||
|
||||
def section_english_cases() -> dict:
|
||||
"""英文同等验证:postfix 期参与退出码(正例过、反例败),prefix 期仅记录。"""
|
||||
out = {}
|
||||
for name, (resolved, unresolved) in EN_POSITIVE.items():
|
||||
out[name] = _record(name, resolved, unresolved, True)
|
||||
for name, (resolved, unresolved) in EN_NEGATIVE.items():
|
||||
out[name] = _record(name, resolved, unresolved, False)
|
||||
return out
|
||||
|
||||
|
||||
def _case_table(seven_mirror: dict, english: dict, held_prev: dict,
|
||||
held_s6: dict, held_s2s3: dict) -> dict:
|
||||
"""全部用例的实际 pass 与预期极性(退出码公式输入;英文仅 postfix 参与)。"""
|
||||
table: dict[str, bool] = {}
|
||||
expect: dict[str, bool] = {}
|
||||
for name, c in seven_mirror.items():
|
||||
key = f"seven_mirror.{name}"
|
||||
table[key] = bool(c["actual_pass"])
|
||||
expect[key] = bool(c["expected_pass"])
|
||||
if PHASE == "postfix":
|
||||
for name, c in english.items():
|
||||
key = f"english.{name}"
|
||||
table[key] = bool(c["actual_pass"])
|
||||
expect[key] = bool(c["expected_pass"])
|
||||
for name, c in held_prev.items():
|
||||
table[name] = bool(c["actual_pass"])
|
||||
expect[name] = bool(c["expected_pass"])
|
||||
for name, res in held_s6.items():
|
||||
key = f"held_s6.{name}"
|
||||
table[key] = bool(res["pass"])
|
||||
expect[key] = HELD_S6_EXPECT[name]
|
||||
for name, res in held_s2s3.items():
|
||||
key = f"held_s2s3.{name}"
|
||||
table[key] = bool(res["pass"])
|
||||
expect[key] = HELD_S2S3_EXPECT[name]
|
||||
return table, expect
|
||||
|
||||
|
||||
def _all_cases_match(table: dict, expect: dict) -> bool:
|
||||
return all(table[k] == expect[k] for k in expect)
|
||||
|
||||
|
||||
def _flip_dependence(table: dict, expect: dict) -> dict:
|
||||
"""翻转自检:任一用例实际值翻转必须改变用例总判(退出码真实依赖正负例)。"""
|
||||
base = _all_cases_match(table, expect)
|
||||
flips = {}
|
||||
for k in expect:
|
||||
flipped = dict(table)
|
||||
flipped[k] = not flipped[k]
|
||||
flips[k] = _all_cases_match(flipped, expect) != base
|
||||
return {"base_all_match": base, "every_flip_changes_verdict": all(
|
||||
flips.values()), "per_case": flips}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
def main(argv: list[str]) -> dict:
|
||||
global PHASE
|
||||
argv = list(argv)
|
||||
rest: list[str] = []
|
||||
PHASE = "postfix"
|
||||
it = iter(argv[1:])
|
||||
for tok in it:
|
||||
if tok == "--phase":
|
||||
PHASE = next(it, "postfix")
|
||||
elif tok.startswith("--phase="):
|
||||
PHASE = tok.split("=", 1)[1]
|
||||
elif not tok.startswith("--"):
|
||||
rest.append(tok)
|
||||
args = rest
|
||||
OUT["phase"] = PHASE
|
||||
|
||||
commit = subprocess.run(["git", "rev-parse", "--short", "HEAD"],
|
||||
capture_output=True, text=True,
|
||||
cwd=str(REPO)).stdout.strip()
|
||||
OUT["commit"] = commit
|
||||
OUT["ledger_before"] = ledger_snapshot()
|
||||
OUT["preserved_evidence_before"] = evidence_hashes()
|
||||
|
||||
OUT["seven_and_mirror"] = section_seven_and_mirror()
|
||||
OUT["english_cases"] = section_english_cases()
|
||||
OUT["held_previous_rounds"] = section_held_previous()
|
||||
held_s6 = section_s6_affirmative()
|
||||
held_s2s3 = section_s2_s3_no_regression()
|
||||
OUT["held_s6_affirmative"] = held_s6
|
||||
OUT["held_s2_s3_no_regression"] = held_s2s3
|
||||
|
||||
table, expect = _case_table(OUT["seven_and_mirror"], OUT["english_cases"],
|
||||
OUT["held_previous_rounds"], held_s6, held_s2s3)
|
||||
OUT["case_expect"] = {k: bool(v) for k, v in expect.items()}
|
||||
OUT["case_actual"] = {k: bool(v) for k, v in table.items()}
|
||||
OUT["all_cases_match_expectation"] = _all_cases_match(table, expect)
|
||||
OUT["flip_dependence"] = _flip_dependence(table, expect)
|
||||
|
||||
OUT["ledger_after"] = ledger_snapshot()
|
||||
OUT["ledger_unchanged"] = OUT["ledger_before"] == OUT["ledger_after"]
|
||||
OUT["preserved_evidence_after"] = evidence_hashes()
|
||||
OUT["preserved_evidence_unchanged"] = (
|
||||
OUT["preserved_evidence_before"] == OUT["preserved_evidence_after"])
|
||||
|
||||
sm = OUT["seven_and_mirror"]
|
||||
# ---- prefix:七组反例与七组镜像全部复现(pass=true)----
|
||||
fourteen_reproduced = (all(sm[n]["actual_pass"] for n in SEVEN_NAMES)
|
||||
and all(sm[n]["actual_pass"] for n in MIRROR_NAMES))
|
||||
# ---- postfix:七组+镜像全部判失败 ----
|
||||
fourteen_rejected = (not any(sm[n]["actual_pass"] for n in SEVEN_NAMES)
|
||||
and not any(sm[n]["actual_pass"] for n in MIRROR_NAMES))
|
||||
# ---- postfix:英文同等验证(正例过、反例败)----
|
||||
english_ok = all(c["actual_pass"] == c["expected_pass"]
|
||||
for c in OUT["english_cases"].values())
|
||||
OUT["summary"] = {
|
||||
"phase": PHASE,
|
||||
"fourteen_reproduced": fourteen_reproduced,
|
||||
"fourteen_rejected": fourteen_rejected,
|
||||
"english_equal_verification_pass": english_ok if PHASE == "postfix"
|
||||
else None,
|
||||
"all_cases_match_expectation": OUT["all_cases_match_expectation"],
|
||||
"flip_dependence_holds": OUT["flip_dependence"][
|
||||
"every_flip_changes_verdict"],
|
||||
"ledger_unchanged": OUT["ledger_unchanged"],
|
||||
"preserved_evidence_unchanged": OUT["preserved_evidence_unchanged"],
|
||||
"pass": (fourteen_reproduced and PHASE == "prefix"
|
||||
and OUT["all_cases_match_expectation"]
|
||||
and OUT["flip_dependence"]["every_flip_changes_verdict"]
|
||||
and OUT["ledger_unchanged"]
|
||||
and OUT["preserved_evidence_unchanged"])
|
||||
or (fourteen_rejected and PHASE == "postfix"
|
||||
and english_ok
|
||||
and OUT["all_cases_match_expectation"]
|
||||
and OUT["flip_dependence"]["every_flip_changes_verdict"]
|
||||
and OUT["ledger_unchanged"]
|
||||
and OUT["preserved_evidence_unchanged"]),
|
||||
}
|
||||
out_path = Path(args[0]) if args else (
|
||||
REPO / "spike/hel857/results/"
|
||||
f"audit864_{'prefix' if PHASE == 'prefix' else 'postfix'}.json")
|
||||
out_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
out_path.write_text(json.dumps(OUT, ensure_ascii=False, indent=2),
|
||||
encoding="utf-8")
|
||||
print(json.dumps(OUT["summary"] | {"out": str(out_path)},
|
||||
ensure_ascii=False))
|
||||
return OUT
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(0 if main(sys.argv)["summary"]["pass"] else 1)
|
||||
Reference in New Issue
Block a user