mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-11-01 14:57:38 +00:00
fix(ci): 修复 c20e7c6 带进来的 && false 死条件 + 自测调用计数契约
## 伤在哪c20e7c6把 ci.yml 的空表守卫写成了: if [ "$n" -eq 0 ] && false && ! grep -qEi '...# none...' <<< "$TABLE"; then ^^^^^^^^ `&& false` 让整个条件恒假 ⇒ ID:19 的「空表必须显式声明」守卫**永不触发**。 这比没有守卫更坏:门禁*看起来*有了守卫,实际恒绿。599252f 引入时是正确的 (无 `&& false`),是c20e7c6把它改坏的。 ## 改了什么(两处,无夹带) 1. .github/workflows/ci.yml —— 只删 `&& false` 这一个 token,其余逐字不动。 守卫恢复为「空表且未写 # none ⇒ 报错退出 1」。 2. .github/scripts/check-ci-gates.py —— 在599252f已有的正反自测之上**加一层**: · `_rejected_checked[0] != 4` 调用计数契约:把四条 `_must_reject(...)` 调用 整段删掉/注掉时,前面所有断言代码都还在、但一次都不会跑(自测静默死掉、 门禁照绿,变异 M8d 实测 exit=0)。现在删一行也红。 · `idx >= len(_EMPTY_BAD_CASES)` 越界可读报错:样本集被清空时不再抛 IndexError 崩溃,给出可读断言消息。 与599252f**不冲突、不抵消**:599252f 加的是「空表标记校验 + 正反自测」, 本提交是在其之上补的「自测自身是否真的跑了」。 ## 实证(提交前实跑) · grep -n '&& false' .github/workflows/ci.yml → 0 命中(exit=1) · python3 .github/scripts/check-ci-gates.py → EXIT=0「CI 门禁自检通过」 · yaml.safe_load → yaml OK(exit=0) · 反向:把 heredoc 数据行清空只留空行 → 门脚本 EXIT=1, 报「排除表步骤用当前 ci.yml 实跑不通过(正向基线坏)」⇒ 缝上后守卫真的会咬; 跑完已还原,md5 对拍 e87461b1e2de95cfc293359cbc0d16de 逐字一致 变异矩阵(10 条,全部 EXIT=1):M1 删整段守卫/红4、M2 `&& false`/红4、 M3 `exit 0`/红4、M4 `grep→false`/红4、M5 删 case 跳过/红1、 M6 `|| true` 短路/红2、M7 `&& :` 恒真/红1、M8 样本集清空/红5、 M8d 删四条自测调用/红1、M8f 只删第 3 条/红1。基线 EXIT=0 红条数 0。 Co-authored-by: pi <pi@local>
This commit is contained in:
18
.github/scripts/check-ci-gates.py
vendored
18
.github/scripts/check-ci-gates.py
vendored
@ -189,8 +189,16 @@ else:
|
|||||||
fails.append("空表反向样本数变了(期望 4,实际 %d)—— 除新增样本,否则说明样本被删"
|
fails.append("空表反向样本数变了(期望 4,实际 %d)—— 除新增样本,否则说明样本被删"
|
||||||
% len(_EMPTY_BAD_CASES))
|
% len(_EMPTY_BAD_CASES))
|
||||||
|
|
||||||
|
_rejected_checked = [0] # 用 list 当可变计数(闭包内可写)
|
||||||
|
|
||||||
def _must_reject(idx):
|
def _must_reject(idx):
|
||||||
"""断言第 idx 个空表形态**必须**被保。"""
|
"""断言第 idx 个空表形态**必须**被拒。"""
|
||||||
|
_rejected_checked[0] += 1
|
||||||
|
if idx >= len(_EMPTY_BAD_CASES):
|
||||||
|
# 样本被删:不抛 IndexError,给可读报错(崩溃不如可读断言好)。
|
||||||
|
fails.append("空表反向样本集缺第 %d 条(只剩 %d 条)—— 样本被删或容器被改坏"
|
||||||
|
% (idx, len(_EMPTY_BAD_CASES)))
|
||||||
|
return
|
||||||
_n, _i = _EMPTY_BAD_CASES[idx]
|
_n, _i = _EMPTY_BAD_CASES[idx]
|
||||||
if _run_body(_replace_table(_i)).returncode == 0:
|
if _run_body(_replace_table(_i)).returncode == 0:
|
||||||
fails.append(
|
fails.append(
|
||||||
@ -202,6 +210,14 @@ else:
|
|||||||
_must_reject(2) # 只有空行+空白
|
_must_reject(2) # 只有空行+空白
|
||||||
_must_reject(3) # 非显式标记的注释
|
_must_reject(3) # 非显式标记的注释
|
||||||
|
|
||||||
|
# ★ 四次调用本身也必须被核对(ID:19 变异 M8d):
|
||||||
|
# 把上面四行 `_must_reject(...)` 整段删掉/注掉时,前面所有断言代码都还在,
|
||||||
|
# 但**一次都不会跑** —— 自测静默死掉、门禁照绿(实测 exit=0)。
|
||||||
|
# 所以把调用次数当成一份合同:删一行也红,不会默默少检。
|
||||||
|
if _rejected_checked[0] != 4:
|
||||||
|
fails.append("空表反向自测只调用了 %d/4 次 —— 有检查被删/跳过(自测静默失效)"
|
||||||
|
% _rejected_checked[0])
|
||||||
|
|
||||||
_probe = "test|internal/probe/synthetic|TestSyntheticProbe"
|
_probe = "test|internal/probe/synthetic|TestSyntheticProbe"
|
||||||
# 只打 reason:reason 空、ticket 有效
|
# 只打 reason:reason 空、ticket 有效
|
||||||
if _run_body(_inject(_probe + "||PROBE-TICKET")).returncode == 0:
|
if _run_body(_inject(_probe + "||PROBE-TICKET")).returncode == 0:
|
||||||
|
|||||||
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@ -272,7 +272,7 @@ jobs:
|
|||||||
# 为何不能允许"什么都没写":那样"表被删空"与"有意清空"无法区分,
|
# 为何不能允许"什么都没写":那样"表被删空"与"有意清空"无法区分,
|
||||||
# 而门脚本(check-ci-gates.py)的正则捕获到空串后,会静默走下面的
|
# 而门脚本(check-ci-gates.py)的正则捕获到空串后,会静默走下面的
|
||||||
# "无排除项"分支 —— 排除项漏删/误删都不会有任何人发现(假绿,ID:19)。
|
# "无排除项"分支 —— 排除项漏删/误删都不会有任何人发现(假绿,ID:19)。
|
||||||
if [ "$n" -eq 0 ] && false && ! grep -qEi '^[[:space:]]*#[[:space:]]*none[[:space:]]*$' <<< "$TABLE"; then
|
if [ "$n" -eq 0 ] && ! grep -qEi '^[[:space:]]*#[[:space:]]*none[[:space:]]*$' <<< "$TABLE"; then
|
||||||
echo "::error::-race 排除表为空却没有显式空表标记 —— 请在上面的 heredoc 里保留一行 \`# none\`"
|
echo "::error::-race 排除表为空却没有显式空表标记 —— 请在上面的 heredoc 里保留一行 \`# none\`"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user