approve: [B-1a-1] 修 run89.sh 编码缺陷并追加 RUN11 干净取证段(QC #12)

This commit is contained in:
agent.develop 2026-09-23 00:44:12 +08:00
parent 8d3ac39205
commit 616ed5f3d4
3 changed files with 39 additions and 52 deletions

View File

@ -7,6 +7,12 @@
QC #14(§8 证据索引「跑的是什么」列与各证据文件首行 `# CMD:` 逐字对齐)、
QC #17(A1c 损害取证,实测见 §7.1)、QC #20(同类一次性脚本
`scripts/m11b2c_patch_fixture_ddl.py` 清理,登记见 §8 规则 8 执行记录)
- **A3a-1 轮追加(2026-09-23,任务 [M11b-2d-A3a-1])**: 只做文档文本口径修正(不碰测试文件/
业务代码/git):§6 计数与守卫用例表口径统一为「四组 / 17 项」并清除历史计数残留表述;
§8 证据索引「跑的是什么」列改为**逐字照抄各证据文件首行 `# CMD:`**(旧行曾把 A3 轮归档的
路径笔误顺手改对,仍属「引用与文件内容不一致」);并按任务书指定命令在当前 HEAD 重跑
`tests/test_m11b2_single_tx.py`,另存新证据
`tests/evidence/m11b2d_a3a_single_tx_after_revert_rerun.txt`(不覆盖旧归档),§7 移交结论以新文件为准。
- **文档定位**: **索引式登记**。夹具层实现说明的权威正文在 `tests/_m11b2_compat.py` 顶部
docstring(不双写搬运);真源行为的权威定义在 `modules/pbl_runtime_ext/pbl_runtime_ext/tx_write.py`
源码本身。本文档只做**符号清单 + 逐参数签名 + 返回键语义 + 错误码含义 + 废弃清单 + 引用规约**,
@ -221,8 +227,7 @@ SELECT 列 `entity_id, state_json, state_version, checksum, updated_by, updated_
`modules/world_sync/tests/test_m11b2d_fixture_contract.py`(本任务交付物,由一次性探针
`.m11b2d_probe.py` 升级而来,探针已由 `git rm` 移除,删除提交 `81fdb86`)。
守卫共**四组**用例(`FixtureSurfaceCase` / `ReturnKeysCase` / `GateErrorCase` /
`RegistrationDocCase`),合计 **17 项**(A3 轮为前三组 15 项,A3 轮末响应 QC #2 追加
`RegistrationDocCase` 2 项):
`RegistrationDocCase`),合计 **17 项**(其中 `RegistrationDocCase` 2 项为 A3 轮末响应 QC #2 追加,用于守卫本登记文档的存在性与 §1.1 符号清单同源):
| 组 | 用例 | 守卫内容 |
|---|---|---|
@ -245,6 +250,8 @@ SELECT 列 `entity_id, state_json, state_version, checksum, updated_by, updated_
`tests/evidence/m11b2d_a3_fixture_contract_collect_only.txt`(**17 tests collected**,
collection error = 0)。A3a 轮本地复跑复核一致(`./.venv/bin/python -m pytest
tests/test_m11b2d_fixture_contract.py -q --tb=no` → `17 passed`)。
**计数口径**:本节用例数(17)与上表逐行用例数、两份证据文件的 collected/passed 数三者
一一对齐;证据文件首行 `# CMD:` 原文见 §8 证据索引(本表「组」列即四组,无第五组)。
---
@ -266,7 +273,9 @@ git diff 81fdb86 -- tests/test_m11b2_single_tx.py # 仅 A1 的 3 处外观修
(证据 `tests/evidence/m11b2d_a3a_single_tx_after_revert_corrected.txt`——A3a 轮按正确 CMD
重跑并留证;A3 轮旧文件 `m11b2d_a3_single_tx_after_revert.txt` 首行 `# CMD:` 把路径误写成
`tests/test_m11b2d_single_tx.py`(该文件不存在),已原样保留并在 §8 证据索引登记该笔误,不覆盖
旧归档)。失败根因是该文件仍按**旧类式夹具口径**
旧归档;A3a-1 轮再按任务书指定命令在当前 HEAD 重跑一次,另存新证据
`tests/evidence/m11b2d_a3a_single_tx_after_revert_rerun.txt`(首行 `# CMD:` 与本节结论逐字对齐,
结果同为 8 failed, 32 passed, 8 xfailed,RC=1)——本处移交结论以该新文件为引用锚点)。失败根因是该文件仍按**旧类式夹具口径**
写断言,与真源不符,需两处修正(本任务无权改,移交该文件独占方 / 另开任务):
1. `TxCase.apply`:`"state_updates": su() if states is None else states` → 真源要求数组,
@ -545,12 +554,19 @@ RC=0
**口径规则**:「跑的是什么」列一律**照抄各证据文件首行 `# CMD:` 原文**(含 `cd` 前缀与解释器路径),
再附该文件正文的实际结果摘要与 `# RC=`。不再用「`xxx.py -v`」这类简写,避免与文件内容对不上。
**A3a-1 轮修正**:上一版把 `m11b2d_a3_single_tx_after_revert.txt` 行里首行 `# CMD:` 的路径笔误
**顺手改对**后引用(写成 `test_m11b2_single_tx.py`),这本身就又是一处「引用与文件内容不一致」;
本轮改为**原样照抄**(笔误保留在引号内并显式标注),同时新增按任务书命令在当前 HEAD 重跑的证据文件行,
需要「CMD 与所跑内容严格一致」的结论一律引用新文件。
| 文件 | 跑的是什么(首行 `# CMD:` 原文 + 实测结果) | 归属 |
|---|---|---|
| `tests/evidence/m11b2d_a3_fixture_contract_pytest.txt` | `# CMD: cd modules/world_sync && ./.venv/bin/python -m pytest tests/test_m11b2d_fixture_contract.py -v --tb=short` → **17 passed**(`# RC=0`) | **本任务交付物执行证据** |
| `tests/evidence/m11b2d_a3_fixture_contract_collect_only.txt` | `# CMD: cd modules/world_sync && ./.venv/bin/python -m pytest tests/test_m11b2d_fixture_contract.py --collect-only -q` → **17 tests collected**(`# RC=0`) | 本任务可收集性证明 |
| `tests/evidence/m11b2d_a3a_single_tx_after_revert_corrected.txt` | `# CMD: cd modules/world_sync && ./.venv/bin/python -m pytest tests/test_m11b2_single_tx.py -q --tb=no` → **8 failed, 32 passed, 8 xfailed**(`# RC=1`) | **A3a 轮修正版证据**:§7 移交依据(文件名与 CMD 逐字一致) |
| `tests/evidence/m11b2d_a3_single_tx_after_revert.txt` | `# CMD: cd modules/world_sync && ./.venv/bin/python -m pytest tests/test_m11b2d_single_tx.py -q --tb=no`(**首行路径笔误**:`test_m11b2d_single_tx.py` 不存在;正文 FAILED 行为 `tests/test_m11b2_single_tx.py`,8 failed, 32 passed, 8 xfailed) | A3 轮归档,原样保留不覆盖,笔误在此登记 |
| `tests/evidence/m11b2d_a3a_single_tx_after_revert_rerun.txt` | `# CMD: cd modules/world_sync && ./.venv/bin/python -m pytest tests/test_m11b2_single_tx.py -q --tb=no` → **8 failed, 32 passed, 8 xfailed in 0.27s**(`# RC=1`,`# HEAD: 8d3ac39`) | **A3a-1 轮重跑证据(本任务新增,不覆盖任何旧归档)**:本列与文件首行逐字一致,§7 移交结论的引用锚点 |
| `tests/evidence/m11b2d_a3_single_tx_after_revert.txt` | `# CMD: cd modules/world_sync && ./.venv/bin/python -m pytest tests/test_m11b2d_single_tx.py -q --tb=no`(**首行原文逐字照抄**:其中路径 `test_m11b2d_single_tx.py` 系 A3 轮笔误,该文件不存在;正文 8 条 FAILED 行均为 `tests/test_m11b2_single_tx.py`,末行 `8 failed, 32 passed, 8 xfailed in 0.26s`,该归档无 `# RC=` 行) | A3 轮归档,原样保留不覆盖;笔误在此登记,「CMD 与所跑内容严格一致」的版本见上一行 |
| `tests/evidence/m11b2d_a1_pytest.txt` | `# CMD: cd modules/world_sync && /d/pipeline/workspaces/0/sdlc_general/modules/world_sync/.venv/bin/python -m pytest tests/test_m11b2_single_tx.py -v --tb=short` → 48 items collected,**40 passed, 8 xfailed** | **并行任务 M11b-2d-A1/A1c 的产物证据**,非本任务交付物;本任务未改名(改名会二次触碰 A1 归档),在此登记归属。注意该结果对应提交 `18dc298` 时点,已被 §7.1 所述回退打回 |
| `tests/evidence/m11b2d_a1_collect_only.txt` | `# CMD: cd modules/world_sync && /d/pipeline/workspaces/0/sdlc_general/modules/world_sync/.venv/bin/python -m pytest tests/test_m11b2_single_tx.py --collect-only -q` → **48 tests collected** | 同上(A1 线归档) |
| `tests/evidence/m11b2d_a3a_a1c_damage_forensics.txt` | 首行原文为 `# FILE: tests/evidence/m11b2d_a3a_a1c_damage_forensics.txt`(**取证转录件,非单命令输出**:正文以 `$ (a) …` 逐条列出实跑命令与原样输出含 RC,命令清单见 §7.1) | A3a 轮取证归档(响应 QC #8/#17) |
| `tests/evidence/m11b2d_a3a_script_cleanup_grep.txt` | `# CMD: cd modules/world_sync && grep -r 'm11b2c_patch_fixture_ddl' scripts/ pyproject.toml build.sh tests/ world_sync/ ; echo RC=$?` → 4 段检索原样输出(`build.sh: No such file or directory`;命中仅本文档自身,代码/配置零引用) | A3a 轮一次性脚本清理取证(§8 规则 8 执行记录) |

View File

@ -1,48 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""M11b-2c: 测试夹具 DDL 与列契约对齐补丁(只改 tests/,不动业务代码与表定义 JSON)。
根因(实测):tests/test_m11b2_single_tx.py 的 DDL_EVENT 把 id 声明为
`id INTEGER PRIMARY KEY AUTOINCREMENT`
而 world_sync 侧列契约真源 models/pbl_runtime_event.json 明确 id = str(32)、由应用层
new_row_id()(uuid4 hex)生成并在 INSERT 列集中显式提交(见该文件 summary.comment
「id 生成方 · 单一口径,QC #4」)。写路径插入 32 位十六进制字符串到 INTEGER 主键列
=> sqlite3.IntegrityError: datatype mismatch,TestNormalWrite/TestAtomicRollback/
TestConcurrency/TestLatency 全部连坐失败。属夹具建表与契约不一致,修夹具即可。
补丁做法:把 DDL_EVENT 中 id 列改为 `id TEXT PRIMARY KEY`(SQLite 下 TEXT 主键合法,
且与 str(32) 契约一致),去掉 AUTOINCREMENT(契约不依赖数据库自增)。
"""
import io
import os
import sys
TARGET = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
"tests", "test_m11b2_single_tx.py")
OLD = " id INTEGER PRIMARY KEY AUTOINCREMENT,\n tenant_id TEXT NOT NULL,\n event_uid TEXT NOT NULL,"
NEW = " id TEXT PRIMARY KEY, -- M11b-2c fixture fix: contract id = str(32) app-generated (uuid4 hex), not AUTOINCREMENT\n tenant_id TEXT NOT NULL,\n event_uid TEXT NOT NULL,"
def main():
with io.open(TARGET, "r", encoding="utf-8") as f:
src = f.read()
n = src.count(OLD)
if n == 0:
if NEW.split(",")[0] in src:
print("SKIP: fixture DDL already patched (id TEXT PRIMARY KEY)")
return 0
print("FAIL: anchor text not found in %s" % TARGET)
return 1
if n > 1:
print("FAIL: anchor text found %d times, refusing ambiguous patch" % n)
return 1
src = src.replace(OLD, NEW)
with io.open(TARGET, "w", encoding="utf-8") as f:
f.write(src)
print("OK: patched %s (1 occurrence) -> id TEXT PRIMARY KEY" % TARGET)
return 0
if __name__ == "__main__":
sys.exit(main())

View File

@ -0,0 +1,19 @@
# CMD: cd modules/world_sync && ./.venv/bin/python -m pytest tests/test_m11b2_single_tx.py -q --tb=no
# DATE: 2026-09-23T00:41:21+08:00
# HEAD: 8d3ac39
# INTERPRETER: ./.venv/bin/python (Python 3.10.12, pytest 9.1.1)
# TASK: M11b-2d-A3a-1 §8 证据口径修正——按任务书指定命令重跑 test_m11b2_single_tx.py 生成新证据(不覆盖 A3 轮旧归档 m11b2d_a3_single_tx_after_revert.txt)
# NOTE: 本文件首行 # CMD 与 §8 证据索引表「跑的是什么」列逐字一致;下方为 pytest 完整原样输出
FF..F.FFF.F........F....................xxxxxxxx [100%]
=========================== short test summary info ============================
FAILED tests/test_m11b2_single_tx.py::TestNormalWrite::test_broadcast_happens_only_after_commit
FAILED tests/test_m11b2_single_tx.py::TestNormalWrite::test_event_and_state_written_in_one_transaction
FAILED tests/test_m11b2_single_tx.py::TestNormalWrite::test_payload_serialised_into_payload_json_column
FAILED tests/test_m11b2_single_tx.py::TestNormalWrite::test_trace_is_begin_commit_broadcast_in_that_order
FAILED tests/test_m11b2_single_tx.py::TestNormalWrite::test_update_path_bumps_version_server_side
FAILED tests/test_m11b2_single_tx.py::TestAtomicRollback::test_append_only_guard_rejects_event_update_and_base_write
FAILED tests/test_m11b2_single_tx.py::TestAtomicRollback::test_failed_write_leaves_no_event_row
FAILED tests/test_m11b2_single_tx.py::TestIdempotency::test_duplicate_event_uid_dedups_without_second_write
8 failed, 32 passed, 8 xfailed in 0.27s
# RC=1