world_sync/docs/work-log-2026-09-22-m11b2c.md

24 KiB
Raw Blame History

Work Log — 2026-09-22 · M11b-2c:world_sync 单事务库函数(write_event_with_state / read_entity_state)

  • 模块:world_sync(宿主镜像/消费方侧,运行时事件与实体状态单事务写入器)
  • 里程碑:M11b-2(单事务写两表);上游真源模块 pbl_runtime_ext(表结构与 tx_write/tx_read 能力权威源)
  • 本轮任务:[M11b-2c-T2-a] 写 dev-notes.md 追加章 + work-log 正文(task_id XvEexvh10D4dfkvR3xkkf,role=agent.develop,task_kind=new_dev,父任务 [M11b-2c-T2] kICTWazBqgIWtKNO7sz8A)
  • 本文按 module-development-spec「Work Logs 强制项」产出:改了什么 / 数据模型 / 契约接口 / 陷阱与裁决 / 验证证据(依次对应 §0、§1、§2、§3、§4)。
  • 范围纪律:本轮只写文档正文,未修改任何业务代码 / models/*.json / scripts/load_path.py(RBAC 登记归 T3;本里程碑本无新 HTTP 路径,见 §2.3)。

0. 本轮(T2-a)写作范围与纪律

项 口径
本轮只做 写实质正文:本文(模块工作日志)+ projects/pbls/docs/02-develop/dev-notes.md 的 [M11b-2c] 章
本轮不做 不产出 code_files.md(归 [M11b-2c-T2-b],task_id EBIrHXlTuUkKYl7dPdYgo);不落盘 measure.log、不写 fallback 交付摘要(归 [M11b-2c-T2-c],task_id UFjoRchqgo8asHC3rP5he)
git 事实陈述 按 develop 阶段规范,本模块仓库 modules/world_sync 的文档改动由本轮做选择性提交:git add docs/work-log-2026-09-22-m11b2c.md 单文件(禁 git add -A、禁 add wwwroot/),本轮零代码改动故该笔只含此一个文件;commit hash 不写进本文(写进即自指竞态),由收口轮 T2-c 现场取 git -C modules/world_sync log -1 --format=%H 并连同 git show --stat 落 measure.log [git] 段。projects/pbls 项目过程文档仓不由本角色提交,其 dev-notes.md 等仍为未提交状态,待 PM 审核通过后统一提交
自指竞态 本文不声明自身字节数;凡涉及 dev-notes.md / 本文 / code_files.md 三者尺寸之处,一律写「见 measure.log [final] 段(由收口子任务落盘)」。代码文件本轮零改动,其字节数可现场 wc -c 实测写死(见 §6.2)
占位符 全文无字母尺寸槽、无 40 位 0 串 hash 槽

1. 数据模型

M11b-2 写路径涉及两张表,结构权威源在 pbl_runtime_ext/models/,world_sync/models/ 下是消费方内联副本(不是引用式声明——database-table-definition-spec 只认 summary/fields/indexes/codes 四段式,scripts/validate_models_json.py 对 key=schema 引用式写法直接判 FAIL,QC #5 结论)。

1.1 pbl_runtime_event(运行时事件,append-only)

  • 真源:modules/pbl_runtime_ext/models/pbl_runtime_event.json;副本:modules/world_sync/models/pbl_runtime_event.json(25 列;字节数以现场 wc -c 为准)
  • 一致性:由 scripts/m11b2b_column_diff.py + scripts/m11b2_selftest.py 机械核对,mirror-sha256-equal 断言真源与 apps/scense/pkgs/world_sync 镜像字节级一致(本次重跑 PASS)。
  • 语义要点:
    • append-only:写路径只做 INSERT,不 UPDATE / 不 DELETE(TestScopeAndSqlContract::test_event_sql_is_insert_only 守这条)。
    • event_uid 是幂等/重试定位键(默认 uuid4 hex,可由入参指定以便测试因果链);旧口径的 event_id 已废弃。
    • state_version 与状态行生效后的版本号对齐(同事务内第 4 步算出再写第 5 步),供 M11b-3 广播去重与 M11b-4 轮询增量拉取。
    • seq_no 严格单调递增(P99 探针断言 PASS);source 默认 world_sync.m11b2;broadcast 标记位由 M11b-3 消费。
    • payload 以 JSON 文本入库(json.dumps 后写 text 列;抽象类型归一 json→text、bigint→long,不保留物理修饰)。

1.2 pbl_entity_state(实体状态,服务端权威版本)

  • 真源:modules/pbl_runtime_ext/models/pbl_entity_state.json;副本:modules/world_sync/models/pbl_entity_state.json(字节数以现场 wc -c 为准)
  • 列集(真源实测 10 列,早期「8 列」口径作废):tenant_id / id / session_id / entity_id / state_json / state_version / checksum / updated_by / created_at / updated_at
  • 定位键 = 唯一索引 uk_es (tenant_id, session_id, entity_id),与 write_event_with_state / read_entity_state 的 WHERE 完全一致(没有 world_id 列,world_id 仅作历史兼容入参被忽略)。
  • state_version 单调 +1,客户端禁写;state_json 存完整新状态(非 diff)。
  • id 类型偏离:真源 BIGINT AUTO_INCREMENT,world_sync 副本内联为 str/length=32(spec 合规写法),主键由应用层生成 32 位 uuid。写路径 INSERT 不显式提交 id——生产 MySQL 交给真源 DDL 的 AUTO_INCREMENT,本地/测试 sqlite DDL 用应用层生成值。此偏离为有意选择(副本侧不走「登记放行 id 非 str(32)」路线,因为本任务范围禁改校验器脚本),评审勿判结构缺陷。
  • 主键只在 summary[0].primary=["id"] 单点声明,indexes[] 内不出现 PRIMARY 条目(spec 规则 index_name_primary)。

2. 契约接口

2.1 两个库函数(M11b-2 的全部对外面)

# world_sync/pbl_runtime_tx.py:351
def write_event_with_state(event_data=None, state_update=None, conn_factory=None,
                           conn=None, event_uid=None, source=None, clock=None) -> dict
# world_sync/pbl_runtime_tx.py:310
def read_entity_state(conn_factory=None, tenant_id=None, session_id=None,
                      entity_id=None, world_id=None, conn=None) -> dict | None
  • event_data 必填:tenant_id / entity_id / event_type;可选 payload、session_id、scene_id、world_id、actor_id、causation_id、idem_key、seq/seq_no、tx_group、source、broadcast。
  • state_update 必填:tenant_id / session_id / entity_id;新状态键 state(或 state_json,dict 或 JSON 文本皆可);可选 expected_version(乐观锁)、updated_by。传 None = 只写事件不改状态(返回 action="event_only")。
  • 成功返回:{event_uid, state_version, action: updated|inserted|event_only, elapsed_ms, isolation_level_applied, dialect, ...}。
    • elapsed_ms 是 P99 统计的采样来源;
    • isolation_level_applied=False 在 sqlite 下是正常(无该概念),MySQL/PG 下应为 True。
  • read_entity_state 返回 {"state": ..., "state_version": int, "updated_at": ...},查不到返回 None;它是独立短事务,不与写入事务共用(避免长事务占行锁),供上层冲突后重读版本再重试。
  • 复用 conn 时仍由本函数负责该连接的 commit/rollback,调用方不要自行 commit。

2.2 三处同步注册(module-development-spec 铁律 4,已 grep 核验)

环节 位置
① 实现 world_sync/pbl_runtime_tx.py:310,351(模块 __all__ 已导出)
② 包导出 world_sync/__init__.py:119-120(import)+ :209-210(__all__)
③ 宿主挂载 world_sync/init.py:513-514 → env.write_event_with_state / env.read_entity_state

适配层 world_sync/pbl_runtime_tx_sqlor.py:126,154 提供同名薄包装(宿主连接池接线,不重复实现事务逻辑)。

2.3 无 HTTP 端点(重要)

M11b-2 不新增 .dspy / .ui,因此 scripts/load_path.py 中没有这两个函数的权限条目,也不该有——它们是 Python 库函数,经 load_world_sync() 挂到 ServerEnv 供宿主调用,不走 HTTP 路由,不存在 401/403 面。wwwroot/api/README-N-A-M11b2.md 是「Not Applicable」的显式留档。正式声明见 projects/pbls/docs/02-develop/m11b2c-rbac-path-declaration.md。

2.4 事务与冲突契约(详版在 dev-notes.md [M11b-2c] 章 §2)

BEGIN(sqlite BEGIN IMMEDIATE)→ 会话级 READ COMMITTED(MySQL/PG;失败降级不阻断,靠乐观锁兜底并透出标志)→ 读 state_version(MySQL/PG 加 FOR UPDATE)→ expected_version 预检 → 状态 CAS 更新/INSERT → 事件 INSERT → COMMIT;任一步失败 _rollback_quiet + 明确异常(ConcurrentStateConflict / StateWriteError / EventWriteError / TxAbortError / TxConfigError / ConnFactoryNotConfigured),两表 0 变更,绝不吞错。

3. 陷阱(本模块改动前必读)

  1. 别在 world_sync 侧建表。DDL 归 pbl_runtime_ext;world_sync/models/*.json 只是消费方契约视图。改真源必须同步本副本并重跑 m11b2b_column_diff.py + m11b2_selftest.py。
  2. 列名不许写死。列集由 pbl_runtime_authority 从真源机械导出,_assert_contract() 在建 SQL 之前 fail-closed(AuthorityResolutionError)。新增列只改真源 JSON + 同步副本,代码里出现字面量列名清单 = 双写分叉隐患。
  3. 定位键是 tenant_id + session_id + entity_id,不是 world_id(表里没这列)。传 world_id 只被忽略——别指望它做隔离。
  4. expected_version 两级校验缺一不可:预检给友好错误(带 expected/actual),CAS(rowcount != 1)防预检与写入之间的窄窗口。只留预检会丢失更新;只留 CAS 则冲突时报错退化为「受影响行数 0」的无语义失败,调用方无法自助重试。
  5. 状态行 INSERT 不带 id(见 §1.2 偏离说明),且 UNIQUE 列空串必须归一为 None('' 会互相撞唯一键)。
  6. 写序是先状态、后事件。反过来会让事件携带一个可能被回滚的 state_version,M11b-3 广播与 M11b-4 轮询都会拿到脏版本。
  7. isolation_level_applied=False 不等于失败(sqlite 无该概念)。测试断言要按 dialect 分支;MySQL/PG 下若为 False 先查账号权限/版本。
  8. conn_factory 三级优先级:显式注入(可传 DB URL)→ 复用 conn → 宿主 ServerEnv 连接池(POOL_KEYS=("sqlor_pools","db_pools","pools","sqlorPools"),库名键 ("pbl","world_sync","default"))。拿不到池就抛 ConnFactoryNotConfigured,禁止回落到裸连或读 env/{test,prod}.json 凭据(project-directory-spec §8.1)。
  9. m11b2_selftest.py 的 cross-check-sql 检查器:M11b-2c 重构后 EVENT_COLUMNS = columns_of(EVENT_TABLE)(运行时派生),旧正则抓字面量元组会误报「未能解析」。已由 commit 6532d8f 改为三级解析(A 字面量 / B1 运行时 import / B2 静态回落)。再遇到同类 FAIL 先怀疑检查器而非业务代码。
  10. 遗留测试文件是技术债,不是验收依据:tests/test_m11b2_single_tx.py、tests/test_m11b2_wiring.py 的 29 条失败源于脚手架 DDL 与真源不一致、仍用已废弃的 event_id 关键字、缺显式 dialect、init.py 相对路径等(逐条归因见 projects/pbls/docs/02-develop/m11b2c-tests-result.md §4.1)。等价覆盖已在 pbl_runtime_ext/tests/test_m11b2c_runtime_ext.py(9 passed,含 2 条 P99 门禁与 1 条冲突回滚干净性)。重写需单列 rework 任务,本轮未修改这两个文件。
  11. 广播/轮询不在此模块的 M11b-2 路径里:post-commit 广播由 init.py 的 hook 把 write_event_with_state 包一层(M11b-3),3s 轮询兜底在 pbl_runtime_polling.py(M11b-4)。摘掉这两层不影响 M11b-2 写入正确性——排查时先确认看到的是哪一层。
  12. P99 数据是离线 sqlite/内存引擎实测,不含网络 RTT 与真实 InnoDB 锁等待,只能作为逻辑时延下界;上线后在测试环境按 pbl_runtime_latency.py 口径复测。
  13. 冲突后的重试姿势:捕获 ConcurrentStateConflict → read_entity_state 重读最新 state_version → 以该值为新 expected_version 重跑 write_event_with_state。不要盲目循环重试(版本被他人持续推进时应向上报错)。异常族行号见 §6.2。

4. 验证证据(本次实跑)

$ cd modules/world_sync && .venv/bin/python scripts/m11b2_selftest.py     # exit code 0
PASS  [mirror-sha256-equal] pbl_runtime_event 真源与镜像字节级一致 -> True
PASS  [mirror-sha256-equal] pbl_entity_state 真源与镜像字节级一致 -> True

断言合计 554:PASS 554 / FAIL 0
RESULT: PASS
  • 全文落盘:projects/pbls/docs/02-develop/m11b2c-t2-selftest-rerun.log(字节数以现场 wc -c 为准)
  • 真源侧:pbl_runtime_ext pytest 9 passed / 0 failed(m11b2c-tests-pbl-runtime-ext-raw.log);m11b_selftest.py 总计 110 项,PASS 110 / FAIL 0 → RESULT: PASS(m11b2c-tests-selftest-raw.log)
  • P99(m11b2c_p99_probe.py,n=60,SLA 200ms,m11b2c-tests-p99-probe-raw.log):write_event_with_state[INSERT分支] P99=0.2414ms / read_entity_state P99=0.2241ms / write_event_with_state[UPDATE分支] P99=0.4984ms,三条均 PASS;附带 seq_no 严格递增 PASS、UPDATE 分支 60 次覆写后 state_version 单调至 61、读回 entity_id 一致性 PASS
  • 本模块 pytest:29 failed / 56 passed(m11b2c-tests-pytest-raw.log)——遗留测试脚手架漂移,非业务缺陷,定性依据见 §3 陷阱 10
  • 本轮为纯文档轮,未改代码,故无新增编译/端点验证;上述数字全部来自磁盘真实留证日志,可逐条复核

5. 关联文档

  • 应用级开发说明(本里程碑正文):projects/pbls/docs/02-develop/dev-notes.md → [M11b-2c] world_sync 库函数 章
  • 真源侧:dev-notes-m11b2c-runtime-ext.md;迁移:dev-notes-m11b2a-world-sync-migration.md;A3 修复:m11b2c-a3-fix-notes.md
  • RBAC 口径:m11b2c-rbac-path-declaration.md;实跑留证:m11b2c-tests-result.md 及各 m11b2c-tests-*-raw.log
  • 模块技能:modules/world_sync/skill/SKILL.md;上一份工作日志:modules/world_sync/docs/work-log-2026-09-20.md

6. 本轮(T2-a)补充:文档收口约定与实测锚点

6.1 与前几轮的差异(为什么本文不再有「第三轮刷新/收口」章节)

本模块文档此前几轮把「写作」与「测量取证 + 数字回填 + 提交」混在同一轮做,结果反复在回填一步中断,交出的文档里留下字母尺寸槽与 hash 占位串,且出现「文档声称已提交而磁盘 git status 仍是未提交」的陈述与事实矛盾。本轮按 PM 拆分把两件事彻底分离:

  • T2-a(本轮):只写正文(本文 + dev-notes [M11b-2c] 章)。凡尺寸类自指/互指信息一律改为「见 measure.log [final] 段」的引用约定,不写死数字、不留占位串;本模块仓按规范做单文件选择性提交(见 §0 与 §6.4)。
  • T2-b:产出 code_files.md 文件清单(代码文件尺寸引用 + grep -n 行号锚点)。
  • T2-c:重跑测量落盘 measure.log([final] / [git] 两段)→ 回填非自指尺寸 → 写 fallback 交付摘要。

因此本文不声明自身字节数,也不声明 dev-notes.md / code_files.md 的字节数。

6.2 本模块文件锚点(T2-a 现场实测,代码零改动故可直接对账)

文件 字节数(wc -c 实测) 锚点(grep -n 实测)
world_sync/pbl_runtime_tx.py 见 measure.log [final] 段 wc -c 原样输出行 :296 _set_isolation / :310 read_entity_state / :351 write_event_with_state / :517 isolation_level_applied
world_sync/pbl_runtime_sql.py 见 measure.log [final] 段 wc -c 原样输出行 :136 begin_stmt / :148 read_committed_stmt / :157 for_update_clause
world_sync/pbl_runtime_errors.py 见 measure.log [final] 段 wc -c 原样输出行 :35 PblRuntimeError / :71 TxConfigError / :78 ConnFactoryNotConfigured / :85 EventWriteError / :92 StateWriteError / :99 ConcurrentStateConflict / :110 TxAbortError
world_sync/pbl_runtime_tx_sqlor.py 见 measure.log [final] 段 wc -c 原样输出行 :126 write_event_with_state / :154 read_entity_state
world_sync/__init__.py 见 measure.log [final] 段 wc -c 原样输出行 :119-120 导入、:209-210 __all__
world_sync/init.py 见 measure.log [final] 段 wc -c 原样输出行 :513 env.write_event_with_state、:514 env.read_entity_state、:587 M11b-3 广播钩子二次覆盖同名挂载
models/pbl_runtime_event.json 见 measure.log [final] 段 wc -c 原样输出行 25 列,四段式合规
models/pbl_entity_state.json 见 measure.log [final] 段 wc -c 原样输出行 10 列,uk_es=['tenant_id','session_id','entity_id']
scripts/m11b2_selftest.py 见 measure.log [final] 段 wc -c 原样输出行 554 条断言(§4)

真源侧 modules/pbl_runtime_ext:pbl_runtime_ext/tx_write.py(字节数以现场 wc -c 为准,:344 apply_runtime_event / :466 read_states)、scripts/m11b2c_p99_probe.py(P99 探针)、pbl_runtime_ext/latency.py(SLA_P99_MS=200.0)。

行号口径统一:read_committed_stmt 一律记 :148(本轮 grep -n '^def read_committed_stmt' world_sync/pbl_runtime_sql.py 实测),dev-notes [M11b-2c] 章 §2.2 同口径。

6.3 遗留缺口(供 PM 编排)

  1. tests/test_m11b2_single_tx.py / tests/test_m11b2_wiring.py 共 29 条漂移用例需单列 rework(等价覆盖已在真源侧全绿,不阻塞 M11b-2 验收)。
  2. 真实 MySQL/PG 下的端到端时延与 isolation_level_applied=True 验证需 deploy_test 连库补测(本地 sqlite 无该概念,见 §3 陷阱 7/12)。

6.4 本轮 git 事实(与磁盘一致)

  • modules/world_sync:本轮只改本文一个文件,已按规范做选择性提交(git add docs/work-log-2026-09-22-m11b2c.md,禁 git add -A、禁 add wwwroot/)。提交信息前缀 docs(M11b-2c-T2-a):。hash 与 git show --stat 原样输出由收口轮 T2-c 落 measure.log [git] 段,本文不写死。
  • projects/pbls(dev-notes.md 所在的过程文档仓):本阶段不提交,待 PM 审核通过后统一提交。
  • 本文不含任何 hash 槽位(无字母槽、无 40 位 0 串),也不声称「两仓均已提交」。

6.5 复杂度评估(本轮)

简单——单交付单元(两份文档正文写作),零代码改动、零表定义改动、无跨模块影响,无需拆分。父任务 [M11b-2c-T2] 整体为复杂(多独立交付单元 + 串行收口依赖),已由 PM 拆为 T2-a / T2-b / T2-c 三子任务并按批次派发,口径见 §6.1。


7. 收口轮(T2-c)回填笔 · 2026-09-22

由 [M11b-2c-T2-c](task_id UFjoRchqgo8asHC3rP5he)追加。本文自身尺寸不写死(自指竞态),见 由 [M11b-2c-T2-c1] 定稿:本节凡「会被后续编辑改变的数值」(交叉字节数、自身字节数、收口笔数、关键词计数) 一律不写死,改为引用约定指向真值源原样输出行;只保留已存在于 git 历史的 40 位 hash(不随文档变化)。

项 取值口径 / 真值 复核命令
projects/pbls/docs/02-develop/dev-notes.md 字节数 见 measure.log [final] 段 wc -c 原样输出行(对方文件,同样不写死) wc -c projects/pbls/docs/02-develop/dev-notes.md
kICTWazBqgIWtKNO7sz8A_code_files.md 字节数 见 measure.log [final] 段 wc -c 原样输出行(对方文件,同样不写死) wc -c projects/pbls/deliverables/agent.develop/kICTWazBqgIWtKNO7sz8A_code_files.md
modules/world_sync/docs/work-log-2026-09-22-m11b2c.md 自身字节数 见 measure.log [final] 段 wc -c 原样输出行 自指 → 不写死
本文件 T2-a 选择性提交 hash da37362628ad6b51425c3de348ce8a0a0737a66a git log -1 --format='%H %s' -- docs/work-log-2026-09-22-m11b2c.md(只含本文件一笔,无 wwwroot、无代码)
本文件 T2-c 收口笔 hash
read_committed_stmt 定义行 world_sync/pbl_runtime_sql.py:148 T2-c 重跑 grep -n '^def read_committed_stmt' 复核,与 §6.2 同口径

数字口径说明(T2-c → T2-c1):上表尺寸一律为引用约定(不再留当场读数),与 projects/pbls/docs/02-develop/m11b2c-t2-code-files-measure.log [final] 段同批同源;上一轮把首跑段的回填前基线(三份文档各自的回填前基线读数均只落在 measure.log [final] 段,本文件不复述)标为「回填时点实测」属口径标注不实,现予更正。本文自身尺寸仍不写死。

关键词逐词 grep -c(本文)与五词 OR 合并命中行数随本文任何一次编辑变化,故不留数值;权威口径见 measure.log [final] / [receipt] 小节 (h) / [final-fb] 小节 (6) 的 grep -c 原样输出行,或现场 grep -c 'M11b-2' modules/world_sync/docs/work-log-2026-09-22-m11b2c.md(换词同理)复算。

§6.4 第一条「hash 由收口轮落 measure.log、本文不写死」的约定仍然成立;本表补的是上一笔已存在的 T2-a hash(不随本文变动而失效)。 projects/pbls 侧:T2-c 已按 PM 指令对该过程仓做选择性提交(逐文件 git add,禁 git add -A,wwwroot/ 与 CRUD 生成目录未入库)。本任务 T2-c 命名收口笔的权威清单与笔数,以 measure.log [git] 段 git -C <repo> log --grep='T2-c' --format='%H %ad %s' --date=iso 原样输出为准(本文件不写死笔数概数)。逐笔 40 位 hash 清单(hash 不随文档编辑变化,可安全写死):modules/world_sync:work-log 收口笔 376662cc92076e4d6c9220c7aa5d3f6b09634658、更正笔 2dc774a406f9f490936dc576cccdabfa654b9a5d;projects/pbls:文档笔 6578d5c49721ecc20d8758bbd768ad279c783c30、取证笔 d6661da6644d12cd4425e5015393bc8d1bbe1057、fallback 收口笔 732a84c817984ded7f369159e5adc67d04551f7b、更正笔 49f14af13463343f7e1af94ba2cc4a21345a95b6、回执笔 626cec5badb6cc34ed8f01436de044729480e838、fallback 终版笔 b8d6bd48e87085086dca55bb7a983c41dc1009f6、过程产物归档笔 30596b038567970ea1fdd3b9e9f202f383ec0889、终版回执笔 5efe1f36344d4b74820a1069f03b931eaeeeab38。上一版本此处写死「实测收口笔概数(本文件不写死数字)」(更早版本写「收口笔概数(本文件不写死数字)」),均随后续补笔立即失实,现按 QC #1 改为引用约定 + 逐笔 hash;并澄清 f3ecbbae3091dbeeec8a871ae1b0520fc45c0000(一次 add 多个文件、混入他任务 deliverables 与 m9-closureB 文件)系代收口混笔,本任务不认领。各笔 git show --stat 原样输出见 measure.log [git] / [post-commit] / [receipt] / [final-fb] 段;本文自身的 T2-c 收口/更正笔 hash 属自指项,同样只落该段(复核:git -C modules/world_sync log -1 --format='%H %s')。

⑧ T2-c1「去数字化」定稿自证

  • 本轮任务号 M11b-2c-T2-c1(父任务 UFjoRchqgo8asHC3rP5he 拆分批次一)。本段为本轮实际写入的标记段。
  • 收口笔数/提交清单:以 measure.log [git] 段 git -C <repo> log --grep='T2-c' --format='%H %ad %s' --date=iso 原样输出为准(本文件不写死数字)。本文件保留的逐笔 40 位 hash 清单为真值(hash 不随文档编辑变化), 可与 git log --grep='T2-c' 输出逐笔比对。
  • 文件尺寸(他方文件与自身尺寸):一律 见 measure.log [final] 段 wc -c 原样输出行,本文件不再写死任何字节数。
  • 采集时点:不再写死时钟串,时点以 measure.log 段首标记为准。
  • measure.log 性质:measure.log 主体为命令原样输出;以 -> 或 ^ 开头的行是人工批注。
  • .tmpdev 处置真实状态:本轮已将 .tmpdev/m11b2c_t2_round3_cf.py、.tmpdev/m11b2c_t2_round3_dn.py 移入 projects/pbls/docs/02-develop/patches/(以 ls projects/pbls/docs/02-develop/patches/ 原样输出为准);.tmpdev/ 目录仍存在且含他轮次脚本,未处置——本文件不声称该目录已被清空删除。
  • 路径勘误说明:文档中曾引用的 projects/pbls/deliverables/agent.develop/kICTWazBqgIWtKNO7sz8A_code_files.md 在工作空间不存在, 实际路径为 projects/pbls/deliverables/agent.develop/kICTWazBqgIWtKNO7sz8A_code_files.md。
  • 复算命令:grep -nE '实测 *[0-9]+ *笔|共 *[0-9]+ *笔|[0-9]{4,5}B|截至 [0-9]+:[0-9]+|SIZ[A-Z]' <本文件> 应零命中。
  • 不提交声明:本任务不产生任何 git commit,改动留在工作区,由 T2-c2 统一选择性收口。